SDL_audio.c File Reference
`#include "../SDL_internal.h"`
`#include "SDL.h"`
`#include "SDL_audio.h"`
`#include "SDL_audio_c.h"`
`#include "SDL_sysaudio.h"`
`#include "../thread/SDL_systhread.h"`
Include dependency graph for SDL_audio.c:

Go to the source code of this file.

## Macros

#define | _THIS SDL_AudioDevice *_this
#define | FILL_STUB(x)
#define | CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x
#define | NUM_FORMATS 10

## Functions

static SDL_AudioDevice * | get_audio_device (SDL_AudioDeviceID id)
static void | SDL_AudioDetectDevices_Default (void)
static void | SDL_AudioThreadInit_Default (_THIS)
static void | SDL_AudioThreadDeinit_Default (_THIS)
static void | SDL_AudioBeginLoopIteration_Default (_THIS)
static void | SDL_AudioWaitDevice_Default (_THIS)
static void | SDL_AudioPlayDevice_Default (_THIS)
static Uint8 * | SDL_AudioGetDeviceBuf_Default (_THIS)
static int | SDL_AudioCaptureFromDevice_Default (_THIS, void *buffer, int buflen)
static void | SDL_AudioFlushCapture_Default (_THIS)
static void | SDL_AudioPrepareToClose_Default (_THIS)
static void | SDL_AudioCloseDevice_Default (_THIS)
static void | SDL_AudioDeinitialize_Default (void)
static void | SDL_AudioFreeDeviceHandle_Default (void *handle)
static int | SDL_AudioOpenDevice_Default (_THIS, void *handle, const char *devname, int iscapture)
static SDL_INLINE SDL_bool | is_in_audio_device_thread (SDL_AudioDevice *device)
static void | SDL_AudioLockDevice_Default (SDL_AudioDevice *device)
static void | SDL_AudioUnlockDevice_Default (SDL_AudioDevice *device)
static void | SDL_AudioLockOrUnlockDeviceWithNoMixerLock (SDL_AudioDevice *device)
static void | finish_audio_entry_points_init (void)
static int | add_audio_device (const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
static SDL_INLINE int | add_capture_device (const char *name, void *handle)
static SDL_INLINE int | add_output_device (const char *name, void *handle)
static void | free_device_list (SDL_AudioDeviceItem **devices, int *devCount)
void | SDL_AddAudioDevice (const int iscapture, const char *name, void *handle)
void | SDL_OpenedAudioDeviceDisconnected (SDL_AudioDevice *device)
static void | mark_device_removed (void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
void | SDL_RemoveAudioDevice (const int iscapture, void *handle)
static void | SDL_BufferQueueDrainCallback (void *userdata, Uint8 *stream, int len)
static void | SDL_BufferQueueFillCallback (void *userdata, Uint8 *stream, int len)
int | SDL_QueueAudio (SDL_AudioDeviceID devid, const void *data, Uint32 len)
Uint32 | SDL_DequeueAudio (SDL_AudioDeviceID devid, void *data, Uint32 len)
Uint32 | SDL_GetQueuedAudioSize (SDL_AudioDeviceID devid)
void | SDL_ClearQueuedAudio (SDL_AudioDeviceID devid)
static int | SDL_RunAudio (void *devicep)
static int | SDL_CaptureAudio (void *devicep)
static SDL_AudioFormat | SDL_ParseAudioFormat (const char *string)
int | SDL_GetNumAudioDrivers (void)
const char * | SDL_GetAudioDriver (int index)
int | SDL_AudioInit (const char *driver_name)
const char * | SDL_GetCurrentAudioDriver ()
static void | clean_out_device_list (SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
int | SDL_GetNumAudioDevices (int iscapture)
const char * | SDL_GetAudioDeviceName (int index, int iscapture)
static void | close_audio_device (SDL_AudioDevice *device)
static int | prepare_audiospec (const SDL_AudioSpec *orig, SDL_AudioSpec *prepared)
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 | SDL_OpenAudio (SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
SDL_AudioDeviceID | SDL_OpenAudioDevice (const char *device, int iscapture, const SDL_AudioSpec *desired, SDL_AudioSpec *obtained, int allowed_changes)
SDL_AudioStatus | SDL_GetAudioDeviceStatus (SDL_AudioDeviceID devid)
SDL_AudioStatus | SDL_GetAudioStatus (void)
void | SDL_PauseAudioDevice (SDL_AudioDeviceID devid, int pause_on)
void | SDL_PauseAudio (int pause_on)
void | SDL_LockAudioDevice (SDL_AudioDeviceID devid)
void | SDL_LockAudio (void)
void | SDL_UnlockAudioDevice (SDL_AudioDeviceID devid)
void | SDL_UnlockAudio (void)
void | SDL_CloseAudioDevice (SDL_AudioDeviceID devid)
void | SDL_CloseAudio (void)
void | SDL_AudioQuit (void)
SDL_AudioFormat | SDL_FirstAudioFormat (SDL_AudioFormat format)
SDL_AudioFormat | SDL_NextAudioFormat (void)
void | SDL_CalculateAudioSpec (SDL_AudioSpec *spec)
void | SDL_MixAudio (Uint8 *dst, const Uint8 *src, Uint32 len, int volume)

## Variables

static SDL_AudioDriver | current_audio
static SDL_AudioDevice * | open_devices [16]
static const AudioBootStrap *const | bootstrap []
static int | format_idx
static int | format_idx_sub
static SDL_AudioFormat | format_list [NUM_FORMATS][NUM_FORMATS]

## Macro Definition Documentation

## _THIS

#define _THIS SDL_AudioDevice *_this

Definition at line 31 of file SDL_audio.c.

## CHECK_FMT_STRING

#define CHECK_FMT_STRING | ( |  | x | ) | if (SDL_strcmp(string, #x) == 0) return AUDIO_##x

## FILL_STUB

#define FILL_STUB | ( |  | x | ) |

Value:
if (current_audio.impl.x == NULL) { \
current_audio.impl.x = SDL_Audio##x##_Default; \
}

## NUM_FORMATS

#define NUM_FORMATS 10

Definition at line 1620 of file SDL_audio.c.

## Function Documentation

## add_audio_device()

static int add_audio_device | ( | const char * | name,
|  | void * | handle,
|  | SDL_AudioDeviceItem ** | devices,
|  | int * | devCount
| ) |  |

static

Definition at line 374 of file SDL_audio.c.

{
int retval = -1;
SDL_AudioDeviceItem *item;
const SDL_AudioDeviceItem *i;
int dupenum = 0;
SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */
SDL_assert(name != NULL);
item = (SDL_AudioDeviceItem *) SDL_malloc(sizeof (SDL_AudioDeviceItem));
if (!item) {
return SDL_OutOfMemory();
}
item->original_name = SDL_strdup(name);
if (!item->original_name) {
SDL_free(item);
return SDL_OutOfMemory();
}
item->dupenum = 0;
item->name = item->original_name;
item->handle = handle;
SDL_LockMutex(current_audio.detectionLock);
for (i = *devices; i != NULL; i = i->next) {
if (SDL_strcmp(name, i->original_name) == 0) {
dupenum = i->dupenum + 1;
break; /* stop at the highest-numbered dupe. */
}
}
if (dupenum) {
const size_t len = SDL_strlen(name) + 16;
char *replacement = (char *) SDL_malloc(len);
if (!replacement) {
SDL_UnlockMutex(current_audio.detectionLock);
SDL_free(item->original_name);
SDL_free(item);
SDL_OutOfMemory();
return -1;
}
SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1);
item->dupenum = dupenum;
item->name = replacement;
}
item->next = *devices;
*devices = item;
retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */
SDL_UnlockMutex(current_audio.detectionLock);
return retval;
}

References current_audio, SDL_AudioDriver::detectionLock, SDL_AudioDeviceItem::dupenum, SDL_AudioDeviceItem::handle, i, SDL_AudioDeviceItem::name, SDL_AudioDeviceItem::next, NULL, SDL_AudioDeviceItem::original_name, retval, SDL_assert, SDL_free, SDL_LockMutex, SDL_malloc, SDL_OutOfMemory, SDL_snprintf, SDL_strcmp, SDL_strdup, SDL_strlen, and SDL_UnlockMutex.

Referenced by add_capture_device(), and add_output_device().

## add_capture_device()

static SDL_INLINE int add_capture_device | ( | const char * | name,
|  | void * | handle
| ) |  |

static

Definition at line 434 of file SDL_audio.c.

{
SDL_assert(current_audio.impl.HasCaptureSupport);
return add_audio_device(name, handle, &current_audio.inputDevices, &current_audio.inputDeviceCount);
}

References add_audio_device(), current_audio, SDL_AudioDriverImpl::HasCaptureSupport, SDL_AudioDriver::impl, SDL_AudioDriver::inputDeviceCount, SDL_AudioDriver::inputDevices, and SDL_assert.

Referenced by SDL_AddAudioDevice().

## add_output_device()

static SDL_INLINE int add_output_device | ( | const char * | name,
|  | void * | handle
| ) |  |

static

Definition at line 441 of file SDL_audio.c.

{
return add_audio_device(name, handle, &current_audio.outputDevices, &current_audio.outputDeviceCount);
}

References add_audio_device(), current_audio, SDL_AudioDriver::outputDeviceCount, and SDL_AudioDriver::outputDevices.

Referenced by SDL_AddAudioDevice().

## clean_out_device_list()

static void clean_out_device_list | ( | SDL_AudioDeviceItem ** | devices,
|  | int * | devCount,
|  | SDL_bool * | removedFlag
| ) |  |

static

Definition at line 1012 of file SDL_audio.c.

{
SDL_AudioDeviceItem *item = *devices;
SDL_AudioDeviceItem *prev = NULL;
int total = 0;
while (item) {
SDL_AudioDeviceItem *next = item->next;
if (item->handle != NULL) {
total++;
prev = item;
} else {
if (prev) {
prev->next = next;
} else {
*devices = next;
}
/* these two pointers are the same if not a duplicate devname */
if (item->name != item->original_name) {
SDL_free(item->name);
}
SDL_free(item->original_name);
SDL_free(item);
}
item = next;
}
*devCount = total;
*removedFlag = SDL_FALSE;
}

References SDL_AudioDeviceItem::handle, SDL_AudioDeviceItem::name, SDL_AudioDeviceItem::next, NULL, SDL_AudioDeviceItem::original_name, SDL_FALSE, and SDL_free.

Referenced by SDL_GetNumAudioDevices().

## close_audio_device()

static void close_audio_device | ( | SDL_AudioDevice * | device | ) |

static

Definition at line 1110 of file SDL_audio.c.

{
if (!device) {
return;
}
/* make sure the device is paused before we do anything else, so the
audio callback definitely won't fire again. */
current_audio.impl.LockDevice(device);
SDL_AtomicSet(&device->paused, 1);
SDL_AtomicSet(&device->shutdown, 1);
SDL_AtomicSet(&device->enabled, 0);
current_audio.impl.UnlockDevice(device);
if (device->thread != NULL) {
SDL_WaitThread(device->thread, NULL);
}
if (device->mixer_lock != NULL) {
SDL_DestroyMutex(device->mixer_lock);
}
SDL_free(device->work_buffer);
SDL_FreeAudioStream(device->stream);
if (device->id > 0) {
SDL_AudioDevice *opendev = open_devices[device->id - 1];
SDL_assert((opendev == device) || (opendev == NULL));
if (opendev == device) {
open_devices[device->id - 1] = NULL;
}
}
if (device->hidden != NULL) {
current_audio.impl.CloseDevice(device);
}
SDL_FreeDataQueue(device->buffer_queue);
SDL_free(device);
}

References SDL_AudioDriverImpl::CloseDevice, current_audio, device, SDL_AudioDriver::impl, SDL_AudioDriverImpl::LockDevice, NULL, open_devices, SDL_assert, SDL_AtomicSet, SDL_DestroyMutex, SDL_free, SDL_FreeAudioStream, SDL_FreeDataQueue(), SDL_WaitThread, and SDL_AudioDriverImpl::UnlockDevice.

Referenced by open_audio_device(), SDL_AudioQuit(), and SDL_CloseAudioDevice().

## finish_audio_entry_points_init()

static void finish_audio_entry_points_init | ( | void |  | ) |

static

Definition at line 331 of file SDL_audio.c.

{
/*
* Fill in stub functions for unused driver entry points. This lets us
* blindly call them without having to check for validity first.
*/
if (current_audio.impl.SkipMixerLock) {
if (current_audio.impl.LockDevice == NULL) {
current_audio.impl.LockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock;
}
if (current_audio.impl.UnlockDevice == NULL) {
current_audio.impl.UnlockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock;
}
}
#define FILL_STUB(x) \
if (current_audio.impl.x == NULL) { \
current_audio.impl.x = SDL_Audio##x##_Default; \
}
FILL_STUB(DetectDevices);
FILL_STUB(OpenDevice);
FILL_STUB(ThreadInit);
FILL_STUB(ThreadDeinit);
FILL_STUB(BeginLoopIteration);
FILL_STUB(WaitDevice);
FILL_STUB(PlayDevice);
FILL_STUB(GetDeviceBuf);
FILL_STUB(CaptureFromDevice);
FILL_STUB(FlushCapture);
FILL_STUB(PrepareToClose);
FILL_STUB(CloseDevice);
FILL_STUB(LockDevice);
FILL_STUB(UnlockDevice);
FILL_STUB(FreeDeviceHandle);
FILL_STUB(Deinitialize);
#undef FILL_STUB
}

References current_audio, FILL_STUB, SDL_AudioDriver::impl, SDL_AudioDriverImpl::LockDevice, NULL, SDL_AudioLockOrUnlockDeviceWithNoMixerLock(), SDL_AudioDriverImpl::SkipMixerLock, and SDL_AudioDriverImpl::UnlockDevice.

Referenced by SDL_AudioInit().

## free_device_list()

static void free_device_list | ( | SDL_AudioDeviceItem ** | devices,
|  | int * | devCount
| ) |  |

static

Definition at line 447 of file SDL_audio.c.

{
SDL_AudioDeviceItem *item, *next;
for (item = *devices; item != NULL; item = next) {
next = item->next;
if (item->handle != NULL) {
current_audio.impl.FreeDeviceHandle(item->handle);
}
/* these two pointers are the same if not a duplicate devname */
if (item->name != item->original_name) {
SDL_free(item->name);
}
SDL_free(item->original_name);
SDL_free(item);
}
*devices = NULL;
*devCount = 0;
}

References current_audio, SDL_AudioDriverImpl::FreeDeviceHandle, SDL_AudioDeviceItem::handle, SDL_AudioDriver::impl, SDL_AudioDeviceItem::name, SDL_AudioDeviceItem::next, NULL, SDL_AudioDeviceItem::original_name, and SDL_free.

Referenced by SDL_AudioQuit().

## get_audio_device()

static SDL_AudioDevice* get_audio_device | ( | SDL_AudioDeviceID | id | ) |

static

Definition at line 200 of file SDL_audio.c.

{
id--;
if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) {
SDL_SetError("Invalid audio device ID");
return NULL;
}
return open_devices[id];
}

References NULL, open_devices, SDL_arraysize, and SDL_SetError.

Referenced by SDL_ClearQueuedAudio(), SDL_CloseAudioDevice(), SDL_DequeueAudio(), SDL_GetAudioDeviceStatus(), SDL_GetQueuedAudioSize(), SDL_LockAudioDevice(), SDL_MixAudio(), SDL_OpenedAudioDeviceDisconnected(), SDL_PauseAudioDevice(), SDL_QueueAudio(), and SDL_UnlockAudioDevice().

## is_in_audio_device_thread()

static SDL_INLINE SDL_bool is_in_audio_device_thread | ( | SDL_AudioDevice * | device | ) |

static

Definition at line 296 of file SDL_audio.c.

{
/* The device thread locks the same mutex, but not through the public API.
This check is in case the application, in the audio callback,
tries to lock the thread that we've already locked from the
device thread...just in case we only have non-recursive mutexes. */
if (device->thread && (SDL_ThreadID() == device->threadid)) {
return SDL_TRUE;
}
return SDL_FALSE;
}

References device, SDL_FALSE, SDL_ThreadID, and SDL_TRUE.

Referenced by SDL_AudioLockDevice_Default(), and SDL_AudioUnlockDevice_Default().

## mark_device_removed()

static void mark_device_removed | ( | void * | handle,
|  | SDL_AudioDeviceItem * | devices,
|  | SDL_bool * | removedFlag
| ) |  |

static

Definition at line 516 of file SDL_audio.c.

{
SDL_AudioDeviceItem *item;
SDL_assert(handle != NULL);
for (item = devices; item != NULL; item = item->next) {
if (item->handle == handle) {
item->handle = NULL;
*removedFlag = SDL_TRUE;
return;
}
}
}

References SDL_AudioDeviceItem::handle, SDL_AudioDeviceItem::next, NULL, SDL_assert, and SDL_TRUE.

Referenced by SDL_RemoveAudioDevice().

## open_audio_device()

static SDL_AudioDeviceID open_audio_device | ( | const char * | devname,
|  | int | iscapture,
|  | const SDL_AudioSpec * | desired,
|  | SDL_AudioSpec * | obtained,
|  | int | allowed_changes,
|  | int | min_id
| ) |  |

static

Definition at line 1216 of file SDL_audio.c.

{
const SDL_bool is_internal_thread = (desired->callback == NULL);
SDL_AudioDeviceID id = 0;
SDL_AudioSpec _obtained;
SDL_AudioDevice *device;
SDL_bool build_stream;
void *handle = NULL;
int i = 0;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
SDL_SetError("Audio subsystem is not initialized");
return 0;
}
if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
SDL_SetError("No capture support");
return 0;
}
/* !!! FIXME: there is a race condition here if two devices open from two threads at once. */
/* Find an available device ID... */
for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
if (open_devices[id] == NULL) {
break;
}
}
if (id == SDL_arraysize(open_devices)) {
SDL_SetError("Too many open audio devices");
return 0;
}
if (!obtained) {
obtained = &_obtained;
}
if (!prepare_audiospec(desired, obtained)) {
return 0;
}
/* If app doesn't care about a specific device, let the user override. */
if (devname == NULL) {
devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME");
}
/*
* Catch device names at the high level for the simple case...
* This lets us have a basic "device enumeration" for systems that
* don't have multiple devices, but makes sure the device name is
* always NULL when it hits the low level.
*
* Also make sure that the simple case prevents multiple simultaneous
* opens of the default system device.
*/
if ((iscapture) && (current_audio.impl.OnlyHasDefaultCaptureDevice)) {
if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
SDL_SetError("No such device");
return 0;
}
devname = NULL;
for (i = 0; i < SDL_arraysize(open_devices); i++) {
if ((open_devices[i]) && (open_devices[i]->iscapture)) {
SDL_SetError("Audio device already open");
return 0;
}
}
} else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
SDL_SetError("No such device");
return 0;
}
devname = NULL;
for (i = 0; i < SDL_arraysize(open_devices); i++) {
if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
SDL_SetError("Audio device already open");
return 0;
}
}
} else if (devname != NULL) {
/* if the app specifies an exact string, we can pass the backend
an actual device handle thingey, which saves them the effort of
figuring out what device this was (such as, reenumerating
everything again to find the matching human-readable name).
It might still need to open a device based on the string for,
say, a network audio server, but this optimizes some cases. */
SDL_AudioDeviceItem *item;
SDL_LockMutex(current_audio.detectionLock);
for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) {
if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) {
handle = item->handle;
break;
}
}
SDL_UnlockMutex(current_audio.detectionLock);
}
if (!current_audio.impl.AllowsArbitraryDeviceNames) {
/* has to be in our device list, or the default device. */
if ((handle == NULL) && (devname != NULL)) {
SDL_SetError("No such device.");
return 0;
}
}
device = (SDL_AudioDevice *) SDL_calloc(1, sizeof (SDL_AudioDevice));
if (device == NULL) {
SDL_OutOfMemory();
return 0;
}
device->id = id + 1;
device->spec = *obtained;
device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
device->handle = handle;
SDL_AtomicSet(&device->shutdown, 0); /* just in case. */
SDL_AtomicSet(&device->paused, 1);
SDL_AtomicSet(&device->enabled, 1);
/* Create a mutex for locking the sound buffers */
if (!current_audio.impl.SkipMixerLock) {
device->mixer_lock = SDL_CreateMutex();
if (device->mixer_lock == NULL) {
close_audio_device(device);
SDL_SetError("Couldn't create mixer lock");
return 0;
}
}
if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) {
close_audio_device(device);
return 0;
}
/* if your target really doesn't need it, set it to 0x1 or something. */
/* otherwise, close_audio_device() won't call impl.CloseDevice(). */
SDL_assert(device->hidden != NULL);
/* See if we need to do any conversion */
build_stream = SDL_FALSE;
if (obtained->freq != device->spec.freq) {
if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) {
obtained->freq = device->spec.freq;
} else {
build_stream = SDL_TRUE;
}
}
if (obtained->format != device->spec.format) {
if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) {
obtained->format = device->spec.format;
} else {
build_stream = SDL_TRUE;
}
}
if (obtained->channels != device->spec.channels) {
if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) {
obtained->channels = device->spec.channels;
} else {
build_stream = SDL_TRUE;
}
}
if (device->spec.samples != obtained->samples) {
if (allowed_changes & SDL_AUDIO_ALLOW_SAMPLES_CHANGE) {
obtained->samples = device->spec.samples;
} else {
build_stream = SDL_TRUE;
}
}
SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */
device->callbackspec = *obtained;
if (build_stream) {
if (iscapture) {
device->stream = SDL_NewAudioStream(device->spec.format,
device->spec.channels, device->spec.freq,
obtained->format, obtained->channels, obtained->freq);
} else {
device->stream = SDL_NewAudioStream(obtained->format, obtained->channels,
obtained->freq, device->spec.format,
device->spec.channels, device->spec.freq);
}
if (!device->stream) {
close_audio_device(device);
return 0;
}
}
if (device->spec.callback == NULL) { /* use buffer queueing? */
/* pool a few packets to start. Enough for two callbacks. */
device->buffer_queue = SDL_NewDataQueue(SDL_AUDIOBUFFERQUEUE_PACKETLEN, obtained->size * 2);
if (!device->buffer_queue) {
close_audio_device(device);
SDL_SetError("Couldn't create audio buffer queue");
return 0;
}
device->callbackspec.callback = iscapture ? SDL_BufferQueueFillCallback : SDL_BufferQueueDrainCallback;
device->callbackspec.userdata = device;
}
/* Allocate a scratch audio buffer */
device->work_buffer_len = build_stream ? device->callbackspec.size : 0;
if (device->spec.size > device->work_buffer_len) {
device->work_buffer_len = device->spec.size;
}
SDL_assert(device->work_buffer_len > 0);
device->work_buffer = (Uint8 *) SDL_malloc(device->work_buffer_len);
if (device->work_buffer == NULL) {
close_audio_device(device);
SDL_OutOfMemory();
return 0;
}
open_devices[id] = device; /* add it to our list of open devices. */
/* Start the audio thread if necessary */
if (!current_audio.impl.ProvidesOwnCallbackThread) {
/* Start the audio thread */
/* !!! FIXME: we don't force the audio thread stack size here if it calls into user code, but maybe we should? */
/* buffer queueing callback only needs a few bytes, so make the stack tiny. */
const size_t stacksize = is_internal_thread ? 64 * 1024 : 0;
char threadname[64];
SDL_snprintf(threadname, sizeof (threadname), "SDLAudio%c%d", (iscapture) ? 'C' : 'P', (int) device->id);
device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, stacksize, device);
if (device->thread == NULL) {
close_audio_device(device);
SDL_SetError("Couldn't create audio thread");
return 0;
}
}
return device->id;
}

