audio: Destroy all existing SDL_AudioStreams on shutdown.
parent
62d4459972
commit
f8fdb20d8f
|
@ -137,6 +137,42 @@ static int GetDefaultSampleFramesFromFreq(const int freq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnAudioStreamCreated(SDL_AudioStream *stream)
|
||||||
|
{
|
||||||
|
SDL_assert(SDL_GetCurrentAudioDriver() != NULL);
|
||||||
|
SDL_assert(stream != NULL);
|
||||||
|
|
||||||
|
// this isn't really part of the "device list" but it's a convenient lock to use here.
|
||||||
|
SDL_LockRWLockForWriting(current_audio.device_list_lock);
|
||||||
|
if (current_audio.existing_streams) {
|
||||||
|
current_audio.existing_streams->prev = stream;
|
||||||
|
}
|
||||||
|
stream->prev = NULL;
|
||||||
|
stream->next = current_audio.existing_streams;
|
||||||
|
current_audio.existing_streams = stream;
|
||||||
|
SDL_UnlockRWLock(current_audio.device_list_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnAudioStreamDestroy(SDL_AudioStream *stream)
|
||||||
|
{
|
||||||
|
SDL_assert(SDL_GetCurrentAudioDriver() != NULL);
|
||||||
|
SDL_assert(stream != NULL);
|
||||||
|
|
||||||
|
// this isn't really part of the "device list" but it's a convenient lock to use here.
|
||||||
|
SDL_LockRWLockForWriting(current_audio.device_list_lock);
|
||||||
|
if (stream->prev) {
|
||||||
|
stream->prev->next = stream->next;
|
||||||
|
}
|
||||||
|
if (stream->next) {
|
||||||
|
stream->next->prev = stream->prev;
|
||||||
|
}
|
||||||
|
if (stream == current_audio.existing_streams) {
|
||||||
|
current_audio.existing_streams = stream->next;
|
||||||
|
}
|
||||||
|
SDL_UnlockRWLock(current_audio.device_list_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// device should be locked when calling this.
|
// device should be locked when calling this.
|
||||||
static SDL_bool AudioDeviceCanUseSimpleCopy(SDL_AudioDevice *device)
|
static SDL_bool AudioDeviceCanUseSimpleCopy(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
|
@ -657,7 +693,10 @@ void SDL_QuitAudio(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// !!! FIXME: Destroy all known audio streams, too.
|
// Destroy any audio streams that still exist...
|
||||||
|
while (current_audio.existing_streams != NULL) {
|
||||||
|
SDL_DestroyAudioStream(current_audio.existing_streams);
|
||||||
|
}
|
||||||
|
|
||||||
// merge device lists so we don't have to duplicate work below.
|
// merge device lists so we don't have to duplicate work below.
|
||||||
SDL_LockRWLockForWriting(current_audio.device_list_lock);
|
SDL_LockRWLockForWriting(current_audio.device_list_lock);
|
||||||
|
|
|
@ -430,6 +430,8 @@ SDL_AudioStream *SDL_CreateAudioStream(const SDL_AudioSpec *src_spec, const SDL_
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OnAudioStreamCreated(retval);
|
||||||
|
|
||||||
if (SDL_SetAudioStreamFormat(retval, src_spec, dst_spec) == -1) {
|
if (SDL_SetAudioStreamFormat(retval, src_spec, dst_spec) == -1) {
|
||||||
SDL_DestroyAudioStream(retval);
|
SDL_DestroyAudioStream(retval);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1152,6 +1154,8 @@ void SDL_DestroyAudioStream(SDL_AudioStream *stream)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OnAudioStreamDestroy(stream);
|
||||||
|
|
||||||
const SDL_bool simplified = stream->simplified;
|
const SDL_bool simplified = stream->simplified;
|
||||||
if (simplified) {
|
if (simplified) {
|
||||||
SDL_assert(stream->bound_device->simplified);
|
SDL_assert(stream->bound_device->simplified);
|
||||||
|
|
|
@ -102,7 +102,7 @@ extern SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByCallback(SDL_bool (*callbac
|
||||||
extern void SDL_UpdatedAudioDeviceFormat(SDL_AudioDevice *device);
|
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.
|
// Backends can call this to get a standardized name for a thread to power a specific audio device.
|
||||||
char *SDL_GetAudioThreadName(SDL_AudioDevice *device, char *buf, size_t buflen);
|
extern char *SDL_GetAudioThreadName(SDL_AudioDevice *device, char *buf, size_t buflen);
|
||||||
|
|
||||||
|
|
||||||
// These functions are the heart of the audio threads. Backends can call them directly if they aren't using the SDL-provided thread.
|
// These functions are the heart of the audio threads. Backends can call them directly if they aren't using the SDL-provided thread.
|
||||||
|
@ -115,9 +115,12 @@ extern void SDL_CaptureAudioThreadShutdown(SDL_AudioDevice *device);
|
||||||
extern void SDL_AudioThreadFinalize(SDL_AudioDevice *device);
|
extern void SDL_AudioThreadFinalize(SDL_AudioDevice *device);
|
||||||
|
|
||||||
// this gets used from the audio device threads. It has rules, don't use this if you don't know how to use it!
|
// this gets used from the audio device threads. It has rules, don't use this if you don't know how to use it!
|
||||||
void ConvertAudio(int num_frames, const void *src, SDL_AudioFormat src_format, int src_channels,
|
extern void ConvertAudio(int num_frames, const void *src, SDL_AudioFormat src_format, int src_channels,
|
||||||
void *dst, SDL_AudioFormat dst_format, int dst_channels, void* scratch);
|
void *dst, SDL_AudioFormat dst_format, int dst_channels, void* scratch);
|
||||||
|
|
||||||
|
// Special case to let something in SDL_audiocvt.c access something in SDL_audio.c. Don't use this.
|
||||||
|
extern void OnAudioStreamCreated(SDL_AudioStream *stream);
|
||||||
|
extern void OnAudioStreamDestroy(SDL_AudioStream *stream);
|
||||||
|
|
||||||
typedef struct SDL_AudioDriverImpl
|
typedef struct SDL_AudioDriverImpl
|
||||||
{
|
{
|
||||||
|
@ -151,6 +154,7 @@ typedef struct SDL_AudioDriver
|
||||||
SDL_RWLock *device_list_lock; // A mutex for device detection
|
SDL_RWLock *device_list_lock; // A mutex for device detection
|
||||||
SDL_AudioDevice *output_devices; // the list of currently-available audio output devices.
|
SDL_AudioDevice *output_devices; // the list of currently-available audio output devices.
|
||||||
SDL_AudioDevice *capture_devices; // the list of currently-available audio capture devices.
|
SDL_AudioDevice *capture_devices; // the list of currently-available audio capture devices.
|
||||||
|
SDL_AudioStream *existing_streams; // a list of all existing SDL_AudioStreams.
|
||||||
SDL_AudioDeviceID default_output_device_id;
|
SDL_AudioDeviceID default_output_device_id;
|
||||||
SDL_AudioDeviceID default_capture_device_id;
|
SDL_AudioDeviceID default_capture_device_id;
|
||||||
SDL_AtomicInt output_device_count;
|
SDL_AtomicInt output_device_count;
|
||||||
|
@ -191,6 +195,9 @@ struct SDL_AudioStream
|
||||||
SDL_LogicalAudioDevice *bound_device;
|
SDL_LogicalAudioDevice *bound_device;
|
||||||
SDL_AudioStream *next_binding;
|
SDL_AudioStream *next_binding;
|
||||||
SDL_AudioStream *prev_binding;
|
SDL_AudioStream *prev_binding;
|
||||||
|
|
||||||
|
SDL_AudioStream *prev; // linked list of all existing streams (so we can free them on shutdown).
|
||||||
|
SDL_AudioStream *next; // linked list of all existing streams (so we can free them on shutdown).
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Logical devices are an abstraction in SDL3; you can open the same physical
|
/* Logical devices are an abstraction in SDL3; you can open the same physical
|
||||||
|
|
Loading…
Reference in New Issue