comparison src/audio/dma/SDL_dmaaudio.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents d910939febfa
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
22 #include "SDL_config.h" 22 #include "SDL_config.h"
23 23
24 /* Allow access to a raw mixing buffer */ 24 /* Allow access to a raw mixing buffer */
25 25
26 #include <stdio.h> 26 #include <stdio.h>
27 #include <string.h> /* For strerror() */ 27 #include <string.h> /* For strerror() */
28 #include <errno.h> 28 #include <errno.h>
29 #include <unistd.h> 29 #include <unistd.h>
30 #include <fcntl.h> 30 #include <fcntl.h>
31 #include <signal.h> 31 #include <signal.h>
32 #include <sys/types.h> 32 #include <sys/types.h>
58 58
59 /* Open the audio device for playback, and don't block if busy */ 59 /* Open the audio device for playback, and don't block if busy */
60 #define OPEN_FLAGS (O_RDWR|O_NONBLOCK) 60 #define OPEN_FLAGS (O_RDWR|O_NONBLOCK)
61 61
62 /* Audio driver functions */ 62 /* Audio driver functions */
63 static int DMA_OpenAudio(_THIS, SDL_AudioSpec *spec); 63 static int DMA_OpenAudio (_THIS, SDL_AudioSpec * spec);
64 static void DMA_WaitAudio(_THIS); 64 static void DMA_WaitAudio (_THIS);
65 static void DMA_PlayAudio(_THIS); 65 static void DMA_PlayAudio (_THIS);
66 static Uint8 *DMA_GetAudioBuf(_THIS); 66 static Uint8 *DMA_GetAudioBuf (_THIS);
67 static void DMA_CloseAudio(_THIS); 67 static void DMA_CloseAudio (_THIS);
68 68
69 /* Audio driver bootstrap functions */ 69 /* Audio driver bootstrap functions */
70 70
71 static int Audio_Available(void) 71 static int
72 { 72 Audio_Available (void)
73 int available; 73 {
74 int fd; 74 int available;
75 75 int fd;
76 available = 0; 76
77 77 available = 0;
78 fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); 78
79 if ( fd >= 0 ) { 79 fd = SDL_OpenAudioPath (NULL, 0, OPEN_FLAGS, 0);
80 int caps; 80 if (fd >= 0) {
81 struct audio_buf_info info; 81 int caps;
82 82 struct audio_buf_info info;
83 if ( (ioctl(fd, SNDCTL_DSP_GETCAPS, &caps) == 0) && 83
84 (caps & DSP_CAP_TRIGGER) && (caps & DSP_CAP_MMAP) && 84 if ((ioctl (fd, SNDCTL_DSP_GETCAPS, &caps) == 0) &&
85 (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) == 0) ) { 85 (caps & DSP_CAP_TRIGGER) && (caps & DSP_CAP_MMAP) &&
86 available = 1; 86 (ioctl (fd, SNDCTL_DSP_GETOSPACE, &info) == 0)) {
87 } 87 available = 1;
88 close(fd); 88 }
89 } 89 close (fd);
90 return(available); 90 }
91 } 91 return (available);
92 92 }
93 static void Audio_DeleteDevice(SDL_AudioDevice *device) 93
94 { 94 static void
95 SDL_free(device->hidden); 95 Audio_DeleteDevice (SDL_AudioDevice * device)
96 SDL_free(device); 96 {
97 } 97 SDL_free (device->hidden);
98 98 SDL_free (device);
99 static SDL_AudioDevice *Audio_CreateDevice(int devindex) 99 }
100 { 100
101 SDL_AudioDevice *this; 101 static SDL_AudioDevice *
102 102 Audio_CreateDevice (int devindex)
103 /* Initialize all variables that we clean on shutdown */ 103 {
104 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); 104 SDL_AudioDevice *this;
105 if ( this ) { 105
106 SDL_memset(this, 0, (sizeof *this)); 106 /* Initialize all variables that we clean on shutdown */
107 this->hidden = (struct SDL_PrivateAudioData *) 107 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice));
108 SDL_malloc((sizeof *this->hidden)); 108 if (this) {
109 } 109 SDL_memset (this, 0, (sizeof *this));
110 if ( (this == NULL) || (this->hidden == NULL) ) { 110 this->hidden = (struct SDL_PrivateAudioData *)
111 SDL_OutOfMemory(); 111 SDL_malloc ((sizeof *this->hidden));
112 if ( this ) { 112 }
113 SDL_free(this); 113 if ((this == NULL) || (this->hidden == NULL)) {
114 } 114 SDL_OutOfMemory ();
115 return(0); 115 if (this) {
116 } 116 SDL_free (this);
117 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 117 }
118 audio_fd = -1; 118 return (0);
119 119 }
120 /* Set the function pointers */ 120 SDL_memset (this->hidden, 0, (sizeof *this->hidden));
121 this->OpenAudio = DMA_OpenAudio; 121 audio_fd = -1;
122 this->WaitAudio = DMA_WaitAudio; 122
123 this->PlayAudio = DMA_PlayAudio; 123 /* Set the function pointers */
124 this->GetAudioBuf = DMA_GetAudioBuf; 124 this->OpenAudio = DMA_OpenAudio;
125 this->CloseAudio = DMA_CloseAudio; 125 this->WaitAudio = DMA_WaitAudio;
126 126 this->PlayAudio = DMA_PlayAudio;
127 this->free = Audio_DeleteDevice; 127 this->GetAudioBuf = DMA_GetAudioBuf;
128 128 this->CloseAudio = DMA_CloseAudio;
129 return this; 129
130 this->free = Audio_DeleteDevice;
131
132 return this;
130 } 133 }
131 134
132 AudioBootStrap DMA_bootstrap = { 135 AudioBootStrap DMA_bootstrap = {
133 DMA_DRIVER_NAME, "OSS /dev/dsp DMA audio", 136 DMA_DRIVER_NAME, "OSS /dev/dsp DMA audio",
134 Audio_Available, Audio_CreateDevice 137 Audio_Available, Audio_CreateDevice
135 }; 138 };
136 139
137 /* This function waits until it is possible to write a full sound buffer */ 140 /* This function waits until it is possible to write a full sound buffer */
138 static void DMA_WaitAudio(_THIS) 141 static void
139 { 142 DMA_WaitAudio (_THIS)
140 fd_set fdset; 143 {
141 144 fd_set fdset;
142 /* Check to see if the thread-parent process is still alive */ 145
143 { static int cnt = 0; 146 /* Check to see if the thread-parent process is still alive */
144 /* Note that this only works with thread implementations 147 {
145 that use a different process id for each thread. 148 static int cnt = 0;
146 */ 149 /* Note that this only works with thread implementations
147 if (parent && (((++cnt)%10) == 0)) { /* Check every 10 loops */ 150 that use a different process id for each thread.
148 if ( kill(parent, 0) < 0 ) { 151 */
149 this->enabled = 0; 152 if (parent && (((++cnt) % 10) == 0)) { /* Check every 10 loops */
150 } 153 if (kill (parent, 0) < 0) {
151 } 154 this->enabled = 0;
152 } 155 }
153 156 }
154 /* See if we need to use timed audio synchronization */ 157 }
155 if ( frame_ticks ) { 158
156 /* Use timer for general audio synchronization */ 159 /* See if we need to use timed audio synchronization */
157 Sint32 ticks; 160 if (frame_ticks) {
158 161 /* Use timer for general audio synchronization */
159 ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS; 162 Sint32 ticks;
160 if ( ticks > 0 ) { 163
161 SDL_Delay(ticks); 164 ticks = ((Sint32) (next_frame - SDL_GetTicks ())) - FUDGE_TICKS;
162 } 165 if (ticks > 0) {
163 } else { 166 SDL_Delay (ticks);
164 /* Use select() for audio synchronization */ 167 }
165 struct timeval timeout; 168 } else {
166 FD_ZERO(&fdset); 169 /* Use select() for audio synchronization */
167 FD_SET(audio_fd, &fdset); 170 struct timeval timeout;
168 timeout.tv_sec = 10; 171 FD_ZERO (&fdset);
169 timeout.tv_usec = 0; 172 FD_SET (audio_fd, &fdset);
173 timeout.tv_sec = 10;
174 timeout.tv_usec = 0;
170 #ifdef DEBUG_AUDIO 175 #ifdef DEBUG_AUDIO
171 fprintf(stderr, "Waiting for audio to get ready\n"); 176 fprintf (stderr, "Waiting for audio to get ready\n");
172 #endif 177 #endif
173 if ( select(audio_fd+1, NULL, &fdset, NULL, &timeout) <= 0 ) { 178 if (select (audio_fd + 1, NULL, &fdset, NULL, &timeout) <= 0) {
174 const char *message = 179 const char *message =
175 #ifdef AUDIO_OSPACE_HACK 180 #ifdef AUDIO_OSPACE_HACK
176 "Audio timeout - buggy audio driver? (trying ospace)"; 181 "Audio timeout - buggy audio driver? (trying ospace)";
177 #else 182 #else
178 "Audio timeout - buggy audio driver? (disabled)"; 183 "Audio timeout - buggy audio driver? (disabled)";
179 #endif 184 #endif
180 /* In general we should never print to the screen, 185 /* In general we should never print to the screen,
181 but in this case we have no other way of letting 186 but in this case we have no other way of letting
182 the user know what happened. 187 the user know what happened.
183 */ 188 */
184 fprintf(stderr, "SDL: %s\n", message); 189 fprintf (stderr, "SDL: %s\n", message);
185 #ifdef AUDIO_OSPACE_HACK 190 #ifdef AUDIO_OSPACE_HACK
186 /* We may be able to use GET_OSPACE trick */ 191 /* We may be able to use GET_OSPACE trick */
187 frame_ticks = (float)(this->spec->samples*1000) / 192 frame_ticks = (float) (this->spec->samples * 1000) /
188 this->spec->freq; 193 this->spec->freq;
189 next_frame = SDL_GetTicks()+frame_ticks; 194 next_frame = SDL_GetTicks () + frame_ticks;
190 #else 195 #else
191 this->enabled = 0; 196 this->enabled = 0;
192 /* Don't try to close - may hang */ 197 /* Don't try to close - may hang */
193 audio_fd = -1; 198 audio_fd = -1;
194 #ifdef DEBUG_AUDIO 199 #ifdef DEBUG_AUDIO
195 fprintf(stderr, "Done disabling audio\n"); 200 fprintf (stderr, "Done disabling audio\n");
196 #endif 201 #endif
197 #endif /* AUDIO_OSPACE_HACK */ 202 #endif /* AUDIO_OSPACE_HACK */
198 } 203 }
199 #ifdef DEBUG_AUDIO 204 #ifdef DEBUG_AUDIO
200 fprintf(stderr, "Ready!\n"); 205 fprintf (stderr, "Ready!\n");
201 #endif 206 #endif
202 } 207 }
203 } 208 }
204 209
205 static void DMA_PlayAudio(_THIS) 210 static void
206 { 211 DMA_PlayAudio (_THIS)
207 /* If timer synchronization is enabled, set the next write frame */ 212 {
208 if ( frame_ticks ) { 213 /* If timer synchronization is enabled, set the next write frame */
209 next_frame += frame_ticks; 214 if (frame_ticks) {
210 } 215 next_frame += frame_ticks;
211 return; 216 }
212 } 217 return;
213 218 }
214 static Uint8 *DMA_GetAudioBuf(_THIS) 219
215 { 220 static Uint8 *
216 count_info info; 221 DMA_GetAudioBuf (_THIS)
217 int playing; 222 {
218 int filling; 223 count_info info;
219 224 int playing;
220 /* Get number of blocks, looping if we're not using select() */ 225 int filling;
221 do { 226
222 if ( ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &info) < 0 ) { 227 /* Get number of blocks, looping if we're not using select() */
223 /* Uh oh... */ 228 do {
224 this->enabled = 0; 229 if (ioctl (audio_fd, SNDCTL_DSP_GETOPTR, &info) < 0) {
225 return(NULL); 230 /* Uh oh... */
226 } 231 this->enabled = 0;
227 } while ( frame_ticks && (info.blocks < 1) ); 232 return (NULL);
233 }
234 }
235 while (frame_ticks && (info.blocks < 1));
228 #ifdef DEBUG_AUDIO 236 #ifdef DEBUG_AUDIO
229 if ( info.blocks > 1 ) { 237 if (info.blocks > 1) {
230 printf("Warning: audio underflow (%d frags)\n", info.blocks-1); 238 printf ("Warning: audio underflow (%d frags)\n", info.blocks - 1);
231 } 239 }
232 #endif 240 #endif
233 playing = info.ptr / this->spec.size; 241 playing = info.ptr / this->spec.size;
234 filling = (playing + 1)%num_buffers; 242 filling = (playing + 1) % num_buffers;
235 return (dma_buf + (filling * this->spec.size)); 243 return (dma_buf + (filling * this->spec.size));
236 } 244 }
237 245
238 static void DMA_CloseAudio(_THIS) 246 static void
239 { 247 DMA_CloseAudio (_THIS)
240 if ( dma_buf != NULL ) { 248 {
241 munmap(dma_buf, dma_len); 249 if (dma_buf != NULL) {
242 dma_buf = NULL; 250 munmap (dma_buf, dma_len);
243 } 251 dma_buf = NULL;
244 if ( audio_fd >= 0 ) { 252 }
245 close(audio_fd); 253 if (audio_fd >= 0) {
246 audio_fd = -1; 254 close (audio_fd);
247 } 255 audio_fd = -1;
248 } 256 }
249 257 }
250 static int DMA_ReopenAudio(_THIS, const char *audiodev, int format, int stereo, 258
251 SDL_AudioSpec *spec) 259 static int
252 { 260 DMA_ReopenAudio (_THIS, const char *audiodev, int format, int stereo,
253 int frag_spec; 261 SDL_AudioSpec * spec)
254 int value; 262 {
255 263 int frag_spec;
256 /* Close and then reopen the audio device */ 264 int value;
257 close(audio_fd); 265
258 audio_fd = open(audiodev, O_RDWR, 0); 266 /* Close and then reopen the audio device */
259 if ( audio_fd < 0 ) { 267 close (audio_fd);
260 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); 268 audio_fd = open (audiodev, O_RDWR, 0);
261 return(-1); 269 if (audio_fd < 0) {
262 } 270 SDL_SetError ("Couldn't open %s: %s", audiodev, strerror (errno));
263 271 return (-1);
264 /* Calculate the final parameters for this audio specification */ 272 }
265 SDL_CalculateAudioSpec(spec); 273
266 274 /* Calculate the final parameters for this audio specification */
267 /* Determine the power of two of the fragment size */ 275 SDL_CalculateAudioSpec (spec);
268 for ( frag_spec = 0; (0x01<<frag_spec) < spec->size; ++frag_spec ); 276
269 if ( (0x01<<frag_spec) != spec->size ) { 277 /* Determine the power of two of the fragment size */
270 SDL_SetError("Fragment size must be a power of two"); 278 for (frag_spec = 0; (0x01 << frag_spec) < spec->size; ++frag_spec);
271 return(-1); 279 if ((0x01 << frag_spec) != spec->size) {
272 } 280 SDL_SetError ("Fragment size must be a power of two");
273 281 return (-1);
274 /* Set the audio buffering parameters */ 282 }
275 if ( ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0 ) { 283
276 SDL_SetError("Couldn't set audio fragment spec"); 284 /* Set the audio buffering parameters */
277 return(-1); 285 if (ioctl (audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) {
278 } 286 SDL_SetError ("Couldn't set audio fragment spec");
279 287 return (-1);
280 /* Set the audio format */ 288 }
281 value = format; 289
282 if ( (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || 290 /* Set the audio format */
283 (value != format) ) { 291 value = format;
284 SDL_SetError("Couldn't set audio format"); 292 if ((ioctl (audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) ||
285 return(-1); 293 (value != format)) {
286 } 294 SDL_SetError ("Couldn't set audio format");
287 295 return (-1);
288 /* Set mono or stereo audio */ 296 }
289 value = (spec->channels > 1); 297
290 if ( (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) < 0) || 298 /* Set mono or stereo audio */
291 (value != stereo) ) { 299 value = (spec->channels > 1);
292 SDL_SetError("Couldn't set audio channels"); 300 if ((ioctl (audio_fd, SNDCTL_DSP_STEREO, &stereo) < 0) ||
293 return(-1); 301 (value != stereo)) {
294 } 302 SDL_SetError ("Couldn't set audio channels");
295 303 return (-1);
296 /* Set the DSP frequency */ 304 }
297 value = spec->freq; 305
298 if ( ioctl(audio_fd, SNDCTL_DSP_SPEED, &value) < 0 ) { 306 /* Set the DSP frequency */
299 SDL_SetError("Couldn't set audio frequency"); 307 value = spec->freq;
300 return(-1); 308 if (ioctl (audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
301 } 309 SDL_SetError ("Couldn't set audio frequency");
302 spec->freq = value; 310 return (-1);
303 311 }
304 /* We successfully re-opened the audio */ 312 spec->freq = value;
305 return(0); 313
306 } 314 /* We successfully re-opened the audio */
307 315 return (0);
308 static int DMA_OpenAudio(_THIS, SDL_AudioSpec *spec) 316 }
309 { 317
310 char audiodev[1024]; 318 static int
311 int format; 319 DMA_OpenAudio (_THIS, SDL_AudioSpec * spec)
312 int stereo; 320 {
313 int value; 321 char audiodev[1024];
314 Uint16 test_format; 322 int format;
315 struct audio_buf_info info; 323 int stereo;
316 324 int value;
317 /* Reset the timer synchronization flag */ 325 Uint16 test_format;
318 frame_ticks = 0.0; 326 struct audio_buf_info info;
319 327
320 /* Open the audio device */ 328 /* Reset the timer synchronization flag */
321 audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); 329 frame_ticks = 0.0;
322 if ( audio_fd < 0 ) { 330
323 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); 331 /* Open the audio device */
324 return(-1); 332 audio_fd = SDL_OpenAudioPath (audiodev, sizeof (audiodev), OPEN_FLAGS, 0);
325 } 333 if (audio_fd < 0) {
326 dma_buf = NULL; 334 SDL_SetError ("Couldn't open %s: %s", audiodev, strerror (errno));
327 ioctl(audio_fd, SNDCTL_DSP_RESET, 0); 335 return (-1);
328 336 }
329 /* Get a list of supported hardware formats */ 337 dma_buf = NULL;
330 if ( ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0 ) { 338 ioctl (audio_fd, SNDCTL_DSP_RESET, 0);
331 SDL_SetError("Couldn't get audio format list"); 339
332 return(-1); 340 /* Get a list of supported hardware formats */
333 } 341 if (ioctl (audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
334 342 SDL_SetError ("Couldn't get audio format list");
335 /* Try for a closest match on audio format */ 343 return (-1);
336 format = 0; 344 }
337 for ( test_format = SDL_FirstAudioFormat(spec->format); 345
338 ! format && test_format; ) { 346 /* Try for a closest match on audio format */
347 format = 0;
348 for (test_format = SDL_FirstAudioFormat (spec->format);
349 !format && test_format;) {
339 #ifdef DEBUG_AUDIO 350 #ifdef DEBUG_AUDIO
340 fprintf(stderr, "Trying format 0x%4.4x\n", test_format); 351 fprintf (stderr, "Trying format 0x%4.4x\n", test_format);
341 #endif 352 #endif
342 switch ( test_format ) { 353 switch (test_format) {
343 case AUDIO_U8: 354 case AUDIO_U8:
344 if ( value & AFMT_U8 ) { 355 if (value & AFMT_U8) {
345 format = AFMT_U8; 356 format = AFMT_U8;
346 } 357 }
347 break; 358 break;
348 case AUDIO_S8: 359 case AUDIO_S8:
349 if ( value & AFMT_S8 ) { 360 if (value & AFMT_S8) {
350 format = AFMT_S8; 361 format = AFMT_S8;
351 } 362 }
352 break; 363 break;
353 case AUDIO_S16LSB: 364 case AUDIO_S16LSB:
354 if ( value & AFMT_S16_LE ) { 365 if (value & AFMT_S16_LE) {
355 format = AFMT_S16_LE; 366 format = AFMT_S16_LE;
356 } 367 }
357 break; 368 break;
358 case AUDIO_S16MSB: 369 case AUDIO_S16MSB:
359 if ( value & AFMT_S16_BE ) { 370 if (value & AFMT_S16_BE) {
360 format = AFMT_S16_BE; 371 format = AFMT_S16_BE;
361 } 372 }
362 break; 373 break;
363 case AUDIO_U16LSB: 374 case AUDIO_U16LSB:
364 if ( value & AFMT_U16_LE ) { 375 if (value & AFMT_U16_LE) {
365 format = AFMT_U16_LE; 376 format = AFMT_U16_LE;
366 } 377 }
367 break; 378 break;
368 case AUDIO_U16MSB: 379 case AUDIO_U16MSB:
369 if ( value & AFMT_U16_BE ) { 380 if (value & AFMT_U16_BE) {
370 format = AFMT_U16_BE; 381 format = AFMT_U16_BE;
371 } 382 }
372 break; 383 break;
373 default: 384 default:
374 format = 0; 385 format = 0;
375 break; 386 break;
376 } 387 }
377 if ( ! format ) { 388 if (!format) {
378 test_format = SDL_NextAudioFormat(); 389 test_format = SDL_NextAudioFormat ();
379 } 390 }
380 } 391 }
381 if ( format == 0 ) { 392 if (format == 0) {
382 SDL_SetError("Couldn't find any hardware audio formats"); 393 SDL_SetError ("Couldn't find any hardware audio formats");
383 return(-1); 394 return (-1);
384 } 395 }
385 spec->format = test_format; 396 spec->format = test_format;
386 397
387 /* Set the audio format */ 398 /* Set the audio format */
388 value = format; 399 value = format;
389 if ( (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || 400 if ((ioctl (audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) ||
390 (value != format) ) { 401 (value != format)) {
391 SDL_SetError("Couldn't set audio format"); 402 SDL_SetError ("Couldn't set audio format");
392 return(-1); 403 return (-1);
393 } 404 }
394 405
395 /* Set mono or stereo audio (currently only two channels supported) */ 406 /* Set mono or stereo audio (currently only two channels supported) */
396 stereo = (spec->channels > 1); 407 stereo = (spec->channels > 1);
397 ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo); 408 ioctl (audio_fd, SNDCTL_DSP_STEREO, &stereo);
398 if ( stereo ) { 409 if (stereo) {
399 spec->channels = 2; 410 spec->channels = 2;
400 } else { 411 } else {
401 spec->channels = 1; 412 spec->channels = 1;
402 } 413 }
403 414
404 /* Because some drivers don't allow setting the buffer size 415 /* Because some drivers don't allow setting the buffer size
405 after setting the format, we must re-open the audio device 416 after setting the format, we must re-open the audio device
406 once we know what format and channels are supported 417 once we know what format and channels are supported
407 */ 418 */
408 if ( DMA_ReopenAudio(this, audiodev, format, stereo, spec) < 0 ) { 419 if (DMA_ReopenAudio (this, audiodev, format, stereo, spec) < 0) {
409 /* Error is set by DMA_ReopenAudio() */ 420 /* Error is set by DMA_ReopenAudio() */
410 return(-1); 421 return (-1);
411 } 422 }
412 423
413 /* Memory map the audio buffer */ 424 /* Memory map the audio buffer */
414 if ( ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) < 0 ) { 425 if (ioctl (audio_fd, SNDCTL_DSP_GETOSPACE, &info) < 0) {
415 SDL_SetError("Couldn't get OSPACE parameters"); 426 SDL_SetError ("Couldn't get OSPACE parameters");
416 return(-1); 427 return (-1);
417 } 428 }
418 spec->size = info.fragsize; 429 spec->size = info.fragsize;
419 spec->samples = spec->size / ((spec->format & 0xFF) / 8); 430 spec->samples = spec->size / ((spec->format & 0xFF) / 8);
420 spec->samples /= spec->channels; 431 spec->samples /= spec->channels;
421 num_buffers = info.fragstotal; 432 num_buffers = info.fragstotal;
422 dma_len = num_buffers*spec->size; 433 dma_len = num_buffers * spec->size;
423 dma_buf = (Uint8 *)mmap(NULL, dma_len, PROT_WRITE, MAP_SHARED, 434 dma_buf = (Uint8 *) mmap (NULL, dma_len, PROT_WRITE, MAP_SHARED,
424 audio_fd, 0); 435 audio_fd, 0);
425 if ( dma_buf == MAP_FAILED ) { 436 if (dma_buf == MAP_FAILED) {
426 SDL_SetError("DMA memory map failed"); 437 SDL_SetError ("DMA memory map failed");
427 dma_buf = NULL; 438 dma_buf = NULL;
428 return(-1); 439 return (-1);
429 } 440 }
430 SDL_memset(dma_buf, spec->silence, dma_len); 441 SDL_memset (dma_buf, spec->silence, dma_len);
431 442
432 /* Check to see if we need to use select() workaround */ 443 /* Check to see if we need to use select() workaround */
433 { char *workaround; 444 {
434 workaround = SDL_getenv("SDL_DSP_NOSELECT"); 445 char *workaround;
435 if ( workaround ) { 446 workaround = SDL_getenv ("SDL_DSP_NOSELECT");
436 frame_ticks = (float)(spec->samples*1000)/spec->freq; 447 if (workaround) {
437 next_frame = SDL_GetTicks()+frame_ticks; 448 frame_ticks = (float) (spec->samples * 1000) / spec->freq;
438 } 449 next_frame = SDL_GetTicks () + frame_ticks;
439 } 450 }
440 451 }
441 /* Trigger audio playback */ 452
442 value = 0; 453 /* Trigger audio playback */
443 ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value); 454 value = 0;
444 value = PCM_ENABLE_OUTPUT; 455 ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &value);
445 if ( ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value) < 0 ) { 456 value = PCM_ENABLE_OUTPUT;
446 SDL_SetError("Couldn't trigger audio output"); 457 if (ioctl (audio_fd, SNDCTL_DSP_SETTRIGGER, &value) < 0) {
447 return(-1); 458 SDL_SetError ("Couldn't trigger audio output");
448 } 459 return (-1);
449 460 }
450 /* Get the parent process id (we're the parent of the audio thread) */ 461
451 parent = getpid(); 462 /* Get the parent process id (we're the parent of the audio thread) */
452 463 parent = getpid ();
453 /* We're ready to rock and roll. :-) */ 464
454 return(0); 465 /* We're ready to rock and roll. :-) */
455 } 466 return (0);
467 }
468
469 /* vi: set ts=4 sw=4 expandtab: */