audio: Let apps save an audio stream from destruction during SDL_Quit().

This is a special-case piece of functionality, generally these are expected
to go away during shutdown, but maybe someone is switching between audio
subsystems or something...
This commit is contained in:
Ryan C. Gordon 2025-06-20 21:09:31 -04:00
parent 7d9fd48557
commit 0ebdd5ae95
No known key found for this signature in database
GPG Key ID: FA148B892AB48044
2 changed files with 24 additions and 3 deletions

View File

@ -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.
*

View File

@ -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);