Mercurial > sdl-ios-xcode
comparison src/audio/alsa/SDL_alsa_audio.c @ 1668:4da1ee79c9af SDL-1.3
more tweaking indent options
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 29 May 2006 04:04:35 +0000 |
parents | cd3db072ba8a |
children | a7ad7081b977 |
comparison
equal
deleted
inserted
replaced
1667:1fddae038bc8 | 1668:4da1ee79c9af |
---|---|
46 | 46 |
47 /* The default ALSA audio driver */ | 47 /* The default ALSA audio driver */ |
48 #define DEFAULT_DEVICE "default" | 48 #define DEFAULT_DEVICE "default" |
49 | 49 |
50 /* Audio driver functions */ | 50 /* Audio driver functions */ |
51 static int ALSA_OpenAudio (_THIS, SDL_AudioSpec * spec); | 51 static int ALSA_OpenAudio(_THIS, SDL_AudioSpec * spec); |
52 static void ALSA_WaitAudio (_THIS); | 52 static void ALSA_WaitAudio(_THIS); |
53 static void ALSA_PlayAudio (_THIS); | 53 static void ALSA_PlayAudio(_THIS); |
54 static Uint8 *ALSA_GetAudioBuf (_THIS); | 54 static Uint8 *ALSA_GetAudioBuf(_THIS); |
55 static void ALSA_CloseAudio (_THIS); | 55 static void ALSA_CloseAudio(_THIS); |
56 | 56 |
57 #ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC | 57 #ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC |
58 | 58 |
59 static const char *alsa_library = SDL_AUDIO_DRIVER_ALSA_DYNAMIC; | 59 static const char *alsa_library = SDL_AUDIO_DRIVER_ALSA_DYNAMIC; |
60 static void *alsa_handle = NULL; | 60 static void *alsa_handle = NULL; |
61 static int alsa_loaded = 0; | 61 static int alsa_loaded = 0; |
62 | 62 |
63 static int (*SDL_snd_pcm_open) (snd_pcm_t ** pcm, const char *name, | 63 static int (*SDL_snd_pcm_open) (snd_pcm_t ** pcm, const char *name, |
64 snd_pcm_stream_t stream, int mode); | 64 snd_pcm_stream_t stream, int mode); |
65 static int (*SDL_NAME (snd_pcm_open)) (snd_pcm_t ** pcm, const char *name, | 65 static int (*SDL_NAME(snd_pcm_open)) (snd_pcm_t ** pcm, const char *name, |
66 snd_pcm_stream_t stream, int mode); | 66 snd_pcm_stream_t stream, int mode); |
67 static int (*SDL_NAME (snd_pcm_close)) (snd_pcm_t * pcm); | 67 static int (*SDL_NAME(snd_pcm_close)) (snd_pcm_t * pcm); |
68 static snd_pcm_sframes_t (*SDL_NAME (snd_pcm_writei)) (snd_pcm_t * pcm, | 68 static snd_pcm_sframes_t(*SDL_NAME(snd_pcm_writei)) (snd_pcm_t * pcm, |
69 const void *buffer, | 69 const void *buffer, |
70 snd_pcm_uframes_t | 70 snd_pcm_uframes_t size); |
71 size); | 71 static int (*SDL_NAME(snd_pcm_resume)) (snd_pcm_t * pcm); |
72 static int (*SDL_NAME (snd_pcm_resume)) (snd_pcm_t * pcm); | 72 static int (*SDL_NAME(snd_pcm_prepare)) (snd_pcm_t * pcm); |
73 static int (*SDL_NAME (snd_pcm_prepare)) (snd_pcm_t * pcm); | 73 static int (*SDL_NAME(snd_pcm_drain)) (snd_pcm_t * pcm); |
74 static int (*SDL_NAME (snd_pcm_drain)) (snd_pcm_t * pcm); | 74 static const char *(*SDL_NAME(snd_strerror)) (int errnum); |
75 static const char *(*SDL_NAME (snd_strerror)) (int errnum); | 75 static size_t(*SDL_NAME(snd_pcm_hw_params_sizeof)) (void); |
76 static size_t (*SDL_NAME (snd_pcm_hw_params_sizeof)) (void); | 76 static size_t(*SDL_NAME(snd_pcm_sw_params_sizeof)) (void); |
77 static size_t (*SDL_NAME (snd_pcm_sw_params_sizeof)) (void); | 77 static int (*SDL_NAME(snd_pcm_hw_params_any)) (snd_pcm_t * pcm, |
78 static int (*SDL_NAME (snd_pcm_hw_params_any)) (snd_pcm_t * pcm, | 78 snd_pcm_hw_params_t * params); |
79 snd_pcm_hw_params_t * params); | 79 static int (*SDL_NAME(snd_pcm_hw_params_set_access)) (snd_pcm_t * pcm, |
80 static int (*SDL_NAME (snd_pcm_hw_params_set_access)) (snd_pcm_t * pcm, | 80 snd_pcm_hw_params_t * |
81 snd_pcm_hw_params_t * | 81 params, |
82 params, | 82 snd_pcm_access_t |
83 snd_pcm_access_t | 83 access); |
84 access); | 84 static int (*SDL_NAME(snd_pcm_hw_params_set_format)) (snd_pcm_t * pcm, |
85 static int (*SDL_NAME (snd_pcm_hw_params_set_format)) (snd_pcm_t * pcm, | 85 snd_pcm_hw_params_t * |
86 snd_pcm_hw_params_t * | 86 params, |
87 params, | 87 snd_pcm_format_t val); |
88 snd_pcm_format_t val); | 88 static int (*SDL_NAME(snd_pcm_hw_params_set_channels)) (snd_pcm_t * pcm, |
89 static int (*SDL_NAME (snd_pcm_hw_params_set_channels)) (snd_pcm_t * pcm, | 89 snd_pcm_hw_params_t * |
90 snd_pcm_hw_params_t * | 90 params, |
91 params, | 91 unsigned int val); |
92 unsigned int val); | 92 static int (*SDL_NAME(snd_pcm_hw_params_get_channels)) (const |
93 static int (*SDL_NAME (snd_pcm_hw_params_get_channels)) (const | 93 snd_pcm_hw_params_t * |
94 snd_pcm_hw_params_t * | 94 params); |
95 params); | |
96 static unsigned int | 95 static unsigned int |
97 (*SDL_NAME (snd_pcm_hw_params_set_rate_near)) (snd_pcm_t * | 96 (*SDL_NAME(snd_pcm_hw_params_set_rate_near)) (snd_pcm_t * |
98 pcm, | 97 pcm, |
99 snd_pcm_hw_params_t | 98 snd_pcm_hw_params_t |
100 * params, | 99 * params, |
101 unsigned | 100 unsigned int val, int *dir); |
102 int val, int *dir); | |
103 static snd_pcm_uframes_t | 101 static snd_pcm_uframes_t |
104 (*SDL_NAME (snd_pcm_hw_params_set_period_size_near)) (snd_pcm_t * pcm, | 102 (*SDL_NAME(snd_pcm_hw_params_set_period_size_near)) (snd_pcm_t * pcm, |
105 snd_pcm_hw_params_t | 103 snd_pcm_hw_params_t |
106 * params, | 104 * params, |
107 snd_pcm_uframes_t | 105 snd_pcm_uframes_t |
108 val, int *dir); | 106 val, int *dir); |
109 static snd_pcm_sframes_t | 107 static snd_pcm_sframes_t |
110 (*SDL_NAME (snd_pcm_hw_params_get_period_size)) (const | 108 (*SDL_NAME(snd_pcm_hw_params_get_period_size)) (const |
109 snd_pcm_hw_params_t | |
110 * params); | |
111 static unsigned int | |
112 (*SDL_NAME(snd_pcm_hw_params_set_periods_near)) (snd_pcm_t * pcm, | |
111 snd_pcm_hw_params_t | 113 snd_pcm_hw_params_t |
112 * params); | 114 * params, |
113 static unsigned int | 115 unsigned int val, |
114 (*SDL_NAME (snd_pcm_hw_params_set_periods_near)) (snd_pcm_t * pcm, | 116 int *dir); |
115 snd_pcm_hw_params_t | 117 static int (*SDL_NAME(snd_pcm_hw_params_get_periods)) (snd_pcm_hw_params_t * |
116 * params, | 118 params); |
117 unsigned int val, | 119 static int (*SDL_NAME(snd_pcm_hw_params)) (snd_pcm_t * pcm, |
118 int *dir); | 120 snd_pcm_hw_params_t * params); |
119 static int (*SDL_NAME (snd_pcm_hw_params_get_periods)) (snd_pcm_hw_params_t * | |
120 params); | |
121 static int (*SDL_NAME (snd_pcm_hw_params)) (snd_pcm_t * pcm, | |
122 snd_pcm_hw_params_t * params); | |
123 /* | 121 /* |
124 */ | 122 */ |
125 static int (*SDL_NAME (snd_pcm_sw_params_current)) (snd_pcm_t * pcm, | 123 static int (*SDL_NAME(snd_pcm_sw_params_current)) (snd_pcm_t * pcm, |
126 snd_pcm_sw_params_t * | 124 snd_pcm_sw_params_t * |
127 swparams); | 125 swparams); |
128 static int (*SDL_NAME (snd_pcm_sw_params_set_start_threshold)) (snd_pcm_t * | 126 static int (*SDL_NAME(snd_pcm_sw_params_set_start_threshold)) (snd_pcm_t * |
129 pcm, | 127 pcm, |
130 snd_pcm_sw_params_t | 128 snd_pcm_sw_params_t |
131 * params, | 129 * params, |
132 snd_pcm_uframes_t | 130 snd_pcm_uframes_t |
133 val); | 131 val); |
134 static int (*SDL_NAME (snd_pcm_sw_params_set_avail_min)) (snd_pcm_t * pcm, | 132 static int (*SDL_NAME(snd_pcm_sw_params_set_avail_min)) (snd_pcm_t * pcm, |
135 snd_pcm_sw_params_t | 133 snd_pcm_sw_params_t |
136 * params, | 134 * params, |
137 snd_pcm_uframes_t | 135 snd_pcm_uframes_t |
138 val); | 136 val); |
139 static int (*SDL_NAME (snd_pcm_sw_params)) (snd_pcm_t * pcm, | 137 static int (*SDL_NAME(snd_pcm_sw_params)) (snd_pcm_t * pcm, |
140 snd_pcm_sw_params_t * params); | 138 snd_pcm_sw_params_t * params); |
141 static int (*SDL_NAME (snd_pcm_nonblock)) (snd_pcm_t * pcm, int nonblock); | 139 static int (*SDL_NAME(snd_pcm_nonblock)) (snd_pcm_t * pcm, int nonblock); |
142 #define snd_pcm_hw_params_sizeof SDL_NAME(snd_pcm_hw_params_sizeof) | 140 #define snd_pcm_hw_params_sizeof SDL_NAME(snd_pcm_hw_params_sizeof) |
143 #define snd_pcm_sw_params_sizeof SDL_NAME(snd_pcm_sw_params_sizeof) | 141 #define snd_pcm_sw_params_sizeof SDL_NAME(snd_pcm_sw_params_sizeof) |
144 | 142 |
145 /* cast funcs to char* first, to please GCC's strict aliasing rules. */ | 143 /* cast funcs to char* first, to please GCC's strict aliasing rules. */ |
146 static struct | 144 static struct |
147 { | 145 { |
148 const char *name; | 146 const char *name; |
149 void **func; | 147 void **func; |
150 } alsa_functions[] = { | 148 } alsa_functions[] = { |
151 { | 149 { |
152 "snd_pcm_open", (void **) (char *) &SDL_NAME (snd_pcm_open)}, { | 150 "snd_pcm_open", (void **) (char *) &SDL_NAME(snd_pcm_open)}, { |
153 "snd_pcm_close", (void **) (char *) &SDL_NAME (snd_pcm_close)}, { | 151 "snd_pcm_close", (void **) (char *) &SDL_NAME(snd_pcm_close)}, { |
154 "snd_pcm_writei", (void **) (char *) &SDL_NAME (snd_pcm_writei)}, { | 152 "snd_pcm_writei", (void **) (char *) &SDL_NAME(snd_pcm_writei)}, { |
155 "snd_pcm_resume", (void **) (char *) &SDL_NAME (snd_pcm_resume)}, { | 153 "snd_pcm_resume", (void **) (char *) &SDL_NAME(snd_pcm_resume)}, { |
156 "snd_pcm_prepare", (void **) (char *) &SDL_NAME (snd_pcm_prepare)}, { | 154 "snd_pcm_prepare", (void **) (char *) &SDL_NAME(snd_pcm_prepare)}, { |
157 "snd_pcm_drain", (void **) (char *) &SDL_NAME (snd_pcm_drain)}, { | 155 "snd_pcm_drain", (void **) (char *) &SDL_NAME(snd_pcm_drain)}, { |
158 "snd_strerror", (void **) (char *) &SDL_NAME (snd_strerror)}, { | 156 "snd_strerror", (void **) (char *) &SDL_NAME(snd_strerror)}, { |
159 "snd_pcm_hw_params_sizeof", | 157 "snd_pcm_hw_params_sizeof", |
160 (void **) (char *) &SDL_NAME (snd_pcm_hw_params_sizeof)}, { | 158 (void **) (char *) &SDL_NAME(snd_pcm_hw_params_sizeof)}, { |
161 "snd_pcm_sw_params_sizeof", | 159 "snd_pcm_sw_params_sizeof", |
162 (void **) (char *) &SDL_NAME (snd_pcm_sw_params_sizeof)}, { | 160 (void **) (char *) &SDL_NAME(snd_pcm_sw_params_sizeof)}, { |
163 "snd_pcm_hw_params_any", | 161 "snd_pcm_hw_params_any", |
164 (void **) (char *) &SDL_NAME (snd_pcm_hw_params_any)}, { | 162 (void **) (char *) &SDL_NAME(snd_pcm_hw_params_any)}, { |
165 "snd_pcm_hw_params_set_access", | 163 "snd_pcm_hw_params_set_access", |
166 (void **) (char *) &SDL_NAME (snd_pcm_hw_params_set_access)}, { | 164 (void **) (char *) &SDL_NAME(snd_pcm_hw_params_set_access)}, { |
167 "snd_pcm_hw_params_set_format", | 165 "snd_pcm_hw_params_set_format", |
168 (void **) (char *) &SDL_NAME (snd_pcm_hw_params_set_format)}, { | 166 (void **) (char *) &SDL_NAME(snd_pcm_hw_params_set_format)}, { |
169 "snd_pcm_hw_params_set_channels", | 167 "snd_pcm_hw_params_set_channels", |
170 (void **) (char *) &SDL_NAME (snd_pcm_hw_params_set_channels)}, { | 168 (void **) (char *) &SDL_NAME(snd_pcm_hw_params_set_channels)}, { |
171 "snd_pcm_hw_params_get_channels", | 169 "snd_pcm_hw_params_get_channels", |
172 (void **) (char *) &SDL_NAME (snd_pcm_hw_params_get_channels)}, { | 170 (void **) (char *) &SDL_NAME(snd_pcm_hw_params_get_channels)}, { |
173 "snd_pcm_hw_params_set_rate_near", | 171 "snd_pcm_hw_params_set_rate_near", |
174 (void **) (char *) &SDL_NAME (snd_pcm_hw_params_set_rate_near)}, { | 172 (void **) (char *) &SDL_NAME(snd_pcm_hw_params_set_rate_near)}, { |
175 "snd_pcm_hw_params_set_period_size_near", (void **) (char *) | 173 "snd_pcm_hw_params_set_period_size_near", (void **) (char *) |
176 &SDL_NAME (snd_pcm_hw_params_set_period_size_near)}, { | 174 &SDL_NAME(snd_pcm_hw_params_set_period_size_near)}, { |
177 "snd_pcm_hw_params_get_period_size", | 175 "snd_pcm_hw_params_get_period_size", |
178 (void **) (char *) &SDL_NAME (snd_pcm_hw_params_get_period_size)}, | 176 (void **) (char *) &SDL_NAME(snd_pcm_hw_params_get_period_size)}, |
179 { | 177 { |
180 "snd_pcm_hw_params_set_periods_near", (void **) (char *) | 178 "snd_pcm_hw_params_set_periods_near", (void **) (char *) |
181 &SDL_NAME (snd_pcm_hw_params_set_periods_near)}, { | 179 &SDL_NAME(snd_pcm_hw_params_set_periods_near)}, { |
182 "snd_pcm_hw_params_get_periods", | 180 "snd_pcm_hw_params_get_periods", |
183 (void **) (char *) &SDL_NAME (snd_pcm_hw_params_get_periods)}, { | 181 (void **) (char *) &SDL_NAME(snd_pcm_hw_params_get_periods)}, { |
184 "snd_pcm_hw_params", (void **) (char *) &SDL_NAME (snd_pcm_hw_params)}, { | 182 "snd_pcm_hw_params", (void **) (char *) &SDL_NAME(snd_pcm_hw_params)}, { |
185 "snd_pcm_sw_params_current", | 183 "snd_pcm_sw_params_current", |
186 (void **) (char *) &SDL_NAME (snd_pcm_sw_params_current)}, { | 184 (void **) (char *) &SDL_NAME(snd_pcm_sw_params_current)}, { |
187 "snd_pcm_sw_params_set_start_threshold", (void **) (char *) | 185 "snd_pcm_sw_params_set_start_threshold", (void **) (char *) |
188 &SDL_NAME (snd_pcm_sw_params_set_start_threshold)}, { | 186 &SDL_NAME(snd_pcm_sw_params_set_start_threshold)}, { |
189 "snd_pcm_sw_params_set_avail_min", | 187 "snd_pcm_sw_params_set_avail_min", |
190 (void **) (char *) &SDL_NAME (snd_pcm_sw_params_set_avail_min)}, { | 188 (void **) (char *) &SDL_NAME(snd_pcm_sw_params_set_avail_min)}, { |
191 "snd_pcm_sw_params", (void **) (char *) &SDL_NAME (snd_pcm_sw_params)}, { | 189 "snd_pcm_sw_params", (void **) (char *) &SDL_NAME(snd_pcm_sw_params)}, { |
192 "snd_pcm_nonblock", (void **) (char *) &SDL_NAME (snd_pcm_nonblock)},}; | 190 "snd_pcm_nonblock", (void **) (char *) &SDL_NAME(snd_pcm_nonblock)},}; |
193 | 191 |
194 static void | 192 static void |
195 UnloadALSALibrary (void) | 193 UnloadALSALibrary(void) |
196 { | 194 { |
197 if (alsa_loaded) { | 195 if (alsa_loaded) { |
198 /* SDL_UnloadObject(alsa_handle);*/ | 196 /* SDL_UnloadObject(alsa_handle);*/ |
199 dlclose (alsa_handle); | 197 dlclose(alsa_handle); |
200 alsa_handle = NULL; | 198 alsa_handle = NULL; |
201 alsa_loaded = 0; | 199 alsa_loaded = 0; |
202 } | 200 } |
203 } | 201 } |
204 | 202 |
205 static int | 203 static int |
206 LoadALSALibrary (void) | 204 LoadALSALibrary(void) |
207 { | 205 { |
208 int i, retval = -1; | 206 int i, retval = -1; |
209 | 207 |
210 /* alsa_handle = SDL_LoadObject(alsa_library);*/ | 208 /* alsa_handle = SDL_LoadObject(alsa_library);*/ |
211 alsa_handle = dlopen (alsa_library, RTLD_NOW); | 209 alsa_handle = dlopen(alsa_library, RTLD_NOW); |
212 if (alsa_handle) { | 210 if (alsa_handle) { |
213 alsa_loaded = 1; | 211 alsa_loaded = 1; |
214 retval = 0; | 212 retval = 0; |
215 for (i = 0; i < SDL_arraysize (alsa_functions); i++) { | 213 for (i = 0; i < SDL_arraysize(alsa_functions); i++) { |
216 /* *alsa_functions[i].func = SDL_LoadFunction(alsa_handle,alsa_functions[i].name);*/ | 214 /* *alsa_functions[i].func = SDL_LoadFunction(alsa_handle,alsa_functions[i].name);*/ |
217 #if HAVE_DLVSYM | 215 #if HAVE_DLVSYM |
218 *alsa_functions[i].func = | 216 *alsa_functions[i].func = |
219 dlvsym (alsa_handle, alsa_functions[i].name, "ALSA_0.9"); | 217 dlvsym(alsa_handle, alsa_functions[i].name, "ALSA_0.9"); |
220 if (!*alsa_functions[i].func) | 218 if (!*alsa_functions[i].func) |
221 #endif | 219 #endif |
222 *alsa_functions[i].func = | 220 *alsa_functions[i].func = |
223 dlsym (alsa_handle, alsa_functions[i].name); | 221 dlsym(alsa_handle, alsa_functions[i].name); |
224 if (!*alsa_functions[i].func) { | 222 if (!*alsa_functions[i].func) { |
225 retval = -1; | 223 retval = -1; |
226 UnloadALSALibrary (); | 224 UnloadALSALibrary(); |
227 break; | 225 break; |
228 } | 226 } |
229 } | 227 } |
230 } | 228 } |
231 return retval; | 229 return retval; |
232 } | 230 } |
233 | 231 |
234 #else | 232 #else |
235 | 233 |
236 static void | 234 static void |
237 UnloadALSALibrary (void) | 235 UnloadALSALibrary(void) |
238 { | 236 { |
239 return; | 237 return; |
240 } | 238 } |
241 | 239 |
242 static int | 240 static int |
243 LoadALSALibrary (void) | 241 LoadALSALibrary(void) |
244 { | 242 { |
245 return 0; | 243 return 0; |
246 } | 244 } |
247 | 245 |
248 #endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */ | 246 #endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */ |
249 | 247 |
250 static const char * | 248 static const char * |
251 get_audio_device (int channels) | 249 get_audio_device(int channels) |
252 { | 250 { |
253 const char *device; | 251 const char *device; |
254 | 252 |
255 device = SDL_getenv ("AUDIODEV"); /* Is there a standard variable name? */ | 253 device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */ |
256 if (device == NULL) { | 254 if (device == NULL) { |
257 if (channels == 6) | 255 if (channels == 6) |
258 device = "surround51"; | 256 device = "surround51"; |
259 else if (channels == 4) | 257 else if (channels == 4) |
260 device = "surround40"; | 258 device = "surround40"; |
265 } | 263 } |
266 | 264 |
267 /* Audio driver bootstrap functions */ | 265 /* Audio driver bootstrap functions */ |
268 | 266 |
269 static int | 267 static int |
270 Audio_Available (void) | 268 Audio_Available(void) |
271 { | 269 { |
272 int available; | 270 int available; |
273 int status; | 271 int status; |
274 snd_pcm_t *handle; | 272 snd_pcm_t *handle; |
275 | 273 |
276 available = 0; | 274 available = 0; |
277 if (LoadALSALibrary () < 0) { | 275 if (LoadALSALibrary() < 0) { |
278 return available; | 276 return available; |
279 } | 277 } |
280 status = | 278 status = |
281 SDL_NAME (snd_pcm_open) (&handle, get_audio_device (2), | 279 SDL_NAME(snd_pcm_open) (&handle, get_audio_device(2), |
282 SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); | 280 SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); |
283 if (status >= 0) { | 281 if (status >= 0) { |
284 available = 1; | 282 available = 1; |
285 SDL_NAME (snd_pcm_close) (handle); | 283 SDL_NAME(snd_pcm_close) (handle); |
286 } | 284 } |
287 UnloadALSALibrary (); | 285 UnloadALSALibrary(); |
288 return (available); | 286 return (available); |
289 } | 287 } |
290 | 288 |
291 static void | 289 static void |
292 Audio_DeleteDevice (SDL_AudioDevice * device) | 290 Audio_DeleteDevice(SDL_AudioDevice * device) |
293 { | 291 { |
294 SDL_free (device->hidden); | 292 SDL_free(device->hidden); |
295 SDL_free (device); | 293 SDL_free(device); |
296 UnloadALSALibrary (); | 294 UnloadALSALibrary(); |
297 } | 295 } |
298 | 296 |
299 static SDL_AudioDevice * | 297 static SDL_AudioDevice * |
300 Audio_CreateDevice (int devindex) | 298 Audio_CreateDevice(int devindex) |
301 { | 299 { |
302 SDL_AudioDevice *this; | 300 SDL_AudioDevice *this; |
303 | 301 |
304 /* Initialize all variables that we clean on shutdown */ | 302 /* Initialize all variables that we clean on shutdown */ |
305 LoadALSALibrary (); | 303 LoadALSALibrary(); |
306 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice)); | 304 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice)); |
307 if (this) { | 305 if (this) { |
308 SDL_memset (this, 0, (sizeof *this)); | 306 SDL_memset(this, 0, (sizeof *this)); |
309 this->hidden = (struct SDL_PrivateAudioData *) | 307 this->hidden = (struct SDL_PrivateAudioData *) |
310 SDL_malloc ((sizeof *this->hidden)); | 308 SDL_malloc((sizeof *this->hidden)); |
311 } | 309 } |
312 if ((this == NULL) || (this->hidden == NULL)) { | 310 if ((this == NULL) || (this->hidden == NULL)) { |
313 SDL_OutOfMemory (); | 311 SDL_OutOfMemory(); |
314 if (this) { | 312 if (this) { |
315 SDL_free (this); | 313 SDL_free(this); |
316 } | 314 } |
317 return (0); | 315 return (0); |
318 } | 316 } |
319 SDL_memset (this->hidden, 0, (sizeof *this->hidden)); | 317 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); |
320 | 318 |
321 /* Set the function pointers */ | 319 /* Set the function pointers */ |
322 this->OpenAudio = ALSA_OpenAudio; | 320 this->OpenAudio = ALSA_OpenAudio; |
323 this->WaitAudio = ALSA_WaitAudio; | 321 this->WaitAudio = ALSA_WaitAudio; |
324 this->PlayAudio = ALSA_PlayAudio; | 322 this->PlayAudio = ALSA_PlayAudio; |
335 Audio_Available, Audio_CreateDevice | 333 Audio_Available, Audio_CreateDevice |
336 }; | 334 }; |
337 | 335 |
338 /* This function waits until it is possible to write a full sound buffer */ | 336 /* This function waits until it is possible to write a full sound buffer */ |
339 static void | 337 static void |
340 ALSA_WaitAudio (_THIS) | 338 ALSA_WaitAudio(_THIS) |
341 { | 339 { |
342 /* Check to see if the thread-parent process is still alive */ | 340 /* Check to see if the thread-parent process is still alive */ |
343 { | 341 { |
344 static int cnt = 0; | 342 static int cnt = 0; |
345 /* Note that this only works with thread implementations | 343 /* Note that this only works with thread implementations |
346 that use a different process id for each thread. | 344 that use a different process id for each thread. |
347 */ | 345 */ |
348 if (parent && (((++cnt) % 10) == 0)) { /* Check every 10 loops */ | 346 if (parent && (((++cnt) % 10) == 0)) { /* Check every 10 loops */ |
349 if (kill (parent, 0) < 0) { | 347 if (kill(parent, 0) < 0) { |
350 this->enabled = 0; | 348 this->enabled = 0; |
351 } | 349 } |
352 } | 350 } |
353 } | 351 } |
354 } | 352 } |
355 | 353 |
356 static void | 354 static void |
357 ALSA_PlayAudio (_THIS) | 355 ALSA_PlayAudio(_THIS) |
358 { | 356 { |
359 int status; | 357 int status; |
360 int sample_len; | 358 int sample_len; |
361 signed short *sample_buf; | 359 signed short *sample_buf; |
362 | 360 |
363 sample_len = this->spec.samples; | 361 sample_len = this->spec.samples; |
364 sample_buf = (signed short *) mixbuf; | 362 sample_buf = (signed short *) mixbuf; |
365 while (sample_len > 0) { | 363 while (sample_len > 0) { |
366 status = | 364 status = |
367 SDL_NAME (snd_pcm_writei) (pcm_handle, sample_buf, sample_len); | 365 SDL_NAME(snd_pcm_writei) (pcm_handle, sample_buf, sample_len); |
368 if (status < 0) { | 366 if (status < 0) { |
369 if (status == -EAGAIN) { | 367 if (status == -EAGAIN) { |
370 SDL_Delay (1); | 368 SDL_Delay(1); |
371 continue; | 369 continue; |
372 } | 370 } |
373 if (status == -ESTRPIPE) { | 371 if (status == -ESTRPIPE) { |
374 do { | 372 do { |
375 SDL_Delay (1); | 373 SDL_Delay(1); |
376 status = SDL_NAME (snd_pcm_resume) (pcm_handle); | 374 status = SDL_NAME(snd_pcm_resume) (pcm_handle); |
377 } | 375 } |
378 while (status == -EAGAIN); | 376 while (status == -EAGAIN); |
379 } | 377 } |
380 if (status < 0) { | 378 if (status < 0) { |
381 status = SDL_NAME (snd_pcm_prepare) (pcm_handle); | 379 status = SDL_NAME(snd_pcm_prepare) (pcm_handle); |
382 } | 380 } |
383 if (status < 0) { | 381 if (status < 0) { |
384 /* Hmm, not much we can do - abort */ | 382 /* Hmm, not much we can do - abort */ |
385 this->enabled = 0; | 383 this->enabled = 0; |
386 return; | 384 return; |
391 sample_len -= status; | 389 sample_len -= status; |
392 } | 390 } |
393 } | 391 } |
394 | 392 |
395 static Uint8 * | 393 static Uint8 * |
396 ALSA_GetAudioBuf (_THIS) | 394 ALSA_GetAudioBuf(_THIS) |
397 { | 395 { |
398 return (mixbuf); | 396 return (mixbuf); |
399 } | 397 } |
400 | 398 |
401 static void | 399 static void |
402 ALSA_CloseAudio (_THIS) | 400 ALSA_CloseAudio(_THIS) |
403 { | 401 { |
404 if (mixbuf != NULL) { | 402 if (mixbuf != NULL) { |
405 SDL_FreeAudioMem (mixbuf); | 403 SDL_FreeAudioMem(mixbuf); |
406 mixbuf = NULL; | 404 mixbuf = NULL; |
407 } | 405 } |
408 if (pcm_handle) { | 406 if (pcm_handle) { |
409 SDL_NAME (snd_pcm_drain) (pcm_handle); | 407 SDL_NAME(snd_pcm_drain) (pcm_handle); |
410 SDL_NAME (snd_pcm_close) (pcm_handle); | 408 SDL_NAME(snd_pcm_close) (pcm_handle); |
411 pcm_handle = NULL; | 409 pcm_handle = NULL; |
412 } | 410 } |
413 } | 411 } |
414 | 412 |
415 static int | 413 static int |
416 ALSA_OpenAudio (_THIS, SDL_AudioSpec * spec) | 414 ALSA_OpenAudio(_THIS, SDL_AudioSpec * spec) |
417 { | 415 { |
418 int status; | 416 int status; |
419 snd_pcm_hw_params_t *hwparams; | 417 snd_pcm_hw_params_t *hwparams; |
420 snd_pcm_sw_params_t *swparams; | 418 snd_pcm_sw_params_t *swparams; |
421 snd_pcm_format_t format; | 419 snd_pcm_format_t format; |
423 Uint16 test_format; | 421 Uint16 test_format; |
424 | 422 |
425 /* Open the audio device */ | 423 /* Open the audio device */ |
426 /* Name of device should depend on # channels in spec */ | 424 /* Name of device should depend on # channels in spec */ |
427 status = | 425 status = |
428 SDL_NAME (snd_pcm_open) (&pcm_handle, | 426 SDL_NAME(snd_pcm_open) (&pcm_handle, |
429 get_audio_device (spec->channels), | 427 get_audio_device(spec->channels), |
430 SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); | 428 SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); |
431 | 429 |
432 if (status < 0) { | 430 if (status < 0) { |
433 SDL_SetError ("Couldn't open audio device: %s", | 431 SDL_SetError("Couldn't open audio device: %s", |
434 SDL_NAME (snd_strerror) (status)); | 432 SDL_NAME(snd_strerror) (status)); |
435 return (-1); | 433 return (-1); |
436 } | 434 } |
437 | 435 |
438 /* Figure out what the hardware is capable of */ | 436 /* Figure out what the hardware is capable of */ |
439 snd_pcm_hw_params_alloca (&hwparams); | 437 snd_pcm_hw_params_alloca(&hwparams); |
440 status = SDL_NAME (snd_pcm_hw_params_any) (pcm_handle, hwparams); | 438 status = SDL_NAME(snd_pcm_hw_params_any) (pcm_handle, hwparams); |
441 if (status < 0) { | 439 if (status < 0) { |
442 SDL_SetError ("Couldn't get hardware config: %s", | 440 SDL_SetError("Couldn't get hardware config: %s", |
443 SDL_NAME (snd_strerror) (status)); | 441 SDL_NAME(snd_strerror) (status)); |
444 ALSA_CloseAudio (this); | 442 ALSA_CloseAudio(this); |
445 return (-1); | 443 return (-1); |
446 } | 444 } |
447 | 445 |
448 /* SDL only uses interleaved sample output */ | 446 /* SDL only uses interleaved sample output */ |
449 status = | 447 status = |
450 SDL_NAME (snd_pcm_hw_params_set_access) (pcm_handle, hwparams, | 448 SDL_NAME(snd_pcm_hw_params_set_access) (pcm_handle, hwparams, |
451 SND_PCM_ACCESS_RW_INTERLEAVED); | 449 SND_PCM_ACCESS_RW_INTERLEAVED); |
452 if (status < 0) { | 450 if (status < 0) { |
453 SDL_SetError ("Couldn't set interleaved access: %s", | 451 SDL_SetError("Couldn't set interleaved access: %s", |
454 SDL_NAME (snd_strerror) (status)); | 452 SDL_NAME(snd_strerror) (status)); |
455 ALSA_CloseAudio (this); | 453 ALSA_CloseAudio(this); |
456 return (-1); | 454 return (-1); |
457 } | 455 } |
458 | 456 |
459 /* Try for a closest match on audio format */ | 457 /* Try for a closest match on audio format */ |
460 status = -1; | 458 status = -1; |
461 for (test_format = SDL_FirstAudioFormat (spec->format); | 459 for (test_format = SDL_FirstAudioFormat(spec->format); |
462 test_format && (status < 0);) { | 460 test_format && (status < 0);) { |
463 switch (test_format) { | 461 switch (test_format) { |
464 case AUDIO_U8: | 462 case AUDIO_U8: |
465 format = SND_PCM_FORMAT_U8; | 463 format = SND_PCM_FORMAT_U8; |
466 break; | 464 break; |
483 format = 0; | 481 format = 0; |
484 break; | 482 break; |
485 } | 483 } |
486 if (format != 0) { | 484 if (format != 0) { |
487 status = | 485 status = |
488 SDL_NAME (snd_pcm_hw_params_set_format) (pcm_handle, | 486 SDL_NAME(snd_pcm_hw_params_set_format) (pcm_handle, |
489 hwparams, format); | 487 hwparams, format); |
490 } | 488 } |
491 if (status < 0) { | 489 if (status < 0) { |
492 test_format = SDL_NextAudioFormat (); | 490 test_format = SDL_NextAudioFormat(); |
493 } | 491 } |
494 } | 492 } |
495 if (status < 0) { | 493 if (status < 0) { |
496 SDL_SetError ("Couldn't find any hardware audio formats"); | 494 SDL_SetError("Couldn't find any hardware audio formats"); |
497 ALSA_CloseAudio (this); | 495 ALSA_CloseAudio(this); |
498 return (-1); | 496 return (-1); |
499 } | 497 } |
500 spec->format = test_format; | 498 spec->format = test_format; |
501 | 499 |
502 /* Set the number of channels */ | 500 /* Set the number of channels */ |
503 status = | 501 status = |
504 SDL_NAME (snd_pcm_hw_params_set_channels) (pcm_handle, hwparams, | 502 SDL_NAME(snd_pcm_hw_params_set_channels) (pcm_handle, hwparams, |
505 spec->channels); | 503 spec->channels); |
506 if (status < 0) { | 504 if (status < 0) { |
507 status = SDL_NAME (snd_pcm_hw_params_get_channels) (hwparams); | 505 status = SDL_NAME(snd_pcm_hw_params_get_channels) (hwparams); |
508 if ((status <= 0) || (status > 2)) { | 506 if ((status <= 0) || (status > 2)) { |
509 SDL_SetError ("Couldn't set audio channels"); | 507 SDL_SetError("Couldn't set audio channels"); |
510 ALSA_CloseAudio (this); | 508 ALSA_CloseAudio(this); |
511 return (-1); | 509 return (-1); |
512 } | 510 } |
513 spec->channels = status; | 511 spec->channels = status; |
514 } | 512 } |
515 | 513 |
516 /* Set the audio rate */ | 514 /* Set the audio rate */ |
517 status = | 515 status = |
518 SDL_NAME (snd_pcm_hw_params_set_rate_near) (pcm_handle, hwparams, | 516 SDL_NAME(snd_pcm_hw_params_set_rate_near) (pcm_handle, hwparams, |
519 spec->freq, NULL); | 517 spec->freq, NULL); |
520 if (status < 0) { | 518 if (status < 0) { |
521 SDL_SetError ("Couldn't set audio frequency: %s", | 519 SDL_SetError("Couldn't set audio frequency: %s", |
522 SDL_NAME (snd_strerror) (status)); | 520 SDL_NAME(snd_strerror) (status)); |
523 ALSA_CloseAudio (this); | 521 ALSA_CloseAudio(this); |
524 return (-1); | 522 return (-1); |
525 } | 523 } |
526 spec->freq = status; | 524 spec->freq = status; |
527 | 525 |
528 /* Set the buffer size, in samples */ | 526 /* Set the buffer size, in samples */ |
529 frames = spec->samples; | 527 frames = spec->samples; |
530 frames = | 528 frames = |
531 SDL_NAME (snd_pcm_hw_params_set_period_size_near) (pcm_handle, | 529 SDL_NAME(snd_pcm_hw_params_set_period_size_near) (pcm_handle, |
532 hwparams, frames, | 530 hwparams, frames, |
533 NULL); | 531 NULL); |
534 spec->samples = frames; | 532 spec->samples = frames; |
535 SDL_NAME (snd_pcm_hw_params_set_periods_near) (pcm_handle, hwparams, 2, | 533 SDL_NAME(snd_pcm_hw_params_set_periods_near) (pcm_handle, hwparams, 2, |
536 NULL); | 534 NULL); |
537 | 535 |
538 /* "set" the hardware with the desired parameters */ | 536 /* "set" the hardware with the desired parameters */ |
539 status = SDL_NAME (snd_pcm_hw_params) (pcm_handle, hwparams); | 537 status = SDL_NAME(snd_pcm_hw_params) (pcm_handle, hwparams); |
540 if (status < 0) { | 538 if (status < 0) { |
541 SDL_SetError ("Couldn't set hardware audio parameters: %s", | 539 SDL_SetError("Couldn't set hardware audio parameters: %s", |
542 SDL_NAME (snd_strerror) (status)); | 540 SDL_NAME(snd_strerror) (status)); |
543 ALSA_CloseAudio (this); | 541 ALSA_CloseAudio(this); |
544 return (-1); | 542 return (-1); |
545 } | 543 } |
546 | 544 |
547 /* This is useful for debugging... */ | 545 /* This is useful for debugging... */ |
548 /* | 546 /* |
553 fprintf(stderr, "ALSA: bufsize = %ld, fragments = %d\n", bufsize, fragments); | 551 fprintf(stderr, "ALSA: bufsize = %ld, fragments = %d\n", bufsize, fragments); |
554 } | 552 } |
555 */ | 553 */ |
556 | 554 |
557 /* Set the software parameters */ | 555 /* Set the software parameters */ |
558 snd_pcm_sw_params_alloca (&swparams); | 556 snd_pcm_sw_params_alloca(&swparams); |
559 status = SDL_NAME (snd_pcm_sw_params_current) (pcm_handle, swparams); | 557 status = SDL_NAME(snd_pcm_sw_params_current) (pcm_handle, swparams); |
560 if (status < 0) { | 558 if (status < 0) { |
561 SDL_SetError ("Couldn't get software config: %s", | 559 SDL_SetError("Couldn't get software config: %s", |
562 SDL_NAME (snd_strerror) (status)); | 560 SDL_NAME(snd_strerror) (status)); |
563 ALSA_CloseAudio (this); | 561 ALSA_CloseAudio(this); |
564 return (-1); | 562 return (-1); |
565 } | 563 } |
566 status = | 564 status = |
567 SDL_NAME (snd_pcm_sw_params_set_start_threshold) (pcm_handle, | 565 SDL_NAME(snd_pcm_sw_params_set_start_threshold) (pcm_handle, |
568 swparams, 0); | 566 swparams, 0); |
569 if (status < 0) { | 567 if (status < 0) { |
570 SDL_SetError ("Couldn't set start threshold: %s", | 568 SDL_SetError("Couldn't set start threshold: %s", |
571 SDL_NAME (snd_strerror) (status)); | 569 SDL_NAME(snd_strerror) (status)); |
572 ALSA_CloseAudio (this); | 570 ALSA_CloseAudio(this); |
573 return (-1); | 571 return (-1); |
574 } | 572 } |
575 status = | 573 status = |
576 SDL_NAME (snd_pcm_sw_params_set_avail_min) (pcm_handle, swparams, | 574 SDL_NAME(snd_pcm_sw_params_set_avail_min) (pcm_handle, swparams, |
577 frames); | 575 frames); |
578 if (status < 0) { | 576 if (status < 0) { |
579 SDL_SetError ("Couldn't set avail min: %s", | 577 SDL_SetError("Couldn't set avail min: %s", |
580 SDL_NAME (snd_strerror) (status)); | 578 SDL_NAME(snd_strerror) (status)); |
581 ALSA_CloseAudio (this); | 579 ALSA_CloseAudio(this); |
582 return (-1); | 580 return (-1); |
583 } | 581 } |
584 status = SDL_NAME (snd_pcm_sw_params) (pcm_handle, swparams); | 582 status = SDL_NAME(snd_pcm_sw_params) (pcm_handle, swparams); |
585 if (status < 0) { | 583 if (status < 0) { |
586 SDL_SetError ("Couldn't set software audio parameters: %s", | 584 SDL_SetError("Couldn't set software audio parameters: %s", |
587 SDL_NAME (snd_strerror) (status)); | 585 SDL_NAME(snd_strerror) (status)); |
588 ALSA_CloseAudio (this); | 586 ALSA_CloseAudio(this); |
589 return (-1); | 587 return (-1); |
590 } | 588 } |
591 | 589 |
592 /* Calculate the final parameters for this audio specification */ | 590 /* Calculate the final parameters for this audio specification */ |
593 SDL_CalculateAudioSpec (spec); | 591 SDL_CalculateAudioSpec(spec); |
594 | 592 |
595 /* Allocate mixing buffer */ | 593 /* Allocate mixing buffer */ |
596 mixlen = spec->size; | 594 mixlen = spec->size; |
597 mixbuf = (Uint8 *) SDL_AllocAudioMem (mixlen); | 595 mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen); |
598 if (mixbuf == NULL) { | 596 if (mixbuf == NULL) { |
599 ALSA_CloseAudio (this); | 597 ALSA_CloseAudio(this); |
600 return (-1); | 598 return (-1); |
601 } | 599 } |
602 SDL_memset (mixbuf, spec->silence, spec->size); | 600 SDL_memset(mixbuf, spec->silence, spec->size); |
603 | 601 |
604 /* Get the parent process id (we're the parent of the audio thread) */ | 602 /* Get the parent process id (we're the parent of the audio thread) */ |
605 parent = getpid (); | 603 parent = getpid(); |
606 | 604 |
607 /* Switch to blocking mode for playback */ | 605 /* Switch to blocking mode for playback */ |
608 SDL_NAME (snd_pcm_nonblock) (pcm_handle, 0); | 606 SDL_NAME(snd_pcm_nonblock) (pcm_handle, 0); |
609 | 607 |
610 /* We're ready to rock and roll. :-) */ | 608 /* We're ready to rock and roll. :-) */ |
611 return (0); | 609 return (0); |
612 } | 610 } |
613 | 611 |