2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
28 #ifndef ID_SND_BACKENDS
29 #define ID_SND_BACKENDS
31 class idAudioHardwareOSS : public idAudioHardware {
32 // if you can't write MIXBUFFER_SAMPLES all at once to the audio device, split in MIXBUFFER_CHUNKS
33 static const int MIXBUFFER_CHUNKS = 4;
37 unsigned int m_channels;
42 // counting the loops through the dma buffer
45 // how many chunks we have left to write in cases where we need to split
47 // how many chunks we can write to the audio device without blocking
48 int m_freeWriteChunks;
51 idAudioHardwareOSS() {
60 m_freeWriteChunks = 0;
62 virtual ~idAudioHardwareOSS();
64 bool Initialize( void );
66 // Linux driver doesn't support memory map API
67 bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) { return false; }
68 bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { return false; }
69 bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ) { return false; }
72 void Write( bool flushing );
74 int GetNumberOfSpeakers() { return m_channels; }
75 int GetMixBufferSize();
76 short* GetMixBuffer();
79 void Release( bool bSilent = false );
81 void ExtractOSSVersion( int version, idStr &str ) const;
87 // the new/old API may be a problem if we are going to dynamically load the asound lib?
88 #define ALSA_PCM_NEW_HW_PARAMS_API
89 #define ALSA_PCM_NEW_SW_PARAMS_API
90 #include <alsa/asoundlib.h>
92 #define id_snd_pcm_hw_params_alloca(ptr) do { assert(ptr); *ptr = (snd_pcm_hw_params_t *) alloca(id_snd_pcm_hw_params_sizeof()); memset(*ptr, 0, id_snd_pcm_hw_params_sizeof()); } while (0)
94 typedef const char * ( *pfn_snd_asoundlib_version )( void );
95 typedef snd_pcm_sframes_t ( *pfn_snd_pcm_avail_update )( snd_pcm_t *pcm );
96 typedef int ( *pfn_snd_pcm_close )( snd_pcm_t *pcm );
97 typedef const char * ( *pfn_snd_strerror )( int errnum );
98 typedef int ( *pfn_snd_pcm_hw_params )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params );
99 typedef int ( *pfn_snd_pcm_hw_params_any )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params );
100 typedef int ( *pfn_snd_pcm_hw_params_get_buffer_size )( const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val );
101 typedef int ( *pfn_snd_pcm_hw_params_set_access )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access );
102 typedef int ( *pfn_snd_pcm_hw_params_set_buffer_size_min )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val );
103 typedef int ( *pfn_snd_pcm_hw_params_set_channels )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val );
104 typedef int ( *pfn_snd_pcm_hw_params_set_format )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format );
105 typedef int ( *pfn_snd_pcm_hw_params_set_rate )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir );
106 typedef size_t ( *pfn_snd_pcm_hw_params_sizeof )( void );
107 typedef int ( *pfn_snd_pcm_open )( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode );
108 typedef int ( *pfn_snd_pcm_prepare )( snd_pcm_t *pcm );
109 typedef snd_pcm_state_t ( *pfn_snd_pcm_state )( snd_pcm_t *pcm );
110 typedef snd_pcm_sframes_t ( *pfn_snd_pcm_writei )( snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size );
112 #define ALSA_DLSYM(SYM) id_##SYM = ( pfn_##SYM )dlvsym( m_handle, #SYM, "ALSA_0.9" ); if ( !id_##SYM ) { common->Printf( "dlsym "#SYM" failed: %s\n", dlerror() ); Release(); return false; }
114 class idAudioHardwareALSA : public idAudioHardware {
116 // if you can't write MIXBUFFER_SAMPLES all at once to the audio device, split in MIXBUFFER_CHUNKS
117 static const int MIXBUFFER_CHUNKS = 4;
119 snd_pcm_t *m_pcm_handle;
120 unsigned int m_channels;
124 // how many frames remaining to be written to the device
125 int m_remainingFrames;
130 idAudioHardwareALSA() {
135 m_remainingFrames = 0;
138 virtual ~idAudioHardwareALSA();
140 // dlopen the lib ( check minimum version )
143 bool Initialize( void );
146 // Linux driver doesn't support memory map API
147 bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) { return false; }
148 bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { return false; }
149 bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ) { return false; }
152 void Write( bool flushing );
154 int GetNumberOfSpeakers( void ) { return m_channels; }
155 int GetMixBufferSize( void );
156 short* GetMixBuffer( void );
161 void PlayTestPattern();
163 // may be NULL, outdated alsa versions are missing it and we just ignore
164 pfn_snd_asoundlib_version id_snd_asoundlib_version;
166 pfn_snd_pcm_avail_update id_snd_pcm_avail_update;
167 pfn_snd_pcm_close id_snd_pcm_close;
168 pfn_snd_strerror id_snd_strerror;
169 pfn_snd_pcm_hw_params id_snd_pcm_hw_params;
170 pfn_snd_pcm_hw_params_any id_snd_pcm_hw_params_any;
171 pfn_snd_pcm_hw_params_get_buffer_size id_snd_pcm_hw_params_get_buffer_size;
172 pfn_snd_pcm_hw_params_set_access id_snd_pcm_hw_params_set_access;
173 pfn_snd_pcm_hw_params_set_buffer_size_min id_snd_pcm_hw_params_set_buffer_size_min;
174 pfn_snd_pcm_hw_params_set_channels id_snd_pcm_hw_params_set_channels;
175 pfn_snd_pcm_hw_params_set_format id_snd_pcm_hw_params_set_format;
176 pfn_snd_pcm_hw_params_set_rate id_snd_pcm_hw_params_set_rate;
177 pfn_snd_pcm_hw_params_sizeof id_snd_pcm_hw_params_sizeof;
178 pfn_snd_pcm_open id_snd_pcm_open;
179 pfn_snd_pcm_prepare id_snd_pcm_prepare;
180 pfn_snd_pcm_state id_snd_pcm_state;
181 pfn_snd_pcm_writei id_snd_pcm_writei;