SDL_audio.c (52469B)
1 /* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20 */ 21 #include "../SDL_internal.h" 22 23 /* Allow access to a raw mixing buffer */ 24 25 #include "SDL.h" 26 #include "SDL_audio.h" 27 #include "SDL_audio_c.h" 28 #include "SDL_sysaudio.h" 29 #include "../thread/SDL_systhread.h" 30 31 #define _THIS SDL_AudioDevice *_this 32 33 static SDL_AudioDriver current_audio; 34 static SDL_AudioDevice *open_devices[16]; 35 36 /* Available audio drivers */ 37 static const AudioBootStrap *const bootstrap[] = { 38 #if SDL_AUDIO_DRIVER_PULSEAUDIO 39 &PULSEAUDIO_bootstrap, 40 #endif 41 #if SDL_AUDIO_DRIVER_ALSA 42 &ALSA_bootstrap, 43 #endif 44 #if SDL_AUDIO_DRIVER_SNDIO 45 &SNDIO_bootstrap, 46 #endif 47 #if SDL_AUDIO_DRIVER_NETBSD 48 &NETBSDAUDIO_bootstrap, 49 #endif 50 #if SDL_AUDIO_DRIVER_OSS 51 &DSP_bootstrap, 52 #endif 53 #if SDL_AUDIO_DRIVER_QSA 54 &QSAAUDIO_bootstrap, 55 #endif 56 #if SDL_AUDIO_DRIVER_SUNAUDIO 57 &SUNAUDIO_bootstrap, 58 #endif 59 #if SDL_AUDIO_DRIVER_ARTS 60 &ARTS_bootstrap, 61 #endif 62 #if SDL_AUDIO_DRIVER_ESD 63 &ESD_bootstrap, 64 #endif 65 #if SDL_AUDIO_DRIVER_NACL 66 &NACLAUDIO_bootstrap, 67 #endif 68 #if SDL_AUDIO_DRIVER_NAS 69 &NAS_bootstrap, 70 #endif 71 #if SDL_AUDIO_DRIVER_WASAPI 72 &WASAPI_bootstrap, 73 #endif 74 #if SDL_AUDIO_DRIVER_DSOUND 75 &DSOUND_bootstrap, 76 #endif 77 #if SDL_AUDIO_DRIVER_WINMM 78 &WINMM_bootstrap, 79 #endif 80 #if SDL_AUDIO_DRIVER_PAUDIO 81 &PAUDIO_bootstrap, 82 #endif 83 #if SDL_AUDIO_DRIVER_HAIKU 84 &HAIKUAUDIO_bootstrap, 85 #endif 86 #if SDL_AUDIO_DRIVER_COREAUDIO 87 &COREAUDIO_bootstrap, 88 #endif 89 #if SDL_AUDIO_DRIVER_FUSIONSOUND 90 &FUSIONSOUND_bootstrap, 91 #endif 92 #if SDL_AUDIO_DRIVER_OPENSLES 93 &openslES_bootstrap, 94 #endif 95 #if SDL_AUDIO_DRIVER_ANDROID 96 &ANDROIDAUDIO_bootstrap, 97 #endif 98 #if SDL_AUDIO_DRIVER_PSP 99 &PSPAUDIO_bootstrap, 100 #endif 101 #if SDL_AUDIO_DRIVER_EMSCRIPTEN 102 &EMSCRIPTENAUDIO_bootstrap, 103 #endif 104 #if SDL_AUDIO_DRIVER_JACK 105 &JACK_bootstrap, 106 #endif 107 #if SDL_AUDIO_DRIVER_OS2 108 &OS2AUDIO_bootstrap, 109 #endif 110 #if SDL_AUDIO_DRIVER_DISK 111 &DISKAUDIO_bootstrap, 112 #endif 113 #if SDL_AUDIO_DRIVER_DUMMY 114 &DUMMYAUDIO_bootstrap, 115 #endif 116 NULL 117 }; 118 119 120 #ifdef HAVE_LIBSAMPLERATE_H 121 #ifdef SDL_LIBSAMPLERATE_DYNAMIC 122 static void *SRC_lib = NULL; 123 #endif 124 SDL_bool SRC_available = SDL_FALSE; 125 int SRC_converter = 0; 126 SRC_STATE* (*SRC_src_new)(int converter_type, int channels, int *error) = NULL; 127 int (*SRC_src_process)(SRC_STATE *state, SRC_DATA *data) = NULL; 128 int (*SRC_src_reset)(SRC_STATE *state) = NULL; 129 SRC_STATE* (*SRC_src_delete)(SRC_STATE *state) = NULL; 130 const char* (*SRC_src_strerror)(int error) = NULL; 131 132 static SDL_bool 133 LoadLibSampleRate(void) 134 { 135 const char *hint = SDL_GetHint(SDL_HINT_AUDIO_RESAMPLING_MODE); 136 137 SRC_available = SDL_FALSE; 138 SRC_converter = 0; 139 140 if (!hint || *hint == '0' || SDL_strcasecmp(hint, "default") == 0) { 141 return SDL_FALSE; /* don't load anything. */ 142 } else if (*hint == '1' || SDL_strcasecmp(hint, "fast") == 0) { 143 SRC_converter = SRC_SINC_FASTEST; 144 } else if (*hint == '2' || SDL_strcasecmp(hint, "medium") == 0) { 145 SRC_converter = SRC_SINC_MEDIUM_QUALITY; 146 } else if (*hint == '3' || SDL_strcasecmp(hint, "best") == 0) { 147 SRC_converter = SRC_SINC_BEST_QUALITY; 148 } else { 149 return SDL_FALSE; /* treat it like "default", don't load anything. */ 150 } 151 152 #ifdef SDL_LIBSAMPLERATE_DYNAMIC 153 SDL_assert(SRC_lib == NULL); 154 SRC_lib = SDL_LoadObject(SDL_LIBSAMPLERATE_DYNAMIC); 155 if (!SRC_lib) { 156 SDL_ClearError(); 157 return SDL_FALSE; 158 } 159 160 SRC_src_new = (SRC_STATE* (*)(int converter_type, int channels, int *error))SDL_LoadFunction(SRC_lib, "src_new"); 161 SRC_src_process = (int (*)(SRC_STATE *state, SRC_DATA *data))SDL_LoadFunction(SRC_lib, "src_process"); 162 SRC_src_reset = (int(*)(SRC_STATE *state))SDL_LoadFunction(SRC_lib, "src_reset"); 163 SRC_src_delete = (SRC_STATE* (*)(SRC_STATE *state))SDL_LoadFunction(SRC_lib, "src_delete"); 164 SRC_src_strerror = (const char* (*)(int error))SDL_LoadFunction(SRC_lib, "src_strerror"); 165 166 if (!SRC_src_new || !SRC_src_process || !SRC_src_reset || !SRC_src_delete || !SRC_src_strerror) { 167 SDL_UnloadObject(SRC_lib); 168 SRC_lib = NULL; 169 return SDL_FALSE; 170 } 171 #else 172 SRC_src_new = src_new; 173 SRC_src_process = src_process; 174 SRC_src_reset = src_reset; 175 SRC_src_delete = src_delete; 176 SRC_src_strerror = src_strerror; 177 #endif 178 179 SRC_available = SDL_TRUE; 180 return SDL_TRUE; 181 } 182 183 static void 184 UnloadLibSampleRate(void) 185 { 186 #ifdef SDL_LIBSAMPLERATE_DYNAMIC 187 if (SRC_lib != NULL) { 188 SDL_UnloadObject(SRC_lib); 189 } 190 SRC_lib = NULL; 191 #endif 192 193 SRC_available = SDL_FALSE; 194 SRC_src_new = NULL; 195 SRC_src_process = NULL; 196 SRC_src_reset = NULL; 197 SRC_src_delete = NULL; 198 SRC_src_strerror = NULL; 199 } 200 #endif 201 202 static SDL_AudioDevice * 203 get_audio_device(SDL_AudioDeviceID id) 204 { 205 id--; 206 if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) { 207 SDL_SetError("Invalid audio device ID"); 208 return NULL; 209 } 210 211 return open_devices[id]; 212 } 213 214 215 /* stubs for audio drivers that don't need a specific entry point... */ 216 static void 217 SDL_AudioDetectDevices_Default(void) 218 { 219 /* you have to write your own implementation if these assertions fail. */ 220 SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice); 221 SDL_assert(current_audio.impl.OnlyHasDefaultCaptureDevice || !current_audio.impl.HasCaptureSupport); 222 223 SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1)); 224 if (current_audio.impl.HasCaptureSupport) { 225 SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2)); 226 } 227 } 228 229 static void 230 SDL_AudioThreadInit_Default(_THIS) 231 { /* no-op. */ 232 } 233 234 static void 235 SDL_AudioThreadDeinit_Default(_THIS) 236 { /* no-op. */ 237 } 238 239 static void 240 SDL_AudioBeginLoopIteration_Default(_THIS) 241 { /* no-op. */ 242 } 243 244 static void 245 SDL_AudioWaitDevice_Default(_THIS) 246 { /* no-op. */ 247 } 248 249 static void 250 SDL_AudioPlayDevice_Default(_THIS) 251 { /* no-op. */ 252 } 253 254 static Uint8 * 255 SDL_AudioGetDeviceBuf_Default(_THIS) 256 { 257 return NULL; 258 } 259 260 static int 261 SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen) 262 { 263 return -1; /* just fail immediately. */ 264 } 265 266 static void 267 SDL_AudioFlushCapture_Default(_THIS) 268 { /* no-op. */ 269 } 270 271 static void 272 SDL_AudioPrepareToClose_Default(_THIS) 273 { /* no-op. */ 274 } 275 276 static void 277 SDL_AudioCloseDevice_Default(_THIS) 278 { /* no-op. */ 279 } 280 281 static void 282 SDL_AudioDeinitialize_Default(void) 283 { /* no-op. */ 284 } 285 286 static void 287 SDL_AudioFreeDeviceHandle_Default(void *handle) 288 { /* no-op. */ 289 } 290 291 292 static int 293 SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture) 294 { 295 return SDL_Unsupported(); 296 } 297 298 static SDL_INLINE SDL_bool 299 is_in_audio_device_thread(SDL_AudioDevice * device) 300 { 301 /* The device thread locks the same mutex, but not through the public API. 302 This check is in case the application, in the audio callback, 303 tries to lock the thread that we've already locked from the 304 device thread...just in case we only have non-recursive mutexes. */ 305 if (device->thread && (SDL_ThreadID() == device->threadid)) { 306 return SDL_TRUE; 307 } 308 309 return SDL_FALSE; 310 } 311 312 static void 313 SDL_AudioLockDevice_Default(SDL_AudioDevice * device) 314 { 315 if (!is_in_audio_device_thread(device)) { 316 SDL_LockMutex(device->mixer_lock); 317 } 318 } 319 320 static void 321 SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device) 322 { 323 if (!is_in_audio_device_thread(device)) { 324 SDL_UnlockMutex(device->mixer_lock); 325 } 326 } 327 328 static void 329 SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device) 330 { 331 } 332 333 static void 334 finish_audio_entry_points_init(void) 335 { 336 /* 337 * Fill in stub functions for unused driver entry points. This lets us 338 * blindly call them without having to check for validity first. 339 */ 340 341 if (current_audio.impl.SkipMixerLock) { 342 if (current_audio.impl.LockDevice == NULL) { 343 current_audio.impl.LockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock; 344 } 345 if (current_audio.impl.UnlockDevice == NULL) { 346 current_audio.impl.UnlockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock; 347 } 348 } 349 350 #define FILL_STUB(x) \ 351 if (current_audio.impl.x == NULL) { \ 352 current_audio.impl.x = SDL_Audio##x##_Default; \ 353 } 354 FILL_STUB(DetectDevices); 355 FILL_STUB(OpenDevice); 356 FILL_STUB(ThreadInit); 357 FILL_STUB(ThreadDeinit); 358 FILL_STUB(BeginLoopIteration); 359 FILL_STUB(WaitDevice); 360 FILL_STUB(PlayDevice); 361 FILL_STUB(GetDeviceBuf); 362 FILL_STUB(CaptureFromDevice); 363 FILL_STUB(FlushCapture); 364 FILL_STUB(PrepareToClose); 365 FILL_STUB(CloseDevice); 366 FILL_STUB(LockDevice); 367 FILL_STUB(UnlockDevice); 368 FILL_STUB(FreeDeviceHandle); 369 FILL_STUB(Deinitialize); 370 #undef FILL_STUB 371 } 372 373 374 /* device hotplug support... */ 375 376 static int 377 add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount) 378 { 379 int retval = -1; 380 SDL_AudioDeviceItem *item; 381 const SDL_AudioDeviceItem *i; 382 int dupenum = 0; 383 384 SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */ 385 SDL_assert(name != NULL); 386 387 item = (SDL_AudioDeviceItem *) SDL_malloc(sizeof (SDL_AudioDeviceItem)); 388 if (!item) { 389 return SDL_OutOfMemory(); 390 } 391 392 item->original_name = SDL_strdup(name); 393 if (!item->original_name) { 394 SDL_free(item); 395 return SDL_OutOfMemory(); 396 } 397 398 item->dupenum = 0; 399 item->name = item->original_name; 400 item->handle = handle; 401 402 SDL_LockMutex(current_audio.detectionLock); 403 404 for (i = *devices; i != NULL; i = i->next) { 405 if (SDL_strcmp(name, i->original_name) == 0) { 406 dupenum = i->dupenum + 1; 407 break; /* stop at the highest-numbered dupe. */ 408 } 409 } 410 411 if (dupenum) { 412 const size_t len = SDL_strlen(name) + 16; 413 char *replacement = (char *) SDL_malloc(len); 414 if (!replacement) { 415 SDL_UnlockMutex(current_audio.detectionLock); 416 SDL_free(item->original_name); 417 SDL_free(item); 418 SDL_OutOfMemory(); 419 return -1; 420 } 421 422 SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1); 423 item->dupenum = dupenum; 424 item->name = replacement; 425 } 426 427 item->next = *devices; 428 *devices = item; 429 retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */ 430 431 SDL_UnlockMutex(current_audio.detectionLock); 432 433 return retval; 434 } 435 436 static SDL_INLINE int 437 add_capture_device(const char *name, void *handle) 438 { 439 SDL_assert(current_audio.impl.HasCaptureSupport); 440 return add_audio_device(name, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); 441 } 442 443 static SDL_INLINE int 444 add_output_device(const char *name, void *handle) 445 { 446 return add_audio_device(name, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); 447 } 448 449 static void 450 free_device_list(SDL_AudioDeviceItem **devices, int *devCount) 451 { 452 SDL_AudioDeviceItem *item, *next; 453 for (item = *devices; item != NULL; item = next) { 454 next = item->next; 455 if (item->handle != NULL) { 456 current_audio.impl.FreeDeviceHandle(item->handle); 457 } 458 /* these two pointers are the same if not a duplicate devname */ 459 if (item->name != item->original_name) { 460 SDL_free(item->name); 461 } 462 SDL_free(item->original_name); 463 SDL_free(item); 464 } 465 *devices = NULL; 466 *devCount = 0; 467 } 468 469 470 /* The audio backends call this when a new device is plugged in. */ 471 void 472 SDL_AddAudioDevice(const int iscapture, const char *name, void *handle) 473 { 474 const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle); 475 if (device_index != -1) { 476 /* Post the event, if desired */ 477 if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) { 478 SDL_Event event; 479 SDL_zero(event); 480 event.adevice.type = SDL_AUDIODEVICEADDED; 481 event.adevice.which = device_index; 482 event.adevice.iscapture = iscapture; 483 SDL_PushEvent(&event); 484 } 485 } 486 } 487 488 /* The audio backends call this when a currently-opened device is lost. */ 489 void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device) 490 { 491 SDL_assert(get_audio_device(device->id) == device); 492 493 if (!SDL_AtomicGet(&device->enabled)) { 494 return; /* don't report disconnects more than once. */ 495 } 496 497 if (SDL_AtomicGet(&device->shutdown)) { 498 return; /* don't report disconnect if we're trying to close device. */ 499 } 500 501 /* Ends the audio callback and mark the device as STOPPED, but the 502 app still needs to close the device to free resources. */ 503 current_audio.impl.LockDevice(device); 504 SDL_AtomicSet(&device->enabled, 0); 505 current_audio.impl.UnlockDevice(device); 506 507 /* Post the event, if desired */ 508 if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) { 509 SDL_Event event; 510 SDL_zero(event); 511 event.adevice.type = SDL_AUDIODEVICEREMOVED; 512 event.adevice.which = device->id; 513 event.adevice.iscapture = device->iscapture ? 1 : 0; 514 SDL_PushEvent(&event); 515 } 516 } 517 518 static void 519 mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag) 520 { 521 SDL_AudioDeviceItem *item; 522 SDL_assert(handle != NULL); 523 for (item = devices; item != NULL; item = item->next) { 524 if (item->handle == handle) { 525 item->handle = NULL; 526 *removedFlag = SDL_TRUE; 527 return; 528 } 529 } 530 } 531 532 /* The audio backends call this when a device is removed from the system. */ 533 void 534 SDL_RemoveAudioDevice(const int iscapture, void *handle) 535 { 536 int device_index; 537 SDL_AudioDevice *device = NULL; 538 539 SDL_LockMutex(current_audio.detectionLock); 540 if (iscapture) { 541 mark_device_removed(handle, current_audio.inputDevices, ¤t_audio.captureDevicesRemoved); 542 } else { 543 mark_device_removed(handle, current_audio.outputDevices, ¤t_audio.outputDevicesRemoved); 544 } 545 for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++) 546 { 547 device = open_devices[device_index]; 548 if (device != NULL && device->handle == handle) 549 { 550 SDL_OpenedAudioDeviceDisconnected(device); 551 break; 552 } 553 } 554 SDL_UnlockMutex(current_audio.detectionLock); 555 556 current_audio.impl.FreeDeviceHandle(handle); 557 } 558 559 560 561 /* buffer queueing support... */ 562 563 static void SDLCALL 564 SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len) 565 { 566 /* this function always holds the mixer lock before being called. */ 567 SDL_AudioDevice *device = (SDL_AudioDevice *) userdata; 568 size_t dequeued; 569 570 SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ 571 SDL_assert(!device->iscapture); /* this shouldn't ever happen, right?! */ 572 SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */ 573 574 dequeued = SDL_ReadFromDataQueue(device->buffer_queue, stream, len); 575 stream += dequeued; 576 len -= (int) dequeued; 577 578 if (len > 0) { /* fill any remaining space in the stream with silence. */ 579 SDL_assert(SDL_CountDataQueue(device->buffer_queue) == 0); 580 SDL_memset(stream, device->callbackspec.silence, len); 581 } 582 } 583 584 static void SDLCALL 585 SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len) 586 { 587 /* this function always holds the mixer lock before being called. */ 588 SDL_AudioDevice *device = (SDL_AudioDevice *) userdata; 589 590 SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ 591 SDL_assert(device->iscapture); /* this shouldn't ever happen, right?! */ 592 SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */ 593 594 /* note that if this needs to allocate more space and run out of memory, 595 we have no choice but to quietly drop the data and hope it works out 596 later, but you probably have bigger problems in this case anyhow. */ 597 SDL_WriteToDataQueue(device->buffer_queue, stream, len); 598 } 599 600 int 601 SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len) 602 { 603 SDL_AudioDevice *device = get_audio_device(devid); 604 int rc = 0; 605 606 if (!device) { 607 return -1; /* get_audio_device() will have set the error state */ 608 } else if (device->iscapture) { 609 return SDL_SetError("This is a capture device, queueing not allowed"); 610 } else if (device->callbackspec.callback != SDL_BufferQueueDrainCallback) { 611 return SDL_SetError("Audio device has a callback, queueing not allowed"); 612 } 613 614 if (len > 0) { 615 current_audio.impl.LockDevice(device); 616 rc = SDL_WriteToDataQueue(device->buffer_queue, data, len); 617 current_audio.impl.UnlockDevice(device); 618 } 619 620 return rc; 621 } 622 623 Uint32 624 SDL_DequeueAudio(SDL_AudioDeviceID devid, void *data, Uint32 len) 625 { 626 SDL_AudioDevice *device = get_audio_device(devid); 627 Uint32 rc; 628 629 if ( (len == 0) || /* nothing to do? */ 630 (!device) || /* called with bogus device id */ 631 (!device->iscapture) || /* playback devices can't dequeue */ 632 (device->callbackspec.callback != SDL_BufferQueueFillCallback) ) { /* not set for queueing */ 633 return 0; /* just report zero bytes dequeued. */ 634 } 635 636 current_audio.impl.LockDevice(device); 637 rc = (Uint32) SDL_ReadFromDataQueue(device->buffer_queue, data, len); 638 current_audio.impl.UnlockDevice(device); 639 return rc; 640 } 641 642 Uint32 643 SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid) 644 { 645 Uint32 retval = 0; 646 SDL_AudioDevice *device = get_audio_device(devid); 647 648 if (!device) { 649 return 0; 650 } 651 652 /* Nothing to do unless we're set up for queueing. */ 653 if (device->callbackspec.callback == SDL_BufferQueueDrainCallback || 654 device->callbackspec.callback == SDL_BufferQueueFillCallback) 655 { 656 current_audio.impl.LockDevice(device); 657 retval = (Uint32) SDL_CountDataQueue(device->buffer_queue); 658 current_audio.impl.UnlockDevice(device); 659 } 660 661 return retval; 662 } 663 664 void 665 SDL_ClearQueuedAudio(SDL_AudioDeviceID devid) 666 { 667 SDL_AudioDevice *device = get_audio_device(devid); 668 669 if (!device) { 670 return; /* nothing to do. */ 671 } 672 673 /* Blank out the device and release the mutex. Free it afterwards. */ 674 current_audio.impl.LockDevice(device); 675 676 /* Keep up to two packets in the pool to reduce future malloc pressure. */ 677 SDL_ClearDataQueue(device->buffer_queue, SDL_AUDIOBUFFERQUEUE_PACKETLEN * 2); 678 679 current_audio.impl.UnlockDevice(device); 680 } 681 682 683 /* The general mixing thread function */ 684 static int SDLCALL 685 SDL_RunAudio(void *devicep) 686 { 687 SDL_AudioDevice *device = (SDL_AudioDevice *) devicep; 688 void *udata = device->callbackspec.userdata; 689 SDL_AudioCallback callback = device->callbackspec.callback; 690 int data_len = 0; 691 Uint8 *data; 692 693 SDL_assert(!device->iscapture); 694 695 #if SDL_AUDIO_DRIVER_ANDROID 696 { 697 /* Set thread priority to THREAD_PRIORITY_AUDIO */ 698 extern void Android_JNI_AudioSetThreadPriority(int, int); 699 Android_JNI_AudioSetThreadPriority(device->iscapture, device->id); 700 } 701 #else 702 /* The audio mixing is always a high priority thread */ 703 SDL_SetThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL); 704 #endif 705 706 /* Perform any thread setup */ 707 device->threadid = SDL_ThreadID(); 708 current_audio.impl.ThreadInit(device); 709 710 /* Loop, filling the audio buffers */ 711 while (!SDL_AtomicGet(&device->shutdown)) { 712 current_audio.impl.BeginLoopIteration(device); 713 data_len = device->callbackspec.size; 714 715 /* Fill the current buffer with sound */ 716 if (!device->stream && SDL_AtomicGet(&device->enabled)) { 717 SDL_assert(data_len == device->spec.size); 718 data = current_audio.impl.GetDeviceBuf(device); 719 } else { 720 /* if the device isn't enabled, we still write to the 721 work_buffer, so the app's callback will fire with 722 a regular frequency, in case they depend on that 723 for timing or progress. They can use hotplug 724 now to know if the device failed. 725 Streaming playback uses work_buffer, too. */ 726 data = NULL; 727 } 728 729 if (data == NULL) { 730 data = device->work_buffer; 731 } 732 733 /* !!! FIXME: this should be LockDevice. */ 734 SDL_LockMutex(device->mixer_lock); 735 if (SDL_AtomicGet(&device->paused)) { 736 SDL_memset(data, device->callbackspec.silence, data_len); 737 } else { 738 callback(udata, data, data_len); 739 } 740 SDL_UnlockMutex(device->mixer_lock); 741 742 if (device->stream) { 743 /* Stream available audio to device, converting/resampling. */ 744 /* if this fails...oh well. We'll play silence here. */ 745 SDL_AudioStreamPut(device->stream, data, data_len); 746 747 while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->spec.size)) { 748 int got; 749 data = SDL_AtomicGet(&device->enabled) ? current_audio.impl.GetDeviceBuf(device) : NULL; 750 got = SDL_AudioStreamGet(device->stream, data ? data : device->work_buffer, device->spec.size); 751 SDL_assert((got < 0) || (got == device->spec.size)); 752 753 if (data == NULL) { /* device is having issues... */ 754 const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); 755 SDL_Delay(delay); /* wait for as long as this buffer would have played. Maybe device recovers later? */ 756 } else { 757 if (got != device->spec.size) { 758 SDL_memset(data, device->spec.silence, device->spec.size); 759 } 760 current_audio.impl.PlayDevice(device); 761 current_audio.impl.WaitDevice(device); 762 } 763 } 764 } else if (data == device->work_buffer) { 765 /* nothing to do; pause like we queued a buffer to play. */ 766 const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); 767 SDL_Delay(delay); 768 } else { /* writing directly to the device. */ 769 /* queue this buffer and wait for it to finish playing. */ 770 current_audio.impl.PlayDevice(device); 771 current_audio.impl.WaitDevice(device); 772 } 773 } 774 775 current_audio.impl.PrepareToClose(device); 776 777 /* Wait for the audio to drain. */ 778 SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2); 779 780 current_audio.impl.ThreadDeinit(device); 781 782 return 0; 783 } 784 785 /* !!! FIXME: this needs to deal with device spec changes. */ 786 /* The general capture thread function */ 787 static int SDLCALL 788 SDL_CaptureAudio(void *devicep) 789 { 790 SDL_AudioDevice *device = (SDL_AudioDevice *) devicep; 791 const int silence = (int) device->spec.silence; 792 const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); 793 const int data_len = device->spec.size; 794 Uint8 *data; 795 void *udata = device->callbackspec.userdata; 796 SDL_AudioCallback callback = device->callbackspec.callback; 797 798 SDL_assert(device->iscapture); 799 800 #if SDL_AUDIO_DRIVER_ANDROID 801 { 802 /* Set thread priority to THREAD_PRIORITY_AUDIO */ 803 extern void Android_JNI_AudioSetThreadPriority(int, int); 804 Android_JNI_AudioSetThreadPriority(device->iscapture, device->id); 805 } 806 #else 807 /* The audio mixing is always a high priority thread */ 808 SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); 809 #endif 810 811 /* Perform any thread setup */ 812 device->threadid = SDL_ThreadID(); 813 current_audio.impl.ThreadInit(device); 814 815 /* Loop, filling the audio buffers */ 816 while (!SDL_AtomicGet(&device->shutdown)) { 817 int still_need; 818 Uint8 *ptr; 819 820 current_audio.impl.BeginLoopIteration(device); 821 822 if (SDL_AtomicGet(&device->paused)) { 823 SDL_Delay(delay); /* just so we don't cook the CPU. */ 824 if (device->stream) { 825 SDL_AudioStreamClear(device->stream); 826 } 827 current_audio.impl.FlushCapture(device); /* dump anything pending. */ 828 continue; 829 } 830 831 /* Fill the current buffer with sound */ 832 still_need = data_len; 833 834 /* Use the work_buffer to hold data read from the device. */ 835 data = device->work_buffer; 836 SDL_assert(data != NULL); 837 838 ptr = data; 839 840 /* We still read from the device when "paused" to keep the state sane, 841 and block when there isn't data so this thread isn't eating CPU. 842 But we don't process it further or call the app's callback. */ 843 844 if (!SDL_AtomicGet(&device->enabled)) { 845 SDL_Delay(delay); /* try to keep callback firing at normal pace. */ 846 } else { 847 while (still_need > 0) { 848 const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need); 849 SDL_assert(rc <= still_need); /* device should not overflow buffer. :) */ 850 if (rc > 0) { 851 still_need -= rc; 852 ptr += rc; 853 } else { /* uhoh, device failed for some reason! */ 854 SDL_OpenedAudioDeviceDisconnected(device); 855 break; 856 } 857 } 858 } 859 860 if (still_need > 0) { 861 /* Keep any data we already read, silence the rest. */ 862 SDL_memset(ptr, silence, still_need); 863 } 864 865 if (device->stream) { 866 /* if this fails...oh well. */ 867 SDL_AudioStreamPut(device->stream, data, data_len); 868 869 while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->callbackspec.size)) { 870 const int got = SDL_AudioStreamGet(device->stream, device->work_buffer, device->callbackspec.size); 871 SDL_assert((got < 0) || (got == device->callbackspec.size)); 872 if (got != device->callbackspec.size) { 873 SDL_memset(device->work_buffer, device->spec.silence, device->callbackspec.size); 874 } 875 876 /* !!! FIXME: this should be LockDevice. */ 877 SDL_LockMutex(device->mixer_lock); 878 if (!SDL_AtomicGet(&device->paused)) { 879 callback(udata, device->work_buffer, device->callbackspec.size); 880 } 881 SDL_UnlockMutex(device->mixer_lock); 882 } 883 } else { /* feeding user callback directly without streaming. */ 884 /* !!! FIXME: this should be LockDevice. */ 885 SDL_LockMutex(device->mixer_lock); 886 if (!SDL_AtomicGet(&device->paused)) { 887 callback(udata, data, device->callbackspec.size); 888 } 889 SDL_UnlockMutex(device->mixer_lock); 890 } 891 } 892 893 current_audio.impl.FlushCapture(device); 894 895 current_audio.impl.ThreadDeinit(device); 896 897 return 0; 898 } 899 900 901 static SDL_AudioFormat 902 SDL_ParseAudioFormat(const char *string) 903 { 904 #define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x 905 CHECK_FMT_STRING(U8); 906 CHECK_FMT_STRING(S8); 907 CHECK_FMT_STRING(U16LSB); 908 CHECK_FMT_STRING(S16LSB); 909 CHECK_FMT_STRING(U16MSB); 910 CHECK_FMT_STRING(S16MSB); 911 CHECK_FMT_STRING(U16SYS); 912 CHECK_FMT_STRING(S16SYS); 913 CHECK_FMT_STRING(U16); 914 CHECK_FMT_STRING(S16); 915 CHECK_FMT_STRING(S32LSB); 916 CHECK_FMT_STRING(S32MSB); 917 CHECK_FMT_STRING(S32SYS); 918 CHECK_FMT_STRING(S32); 919 CHECK_FMT_STRING(F32LSB); 920 CHECK_FMT_STRING(F32MSB); 921 CHECK_FMT_STRING(F32SYS); 922 CHECK_FMT_STRING(F32); 923 #undef CHECK_FMT_STRING 924 return 0; 925 } 926 927 int 928 SDL_GetNumAudioDrivers(void) 929 { 930 return SDL_arraysize(bootstrap) - 1; 931 } 932 933 const char * 934 SDL_GetAudioDriver(int index) 935 { 936 if (index >= 0 && index < SDL_GetNumAudioDrivers()) { 937 return bootstrap[index]->name; 938 } 939 return NULL; 940 } 941 942 int 943 SDL_AudioInit(const char *driver_name) 944 { 945 int i = 0; 946 int initialized = 0; 947 int tried_to_init = 0; 948 949 if (SDL_WasInit(SDL_INIT_AUDIO)) { 950 SDL_AudioQuit(); /* shutdown driver if already running. */ 951 } 952 953 SDL_zero(current_audio); 954 SDL_zeroa(open_devices); 955 956 /* Select the proper audio driver */ 957 if (driver_name == NULL) { 958 driver_name = SDL_getenv("SDL_AUDIODRIVER"); 959 } 960 961 for (i = 0; (!initialized) && (bootstrap[i]); ++i) { 962 /* make sure we should even try this driver before doing so... */ 963 const AudioBootStrap *backend = bootstrap[i]; 964 if ((driver_name && (SDL_strncasecmp(backend->name, driver_name, SDL_strlen(driver_name)) != 0)) || 965 (!driver_name && backend->demand_only)) { 966 continue; 967 } 968 969 tried_to_init = 1; 970 SDL_zero(current_audio); 971 current_audio.name = backend->name; 972 current_audio.desc = backend->desc; 973 initialized = backend->init(¤t_audio.impl); 974 } 975 976 if (!initialized) { 977 /* specific drivers will set the error message if they fail... */ 978 if (!tried_to_init) { 979 if (driver_name) { 980 SDL_SetError("Audio target '%s' not available", driver_name); 981 } else { 982 SDL_SetError("No available audio device"); 983 } 984 } 985 986 SDL_zero(current_audio); 987 return -1; /* No driver was available, so fail. */ 988 } 989 990 current_audio.detectionLock = SDL_CreateMutex(); 991 992 finish_audio_entry_points_init(); 993 994 /* Make sure we have a list of devices available at startup. */ 995 current_audio.impl.DetectDevices(); 996 997 #ifdef HAVE_LIBSAMPLERATE_H 998 LoadLibSampleRate(); 999 #endif 1000 1001 return 0; 1002 } 1003 1004 /* 1005 * Get the current audio driver name 1006 */ 1007 const char * 1008 SDL_GetCurrentAudioDriver() 1009 { 1010 return current_audio.name; 1011 } 1012 1013 /* Clean out devices that we've removed but had to keep around for stability. */ 1014 static void 1015 clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag) 1016 { 1017 SDL_AudioDeviceItem *item = *devices; 1018 SDL_AudioDeviceItem *prev = NULL; 1019 int total = 0; 1020 1021 while (item) { 1022 SDL_AudioDeviceItem *next = item->next; 1023 if (item->handle != NULL) { 1024 total++; 1025 prev = item; 1026 } else { 1027 if (prev) { 1028 prev->next = next; 1029 } else { 1030 *devices = next; 1031 } 1032 /* these two pointers are the same if not a duplicate devname */ 1033 if (item->name != item->original_name) { 1034 SDL_free(item->name); 1035 } 1036 SDL_free(item->original_name); 1037 SDL_free(item); 1038 } 1039 item = next; 1040 } 1041 1042 *devCount = total; 1043 *removedFlag = SDL_FALSE; 1044 } 1045 1046 1047 int 1048 SDL_GetNumAudioDevices(int iscapture) 1049 { 1050 int retval = 0; 1051 1052 if (!SDL_WasInit(SDL_INIT_AUDIO)) { 1053 return -1; 1054 } 1055 1056 SDL_LockMutex(current_audio.detectionLock); 1057 if (iscapture && current_audio.captureDevicesRemoved) { 1058 clean_out_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount, ¤t_audio.captureDevicesRemoved); 1059 } 1060 1061 if (!iscapture && current_audio.outputDevicesRemoved) { 1062 clean_out_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount, ¤t_audio.outputDevicesRemoved); 1063 } 1064 1065 retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; 1066 SDL_UnlockMutex(current_audio.detectionLock); 1067 1068 return retval; 1069 } 1070 1071 1072 const char * 1073 SDL_GetAudioDeviceName(int index, int iscapture) 1074 { 1075 const char *retval = NULL; 1076 1077 if (!SDL_WasInit(SDL_INIT_AUDIO)) { 1078 SDL_SetError("Audio subsystem is not initialized"); 1079 return NULL; 1080 } 1081 1082 if (iscapture && !current_audio.impl.HasCaptureSupport) { 1083 SDL_SetError("No capture support"); 1084 return NULL; 1085 } 1086 1087 if (index >= 0) { 1088 SDL_AudioDeviceItem *item; 1089 int i; 1090 1091 SDL_LockMutex(current_audio.detectionLock); 1092 item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; 1093 i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; 1094 if (index < i) { 1095 for (i--; i > index; i--, item = item->next) { 1096 SDL_assert(item != NULL); 1097 } 1098 SDL_assert(item != NULL); 1099 retval = item->name; 1100 } 1101 SDL_UnlockMutex(current_audio.detectionLock); 1102 } 1103 1104 if (retval == NULL) { 1105 SDL_SetError("No such device"); 1106 } 1107 1108 return retval; 1109 } 1110 1111 1112 static void 1113 close_audio_device(SDL_AudioDevice * device) 1114 { 1115 if (!device) { 1116 return; 1117 } 1118 1119 /* make sure the device is paused before we do anything else, so the 1120 audio callback definitely won't fire again. */ 1121 current_audio.impl.LockDevice(device); 1122 SDL_AtomicSet(&device->paused, 1); 1123 SDL_AtomicSet(&device->shutdown, 1); 1124 SDL_AtomicSet(&device->enabled, 0); 1125 current_audio.impl.UnlockDevice(device); 1126 1127 if (device->thread != NULL) { 1128 SDL_WaitThread(device->thread, NULL); 1129 } 1130 if (device->mixer_lock != NULL) { 1131 SDL_DestroyMutex(device->mixer_lock); 1132 } 1133 1134 SDL_free(device->work_buffer); 1135 SDL_FreeAudioStream(device->stream); 1136 1137 if (device->id > 0) { 1138 SDL_AudioDevice *opendev = open_devices[device->id - 1]; 1139 SDL_assert((opendev == device) || (opendev == NULL)); 1140 if (opendev == device) { 1141 open_devices[device->id - 1] = NULL; 1142 } 1143 } 1144 1145 if (device->hidden != NULL) { 1146 current_audio.impl.CloseDevice(device); 1147 } 1148 1149 SDL_FreeDataQueue(device->buffer_queue); 1150 1151 SDL_free(device); 1152 } 1153 1154 1155 /* 1156 * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig). 1157 * Fills in a sanitized copy in (prepared). 1158 * Returns non-zero if okay, zero on fatal parameters in (orig). 1159 */ 1160 static int 1161 prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared) 1162 { 1163 SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec)); 1164 1165 if (orig->freq == 0) { 1166 const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY"); 1167 if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) { 1168 prepared->freq = 22050; /* a reasonable default */ 1169 } 1170 } 1171 1172 if (orig->format == 0) { 1173 const char *env = SDL_getenv("SDL_AUDIO_FORMAT"); 1174 if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) { 1175 prepared->format = AUDIO_S16; /* a reasonable default */ 1176 } 1177 } 1178 1179 switch (orig->channels) { 1180 case 0:{ 1181 const char *env = SDL_getenv("SDL_AUDIO_CHANNELS"); 1182 if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) { 1183 prepared->channels = 2; /* a reasonable default */ 1184 } 1185 break; 1186 } 1187 case 1: /* Mono */ 1188 case 2: /* Stereo */ 1189 case 4: /* Quadrophonic */ 1190 case 6: /* 5.1 surround */ 1191 case 8: /* 7.1 surround */ 1192 break; 1193 default: 1194 SDL_SetError("Unsupported number of audio channels."); 1195 return 0; 1196 } 1197 1198 if (orig->samples == 0) { 1199 const char *env = SDL_getenv("SDL_AUDIO_SAMPLES"); 1200 if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) { 1201 /* Pick a default of ~46 ms at desired frequency */ 1202 /* !!! FIXME: remove this when the non-Po2 resampling is in. */ 1203 const int samples = (prepared->freq / 1000) * 46; 1204 int power2 = 1; 1205 while (power2 < samples) { 1206 power2 *= 2; 1207 } 1208 prepared->samples = power2; 1209 } 1210 } 1211 1212 /* Calculate the silence and size of the audio specification */ 1213 SDL_CalculateAudioSpec(prepared); 1214 1215 return 1; 1216 } 1217 1218 static SDL_AudioDeviceID 1219 open_audio_device(const char *devname, int iscapture, 1220 const SDL_AudioSpec * desired, SDL_AudioSpec * obtained, 1221 int allowed_changes, int min_id) 1222 { 1223 const SDL_bool is_internal_thread = (desired->callback == NULL); 1224 SDL_AudioDeviceID id = 0; 1225 SDL_AudioSpec _obtained; 1226 SDL_AudioDevice *device; 1227 SDL_bool build_stream; 1228 void *handle = NULL; 1229 int i = 0; 1230 1231 if (!SDL_WasInit(SDL_INIT_AUDIO)) { 1232 SDL_SetError("Audio subsystem is not initialized"); 1233 return 0; 1234 } 1235 1236 if (iscapture && !current_audio.impl.HasCaptureSupport) { 1237 SDL_SetError("No capture support"); 1238 return 0; 1239 } 1240 1241 /* !!! FIXME: there is a race condition here if two devices open from two threads at once. */ 1242 /* Find an available device ID... */ 1243 for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) { 1244 if (open_devices[id] == NULL) { 1245 break; 1246 } 1247 } 1248 1249 if (id == SDL_arraysize(open_devices)) { 1250 SDL_SetError("Too many open audio devices"); 1251 return 0; 1252 } 1253 1254 if (!obtained) { 1255 obtained = &_obtained; 1256 } 1257 if (!prepare_audiospec(desired, obtained)) { 1258 return 0; 1259 } 1260 1261 /* If app doesn't care about a specific device, let the user override. */ 1262 if (devname == NULL) { 1263 devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME"); 1264 } 1265 1266 /* 1267 * Catch device names at the high level for the simple case... 1268 * This lets us have a basic "device enumeration" for systems that 1269 * don't have multiple devices, but makes sure the device name is 1270 * always NULL when it hits the low level. 1271 * 1272 * Also make sure that the simple case prevents multiple simultaneous 1273 * opens of the default system device. 1274 */ 1275 1276 if ((iscapture) && (current_audio.impl.OnlyHasDefaultCaptureDevice)) { 1277 if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) { 1278 SDL_SetError("No such device"); 1279 return 0; 1280 } 1281 devname = NULL; 1282 1283 for (i = 0; i < SDL_arraysize(open_devices); i++) { 1284 if ((open_devices[i]) && (open_devices[i]->iscapture)) { 1285 SDL_SetError("Audio device already open"); 1286 return 0; 1287 } 1288 } 1289 } else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { 1290 if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) { 1291 SDL_SetError("No such device"); 1292 return 0; 1293 } 1294 devname = NULL; 1295 1296 for (i = 0; i < SDL_arraysize(open_devices); i++) { 1297 if ((open_devices[i]) && (!open_devices[i]->iscapture)) { 1298 SDL_SetError("Audio device already open"); 1299 return 0; 1300 } 1301 } 1302 } else if (devname != NULL) { 1303 /* if the app specifies an exact string, we can pass the backend 1304 an actual device handle thingey, which saves them the effort of 1305 figuring out what device this was (such as, reenumerating 1306 everything again to find the matching human-readable name). 1307 It might still need to open a device based on the string for, 1308 say, a network audio server, but this optimizes some cases. */ 1309 SDL_AudioDeviceItem *item; 1310 SDL_LockMutex(current_audio.detectionLock); 1311 for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) { 1312 if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) { 1313 handle = item->handle; 1314 break; 1315 } 1316 } 1317 SDL_UnlockMutex(current_audio.detectionLock); 1318 } 1319 1320 if (!current_audio.impl.AllowsArbitraryDeviceNames) { 1321 /* has to be in our device list, or the default device. */ 1322 if ((handle == NULL) && (devname != NULL)) { 1323 SDL_SetError("No such device."); 1324 return 0; 1325 } 1326 } 1327 1328 device = (SDL_AudioDevice *) SDL_calloc(1, sizeof (SDL_AudioDevice)); 1329 if (device == NULL) { 1330 SDL_OutOfMemory(); 1331 return 0; 1332 } 1333 device->id = id + 1; 1334 device->spec = *obtained; 1335 device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE; 1336 device->handle = handle; 1337 1338 SDL_AtomicSet(&device->shutdown, 0); /* just in case. */ 1339 SDL_AtomicSet(&device->paused, 1); 1340 SDL_AtomicSet(&device->enabled, 1); 1341 1342 /* Create a mutex for locking the sound buffers */ 1343 if (!current_audio.impl.SkipMixerLock) { 1344 device->mixer_lock = SDL_CreateMutex(); 1345 if (device->mixer_lock == NULL) { 1346 close_audio_device(device); 1347 SDL_SetError("Couldn't create mixer lock"); 1348 return 0; 1349 } 1350 } 1351 1352 if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) { 1353 close_audio_device(device); 1354 return 0; 1355 } 1356 1357 /* if your target really doesn't need it, set it to 0x1 or something. */ 1358 /* otherwise, close_audio_device() won't call impl.CloseDevice(). */ 1359 SDL_assert(device->hidden != NULL); 1360 1361 /* See if we need to do any conversion */ 1362 build_stream = SDL_FALSE; 1363 if (obtained->freq != device->spec.freq) { 1364 if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) { 1365 obtained->freq = device->spec.freq; 1366 } else { 1367 build_stream = SDL_TRUE; 1368 } 1369 } 1370 if (obtained->format != device->spec.format) { 1371 if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) { 1372 obtained->format = device->spec.format; 1373 } else { 1374 build_stream = SDL_TRUE; 1375 } 1376 } 1377 if (obtained->channels != device->spec.channels) { 1378 if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) { 1379 obtained->channels = device->spec.channels; 1380 } else { 1381 build_stream = SDL_TRUE; 1382 } 1383 } 1384 if (device->spec.samples != obtained->samples) { 1385 if (allowed_changes & SDL_AUDIO_ALLOW_SAMPLES_CHANGE) { 1386 obtained->samples = device->spec.samples; 1387 } else { 1388 build_stream = SDL_TRUE; 1389 } 1390 } 1391 1392 SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */ 1393 1394 device->callbackspec = *obtained; 1395 1396 if (build_stream) { 1397 if (iscapture) { 1398 device->stream = SDL_NewAudioStream(device->spec.format, 1399 device->spec.channels, device->spec.freq, 1400 obtained->format, obtained->channels, obtained->freq); 1401 } else { 1402 device->stream = SDL_NewAudioStream(obtained->format, obtained->channels, 1403 obtained->freq, device->spec.format, 1404 device->spec.channels, device->spec.freq); 1405 } 1406 1407 if (!device->stream) { 1408 close_audio_device(device); 1409 return 0; 1410 } 1411 } 1412 1413 if (device->spec.callback == NULL) { /* use buffer queueing? */ 1414 /* pool a few packets to start. Enough for two callbacks. */ 1415 device->buffer_queue = SDL_NewDataQueue(SDL_AUDIOBUFFERQUEUE_PACKETLEN, obtained->size * 2); 1416 if (!device->buffer_queue) { 1417 close_audio_device(device); 1418 SDL_SetError("Couldn't create audio buffer queue"); 1419 return 0; 1420 } 1421 device->callbackspec.callback = iscapture ? SDL_BufferQueueFillCallback : SDL_BufferQueueDrainCallback; 1422 device->callbackspec.userdata = device; 1423 } 1424 1425 /* Allocate a scratch audio buffer */ 1426 device->work_buffer_len = build_stream ? device->callbackspec.size : 0; 1427 if (device->spec.size > device->work_buffer_len) { 1428 device->work_buffer_len = device->spec.size; 1429 } 1430 SDL_assert(device->work_buffer_len > 0); 1431 1432 device->work_buffer = (Uint8 *) SDL_malloc(device->work_buffer_len); 1433 if (device->work_buffer == NULL) { 1434 close_audio_device(device); 1435 SDL_OutOfMemory(); 1436 return 0; 1437 } 1438 1439 open_devices[id] = device; /* add it to our list of open devices. */ 1440 1441 /* Start the audio thread if necessary */ 1442 if (!current_audio.impl.ProvidesOwnCallbackThread) { 1443 /* Start the audio thread */ 1444 /* !!! FIXME: we don't force the audio thread stack size here if it calls into user code, but maybe we should? */ 1445 /* buffer queueing callback only needs a few bytes, so make the stack tiny. */ 1446 const size_t stacksize = is_internal_thread ? 64 * 1024 : 0; 1447 char threadname[64]; 1448 1449 SDL_snprintf(threadname, sizeof (threadname), "SDLAudio%c%d", (iscapture) ? 'C' : 'P', (int) device->id); 1450 device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, stacksize, device); 1451 1452 if (device->thread == NULL) { 1453 close_audio_device(device); 1454 SDL_SetError("Couldn't create audio thread"); 1455 return 0; 1456 } 1457 } 1458 1459 return device->id; 1460 } 1461 1462 1463 int 1464 SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained) 1465 { 1466 SDL_AudioDeviceID id = 0; 1467 1468 /* Start up the audio driver, if necessary. This is legacy behaviour! */ 1469 if (!SDL_WasInit(SDL_INIT_AUDIO)) { 1470 if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { 1471 return -1; 1472 } 1473 } 1474 1475 /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */ 1476 if (open_devices[0] != NULL) { 1477 SDL_SetError("Audio device is already opened"); 1478 return -1; 1479 } 1480 1481 if (obtained) { 1482 id = open_audio_device(NULL, 0, desired, obtained, 1483 SDL_AUDIO_ALLOW_ANY_CHANGE, 1); 1484 } else { 1485 SDL_AudioSpec _obtained; 1486 SDL_zero(_obtained); 1487 id = open_audio_device(NULL, 0, desired, &_obtained, 0, 1); 1488 /* On successful open, copy calculated values into 'desired'. */ 1489 if (id > 0) { 1490 desired->size = _obtained.size; 1491 desired->silence = _obtained.silence; 1492 } 1493 } 1494 1495 SDL_assert((id == 0) || (id == 1)); 1496 return (id == 0) ? -1 : 0; 1497 } 1498 1499 SDL_AudioDeviceID 1500 SDL_OpenAudioDevice(const char *device, int iscapture, 1501 const SDL_AudioSpec * desired, SDL_AudioSpec * obtained, 1502 int allowed_changes) 1503 { 1504 return open_audio_device(device, iscapture, desired, obtained, 1505 allowed_changes, 2); 1506 } 1507 1508 SDL_AudioStatus 1509 SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) 1510 { 1511 SDL_AudioDevice *device = get_audio_device(devid); 1512 SDL_AudioStatus status = SDL_AUDIO_STOPPED; 1513 if (device && SDL_AtomicGet(&device->enabled)) { 1514 if (SDL_AtomicGet(&device->paused)) { 1515 status = SDL_AUDIO_PAUSED; 1516 } else { 1517 status = SDL_AUDIO_PLAYING; 1518 } 1519 } 1520 return status; 1521 } 1522 1523 1524 SDL_AudioStatus 1525 SDL_GetAudioStatus(void) 1526 { 1527 return SDL_GetAudioDeviceStatus(1); 1528 } 1529 1530 void 1531 SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on) 1532 { 1533 SDL_AudioDevice *device = get_audio_device(devid); 1534 if (device) { 1535 current_audio.impl.LockDevice(device); 1536 SDL_AtomicSet(&device->paused, pause_on ? 1 : 0); 1537 current_audio.impl.UnlockDevice(device); 1538 } 1539 } 1540 1541 void 1542 SDL_PauseAudio(int pause_on) 1543 { 1544 SDL_PauseAudioDevice(1, pause_on); 1545 } 1546 1547 1548 void 1549 SDL_LockAudioDevice(SDL_AudioDeviceID devid) 1550 { 1551 /* Obtain a lock on the mixing buffers */ 1552 SDL_AudioDevice *device = get_audio_device(devid); 1553 if (device) { 1554 current_audio.impl.LockDevice(device); 1555 } 1556 } 1557 1558 void 1559 SDL_LockAudio(void) 1560 { 1561 SDL_LockAudioDevice(1); 1562 } 1563 1564 void 1565 SDL_UnlockAudioDevice(SDL_AudioDeviceID devid) 1566 { 1567 /* Obtain a lock on the mixing buffers */ 1568 SDL_AudioDevice *device = get_audio_device(devid); 1569 if (device) { 1570 current_audio.impl.UnlockDevice(device); 1571 } 1572 } 1573 1574 void 1575 SDL_UnlockAudio(void) 1576 { 1577 SDL_UnlockAudioDevice(1); 1578 } 1579 1580 void 1581 SDL_CloseAudioDevice(SDL_AudioDeviceID devid) 1582 { 1583 close_audio_device(get_audio_device(devid)); 1584 } 1585 1586 void 1587 SDL_CloseAudio(void) 1588 { 1589 SDL_CloseAudioDevice(1); 1590 } 1591 1592 void 1593 SDL_AudioQuit(void) 1594 { 1595 SDL_AudioDeviceID i; 1596 1597 if (!current_audio.name) { /* not initialized?! */ 1598 return; 1599 } 1600 1601 for (i = 0; i < SDL_arraysize(open_devices); i++) { 1602 close_audio_device(open_devices[i]); 1603 } 1604 1605 free_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); 1606 free_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); 1607 1608 /* Free the driver data */ 1609 current_audio.impl.Deinitialize(); 1610 1611 SDL_DestroyMutex(current_audio.detectionLock); 1612 1613 SDL_zero(current_audio); 1614 SDL_zeroa(open_devices); 1615 1616 #ifdef HAVE_LIBSAMPLERATE_H 1617 UnloadLibSampleRate(); 1618 #endif 1619 1620 SDL_FreeResampleFilter(); 1621 } 1622 1623 #define NUM_FORMATS 10 1624 static int format_idx; 1625 static int format_idx_sub; 1626 static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS] = { 1627 {AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, 1628 AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB}, 1629 {AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, 1630 AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB}, 1631 {AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB, 1632 AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8}, 1633 {AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB, 1634 AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8}, 1635 {AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB, 1636 AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8}, 1637 {AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB, 1638 AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8}, 1639 {AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB, 1640 AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8}, 1641 {AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB, 1642 AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8}, 1643 {AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB, 1644 AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8}, 1645 {AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB, 1646 AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8}, 1647 }; 1648 1649 SDL_AudioFormat 1650 SDL_FirstAudioFormat(SDL_AudioFormat format) 1651 { 1652 for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) { 1653 if (format_list[format_idx][0] == format) { 1654 break; 1655 } 1656 } 1657 format_idx_sub = 0; 1658 return SDL_NextAudioFormat(); 1659 } 1660 1661 SDL_AudioFormat 1662 SDL_NextAudioFormat(void) 1663 { 1664 if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) { 1665 return 0; 1666 } 1667 return format_list[format_idx][format_idx_sub++]; 1668 } 1669 1670 Uint8 1671 SDL_SilenceValueForFormat(const SDL_AudioFormat format) 1672 { 1673 switch (format) { 1674 /* !!! FIXME: 0x80 isn't perfect for U16, but we can't fit 0x8000 in a 1675 !!! FIXME: byte for memset() use. This is actually 0.1953 percent 1676 !!! FIXME: off from silence. Maybe just don't use U16. */ 1677 case AUDIO_U16LSB: 1678 case AUDIO_U16MSB: 1679 case AUDIO_U8: 1680 return 0x80; 1681 1682 default: break; 1683 } 1684 1685 return 0x00; 1686 } 1687 1688 void 1689 SDL_CalculateAudioSpec(SDL_AudioSpec * spec) 1690 { 1691 spec->silence = SDL_SilenceValueForFormat(spec->format); 1692 spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8; 1693 spec->size *= spec->channels; 1694 spec->size *= spec->samples; 1695 } 1696 1697 1698 /* 1699 * Moved here from SDL_mixer.c, since it relies on internals of an opened 1700 * audio device (and is deprecated, by the way!). 1701 */ 1702 void 1703 SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume) 1704 { 1705 /* Mix the user-level audio format */ 1706 SDL_AudioDevice *device = get_audio_device(1); 1707 if (device != NULL) { 1708 SDL_MixAudioFormat(dst, src, device->callbackspec.format, len, volume); 1709 } 1710 } 1711 1712 /* vi: set ts=4 sw=4 expandtab: */