References SDL_AudioDriverImpl::AllowsArbitraryDeviceNames, SDL_AudioSpec::callback, SDL_AudioSpec::channels, close_audio_device(), current_audio, DEFAULT_INPUT_DEVNAME, DEFAULT_OUTPUT_DEVNAME, SDL_AudioDriver::detectionLock, device, SDL_AudioSpec::format, SDL_AudioSpec::freq, SDL_AudioDeviceItem::handle, SDL_AudioDriverImpl::HasCaptureSupport, i, SDL_AudioDriver::impl, SDL_AudioDriver::inputDevices, SDL_AudioDevice::iscapture, SDL_AudioDeviceItem::name, SDL_AudioDeviceItem::next, NULL, SDL_AudioDriverImpl::OnlyHasDefaultCaptureDevice, SDL_AudioDriverImpl::OnlyHasDefaultOutputDevice, open_devices, SDL_AudioDriverImpl::OpenDevice, SDL_AudioDriver::outputDevices, prepare_audiospec(), SDL_AudioDriverImpl::ProvidesOwnCallbackThread, SDL_AudioSpec::samples, SDL_arraysize, SDL_assert, SDL_AtomicSet, SDL_AUDIO_ALLOW_CHANNELS_CHANGE, SDL_AUDIO_ALLOW_FORMAT_CHANGE, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE, SDL_AUDIO_ALLOW_SAMPLES_CHANGE, SDL_AUDIOBUFFERQUEUE_PACKETLEN, SDL_BufferQueueDrainCallback(), SDL_BufferQueueFillCallback(), SDL_CalculateAudioSpec(), SDL_calloc, SDL_CaptureAudio(), SDL_CreateMutex, SDL_CreateThreadInternal(), SDL_FALSE, SDL_getenv, SDL_INIT_AUDIO, SDL_LockMutex, SDL_malloc, SDL_NewAudioStream, SDL_NewDataQueue(), SDL_OutOfMemory, SDL_RunAudio(), SDL_SetError, SDL_snprintf, SDL_strcmp, SDL_TRUE, SDL_UnlockMutex, SDL_WasInit, SDL_AudioSpec::size, and SDL_AudioDriverImpl::SkipMixerLock.

