From b733adb503407efffe249bfad86624fb7bdb25be Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 16 Oct 2023 20:17:04 -0400 Subject: [PATCH] audio: Fix device refcounting vs ProvidesOwnCallbackThread backends. --- src/audio/SDL_audio.c | 8 ++++---- src/audio/SDL_sysaudio.h | 3 +++ src/audio/emscripten/SDL_emscriptenaudio.c | 2 ++ src/audio/haiku/SDL_haikuaudio.cc | 2 ++ src/audio/jack/SDL_jackaudio.c | 2 ++ 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 18b5f533f2..331e57c7ee 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -352,7 +352,7 @@ static void DestroyPhysicalAudioDevice(SDL_AudioDevice *device) } // Don't hold the device lock when calling this, as we may destroy the device! -static void UnrefPhysicalAudioDevice(SDL_AudioDevice *device) +void UnrefPhysicalAudioDevice(SDL_AudioDevice *device) { if (SDL_AtomicDecRef(&device->refcount)) { // take it out of the device list. @@ -365,7 +365,7 @@ static void UnrefPhysicalAudioDevice(SDL_AudioDevice *device) } } -static void RefPhysicalAudioDevice(SDL_AudioDevice *device) +void RefPhysicalAudioDevice(SDL_AudioDevice *device) { SDL_AtomicIncRef(&device->refcount); } @@ -861,6 +861,7 @@ static void MixFloat32Audio(float *dst, const float *src, const int buffer_size) void SDL_OutputAudioThreadSetup(SDL_AudioDevice *device) { SDL_assert(!device->iscapture); + RefPhysicalAudioDevice(device); // unref'd when the audio thread terminates (ProvidesOwnCallbackThread implementations should call SDL_AudioThreadFinalize appropriately). current_audio.impl.ThreadInit(device); } @@ -1010,6 +1011,7 @@ static int SDLCALL OutputAudioThread(void *devicep) // thread entry point void SDL_CaptureAudioThreadSetup(SDL_AudioDevice *device) { SDL_assert(device->iscapture); + RefPhysicalAudioDevice(device); // unref'd when the audio thread terminates (ProvidesOwnCallbackThread implementations should call SDL_AudioThreadFinalize appropriately). current_audio.impl.ThreadInit(device); } @@ -1495,8 +1497,6 @@ static int OpenPhysicalAudioDevice(SDL_AudioDevice *device, const SDL_AudioSpec } } - RefPhysicalAudioDevice(device); // unref'd when the audio thread terminates (ProvidesOwnCallbackThread implementations should call SDL_AudioThreadFinalize appropriately). - return 0; } diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 6dd7a9f2b7..c33ac9ce08 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -106,6 +106,9 @@ extern void SDL_UpdatedAudioDeviceFormat(SDL_AudioDevice *device); // Backends can call this to get a standardized name for a thread to power a specific audio device. extern char *SDL_GetAudioThreadName(SDL_AudioDevice *device, char *buf, size_t buflen); +// Backends can call these to change a device's refcount. +extern void RefPhysicalAudioDevice(SDL_AudioDevice *device); +extern void UnrefPhysicalAudioDevice(SDL_AudioDevice *device); // These functions are the heart of the audio threads. Backends can call them directly if they aren't using the SDL-provided thread. extern void SDL_OutputAudioThreadSetup(SDL_AudioDevice *device); diff --git a/src/audio/emscripten/SDL_emscriptenaudio.c b/src/audio/emscripten/SDL_emscriptenaudio.c index b8740a8875..d2ee78b9dd 100644 --- a/src/audio/emscripten/SDL_emscriptenaudio.c +++ b/src/audio/emscripten/SDL_emscriptenaudio.c @@ -181,6 +181,8 @@ static int EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *device) return SDL_OutOfMemory(); } + RefPhysicalAudioDevice(device); // CloseDevice will always unref this through SDL_AudioThreadFinalize, even if we failed to start the thread. + // limit to native freq device->spec.freq = EM_ASM_INT({ return Module['SDL3'].audioContext.sampleRate; }); diff --git a/src/audio/haiku/SDL_haikuaudio.cc b/src/audio/haiku/SDL_haikuaudio.cc index 15204362d6..5d74462672 100644 --- a/src/audio/haiku/SDL_haikuaudio.cc +++ b/src/audio/haiku/SDL_haikuaudio.cc @@ -112,6 +112,8 @@ static int HAIKUAUDIO_OpenDevice(SDL_AudioDevice *device) } SDL_zerop(device->hidden); + RefPhysicalAudioDevice(device); // CloseDevice will always unref this through SDL_AudioThreadFinalize, even if we failed to start the thread. + // Parse the audio format and fill the Be raw audio format media_raw_audio_format format; SDL_zero(format); diff --git a/src/audio/jack/SDL_jackaudio.c b/src/audio/jack/SDL_jackaudio.c index ba19621ef5..4f0691bc3d 100644 --- a/src/audio/jack/SDL_jackaudio.c +++ b/src/audio/jack/SDL_jackaudio.c @@ -300,6 +300,8 @@ static int JACK_OpenDevice(SDL_AudioDevice *device) return SDL_OutOfMemory(); } + RefPhysicalAudioDevice(device); // CloseDevice will always unref this through SDL_AudioThreadFinalize, even if we failed to start the thread. + client = JACK_jack_client_open(GetJackAppName(), JackNoStartServer, &status, NULL); device->hidden->client = client; if (client == NULL) {