2015-06-21 17:33:46 +02:00
|
|
|
/*
|
|
|
|
|
Simple DirectMedia Layer
|
2023-01-09 09:41:41 -08:00
|
|
|
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
2015-06-21 17:33:46 +02:00
|
|
|
|
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
|
|
|
warranty. In no event will the authors be held liable for any damages
|
|
|
|
|
arising from the use of this software.
|
|
|
|
|
|
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
|
|
|
including commercial applications, and to alter it and redistribute it
|
|
|
|
|
freely, subject to the following restrictions:
|
|
|
|
|
|
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
|
|
|
claim that you wrote the original software. If you use this software
|
|
|
|
|
in a product, an acknowledgment in the product documentation would be
|
|
|
|
|
appreciated but is not required.
|
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
|
|
|
misrepresented as being the original software.
|
|
|
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
|
|
|
*/
|
2023-07-03 20:36:39 -04:00
|
|
|
|
2022-11-29 18:34:15 -08:00
|
|
|
#include "SDL_internal.h"
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2016-11-20 21:34:54 -08:00
|
|
|
#ifndef SDL_sysaudio_h_
|
|
|
|
|
#define SDL_sysaudio_h_
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-05-12 23:37:02 -04:00
|
|
|
#define DEBUG_AUDIOSTREAM 0
|
|
|
|
|
#define DEBUG_AUDIO_CONVERT 0
|
|
|
|
|
|
|
|
|
|
#if DEBUG_AUDIO_CONVERT
|
|
|
|
|
#define LOG_DEBUG_AUDIO_CONVERT(from, to) SDL_Log("SDL_AUDIO_CONVERT: Converting %s to %s.\n", from, to);
|
|
|
|
|
#else
|
|
|
|
|
#define LOG_DEBUG_AUDIO_CONVERT(from, to)
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// These pointers get set during SDL_ChooseAudioConverters() to various SIMD implementations.
|
2023-05-12 23:37:02 -04:00
|
|
|
extern void (*SDL_Convert_S8_to_F32)(float *dst, const Sint8 *src, int num_samples);
|
|
|
|
|
extern void (*SDL_Convert_U8_to_F32)(float *dst, const Uint8 *src, int num_samples);
|
|
|
|
|
extern void (*SDL_Convert_S16_to_F32)(float *dst, const Sint16 *src, int num_samples);
|
|
|
|
|
extern void (*SDL_Convert_S32_to_F32)(float *dst, const Sint32 *src, int num_samples);
|
|
|
|
|
extern void (*SDL_Convert_F32_to_S8)(Sint8 *dst, const float *src, int num_samples);
|
|
|
|
|
extern void (*SDL_Convert_F32_to_U8)(Uint8 *dst, const float *src, int num_samples);
|
|
|
|
|
extern void (*SDL_Convert_F32_to_S16)(Sint16 *dst, const float *src, int num_samples);
|
|
|
|
|
extern void (*SDL_Convert_F32_to_S32)(Sint32 *dst, const float *src, int num_samples);
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// !!! FIXME: These are wordy and unlocalized...
|
2016-08-06 03:39:15 -04:00
|
|
|
#define DEFAULT_OUTPUT_DEVNAME "System audio output device"
|
2022-11-30 12:51:59 -08:00
|
|
|
#define DEFAULT_INPUT_DEVNAME "System audio capture device"
|
2016-08-06 03:39:15 -04:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// these are used when no better specifics are known. We default to CD audio quality.
|
2023-06-24 11:24:24 -04:00
|
|
|
#define DEFAULT_AUDIO_OUTPUT_FORMAT SDL_AUDIO_S16
|
|
|
|
|
#define DEFAULT_AUDIO_OUTPUT_CHANNELS 2
|
|
|
|
|
#define DEFAULT_AUDIO_OUTPUT_FREQUENCY 44100
|
2023-05-12 23:37:02 -04:00
|
|
|
|
2023-06-24 11:24:24 -04:00
|
|
|
#define DEFAULT_AUDIO_CAPTURE_FORMAT SDL_AUDIO_S16
|
|
|
|
|
#define DEFAULT_AUDIO_CAPTURE_CHANNELS 1
|
|
|
|
|
#define DEFAULT_AUDIO_CAPTURE_FREQUENCY 44100
|
2023-05-12 23:37:02 -04:00
|
|
|
|
2015-06-21 17:33:46 +02:00
|
|
|
typedef struct SDL_AudioDevice SDL_AudioDevice;
|
2023-06-20 23:35:24 -04:00
|
|
|
typedef struct SDL_LogicalAudioDevice SDL_LogicalAudioDevice;
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// Used by src/SDL.c to initialize a particular audio driver.
|
2023-05-12 23:37:02 -04:00
|
|
|
extern int SDL_InitAudio(const char *driver_name);
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// Used by src/SDL.c to shut down previously-initialized audio.
|
2023-05-12 23:37:02 -04:00
|
|
|
extern void SDL_QuitAudio(void);
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// Function to get a list of audio formats, ordered most similar to `format` to least, 0-terminated. Don't free results.
|
2023-05-12 23:37:02 -04:00
|
|
|
const SDL_AudioFormat *SDL_ClosestAudioFormats(SDL_AudioFormat format);
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// Must be called at least once before using converters (SDL_CreateAudioStream will call it !!! FIXME but probably shouldn't).
|
2023-05-12 23:37:02 -04:00
|
|
|
extern void SDL_ChooseAudioConverters(void);
|
2023-08-24 19:00:17 +01:00
|
|
|
extern void SDL_SetupAudioResampler(void);
|
2023-05-12 23:37:02 -04:00
|
|
|
|
2023-06-23 02:37:48 -04:00
|
|
|
/* Backends should call this as devices are added to the system (such as
|
2015-06-21 17:33:46 +02:00
|
|
|
a USB headset being plugged in), and should also be called for
|
|
|
|
|
for every device found during DetectDevices(). */
|
2023-05-30 01:08:22 -04:00
|
|
|
extern SDL_AudioDevice *SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, const SDL_AudioSpec *spec, void *handle);
|
2023-05-12 23:37:02 -04:00
|
|
|
|
2023-06-23 02:37:48 -04:00
|
|
|
/* Backends should call this if an opened audio device is lost.
|
2023-05-12 23:37:02 -04:00
|
|
|
This can happen due to i/o errors, or a device being unplugged, etc. */
|
|
|
|
|
extern void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device);
|
|
|
|
|
|
2023-06-23 02:37:48 -04:00
|
|
|
// Backends should call this if the system default device changes.
|
|
|
|
|
extern void SDL_DefaultAudioDeviceChanged(SDL_AudioDevice *new_default_device);
|
|
|
|
|
|
2023-07-14 19:55:30 -04:00
|
|
|
// Backends should call this if a device's format is changing (opened or not); SDL will update state and carry on with the new format.
|
|
|
|
|
extern int SDL_AudioDeviceFormatChanged(SDL_AudioDevice *device, const SDL_AudioSpec *newspec, int new_sample_frames);
|
|
|
|
|
|
|
|
|
|
// Same as above, but assume the device is already locked.
|
|
|
|
|
extern int SDL_AudioDeviceFormatChangedAlreadyLocked(SDL_AudioDevice *device, const SDL_AudioSpec *newspec, int new_sample_frames);
|
|
|
|
|
|
2023-07-11 13:59:54 -04:00
|
|
|
// Find the SDL_AudioDevice associated with the handle supplied to SDL_AddAudioDevice. NULL if not found. DOES NOT LOCK THE DEVICE.
|
|
|
|
|
extern SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle);
|
2023-05-12 23:37:02 -04:00
|
|
|
|
2023-07-11 17:31:02 -04:00
|
|
|
// Find an SDL_AudioDevice, selected by a callback. NULL if not found. DOES NOT LOCK THE DEVICE.
|
|
|
|
|
extern SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByCallback(SDL_bool (*callback)(SDL_AudioDevice *device, void *userdata), void *userdata);
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// Backends should call this if they change the device format, channels, freq, or sample_frames to keep other state correct.
|
2023-05-12 23:37:02 -04:00
|
|
|
extern void SDL_UpdatedAudioDeviceFormat(SDL_AudioDevice *device);
|
|
|
|
|
|
2023-07-03 20:35:58 -04:00
|
|
|
// 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);
|
|
|
|
|
|
2023-05-12 23:37:02 -04:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// These functions are the heart of the audio threads. Backends can call them directly if they aren't using the SDL-provided thread.
|
2023-05-12 23:37:02 -04:00
|
|
|
extern void SDL_OutputAudioThreadSetup(SDL_AudioDevice *device);
|
|
|
|
|
extern SDL_bool SDL_OutputAudioThreadIterate(SDL_AudioDevice *device);
|
|
|
|
|
extern void SDL_OutputAudioThreadShutdown(SDL_AudioDevice *device);
|
|
|
|
|
extern void SDL_CaptureAudioThreadSetup(SDL_AudioDevice *device);
|
|
|
|
|
extern SDL_bool SDL_CaptureAudioThreadIterate(SDL_AudioDevice *device);
|
|
|
|
|
extern void SDL_CaptureAudioThreadShutdown(SDL_AudioDevice *device);
|
2023-06-28 10:13:34 -04:00
|
|
|
extern void SDL_AudioThreadFinalize(SDL_AudioDevice *device);
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-08-31 23:38:24 -04:00
|
|
|
// 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,
|
|
|
|
|
void *dst, SDL_AudioFormat dst_format, int dst_channels, void* scratch);
|
|
|
|
|
|
|
|
|
|
|
2015-06-21 17:33:46 +02:00
|
|
|
typedef struct SDL_AudioDriverImpl
|
|
|
|
|
{
|
2023-06-23 02:37:48 -04:00
|
|
|
void (*DetectDevices)(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture);
|
2023-05-12 23:37:02 -04:00
|
|
|
int (*OpenDevice)(SDL_AudioDevice *device);
|
2023-07-03 20:36:39 -04:00
|
|
|
void (*ThreadInit)(SDL_AudioDevice *device); // Called by audio thread at start
|
|
|
|
|
void (*ThreadDeinit)(SDL_AudioDevice *device); // Called by audio thread at end
|
2023-05-12 23:37:02 -04:00
|
|
|
void (*WaitDevice)(SDL_AudioDevice *device);
|
2023-08-30 19:16:39 -04:00
|
|
|
int (*PlayDevice)(SDL_AudioDevice *device, const Uint8 *buffer, int buflen); // buffer and buflen are always from GetDeviceBuf, passed here for convenience.
|
2023-05-12 23:37:02 -04:00
|
|
|
Uint8 *(*GetDeviceBuf)(SDL_AudioDevice *device, int *buffer_size);
|
2023-06-24 14:51:39 -04:00
|
|
|
void (*WaitCaptureDevice)(SDL_AudioDevice *device);
|
2023-05-12 23:37:02 -04:00
|
|
|
int (*CaptureFromDevice)(SDL_AudioDevice *device, void *buffer, int buflen);
|
|
|
|
|
void (*FlushCapture)(SDL_AudioDevice *device);
|
|
|
|
|
void (*CloseDevice)(SDL_AudioDevice *device);
|
2023-07-11 17:32:31 -04:00
|
|
|
void (*FreeDeviceHandle)(SDL_AudioDevice *device); // SDL is done with this device; free the handle from SDL_AddAudioDevice()
|
2022-11-30 12:51:59 -08:00
|
|
|
void (*Deinitialize)(void);
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// Some flags to push duplicate code into the core and reduce #ifdefs.
|
2023-07-03 11:37:40 -04:00
|
|
|
SDL_bool ProvidesOwnCallbackThread; // !!! FIXME: rename this, it's not a callback thread anymore.
|
2022-01-17 11:21:01 +01:00
|
|
|
SDL_bool HasCaptureSupport;
|
|
|
|
|
SDL_bool OnlyHasDefaultOutputDevice;
|
|
|
|
|
SDL_bool OnlyHasDefaultCaptureDevice;
|
|
|
|
|
SDL_bool AllowsArbitraryDeviceNames;
|
2015-06-21 17:33:46 +02:00
|
|
|
} SDL_AudioDriverImpl;
|
|
|
|
|
|
2023-05-12 23:37:02 -04:00
|
|
|
typedef struct SDL_AudioDriver
|
2015-06-21 17:33:46 +02:00
|
|
|
{
|
2023-07-03 20:36:39 -04:00
|
|
|
const char *name; // The name of this audio driver
|
|
|
|
|
const char *desc; // The description of this audio driver
|
|
|
|
|
SDL_AudioDriverImpl impl; // the backend's interface
|
|
|
|
|
SDL_RWLock *device_list_lock; // A mutex for device detection
|
|
|
|
|
SDL_AudioDevice *output_devices; // the list of currently-available audio output devices.
|
|
|
|
|
SDL_AudioDevice *capture_devices; // the list of currently-available audio capture devices.
|
2023-06-23 02:37:48 -04:00
|
|
|
SDL_AudioDeviceID default_output_device_id;
|
|
|
|
|
SDL_AudioDeviceID default_capture_device_id;
|
2023-05-12 23:37:02 -04:00
|
|
|
SDL_AtomicInt output_device_count;
|
|
|
|
|
SDL_AtomicInt capture_device_count;
|
2023-07-03 20:36:39 -04:00
|
|
|
SDL_AtomicInt last_device_instance_id; // increments on each device add to provide unique instance IDs
|
|
|
|
|
SDL_AtomicInt shutting_down; // non-zero during SDL_Quit, so we known not to accept any last-minute device hotplugs.
|
2023-05-12 23:37:02 -04:00
|
|
|
} SDL_AudioDriver;
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-09-04 21:29:40 +03:00
|
|
|
struct SDL_AudioQueue; // forward decl.
|
2023-08-31 13:29:35 +01:00
|
|
|
|
2023-05-12 23:37:02 -04:00
|
|
|
struct SDL_AudioStream
|
2015-06-21 17:33:46 +02:00
|
|
|
{
|
2023-08-31 13:29:35 +01:00
|
|
|
SDL_Mutex* lock;
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-08-27 14:43:21 -07:00
|
|
|
SDL_AudioStreamCallback get_callback;
|
2023-05-28 22:39:39 -04:00
|
|
|
void *get_callback_userdata;
|
2023-08-27 14:43:21 -07:00
|
|
|
SDL_AudioStreamCallback put_callback;
|
2023-05-28 22:39:39 -04:00
|
|
|
void *put_callback_userdata;
|
|
|
|
|
|
2023-05-30 01:08:22 -04:00
|
|
|
SDL_AudioSpec src_spec;
|
|
|
|
|
SDL_AudioSpec dst_spec;
|
2023-09-03 19:37:57 +01:00
|
|
|
float freq_ratio;
|
2023-08-21 10:14:59 +01:00
|
|
|
|
2023-09-04 21:29:40 +03:00
|
|
|
struct SDL_AudioQueue* queue;
|
2023-08-31 13:29:35 +01:00
|
|
|
|
|
|
|
|
SDL_bool track_changed;
|
2023-08-21 10:14:59 +01:00
|
|
|
Sint64 resample_offset;
|
2023-05-12 23:37:02 -04:00
|
|
|
|
2023-08-31 13:29:35 +01:00
|
|
|
Uint8 *work_buffer; // used for scratch space during data conversion/resampling.
|
|
|
|
|
size_t work_buffer_allocation;
|
2023-05-12 23:37:02 -04:00
|
|
|
|
2023-08-31 13:29:35 +01:00
|
|
|
Uint8 *history_buffer; // history for left padding and future sample rate changes.
|
|
|
|
|
size_t history_buffer_allocation;
|
2023-05-12 23:37:02 -04:00
|
|
|
|
2023-08-29 10:46:14 -04:00
|
|
|
SDL_bool simplified; // SDL_TRUE if created via SDL_OpenAudioDeviceStream
|
2023-08-27 13:32:33 -04:00
|
|
|
|
2023-06-20 23:35:24 -04:00
|
|
|
SDL_LogicalAudioDevice *bound_device;
|
2023-05-12 23:37:02 -04:00
|
|
|
SDL_AudioStream *next_binding;
|
|
|
|
|
SDL_AudioStream *prev_binding;
|
|
|
|
|
};
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-06-20 23:35:24 -04:00
|
|
|
/* Logical devices are an abstraction in SDL3; you can open the same physical
|
|
|
|
|
device multiple times, and each will result in an object with its own set
|
|
|
|
|
of bound audio streams, etc, even though internally these are all processed
|
|
|
|
|
as a group when mixing the final output for the physical device. */
|
|
|
|
|
struct SDL_LogicalAudioDevice
|
|
|
|
|
{
|
2023-07-03 20:36:39 -04:00
|
|
|
// the unique instance ID of this device.
|
2023-06-20 23:35:24 -04:00
|
|
|
SDL_AudioDeviceID instance_id;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// The physical device associated with this opened device.
|
2023-06-20 23:35:24 -04:00
|
|
|
SDL_AudioDevice *physical_device;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// If whole logical device is paused (process no streams bound to this device).
|
2023-06-20 23:35:24 -04:00
|
|
|
SDL_AtomicInt paused;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// double-linked list of all audio streams currently bound to this opened device.
|
2023-06-20 23:35:24 -04:00
|
|
|
SDL_AudioStream *bound_streams;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// SDL_TRUE if this was opened as a default device.
|
2023-08-29 10:46:14 -04:00
|
|
|
SDL_bool opened_as_default;
|
2023-06-20 23:35:24 -04:00
|
|
|
|
2023-08-27 13:32:33 -04:00
|
|
|
// SDL_TRUE if device was opened with SDL_OpenAudioDeviceStream (so it forbids binding changes, etc).
|
2023-08-29 10:46:14 -04:00
|
|
|
SDL_bool simplified;
|
2023-08-27 13:32:33 -04:00
|
|
|
|
2023-09-07 10:56:09 -04:00
|
|
|
// If non-NULL, callback into the app that lets them access the final postmix buffer.
|
|
|
|
|
SDL_AudioPostmixCallback postmix;
|
|
|
|
|
|
|
|
|
|
// App-supplied pointer for postmix callback.
|
|
|
|
|
void *postmix_userdata;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// double-linked list of opened devices on the same physical device.
|
2023-06-20 23:35:24 -04:00
|
|
|
SDL_LogicalAudioDevice *next;
|
|
|
|
|
SDL_LogicalAudioDevice *prev;
|
|
|
|
|
};
|
|
|
|
|
|
2015-06-21 17:33:46 +02:00
|
|
|
struct SDL_AudioDevice
|
|
|
|
|
{
|
2023-07-03 20:36:39 -04:00
|
|
|
// A mutex for locking access to this struct
|
2023-05-12 23:37:02 -04:00
|
|
|
SDL_Mutex *lock;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// human-readable name of the device. ("SoundBlaster Pro 16")
|
2023-05-12 23:37:02 -04:00
|
|
|
char *name;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// the unique instance ID of this device.
|
2023-05-12 23:37:02 -04:00
|
|
|
SDL_AudioDeviceID instance_id;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// a way for the backend to identify this device _when not opened_
|
2023-05-12 23:37:02 -04:00
|
|
|
void *handle;
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// The device's current audio specification
|
2023-05-30 01:08:22 -04:00
|
|
|
SDL_AudioSpec spec;
|
2023-07-11 22:07:52 -04:00
|
|
|
int buffer_size;
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// The device's default audio specification
|
2023-05-30 01:08:22 -04:00
|
|
|
SDL_AudioSpec default_spec;
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// Number of sample frames the devices wants per-buffer.
|
2023-05-12 23:37:02 -04:00
|
|
|
int sample_frames;
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// Value to use for SDL_memset to silence a buffer in this device's format
|
2023-05-12 23:37:02 -04:00
|
|
|
int silence_value;
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// non-zero if we are signaling the audio thread to end.
|
2023-05-12 23:37:02 -04:00
|
|
|
SDL_AtomicInt shutdown;
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// non-zero if we want the device to be destroyed (so audio thread knows to do it on termination).
|
2023-05-12 23:37:02 -04:00
|
|
|
SDL_AtomicInt condemned;
|
2017-01-05 19:29:38 -05:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// non-zero if this was a disconnected default device and we're waiting for its replacement.
|
audio: Mark disconnected default devices as "zombies".
Zombie devices just sit there doing nothing until a new default device
is chosen, and then they migrate all their logical devices before being
destroyed.
This lets the system deal with the likely outcome of a USB headset being
the default audio device, and when its cable is yanked out, the backend
will likely announce this _before_ it chooses a new default (or, perhaps,
the only device in the system got yanked out and there _isn't_ a new
default to be had until the user plugs the cable back in).
This lets the audio device hold on without disturbing the app until it can
seamlessly migrate audio, and it also means the backend does not have to
be careful in how it announces device events, since SDL will manage the
time between a device loss and its replacement.
Note that this _only_ applies to things opened as the default device
(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, etc). If those USB headphones are the
default, and one SDL_OpenAudioDevice() call asked for them specifically and
the other just said "give me the system default," the explicitly requested
open will get a device-lost notification immediately. The other open will
live on as a zombie until it can migrate to the new default.
This drops the complexity of the PulseAudio hotplug thread dramatically,
back to what it was previously, since it no longer needs to fight against
Pulse's asychronous nature, but just report device disconnects and new
default choices as they arrive.
loopwave has been updated to not check for device removals anymore; since
it opens the default device, this is now managed for it; it no longer
needs to close and reopen a device, and as far as it knows, the device
is never lost in the first place.
2023-06-23 21:50:24 -04:00
|
|
|
SDL_AtomicInt zombie;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// non-zero if this has a thread running (which might be `thread` or something provided by the backend!)
|
2023-07-03 11:37:40 -04:00
|
|
|
SDL_AtomicInt thread_alive;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// SDL_TRUE if this is a capture device instead of an output device
|
2023-05-12 23:37:02 -04:00
|
|
|
SDL_bool iscapture;
|
|
|
|
|
|
2023-08-31 23:38:24 -04:00
|
|
|
// Scratch buffers used for mixing.
|
2023-05-12 23:37:02 -04:00
|
|
|
Uint8 *work_buffer;
|
2023-08-31 23:38:24 -04:00
|
|
|
Uint8 *mix_buffer;
|
2023-09-07 10:56:09 -04:00
|
|
|
float *postmix_buffer;
|
2023-08-31 23:38:24 -04:00
|
|
|
|
|
|
|
|
// Size of work_buffer (and mix_buffer) in bytes.
|
|
|
|
|
int work_buffer_size;
|
2015-06-21 17:33:46 +02:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// A thread to feed the audio device
|
2015-06-21 17:33:46 +02:00
|
|
|
SDL_Thread *thread;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// SDL_TRUE if this physical device is currently opened by the backend.
|
2023-08-29 10:46:14 -04:00
|
|
|
SDL_bool currently_opened;
|
2023-06-20 23:35:24 -04:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// Data private to this driver
|
2015-06-21 17:33:46 +02:00
|
|
|
struct SDL_PrivateAudioData *hidden;
|
2016-10-04 06:48:07 -07:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// All logical devices associated with this physical device.
|
2023-06-20 23:35:24 -04:00
|
|
|
SDL_LogicalAudioDevice *logical_devices;
|
2023-05-12 23:37:02 -04:00
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// double-linked list of all physical devices.
|
2023-05-12 23:37:02 -04:00
|
|
|
struct SDL_AudioDevice *prev;
|
|
|
|
|
struct SDL_AudioDevice *next;
|
2015-06-21 17:33:46 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef struct AudioBootStrap
|
|
|
|
|
{
|
|
|
|
|
const char *name;
|
|
|
|
|
const char *desc;
|
2022-11-30 12:51:59 -08:00
|
|
|
SDL_bool (*init)(SDL_AudioDriverImpl *impl);
|
2023-07-03 20:36:39 -04:00
|
|
|
SDL_bool demand_only; // if SDL_TRUE: request explicitly, or it won't be available.
|
2015-06-21 17:33:46 +02:00
|
|
|
} AudioBootStrap;
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
// Not all of these are available in a given build. Use #ifdefs, etc.
|
2021-02-13 11:56:05 -05:00
|
|
|
extern AudioBootStrap PIPEWIRE_bootstrap;
|
2016-11-13 22:57:41 -08:00
|
|
|
extern AudioBootStrap PULSEAUDIO_bootstrap;
|
|
|
|
|
extern AudioBootStrap ALSA_bootstrap;
|
2022-11-23 06:50:20 +03:00
|
|
|
extern AudioBootStrap JACK_bootstrap;
|
2022-11-22 22:04:10 +03:00
|
|
|
extern AudioBootStrap SNDIO_bootstrap;
|
2017-05-24 19:56:59 -04:00
|
|
|
extern AudioBootStrap NETBSDAUDIO_bootstrap;
|
2016-11-13 22:57:41 -08:00
|
|
|
extern AudioBootStrap DSP_bootstrap;
|
2017-02-14 03:12:09 -05:00
|
|
|
extern AudioBootStrap WASAPI_bootstrap;
|
2016-11-13 22:57:41 -08:00
|
|
|
extern AudioBootStrap DSOUND_bootstrap;
|
|
|
|
|
extern AudioBootStrap WINMM_bootstrap;
|
|
|
|
|
extern AudioBootStrap HAIKUAUDIO_bootstrap;
|
|
|
|
|
extern AudioBootStrap COREAUDIO_bootstrap;
|
|
|
|
|
extern AudioBootStrap DISKAUDIO_bootstrap;
|
|
|
|
|
extern AudioBootStrap DUMMYAUDIO_bootstrap;
|
2023-06-26 21:43:53 -04:00
|
|
|
extern AudioBootStrap AAUDIO_bootstrap;
|
2023-07-03 20:36:39 -04:00
|
|
|
extern AudioBootStrap openslES_bootstrap; // !!! FIXME: capitalize this to match the others
|
2019-05-23 13:47:30 -07:00
|
|
|
extern AudioBootStrap ANDROIDAUDIO_bootstrap;
|
2022-06-24 16:43:20 +02:00
|
|
|
extern AudioBootStrap PS2AUDIO_bootstrap;
|
2016-11-13 22:57:41 -08:00
|
|
|
extern AudioBootStrap PSPAUDIO_bootstrap;
|
2020-11-02 18:09:43 +03:00
|
|
|
extern AudioBootStrap VITAAUD_bootstrap;
|
2021-03-30 04:32:39 -04:00
|
|
|
extern AudioBootStrap N3DSAUDIO_bootstrap;
|
2016-11-13 22:57:41 -08:00
|
|
|
extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap;
|
2023-01-07 06:29:03 -05:00
|
|
|
extern AudioBootStrap QSAAUDIO_bootstrap;
|
2016-11-13 22:57:41 -08:00
|
|
|
|
2023-04-06 23:17:29 +02:00
|
|
|
extern SDL_AudioDevice *get_audio_dev(SDL_AudioDeviceID id);
|
|
|
|
|
extern int get_max_num_audio_dev(void);
|
|
|
|
|
|
2023-07-03 20:36:39 -04:00
|
|
|
#endif // SDL_sysaudio_h_
|