Referenced by SDL_OpenAudio(), and SDL_OpenAudioDevice().

## prepare_audiospec()

static int prepare_audiospec | ( | const SDL_AudioSpec * | orig,
|  | SDL_AudioSpec * | prepared
| ) |  |

static

Definition at line 1158 of file SDL_audio.c.

{
SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec));
if (orig->freq == 0) {
const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY");
if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) {
prepared->freq = 22050; /* a reasonable default */
}
}
if (orig->format == 0) {
const char *env = SDL_getenv("SDL_AUDIO_FORMAT");
if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) {
prepared->format = AUDIO_S16; /* a reasonable default */
}
}
switch (orig->channels) {
case 0:{
const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) {
prepared->channels = 2; /* a reasonable default */
}
break;
}
case 1: /* Mono */
case 2: /* Stereo */
case 4: /* Quadrophonic */
case 6: /* 5.1 surround */
case 8: /* 7.1 surround */
break;
default:
SDL_SetError("Unsupported number of audio channels.");
return 0;
}
if (orig->samples == 0) {
const char *env = SDL_getenv("SDL_AUDIO_SAMPLES");
if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) {
/* Pick a default of ~46 ms at desired frequency */
/* !!! FIXME: remove this when the non-Po2 resampling is in. */
const int samples = (prepared->freq / 1000) * 46;
int power2 = 1;
while (power2 < samples) {
power2 *= 2;
}
prepared->samples = power2;
}
}
/* Calculate the silence and size of the audio specification */
SDL_CalculateAudioSpec(prepared);
return 1;
}

References AUDIO_S16, SDL_AudioSpec::channels, SDL_AudioSpec::format, SDL_AudioSpec::freq, SDL_AudioSpec::samples, SDL_atoi, SDL_CalculateAudioSpec(), SDL_getenv, SDL_memcpy, SDL_ParseAudioFormat(), and SDL_SetError.

Referenced by open_audio_device().

## SDL_AddAudioDevice()

void SDL_AddAudioDevice | ( | const int | iscapture,
|  | const char * | name,
|  | void * | handle
| ) |  |

Definition at line 469 of file SDL_audio.c.

{
const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle);
if (device_index != -1) {
/* Post the event, if desired */
if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) {
SDL_Event event;
SDL_zero(event);
event.adevice.type = SDL_AUDIODEVICEADDED;
event.adevice.which = device_index;
event.adevice.iscapture = iscapture;
SDL_PushEvent(&event);
}
}
}

References add_capture_device(), add_output_device(), SDL_AUDIODEVICEADDED, SDL_ENABLE, SDL_GetEventState, SDL_PushEvent, and SDL_zero.

Referenced by SDL_AudioDetectDevices_Default().

## SDL_AudioBeginLoopIteration_Default()

static void SDL_AudioBeginLoopIteration_Default | ( | _THIS |  | ) |

static

Definition at line 237 of file SDL_audio.c.

{ /* no-op. */
}

## SDL_AudioCaptureFromDevice_Default()

static int SDL_AudioCaptureFromDevice_Default | ( | _THIS | ,
|  | void * | buffer,
|  | int | buflen
| ) |  |

static

Definition at line 258 of file SDL_audio.c.

{
return -1; /* just fail immediately. */
}

## SDL_AudioCloseDevice_Default()

static void SDL_AudioCloseDevice_Default | ( | _THIS |  | ) |

static

Definition at line 274 of file SDL_audio.c.

{ /* no-op. */
}

## SDL_AudioDeinitialize_Default()

static void SDL_AudioDeinitialize_Default | ( | void |  | ) |

static

Definition at line 279 of file SDL_audio.c.

{ /* no-op. */
}

## SDL_AudioDetectDevices_Default()

static void SDL_AudioDetectDevices_Default | ( | void |  | ) |

static

Definition at line 214 of file SDL_audio.c.

{
/* you have to write your own implementation if these assertions fail. */
SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice);
SDL_assert(current_audio.impl.OnlyHasDefaultCaptureDevice || !current_audio.impl.HasCaptureSupport);
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1));
if (current_audio.impl.HasCaptureSupport) {
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2));
}
}

References current_audio, DEFAULT_INPUT_DEVNAME, DEFAULT_OUTPUT_DEVNAME, SDL_AudioDriverImpl::HasCaptureSupport, SDL_AudioDriver::impl, SDL_AudioDriverImpl::OnlyHasDefaultCaptureDevice, SDL_AudioDriverImpl::OnlyHasDefaultOutputDevice, SDL_AddAudioDevice(), SDL_assert, SDL_FALSE, and SDL_TRUE.

## SDL_AudioFlushCapture_Default()

static void SDL_AudioFlushCapture_Default | ( | _THIS |  | ) |

static

Definition at line 264 of file SDL_audio.c.

{ /* no-op. */
}

## SDL_AudioFreeDeviceHandle_Default()

static void SDL_AudioFreeDeviceHandle_Default | ( | void * | handle | ) |

static

Definition at line 284 of file SDL_audio.c.

{ /* no-op. */
}

## SDL_AudioGetDeviceBuf_Default()

static Uint8* SDL_AudioGetDeviceBuf_Default | ( | _THIS |  | ) |

static

Definition at line 252 of file SDL_audio.c.

{
return NULL;
}

References NULL.

## SDL_AudioInit()

int SDL_AudioInit | ( | const char * | driver_name | ) |

Definition at line 940 of file SDL_audio.c.

{
int i = 0;
int initialized = 0;
int tried_to_init = 0;
if (SDL_WasInit(SDL_INIT_AUDIO)) {
SDL_AudioQuit(); /* shutdown driver if already running. */
}
SDL_zero(current_audio);
SDL_zero(open_devices);
/* Select the proper audio driver */
if (driver_name == NULL) {
driver_name = SDL_getenv("SDL_AUDIODRIVER");
}
for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
/* make sure we should even try this driver before doing so... */
const AudioBootStrap *backend = bootstrap[i];
if ((driver_name && (SDL_strncasecmp(backend->name, driver_name, SDL_strlen(driver_name)) != 0)) ||
(!driver_name && backend->demand_only)) {
continue;
}
tried_to_init = 1;
SDL_zero(current_audio);
current_audio.name = backend->name;
current_audio.desc = backend->desc;
initialized = backend->init(&current_audio.impl);
}
if (!initialized) {
/* specific drivers will set the error message if they fail... */
if (!tried_to_init) {
if (driver_name) {
SDL_SetError("Audio target '%s' not available", driver_name);
} else {
SDL_SetError("No available audio device");
}
}
SDL_zero(current_audio);
return -1; /* No driver was available, so fail. */
}
current_audio.detectionLock = SDL_CreateMutex();
finish_audio_entry_points_init();
/* Make sure we have a list of devices available at startup. */
current_audio.impl.DetectDevices();
#ifdef HAVE_LIBSAMPLERATE_H
LoadLibSampleRate();
#endif
return 0;
}

References bootstrap, current_audio, AudioBootStrap::demand_only, SDL_AudioDriver::desc, AudioBootStrap::desc, SDL_AudioDriverImpl::DetectDevices, SDL_AudioDriver::detectionLock, finish_audio_entry_points_init(), i, SDL_AudioDriver::impl, AudioBootStrap::init, SDL_AudioDriver::name, AudioBootStrap::name, NULL, open_devices, SDL_AudioQuit(), SDL_CreateMutex, SDL_getenv, SDL_INIT_AUDIO, SDL_SetError, SDL_strlen, SDL_strncasecmp, SDL_WasInit, and SDL_zero.

## SDL_AudioLockDevice_Default()

static void SDL_AudioLockDevice_Default | ( | SDL_AudioDevice * | device | ) |

static

Definition at line 310 of file SDL_audio.c.

{
if (!is_in_audio_device_thread(device)) {
SDL_LockMutex(device->mixer_lock);
}
}

References device, is_in_audio_device_thread(), and SDL_LockMutex.

## SDL_AudioLockOrUnlockDeviceWithNoMixerLock()

static void SDL_AudioLockOrUnlockDeviceWithNoMixerLock | ( | SDL_AudioDevice * | device | ) |

static

Definition at line 326 of file SDL_audio.c.

{
}

Referenced by finish_audio_entry_points_init().

## SDL_AudioOpenDevice_Default()

static int SDL_AudioOpenDevice_Default | ( | _THIS | ,
|  | void * | handle,
|  | const char * | devname,
|  | int | iscapture
| ) |  |

static

Definition at line 290 of file SDL_audio.c.

{
return SDL_Unsupported();
}

References SDL_Unsupported.

## SDL_AudioPlayDevice_Default()

static void SDL_AudioPlayDevice_Default | ( | _THIS |  | ) |

static

Definition at line 247 of file SDL_audio.c.

{ /* no-op. */
}

## SDL_AudioPrepareToClose_Default()

static void SDL_AudioPrepareToClose_Default | ( | _THIS |  | ) |

static

Definition at line 269 of file SDL_audio.c.

{ /* no-op. */
}

## SDL_AudioQuit()

void SDL_AudioQuit | ( | void |  | ) |

Definition at line 1590 of file SDL_audio.c.

{
SDL_AudioDeviceID i;
if (!current_audio.name) { /* not initialized?! */
return;
}
for (i = 0; i < SDL_arraysize(open_devices); i++) {
close_audio_device(open_devices[i]);
}
free_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount);
free_device_list(&current_audio.inputDevices, &current_audio.inputDeviceCount);
/* Free the driver data */
current_audio.impl.Deinitialize();
SDL_DestroyMutex(current_audio.detectionLock);
SDL_zero(current_audio);
SDL_zero(open_devices);
#ifdef HAVE_LIBSAMPLERATE_H
UnloadLibSampleRate();
#endif
SDL_FreeResampleFilter();
}

References close_audio_device(), current_audio, SDL_AudioDriverImpl::Deinitialize, SDL_AudioDriver::detectionLock, free_device_list(), i, SDL_AudioDriver::impl, SDL_AudioDriver::inputDeviceCount, SDL_AudioDriver::inputDevices, SDL_AudioDriver::name, open_devices, SDL_AudioDriver::outputDeviceCount, SDL_AudioDriver::outputDevices, SDL_arraysize, SDL_DestroyMutex, SDL_FreeResampleFilter(), and SDL_zero.

Referenced by SDL_AudioInit().

## SDL_AudioThreadDeinit_Default()

static void SDL_AudioThreadDeinit_Default | ( | _THIS |  | ) |

static

Definition at line 232 of file SDL_audio.c.

{ /* no-op. */
}

## SDL_AudioThreadInit_Default()

