diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h index b91586fd6a..90e0018b90 100644 --- a/include/SDL3/SDL_audio.h +++ b/include/SDL3/SDL_audio.h @@ -1064,6 +1064,15 @@ extern SDL_DECLSPEC SDL_AudioStream * SDLCALL SDL_CreateAudioStream(const SDL_Au /** * Get the properties associated with an audio stream. * + * The application can hang any data it wants here, but + * the following properties are understood by SDL: + * + * - `SDL_PROP_AUDIOSTREAM_KEEP_ON_SHUTDOWN_BOOLEAN`: if true, the stream will + * not be automatically destroyed during SDL_Quit(). This property is + * ignored for streams created through SDL_OpenAudioDeviceStream(). Streams + * bound to devices that aren't destroyed will still be unbound. + * Default false. (since SDL 3.4.0) + * * \param stream the SDL_AudioStream to query. * \returns a valid property ID on success or 0 on failure; call * SDL_GetError() for more information. @@ -1074,6 +1083,9 @@ extern SDL_DECLSPEC SDL_AudioStream * SDLCALL SDL_CreateAudioStream(const SDL_Au */ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetAudioStreamProperties(SDL_AudioStream *stream); +#define SDL_PROP_AUDIOSTREAM_KEEP_ON_SHUTDOWN_BOOLEAN "SDL.audiostream.keep_on_shutdown" + + /** * Query the current format of an audio stream. * diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 90d9f9bba6..979484c858 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -941,6 +941,9 @@ bool SDL_InitAudio(const char *driver_name) driver_name = SDL_GetHint(SDL_HINT_AUDIO_DRIVER); } + // save this off in case we kept any streams from a previous init/quit. + SDL_AudioStream *streams = current_audio.existing_streams; + bool initialized = false; bool tried_to_init = false; @@ -1024,6 +1027,8 @@ bool SDL_InitAudio(const char *driver_name) CompleteAudioEntryPoints(); + current_audio.existing_streams = streams; // in case we kept any. + // Make sure we have a list of devices available at startup... SDL_AudioDevice *default_playback = NULL; SDL_AudioDevice *default_recording = NULL; @@ -1073,9 +1078,13 @@ void SDL_QuitAudio(void) current_audio.impl.DeinitializeStart(); - // Destroy any audio streams that still exist... - while (current_audio.existing_streams) { - SDL_DestroyAudioStream(current_audio.existing_streams); + // Destroy any audio streams that still exist...unless app asked to keep it. + SDL_AudioStream *next = NULL; + for (SDL_AudioStream *i = current_audio.existing_streams; i; i = next) { + next = i->next; + if (i->simplified || !SDL_GetBooleanProperty(i->props, SDL_PROP_AUDIOSTREAM_KEEP_ON_SHUTDOWN_BOOLEAN, false)) { + SDL_DestroyAudioStream(i); + } } SDL_LockRWLockForWriting(current_audio.device_hash_lock);