Mercurial > sdl-ios-xcode
comparison src/audio/paudio/SDL_paudio.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 | 782fd950bd46 |
children |
comparison
equal
deleted
inserted
replaced
1667:1fddae038bc8 | 1668:4da1ee79c9af |
---|---|
53 /* Open the audio device for playback, and don't block if busy */ | 53 /* Open the audio device for playback, and don't block if busy */ |
54 /* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */ | 54 /* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */ |
55 #define OPEN_FLAGS O_WRONLY | 55 #define OPEN_FLAGS O_WRONLY |
56 | 56 |
57 /* Audio driver functions */ | 57 /* Audio driver functions */ |
58 static int Paud_OpenAudio (_THIS, SDL_AudioSpec * spec); | 58 static int Paud_OpenAudio(_THIS, SDL_AudioSpec * spec); |
59 static void Paud_WaitAudio (_THIS); | 59 static void Paud_WaitAudio(_THIS); |
60 static void Paud_PlayAudio (_THIS); | 60 static void Paud_PlayAudio(_THIS); |
61 static Uint8 *Paud_GetAudioBuf (_THIS); | 61 static Uint8 *Paud_GetAudioBuf(_THIS); |
62 static void Paud_CloseAudio (_THIS); | 62 static void Paud_CloseAudio(_THIS); |
63 | 63 |
64 /* Audio driver bootstrap functions */ | 64 /* Audio driver bootstrap functions */ |
65 | 65 |
66 static int | 66 static int |
67 Audio_Available (void) | 67 Audio_Available(void) |
68 { | 68 { |
69 int fd; | 69 int fd; |
70 int available; | 70 int available; |
71 | 71 |
72 available = 0; | 72 available = 0; |
73 fd = SDL_OpenAudioPath (NULL, 0, OPEN_FLAGS, 0); | 73 fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); |
74 if (fd >= 0) { | 74 if (fd >= 0) { |
75 available = 1; | 75 available = 1; |
76 close (fd); | 76 close(fd); |
77 } | 77 } |
78 return (available); | 78 return (available); |
79 } | 79 } |
80 | 80 |
81 static void | 81 static void |
82 Audio_DeleteDevice (SDL_AudioDevice * device) | 82 Audio_DeleteDevice(SDL_AudioDevice * device) |
83 { | 83 { |
84 SDL_free (device->hidden); | 84 SDL_free(device->hidden); |
85 SDL_free (device); | 85 SDL_free(device); |
86 } | 86 } |
87 | 87 |
88 static SDL_AudioDevice * | 88 static SDL_AudioDevice * |
89 Audio_CreateDevice (int devindex) | 89 Audio_CreateDevice(int devindex) |
90 { | 90 { |
91 SDL_AudioDevice *this; | 91 SDL_AudioDevice *this; |
92 | 92 |
93 /* Initialize all variables that we clean on shutdown */ | 93 /* Initialize all variables that we clean on shutdown */ |
94 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice)); | 94 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice)); |
95 if (this) { | 95 if (this) { |
96 SDL_memset (this, 0, (sizeof *this)); | 96 SDL_memset(this, 0, (sizeof *this)); |
97 this->hidden = (struct SDL_PrivateAudioData *) | 97 this->hidden = (struct SDL_PrivateAudioData *) |
98 SDL_malloc ((sizeof *this->hidden)); | 98 SDL_malloc((sizeof *this->hidden)); |
99 } | 99 } |
100 if ((this == NULL) || (this->hidden == NULL)) { | 100 if ((this == NULL) || (this->hidden == NULL)) { |
101 SDL_OutOfMemory (); | 101 SDL_OutOfMemory(); |
102 if (this) { | 102 if (this) { |
103 SDL_free (this); | 103 SDL_free(this); |
104 } | 104 } |
105 return (0); | 105 return (0); |
106 } | 106 } |
107 SDL_memset (this->hidden, 0, (sizeof *this->hidden)); | 107 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); |
108 audio_fd = -1; | 108 audio_fd = -1; |
109 | 109 |
110 /* Set the function pointers */ | 110 /* Set the function pointers */ |
111 this->OpenAudio = Paud_OpenAudio; | 111 this->OpenAudio = Paud_OpenAudio; |
112 this->WaitAudio = Paud_WaitAudio; | 112 this->WaitAudio = Paud_WaitAudio; |
124 Audio_Available, Audio_CreateDevice | 124 Audio_Available, Audio_CreateDevice |
125 }; | 125 }; |
126 | 126 |
127 /* This function waits until it is possible to write a full sound buffer */ | 127 /* This function waits until it is possible to write a full sound buffer */ |
128 static void | 128 static void |
129 Paud_WaitAudio (_THIS) | 129 Paud_WaitAudio(_THIS) |
130 { | 130 { |
131 fd_set fdset; | 131 fd_set fdset; |
132 | 132 |
133 /* See if we need to use timed audio synchronization */ | 133 /* See if we need to use timed audio synchronization */ |
134 if (frame_ticks) { | 134 if (frame_ticks) { |
135 /* Use timer for general audio synchronization */ | 135 /* Use timer for general audio synchronization */ |
136 Sint32 ticks; | 136 Sint32 ticks; |
137 | 137 |
138 ticks = ((Sint32) (next_frame - SDL_GetTicks ())) - FUDGE_TICKS; | 138 ticks = ((Sint32) (next_frame - SDL_GetTicks())) - FUDGE_TICKS; |
139 if (ticks > 0) { | 139 if (ticks > 0) { |
140 SDL_Delay (ticks); | 140 SDL_Delay(ticks); |
141 } | 141 } |
142 } else { | 142 } else { |
143 audio_buffer paud_bufinfo; | 143 audio_buffer paud_bufinfo; |
144 | 144 |
145 /* Use select() for audio synchronization */ | 145 /* Use select() for audio synchronization */ |
146 struct timeval timeout; | 146 struct timeval timeout; |
147 FD_ZERO (&fdset); | 147 FD_ZERO(&fdset); |
148 FD_SET (audio_fd, &fdset); | 148 FD_SET(audio_fd, &fdset); |
149 | 149 |
150 if (ioctl (audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { | 150 if (ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { |
151 #ifdef DEBUG_AUDIO | 151 #ifdef DEBUG_AUDIO |
152 fprintf (stderr, "Couldn't get audio buffer information\n"); | 152 fprintf(stderr, "Couldn't get audio buffer information\n"); |
153 #endif | 153 #endif |
154 timeout.tv_sec = 10; | 154 timeout.tv_sec = 10; |
155 timeout.tv_usec = 0; | 155 timeout.tv_usec = 0; |
156 } else { | 156 } else { |
157 long ms_in_buf = paud_bufinfo.write_buf_time; | 157 long ms_in_buf = paud_bufinfo.write_buf_time; |
158 timeout.tv_sec = ms_in_buf / 1000; | 158 timeout.tv_sec = ms_in_buf / 1000; |
159 ms_in_buf = ms_in_buf - timeout.tv_sec * 1000; | 159 ms_in_buf = ms_in_buf - timeout.tv_sec * 1000; |
160 timeout.tv_usec = ms_in_buf * 1000; | 160 timeout.tv_usec = ms_in_buf * 1000; |
161 #ifdef DEBUG_AUDIO | 161 #ifdef DEBUG_AUDIO |
162 fprintf (stderr, | 162 fprintf(stderr, |
163 "Waiting for write_buf_time=%ld,%ld\n", | 163 "Waiting for write_buf_time=%ld,%ld\n", |
164 timeout.tv_sec, timeout.tv_usec); | 164 timeout.tv_sec, timeout.tv_usec); |
165 #endif | 165 #endif |
166 } | 166 } |
167 | 167 |
168 #ifdef DEBUG_AUDIO | 168 #ifdef DEBUG_AUDIO |
169 fprintf (stderr, "Waiting for audio to get ready\n"); | 169 fprintf(stderr, "Waiting for audio to get ready\n"); |
170 #endif | 170 #endif |
171 if (select (audio_fd + 1, NULL, &fdset, NULL, &timeout) <= 0) { | 171 if (select(audio_fd + 1, NULL, &fdset, NULL, &timeout) <= 0) { |
172 const char *message = | 172 const char *message = |
173 "Audio timeout - buggy audio driver? (disabled)"; | 173 "Audio timeout - buggy audio driver? (disabled)"; |
174 /* | 174 /* |
175 * In general we should never print to the screen, | 175 * In general we should never print to the screen, |
176 * but in this case we have no other way of letting | 176 * but in this case we have no other way of letting |
177 * the user know what happened. | 177 * the user know what happened. |
178 */ | 178 */ |
179 fprintf (stderr, "SDL: %s - %s\n", strerror (errno), message); | 179 fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message); |
180 this->enabled = 0; | 180 this->enabled = 0; |
181 /* Don't try to close - may hang */ | 181 /* Don't try to close - may hang */ |
182 audio_fd = -1; | 182 audio_fd = -1; |
183 #ifdef DEBUG_AUDIO | 183 #ifdef DEBUG_AUDIO |
184 fprintf (stderr, "Done disabling audio\n"); | 184 fprintf(stderr, "Done disabling audio\n"); |
185 #endif | 185 #endif |
186 } | 186 } |
187 #ifdef DEBUG_AUDIO | 187 #ifdef DEBUG_AUDIO |
188 fprintf (stderr, "Ready!\n"); | 188 fprintf(stderr, "Ready!\n"); |
189 #endif | 189 #endif |
190 } | 190 } |
191 } | 191 } |
192 | 192 |
193 static void | 193 static void |
194 Paud_PlayAudio (_THIS) | 194 Paud_PlayAudio(_THIS) |
195 { | 195 { |
196 int written; | 196 int written; |
197 | 197 |
198 /* Write the audio data, checking for EAGAIN on broken audio drivers */ | 198 /* Write the audio data, checking for EAGAIN on broken audio drivers */ |
199 do { | 199 do { |
200 written = write (audio_fd, mixbuf, mixlen); | 200 written = write(audio_fd, mixbuf, mixlen); |
201 if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) { | 201 if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) { |
202 SDL_Delay (1); /* Let a little CPU time go by */ | 202 SDL_Delay(1); /* Let a little CPU time go by */ |
203 } | 203 } |
204 } | 204 } |
205 while ((written < 0) && | 205 while ((written < 0) && |
206 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR))); | 206 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR))); |
207 | 207 |
213 /* If we couldn't write, assume fatal error for now */ | 213 /* If we couldn't write, assume fatal error for now */ |
214 if (written < 0) { | 214 if (written < 0) { |
215 this->enabled = 0; | 215 this->enabled = 0; |
216 } | 216 } |
217 #ifdef DEBUG_AUDIO | 217 #ifdef DEBUG_AUDIO |
218 fprintf (stderr, "Wrote %d bytes of audio data\n", written); | 218 fprintf(stderr, "Wrote %d bytes of audio data\n", written); |
219 #endif | 219 #endif |
220 } | 220 } |
221 | 221 |
222 static Uint8 * | 222 static Uint8 * |
223 Paud_GetAudioBuf (_THIS) | 223 Paud_GetAudioBuf(_THIS) |
224 { | 224 { |
225 return mixbuf; | 225 return mixbuf; |
226 } | 226 } |
227 | 227 |
228 static void | 228 static void |
229 Paud_CloseAudio (_THIS) | 229 Paud_CloseAudio(_THIS) |
230 { | 230 { |
231 if (mixbuf != NULL) { | 231 if (mixbuf != NULL) { |
232 SDL_FreeAudioMem (mixbuf); | 232 SDL_FreeAudioMem(mixbuf); |
233 mixbuf = NULL; | 233 mixbuf = NULL; |
234 } | 234 } |
235 if (audio_fd >= 0) { | 235 if (audio_fd >= 0) { |
236 close (audio_fd); | 236 close(audio_fd); |
237 audio_fd = -1; | 237 audio_fd = -1; |
238 } | 238 } |
239 } | 239 } |
240 | 240 |
241 static int | 241 static int |
242 Paud_OpenAudio (_THIS, SDL_AudioSpec * spec) | 242 Paud_OpenAudio(_THIS, SDL_AudioSpec * spec) |
243 { | 243 { |
244 char audiodev[1024]; | 244 char audiodev[1024]; |
245 int format; | 245 int format; |
246 int bytes_per_sample; | 246 int bytes_per_sample; |
247 Uint16 test_format; | 247 Uint16 test_format; |
253 | 253 |
254 /* Reset the timer synchronization flag */ | 254 /* Reset the timer synchronization flag */ |
255 frame_ticks = 0.0; | 255 frame_ticks = 0.0; |
256 | 256 |
257 /* Open the audio device */ | 257 /* Open the audio device */ |
258 audio_fd = SDL_OpenAudioPath (audiodev, sizeof (audiodev), OPEN_FLAGS, 0); | 258 audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); |
259 if (audio_fd < 0) { | 259 if (audio_fd < 0) { |
260 SDL_SetError ("Couldn't open %s: %s", audiodev, strerror (errno)); | 260 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); |
261 return -1; | 261 return -1; |
262 } | 262 } |
263 | 263 |
264 /* | 264 /* |
265 * We can't set the buffer size - just ask the device for the maximum | 265 * We can't set the buffer size - just ask the device for the maximum |
266 * that we can have. | 266 * that we can have. |
267 */ | 267 */ |
268 if (ioctl (audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { | 268 if (ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { |
269 SDL_SetError ("Couldn't get audio buffer information"); | 269 SDL_SetError("Couldn't get audio buffer information"); |
270 return -1; | 270 return -1; |
271 } | 271 } |
272 | 272 |
273 mixbuf = NULL; | 273 mixbuf = NULL; |
274 | 274 |
327 paud_init.operation = PLAY; | 327 paud_init.operation = PLAY; |
328 paud_init.channels = spec->channels; | 328 paud_init.channels = spec->channels; |
329 | 329 |
330 /* Try for a closest match on audio format */ | 330 /* Try for a closest match on audio format */ |
331 format = 0; | 331 format = 0; |
332 for (test_format = SDL_FirstAudioFormat (spec->format); | 332 for (test_format = SDL_FirstAudioFormat(spec->format); |
333 !format && test_format;) { | 333 !format && test_format;) { |
334 #ifdef DEBUG_AUDIO | 334 #ifdef DEBUG_AUDIO |
335 fprintf (stderr, "Trying format 0x%4.4x\n", test_format); | 335 fprintf(stderr, "Trying format 0x%4.4x\n", test_format); |
336 #endif | 336 #endif |
337 switch (test_format) { | 337 switch (test_format) { |
338 case AUDIO_U8: | 338 case AUDIO_U8: |
339 bytes_per_sample = 1; | 339 bytes_per_sample = 1; |
340 paud_init.bits_per_sample = 8; | 340 paud_init.bits_per_sample = 8; |
373 break; | 373 break; |
374 default: | 374 default: |
375 break; | 375 break; |
376 } | 376 } |
377 if (!format) { | 377 if (!format) { |
378 test_format = SDL_NextAudioFormat (); | 378 test_format = SDL_NextAudioFormat(); |
379 } | 379 } |
380 } | 380 } |
381 if (format == 0) { | 381 if (format == 0) { |
382 #ifdef DEBUG_AUDIO | 382 #ifdef DEBUG_AUDIO |
383 fprintf (stderr, "Couldn't find any hardware audio formats\n"); | 383 fprintf(stderr, "Couldn't find any hardware audio formats\n"); |
384 #endif | 384 #endif |
385 SDL_SetError ("Couldn't find any hardware audio formats"); | 385 SDL_SetError("Couldn't find any hardware audio formats"); |
386 return -1; | 386 return -1; |
387 } | 387 } |
388 spec->format = test_format; | 388 spec->format = test_format; |
389 | 389 |
390 /* | 390 /* |
404 spec->samples = paud_bufinfo.write_buf_cap | 404 spec->samples = paud_bufinfo.write_buf_cap |
405 / bytes_per_sample / spec->channels / 2; | 405 / bytes_per_sample / spec->channels / 2; |
406 } | 406 } |
407 paud_init.bsize = bytes_per_sample * spec->channels; | 407 paud_init.bsize = bytes_per_sample * spec->channels; |
408 | 408 |
409 SDL_CalculateAudioSpec (spec); | 409 SDL_CalculateAudioSpec(spec); |
410 | 410 |
411 /* | 411 /* |
412 * The AIX paud device init can't modify the values of the audio_init | 412 * The AIX paud device init can't modify the values of the audio_init |
413 * structure that we pass to it. So we don't need any recalculation | 413 * structure that we pass to it. So we don't need any recalculation |
414 * of this stuff and no reinit call as in linux dsp and dma code. | 414 * of this stuff and no reinit call as in linux dsp and dma code. |
415 * | 415 * |
416 * /dev/paud supports all of the encoding formats, so we don't need | 416 * /dev/paud supports all of the encoding formats, so we don't need |
417 * to do anything like reopening the device, either. | 417 * to do anything like reopening the device, either. |
418 */ | 418 */ |
419 if (ioctl (audio_fd, AUDIO_INIT, &paud_init) < 0) { | 419 if (ioctl(audio_fd, AUDIO_INIT, &paud_init) < 0) { |
420 switch (paud_init.rc) { | 420 switch (paud_init.rc) { |
421 case 1: | 421 case 1: |
422 SDL_SetError | 422 SDL_SetError |
423 ("Couldn't set audio format: DSP can't do play requests"); | 423 ("Couldn't set audio format: DSP can't do play requests"); |
424 return -1; | 424 return -1; |
427 SDL_SetError | 427 SDL_SetError |
428 ("Couldn't set audio format: DSP can't do record requests"); | 428 ("Couldn't set audio format: DSP can't do record requests"); |
429 return -1; | 429 return -1; |
430 break; | 430 break; |
431 case 4: | 431 case 4: |
432 SDL_SetError ("Couldn't set audio format: request was invalid"); | 432 SDL_SetError("Couldn't set audio format: request was invalid"); |
433 return -1; | 433 return -1; |
434 break; | 434 break; |
435 case 5: | 435 case 5: |
436 SDL_SetError | 436 SDL_SetError |
437 ("Couldn't set audio format: conflict with open's flags"); | 437 ("Couldn't set audio format: conflict with open's flags"); |
450 } | 450 } |
451 } | 451 } |
452 | 452 |
453 /* Allocate mixing buffer */ | 453 /* Allocate mixing buffer */ |
454 mixlen = spec->size; | 454 mixlen = spec->size; |
455 mixbuf = (Uint8 *) SDL_AllocAudioMem (mixlen); | 455 mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen); |
456 if (mixbuf == NULL) { | 456 if (mixbuf == NULL) { |
457 return -1; | 457 return -1; |
458 } | 458 } |
459 SDL_memset (mixbuf, spec->silence, spec->size); | 459 SDL_memset(mixbuf, spec->silence, spec->size); |
460 | 460 |
461 /* | 461 /* |
462 * Set some paramters: full volume, first speaker that we can find. | 462 * Set some paramters: full volume, first speaker that we can find. |
463 * Ignore the other settings for now. | 463 * Ignore the other settings for now. |
464 */ | 464 */ |
473 paud_change.bass = AUDIO_IGNORE; /* the new bass state */ | 473 paud_change.bass = AUDIO_IGNORE; /* the new bass state */ |
474 paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */ | 474 paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */ |
475 | 475 |
476 paud_control.ioctl_request = AUDIO_CHANGE; | 476 paud_control.ioctl_request = AUDIO_CHANGE; |
477 paud_control.request_info = (char *) &paud_change; | 477 paud_control.request_info = (char *) &paud_change; |
478 if (ioctl (audio_fd, AUDIO_CONTROL, &paud_control) < 0) { | 478 if (ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0) { |
479 #ifdef DEBUG_AUDIO | 479 #ifdef DEBUG_AUDIO |
480 fprintf (stderr, "Can't change audio display settings\n"); | 480 fprintf(stderr, "Can't change audio display settings\n"); |
481 #endif | 481 #endif |
482 } | 482 } |
483 | 483 |
484 /* | 484 /* |
485 * Tell the device to expect data. Actual start will wait for | 485 * Tell the device to expect data. Actual start will wait for |
486 * the first write() call. | 486 * the first write() call. |
487 */ | 487 */ |
488 paud_control.ioctl_request = AUDIO_START; | 488 paud_control.ioctl_request = AUDIO_START; |
489 paud_control.position = 0; | 489 paud_control.position = 0; |
490 if (ioctl (audio_fd, AUDIO_CONTROL, &paud_control) < 0) { | 490 if (ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0) { |
491 #ifdef DEBUG_AUDIO | 491 #ifdef DEBUG_AUDIO |
492 fprintf (stderr, "Can't start audio play\n"); | 492 fprintf(stderr, "Can't start audio play\n"); |
493 #endif | 493 #endif |
494 SDL_SetError ("Can't start audio play"); | 494 SDL_SetError("Can't start audio play"); |
495 return -1; | 495 return -1; |
496 } | 496 } |
497 | 497 |
498 /* Check to see if we need to use select() workaround */ | 498 /* Check to see if we need to use select() workaround */ |
499 { | 499 { |
500 char *workaround; | 500 char *workaround; |
501 workaround = SDL_getenv ("SDL_DSP_NOSELECT"); | 501 workaround = SDL_getenv("SDL_DSP_NOSELECT"); |
502 if (workaround) { | 502 if (workaround) { |
503 frame_ticks = (float) (spec->samples * 1000) / spec->freq; | 503 frame_ticks = (float) (spec->samples * 1000) / spec->freq; |
504 next_frame = SDL_GetTicks () + frame_ticks; | 504 next_frame = SDL_GetTicks() + frame_ticks; |
505 } | 505 } |
506 } | 506 } |
507 | 507 |
508 /* Get the parent process id (we're the parent of the audio thread) */ | 508 /* Get the parent process id (we're the parent of the audio thread) */ |
509 parent = getpid (); | 509 parent = getpid(); |
510 | 510 |
511 /* We're ready to rock and roll. :-) */ | 511 /* We're ready to rock and roll. :-) */ |
512 return 0; | 512 return 0; |
513 } | 513 } |
514 | 514 |