static void SDL_AudioThreadInit_Default | ( | _THIS |  | ) |

static

Definition at line 227 of file SDL_audio.c.

{ /* no-op. */
}

## SDL_AudioUnlockDevice_Default()

static void SDL_AudioUnlockDevice_Default | ( | SDL_AudioDevice * | device | ) |

static

Definition at line 318 of file SDL_audio.c.

{
if (!is_in_audio_device_thread(device)) {
SDL_UnlockMutex(device->mixer_lock);
}
}

References device, is_in_audio_device_thread(), and SDL_UnlockMutex.

## SDL_AudioWaitDevice_Default()

static void SDL_AudioWaitDevice_Default | ( | _THIS |  | ) |

static

Definition at line 242 of file SDL_audio.c.

{ /* no-op. */
}

## SDL_BufferQueueDrainCallback()

static void SDL_BufferQueueDrainCallback | ( | void * | userdata,
|  | Uint8 * | stream,
|  | int | len
| ) |  |

static

Definition at line 561 of file SDL_audio.c.

{
/* this function always holds the mixer lock before being called. */
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
size_t dequeued;
SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */
SDL_assert(!device->iscapture); /* this shouldn't ever happen, right?! */
SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */
dequeued = SDL_ReadFromDataQueue(device->buffer_queue, stream, len);
stream += dequeued;
len -= (int) dequeued;
if (len > 0) { /* fill any remaining space in the stream with silence. */
SDL_assert(SDL_CountDataQueue(device->buffer_queue) == 0);
SDL_memset(stream, device->spec.silence, len);
}
}

References device, NULL, SDL_assert, SDL_CountDataQueue(), SDL_memset, and SDL_ReadFromDataQueue().

Referenced by open_audio_device(), SDL_GetQueuedAudioSize(), and SDL_QueueAudio().

## SDL_BufferQueueFillCallback()

static void SDL_BufferQueueFillCallback | ( | void * | userdata,
|  | Uint8 * | stream,
|  | int | len
| ) |  |

static

Definition at line 582 of file SDL_audio.c.

{
/* this function always holds the mixer lock before being called. */
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */
SDL_assert(device->iscapture); /* this shouldn't ever happen, right?! */
SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */
/* note that if this needs to allocate more space and run out of memory,
we have no choice but to quietly drop the data and hope it works out
later, but you probably have bigger problems in this case anyhow. */
SDL_WriteToDataQueue(device->buffer_queue, stream, len);
}

References device, NULL, SDL_assert, and SDL_WriteToDataQueue().

Referenced by open_audio_device(), SDL_DequeueAudio(), and SDL_GetQueuedAudioSize().

## SDL_CalculateAudioSpec()

void SDL_CalculateAudioSpec | ( | SDL_AudioSpec * | spec | ) |

Definition at line 1668 of file SDL_audio.c.

{
switch (spec->format) {
case AUDIO_U8:
spec->silence = 0x80;
break;
default:
spec->silence = 0x00;
break;
}
spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8;
spec->size *= spec->channels;
spec->size *= spec->samples;
}

References AUDIO_U8, SDL_AudioSpec::channels, SDL_AudioSpec::format, SDL_AudioSpec::samples, SDL_AUDIO_BITSIZE, SDL_AudioSpec::silence, SDL_AudioSpec::size, and spec.

Referenced by open_audio_device(), and prepare_audiospec().

## SDL_CaptureAudio()

static int SDL_CaptureAudio | ( | void * | devicep | ) |

static

Definition at line 785 of file SDL_audio.c.

{
SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
const int silence = (int) device->spec.silence;
const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
const int data_len = device->spec.size;
Uint8 *data;
void *udata = device->callbackspec.userdata;
SDL_AudioCallback callback = device->callbackspec.callback;
SDL_assert(device->iscapture);
#if SDL_AUDIO_DRIVER_ANDROID
{
/* Set thread priority to THREAD_PRIORITY_AUDIO */
extern void Android_JNI_AudioSetThreadPriority(int, int);
Android_JNI_AudioSetThreadPriority(device->iscapture, device->id);
}
#else
/* The audio mixing is always a high priority thread */
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
#endif
/* Perform any thread setup */
device->threadid = SDL_ThreadID();
current_audio.impl.ThreadInit(device);
/* Loop, filling the audio buffers */
while (!SDL_AtomicGet(&device->shutdown)) {
int still_need;
Uint8 *ptr;
current_audio.impl.BeginLoopIteration(device);
if (SDL_AtomicGet(&device->paused)) {
SDL_Delay(delay); /* just so we don't cook the CPU. */
if (device->stream) {
SDL_AudioStreamClear(device->stream);
}
current_audio.impl.FlushCapture(device); /* dump anything pending. */
continue;
}
/* Fill the current buffer with sound */
still_need = data_len;
/* Use the work_buffer to hold data read from the device. */
data = device->work_buffer;
SDL_assert(data != NULL);
ptr = data;
/* We still read from the device when "paused" to keep the state sane,
and block when there isn't data so this thread isn't eating CPU.
But we don't process it further or call the app's callback. */
if (!SDL_AtomicGet(&device->enabled)) {
SDL_Delay(delay); /* try to keep callback firing at normal pace. */
} else {
while (still_need > 0) {
const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need);
SDL_assert(rc <= still_need); /* device should not overflow buffer. :) */
if (rc > 0) {
still_need -= rc;
ptr += rc;
} else { /* uhoh, device failed for some reason! */
SDL_OpenedAudioDeviceDisconnected(device);
break;
}
}
}
if (still_need > 0) {
/* Keep any data we already read, silence the rest. */
SDL_memset(ptr, silence, still_need);
}
if (device->stream) {
/* if this fails...oh well. */
SDL_AudioStreamPut(device->stream, data, data_len);
while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->callbackspec.size)) {
const int got = SDL_AudioStreamGet(device->stream, device->work_buffer, device->callbackspec.size);
SDL_assert((got < 0) || (got == device->callbackspec.size));
if (got != device->callbackspec.size) {
SDL_memset(device->work_buffer, device->spec.silence, device->callbackspec.size);
}
/* !!! FIXME: this should be LockDevice. */
SDL_LockMutex(device->mixer_lock);
if (!SDL_AtomicGet(&device->paused)) {
callback(udata, device->work_buffer, device->callbackspec.size);
}
SDL_UnlockMutex(device->mixer_lock);
}
} else { /* feeding user callback directly without streaming. */
/* !!! FIXME: this should be LockDevice. */
SDL_LockMutex(device->mixer_lock);
if (!SDL_AtomicGet(&device->paused)) {
callback(udata, data, device->callbackspec.size);
}
SDL_UnlockMutex(device->mixer_lock);
}
}
current_audio.impl.FlushCapture(device);
current_audio.impl.ThreadDeinit(device);
return 0;
}

References Android_JNI_AudioSetThreadPriority(), SDL_AudioDriverImpl::BeginLoopIteration, callback(), SDL_AudioDriverImpl::CaptureFromDevice, current_audio, device, SDL_AudioDriverImpl::FlushCapture, SDL_AudioDriver::impl, NULL, SDL_assert, SDL_AtomicGet, SDL_AudioStreamAvailable, SDL_AudioStreamClear, SDL_AudioStreamGet, SDL_AudioStreamPut, SDL_Delay, SDL_LockMutex, SDL_memset, SDL_OpenedAudioDeviceDisconnected(), SDL_SetThreadPriority, SDL_THREAD_PRIORITY_HIGH, SDL_ThreadID, SDL_UnlockMutex, SDL_AudioDriverImpl::ThreadDeinit, and SDL_AudioDriverImpl::ThreadInit.

Referenced by open_audio_device().

## SDL_ClearQueuedAudio()

void SDL_ClearQueuedAudio | ( | SDL_AudioDeviceID | dev | ) |

Drop any queued audio data. For playback devices, this is any queued data still waiting to be submitted to the hardware. For capture devices, this is any data that was queued by the device that hasn't yet been dequeued by the application.

Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For playback devices, the hardware will start playing silence if more audio isn't queued. Unpaused capture devices will start filling the queue again as soon as they have more data available (which, depending on the state of the hardware and the thread, could be before this function call returns!).

This will not prevent playback of queued audio that's already been sent to the hardware, as we can not undo that, so expect there to be some fraction of a second of audio that might still be heard. This can be useful if you want to, say, drop any pending music during a level change in your game.

You may not queue audio on a device that is using an application-supplied callback; calling this function on such a device is always a no-op. You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use the audio callback, but not both.

You should not call SDL_LockAudio() on the device before clearing the queue; SDL handles locking internally for this function.

This function always succeeds and thus returns void.

Parameters

  dev | The device ID of which to clear the audio queue.

See also
  SDL_QueueAudio
  SDL_GetQueuedAudioSize

Definition at line 662 of file SDL_audio.c.

{
SDL_AudioDevice *device = get_audio_device(devid);
if (!device) {
return; /* nothing to do. */
}
/* Blank out the device and release the mutex. Free it afterwards. */
current_audio.impl.LockDevice(device);
/* Keep up to two packets in the pool to reduce future malloc pressure. */
SDL_ClearDataQueue(device->buffer_queue, SDL_AUDIOBUFFERQUEUE_PACKETLEN * 2);
current_audio.impl.UnlockDevice(device);
}

References current_audio, device, get_audio_device(), SDL_AudioDriver::impl, SDL_AudioDriverImpl::LockDevice, SDL_AUDIOBUFFERQUEUE_PACKETLEN, SDL_ClearDataQueue(), and SDL_AudioDriverImpl::UnlockDevice.

## SDL_CloseAudio()

void SDL_CloseAudio | ( | void |  | ) |

This function shuts down audio processing and closes the audio device.

Definition at line 1584 of file SDL_audio.c.

{
SDL_CloseAudioDevice(1);
}

References SDL_CloseAudioDevice().

## SDL_CloseAudioDevice()

void SDL_CloseAudioDevice | ( | SDL_AudioDeviceID | devid | ) |

Definition at line 1578 of file SDL_audio.c.

{
close_audio_device(get_audio_device(devid));
}

References close_audio_device(), and get_audio_device().

Referenced by SDL_CloseAudio().

## SDL_DequeueAudio()

Uint32 SDL_DequeueAudio | ( | SDL_AudioDeviceID | dev,
|  | void * | data,
|  | Uint32 | len
| ) |  |

Dequeue more audio on non-callback devices.

(If you are looking to queue audio for output on a non-callback playback device, you want SDL_QueueAudio() instead. This will always return 0 if you use it with playback devices.)

SDL offers two ways to retrieve audio from a capture device: you can either supply a callback that SDL triggers with some frequency as the device records more audio data, (push method), or you can supply no callback, and then SDL will expect you to retrieve data at regular intervals (pull method) with this function.

There are no limits on the amount of data you can queue, short of exhaustion of address space. Data from the device will keep queuing as necessary without further intervention from you. This means you will eventually run out of memory if you aren't routinely dequeueing data.

Capture devices will not queue data when paused; if you are expecting to not need captured audio for some length of time, use SDL_PauseAudioDevice() to stop the capture device from queueing more data. This can be useful during, say, level loading times. When unpaused, capture devices will start queueing data from that point, having flushed any capturable data available while paused.

This function is thread-safe, but dequeueing from the same device from two threads at once does not promise which thread will dequeued data first.

You may not dequeue audio from a device that is using an application-supplied callback; doing so returns an error. You have to use the audio callback, or dequeue audio with this function, but not both.

You should not call SDL_LockAudio() on the device before queueing; SDL handles locking internally for this function.

Parameters

  dev | The device ID from which we will dequeue audio.
  data | A pointer into where audio data should be copied.
  len | The number of bytes (not samples!) to which (data) points.

Returns
  number of bytes dequeued, which could be less than requested.

See also
  SDL_GetQueuedAudioSize
  SDL_ClearQueuedAudio

Definition at line 621 of file SDL_audio.c.

{
SDL_AudioDevice *device = get_audio_device(devid);
Uint32 rc;
if ( (len == 0) || /* nothing to do? */
(!device) || /* called with bogus device id */
(!device->iscapture) || /* playback devices can't dequeue */
(device->callbackspec.callback != SDL_BufferQueueFillCallback) ) { /* not set for queueing */
return 0; /* just report zero bytes dequeued. */
}
current_audio.impl.LockDevice(device);
rc = (Uint32) SDL_ReadFromDataQueue(device->buffer_queue, data, len);
current_audio.impl.UnlockDevice(device);
return rc;
}

