Go to the documentation of this file.
21 #include "../SDL_internal.h"
29 #include "../thread/SDL_systhread.h"
31 #define _THIS SDL_AudioDevice *_this
38 #if SDL_AUDIO_DRIVER_PULSEAUDIO
41 #if SDL_AUDIO_DRIVER_ALSA
44 #if SDL_AUDIO_DRIVER_SNDIO
47 #if SDL_AUDIO_DRIVER_NETBSD
50 #if SDL_AUDIO_DRIVER_OSS
53 #if SDL_AUDIO_DRIVER_QSA
56 #if SDL_AUDIO_DRIVER_SUNAUDIO
59 #if SDL_AUDIO_DRIVER_ARTS
62 #if SDL_AUDIO_DRIVER_ESD
65 #if SDL_AUDIO_DRIVER_NACL
68 #if SDL_AUDIO_DRIVER_NAS
71 #if SDL_AUDIO_DRIVER_WASAPI
74 #if SDL_AUDIO_DRIVER_DSOUND
77 #if SDL_AUDIO_DRIVER_WINMM
80 #if SDL_AUDIO_DRIVER_PAUDIO
83 #if SDL_AUDIO_DRIVER_HAIKU
86 #if SDL_AUDIO_DRIVER_COREAUDIO
89 #if SDL_AUDIO_DRIVER_FUSIONSOUND
92 #if SDL_AUDIO_DRIVER_OPENSLES
95 #if SDL_AUDIO_DRIVER_ANDROID
98 #if SDL_AUDIO_DRIVER_PSP
101 #if SDL_AUDIO_DRIVER_EMSCRIPTEN
104 #if SDL_AUDIO_DRIVER_JACK
107 #if SDL_AUDIO_DRIVER_DISK
110 #if SDL_AUDIO_DRIVER_DUMMY
117 #ifdef HAVE_LIBSAMPLERATE_H
118 #ifdef SDL_LIBSAMPLERATE_DYNAMIC
119 static void *SRC_lib =
NULL;
122 int SRC_converter = 0;
123 SRC_STATE* (*SRC_src_new)(
int converter_type,
int channels,
int *error) =
NULL;
124 int (*SRC_src_process)(SRC_STATE *
state, SRC_DATA *
data) =
NULL;
125 int (*SRC_src_reset)(SRC_STATE *
state) =
NULL;
126 SRC_STATE* (*SRC_src_delete)(SRC_STATE *
state) =
NULL;
127 const char* (*SRC_src_strerror)(
int error) =
NULL;
130 LoadLibSampleRate(
void)
137 if (!hint || *hint ==
'0' ||
SDL_strcasecmp(hint,
"default") == 0) {
140 SRC_converter = SRC_SINC_FASTEST;
142 SRC_converter = SRC_SINC_MEDIUM_QUALITY;
144 SRC_converter = SRC_SINC_BEST_QUALITY;
149 #ifdef SDL_LIBSAMPLERATE_DYNAMIC
157 SRC_src_new = (SRC_STATE* (*)(
int converter_type,
int channels,
int *error))
SDL_LoadFunction(SRC_lib,
"src_new");
161 SRC_src_strerror = (
const char* (*)(
int error))
SDL_LoadFunction(SRC_lib,
"src_strerror");
163 if (!SRC_src_new || !SRC_src_process || !SRC_src_reset || !SRC_src_delete || !SRC_src_strerror) {
169 SRC_src_new = src_new;
170 SRC_src_process = src_process;
171 SRC_src_reset = src_reset;
172 SRC_src_delete = src_delete;
173 SRC_src_strerror = src_strerror;
181 UnloadLibSampleRate(
void)
183 #ifdef SDL_LIBSAMPLERATE_DYNAMIC
184 if (SRC_lib !=
NULL) {
192 SRC_src_process =
NULL;
193 SRC_src_reset =
NULL;
194 SRC_src_delete =
NULL;
195 SRC_src_strerror =
NULL;
347 #define FILL_STUB(x) \
348 if (current_audio.impl.x == NULL) { \
349 current_audio.impl.x = SDL_Audio##x##_Default; \
403 dupenum =
i->dupenum + 1;
421 item->
name = replacement;
472 if (device_index != -1) {
478 event.adevice.which = device_index;
479 event.adevice.iscapture = iscapture;
509 event.adevice.which =
device->id;
510 event.adevice.iscapture =
device->iscapture ? 1 : 0;
573 len -= (int) dequeued;
605 }
else if (
device->iscapture) {
606 return SDL_SetError(
"This is a capture device, queueing not allowed");
608 return SDL_SetError(
"Audio device has a callback, queueing not allowed");
685 void *udata =
device->callbackspec.userdata;
692 #if SDL_AUDIO_DRIVER_ANDROID
710 data_len =
device->callbackspec.size;
754 if (got !=
device->spec.size) {
788 const int silence = (int)
device->spec.silence;
790 const int data_len =
device->spec.size;
792 void *udata =
device->callbackspec.userdata;
797 #if SDL_AUDIO_DRIVER_ANDROID
829 still_need = data_len;
844 while (still_need > 0) {
857 if (still_need > 0) {
869 if (got !=
device->callbackspec.size) {
901 #define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x
920 #undef CHECK_FMT_STRING
944 int tried_to_init = 0;
954 if (driver_name ==
NULL) {
975 if (!tried_to_init) {
977 SDL_SetError(
"Audio target '%s' not available", driver_name);
994 #ifdef HAVE_LIBSAMPLERATE_H
1162 if (orig->
freq == 0) {
1163 const char *env =
SDL_getenv(
"SDL_AUDIO_FREQUENCY");
1164 if ((!env) || ((prepared->
freq =
SDL_atoi(env)) == 0)) {
1165 prepared->
freq = 22050;
1170 const char *env =
SDL_getenv(
"SDL_AUDIO_FORMAT");
1178 const char *env =
SDL_getenv(
"SDL_AUDIO_CHANNELS");
1196 const char *env =
SDL_getenv(
"SDL_AUDIO_SAMPLES");
1218 int allowed_changes,
int min_id)
1252 obtained = &_obtained;
1259 if (devname ==
NULL) {
1260 devname =
SDL_getenv(
"SDL_AUDIO_DEVICE_NAME");
1299 }
else if (devname !=
NULL) {
1331 device->spec = *obtained;
1391 device->callbackspec = *obtained;
1413 if (!
device->buffer_queue) {
1423 device->work_buffer_len = build_stream ?
device->callbackspec.size : 0;
1443 const size_t stacksize = is_internal_thread ? 64 * 1024 : 0;
1444 char threadname[64];
1446 SDL_snprintf(threadname,
sizeof (threadname),
"SDLAudio%c%d", (iscapture) ?
'C' :
'P', (
int)
device->id);
1493 return (
id == 0) ? -1 : 0;
1499 int allowed_changes)
1502 allowed_changes, 2);
1613 #ifdef HAVE_LIBSAMPLERATE_H
1614 UnloadLibSampleRate();
1620 #define NUM_FORMATS 10
static void finish_audio_entry_points_init(void)
static void SDL_AudioFreeDeviceHandle_Default(void *handle)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
SDL_DataQueue * SDL_NewDataQueue(const size_t _packetlen, const size_t initialslack)
#define SDL_SetThreadPriority
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
int SDL_AudioInit(const char *driver_name)
size_t SDL_CountDataQueue(SDL_DataQueue *queue)
void(* UnlockDevice)(_THIS)
int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
static int format_idx_sub
int ProvidesOwnCallbackThread
#define DEFAULT_OUTPUT_DEVNAME
#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE
static void clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
static int SDL_CaptureAudio(void *devicep)
AudioBootStrap ESD_bootstrap
void(* FlushCapture)(_THIS)
#define SDL_AudioStreamAvailable
EGLImageKHR EGLint EGLint * handle
static SDL_INLINE int add_output_device(const char *name, void *handle)
AudioBootStrap PSPAUDIO_bootstrap
AudioBootStrap WINMM_bootstrap
int SDL_GetNumAudioDrivers(void)
@ SDL_THREAD_PRIORITY_TIME_CRITICAL
SDL_AudioDeviceID SDL_OpenAudioDevice(const char *device, int iscapture, const SDL_AudioSpec *desired, SDL_AudioSpec *obtained, int allowed_changes)
const char * SDL_GetCurrentAudioDriver()
SDL_bool captureDevicesRemoved
void SDL_FreeDataQueue(SDL_DataQueue *queue)
#define DEFAULT_INPUT_DEVNAME
static void mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
#define SDL_MixAudioFormat
const char * SDL_GetAudioDriver(int index)
void SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
@ SDL_THREAD_PRIORITY_HIGH
SDL_AudioCallback callback
struct SDL_AudioDeviceItem * next
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
#define SDL_AudioStreamGet
static SDL_AudioDriver current_audio
static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS]
void(* PrepareToClose)(_THIS)
static Uint32 callback(Uint32 interval, void *param)
int SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len)
AudioBootStrap DISKAUDIO_bootstrap
AudioBootStrap ARTS_bootstrap
#define SDL_LIBSAMPLERATE_DYNAMIC
GLuint GLfloat GLfloat GLfloat x1
SDL_AudioFormat SDL_NextAudioFormat(void)
AudioBootStrap QSAAUDIO_bootstrap
Uint8 SDL_SilenceValueForFormat(const SDL_AudioFormat format)
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE
#define SDL_InitSubSystem
static int SDL_RunAudio(void *devicep)
AudioBootStrap SUNAUDIO_bootstrap
Uint16 SDL_AudioFormat
Audio format flags.
Uint32 SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid)
static Uint8 * SDL_AudioGetDeviceBuf_Default(_THIS)
void(* FreeDeviceHandle)(void *handle)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
static void SDL_AudioUnlockDevice_Default(SDL_AudioDevice *device)
AudioBootStrap COREAUDIO_bootstrap
#define SDL_AUDIOBUFFERQUEUE_PACKETLEN
void(* WaitDevice)(_THIS)
AudioBootStrap EMSCRIPTENAUDIO_bootstrap
AudioBootStrap PAUDIO_bootstrap
int(* init)(SDL_AudioDriverImpl *impl)
#define SDL_GetEventState(type)
SDL_Thread * SDL_CreateThreadInternal(int(*fn)(void *), const char *name, const size_t stacksize, void *data)
static void SDL_AudioWaitDevice_Default(_THIS)
AudioBootStrap SNDIO_bootstrap
#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE
AudioBootStrap DSOUND_bootstrap
#define SDL_AUDIO_ALLOW_ANY_CHANGE
int OnlyHasDefaultOutputDevice
static void SDL_AudioDeinitialize_Default(void)
GLuint const GLchar * name
static int prepare_audiospec(const SDL_AudioSpec *orig, SDL_AudioSpec *prepared)
AudioBootStrap NACLAUDIO_bootstrap
SDL_AudioStatus SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
void(* LockDevice)(_THIS)
void(* ThreadDeinit)(_THIS)
AudioBootStrap NAS_bootstrap
void SDL_RemoveAudioDevice(const int iscapture, void *handle)
void SDL_PauseAudio(int pause_on)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
static void SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice *device)
void(* DetectDevices)(void)
AudioBootStrap WASAPI_bootstrap
SDL_AudioStatus SDL_GetAudioStatus(void)
#define SDL_AudioStreamPut
static void SDL_AudioThreadInit_Default(_THIS)
#define SDL_AUDIO_BITSIZE(x)
void Android_JNI_AudioSetThreadPriority(int iscapture, int device_id)
void(* PlayDevice)(_THIS)
static int SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen)
AudioBootStrap ALSA_bootstrap
static int add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
const char * SDL_GetAudioDeviceName(int index, int iscapture)
AudioBootStrap PULSEAUDIO_bootstrap
void(* BeginLoopIteration)(_THIS)
int OnlyHasDefaultCaptureDevice
static int SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture)
#define SDL_assert(condition)
void SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
static const AudioBootStrap *const bootstrap[]
int AllowsArbitraryDeviceNames
#define SDL_HINT_AUDIO_RESAMPLING_MODE
A variable controlling speed/quality tradeoff of audio resampling.
static void SDL_AudioPlayDevice_Default(_THIS)
#define SDL_OutOfMemory()
size_t SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len)
void(* ThreadInit)(_THIS)
static void SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len)
static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture, const SDL_AudioSpec *desired, SDL_AudioSpec *obtained, int allowed_changes, int min_id)
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
AudioBootStrap FUSIONSOUND_bootstrap
static void SDL_AudioDetectDevices_Default(void)
#define SDL_arraysize(array)
static SDL_INLINE int add_capture_device(const char *name, void *handle)
int SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len)
static void SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len)
#define SDL_AudioStreamClear
void SDL_CloseAudio(void)
static void free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
AudioBootStrap HAIKUAUDIO_bootstrap
#define SDL_NewAudioStream
void SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack)
void * SDL_LoadFunction(void *handle, const char *name)
Uint8 *(* GetDeviceBuf)(_THIS)
static void SDL_AudioThreadDeinit_Default(_THIS)
static void SDL_AudioCloseDevice_Default(_THIS)
static void SDL_AudioLockDevice_Default(SDL_AudioDevice *device)
SDL_AudioDeviceItem * inputDevices
AudioBootStrap ANDROIDAUDIO_bootstrap
void SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
AudioBootStrap DSP_bootstrap
int SDL_GetNumAudioDevices(int iscapture)
SDL_bool outputDevicesRemoved
#define SDL_Unsupported()
#define SDL_AUDIO_ALLOW_FORMAT_CHANGE
#define SDL_FreeAudioStream
static SDL_AudioFormat SDL_ParseAudioFormat(const char *string)
AudioBootStrap NETBSDAUDIO_bootstrap
static void SDL_AudioPrepareToClose_Default(_THIS)
void(* SDL_AudioCallback)(void *userdata, Uint8 *stream, int len)
AudioBootStrap JACK_bootstrap
AudioBootStrap DUMMYAUDIO_bootstrap
static SDL_AudioDeviceID device
SDL_AudioDeviceItem * outputDevices
Uint32 SDL_DequeueAudio(SDL_AudioDeviceID devid, void *data, Uint32 len)
AudioBootStrap openslES_bootstrap
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
void(* CloseDevice)(_THIS)
void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
static void close_audio_device(SDL_AudioDevice *device)
static void SDL_AudioBeginLoopIteration_Default(_THIS)
static SDL_AudioDevice * open_devices[16]
static void SDL_AudioFlushCapture_Default(_THIS)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
void SDL_MixAudio(Uint8 *dst, const Uint8 *src, Uint32 len, int volume)
#define CHECK_FMT_STRING(x)
void SDL_LockAudioDevice(SDL_AudioDeviceID devid)
SDL_mutex * detectionLock
void(* Deinitialize)(void)
void SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
static SDL_AudioDevice * get_audio_device(SDL_AudioDeviceID id)
void SDL_UnlockAudio(void)
void SDL_FreeResampleFilter(void)
static SDL_INLINE SDL_bool is_in_audio_device_thread(SDL_AudioDevice *device)