Mercurial > sdl-ios-xcode
comparison src/audio/SDL_audio.c @ 3796:b19680c84cdf SDL-ryan-multiple-audio-device
Bunch of 1.3 audio cleanups to remove FIXMEs, get driver specific crap out of
the core and into the drivers where it belongs, and push generic
responsibilities out of the drivers and into the core where they belong.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Wed, 04 Oct 2006 19:54:23 +0000 |
parents | 589bc3d060cd |
children | c8b3d3d13ed1 |
comparison
equal
deleted
inserted
replaced
3795:589bc3d060cd | 3796:b19680c84cdf |
---|---|
32 /* We'll need the DosSetPriority() API! */ | 32 /* We'll need the DosSetPriority() API! */ |
33 #define INCL_DOSPROCESS | 33 #define INCL_DOSPROCESS |
34 #include <os2.h> | 34 #include <os2.h> |
35 #endif | 35 #endif |
36 | 36 |
37 #define _THIS SDL_AudioDevice *this | |
38 | |
37 static SDL_AudioDriver current_audio; | 39 static SDL_AudioDriver current_audio; |
38 | 40 |
39 /* !!! FIXME: don't use a static array, but it's Good Enough For Now... */ | 41 /* !!! FIXME: don't use a static array, but it's Good Enough For Now... */ |
40 static SDL_AudioDevice *open_devices[16]; | 42 static SDL_AudioDevice *open_devices[16]; |
43 | |
44 /* !!! FIXME: These are wordy and unlocalized... */ | |
45 #define DEFAULT_OUTPUT_DEVNAME "System audio output device" | |
46 #define DEFAULT_INPUT_DEVNAME "System audio capture device" | |
47 | |
48 | |
49 /* | |
50 * Not all of these will be compiled and linked in, but it's convenient | |
51 * to have a complete list here and saves yet-another block of #ifdefs... | |
52 * Please see bootstrap[], below, for the actual #ifdef mess. | |
53 */ | |
54 extern AudioBootStrap BSD_AUDIO_bootstrap; | |
55 extern AudioBootStrap DSP_bootstrap; | |
56 extern AudioBootStrap DMA_bootstrap; | |
57 extern AudioBootStrap ALSA_bootstrap; | |
58 extern AudioBootStrap QNXNTOAUDIO_bootstrap; | |
59 extern AudioBootStrap SUNAUDIO_bootstrap; | |
60 extern AudioBootStrap DMEDIA_bootstrap; | |
61 extern AudioBootStrap ARTS_bootstrap; | |
62 extern AudioBootStrap ESD_bootstrap; | |
63 extern AudioBootStrap NAS_bootstrap; | |
64 extern AudioBootStrap DSOUND_bootstrap; | |
65 extern AudioBootStrap WAVEOUT_bootstrap; | |
66 extern AudioBootStrap Paud_bootstrap; | |
67 extern AudioBootStrap BAUDIO_bootstrap; | |
68 extern AudioBootStrap COREAUDIO_bootstrap; | |
69 extern AudioBootStrap SNDMGR_bootstrap; | |
70 extern AudioBootStrap AHI_bootstrap; | |
71 extern AudioBootStrap MINTAUDIO_GSXB_bootstrap; | |
72 extern AudioBootStrap MINTAUDIO_MCSN_bootstrap; | |
73 extern AudioBootStrap MINTAUDIO_STFA_bootstrap; | |
74 extern AudioBootStrap MINTAUDIO_XBIOS_bootstrap; | |
75 extern AudioBootStrap MINTAUDIO_DMA8_bootstrap; | |
76 extern AudioBootStrap DISKAUD_bootstrap; | |
77 extern AudioBootStrap DUMMYAUD_bootstrap; | |
78 extern AudioBootStrap DCAUD_bootstrap; | |
79 extern AudioBootStrap MMEAUDIO_bootstrap; | |
80 extern AudioBootStrap DART_bootstrap; | |
41 | 81 |
42 | 82 |
43 /* Available audio drivers */ | 83 /* Available audio drivers */ |
44 static AudioBootStrap *bootstrap[] = { | 84 static AudioBootStrap *bootstrap[] = { |
45 #if SDL_AUDIO_DRIVER_BSD | 85 #if SDL_AUDIO_DRIVER_BSD |
131 return open_devices[id]; | 171 return open_devices[id]; |
132 } | 172 } |
133 | 173 |
134 | 174 |
135 /* stubs for audio drivers that don't need a specific entry point... */ | 175 /* stubs for audio drivers that don't need a specific entry point... */ |
136 /* !!! FIXME: fill in more of these. */ | 176 static int SDL_AudioDetectDevices_Default(int iscapture) { return -1; } |
137 | 177 static void SDL_AudioThreadInit_Default(_THIS) { /* no-op. */ } |
138 static void SDL_DeinitializeAudio_Default(void) | 178 static void SDL_AudioWaitDevice_Default(_THIS) { /* no-op. */ } |
139 { | 179 static void SDL_AudioPlayDevice_Default(_THIS) { /* no-op. */ } |
140 /* no-op. */ | 180 static Uint8 *SDL_AudioGetDeviceBuf_Default(_THIS) { return NULL; } |
141 } | 181 static void SDL_AudioWaitDone_Default(_THIS) { /* no-op. */ } |
142 | 182 static void SDL_AudioCloseDevice_Default(_THIS) { /* no-op. */ } |
183 static void SDL_AudioDeinitialize_Default(void) { /* no-op. */ } | |
184 | |
185 static int | |
186 SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture) | |
187 { | |
188 return 0; | |
189 } | |
190 | |
191 static const char *SDL_AudioGetDeviceName_Default(int index, int iscapture) | |
192 { | |
193 SDL_SetError("No such device"); | |
194 return NULL; | |
195 } | |
196 | |
197 static void | |
198 SDL_AudioLockDevice_Default(SDL_AudioDevice * device) | |
199 { | |
200 if (device->thread && (SDL_ThreadID() == device->threadid)) { | |
201 return; | |
202 } | |
203 SDL_mutexP(device->mixer_lock); | |
204 } | |
205 | |
206 static void | |
207 SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device) | |
208 { | |
209 if (device->thread && (SDL_ThreadID() == device->threadid)) { | |
210 return; | |
211 } | |
212 SDL_mutexV(device->mixer_lock); | |
213 } | |
214 | |
215 | |
216 static void finalize_audio_entry_points(void) | |
217 { | |
218 /* | |
219 * Fill in stub functions for unused driver entry points. This lets us | |
220 * blindly call them without having to check for validity first. | |
221 */ | |
222 | |
223 #define FILL_STUB(x) \ | |
224 if (current_audio.impl.x == NULL) { \ | |
225 current_audio.impl.x = SDL_Audio##x##_Default; \ | |
226 } | |
227 FILL_STUB(DetectDevices); | |
228 FILL_STUB(GetDeviceName); | |
229 FILL_STUB(OpenDevice); | |
230 FILL_STUB(ThreadInit); | |
231 FILL_STUB(WaitDevice); | |
232 FILL_STUB(PlayDevice); | |
233 FILL_STUB(GetDeviceBuf); | |
234 FILL_STUB(WaitDone); | |
235 FILL_STUB(CloseDevice); | |
236 FILL_STUB(LockDevice); | |
237 FILL_STUB(UnlockDevice); | |
238 FILL_STUB(Deinitialize); | |
239 #undef FILL_STUB | |
240 } | |
143 | 241 |
144 | 242 |
145 /* The general mixing thread function */ | 243 /* The general mixing thread function */ |
146 int SDLCALL | 244 int SDLCALL |
147 SDL_RunAudio(void *devicep) | 245 SDL_RunAudio(void *devicep) |
170 } | 268 } |
171 D(bug("OpenAudio...OK\n")); | 269 D(bug("OpenAudio...OK\n")); |
172 #endif | 270 #endif |
173 | 271 |
174 /* Perform any thread setup */ | 272 /* Perform any thread setup */ |
175 if (current_audio.impl.ThreadInit != NULL) { | |
176 current_audio.impl.ThreadInit(device); | |
177 } | |
178 device->threadid = SDL_ThreadID(); | 273 device->threadid = SDL_ThreadID(); |
274 current_audio.impl.ThreadInit(device); | |
179 | 275 |
180 /* Set up the mixing function */ | 276 /* Set up the mixing function */ |
181 fill = device->spec.callback; | 277 fill = device->spec.callback; |
182 udata = device->spec.userdata; | 278 udata = device->spec.userdata; |
183 | 279 |
202 } | 298 } |
203 | 299 |
204 #if SDL_AUDIO_DRIVER_AHI | 300 #if SDL_AUDIO_DRIVER_AHI |
205 SDL_mutexV(device->mixer_lock); | 301 SDL_mutexV(device->mixer_lock); |
206 D(bug("Entering audio loop...\n")); | 302 D(bug("Entering audio loop...\n")); |
207 #endif | |
208 | |
209 /* !!! FIXME: push this out of core. */ | |
210 #ifdef __OS2__ | |
211 /* Increase the priority of this thread to make sure that | |
212 the audio will be continuous all the time! */ | |
213 #ifdef USE_DOSSETPRIORITY | |
214 if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) { | |
215 #ifdef DEBUG_BUILD | |
216 printf | |
217 ("[SDL_RunAudio] : Setting priority to TimeCritical+0! (TID%d)\n", | |
218 SDL_ThreadID()); | |
219 #endif | |
220 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); | |
221 } else { | |
222 #ifdef DEBUG_BUILD | |
223 printf | |
224 ("[SDL_RunAudio] : Setting priority to ForegroundServer+0! (TID%d)\n", | |
225 SDL_ThreadID()); | |
226 #endif | |
227 DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0); | |
228 } | |
229 #endif | |
230 #endif | 303 #endif |
231 | 304 |
232 /* Loop, filling the audio buffers */ | 305 /* Loop, filling the audio buffers */ |
233 while (device->enabled) { | 306 while (device->enabled) { |
234 | 307 |
279 current_audio.impl.WaitDevice(device); | 352 current_audio.impl.WaitDevice(device); |
280 } | 353 } |
281 } | 354 } |
282 | 355 |
283 /* Wait for the audio to drain.. */ | 356 /* Wait for the audio to drain.. */ |
284 if (current_audio.impl.WaitDone) { | 357 current_audio.impl.WaitDone(device); |
285 current_audio.impl.WaitDone(device); | 358 |
286 } | 359 /* !!! FIXME: get this out of core. */ |
287 #if SDL_AUDIO_DRIVER_AHI | 360 #if SDL_AUDIO_DRIVER_AHI |
288 D(bug("WaitDevice...Done\n")); | 361 D(bug("WaitDevice...Done\n")); |
289 | 362 current_audio.impl.CloseDevice(device); |
290 audio->CloseDevice(audio); | 363 device->opened = 0; |
291 | |
292 D(bug("CloseDevice..Done, subtask exiting...\n")); | 364 D(bug("CloseDevice..Done, subtask exiting...\n")); |
293 audio_configured = 0; | 365 audio_configured = 0; |
294 #endif | 366 #endif |
295 #ifdef __OS2__ | 367 |
296 #ifdef DEBUG_BUILD | |
297 printf("[SDL_RunAudio] : Task exiting. (TID%d)\n", SDL_ThreadID()); | |
298 #endif | |
299 #endif | |
300 return (0); | 368 return (0); |
301 } | 369 } |
302 | 370 |
303 static void | |
304 SDL_LockDevice_Default(SDL_AudioDevice * audio) | |
305 { | |
306 if (audio->thread && (SDL_ThreadID() == audio->threadid)) { | |
307 return; | |
308 } | |
309 SDL_mutexP(audio->mixer_lock); | |
310 } | |
311 | |
312 static void | |
313 SDL_UnlockDevice_Default(SDL_AudioDevice * audio) | |
314 { | |
315 if (audio->thread && (SDL_ThreadID() == audio->threadid)) { | |
316 return; | |
317 } | |
318 SDL_mutexV(audio->mixer_lock); | |
319 } | |
320 | 371 |
321 static SDL_AudioFormat | 372 static SDL_AudioFormat |
322 SDL_ParseAudioFormat(const char *string) | 373 SDL_ParseAudioFormat(const char *string) |
323 { | 374 { |
324 #define CHECK_FMT_STRING(x) if (strcmp(string, #x) == 0) return AUDIO_##x | 375 #define CHECK_FMT_STRING(x) if (strcmp(string, #x) == 0) return AUDIO_##x |
446 SDL_memset(¤t_audio, 0, sizeof (current_audio)); | 497 SDL_memset(¤t_audio, 0, sizeof (current_audio)); |
447 return (-1); /* No driver was available, so fail. */ | 498 return (-1); /* No driver was available, so fail. */ |
448 } | 499 } |
449 } | 500 } |
450 | 501 |
451 if (!current_audio.impl.LockDevice && !current_audio.impl.UnlockDevice) { | 502 finalize_audio_entry_points(); |
452 current_audio.impl.LockDevice = SDL_LockDevice_Default; | |
453 current_audio.impl.UnlockDevice = SDL_UnlockDevice_Default; | |
454 } | |
455 | |
456 if (!current_audio.impl.Deinitialize) { | |
457 current_audio.impl.Deinitialize = SDL_DeinitializeAudio_Default; | |
458 } | |
459 | 503 |
460 return (0); | 504 return (0); |
461 } | 505 } |
462 | 506 |
463 /* | 507 /* |
471 | 515 |
472 | 516 |
473 int | 517 int |
474 SDL_GetNumAudioDevices(int iscapture) | 518 SDL_GetNumAudioDevices(int iscapture) |
475 { | 519 { |
476 if (!SDL_WasInit(SDL_INIT_AUDIO) || !current_audio.impl.DetectDevices) { | 520 if (!SDL_WasInit(SDL_INIT_AUDIO)) { |
477 return -1; | 521 return -1; |
478 } | 522 } |
523 if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) { | |
524 return 0; | |
525 } | |
526 | |
527 if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) { | |
528 return 1; | |
529 } | |
530 | |
531 if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { | |
532 return 1; | |
533 } | |
534 | |
479 return current_audio.impl.DetectDevices(iscapture); | 535 return current_audio.impl.DetectDevices(iscapture); |
480 } | 536 } |
481 | 537 |
482 | 538 |
483 const char * | 539 const char * |
486 if (!SDL_WasInit(SDL_INIT_AUDIO)) { | 542 if (!SDL_WasInit(SDL_INIT_AUDIO)) { |
487 SDL_SetError("Audio subsystem is not initialized"); | 543 SDL_SetError("Audio subsystem is not initialized"); |
488 return NULL; | 544 return NULL; |
489 } | 545 } |
490 | 546 |
491 if ((index < 0) && (!current_audio.impl.GetDeviceName)) { | 547 if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) { |
548 SDL_SetError("No capture support"); | |
549 return NULL; | |
550 } | |
551 | |
552 if (index < 0) { | |
492 SDL_SetError("No such device"); | 553 SDL_SetError("No such device"); |
493 return NULL; | 554 return NULL; |
555 } | |
556 | |
557 if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) { | |
558 return DEFAULT_INPUT_DEVNAME; | |
559 } | |
560 | |
561 if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { | |
562 return DEFAULT_OUTPUT_DEVNAME; | |
494 } | 563 } |
495 | 564 |
496 return current_audio.impl.GetDeviceName(index, iscapture); | 565 return current_audio.impl.GetDeviceName(index, iscapture); |
497 } | 566 } |
498 | 567 |
511 SDL_FreeAudioMem(device->fake_stream); | 580 SDL_FreeAudioMem(device->fake_stream); |
512 } | 581 } |
513 if (device->convert.needed) { | 582 if (device->convert.needed) { |
514 SDL_FreeAudioMem(device->convert.buf); | 583 SDL_FreeAudioMem(device->convert.buf); |
515 } | 584 } |
516 #if !SDL_AUDIO_DRIVER_AHI /* !!! FIXME: get rid of this #if. */ | |
517 if (device->opened) { | 585 if (device->opened) { |
518 current_audio.impl.CloseDevice(device); | 586 current_audio.impl.CloseDevice(device); |
519 device->opened = 0; | 587 device->opened = 0; |
520 } | 588 } |
521 #endif | |
522 SDL_FreeAudioMem(device); | 589 SDL_FreeAudioMem(device); |
523 } | 590 } |
524 | 591 |
525 | 592 |
526 /* | 593 /* |
594 static SDL_AudioDeviceID | 661 static SDL_AudioDeviceID |
595 open_audio_device(const char *devname, int iscapture, | 662 open_audio_device(const char *devname, int iscapture, |
596 const SDL_AudioSpec *_desired, SDL_AudioSpec *obtained, | 663 const SDL_AudioSpec *_desired, SDL_AudioSpec *obtained, |
597 int min_id) | 664 int min_id) |
598 { | 665 { |
599 int i = 0; | |
600 SDL_AudioDeviceID id = 0; | 666 SDL_AudioDeviceID id = 0; |
601 SDL_AudioSpec desired; | 667 SDL_AudioSpec desired; |
602 SDL_AudioDevice *device; | 668 SDL_AudioDevice *device; |
603 | 669 int i = 0; |
604 if (iscapture) { | |
605 SDL_SetError("Audio capture support not implemented yet!"); | |
606 return 0; /* !!! FIXME */ | |
607 } | |
608 | 670 |
609 if (!SDL_WasInit(SDL_INIT_AUDIO)) { | 671 if (!SDL_WasInit(SDL_INIT_AUDIO)) { |
610 SDL_SetError("Audio subsystem is not initialized"); | 672 SDL_SetError("Audio subsystem is not initialized"); |
611 return 0; | 673 return 0; |
612 } | 674 } |
613 | 675 |
676 if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) { | |
677 SDL_SetError("No capture support"); | |
678 return 0; | |
679 } | |
680 | |
614 if (!prepare_audiospec(_desired, &desired)) { | 681 if (!prepare_audiospec(_desired, &desired)) { |
615 return 0; | 682 return 0; |
616 } | 683 } |
617 | 684 |
618 /* If app doesn't care about a specific device, let the user override. */ | 685 /* If app doesn't care about a specific device, let the user override. */ |
619 if (devname == NULL) { | 686 if (devname == NULL) { |
620 devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME"); | 687 devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME"); |
688 } | |
689 | |
690 /* | |
691 * Catch device names at the high level for the simple case... | |
692 * This lets us have a basic "device enumeration" for systems that | |
693 * don't have multiple devices, but makes sure the device name is | |
694 * always NULL when it hits the low level. | |
695 * | |
696 * Also make sure that the simple case prevents multiple simultaneous | |
697 * opens of the default system device. | |
698 */ | |
699 | |
700 if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) { | |
701 if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) { | |
702 SDL_SetError("No such device"); | |
703 return 0; | |
704 } | |
705 devname = NULL; | |
706 | |
707 for (i = 0; i < SDL_arraysize(open_devices); i++) { | |
708 if ((open_devices[i]) && (open_devices[i]->iscapture)) { | |
709 SDL_SetError("Audio device already open"); | |
710 return; | |
711 } | |
712 } | |
713 } | |
714 | |
715 if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { | |
716 if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) { | |
717 SDL_SetError("No such device"); | |
718 return 0; | |
719 } | |
720 devname = NULL; | |
721 | |
722 for (i = 0; i < SDL_arraysize(open_devices); i++) { | |
723 if ((open_devices[i]) && (!open_devices[i]->iscapture)) { | |
724 SDL_SetError("Audio device already open"); | |
725 return; | |
726 } | |
727 } | |
621 } | 728 } |
622 | 729 |
623 device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof (SDL_AudioDevice)); | 730 device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof (SDL_AudioDevice)); |
624 if (device == NULL) { | 731 if (device == NULL) { |
625 SDL_OutOfMemory(); | 732 SDL_OutOfMemory(); |
626 return 0; | 733 return 0; |
627 } | 734 } |
628 SDL_memset(device, '\0', sizeof (SDL_AudioDevice)); | 735 SDL_memset(device, '\0', sizeof (SDL_AudioDevice)); |
629 SDL_memcpy(&device->spec, &desired, sizeof (SDL_AudioSpec)); | 736 SDL_memcpy(&device->spec, &desired, sizeof (SDL_AudioSpec)); |
630 device->driver = ¤t_audio; /* !!! FIXME: unused... */ | |
631 device->enabled = 1; | 737 device->enabled = 1; |
632 device->paused = 1; | 738 device->paused = 1; |
633 | 739 device->iscapture = iscapture; |
634 /* !!! FIXME: Get this out of the core. */ | 740 |
635 #if defined(__MINT__) && SDL_THREADS_DISABLED | |
636 /* Uses interrupt driven audio, without thread */ | |
637 #else | |
638 /* Create a semaphore for locking the sound buffers */ | 741 /* Create a semaphore for locking the sound buffers */ |
639 device->mixer_lock = SDL_CreateMutex(); | 742 if (!current_audio.impl.SkipMixerLock) { |
640 if (device->mixer_lock == NULL) { | 743 device->mixer_lock = SDL_CreateMutex(); |
641 SDL_SetError("Couldn't create mixer lock"); | 744 if (device->mixer_lock == NULL) { |
642 return 0; | 745 close_audio_device(device); |
643 } | 746 SDL_SetError("Couldn't create mixer lock"); |
644 #endif /* __MINT__ */ | 747 return 0; |
748 } | |
749 } | |
645 | 750 |
646 /* !!! FIXME: Get this #if out of the core. */ | 751 /* !!! FIXME: Get this #if out of the core. */ |
647 /* AmigaOS opens audio inside the main loop */ | 752 /* AmigaOS opens audio inside the main loop */ |
648 #if !SDL_AUDIO_DRIVER_AHI | 753 #if !SDL_AUDIO_DRIVER_AHI |
649 if (!current_audio.impl.OpenDevice(device, devname, iscapture)) { | 754 if (!current_audio.impl.OpenDevice(device, devname, iscapture)) { |
650 close_audio_device(device); | 755 close_audio_device(device); |
651 return 0; | 756 return 0; |
652 } | 757 } |
653 device->opened = 2; /* !!! FIXME */ | 758 device->opened = 1; |
654 #else | 759 #else |
655 # error needs to be fixed for new internal API. Email Ryan for details. | 760 # error needs to be fixed for new internal API. Email Ryan for details. |
656 | 761 |
657 D(bug("Locking semaphore...")); | 762 D(bug("Locking semaphore...")); |
658 SDL_mutexP(audio->mixer_lock); | 763 SDL_mutexP(audio->mixer_lock); |
727 SDL_SetError("Too many open audio devices"); | 832 SDL_SetError("Too many open audio devices"); |
728 close_audio_device(device); | 833 close_audio_device(device); |
729 return 0; | 834 return 0; |
730 } | 835 } |
731 | 836 |
837 /* !!! FIXME: get this out of core. */ | |
732 #if !SDL_AUDIO_DRIVER_AHI | 838 #if !SDL_AUDIO_DRIVER_AHI |
733 /* Start the audio thread if necessary */ | 839 /* Start the audio thread if necessary */ |
734 switch (device->opened) { /* !!! FIXME: what is this?! */ | 840 if (!current_audio.impl.ProvidesOwnCallbackThread) { |
735 case 1: | |
736 /* Start the audio thread */ | 841 /* Start the audio thread */ |
737 /* !!! FIXME: this is nasty. */ | 842 /* !!! FIXME: this is nasty. */ |
738 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) | 843 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) |
739 #undef SDL_CreateThread | 844 #undef SDL_CreateThread |
740 device->thread = SDL_CreateThread(SDL_RunAudio, device, NULL, NULL); | 845 device->thread = SDL_CreateThread(SDL_RunAudio, device, NULL, NULL); |
744 if (device->thread == NULL) { | 849 if (device->thread == NULL) { |
745 SDL_CloseAudioDevice(id+1); | 850 SDL_CloseAudioDevice(id+1); |
746 SDL_SetError("Couldn't create audio thread"); | 851 SDL_SetError("Couldn't create audio thread"); |
747 return 0; | 852 return 0; |
748 } | 853 } |
749 break; | 854 } |
750 | 855 |
751 default: | |
752 /* The audio is now playing */ | |
753 break; | |
754 } | |
755 #else | 856 #else |
756 SDL_mutexV(audio->mixer_lock); | 857 SDL_mutexV(audio->mixer_lock); |
757 D(bug("SDL_OpenAudio USCITA...\n")); | 858 D(bug("SDL_OpenAudio USCITA...\n")); |
758 | 859 |
759 #endif | 860 #endif |
836 | 937 |
837 | 938 |
838 void | 939 void |
839 SDL_LockAudioDevice(SDL_AudioDeviceID devid) | 940 SDL_LockAudioDevice(SDL_AudioDeviceID devid) |
840 { | 941 { |
841 if (current_audio.impl.LockDevice != NULL) { | 942 /* Obtain a lock on the mixing buffers */ |
842 SDL_AudioDevice *device = get_audio_device(devid); | 943 SDL_AudioDevice *device = get_audio_device(devid); |
843 /* Obtain a lock on the mixing buffers */ | 944 if (device) { |
844 if (device) { | 945 current_audio.impl.LockDevice(device); |
845 current_audio.impl.LockDevice(device); | |
846 } | |
847 } | 946 } |
848 } | 947 } |
849 | 948 |
850 void | 949 void |
851 SDL_LockAudio(void) | 950 SDL_LockAudio(void) |
854 } | 953 } |
855 | 954 |
856 void | 955 void |
857 SDL_UnlockAudioDevice(SDL_AudioDeviceID devid) | 956 SDL_UnlockAudioDevice(SDL_AudioDeviceID devid) |
858 { | 957 { |
859 if (current_audio.impl.UnlockDevice != NULL) { | 958 /* Obtain a lock on the mixing buffers */ |
860 SDL_AudioDevice *device = get_audio_device(devid); | 959 SDL_AudioDevice *device = get_audio_device(devid); |
861 /* Obtain a lock on the mixing buffers */ | 960 if (device) { |
862 if (device) { | 961 current_audio.impl.UnlockDevice(device); |
863 current_audio.impl.UnlockDevice(device); | |
864 } | |
865 } | 962 } |
866 } | 963 } |
867 | 964 |
868 void | 965 void |
869 SDL_UnlockAudio(void) | 966 SDL_UnlockAudio(void) |