References current_audio, device, get_audio_device(), SDL_AudioDriver::impl, SDL_AudioDriverImpl::LockDevice, SDL_BufferQueueFillCallback(), SDL_ReadFromDataQueue(), and SDL_AudioDriverImpl::UnlockDevice.

## SDL_FirstAudioFormat()

SDL_AudioFormat SDL_FirstAudioFormat | ( | SDL_AudioFormat | format | ) |

Definition at line 1647 of file SDL_audio.c.

{
for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) {
if (format_list[format_idx][0] == format) {
break;
}
}
format_idx_sub = 0;
return SDL_NextAudioFormat();
}

References format_idx, format_idx_sub, format_list, NUM_FORMATS, and SDL_NextAudioFormat().

## SDL_GetAudioDeviceName()

const char* SDL_GetAudioDeviceName | ( | int | index,
|  | int | iscapture
| ) |  |

Get the human-readable name of a specific audio device. Must be a value between 0 and (number of audio devices-1). Only valid after a successfully initializing the audio subsystem. The values returned by this function reflect the latest call to SDL_GetNumAudioDevices(); recall that function to redetect available hardware.

The string returned by this function is UTF-8 encoded, read-only, and managed internally. You are not to free it. If you need to keep the string for any length of time, you should make your own copy of it, as it will be invalid next time any of several other SDL functions is called.

Definition at line 1070 of file SDL_audio.c.

{
const char *retval = NULL;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
SDL_SetError("Audio subsystem is not initialized");
return NULL;
}
if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
SDL_SetError("No capture support");
return NULL;
}
if (index >= 0) {
SDL_AudioDeviceItem *item;
int i;
SDL_LockMutex(current_audio.detectionLock);
item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
if (index < i) {
for (i--; i > index; i--, item = item->next) {
SDL_assert(item != NULL);
}
SDL_assert(item != NULL);
retval = item->name;
}
SDL_UnlockMutex(current_audio.detectionLock);
}
if (retval == NULL) {
SDL_SetError("No such device");
}
return retval;
}

References current_audio, SDL_AudioDriver::detectionLock, SDL_AudioDriverImpl::HasCaptureSupport, i, SDL_AudioDriver::impl, SDL_AudioDriver::inputDeviceCount, SDL_AudioDriver::inputDevices, SDL_AudioDeviceItem::next, NULL, SDL_AudioDriver::outputDeviceCount, SDL_AudioDriver::outputDevices, retval, SDL_assert, SDL_INIT_AUDIO, SDL_LockMutex, SDL_SetError, SDL_UnlockMutex, and SDL_WasInit.

## SDL_GetAudioDeviceStatus()

SDL_AudioStatus SDL_GetAudioDeviceStatus | ( | SDL_AudioDeviceID | devid | ) |

Definition at line 1506 of file SDL_audio.c.

{
SDL_AudioDevice *device = get_audio_device(devid);
SDL_AudioStatus status = SDL_AUDIO_STOPPED;
if (device && SDL_AtomicGet(&device->enabled)) {
if (SDL_AtomicGet(&device->paused)) {
status = SDL_AUDIO_PAUSED;
} else {
status = SDL_AUDIO_PLAYING;
}
}
return status;
}

References device, get_audio_device(), SDL_AtomicGet, SDL_AUDIO_PAUSED, SDL_AUDIO_PLAYING, and SDL_AUDIO_STOPPED.

Referenced by SDL_GetAudioStatus().

## SDL_GetAudioDriver()

const char* SDL_GetAudioDriver | ( | int | index | ) |

Definition at line 931 of file SDL_audio.c.

{
if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
return bootstrap[index]->name;
}
return NULL;
}

References bootstrap, AudioBootStrap::name, NULL, and SDL_GetNumAudioDrivers().

## SDL_GetAudioStatus()

SDL_AudioStatus SDL_GetAudioStatus | ( | void |  | ) |

Definition at line 1522 of file SDL_audio.c.

{
return SDL_GetAudioDeviceStatus(1);
}

References SDL_GetAudioDeviceStatus().

## SDL_GetCurrentAudioDriver()

const char* SDL_GetCurrentAudioDriver | ( | void |  | ) |

This function returns the name of the current audio driver, or NULL if no driver has been initialized.

Definition at line 1005 of file SDL_audio.c.

{
return current_audio.name;
}

References current_audio, and SDL_AudioDriver::name.

## SDL_GetNumAudioDevices()

int SDL_GetNumAudioDevices | ( | int | iscapture | ) |

Get the number of available devices exposed by the current driver. Only valid after a successfully initializing the audio subsystem. Returns -1 if an explicit list of devices can't be determined; this is not an error. For example, if SDL is set up to talk to a remote audio server, it can't list every one available on the Internet, but it will still allow a specific host to be specified to SDL_OpenAudioDevice().

In many common cases, when this function returns a value <= 0, it can still successfully open the default device (NULL for first argument of SDL_OpenAudioDevice()).

Definition at line 1045 of file SDL_audio.c.

{
int retval = 0;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
return -1;
}
SDL_LockMutex(current_audio.detectionLock);
if (iscapture && current_audio.captureDevicesRemoved) {
clean_out_device_list(&current_audio.inputDevices, &current_audio.inputDeviceCount, &current_audio.captureDevicesRemoved);
}
if (!iscapture && current_audio.outputDevicesRemoved) {
clean_out_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount, &current_audio.outputDevicesRemoved);
}
retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
SDL_UnlockMutex(current_audio.detectionLock);
return retval;
}

References SDL_AudioDriver::captureDevicesRemoved, clean_out_device_list(), current_audio, SDL_AudioDriver::detectionLock, SDL_AudioDriver::inputDeviceCount, SDL_AudioDriver::inputDevices, SDL_AudioDriver::outputDeviceCount, SDL_AudioDriver::outputDevices, SDL_AudioDriver::outputDevicesRemoved, retval, SDL_INIT_AUDIO, SDL_LockMutex, SDL_UnlockMutex, and SDL_WasInit.

## SDL_GetNumAudioDrivers()

int SDL_GetNumAudioDrivers | ( | void |  | ) |

Definition at line 925 of file SDL_audio.c.

{
return SDL_arraysize(bootstrap) - 1;
}

References bootstrap, and SDL_arraysize.

Referenced by SDL_GetAudioDriver().

## SDL_GetQueuedAudioSize()

Uint32 SDL_GetQueuedAudioSize | ( | SDL_AudioDeviceID | dev | ) |

Get the number of bytes of still-queued audio.

For playback device:

This is the number of bytes that have been queued for playback with SDL_QueueAudio(), but have not yet been sent to the hardware. This number may shrink at any time, so this only informs of pending data.

Once we've sent it to the hardware, this function can not decide the exact byte boundary of what has been played. It's possible that we just gave the hardware several kilobytes right before you called this function, but it hasn't played any of it yet, or maybe half of it, etc.

For capture devices:

This is the number of bytes that have been captured by the device and are waiting for you to dequeue. This number may grow at any time, so this only informs of the lower-bound of available data.

You may not queue audio on a device that is using an application-supplied callback; calling this function on such a device always returns 0. You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use the audio callback, but not both.

You should not call SDL_LockAudio() on the device before querying; SDL handles locking internally for this function.

Parameters

  dev | The device ID of which we will query queued audio size.

Returns
  Number of bytes (not samples!) of queued audio.

See also
  SDL_QueueAudio
  SDL_ClearQueuedAudio

Definition at line 640 of file SDL_audio.c.

{
Uint32 retval = 0;
SDL_AudioDevice *device = get_audio_device(devid);
if (!device) {
return 0;
}
/* Nothing to do unless we're set up for queueing. */
if (device->callbackspec.callback == SDL_BufferQueueDrainCallback ||
device->callbackspec.callback == SDL_BufferQueueFillCallback)
{
current_audio.impl.LockDevice(device);
retval = (Uint32) SDL_CountDataQueue(device->buffer_queue);
current_audio.impl.UnlockDevice(device);
}
return retval;
}

References current_audio, device, get_audio_device(), SDL_AudioDriver::impl, SDL_AudioDriverImpl::LockDevice, retval, SDL_BufferQueueDrainCallback(), SDL_BufferQueueFillCallback(), SDL_CountDataQueue(), and SDL_AudioDriverImpl::UnlockDevice.

## SDL_LockAudio()

void SDL_LockAudio | ( | void |  | ) |

Definition at line 1556 of file SDL_audio.c.

{
SDL_LockAudioDevice(1);
}

References SDL_LockAudioDevice().

## SDL_LockAudioDevice()

void SDL_LockAudioDevice | ( | SDL_AudioDeviceID | devid | ) |

Definition at line 1546 of file SDL_audio.c.

{
/* Obtain a lock on the mixing buffers */
SDL_AudioDevice *device = get_audio_device(devid);
if (device) {
current_audio.impl.LockDevice(device);
}
}

References current_audio, device, get_audio_device(), SDL_AudioDriver::impl, and SDL_AudioDriverImpl::LockDevice.

Referenced by SDL_LockAudio().

## SDL_MixAudio()

void SDL_MixAudio | ( | Uint8 * | dst,
|  | const Uint8 * | src,
|  | Uint32 | len,
|  | int | volume
| ) |  |

This takes two audio buffers of the playing audio format and mixes them, performing addition, volume adjustment, and overflow clipping. The volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME for full audio volume. Note this does not change hardware volume. This is provided for convenience – you can mix your own audio data.

Definition at line 1689 of file SDL_audio.c.

{
/* Mix the user-level audio format */
SDL_AudioDevice *device = get_audio_device(1);
if (device != NULL) {
SDL_MixAudioFormat(dst, src, device->callbackspec.format, len, volume);
}
}

References device, get_audio_device(), NULL, and SDL_MixAudioFormat.

## SDL_NextAudioFormat()

SDL_AudioFormat SDL_NextAudioFormat | ( | void |  | ) |

Definition at line 1659 of file SDL_audio.c.

{
if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
return 0;
}
return format_list[format_idx][format_idx_sub++];
}

References format_idx, format_idx_sub, format_list, and NUM_FORMATS.

Referenced by SDL_FirstAudioFormat().

## SDL_OpenAudio()

int SDL_OpenAudio | ( | SDL_AudioSpec * | desired,
|  | SDL_AudioSpec * | obtained
| ) |  |

This function opens the audio device with the desired parameters, and returns 0 if successful, placing the actual hardware parameters in the structure pointed to by `obtained`. If `obtained` is NULL, the audio data passed to the callback function will be guaranteed to be in the requested format, and will be automatically converted to the hardware audio format if necessary. This function returns -1 if it failed to open the audio device, or couldn't set up the audio thread.

When filling in the desired audio spec structure,

- `desired->freq` should be the desired audio frequency in samples-per- second.
- `desired->format` should be the desired audio format.
- `desired->samples` is the desired size of the audio buffer, in samples. This number should be a power of two, and may be adjusted by the audio driver to a value more suitable for the hardware. Good values seem to range between 512 and 8096 inclusive, depending on the application and CPU speed. Smaller values yield faster response time, but can lead to underflow if the application is doing heavy processing and cannot fill the audio buffer in time. A stereo sample consists of both right and left channels in LR ordering. Note that the number of samples is directly related to time by the following formula:
  ms = (samples*1000)/freq
- `desired->size` is the size in bytes of the audio buffer, and is calculated by SDL_OpenAudio().
- `desired->silence` is the value used to set the buffer to silence, and is calculated by SDL_OpenAudio().
- `desired->callback` should be set to a function that will be called when the audio device is ready for more data. It is passed a pointer to the audio buffer, and the length in bytes of the audio buffer. This function usually runs in a separate thread, and so you should protect data structures that it accesses by calling SDL_LockAudio() and SDL_UnlockAudio() in your code. Alternately, you may pass a NULL pointer here, and call SDL_QueueAudio() with some frequency, to queue more audio samples to be played (or for capture devices, call SDL_DequeueAudio() with some frequency, to obtain audio samples).
- `desired->userdata` is passed as the first parameter to your callback function. If you passed a NULL callback, this value is ignored.

