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