comparison src/audio/SDL_audio.c @ 2060:866052b01ee5

indent is evil
author Sam Lantinga <slouken@libsdl.org>
date Sat, 28 Oct 2006 16:48:03 +0000
parents 716cf90f24a0
children dbfa1ebd73b0
comparison
equal deleted inserted replaced
2059:4685ccd33d0e 2060:866052b01ee5
142 &DART_bootstrap, 142 &DART_bootstrap,
143 #endif 143 #endif
144 NULL 144 NULL
145 }; 145 };
146 146
147 static SDL_AudioDevice *get_audio_device(SDL_AudioDeviceID id) 147 static SDL_AudioDevice *
148 get_audio_device(SDL_AudioDeviceID id)
148 { 149 {
149 id--; 150 id--;
150 if ( (id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL) ) { 151 if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) {
151 SDL_SetError("Invalid audio device ID"); 152 SDL_SetError("Invalid audio device ID");
152 return NULL; 153 return NULL;
153 } 154 }
154 155
155 return open_devices[id]; 156 return open_devices[id];
156 } 157 }
157 158
158 159
159 /* stubs for audio drivers that don't need a specific entry point... */ 160 /* stubs for audio drivers that don't need a specific entry point... */
160 static int SDL_AudioDetectDevices_Default(int iscapture) { return -1; } 161 static int
161 static void SDL_AudioThreadInit_Default(_THIS) { /* no-op. */ } 162 SDL_AudioDetectDevices_Default(int iscapture)
162 static void SDL_AudioWaitDevice_Default(_THIS) { /* no-op. */ } 163 {
163 static void SDL_AudioPlayDevice_Default(_THIS) { /* no-op. */ } 164 return -1;
164 static Uint8 *SDL_AudioGetDeviceBuf_Default(_THIS) { return NULL; } 165 }
165 static void SDL_AudioWaitDone_Default(_THIS) { /* no-op. */ } 166 static void
166 static void SDL_AudioCloseDevice_Default(_THIS) { /* no-op. */ } 167 SDL_AudioThreadInit_Default(_THIS)
167 static void SDL_AudioDeinitialize_Default(void) { /* no-op. */ } 168 { /* no-op. */
169 }
170 static void
171 SDL_AudioWaitDevice_Default(_THIS)
172 { /* no-op. */
173 }
174 static void
175 SDL_AudioPlayDevice_Default(_THIS)
176 { /* no-op. */
177 }
178 static Uint8 *
179 SDL_AudioGetDeviceBuf_Default(_THIS)
180 {
181 return NULL;
182 }
183 static void
184 SDL_AudioWaitDone_Default(_THIS)
185 { /* no-op. */
186 }
187 static void
188 SDL_AudioCloseDevice_Default(_THIS)
189 { /* no-op. */
190 }
191 static void
192 SDL_AudioDeinitialize_Default(void)
193 { /* no-op. */
194 }
168 195
169 static int 196 static int
170 SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture) 197 SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture)
171 { 198 {
172 return 0; 199 return 0;
173 } 200 }
174 201
175 static const char *SDL_AudioGetDeviceName_Default(int index, int iscapture) 202 static const char *
203 SDL_AudioGetDeviceName_Default(int index, int iscapture)
176 { 204 {
177 SDL_SetError("No such device"); 205 SDL_SetError("No such device");
178 return NULL; 206 return NULL;
179 } 207 }
180 208
195 } 223 }
196 SDL_mutexV(device->mixer_lock); 224 SDL_mutexV(device->mixer_lock);
197 } 225 }
198 226
199 227
200 static void finalize_audio_entry_points(void) 228 static void
229 finalize_audio_entry_points(void)
201 { 230 {
202 /* 231 /*
203 * Fill in stub functions for unused driver entry points. This lets us 232 * Fill in stub functions for unused driver entry points. This lets us
204 * blindly call them without having to check for validity first. 233 * blindly call them without having to check for validity first.
205 */ 234 */
206 235
207 #define FILL_STUB(x) \ 236 #define FILL_STUB(x) \
208 if (current_audio.impl.x == NULL) { \ 237 if (current_audio.impl.x == NULL) { \
209 current_audio.impl.x = SDL_Audio##x##_Default; \ 238 current_audio.impl.x = SDL_Audio##x##_Default; \
210 } 239 }
211 FILL_STUB(DetectDevices); 240 FILL_STUB(DetectDevices);
212 FILL_STUB(GetDeviceName); 241 FILL_STUB(GetDeviceName);
218 FILL_STUB(WaitDone); 247 FILL_STUB(WaitDone);
219 FILL_STUB(CloseDevice); 248 FILL_STUB(CloseDevice);
220 FILL_STUB(LockDevice); 249 FILL_STUB(LockDevice);
221 FILL_STUB(UnlockDevice); 250 FILL_STUB(UnlockDevice);
222 FILL_STUB(Deinitialize); 251 FILL_STUB(Deinitialize);
223 #undef FILL_STUB 252 #undef FILL_STUB
224 } 253 }
225 254
226 255
227 /* The general mixing thread function */ 256 /* The general mixing thread function */
228 int SDLCALL 257 int SDLCALL
315 344
316 345
317 static SDL_AudioFormat 346 static SDL_AudioFormat
318 SDL_ParseAudioFormat(const char *string) 347 SDL_ParseAudioFormat(const char *string)
319 { 348 {
320 #define CHECK_FMT_STRING(x) if (strcmp(string, #x) == 0) return AUDIO_##x 349 #define CHECK_FMT_STRING(x) if (strcmp(string, #x) == 0) return AUDIO_##x
321 CHECK_FMT_STRING(U8); 350 CHECK_FMT_STRING(U8);
322 CHECK_FMT_STRING(S8); 351 CHECK_FMT_STRING(S8);
323 CHECK_FMT_STRING(U16LSB); 352 CHECK_FMT_STRING(U16LSB);
324 CHECK_FMT_STRING(S16LSB); 353 CHECK_FMT_STRING(S16LSB);
325 CHECK_FMT_STRING(U16MSB); 354 CHECK_FMT_STRING(U16MSB);
334 CHECK_FMT_STRING(S32); 363 CHECK_FMT_STRING(S32);
335 CHECK_FMT_STRING(F32LSB); 364 CHECK_FMT_STRING(F32LSB);
336 CHECK_FMT_STRING(F32MSB); 365 CHECK_FMT_STRING(F32MSB);
337 CHECK_FMT_STRING(F32SYS); 366 CHECK_FMT_STRING(F32SYS);
338 CHECK_FMT_STRING(F32); 367 CHECK_FMT_STRING(F32);
339 #undef CHECK_FMT_STRING 368 #undef CHECK_FMT_STRING
340 return 0; 369 return 0;
341 } 370 }
342 371
343 int 372 int
344 SDL_GetNumAudioDrivers(void) 373 SDL_GetNumAudioDrivers(void)
361 int i = 0; 390 int i = 0;
362 int initialized = 0; 391 int initialized = 0;
363 int tried_to_init = 0; 392 int tried_to_init = 0;
364 393
365 if (SDL_WasInit(SDL_INIT_AUDIO)) { 394 if (SDL_WasInit(SDL_INIT_AUDIO)) {
366 SDL_AudioQuit(); /* shutdown driver if already running. */ 395 SDL_AudioQuit(); /* shutdown driver if already running. */
367 } 396 }
368 397
369 SDL_memset(&current_audio, '\0', sizeof (current_audio)); 398 SDL_memset(&current_audio, '\0', sizeof(current_audio));
370 SDL_memset(open_devices, '\0', sizeof (open_devices)); 399 SDL_memset(open_devices, '\0', sizeof(open_devices));
371 400
372 /* Select the proper audio driver */ 401 /* Select the proper audio driver */
373 if (driver_name == NULL) { 402 if (driver_name == NULL) {
374 driver_name = SDL_getenv("SDL_AUDIODRIVER"); 403 driver_name = SDL_getenv("SDL_AUDIODRIVER");
375 } 404 }
376 405
377 for (i = 0; (!initialized) && (bootstrap[i]); ++i) { 406 for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
378 /* make sure we should even try this driver before doing so... */ 407 /* make sure we should even try this driver before doing so... */
379 const AudioBootStrap *backend = bootstrap[i]; 408 const AudioBootStrap *backend = bootstrap[i];
380 if ( ((driver_name) && (SDL_strcasecmp(backend->name, driver_name))) || 409 if (((driver_name) && (SDL_strcasecmp(backend->name, driver_name))) ||
381 ((!driver_name) && (backend->demand_only)) ) { 410 ((!driver_name) && (backend->demand_only))) {
382 continue; 411 continue;
383 } 412 }
384 413
385 tried_to_init = 1; 414 tried_to_init = 1;
386 SDL_memset(&current_audio, 0, sizeof (current_audio)); 415 SDL_memset(&current_audio, 0, sizeof(current_audio));
387 current_audio.name = backend->name; 416 current_audio.name = backend->name;
388 current_audio.desc = backend->desc; 417 current_audio.desc = backend->desc;
389 initialized = backend->init(&current_audio.impl); 418 initialized = backend->init(&current_audio.impl);
390 } 419 }
391 420
397 } else { 426 } else {
398 SDL_SetError("No available audio device"); 427 SDL_SetError("No available audio device");
399 } 428 }
400 } 429 }
401 430
402 SDL_memset(&current_audio, 0, sizeof (current_audio)); 431 SDL_memset(&current_audio, 0, sizeof(current_audio));
403 return (-1); /* No driver was available, so fail. */ 432 return (-1); /* No driver was available, so fail. */
404 } 433 }
405 434
406 finalize_audio_entry_points(); 435 finalize_audio_entry_points();
407 436
408 return (0); 437 return (0);
469 return current_audio.impl.GetDeviceName(index, iscapture); 498 return current_audio.impl.GetDeviceName(index, iscapture);
470 } 499 }
471 500
472 501
473 static void 502 static void
474 close_audio_device(SDL_AudioDevice *device) 503 close_audio_device(SDL_AudioDevice * device)
475 { 504 {
476 device->enabled = 0; 505 device->enabled = 0;
477 if (device->thread != NULL) { 506 if (device->thread != NULL) {
478 SDL_WaitThread(device->thread, NULL); 507 SDL_WaitThread(device->thread, NULL);
479 } 508 }
498 * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig). 527 * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig).
499 * Fills in a sanitized copy in (prepared). 528 * Fills in a sanitized copy in (prepared).
500 * Returns non-zero if okay, zero on fatal parameters in (orig). 529 * Returns non-zero if okay, zero on fatal parameters in (orig).
501 */ 530 */
502 static int 531 static int
503 prepare_audiospec(const SDL_AudioSpec *orig, SDL_AudioSpec *prepared) 532 prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
504 { 533 {
505 SDL_memcpy(prepared, orig, sizeof (SDL_AudioSpec)); 534 SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec));
506 535
507 if (orig->callback == NULL) { 536 if (orig->callback == NULL) {
508 SDL_SetError("SDL_OpenAudio() passed a NULL callback"); 537 SDL_SetError("SDL_OpenAudio() passed a NULL callback");
509 return 0; 538 return 0;
510 } 539 }
511 540
512 if (orig->freq == 0) { 541 if (orig->freq == 0) {
513 const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY"); 542 const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY");
514 if ( (!env) || ((prepared->freq = SDL_atoi(env)) == 0) ) { 543 if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) {
515 prepared->freq = 22050; /* a reasonable default */ 544 prepared->freq = 22050; /* a reasonable default */
516 } 545 }
517 } 546 }
518 547
519 if (orig->format == 0) { 548 if (orig->format == 0) {
520 const char *env = SDL_getenv("SDL_AUDIO_FORMAT"); 549 const char *env = SDL_getenv("SDL_AUDIO_FORMAT");
521 if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) { 550 if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) {
522 prepared->format = AUDIO_S16; /* a reasonable default */ 551 prepared->format = AUDIO_S16; /* a reasonable default */
523 } 552 }
524 } 553 }
525 554
526 switch (orig->channels) { 555 switch (orig->channels) {
527 case 0: { 556 case 0:{
528 const char *env = SDL_getenv("SDL_AUDIO_CHANNELS"); 557 const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
529 if ( (!env) || ((prepared->channels = SDL_atoi(env)) == 0) ) { 558 if ((!env) || ((prepared->channels = SDL_atoi(env)) == 0)) {
530 prepared->channels = 2; /* a reasonable default */ 559 prepared->channels = 2; /* a reasonable default */
531 } 560 }
532 break; 561 break;
533 } 562 }
534 case 1: /* Mono */ 563 case 1: /* Mono */
535 case 2: /* Stereo */ 564 case 2: /* Stereo */
536 case 4: /* surround */ 565 case 4: /* surround */
537 case 6: /* surround with center and lfe */ 566 case 6: /* surround with center and lfe */
538 break; 567 break;
541 return 0; 570 return 0;
542 } 571 }
543 572
544 if (orig->samples == 0) { 573 if (orig->samples == 0) {
545 const char *env = SDL_getenv("SDL_AUDIO_SAMPLES"); 574 const char *env = SDL_getenv("SDL_AUDIO_SAMPLES");
546 if ( (!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0) ) { 575 if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) {
547 /* Pick a default of ~46 ms at desired frequency */ 576 /* Pick a default of ~46 ms at desired frequency */
548 /* !!! FIXME: remove this when the non-Po2 resampling is in. */ 577 /* !!! FIXME: remove this when the non-Po2 resampling is in. */
549 const int samples = (prepared->freq / 1000) * 46; 578 const int samples = (prepared->freq / 1000) * 46;
550 int power2 = 1; 579 int power2 = 1;
551 while (power2 < samples) { 580 while (power2 < samples) {
562 } 591 }
563 592
564 593
565 static SDL_AudioDeviceID 594 static SDL_AudioDeviceID
566 open_audio_device(const char *devname, int iscapture, 595 open_audio_device(const char *devname, int iscapture,
567 const SDL_AudioSpec *_desired, SDL_AudioSpec *obtained, 596 const SDL_AudioSpec * _desired, SDL_AudioSpec * obtained,
568 int min_id) 597 int min_id)
569 { 598 {
570 SDL_AudioDeviceID id = 0; 599 SDL_AudioDeviceID id = 0;
571 SDL_AudioSpec desired; 600 SDL_AudioSpec desired;
572 SDL_AudioDevice *device; 601 SDL_AudioDevice *device;
573 int i = 0; 602 int i = 0;
629 return 0; 658 return 0;
630 } 659 }
631 } 660 }
632 } 661 }
633 662
634 device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof (SDL_AudioDevice)); 663 device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice));
635 if (device == NULL) { 664 if (device == NULL) {
636 SDL_OutOfMemory(); 665 SDL_OutOfMemory();
637 return 0; 666 return 0;
638 } 667 }
639 SDL_memset(device, '\0', sizeof (SDL_AudioDevice)); 668 SDL_memset(device, '\0', sizeof(SDL_AudioDevice));
640 SDL_memcpy(&device->spec, &desired, sizeof (SDL_AudioSpec)); 669 SDL_memcpy(&device->spec, &desired, sizeof(SDL_AudioSpec));
641 device->enabled = 1; 670 device->enabled = 1;
642 device->paused = 1; 671 device->paused = 1;
643 device->iscapture = iscapture; 672 device->iscapture = iscapture;
644 673
645 /* Create a semaphore for locking the sound buffers */ 674 /* Create a semaphore for locking the sound buffers */
686 device->spec.freq) < 0) { 715 device->spec.freq) < 0) {
687 close_audio_device(device); 716 close_audio_device(device);
688 return 0; 717 return 0;
689 } 718 }
690 if (device->convert.needed) { 719 if (device->convert.needed) {
691 device->convert.len = (int) ( ((double) desired.size) / 720 device->convert.len = (int) (((double) desired.size) /
692 device->convert.len_ratio ); 721 device->convert.len_ratio);
693 722
694 device->convert.buf = 723 device->convert.buf =
695 (Uint8 *) SDL_AllocAudioMem(device->convert.len * 724 (Uint8 *) SDL_AllocAudioMem(device->convert.len *
696 device->convert.len_mult); 725 device->convert.len_mult);
697 if (device->convert.buf == NULL) { 726 if (device->convert.buf == NULL) {
701 } 730 }
702 } 731 }
703 } 732 }
704 733
705 /* Find an available device ID and store the structure... */ 734 /* Find an available device ID and store the structure... */
706 for (id = min_id-1; id < SDL_arraysize(open_devices); id++) { 735 for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
707 if (open_devices[id] == NULL) { 736 if (open_devices[id] == NULL) {
708 open_devices[id] = device; 737 open_devices[id] = device;
709 break; 738 break;
710 } 739 }
711 } 740 }
725 device->thread = SDL_CreateThread(SDL_RunAudio, device, NULL, NULL); 754 device->thread = SDL_CreateThread(SDL_RunAudio, device, NULL, NULL);
726 #else 755 #else
727 device->thread = SDL_CreateThread(SDL_RunAudio, device); 756 device->thread = SDL_CreateThread(SDL_RunAudio, device);
728 #endif 757 #endif
729 if (device->thread == NULL) { 758 if (device->thread == NULL) {
730 SDL_CloseAudioDevice(id+1); 759 SDL_CloseAudioDevice(id + 1);
731 SDL_SetError("Couldn't create audio thread"); 760 SDL_SetError("Couldn't create audio thread");
732 return 0; 761 return 0;
733 } 762 }
734 } 763 }
735 764
736 return id+1; 765 return id + 1;
737 } 766 }
738 767
739 768
740 int 769 int
741 SDL_OpenAudio(const SDL_AudioSpec * desired, SDL_AudioSpec * obtained) 770 SDL_OpenAudio(const SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
754 SDL_SetError("Audio device is already opened"); 783 SDL_SetError("Audio device is already opened");
755 return (-1); 784 return (-1);
756 } 785 }
757 786
758 id = open_audio_device(NULL, 0, desired, obtained, 1); 787 id = open_audio_device(NULL, 0, desired, obtained, 1);
759 if (id > 1) { /* this should never happen in theory... */ 788 if (id > 1) { /* this should never happen in theory... */
760 SDL_CloseAudioDevice(id); 789 SDL_CloseAudioDevice(id);
761 SDL_SetError("Internal error"); /* MUST be Device ID #1! */ 790 SDL_SetError("Internal error"); /* MUST be Device ID #1! */
762 return (-1); 791 return (-1);
763 } 792 }
764 793
765 return ((id == 0) ? -1 : 0); 794 return ((id == 0) ? -1 : 0);
766 } 795 }
767 796
768 SDL_AudioDeviceID 797 SDL_AudioDeviceID
769 SDL_OpenAudioDevice(const char *device, int iscapture, 798 SDL_OpenAudioDevice(const char *device, int iscapture,
770 const SDL_AudioSpec *desired, SDL_AudioSpec *obtained) 799 const SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
771 { 800 {
772 return open_audio_device(device, iscapture, desired, obtained, 2); 801 return open_audio_device(device, iscapture, desired, obtained, 2);
773 } 802 }
774 803
775 SDL_audiostatus 804 SDL_audiostatus
846 SDL_CloseAudioDevice(SDL_AudioDeviceID devid) 875 SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
847 { 876 {
848 SDL_AudioDevice *device = get_audio_device(devid); 877 SDL_AudioDevice *device = get_audio_device(devid);
849 if (device) { 878 if (device) {
850 close_audio_device(device); 879 close_audio_device(device);
851 open_devices[devid-1] = NULL; 880 open_devices[devid - 1] = NULL;
852 } 881 }
853 } 882 }
854 883
855 void 884 void
856 SDL_CloseAudio(void) 885 SDL_CloseAudio(void)
866 SDL_CloseAudioDevice(i); 895 SDL_CloseAudioDevice(i);
867 } 896 }
868 897
869 /* Free the driver data */ 898 /* Free the driver data */
870 current_audio.impl.Deinitialize(); 899 current_audio.impl.Deinitialize();
871 SDL_memset(&current_audio, '\0', sizeof (current_audio)); 900 SDL_memset(&current_audio, '\0', sizeof(current_audio));
872 SDL_memset(open_devices, '\0', sizeof (open_devices)); 901 SDL_memset(open_devices, '\0', sizeof(open_devices));
873 } 902 }
874 903
875 #define NUM_FORMATS 10 904 #define NUM_FORMATS 10
876 static int format_idx; 905 static int format_idx;
877 static int format_idx_sub; 906 static int format_idx_sub;