The audio device starts out playing silence when it's opened, and should be enabled for playing by calling `SDL_PauseAudio(0)` when you are ready for your audio callback function to be called. Since the audio driver may modify the requested size of the audio buffer, you should allocate any local mixing buffers after you open the audio device.

Definition at line 1461 of file SDL_audio.c.

{
SDL_AudioDeviceID id = 0;
/* Start up the audio driver, if necessary. This is legacy behaviour! */
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
return -1;
}
}
/* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
if (open_devices[0] != NULL) {
SDL_SetError("Audio device is already opened");
return -1;
}
if (obtained) {
id = open_audio_device(NULL, 0, desired, obtained,
SDL_AUDIO_ALLOW_ANY_CHANGE, 1);
} else {
SDL_AudioSpec _obtained;
SDL_zero(_obtained);
id = open_audio_device(NULL, 0, desired, &_obtained, 0, 1);
/* On successful open, copy calculated values into 'desired'. */
if (id > 0) {
desired->size = _obtained.size;
desired->silence = _obtained.silence;
}
}
SDL_assert((id == 0) || (id == 1));
return (id == 0) ? -1 : 0;
}

References NULL, open_audio_device(), open_devices, SDL_assert, SDL_AUDIO_ALLOW_ANY_CHANGE, SDL_INIT_AUDIO, SDL_InitSubSystem, SDL_SetError, SDL_WasInit, SDL_zero, SDL_AudioSpec::silence, and SDL_AudioSpec::size.

## SDL_OpenAudioDevice()

SDL_AudioDeviceID SDL_OpenAudioDevice | ( | const char * | device,
|  | int | iscapture,
|  | const SDL_AudioSpec * | desired,
|  | SDL_AudioSpec * | obtained,
|  | int | allowed_changes
| ) |  |

Open a specific audio device. Passing in a device name of NULL requests the most reasonable default (and is equivalent to calling SDL_OpenAudio()).

The device name is a UTF-8 string reported by SDL_GetAudioDeviceName(), but some drivers allow arbitrary and driver-specific strings, such as a hostname/IP address for a remote audio server, or a filename in the diskaudio driver.

Returns
  0 on error, a valid device ID that is >= 2 on success.

SDL_OpenAudio(), unlike this function, always acts on device ID 1.

Definition at line 1497 of file SDL_audio.c.

{
return open_audio_device(device, iscapture, desired, obtained,
allowed_changes, 2);
}

References device, and open_audio_device().

## SDL_OpenedAudioDeviceDisconnected()

void SDL_OpenedAudioDeviceDisconnected | ( | SDL_AudioDevice * | device | ) |

Definition at line 486 of file SDL_audio.c.

{
SDL_assert(get_audio_device(device->id) == device);
if (!SDL_AtomicGet(&device->enabled)) {
return; /* don't report disconnects more than once. */
}
if (SDL_AtomicGet(&device->shutdown)) {
return; /* don't report disconnect if we're trying to close device. */
}
/* Ends the audio callback and mark the device as STOPPED, but the
app still needs to close the device to free resources. */
current_audio.impl.LockDevice(device);
SDL_AtomicSet(&device->enabled, 0);
current_audio.impl.UnlockDevice(device);
/* Post the event, if desired */
if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) {
SDL_Event event;
SDL_zero(event);
event.adevice.type = SDL_AUDIODEVICEREMOVED;
event.adevice.which = device->id;
event.adevice.iscapture = device->iscapture ? 1 : 0;
SDL_PushEvent(&event);
}
}

References current_audio, device, get_audio_device(), SDL_AudioDriver::impl, SDL_AudioDriverImpl::LockDevice, SDL_assert, SDL_AtomicGet, SDL_AtomicSet, SDL_AUDIODEVICEREMOVED, SDL_ENABLE, SDL_GetEventState, SDL_PushEvent, SDL_zero, and SDL_AudioDriverImpl::UnlockDevice.

Referenced by SDL_CaptureAudio(), and SDL_RemoveAudioDevice().

## SDL_ParseAudioFormat()

static SDL_AudioFormat SDL_ParseAudioFormat | ( | const char * | string | ) |

static

Definition at line 899 of file SDL_audio.c.

{
#define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x
CHECK_FMT_STRING(U8);
CHECK_FMT_STRING(S8);
CHECK_FMT_STRING(U16LSB);
CHECK_FMT_STRING(S16LSB);
CHECK_FMT_STRING(U16MSB);
CHECK_FMT_STRING(S16MSB);
CHECK_FMT_STRING(U16SYS);
CHECK_FMT_STRING(S16SYS);
CHECK_FMT_STRING(U16);
CHECK_FMT_STRING(S16);
CHECK_FMT_STRING(S32LSB);
CHECK_FMT_STRING(S32MSB);
CHECK_FMT_STRING(S32SYS);
CHECK_FMT_STRING(S32);
CHECK_FMT_STRING(F32LSB);
CHECK_FMT_STRING(F32MSB);
CHECK_FMT_STRING(F32SYS);
CHECK_FMT_STRING(F32);
#undef CHECK_FMT_STRING
return 0;
}

References CHECK_FMT_STRING, and S32.

Referenced by prepare_audiospec().

## SDL_PauseAudio()

void SDL_PauseAudio | ( | int | pause_on | ) |

Definition at line 1539 of file SDL_audio.c.

{
SDL_PauseAudioDevice(1, pause_on);
}

References SDL_PauseAudioDevice().

## SDL_PauseAudioDevice()

void SDL_PauseAudioDevice | ( | SDL_AudioDeviceID | devid,
|  | int | pause_on
| ) |  |

Definition at line 1528 of file SDL_audio.c.

{
SDL_AudioDevice *device = get_audio_device(devid);
if (device) {
current_audio.impl.LockDevice(device);
SDL_AtomicSet(&device->paused, pause_on ? 1 : 0);
current_audio.impl.UnlockDevice(device);
}
}

References current_audio, device, get_audio_device(), SDL_AudioDriver::impl, SDL_AudioDriverImpl::LockDevice, SDL_AtomicSet, and SDL_AudioDriverImpl::UnlockDevice.

Referenced by SDL_PauseAudio().

## SDL_QueueAudio()

int SDL_QueueAudio | ( | SDL_AudioDeviceID | dev,
|  | const void * | data,
|  | Uint32 | len
| ) |  |

Queue more audio on non-callback devices.

(If you are looking to retrieve queued audio from a non-callback capture device, you want SDL_DequeueAudio() instead. This will return -1 to signify an error if you use it with capture devices.)

SDL offers two ways to feed audio to the device: you can either supply a callback that SDL triggers with some frequency to obtain more audio (pull method), or you can supply no callback, and then SDL will expect you to supply data at regular intervals (push method) with this function.

There are no limits on the amount of data you can queue, short of exhaustion of address space. Queued data will drain to the device as necessary without further intervention from you. If the device needs audio but there is not enough queued, it will play silence to make up the difference. This means you will have skips in your audio playback if you aren't routinely queueing sufficient data.

This function copies the supplied data, so you are safe to free it when the function returns. This function is thread-safe, but queueing to the same device from two threads at once does not promise which buffer will be queued first.

You may not queue audio on a device that is using an application-supplied callback; doing so returns an error. You have to use the audio callback or queue audio with this function, but not both.

You should not call SDL_LockAudio() on the device before queueing; SDL handles locking internally for this function.

Parameters

  dev | The device ID to which we will queue audio.
  data | The data to queue to the device for later playback.
  len | The number of bytes (not samples!) to which (data) points.

Returns
  0 on success, or -1 on error.

See also
  SDL_GetQueuedAudioSize
  SDL_ClearQueuedAudio

Definition at line 598 of file SDL_audio.c.

{
SDL_AudioDevice *device = get_audio_device(devid);
int rc = 0;
if (!device) {
return -1; /* get_audio_device() will have set the error state */
} else if (device->iscapture) {
return SDL_SetError("This is a capture device, queueing not allowed");
} else if (device->callbackspec.callback != SDL_BufferQueueDrainCallback) {
return SDL_SetError("Audio device has a callback, queueing not allowed");
}
if (len > 0) {
current_audio.impl.LockDevice(device);
rc = SDL_WriteToDataQueue(device->buffer_queue, data, len);
current_audio.impl.UnlockDevice(device);
}
return rc;
}

References current_audio, device, get_audio_device(), SDL_AudioDriver::impl, SDL_AudioDriverImpl::LockDevice, SDL_BufferQueueDrainCallback(), SDL_SetError, SDL_WriteToDataQueue(), and SDL_AudioDriverImpl::UnlockDevice.

## SDL_RemoveAudioDevice()

void SDL_RemoveAudioDevice | ( | const int | iscapture,
|  | void * | handle
| ) |  |

Definition at line 531 of file SDL_audio.c.

{
int device_index;
SDL_AudioDevice *device = NULL;
SDL_LockMutex(current_audio.detectionLock);
if (iscapture) {
mark_device_removed(handle, current_audio.inputDevices, &current_audio.captureDevicesRemoved);
} else {
mark_device_removed(handle, current_audio.outputDevices, &current_audio.outputDevicesRemoved);
}
for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++)
{
device = open_devices[device_index];
if (device != NULL && device->handle == handle)
{
SDL_OpenedAudioDeviceDisconnected(device);
break;
}
}
SDL_UnlockMutex(current_audio.detectionLock);
current_audio.impl.FreeDeviceHandle(handle);
}

References SDL_AudioDriver::captureDevicesRemoved, current_audio, SDL_AudioDriver::detectionLock, device, SDL_AudioDriverImpl::FreeDeviceHandle, SDL_AudioDriver::impl, SDL_AudioDriver::inputDevices, mark_device_removed(), NULL, open_devices, SDL_AudioDriver::outputDevices, SDL_AudioDriver::outputDevicesRemoved, SDL_arraysize, SDL_LockMutex, SDL_OpenedAudioDeviceDisconnected(), and SDL_UnlockMutex.

## SDL_RunAudio()

static int SDL_RunAudio | ( | void * | devicep | ) |

static

Definition at line 682 of file SDL_audio.c.

{
SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
void *udata = device->callbackspec.userdata;
SDL_AudioCallback callback = device->callbackspec.callback;
int data_len = 0;
Uint8 *data;
SDL_assert(!device->iscapture);
#if SDL_AUDIO_DRIVER_ANDROID
{
/* Set thread priority to THREAD_PRIORITY_AUDIO */
extern void Android_JNI_AudioSetThreadPriority(int, int);
Android_JNI_AudioSetThreadPriority(device->iscapture, device->id);
}
#else
/* The audio mixing is always a high priority thread */
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL);
#endif
/* Perform any thread setup */
device->threadid = SDL_ThreadID();
current_audio.impl.ThreadInit(device);
/* Loop, filling the audio buffers */
while (!SDL_AtomicGet(&device->shutdown)) {
current_audio.impl.BeginLoopIteration(device);
data_len = device->callbackspec.size;
/* Fill the current buffer with sound */
if (!device->stream && SDL_AtomicGet(&device->enabled)) {
SDL_assert(data_len == device->spec.size);
data = current_audio.impl.GetDeviceBuf(device);
} else {
/* if the device isn't enabled, we still write to the
work_buffer, so the app's callback will fire with
a regular frequency, in case they depend on that
for timing or progress. They can use hotplug
now to know if the device failed.
Streaming playback uses work_buffer, too. */
data = NULL;
}
if (data == NULL) {
data = device->work_buffer;
}
/* !!! FIXME: this should be LockDevice. */
SDL_LockMutex(device->mixer_lock);
if (SDL_AtomicGet(&device->paused)) {
SDL_memset(data, device->spec.silence, data_len);
} else {
callback(udata, data, data_len);
}
SDL_UnlockMutex(device->mixer_lock);
if (device->stream) {
/* Stream available audio to device, converting/resampling. */
/* if this fails...oh well. We'll play silence here. */
SDL_AudioStreamPut(device->stream, data, data_len);
while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->spec.size)) {
int got;
data = SDL_AtomicGet(&device->enabled) ? current_audio.impl.GetDeviceBuf(device) : NULL;
got = SDL_AudioStreamGet(device->stream, data ? data : device->work_buffer, device->spec.size);
SDL_assert((got < 0) || (got == device->spec.size));
if (data == NULL) { /* device is having issues... */
const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
SDL_Delay(delay); /* wait for as long as this buffer would have played. Maybe device recovers later? */
} else {
if (got != device->spec.size) {
SDL_memset(data, device->spec.silence, device->spec.size);
}
current_audio.impl.PlayDevice(device);
current_audio.impl.WaitDevice(device);
}
}
} else if (data == device->work_buffer) {
/* nothing to do; pause like we queued a buffer to play. */
const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
SDL_Delay(delay);
} else { /* writing directly to the device. */
/* queue this buffer and wait for it to finish playing. */
current_audio.impl.PlayDevice(device);
current_audio.impl.WaitDevice(device);
}
}
current_audio.impl.PrepareToClose(device);
/* Wait for the audio to drain. */
SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2);
current_audio.impl.ThreadDeinit(device);
return 0;
}

References Android_JNI_AudioSetThreadPriority(), SDL_AudioDriverImpl::BeginLoopIteration, callback(), current_audio, device, SDL_AudioDriverImpl::GetDeviceBuf, SDL_AudioDriver::impl, NULL, SDL_AudioDriverImpl::PlayDevice, SDL_AudioDriverImpl::PrepareToClose, SDL_assert, SDL_AtomicGet, SDL_AudioStreamAvailable, SDL_AudioStreamGet, SDL_AudioStreamPut, SDL_Delay, SDL_LockMutex, SDL_memset, SDL_SetThreadPriority, SDL_THREAD_PRIORITY_TIME_CRITICAL, SDL_ThreadID, SDL_UnlockMutex, SDL_AudioDriverImpl::ThreadDeinit, SDL_AudioDriverImpl::ThreadInit, and SDL_AudioDriverImpl::WaitDevice.

Referenced by open_audio_device().

## SDL_UnlockAudio()

void SDL_UnlockAudio | ( | void |  | ) |

Definition at line 1572 of file SDL_audio.c.

{
SDL_UnlockAudioDevice(1);
}

References SDL_UnlockAudioDevice().

## SDL_UnlockAudioDevice()

void SDL_UnlockAudioDevice | ( | SDL_AudioDeviceID | devid | ) |

Definition at line 1562 of file SDL_audio.c.

{
/* Obtain a lock on the mixing buffers */
SDL_AudioDevice *device = get_audio_device(devid);
if (device) {
current_audio.impl.UnlockDevice(device);
}
}

References current_audio, device, get_audio_device(), SDL_AudioDriver::impl, and SDL_AudioDriverImpl::UnlockDevice.

Referenced by SDL_UnlockAudio().

## Variable Documentation

## bootstrap

const AudioBootStrap* const bootstrap[]

static

Definition at line 37 of file SDL_audio.c.

Referenced by SDL_AudioInit(), SDL_GetAudioDriver(), and SDL_GetNumAudioDrivers().

## current_audio

SDL_AudioDriver current_audio

static

Definition at line 33 of file SDL_audio.c.

Referenced by add_audio_device(), add_capture_device(), add_output_device(), close_audio_device(), finish_audio_entry_points_init(), free_device_list(), open_audio_device(), SDL_AudioDetectDevices_Default(), SDL_AudioInit(), SDL_AudioQuit(), SDL_CaptureAudio(), SDL_ClearQueuedAudio(), SDL_DequeueAudio(), SDL_GetAudioDeviceName(), SDL_GetCurrentAudioDriver(), SDL_GetNumAudioDevices(), SDL_GetQueuedAudioSize(), SDL_LockAudioDevice(), SDL_OpenedAudioDeviceDisconnected(), SDL_PauseAudioDevice(), SDL_QueueAudio(), SDL_RemoveAudioDevice(), SDL_RunAudio(), and SDL_UnlockAudioDevice().

## format_idx

int format_idx

static

Definition at line 1621 of file SDL_audio.c.

Referenced by SDL_FirstAudioFormat(), and SDL_NextAudioFormat().

## format_idx_sub

int format_idx_sub

static

Definition at line 1622 of file SDL_audio.c.

Referenced by SDL_FirstAudioFormat(), and SDL_NextAudioFormat().

## format_list

SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS]

static

Initial value:
= {
{AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
{AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB},
{AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB,
AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
{AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB,
AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
{AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB,
AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8},
{AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB,
AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8},
{AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB,
AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8},
{AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB,
AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8},
{AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB,
AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8},
{AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB,
AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8},
}

Definition at line 1623 of file SDL_audio.c.

Referenced by SDL_FirstAudioFormat(), and SDL_NextAudioFormat().

## open_devices

SDL_AudioDevice* open_devices[16]

static

Definition at line 34 of file SDL_audio.c.

Referenced by close_audio_device(), get_audio_device(), open_audio_device(), SDL_AudioInit(), SDL_AudioQuit(), SDL_OpenAudio(), and SDL_RemoveAudioDevice().

finish_audio_entry_points_init
static void finish_audio_entry_points_init(void)
Definition: SDL_audio.c:331
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
format_idx
static int format_idx
Definition: SDL_audio.c:1621
format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
SDL_NewDataQueue
SDL_DataQueue * SDL_NewDataQueue(const size_t _packetlen, const size_t initialslack)
Definition: SDL_dataqueue.c:58
SDL_SetThreadPriority
#define SDL_SetThreadPriority
Definition: SDL_dynapi_overrides.h:477
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
SDL_AudioSpec::channels
Uint8 channels
Definition: SDL_audio.h:182
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_AudioDriverImpl::HasCaptureSupport
int HasCaptureSupport
Definition: SDL_sysaudio.h:90
SDL_CountDataQueue
size_t SDL_CountDataQueue(SDL_DataQueue *queue)
Definition: SDL_dataqueue.c:294
SDL_AudioDriverImpl::UnlockDevice
void(* UnlockDevice)(_THIS)
Definition: SDL_sysaudio.h:80
format_idx_sub
static int format_idx_sub
Definition: SDL_audio.c:1622
SDL_AudioDriverImpl::ProvidesOwnCallbackThread
int ProvidesOwnCallbackThread
Definition: SDL_sysaudio.h:88
DEFAULT_OUTPUT_DEVNAME
#define DEFAULT_OUTPUT_DEVNAME
Definition: SDL_sysaudio.h:32
AUDIO_U16LSB
#define AUDIO_U16LSB
Definition: SDL_audio.h:91
SDL_AUDIO_ALLOW_FREQUENCY_CHANGE
#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE
Definition: SDL_audio.h:140
clean_out_device_list
static void clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
Definition: SDL_audio.c:1012
SDL_CaptureAudio
static int SDL_CaptureAudio(void *devicep)
Definition: SDL_audio.c:785
SDL_LockMutex
#define SDL_LockMutex
Definition: SDL_dynapi_overrides.h:260
SDL_AudioDriverImpl::FlushCapture
void(* FlushCapture)(_THIS)
Definition: SDL_sysaudio.h:76
NULL
#define NULL
Definition: begin_code.h:167
SDL_AudioStreamAvailable
#define SDL_AudioStreamAvailable
Definition: SDL_dynapi_overrides.h:647
handle
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
add_output_device
static SDL_INLINE int add_output_device(const char *name, void *handle)
Definition: SDL_audio.c:441
AUDIO_S32MSB
#define AUDIO_S32MSB
Definition: SDL_audio.h:104
SDL_AudioSpec::samples
Uint16 samples
Definition: SDL_audio.h:184
SDL_GetNumAudioDrivers
int SDL_GetNumAudioDrivers(void)
Definition: SDL_audio.c:925
SDL_THREAD_PRIORITY_TIME_CRITICAL
@ SDL_THREAD_PRIORITY_TIME_CRITICAL
Definition: SDL_thread.h:63
samples
GLsizei samples
Definition: SDL_opengl_glext.h:1185
SDL_AudioDriver::captureDevicesRemoved
SDL_bool captureDevicesRemoved
Definition: SDL_sysaudio.h:121
SDL_FreeDataQueue
void SDL_FreeDataQueue(SDL_DataQueue *queue)
Definition: SDL_dataqueue.c:88
SDL_AudioSpec::format
SDL_AudioFormat format
Definition: SDL_audio.h:181
SDL_AudioDriverImpl::SkipMixerLock
int SkipMixerLock
Definition: SDL_sysaudio.h:89
SDL_AudioDeviceItem::dupenum
int dupenum
Definition: SDL_sysaudio.h:102
DEFAULT_INPUT_DEVNAME
#define DEFAULT_INPUT_DEVNAME
Definition: SDL_sysaudio.h:33
mark_device_removed
static void mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
Definition: SDL_audio.c:516
SDL_MixAudioFormat
#define SDL_MixAudioFormat
Definition: SDL_dynapi_overrides.h:91
devices
EGLDeviceEXT * devices
Definition: eglext.h:621
SDL_THREAD_PRIORITY_HIGH
@ SDL_THREAD_PRIORITY_HIGH
Definition: SDL_thread.h:62
SDL_AudioSpec::callback
SDL_AudioCallback callback
Definition: SDL_audio.h:187
SDL_AudioDeviceItem::next
struct SDL_AudioDeviceItem * next
Definition: SDL_sysaudio.h:103
stream
GLuint GLuint stream
Definition: SDL_opengl_glext.h:1776
SDL_AudioDriverImpl::OpenDevice
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
Definition: SDL_sysaudio.h:68
SDL_AudioStreamGet
#define SDL_AudioStreamGet
Definition: SDL_dynapi_overrides.h:645
SDL_CreateMutex
#define SDL_CreateMutex
Definition: SDL_dynapi_overrides.h:259
current_audio
static SDL_AudioDriver current_audio
Definition: SDL_audio.c:33
format_list
static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS]
Definition: SDL_audio.c:1623
SDL_AudioSpec
Definition: SDL_audio.h:178
SDL_AudioDriverImpl::PrepareToClose
void(* PrepareToClose)(_THIS)
Definition: SDL_sysaudio.h:77
callback
static Uint32 callback(Uint32 interval, void *param)
Definition: testtimer.c:34
SDL_WriteToDataQueue
int SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len)
Definition: SDL_dataqueue.c:175
SDL_ENABLE
#define SDL_ENABLE
Definition: SDL_events.h:759
SDL_AudioStatus
SDL_AudioStatus
Definition: SDL_audio.h:395
index
GLuint index
Definition: SDL_opengl_glext.h:660
x1
GLuint GLfloat GLfloat GLfloat x1
Definition: SDL_opengl_glext.h:8583
SDL_AudioDevice::iscapture
SDL_bool iscapture
Definition: SDL_sysaudio.h:150
SDL_AudioDriver::name
const char * name
Definition: SDL_sysaudio.h:111
SDL_NextAudioFormat
SDL_AudioFormat SDL_NextAudioFormat(void)
Definition: SDL_audio.c:1659
SDL_OpenedAudioDeviceDisconnected
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
Definition: SDL_audio.c:486
SDL_AUDIO_ALLOW_CHANNELS_CHANGE
#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE
Definition: SDL_audio.h:142
SDL_AUDIODEVICEADDED
@ SDL_AUDIODEVICEADDED
Definition: SDL_events.h:147
SDL_InitSubSystem
#define SDL_InitSubSystem
Definition: SDL_dynapi_overrides.h:55
SDL_RunAudio
static int SDL_RunAudio(void *devicep)
Definition: SDL_audio.c:682
SDL_AudioDriver::desc
const char * desc
Definition: SDL_sysaudio.h:115
FILL_STUB
#define FILL_STUB(x)
SDL_AudioDriver::outputDeviceCount
int outputDeviceCount
Definition: SDL_sysaudio.h:123
SDL_AudioDriverImpl::FreeDeviceHandle
void(* FreeDeviceHandle)(void *handle)
Definition: SDL_sysaudio.h:81
AudioBootStrap
Definition: SDL_sysaudio.h:176
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_AUDIOBUFFERQUEUE_PACKETLEN
#define SDL_AUDIOBUFFERQUEUE_PACKETLEN
Definition: SDL_sysaudio.h:63
SDL_AudioDriver::impl
SDL_AudioDriverImpl impl
Definition: SDL_sysaudio.h:117
SDL_AUDIO_PAUSED
@ SDL_AUDIO_PAUSED
Definition: SDL_audio.h:399
SDL_strncasecmp
#define SDL_strncasecmp
Definition: SDL_dynapi_overrides.h:420
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
AUDIO_U8
#define AUDIO_U8
Definition: SDL_audio.h:89
SDL_AudioDriverImpl::WaitDevice
void(* WaitDevice)(_THIS)
Definition: SDL_sysaudio.h:72
len
GLenum GLsizei len
Definition: SDL_opengl_glext.h:2926
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_AudioDeviceItem::name
char * name
Definition: SDL_sysaudio.h:100
S32
#define S32
AUDIO_F32MSB
#define AUDIO_F32MSB
Definition: SDL_audio.h:113
SDL_AudioDeviceID
Uint32 SDL_AudioDeviceID
Definition: SDL_audio.h:330
AudioBootStrap::init
int(* init)(SDL_AudioDriverImpl *impl)
Definition: SDL_sysaudio.h:180
retval
SDL_bool retval
Definition: testgamecontroller.c:65
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
SDL_GetEventState
#define SDL_GetEventState(type)
Definition: SDL_events.h:772
SDL_CreateThreadInternal
SDL_Thread * SDL_CreateThreadInternal(int(*fn)(void *), const char *name, const size_t stacksize, void *data)
Definition: SDL_thread.c:429
SDL_AUDIO_STOPPED
@ SDL_AUDIO_STOPPED
Definition: SDL_audio.h:397
SDL_AUDIO_ALLOW_SAMPLES_CHANGE
#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE
Definition: SDL_audio.h:143
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_AudioDeviceItem::original_name
char * original_name
Definition: SDL_sysaudio.h:101
SDL_AudioQuit
void SDL_AudioQuit(void)
Definition: SDL_audio.c:1590
SDL_PushEvent
#define SDL_PushEvent
Definition: SDL_dynapi_overrides.h:125
SDL_AUDIO_ALLOW_ANY_CHANGE
#define SDL_AUDIO_ALLOW_ANY_CHANGE
Definition: SDL_audio.h:144
SDL_AudioDriverImpl::OnlyHasDefaultOutputDevice
int OnlyHasDefaultOutputDevice
Definition: SDL_sysaudio.h:91
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:660
prepare_audiospec
static int prepare_audiospec(const SDL_AudioSpec *orig, SDL_AudioSpec *prepared)
Definition: SDL_audio.c:1158
SDL_GetAudioDeviceStatus
SDL_AudioStatus SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
Definition: SDL_audio.c:1506
SDL_AudioDriverImpl::LockDevice
void(* LockDevice)(_THIS)
Definition: SDL_sysaudio.h:79
SDL_AudioDriverImpl::ThreadDeinit
void(* ThreadDeinit)(_THIS)
Definition: SDL_sysaudio.h:70
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
NUM_FORMATS
#define NUM_FORMATS
Definition: SDL_audio.c:1620
SDL_CalculateAudioSpec
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
Definition: SDL_audio.c:1668
SDL_AudioLockOrUnlockDeviceWithNoMixerLock
static void SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice *device)
Definition: SDL_audio.c:326
SDL_AudioDriverImpl::DetectDevices
void(* DetectDevices)(void)
Definition: SDL_sysaudio.h:67
SDL_AudioStreamPut
#define SDL_AudioStreamPut
Definition: SDL_dynapi_overrides.h:644
SDL_AUDIO_BITSIZE
#define SDL_AUDIO_BITSIZE(x)
Definition: SDL_audio.h:75
AUDIO_F32LSB
#define AUDIO_F32LSB
Definition: SDL_audio.h:112
Android_JNI_AudioSetThreadPriority
void Android_JNI_AudioSetThreadPriority(int iscapture, int device_id)
SDL_AudioDriverImpl::PlayDevice
void(* PlayDevice)(_THIS)
Definition: SDL_sysaudio.h:73
SDL_AudioDeviceItem
Definition: SDL_sysaudio.h:97
add_audio_device
static int add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
Definition: SDL_audio.c:374
SDL_Delay
#define SDL_Delay
Definition: SDL_dynapi_overrides.h:486
SDL_AudioSpec::freq
int freq
Definition: SDL_audio.h:180
SDL_AudioDriverImpl::BeginLoopIteration
void(* BeginLoopIteration)(_THIS)
Definition: SDL_sysaudio.h:71
SDL_AudioDriverImpl::OnlyHasDefaultCaptureDevice
int OnlyHasDefaultCaptureDevice
Definition: SDL_sysaudio.h:92
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_AudioSpec::silence
Uint8 silence
Definition: SDL_audio.h:183
SDL_UnlockAudioDevice
void SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
Definition: SDL_audio.c:1562
bootstrap
static const AudioBootStrap *const bootstrap[]
Definition: SDL_audio.c:37
AUDIO_S32LSB
#define AUDIO_S32LSB
Definition: SDL_audio.h:103
SDL_AudioDriverImpl::AllowsArbitraryDeviceNames
int AllowsArbitraryDeviceNames
Definition: SDL_sysaudio.h:93
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_ReadFromDataQueue
size_t SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len)
Definition: SDL_dataqueue.c:254
SDL_AudioDeviceItem::handle
void * handle
Definition: SDL_sysaudio.h:99
SDL_AudioDriverImpl::ThreadInit
void(* ThreadInit)(_THIS)
Definition: SDL_sysaudio.h:69
SDL_AudioDriver::inputDeviceCount
int inputDeviceCount
Definition: SDL_sysaudio.h:124
spec
SDL_AudioSpec spec
Definition: loopwave.c:31
SDL_BufferQueueFillCallback
static void SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len)
Definition: SDL_audio.c:582
id
GLuint id
Definition: SDL_opengl_glext.h:528
open_audio_device
static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture, const SDL_AudioSpec *desired, SDL_AudioSpec *obtained, int allowed_changes, int min_id)
Definition: SDL_audio.c:1216
SDL_AudioDriverImpl::CaptureFromDevice
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
Definition: SDL_sysaudio.h:75
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_atoi
#define SDL_atoi
Definition: SDL_dynapi_overrides.h:410
add_capture_device
static SDL_INLINE int add_capture_device(const char *name, void *handle)
Definition: SDL_audio.c:434
SDL_AudioSpec::size
Uint32 size
Definition: SDL_audio.h:186
SDL_BufferQueueDrainCallback
static void SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len)
Definition: SDL_audio.c:561
src
GLenum src
Definition: SDL_opengl_glext.h:1737
SDL_getenv
#define SDL_getenv
Definition: SDL_dynapi_overrides.h:378
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
AudioBootStrap::desc
const char * desc
Definition: SDL_sysaudio.h:179
SDL_AudioStreamClear
#define SDL_AudioStreamClear
Definition: SDL_dynapi_overrides.h:646
AUDIO_S16
#define AUDIO_S16
Definition: SDL_audio.h:96
x2
GLfixed GLfixed x2
Definition: SDL_opengl_glext.h:4583
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
free_device_list
static void free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
Definition: SDL_audio.c:447
SDL_AUDIO_PLAYING
@ SDL_AUDIO_PLAYING
Definition: SDL_audio.h:398
SDL_snprintf
#define SDL_snprintf
Definition: SDL_dynapi_overrides.h:40
SDL_NewAudioStream
#define SDL_NewAudioStream
Definition: SDL_dynapi_overrides.h:643
SDL_ClearDataQueue
void SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack)
Definition: SDL_dataqueue.c:98
SDL_AudioDriverImpl::GetDeviceBuf
Uint8 *(* GetDeviceBuf)(_THIS)
Definition: SDL_sysaudio.h:74
SDL_DestroyMutex
#define SDL_DestroyMutex
Definition: SDL_dynapi_overrides.h:263
AUDIO_S16MSB
#define AUDIO_S16MSB
Definition: SDL_audio.h:94
SDL_AudioDriver::inputDevices
SDL_AudioDeviceItem * inputDevices
Definition: SDL_sysaudio.h:126
AudioBootStrap::name
const char * name
Definition: SDL_sysaudio.h:178
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:397
SDL_strlen
#define SDL_strlen
Definition: SDL_dynapi_overrides.h:393
SDL_CloseAudioDevice
void SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
Definition: SDL_audio.c:1578
AUDIO_S16LSB
#define AUDIO_S16LSB
Definition: SDL_audio.h:92
SDL_Event
General event structure.
Definition: SDL_events.h:557
AUDIO_S8
#define AUDIO_S8
Definition: SDL_audio.h:90
SDL_AudioDriver::outputDevicesRemoved
SDL_bool outputDevicesRemoved
Definition: SDL_sysaudio.h:122
SDL_Unsupported
#define SDL_Unsupported()
Definition: SDL_error.h:53
SDL_AUDIO_ALLOW_FORMAT_CHANGE
#define SDL_AUDIO_ALLOW_FORMAT_CHANGE
Definition: SDL_audio.h:141
SDL_AtomicSet
#define SDL_AtomicSet
Definition: SDL_dynapi_overrides.h:67
SDL_FreeAudioStream
#define SDL_FreeAudioStream
Definition: SDL_dynapi_overrides.h:648
SDL_ParseAudioFormat
static SDL_AudioFormat SDL_ParseAudioFormat(const char *string)
Definition: SDL_audio.c:899
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_AtomicGet
#define SDL_AtomicGet
Definition: SDL_dynapi_overrides.h:68
SDL_AUDIODEVICEREMOVED
@ SDL_AUDIODEVICEREMOVED
Definition: SDL_events.h:148
SDL_strcmp
#define SDL_strcmp
Definition: SDL_dynapi_overrides.h:417
SDL_AudioCallback
void(* SDL_AudioCallback)(void *userdata, Uint8 *stream, int len)
Definition: SDL_audio.h:163
SDL_UnlockMutex
#define SDL_UnlockMutex
Definition: SDL_dynapi_overrides.h:262
SDL_WasInit
#define SDL_WasInit
Definition: SDL_dynapi_overrides.h:57
device
static SDL_AudioDeviceID device
Definition: loopwave.c:37
SDL_AudioDriver::outputDevices
SDL_AudioDeviceItem * outputDevices
Definition: SDL_sysaudio.h:125
SDL_AudioDriverImpl::CloseDevice
void(* CloseDevice)(_THIS)
Definition: SDL_sysaudio.h:78
AUDIO_U16MSB
#define AUDIO_U16MSB
Definition: SDL_audio.h:93
i
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)
Definition: SDL_x11sym.h:50
SDL_ThreadID
#define SDL_ThreadID
Definition: SDL_dynapi_overrides.h:475
SDL_AddAudioDevice
void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
Definition: SDL_audio.c:469
close_audio_device
static void close_audio_device(SDL_AudioDevice *device)
Definition: SDL_audio.c:1110
SDL_WaitThread
#define SDL_WaitThread
Definition: SDL_dynapi_overrides.h:478
open_devices
static SDL_AudioDevice * open_devices[16]
Definition: SDL_audio.c:34
CHECK_FMT_STRING
#define CHECK_FMT_STRING(x)
SDL_LockAudioDevice
void SDL_LockAudioDevice(SDL_AudioDeviceID devid)
Definition: SDL_audio.c:1546
SDL_AudioDevice
Definition: SDL_sysaudio.h:131
SDL_AudioDriver::detectionLock
SDL_mutex * detectionLock
Definition: SDL_sysaudio.h:120
SDL_AudioDriverImpl::Deinitialize
void(* Deinitialize)(void)
Definition: SDL_sysaudio.h:82
SDL_PauseAudioDevice
void SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
Definition: SDL_audio.c:1528
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
get_audio_device
static SDL_AudioDevice * get_audio_device(SDL_AudioDeviceID id)
Definition: SDL_audio.c:200
SDL_INIT_AUDIO
#define SDL_INIT_AUDIO
Definition: SDL.h:78
SDL_FreeResampleFilter
void SDL_FreeResampleFilter(void)
Definition: SDL_audiocvt.c:464
is_in_audio_device_thread
static SDL_INLINE SDL_bool is_in_audio_device_thread(SDL_AudioDevice *device)
Definition: SDL_audio.c:296
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
AudioBootStrap::demand_only
int demand_only
Definition: SDL_sysaudio.h:181