Update for SDL3 coding style (#6717)
I updated .clang-format and ran clang-format 14 over the src and test directories to standardize the code base. In general I let clang-format have it's way, and added markup to prevent formatting of code that would break or be completely unreadable if formatted. The script I ran for the src directory is added as build-scripts/clang-format-src.sh This fixes: #6592 #6593 #6594
This commit is contained in:
@@ -100,22 +100,20 @@ static const AudioBootStrap *const bootstrap[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
#ifdef HAVE_LIBSAMPLERATE_H
|
||||
#ifdef SDL_LIBSAMPLERATE_DYNAMIC
|
||||
static void *SRC_lib = NULL;
|
||||
#endif
|
||||
SDL_bool SRC_available = SDL_FALSE;
|
||||
int SRC_converter = 0;
|
||||
SRC_STATE* (*SRC_src_new)(int converter_type, int channels, int *error) = NULL;
|
||||
SRC_STATE *(*SRC_src_new)(int converter_type, int channels, int *error) = NULL;
|
||||
int (*SRC_src_process)(SRC_STATE *state, SRC_DATA *data) = NULL;
|
||||
int (*SRC_src_reset)(SRC_STATE *state) = NULL;
|
||||
SRC_STATE* (*SRC_src_delete)(SRC_STATE *state) = NULL;
|
||||
const char* (*SRC_src_strerror)(int error) = NULL;
|
||||
SRC_STATE *(*SRC_src_delete)(SRC_STATE *state) = NULL;
|
||||
const char *(*SRC_src_strerror)(int error) = NULL;
|
||||
int (*SRC_src_simple)(SRC_DATA *data, int converter_type, int channels) = NULL;
|
||||
|
||||
static SDL_bool
|
||||
LoadLibSampleRate(void)
|
||||
static SDL_bool LoadLibSampleRate(void)
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_AUDIO_RESAMPLING_MODE);
|
||||
|
||||
@@ -123,7 +121,7 @@ LoadLibSampleRate(void)
|
||||
SRC_converter = 0;
|
||||
|
||||
if (!hint || *hint == '0' || SDL_strcasecmp(hint, "default") == 0) {
|
||||
return SDL_FALSE; /* don't load anything. */
|
||||
return SDL_FALSE; /* don't load anything. */
|
||||
} else if (*hint == '1' || SDL_strcasecmp(hint, "fast") == 0) {
|
||||
SRC_converter = SRC_SINC_FASTEST;
|
||||
} else if (*hint == '2' || SDL_strcasecmp(hint, "medium") == 0) {
|
||||
@@ -131,7 +129,7 @@ LoadLibSampleRate(void)
|
||||
} else if (*hint == '3' || SDL_strcasecmp(hint, "best") == 0) {
|
||||
SRC_converter = SRC_SINC_BEST_QUALITY;
|
||||
} else {
|
||||
return SDL_FALSE; /* treat it like "default", don't load anything. */
|
||||
return SDL_FALSE; /* treat it like "default", don't load anything. */
|
||||
}
|
||||
|
||||
#ifdef SDL_LIBSAMPLERATE_DYNAMIC
|
||||
@@ -142,12 +140,14 @@ LoadLibSampleRate(void)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
SRC_src_new = (SRC_STATE* (*)(int converter_type, int channels, int *error))SDL_LoadFunction(SRC_lib, "src_new");
|
||||
SRC_src_process = (int (*)(SRC_STATE *state, SRC_DATA *data))SDL_LoadFunction(SRC_lib, "src_process");
|
||||
SRC_src_reset = (int(*)(SRC_STATE *state))SDL_LoadFunction(SRC_lib, "src_reset");
|
||||
SRC_src_delete = (SRC_STATE* (*)(SRC_STATE *state))SDL_LoadFunction(SRC_lib, "src_delete");
|
||||
SRC_src_strerror = (const char* (*)(int error))SDL_LoadFunction(SRC_lib, "src_strerror");
|
||||
SRC_src_simple = (int(*)(SRC_DATA *data, int converter_type, int channels))SDL_LoadFunction(SRC_lib, "src_simple");
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
if (!SRC_src_new || !SRC_src_process || !SRC_src_reset || !SRC_src_delete || !SRC_src_strerror || !SRC_src_simple) {
|
||||
SDL_UnloadObject(SRC_lib);
|
||||
@@ -167,8 +167,7 @@ LoadLibSampleRate(void)
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
UnloadLibSampleRate(void)
|
||||
static void UnloadLibSampleRate(void)
|
||||
{
|
||||
#ifdef SDL_LIBSAMPLERATE_DYNAMIC
|
||||
if (SRC_lib != NULL) {
|
||||
@@ -186,8 +185,7 @@ UnloadLibSampleRate(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static SDL_AudioDevice *
|
||||
get_audio_device(SDL_AudioDeviceID id)
|
||||
static SDL_AudioDevice *get_audio_device(SDL_AudioDeviceID id)
|
||||
{
|
||||
id--;
|
||||
if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) {
|
||||
@@ -198,82 +196,67 @@ get_audio_device(SDL_AudioDeviceID id)
|
||||
return open_devices[id];
|
||||
}
|
||||
|
||||
|
||||
/* stubs for audio drivers that don't need a specific entry point... */
|
||||
static void
|
||||
SDL_AudioDetectDevices_Default(void)
|
||||
static void SDL_AudioDetectDevices_Default(void)
|
||||
{
|
||||
/* 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, NULL, (void *) ((size_t) 0x1));
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)((size_t)0x1));
|
||||
if (current_audio.impl.HasCaptureSupport) {
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *) ((size_t) 0x2));
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)((size_t)0x2));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioThreadInit_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
static void SDL_AudioThreadInit_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioThreadDeinit_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
static void SDL_AudioThreadDeinit_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioWaitDevice_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
static void SDL_AudioWaitDevice_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioPlayDevice_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
static void SDL_AudioPlayDevice_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
SDL_AudioGetDeviceBuf_Default(_THIS)
|
||||
static Uint8 *SDL_AudioGetDeviceBuf_Default(_THIS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen)
|
||||
static int SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
return -1; /* just fail immediately. */
|
||||
return -1; /* just fail immediately. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioFlushCapture_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
static void SDL_AudioFlushCapture_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioCloseDevice_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
static void SDL_AudioCloseDevice_Default(_THIS)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioDeinitialize_Default(void)
|
||||
{ /* no-op. */
|
||||
static void SDL_AudioDeinitialize_Default(void)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioFreeDeviceHandle_Default(void *handle)
|
||||
{ /* no-op. */
|
||||
static void SDL_AudioFreeDeviceHandle_Default(void *handle)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
SDL_AudioOpenDevice_Default(_THIS, const char *devname)
|
||||
static int SDL_AudioOpenDevice_Default(_THIS, const char *devname)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_INLINE SDL_bool
|
||||
is_in_audio_device_thread(SDL_AudioDevice * device)
|
||||
static SDL_INLINE SDL_bool is_in_audio_device_thread(SDL_AudioDevice *device)
|
||||
{
|
||||
/* The device thread locks the same mutex, but not through the public API.
|
||||
This check is in case the application, in the audio callback,
|
||||
@@ -286,35 +269,31 @@ is_in_audio_device_thread(SDL_AudioDevice * device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioLockDevice_Default(SDL_AudioDevice * device)
|
||||
static void SDL_AudioLockDevice_Default(SDL_AudioDevice *device)
|
||||
{
|
||||
if (!is_in_audio_device_thread(device)) {
|
||||
SDL_LockMutex(device->mixer_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device)
|
||||
static void SDL_AudioUnlockDevice_Default(SDL_AudioDevice *device)
|
||||
{
|
||||
if (!is_in_audio_device_thread(device)) {
|
||||
SDL_UnlockMutex(device->mixer_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
finish_audio_entry_points_init(void)
|
||||
static void finish_audio_entry_points_init(void)
|
||||
{
|
||||
/*
|
||||
* Fill in stub functions for unused driver entry points. This lets us
|
||||
* blindly call them without having to check for validity first.
|
||||
*/
|
||||
|
||||
|
||||
#define FILL_STUB(x) \
|
||||
if (current_audio.impl.x == NULL) { \
|
||||
current_audio.impl.x = SDL_Audio##x##_Default; \
|
||||
}
|
||||
#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);
|
||||
@@ -332,21 +311,19 @@ finish_audio_entry_points_init(void)
|
||||
#undef FILL_STUB
|
||||
}
|
||||
|
||||
|
||||
/* device hotplug support... */
|
||||
|
||||
static int
|
||||
add_audio_device(const char *name, SDL_AudioSpec *spec, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
|
||||
static int add_audio_device(const char *name, SDL_AudioSpec *spec, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
|
||||
{
|
||||
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(handle != NULL); /* we reserve NULL, audio backends can't use it. */
|
||||
SDL_assert(name != NULL);
|
||||
|
||||
item = (SDL_AudioDeviceItem *) SDL_malloc(sizeof (SDL_AudioDeviceItem));
|
||||
item = (SDL_AudioDeviceItem *)SDL_malloc(sizeof(SDL_AudioDeviceItem));
|
||||
if (!item) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -371,13 +348,13 @@ add_audio_device(const char *name, SDL_AudioSpec *spec, void *handle, SDL_AudioD
|
||||
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. */
|
||||
break; /* stop at the highest-numbered dupe. */
|
||||
}
|
||||
}
|
||||
|
||||
if (dupenum) {
|
||||
const size_t len = SDL_strlen(name) + 16;
|
||||
char *replacement = (char *) SDL_malloc(len);
|
||||
char *replacement = (char *)SDL_malloc(len);
|
||||
if (!replacement) {
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
SDL_free(item->original_name);
|
||||
@@ -392,28 +369,25 @@ add_audio_device(const char *name, SDL_AudioSpec *spec, void *handle, SDL_AudioD
|
||||
|
||||
item->next = *devices;
|
||||
*devices = item;
|
||||
retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */
|
||||
retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */
|
||||
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static SDL_INLINE int
|
||||
add_capture_device(const char *name, SDL_AudioSpec *spec, void *handle)
|
||||
static SDL_INLINE int add_capture_device(const char *name, SDL_AudioSpec *spec, void *handle)
|
||||
{
|
||||
SDL_assert(current_audio.impl.HasCaptureSupport);
|
||||
return add_audio_device(name, spec, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount);
|
||||
}
|
||||
|
||||
static SDL_INLINE int
|
||||
add_output_device(const char *name, SDL_AudioSpec *spec, void *handle)
|
||||
static SDL_INLINE int add_output_device(const char *name, SDL_AudioSpec *spec, void *handle)
|
||||
{
|
||||
return add_audio_device(name, spec, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount);
|
||||
}
|
||||
|
||||
static void
|
||||
free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
|
||||
static void free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
|
||||
{
|
||||
SDL_AudioDeviceItem *item, *next;
|
||||
for (item = *devices; item != NULL; item = next) {
|
||||
@@ -432,10 +406,8 @@ free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
|
||||
*devCount = 0;
|
||||
}
|
||||
|
||||
|
||||
/* The audio backends call this when a new device is plugged in. */
|
||||
void
|
||||
SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle)
|
||||
void SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle)
|
||||
{
|
||||
const int device_index = iscapture ? add_capture_device(name, spec, handle) : add_output_device(name, spec, handle);
|
||||
if (device_index != -1) {
|
||||
@@ -457,11 +429,11 @@ void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
|
||||
SDL_assert(get_audio_device(device->id) == device);
|
||||
|
||||
if (!SDL_AtomicGet(&device->enabled)) {
|
||||
return; /* don't report disconnects more than once. */
|
||||
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. */
|
||||
return; /* don't report disconnect if we're trying to close device. */
|
||||
}
|
||||
|
||||
/* Ends the audio callback and mark the device as STOPPED, but the
|
||||
@@ -481,8 +453,7 @@ void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
|
||||
static void mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
|
||||
{
|
||||
SDL_AudioDeviceItem *item;
|
||||
SDL_assert(handle != NULL);
|
||||
@@ -496,8 +467,7 @@ mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *remove
|
||||
}
|
||||
|
||||
/* The audio backends call this when a device is removed from the system. */
|
||||
void
|
||||
SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle)
|
||||
void SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle)
|
||||
{
|
||||
int device_index;
|
||||
SDL_AudioDevice *device = NULL;
|
||||
@@ -540,40 +510,36 @@ SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle)
|
||||
current_audio.impl.FreeDeviceHandle(handle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* buffer queueing support... */
|
||||
|
||||
static void SDLCALL
|
||||
SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len)
|
||||
static void SDLCALL SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len)
|
||||
{
|
||||
/* this function always holds the mixer lock before being called. */
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||
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?! */
|
||||
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;
|
||||
len -= (int)dequeued;
|
||||
|
||||
if (len > 0) { /* fill any remaining space in the stream with silence. */
|
||||
if (len > 0) { /* fill any remaining space in the stream with silence. */
|
||||
SDL_assert(SDL_CountDataQueue(device->buffer_queue) == 0);
|
||||
SDL_memset(stream, device->callbackspec.silence, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void SDLCALL
|
||||
SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len)
|
||||
static void SDLCALL SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len)
|
||||
{
|
||||
/* this function always holds the mixer lock before being called. */
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||
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?! */
|
||||
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
|
||||
@@ -581,14 +547,13 @@ SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len)
|
||||
SDL_WriteToDataQueue(device->buffer_queue, stream, len);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len)
|
||||
int SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len)
|
||||
{
|
||||
SDL_AudioDevice *device = get_audio_device(devid);
|
||||
int rc = 0;
|
||||
|
||||
if (!device) {
|
||||
return -1; /* get_audio_device() will have set the error state */
|
||||
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) {
|
||||
@@ -610,15 +575,15 @@ SDL_DequeueAudio(SDL_AudioDeviceID devid, void *data, Uint32 len)
|
||||
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. */
|
||||
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);
|
||||
rc = (Uint32)SDL_ReadFromDataQueue(device->buffer_queue, data, len);
|
||||
current_audio.impl.UnlockDevice(device);
|
||||
return rc;
|
||||
}
|
||||
@@ -635,23 +600,21 @@ SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid)
|
||||
|
||||
/* Nothing to do unless we're set up for queueing. */
|
||||
if (device->callbackspec.callback == SDL_BufferQueueDrainCallback ||
|
||||
device->callbackspec.callback == SDL_BufferQueueFillCallback)
|
||||
{
|
||||
device->callbackspec.callback == SDL_BufferQueueFillCallback) {
|
||||
current_audio.impl.LockDevice(device);
|
||||
retval = (Uint32) SDL_CountDataQueue(device->buffer_queue);
|
||||
retval = (Uint32)SDL_CountDataQueue(device->buffer_queue);
|
||||
current_audio.impl.UnlockDevice(device);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
|
||||
void SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
|
||||
{
|
||||
SDL_AudioDevice *device = get_audio_device(devid);
|
||||
|
||||
if (!device) {
|
||||
return; /* nothing to do. */
|
||||
return; /* nothing to do. */
|
||||
}
|
||||
|
||||
/* Blank out the device and release the mutex. Free it afterwards. */
|
||||
@@ -663,12 +626,10 @@ SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
|
||||
current_audio.impl.UnlockDevice(device);
|
||||
}
|
||||
|
||||
|
||||
/* The general mixing thread function */
|
||||
static int SDLCALL
|
||||
SDL_RunAudio(void *devicep)
|
||||
static int SDLCALL SDL_RunAudio(void *devicep)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *)devicep;
|
||||
void *udata = device->callbackspec.userdata;
|
||||
SDL_AudioCallback callback = device->callbackspec.callback;
|
||||
int data_len = 0;
|
||||
@@ -727,15 +688,15 @@ SDL_RunAudio(void *devicep)
|
||||
/* 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)) {
|
||||
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... */
|
||||
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? */
|
||||
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);
|
||||
@@ -748,7 +709,7 @@ SDL_RunAudio(void *devicep)
|
||||
/* 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. */
|
||||
} 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);
|
||||
@@ -765,11 +726,10 @@ SDL_RunAudio(void *devicep)
|
||||
|
||||
/* !!! FIXME: this needs to deal with device spec changes. */
|
||||
/* The general capture thread function */
|
||||
static int SDLCALL
|
||||
SDL_CaptureAudio(void *devicep)
|
||||
static int SDLCALL SDL_CaptureAudio(void *devicep)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
|
||||
const int silence = (int) device->spec.silence;
|
||||
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;
|
||||
@@ -799,11 +759,11 @@ SDL_CaptureAudio(void *devicep)
|
||||
Uint8 *ptr;
|
||||
|
||||
if (SDL_AtomicGet(&device->paused)) {
|
||||
SDL_Delay(delay); /* just so we don't cook the CPU. */
|
||||
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. */
|
||||
current_audio.impl.FlushCapture(device); /* dump anything pending. */
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -821,15 +781,15 @@ SDL_CaptureAudio(void *devicep)
|
||||
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. */
|
||||
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. :) */
|
||||
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! */
|
||||
} else { /* uhoh, device failed for some reason! */
|
||||
SDL_OpenedAudioDeviceDisconnected(device);
|
||||
break;
|
||||
}
|
||||
@@ -845,7 +805,7 @@ SDL_CaptureAudio(void *devicep)
|
||||
/* if this fails...oh well. */
|
||||
SDL_AudioStreamPut(device->stream, data, data_len);
|
||||
|
||||
while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->callbackspec.size)) {
|
||||
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) {
|
||||
@@ -859,7 +819,7 @@ SDL_CaptureAudio(void *devicep)
|
||||
}
|
||||
SDL_UnlockMutex(device->mixer_lock);
|
||||
}
|
||||
} else { /* feeding user callback directly without streaming. */
|
||||
} else { /* feeding user callback directly without streaming. */
|
||||
/* !!! FIXME: this should be LockDevice. */
|
||||
SDL_LockMutex(device->mixer_lock);
|
||||
if (!SDL_AtomicGet(&device->paused)) {
|
||||
@@ -876,11 +836,11 @@ SDL_CaptureAudio(void *devicep)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static SDL_AudioFormat
|
||||
SDL_ParseAudioFormat(const char *string)
|
||||
static SDL_AudioFormat SDL_ParseAudioFormat(const char *string)
|
||||
{
|
||||
#define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x
|
||||
#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);
|
||||
@@ -903,8 +863,7 @@ SDL_ParseAudioFormat(const char *string)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_GetNumAudioDrivers(void)
|
||||
int SDL_GetNumAudioDrivers(void)
|
||||
{
|
||||
return SDL_arraysize(bootstrap) - 1;
|
||||
}
|
||||
@@ -918,14 +877,13 @@ SDL_GetAudioDriver(int index)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_AudioInit(const char *driver_name)
|
||||
int SDL_AudioInit(const char *driver_name)
|
||||
{
|
||||
int i;
|
||||
SDL_bool initialized = SDL_FALSE, tried_to_init = SDL_FALSE;
|
||||
|
||||
if (SDL_GetCurrentAudioDriver()) {
|
||||
SDL_AudioQuit(); /* shutdown driver if already running. */
|
||||
SDL_AudioQuit(); /* shutdown driver if already running. */
|
||||
}
|
||||
|
||||
SDL_zeroa(open_devices);
|
||||
@@ -998,7 +956,7 @@ SDL_AudioInit(const char *driver_name)
|
||||
}
|
||||
|
||||
SDL_zero(current_audio);
|
||||
return -1; /* No driver was available, so fail. */
|
||||
return -1; /* No driver was available, so fail. */
|
||||
}
|
||||
|
||||
current_audio.detectionLock = SDL_CreateMutex();
|
||||
@@ -1025,8 +983,7 @@ SDL_GetCurrentAudioDriver()
|
||||
}
|
||||
|
||||
/* Clean out devices that we've removed but had to keep around for stability. */
|
||||
static void
|
||||
clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
|
||||
static void clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
|
||||
{
|
||||
SDL_AudioDeviceItem *item = *devices;
|
||||
SDL_AudioDeviceItem *prev = NULL;
|
||||
@@ -1057,9 +1014,7 @@ clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *re
|
||||
*removedFlag = SDL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_GetNumAudioDevices(int iscapture)
|
||||
int SDL_GetNumAudioDevices(int iscapture)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
@@ -1082,7 +1037,6 @@ SDL_GetNumAudioDevices(int iscapture)
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
SDL_GetAudioDeviceName(int index, int iscapture)
|
||||
{
|
||||
@@ -1113,9 +1067,7 @@ SDL_GetAudioDeviceName(int index, int iscapture)
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_GetAudioDeviceSpec(int index, int iscapture, SDL_AudioSpec *spec)
|
||||
int SDL_GetAudioDeviceSpec(int index, int iscapture, SDL_AudioSpec *spec)
|
||||
{
|
||||
SDL_AudioDeviceItem *item;
|
||||
int i, retval;
|
||||
@@ -1146,9 +1098,7 @@ SDL_GetAudioDeviceSpec(int index, int iscapture, SDL_AudioSpec *spec)
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
int SDL_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
if (spec == NULL) {
|
||||
return SDL_InvalidParamError("spec");
|
||||
@@ -1164,9 +1114,7 @@ SDL_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
return current_audio.impl.GetDefaultAudioInfo(name, spec, iscapture);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
close_audio_device(SDL_AudioDevice * device)
|
||||
static void close_audio_device(SDL_AudioDevice *device)
|
||||
{
|
||||
if (!device) {
|
||||
return;
|
||||
@@ -1207,34 +1155,32 @@ close_audio_device(SDL_AudioDevice * device)
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sanity check desired AudioSpec for SDL_OpenAudio() in (orig).
|
||||
* Fills in a sanitized copy in (prepared).
|
||||
* Returns non-zero if okay, zero on fatal parameters in (orig).
|
||||
*/
|
||||
static int
|
||||
prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
|
||||
static int prepare_audiospec(const SDL_AudioSpec *orig, SDL_AudioSpec *prepared)
|
||||
{
|
||||
SDL_copyp(prepared, orig);
|
||||
|
||||
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 */
|
||||
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 */
|
||||
prepared->format = AUDIO_S16; /* a reasonable default */
|
||||
}
|
||||
}
|
||||
|
||||
if (orig->channels == 0) {
|
||||
const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
|
||||
if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) {
|
||||
if ((!env) || ((prepared->channels = (Uint8)SDL_atoi(env)) == 0)) {
|
||||
prepared->channels = 2; /* a reasonable default */
|
||||
}
|
||||
} else if (orig->channels > 8) {
|
||||
@@ -1244,7 +1190,7 @@ prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
|
||||
|
||||
if (orig->samples == 0) {
|
||||
const char *env = SDL_getenv("SDL_AUDIO_SAMPLES");
|
||||
if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) {
|
||||
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;
|
||||
@@ -1262,10 +1208,9 @@ prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
|
||||
return 1;
|
||||
}
|
||||
|
||||
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 SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||
const SDL_AudioSpec *desired, SDL_AudioSpec *obtained,
|
||||
int allowed_changes, int min_id)
|
||||
{
|
||||
const SDL_bool is_internal_thread = (desired->callback == NULL);
|
||||
SDL_AudioDeviceID id = 0;
|
||||
@@ -1377,7 +1322,7 @@ open_audio_device(const char *devname, int iscapture,
|
||||
}
|
||||
}
|
||||
|
||||
device = (SDL_AudioDevice *) SDL_calloc(1, sizeof (SDL_AudioDevice));
|
||||
device = (SDL_AudioDevice *)SDL_calloc(1, sizeof(SDL_AudioDevice));
|
||||
if (device == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
@@ -1388,7 +1333,7 @@ open_audio_device(const char *devname, int iscapture,
|
||||
device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
|
||||
device->handle = handle;
|
||||
|
||||
SDL_AtomicSet(&device->shutdown, 0); /* just in case. */
|
||||
SDL_AtomicSet(&device->shutdown, 0); /* just in case. */
|
||||
SDL_AtomicSet(&device->paused, 1);
|
||||
SDL_AtomicSet(&device->enabled, 1);
|
||||
|
||||
@@ -1451,19 +1396,19 @@ open_audio_device(const char *devname, int iscapture,
|
||||
}
|
||||
}
|
||||
|
||||
SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */
|
||||
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);
|
||||
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);
|
||||
obtained->freq, device->spec.format,
|
||||
device->spec.channels, device->spec.freq);
|
||||
}
|
||||
|
||||
if (!device->stream) {
|
||||
@@ -1473,7 +1418,7 @@ open_audio_device(const char *devname, int iscapture,
|
||||
}
|
||||
}
|
||||
|
||||
if (device->spec.callback == NULL) { /* use buffer queueing? */
|
||||
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) {
|
||||
@@ -1493,7 +1438,7 @@ open_audio_device(const char *devname, int iscapture,
|
||||
}
|
||||
SDL_assert(device->work_buffer_len > 0);
|
||||
|
||||
device->work_buffer = (Uint8 *) SDL_malloc(device->work_buffer_len);
|
||||
device->work_buffer = (Uint8 *)SDL_malloc(device->work_buffer_len);
|
||||
if (device->work_buffer == NULL) {
|
||||
close_audio_device(device);
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
@@ -1501,7 +1446,7 @@ open_audio_device(const char *devname, int iscapture,
|
||||
return 0;
|
||||
}
|
||||
|
||||
open_devices[id] = device; /* add it to our list of open devices. */
|
||||
open_devices[id] = device; /* add it to our list of open devices. */
|
||||
|
||||
/* Start the audio thread if necessary */
|
||||
if (!current_audio.impl.ProvidesOwnCallbackThread) {
|
||||
@@ -1511,7 +1456,7 @@ open_audio_device(const char *devname, int iscapture,
|
||||
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);
|
||||
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) {
|
||||
@@ -1526,9 +1471,7 @@ open_audio_device(const char *devname, int iscapture,
|
||||
return device->id;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
|
||||
int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
|
||||
{
|
||||
SDL_AudioDeviceID id = 0;
|
||||
|
||||
@@ -1564,7 +1507,7 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
|
||||
|
||||
SDL_AudioDeviceID
|
||||
SDL_OpenAudioDevice(const char *device, int iscapture,
|
||||
const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
|
||||
const SDL_AudioSpec *desired, SDL_AudioSpec *obtained,
|
||||
int allowed_changes)
|
||||
{
|
||||
return open_audio_device(device, iscapture, desired, obtained,
|
||||
@@ -1586,15 +1529,13 @@ SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
SDL_AudioStatus
|
||||
SDL_GetAudioStatus(void)
|
||||
{
|
||||
return SDL_GetAudioDeviceStatus(1);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
|
||||
void SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
|
||||
{
|
||||
SDL_AudioDevice *device = get_audio_device(devid);
|
||||
if (device) {
|
||||
@@ -1604,15 +1545,12 @@ SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_PauseAudio(int pause_on)
|
||||
void SDL_PauseAudio(int pause_on)
|
||||
{
|
||||
SDL_PauseAudioDevice(1, pause_on);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SDL_LockAudioDevice(SDL_AudioDeviceID devid)
|
||||
void SDL_LockAudioDevice(SDL_AudioDeviceID devid)
|
||||
{
|
||||
/* Obtain a lock on the mixing buffers */
|
||||
SDL_AudioDevice *device = get_audio_device(devid);
|
||||
@@ -1621,14 +1559,12 @@ SDL_LockAudioDevice(SDL_AudioDeviceID devid)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_LockAudio(void)
|
||||
void SDL_LockAudio(void)
|
||||
{
|
||||
SDL_LockAudioDevice(1);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
|
||||
void SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
|
||||
{
|
||||
/* Obtain a lock on the mixing buffers */
|
||||
SDL_AudioDevice *device = get_audio_device(devid);
|
||||
@@ -1637,30 +1573,26 @@ SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UnlockAudio(void)
|
||||
void SDL_UnlockAudio(void)
|
||||
{
|
||||
SDL_UnlockAudioDevice(1);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
|
||||
void SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
|
||||
{
|
||||
close_audio_device(get_audio_device(devid));
|
||||
}
|
||||
|
||||
void
|
||||
SDL_CloseAudio(void)
|
||||
void SDL_CloseAudio(void)
|
||||
{
|
||||
SDL_CloseAudioDevice(1);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_AudioQuit(void)
|
||||
void SDL_AudioQuit(void)
|
||||
{
|
||||
SDL_AudioDeviceID i;
|
||||
|
||||
if (!current_audio.name) { /* not initialized?! */
|
||||
if (!current_audio.name) { /* not initialized?! */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1688,26 +1620,26 @@ SDL_AudioQuit(void)
|
||||
static int format_idx;
|
||||
static int format_idx_sub;
|
||||
static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS] = {
|
||||
{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},
|
||||
{ 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 },
|
||||
};
|
||||
|
||||
SDL_AudioFormat
|
||||
@@ -1731,26 +1663,25 @@ SDL_NextAudioFormat(void)
|
||||
return format_list[format_idx][format_idx_sub++];
|
||||
}
|
||||
|
||||
Uint8
|
||||
SDL_SilenceValueForFormat(const SDL_AudioFormat format)
|
||||
Uint8 SDL_SilenceValueForFormat(const SDL_AudioFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
/* !!! FIXME: 0x80 isn't perfect for U16, but we can't fit 0x8000 in a
|
||||
!!! FIXME: byte for SDL_memset() use. This is actually 0.1953 percent
|
||||
!!! FIXME: off from silence. Maybe just don't use U16. */
|
||||
case AUDIO_U16LSB:
|
||||
case AUDIO_U16MSB:
|
||||
case AUDIO_U8:
|
||||
return 0x80;
|
||||
/* !!! FIXME: 0x80 isn't perfect for U16, but we can't fit 0x8000 in a
|
||||
!!! FIXME: byte for SDL_memset() use. This is actually 0.1953 percent
|
||||
!!! FIXME: off from silence. Maybe just don't use U16. */
|
||||
case AUDIO_U16LSB:
|
||||
case AUDIO_U16MSB:
|
||||
case AUDIO_U8:
|
||||
return 0x80;
|
||||
|
||||
default: break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_CalculateAudioSpec(SDL_AudioSpec * spec)
|
||||
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
|
||||
{
|
||||
spec->silence = SDL_SilenceValueForFormat(spec->format);
|
||||
spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8;
|
||||
@@ -1758,13 +1689,11 @@ SDL_CalculateAudioSpec(SDL_AudioSpec * spec)
|
||||
spec->size *= spec->samples;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Moved here from SDL_mixer.c, since it relies on internals of an opened
|
||||
* audio device (and is deprecated, by the way!).
|
||||
*/
|
||||
void
|
||||
SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
|
||||
void SDL_MixAudio(Uint8 *dst, const Uint8 *src, Uint32 len, int volume)
|
||||
{
|
||||
/* Mix the user-level audio format */
|
||||
SDL_AudioDevice *device = get_audio_device(1);
|
||||
|
||||
@@ -40,11 +40,11 @@
|
||||
#include "samplerate.h"
|
||||
extern SDL_bool SRC_available;
|
||||
extern int SRC_converter;
|
||||
extern SRC_STATE* (*SRC_src_new)(int converter_type, int channels, int *error);
|
||||
extern SRC_STATE *(*SRC_src_new)(int converter_type, int channels, int *error);
|
||||
extern int (*SRC_src_process)(SRC_STATE *state, SRC_DATA *data);
|
||||
extern int (*SRC_src_reset)(SRC_STATE *state);
|
||||
extern SRC_STATE* (*SRC_src_delete)(SRC_STATE *state);
|
||||
extern const char* (*SRC_src_strerror)(int error);
|
||||
extern SRC_STATE *(*SRC_src_delete)(SRC_STATE *state);
|
||||
extern const char *(*SRC_src_strerror)(int error);
|
||||
extern int (*SRC_src_simple)(SRC_DATA *data, int converter_type, int channels);
|
||||
#endif
|
||||
|
||||
@@ -54,7 +54,7 @@ extern SDL_AudioFormat SDL_NextAudioFormat(void);
|
||||
|
||||
/* Function to calculate the size and silence for a SDL_AudioSpec */
|
||||
extern Uint8 SDL_SilenceValueForFormat(const SDL_AudioFormat format);
|
||||
extern void SDL_CalculateAudioSpec(SDL_AudioSpec * spec);
|
||||
extern void SDL_CalculateAudioSpec(SDL_AudioSpec *spec);
|
||||
|
||||
/* Choose the audio filter functions below */
|
||||
extern void SDL_ChooseAudioConverters(void);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,10 +21,10 @@
|
||||
|
||||
/* DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_resampler_filter.c */
|
||||
|
||||
#define RESAMPLER_ZERO_CROSSINGS 5
|
||||
#define RESAMPLER_BITS_PER_SAMPLE 16
|
||||
#define RESAMPLER_ZERO_CROSSINGS 5
|
||||
#define RESAMPLER_BITS_PER_SAMPLE 16
|
||||
#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1))
|
||||
#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1)
|
||||
#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1)
|
||||
|
||||
static const float ResamplerFilter[RESAMPLER_FILTER_SIZE] = {
|
||||
1.000000000f, 0.999993682f, 0.999974370f, 0.999941289f, 0.999894559f,
|
||||
@@ -1059,4 +1059,3 @@ static const float ResamplerFilterDifference[RESAMPLER_FILTER_SIZE] = {
|
||||
};
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,9 +33,9 @@
|
||||
|
||||
#ifndef _PATH_DEV_DSP
|
||||
#if defined(__NETBSD__) || defined(__OPENBSD__)
|
||||
#define _PATH_DEV_DSP "/dev/audio"
|
||||
#define _PATH_DEV_DSP "/dev/audio"
|
||||
#else
|
||||
#define _PATH_DEV_DSP "/dev/dsp"
|
||||
#define _PATH_DEV_DSP "/dev/dsp"
|
||||
#endif
|
||||
#endif
|
||||
#ifndef _PATH_DEV_DSP24
|
||||
@@ -45,8 +45,7 @@
|
||||
#define _PATH_DEV_AUDIO "/dev/audio"
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_device(const int iscapture, const char *fname, int flags, int (*test) (int fd))
|
||||
static void test_device(const int iscapture, const char *fname, int flags, int (*test)(int fd))
|
||||
{
|
||||
struct stat sb;
|
||||
if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) {
|
||||
@@ -64,20 +63,18 @@ test_device(const int iscapture, const char *fname, int flags, int (*test) (int
|
||||
* information, making this information inaccessible at
|
||||
* enumeration time
|
||||
*/
|
||||
SDL_AddAudioDevice(iscapture, fname, NULL, (void *) (uintptr_t) dummyhandle);
|
||||
SDL_AddAudioDevice(iscapture, fname, NULL, (void *)(uintptr_t)dummyhandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
test_stub(int fd)
|
||||
static int test_stub(int fd)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int))
|
||||
static void SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int))
|
||||
{
|
||||
const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT;
|
||||
const char *audiodev;
|
||||
@@ -96,9 +93,7 @@ SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*
|
||||
struct stat sb;
|
||||
|
||||
/* Added support for /dev/sound/\* in Linux 2.4 */
|
||||
if (((stat("/dev/sound", &sb) == 0) && S_ISDIR(sb.st_mode))
|
||||
&& ((stat(_PATH_DEV_DSP24, &sb) == 0)
|
||||
&& S_ISCHR(sb.st_mode))) {
|
||||
if (((stat("/dev/sound", &sb) == 0) && S_ISDIR(sb.st_mode)) && ((stat(_PATH_DEV_DSP24, &sb) == 0) && S_ISCHR(sb.st_mode))) {
|
||||
audiodev = _PATH_DEV_DSP24;
|
||||
} else {
|
||||
audiodev = _PATH_DEV_DSP;
|
||||
@@ -118,8 +113,7 @@ SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_EnumUnixAudioDevices(const int classic, int (*test)(int))
|
||||
void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int))
|
||||
{
|
||||
SDL_EnumUnixAudioDevices_Internal(SDL_TRUE, classic, test);
|
||||
SDL_EnumUnixAudioDevices_Internal(SDL_FALSE, classic, test);
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
|
||||
#ifdef USE_BLOCKING_WRITES
|
||||
#define OPEN_FLAGS_OUTPUT O_WRONLY
|
||||
#define OPEN_FLAGS_INPUT O_RDONLY
|
||||
#define OPEN_FLAGS_INPUT O_RDONLY
|
||||
#else
|
||||
#define OPEN_FLAGS_OUTPUT (O_WRONLY|O_NONBLOCK)
|
||||
#define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK)
|
||||
#define OPEN_FLAGS_OUTPUT (O_WRONLY | O_NONBLOCK)
|
||||
#define OPEN_FLAGS_INPUT (O_RDONLY | O_NONBLOCK)
|
||||
#endif
|
||||
|
||||
extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -78,14 +78,12 @@ static const Uint8 mix8[] = {
|
||||
};
|
||||
|
||||
/* The volume ranges from 0 - 128 */
|
||||
#define ADJUST_VOLUME(s, v) (s = (s*v)/SDL_MIX_MAXVOLUME)
|
||||
#define ADJUST_VOLUME_U8(s, v) (s = (((s-128)*v)/SDL_MIX_MAXVOLUME)+128)
|
||||
#define ADJUST_VOLUME_U16(s, v) (s = (((s-32768)*v)/SDL_MIX_MAXVOLUME)+32768)
|
||||
#define ADJUST_VOLUME(s, v) (s = (s * v) / SDL_MIX_MAXVOLUME)
|
||||
#define ADJUST_VOLUME_U8(s, v) (s = (((s - 128) * v) / SDL_MIX_MAXVOLUME) + 128)
|
||||
#define ADJUST_VOLUME_U16(s, v) (s = (((s - 32768) * v) / SDL_MIX_MAXVOLUME) + 32768)
|
||||
|
||||
|
||||
void
|
||||
SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
||||
Uint32 len, int volume)
|
||||
void SDL_MixAudioFormat(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format,
|
||||
Uint32 len, int volume)
|
||||
{
|
||||
if (volume == 0) {
|
||||
return;
|
||||
@@ -94,258 +92,248 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
|
||||
switch (format) {
|
||||
|
||||
case AUDIO_U8:
|
||||
{
|
||||
Uint8 src_sample;
|
||||
{
|
||||
Uint8 src_sample;
|
||||
|
||||
while (len--) {
|
||||
src_sample = *src;
|
||||
ADJUST_VOLUME_U8(src_sample, volume);
|
||||
*dst = mix8[*dst + src_sample];
|
||||
++dst;
|
||||
++src;
|
||||
}
|
||||
while (len--) {
|
||||
src_sample = *src;
|
||||
ADJUST_VOLUME_U8(src_sample, volume);
|
||||
*dst = mix8[*dst + src_sample];
|
||||
++dst;
|
||||
++src;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case AUDIO_S8:
|
||||
{
|
||||
Sint8 *dst8, *src8;
|
||||
Sint8 src_sample;
|
||||
int dst_sample;
|
||||
const int max_audioval = SDL_MAX_SINT8;
|
||||
const int min_audioval = SDL_MIN_SINT8;
|
||||
{
|
||||
Sint8 *dst8, *src8;
|
||||
Sint8 src_sample;
|
||||
int dst_sample;
|
||||
const int max_audioval = SDL_MAX_SINT8;
|
||||
const int min_audioval = SDL_MIN_SINT8;
|
||||
|
||||
src8 = (Sint8 *) src;
|
||||
dst8 = (Sint8 *) dst;
|
||||
while (len--) {
|
||||
src_sample = *src8;
|
||||
ADJUST_VOLUME(src_sample, volume);
|
||||
dst_sample = *dst8 + src_sample;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*dst8 = dst_sample;
|
||||
++dst8;
|
||||
++src8;
|
||||
src8 = (Sint8 *)src;
|
||||
dst8 = (Sint8 *)dst;
|
||||
while (len--) {
|
||||
src_sample = *src8;
|
||||
ADJUST_VOLUME(src_sample, volume);
|
||||
dst_sample = *dst8 + src_sample;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*dst8 = dst_sample;
|
||||
++dst8;
|
||||
++src8;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case AUDIO_S16LSB:
|
||||
{
|
||||
Sint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
{
|
||||
Sint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = SDL_SwapLE16(*(Sint16 *)src);
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = SDL_SwapLE16(*(Sint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(Sint16 *)dst = SDL_SwapLE16(dst_sample);
|
||||
dst += 2;
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = SDL_SwapLE16(*(Sint16 *)src);
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = SDL_SwapLE16(*(Sint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(Sint16 *)dst = SDL_SwapLE16(dst_sample);
|
||||
dst += 2;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case AUDIO_S16MSB:
|
||||
{
|
||||
Sint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
{
|
||||
Sint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = SDL_SwapBE16(*(Sint16 *)src);
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = SDL_SwapBE16(*(Sint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(Sint16 *)dst = SDL_SwapBE16(dst_sample);
|
||||
dst += 2;
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = SDL_SwapBE16(*(Sint16 *)src);
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = SDL_SwapBE16(*(Sint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(Sint16 *)dst = SDL_SwapBE16(dst_sample);
|
||||
dst += 2;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case AUDIO_U16LSB:
|
||||
{
|
||||
Uint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
{
|
||||
Uint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = SDL_SwapLE16(*(Uint16 *)src);
|
||||
ADJUST_VOLUME_U16(src1, volume);
|
||||
src2 = SDL_SwapLE16(*(Uint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2 - 32768 * 2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
dst_sample += 32768;
|
||||
*(Uint16 *)dst = SDL_SwapLE16(dst_sample);
|
||||
dst += 2;
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = SDL_SwapLE16(*(Uint16 *)src);
|
||||
ADJUST_VOLUME_U16(src1, volume);
|
||||
src2 = SDL_SwapLE16(*(Uint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2 - 32768 * 2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
dst_sample += 32768;
|
||||
*(Uint16 *)dst = SDL_SwapLE16(dst_sample);
|
||||
dst += 2;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case AUDIO_U16MSB:
|
||||
{
|
||||
Uint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
{
|
||||
Uint16 src1, src2;
|
||||
int dst_sample;
|
||||
const int max_audioval = SDL_MAX_SINT16;
|
||||
const int min_audioval = SDL_MIN_SINT16;
|
||||
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = SDL_SwapBE16(*(Uint16 *)src);
|
||||
ADJUST_VOLUME_U16(src1, volume);
|
||||
src2 = SDL_SwapBE16(*(Uint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2 - 32768 * 2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
dst_sample += 32768;
|
||||
*(Uint16 *)dst = SDL_SwapBE16(dst_sample);
|
||||
dst += 2;
|
||||
len /= 2;
|
||||
while (len--) {
|
||||
src1 = SDL_SwapBE16(*(Uint16 *)src);
|
||||
ADJUST_VOLUME_U16(src1, volume);
|
||||
src2 = SDL_SwapBE16(*(Uint16 *)dst);
|
||||
src += 2;
|
||||
dst_sample = src1 + src2 - 32768 * 2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
dst_sample += 32768;
|
||||
*(Uint16 *)dst = SDL_SwapBE16(dst_sample);
|
||||
dst += 2;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case AUDIO_S32LSB:
|
||||
{
|
||||
const Uint32 *src32 = (Uint32 *) src;
|
||||
Uint32 *dst32 = (Uint32 *) dst;
|
||||
Sint64 src1, src2;
|
||||
Sint64 dst_sample;
|
||||
const Sint64 max_audioval = SDL_MAX_SINT32;
|
||||
const Sint64 min_audioval = SDL_MIN_SINT32;
|
||||
{
|
||||
const Uint32 *src32 = (Uint32 *)src;
|
||||
Uint32 *dst32 = (Uint32 *)dst;
|
||||
Sint64 src1, src2;
|
||||
Sint64 dst_sample;
|
||||
const Sint64 max_audioval = SDL_MAX_SINT32;
|
||||
const Sint64 min_audioval = SDL_MIN_SINT32;
|
||||
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
src1 = (Sint64) ((Sint32) SDL_SwapLE32(*src32));
|
||||
src32++;
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = (Sint64) ((Sint32) SDL_SwapLE32(*dst32));
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(dst32++) = SDL_SwapLE32((Uint32) ((Sint32) dst_sample));
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
src1 = (Sint64)((Sint32)SDL_SwapLE32(*src32));
|
||||
src32++;
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = (Sint64)((Sint32)SDL_SwapLE32(*dst32));
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(dst32++) = SDL_SwapLE32((Uint32)((Sint32)dst_sample));
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case AUDIO_S32MSB:
|
||||
{
|
||||
const Uint32 *src32 = (Uint32 *) src;
|
||||
Uint32 *dst32 = (Uint32 *) dst;
|
||||
Sint64 src1, src2;
|
||||
Sint64 dst_sample;
|
||||
const Sint64 max_audioval = SDL_MAX_SINT32;
|
||||
const Sint64 min_audioval = SDL_MIN_SINT32;
|
||||
{
|
||||
const Uint32 *src32 = (Uint32 *)src;
|
||||
Uint32 *dst32 = (Uint32 *)dst;
|
||||
Sint64 src1, src2;
|
||||
Sint64 dst_sample;
|
||||
const Sint64 max_audioval = SDL_MAX_SINT32;
|
||||
const Sint64 min_audioval = SDL_MIN_SINT32;
|
||||
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
src1 = (Sint64) ((Sint32) SDL_SwapBE32(*src32));
|
||||
src32++;
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = (Sint64) ((Sint32) SDL_SwapBE32(*dst32));
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(dst32++) = SDL_SwapBE32((Uint32) ((Sint32) dst_sample));
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
src1 = (Sint64)((Sint32)SDL_SwapBE32(*src32));
|
||||
src32++;
|
||||
ADJUST_VOLUME(src1, volume);
|
||||
src2 = (Sint64)((Sint32)SDL_SwapBE32(*dst32));
|
||||
dst_sample = src1 + src2;
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(dst32++) = SDL_SwapBE32((Uint32)((Sint32)dst_sample));
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case AUDIO_F32LSB:
|
||||
{
|
||||
const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
|
||||
const float fvolume = (float) volume;
|
||||
const float *src32 = (float *) src;
|
||||
float *dst32 = (float *) dst;
|
||||
float src1, src2;
|
||||
double dst_sample;
|
||||
/* !!! FIXME: are these right? */
|
||||
const double max_audioval = 3.402823466e+38F;
|
||||
const double min_audioval = -3.402823466e+38F;
|
||||
{
|
||||
const float fmaxvolume = 1.0f / ((float)SDL_MIX_MAXVOLUME);
|
||||
const float fvolume = (float)volume;
|
||||
const float *src32 = (float *)src;
|
||||
float *dst32 = (float *)dst;
|
||||
float src1, src2;
|
||||
double dst_sample;
|
||||
/* !!! FIXME: are these right? */
|
||||
const double max_audioval = 3.402823466e+38F;
|
||||
const double min_audioval = -3.402823466e+38F;
|
||||
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
src1 = ((SDL_SwapFloatLE(*src32) * fvolume) * fmaxvolume);
|
||||
src2 = SDL_SwapFloatLE(*dst32);
|
||||
src32++;
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
src1 = ((SDL_SwapFloatLE(*src32) * fvolume) * fmaxvolume);
|
||||
src2 = SDL_SwapFloatLE(*dst32);
|
||||
src32++;
|
||||
|
||||
dst_sample = ((double) src1) + ((double) src2);
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(dst32++) = SDL_SwapFloatLE((float) dst_sample);
|
||||
dst_sample = ((double)src1) + ((double)src2);
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(dst32++) = SDL_SwapFloatLE((float)dst_sample);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case AUDIO_F32MSB:
|
||||
{
|
||||
const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
|
||||
const float fvolume = (float) volume;
|
||||
const float *src32 = (float *) src;
|
||||
float *dst32 = (float *) dst;
|
||||
float src1, src2;
|
||||
double dst_sample;
|
||||
/* !!! FIXME: are these right? */
|
||||
const double max_audioval = 3.402823466e+38F;
|
||||
const double min_audioval = -3.402823466e+38F;
|
||||
{
|
||||
const float fmaxvolume = 1.0f / ((float)SDL_MIX_MAXVOLUME);
|
||||
const float fvolume = (float)volume;
|
||||
const float *src32 = (float *)src;
|
||||
float *dst32 = (float *)dst;
|
||||
float src1, src2;
|
||||
double dst_sample;
|
||||
/* !!! FIXME: are these right? */
|
||||
const double max_audioval = 3.402823466e+38F;
|
||||
const double min_audioval = -3.402823466e+38F;
|
||||
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
src1 = ((SDL_SwapFloatBE(*src32) * fvolume) * fmaxvolume);
|
||||
src2 = SDL_SwapFloatBE(*dst32);
|
||||
src32++;
|
||||
len /= 4;
|
||||
while (len--) {
|
||||
src1 = ((SDL_SwapFloatBE(*src32) * fvolume) * fmaxvolume);
|
||||
src2 = SDL_SwapFloatBE(*dst32);
|
||||
src32++;
|
||||
|
||||
dst_sample = ((double) src1) + ((double) src2);
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(dst32++) = SDL_SwapFloatBE((float) dst_sample);
|
||||
dst_sample = ((double)src1) + ((double)src2);
|
||||
if (dst_sample > max_audioval) {
|
||||
dst_sample = max_audioval;
|
||||
} else if (dst_sample < min_audioval) {
|
||||
dst_sample = min_audioval;
|
||||
}
|
||||
*(dst32++) = SDL_SwapFloatBE((float)dst_sample);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
default: /* If this happens... FIXME! */
|
||||
default: /* If this happens... FIXME! */
|
||||
SDL_SetError("SDL_MixAudioFormat(): unknown audio format");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
|
||||
/* !!! FIXME: These are wordy and unlocalized... */
|
||||
#define DEFAULT_OUTPUT_DEVNAME "System audio output device"
|
||||
#define DEFAULT_INPUT_DEVNAME "System audio capture device"
|
||||
#define DEFAULT_INPUT_DEVNAME "System audio capture device"
|
||||
|
||||
/* The SDL audio driver */
|
||||
typedef struct SDL_AudioDevice SDL_AudioDevice;
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
|
||||
/* Audio targets should call this as devices are added to the system (such as
|
||||
a USB headset being plugged in), and should also be called for
|
||||
@@ -62,21 +62,21 @@ extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device);
|
||||
|
||||
typedef struct SDL_AudioDriverImpl
|
||||
{
|
||||
void (*DetectDevices) (void);
|
||||
int (*OpenDevice) (_THIS, const char *devname);
|
||||
void (*ThreadInit) (_THIS); /* Called by audio thread at start */
|
||||
void (*ThreadDeinit) (_THIS); /* Called by audio thread at end */
|
||||
void (*WaitDevice) (_THIS);
|
||||
void (*PlayDevice) (_THIS);
|
||||
Uint8 *(*GetDeviceBuf) (_THIS);
|
||||
int (*CaptureFromDevice) (_THIS, void *buffer, int buflen);
|
||||
void (*FlushCapture) (_THIS);
|
||||
void (*CloseDevice) (_THIS);
|
||||
void (*LockDevice) (_THIS);
|
||||
void (*UnlockDevice) (_THIS);
|
||||
void (*FreeDeviceHandle) (void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */
|
||||
void (*Deinitialize) (void);
|
||||
int (*GetDefaultAudioInfo) (char **name, SDL_AudioSpec *spec, int iscapture);
|
||||
void (*DetectDevices)(void);
|
||||
int (*OpenDevice)(_THIS, const char *devname);
|
||||
void (*ThreadInit)(_THIS); /* Called by audio thread at start */
|
||||
void (*ThreadDeinit)(_THIS); /* Called by audio thread at end */
|
||||
void (*WaitDevice)(_THIS);
|
||||
void (*PlayDevice)(_THIS);
|
||||
Uint8 *(*GetDeviceBuf)(_THIS);
|
||||
int (*CaptureFromDevice)(_THIS, void *buffer, int buflen);
|
||||
void (*FlushCapture)(_THIS);
|
||||
void (*CloseDevice)(_THIS);
|
||||
void (*LockDevice)(_THIS);
|
||||
void (*UnlockDevice)(_THIS);
|
||||
void (*FreeDeviceHandle)(void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */
|
||||
void (*Deinitialize)(void);
|
||||
int (*GetDefaultAudioInfo)(char **name, SDL_AudioSpec *spec, int iscapture);
|
||||
|
||||
/* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */
|
||||
|
||||
@@ -89,7 +89,6 @@ typedef struct SDL_AudioDriverImpl
|
||||
SDL_bool SupportsNonPow2Samples;
|
||||
} SDL_AudioDriverImpl;
|
||||
|
||||
|
||||
typedef struct SDL_AudioDeviceItem
|
||||
{
|
||||
void *handle;
|
||||
@@ -100,7 +99,6 @@ typedef struct SDL_AudioDeviceItem
|
||||
struct SDL_AudioDeviceItem *next;
|
||||
} SDL_AudioDeviceItem;
|
||||
|
||||
|
||||
typedef struct SDL_AudioDriver
|
||||
{
|
||||
/* * * */
|
||||
@@ -123,7 +121,6 @@ typedef struct SDL_AudioDriver
|
||||
SDL_AudioDeviceItem *inputDevices;
|
||||
} SDL_AudioDriver;
|
||||
|
||||
|
||||
/* Define the SDL audio driver structure */
|
||||
struct SDL_AudioDevice
|
||||
{
|
||||
@@ -174,8 +171,8 @@ typedef struct AudioBootStrap
|
||||
{
|
||||
const char *name;
|
||||
const char *desc;
|
||||
SDL_bool (*init) (SDL_AudioDriverImpl * impl);
|
||||
SDL_bool demand_only; /* 1==request explicitly, or it won't be available. */
|
||||
SDL_bool (*init)(SDL_AudioDriverImpl *impl);
|
||||
SDL_bool demand_only; /* 1==request explicitly, or it won't be available. */
|
||||
} AudioBootStrap;
|
||||
|
||||
/* Not all of these are available in a given build. Use #ifdefs, etc. */
|
||||
|
||||
@@ -41,8 +41,7 @@
|
||||
* Returns 0 on success, or -1 if the multiplication overflows, in which case f1
|
||||
* does not get modified.
|
||||
*/
|
||||
static int
|
||||
SafeMult(size_t *f1, size_t f2)
|
||||
static int SafeMult(size_t *f1, size_t f2)
|
||||
{
|
||||
if (*f1 > 0 && SIZE_MAX / *f1 <= f2) {
|
||||
return -1;
|
||||
@@ -64,21 +63,24 @@ typedef struct ADPCM_DecoderState
|
||||
void *cstate; /* Decoding state for each channel. */
|
||||
|
||||
/* ADPCM data. */
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
Uint8 *data;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
} input;
|
||||
|
||||
/* Current ADPCM block in the ADPCM data above. */
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
Uint8 *data;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
} block;
|
||||
|
||||
/* Decoded 16-bit PCM data. */
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
Sint16 *data;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
@@ -100,8 +102,7 @@ typedef struct MS_ADPCM_ChannelState
|
||||
} MS_ADPCM_ChannelState;
|
||||
|
||||
#ifdef SDL_WAVE_DEBUG_LOG_FORMAT
|
||||
static void
|
||||
WaveDebugLogFormat(WaveFile *file)
|
||||
static void WaveDebugLogFormat(WaveFile *file)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
const char *fmtstr = "WAVE file: %s, %u Hz, %s, %u bits, %u %s/s";
|
||||
@@ -135,55 +136,60 @@ WaveDebugLogFormat(WaveFile *file)
|
||||
break;
|
||||
}
|
||||
|
||||
#define SDL_WAVE_DEBUG_CHANNELCFG(STR, CODE) case CODE: wavechannel = STR; break;
|
||||
#define SDL_WAVE_DEBUG_CHANNELSTR(STR, CODE) if (format->channelmask & CODE) { \
|
||||
SDL_strlcat(channelstr, channelstr[0] ? "-" STR : STR, sizeof(channelstr));}
|
||||
#define SDL_WAVE_DEBUG_CHANNELCFG(STR, CODE) \
|
||||
case CODE: \
|
||||
wavechannel = STR; \
|
||||
break;
|
||||
#define SDL_WAVE_DEBUG_CHANNELSTR(STR, CODE) \
|
||||
if (format->channelmask & CODE) { \
|
||||
SDL_strlcat(channelstr, channelstr[0] ? "-" STR : STR, sizeof(channelstr)); \
|
||||
}
|
||||
|
||||
if (format->formattag == EXTENSIBLE_CODE && format->channelmask > 0) {
|
||||
switch (format->channelmask) {
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("1.0 Mono", 0x4)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("1.1 Mono", 0xc)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("2.0 Stereo", 0x3)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("2.1 Stereo", 0xb)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("3.0 Stereo", 0x7)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("3.1 Stereo", 0xf)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("3.0 Surround", 0x103)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("3.1 Surround", 0x10b)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("4.0 Quad", 0x33)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("4.1 Quad", 0x3b)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("4.0 Surround", 0x107)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("4.1 Surround", 0x10f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("5.0", 0x37)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("5.1", 0x3f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("5.0 Side", 0x607)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("5.1 Side", 0x60f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("6.0", 0x137)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("6.1", 0x13f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("6.0 Side", 0x707)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("6.1 Side", 0x70f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.0", 0xf7)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.1", 0xff)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.0 Side", 0x6c7)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.1 Side", 0x6cf)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.0 Surround", 0x637)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.1 Surround", 0x63f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("9.0 Surround", 0x5637)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("9.1 Surround", 0x563f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("11.0 Surround", 0x56f7)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("11.1 Surround", 0x56ff)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("1.0 Mono", 0x4)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("1.1 Mono", 0xc)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("2.0 Stereo", 0x3)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("2.1 Stereo", 0xb)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("3.0 Stereo", 0x7)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("3.1 Stereo", 0xf)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("3.0 Surround", 0x103)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("3.1 Surround", 0x10b)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("4.0 Quad", 0x33)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("4.1 Quad", 0x3b)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("4.0 Surround", 0x107)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("4.1 Surround", 0x10f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("5.0", 0x37)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("5.1", 0x3f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("5.0 Side", 0x607)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("5.1 Side", 0x60f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("6.0", 0x137)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("6.1", 0x13f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("6.0 Side", 0x707)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("6.1 Side", 0x70f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.0", 0xf7)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.1", 0xff)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.0 Side", 0x6c7)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.1 Side", 0x6cf)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.0 Surround", 0x637)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("7.1 Surround", 0x63f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("9.0 Surround", 0x5637)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("9.1 Surround", 0x563f)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("11.0 Surround", 0x56f7)
|
||||
SDL_WAVE_DEBUG_CHANNELCFG("11.1 Surround", 0x56ff)
|
||||
default:
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("FL", 0x1)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("FR", 0x2)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("FC", 0x4)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("LF", 0x8)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("BL", 0x10)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("BR", 0x20)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("FL", 0x1)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("FR", 0x2)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("FC", 0x4)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("LF", 0x8)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("BL", 0x10)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("BR", 0x20)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("FLC", 0x40)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("FRC", 0x80)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("BC", 0x100)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("SL", 0x200)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("SR", 0x400)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("TC", 0x800)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("BC", 0x100)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("SL", 0x200)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("SR", 0x400)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("TC", 0x800)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("TFL", 0x1000)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("TFC", 0x2000)
|
||||
SDL_WAVE_DEBUG_CHANNELSTR("TFR", 0x4000)
|
||||
@@ -224,33 +230,32 @@ WaveDebugLogFormat(WaveFile *file)
|
||||
#endif
|
||||
|
||||
#ifdef SDL_WAVE_DEBUG_DUMP_FORMAT
|
||||
static void
|
||||
WaveDebugDumpFormat(WaveFile *file, Uint32 rifflen, Uint32 fmtlen, Uint32 datalen)
|
||||
static void WaveDebugDumpFormat(WaveFile *file, Uint32 rifflen, Uint32 fmtlen, Uint32 datalen)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
const char *fmtstr1 = "WAVE chunk dump:\n"
|
||||
"-------------------------------------------\n"
|
||||
"RIFF %11u\n"
|
||||
"-------------------------------------------\n"
|
||||
" fmt %11u\n"
|
||||
" wFormatTag 0x%04x\n"
|
||||
" nChannels %11u\n"
|
||||
" nSamplesPerSec %11u\n"
|
||||
" nAvgBytesPerSec %11u\n"
|
||||
" nBlockAlign %11u\n";
|
||||
"-------------------------------------------\n"
|
||||
"RIFF %11u\n"
|
||||
"-------------------------------------------\n"
|
||||
" fmt %11u\n"
|
||||
" wFormatTag 0x%04x\n"
|
||||
" nChannels %11u\n"
|
||||
" nSamplesPerSec %11u\n"
|
||||
" nAvgBytesPerSec %11u\n"
|
||||
" nBlockAlign %11u\n";
|
||||
const char *fmtstr2 = " wBitsPerSample %11u\n";
|
||||
const char *fmtstr3 = " cbSize %11u\n";
|
||||
const char *fmtstr4a = " wValidBitsPerSample %11u\n";
|
||||
const char *fmtstr4b = " wSamplesPerBlock %11u\n";
|
||||
const char *fmtstr5 = " dwChannelMask 0x%08x\n"
|
||||
" SubFormat\n"
|
||||
" %08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x\n";
|
||||
" SubFormat\n"
|
||||
" %08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x\n";
|
||||
const char *fmtstr6 = "-------------------------------------------\n"
|
||||
" fact\n"
|
||||
" dwSampleLength %11u\n";
|
||||
" fact\n"
|
||||
" dwSampleLength %11u\n";
|
||||
const char *fmtstr7 = "-------------------------------------------\n"
|
||||
" data %11u\n"
|
||||
"-------------------------------------------\n";
|
||||
" data %11u\n"
|
||||
"-------------------------------------------\n";
|
||||
char *dumpstr;
|
||||
size_t dumppos = 0;
|
||||
const size_t bufsize = 1024;
|
||||
@@ -315,8 +320,7 @@ WaveDebugDumpFormat(WaveFile *file, Uint32 rifflen, Uint32 fmtlen, Uint32 datale
|
||||
}
|
||||
#endif
|
||||
|
||||
static Sint64
|
||||
WaveAdjustToFactValue(WaveFile *file, Sint64 sampleframes)
|
||||
static Sint64 WaveAdjustToFactValue(WaveFile *file, Sint64 sampleframes)
|
||||
{
|
||||
if (file->fact.status == 2) {
|
||||
if (file->facthint == FactStrict && sampleframes < file->fact.samplelength) {
|
||||
@@ -329,8 +333,7 @@ WaveAdjustToFactValue(WaveFile *file, Sint64 sampleframes)
|
||||
return sampleframes;
|
||||
}
|
||||
|
||||
static int
|
||||
MS_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength)
|
||||
static int MS_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
const size_t blockheadersize = (size_t)file->format.channels * 7;
|
||||
@@ -369,8 +372,7 @@ MS_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
MS_ADPCM_Init(WaveFile *file, size_t datalength)
|
||||
static int MS_ADPCM_Init(WaveFile *file, size_t datalength)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
WaveChunk *chunk = &file->chunk;
|
||||
@@ -378,7 +380,7 @@ MS_ADPCM_Init(WaveFile *file, size_t datalength)
|
||||
const size_t blockdatasize = (size_t)format->blockalign - blockheadersize;
|
||||
const size_t blockframebitsize = (size_t)format->bitspersample * format->channels;
|
||||
const size_t blockdatasamples = (blockdatasize * 8) / blockframebitsize;
|
||||
const Sint16 presetcoeffs[14] = {256, 0, 512, -256, 0, 0, 192, 64, 240, 0, 460, -208, 392, -232};
|
||||
const Sint16 presetcoeffs[14] = { 256, 0, 512, -256, 0, 0, 192, 64, 240, 0, 460, -208, 392, -232 };
|
||||
size_t i, coeffcount;
|
||||
MS_ADPCM_CoeffData *coeffdata;
|
||||
|
||||
@@ -488,8 +490,7 @@ MS_ADPCM_Init(WaveFile *file, size_t datalength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Sint16
|
||||
MS_ADPCM_ProcessNibble(MS_ADPCM_ChannelState *cstate, Sint32 sample1, Sint32 sample2, Uint8 nybble)
|
||||
static Sint16 MS_ADPCM_ProcessNibble(MS_ADPCM_ChannelState *cstate, Sint32 sample1, Sint32 sample2, Uint8 nybble)
|
||||
{
|
||||
const Sint32 max_audioval = 32767;
|
||||
const Sint32 min_audioval = -32768;
|
||||
@@ -525,8 +526,7 @@ MS_ADPCM_ProcessNibble(MS_ADPCM_ChannelState *cstate, Sint32 sample1, Sint32 sam
|
||||
return (Sint16)new_sample;
|
||||
}
|
||||
|
||||
static int
|
||||
MS_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state)
|
||||
static int MS_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state)
|
||||
{
|
||||
Uint8 coeffindex;
|
||||
const Uint32 channels = state->channels;
|
||||
@@ -586,8 +586,7 @@ MS_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state)
|
||||
* will always contain full sample frames (same sample count for each channel).
|
||||
* Incomplete sample frames are discarded.
|
||||
*/
|
||||
static int
|
||||
MS_ADPCM_DecodeBlockData(ADPCM_DecoderState *state)
|
||||
static int MS_ADPCM_DecodeBlockData(ADPCM_DecoderState *state)
|
||||
{
|
||||
Uint16 nybble = 0;
|
||||
Sint16 sample1, sample2;
|
||||
@@ -634,8 +633,7 @@ MS_ADPCM_DecodeBlockData(ADPCM_DecoderState *state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
static int MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
int result;
|
||||
size_t bytesleft, outputsize;
|
||||
@@ -734,8 +732,7 @@ MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
IMA_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength)
|
||||
static int IMA_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
const size_t blockheadersize = (size_t)format->channels * 4;
|
||||
@@ -788,8 +785,7 @@ IMA_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
IMA_ADPCM_Init(WaveFile *file, size_t datalength)
|
||||
static int IMA_ADPCM_Init(WaveFile *file, size_t datalength)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
WaveChunk *chunk = &file->chunk;
|
||||
@@ -854,8 +850,7 @@ IMA_ADPCM_Init(WaveFile *file, size_t datalength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Sint16
|
||||
IMA_ADPCM_ProcessNibble(Sint8 *cindex, Sint16 lastsample, Uint8 nybble)
|
||||
static Sint16 IMA_ADPCM_ProcessNibble(Sint8 *cindex, Sint16 lastsample, Uint8 nybble)
|
||||
{
|
||||
const Sint32 max_audioval = 32767;
|
||||
const Sint32 min_audioval = -32768;
|
||||
@@ -924,12 +919,11 @@ IMA_ADPCM_ProcessNibble(Sint8 *cindex, Sint16 lastsample, Uint8 nybble)
|
||||
return (Sint16)sample;
|
||||
}
|
||||
|
||||
static int
|
||||
IMA_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state)
|
||||
static int IMA_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state)
|
||||
{
|
||||
Sint16 step;
|
||||
Uint32 c;
|
||||
Uint8 *cstate = (Uint8 *) state->cstate;
|
||||
Uint8 *cstate = (Uint8 *)state->cstate;
|
||||
|
||||
for (c = 0; c < state->channels; c++) {
|
||||
size_t o = state->block.pos + c * 4;
|
||||
@@ -947,7 +941,7 @@ IMA_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state)
|
||||
|
||||
/* Reserved byte in block header, should be 0. */
|
||||
if (state->block.data[o + 3] != 0) {
|
||||
/* Uh oh, corrupt data? Buggy code? */ ;
|
||||
/* Uh oh, corrupt data? Buggy code? */;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -964,8 +958,7 @@ IMA_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state)
|
||||
* contains full sample frames (same sample count for each channel).
|
||||
* Incomplete sample frames are discarded.
|
||||
*/
|
||||
static int
|
||||
IMA_ADPCM_DecodeBlockData(ADPCM_DecoderState *state)
|
||||
static int IMA_ADPCM_DecodeBlockData(ADPCM_DecoderState *state)
|
||||
{
|
||||
size_t i;
|
||||
int retval = 0;
|
||||
@@ -1034,8 +1027,7 @@ IMA_ADPCM_DecodeBlockData(ADPCM_DecoderState *state)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
IMA_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
static int IMA_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
int result;
|
||||
size_t bytesleft, outputsize;
|
||||
@@ -1138,8 +1130,7 @@ IMA_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
LAW_Init(WaveFile *file, size_t datalength)
|
||||
static int LAW_Init(WaveFile *file, size_t datalength)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
|
||||
@@ -1167,8 +1158,7 @@ LAW_Init(WaveFile *file, size_t datalength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
LAW_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
static int LAW_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
#ifdef SDL_WAVE_LAW_LUT
|
||||
const Sint16 alaw_lut[256] = {
|
||||
@@ -1310,8 +1300,7 @@ LAW_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
PCM_Init(WaveFile *file, size_t datalength)
|
||||
static int PCM_Init(WaveFile *file, size_t datalength)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
|
||||
@@ -1354,8 +1343,7 @@ PCM_Init(WaveFile *file, size_t datalength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
PCM_ConvertSint24ToSint32(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
static int PCM_ConvertSint24ToSint32(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
WaveChunk *chunk = &file->chunk;
|
||||
@@ -1406,8 +1394,7 @@ PCM_ConvertSint24ToSint32(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
PCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
static int PCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
WaveChunk *chunk = &file->chunk;
|
||||
@@ -1449,8 +1436,7 @@ PCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static WaveRiffSizeHint
|
||||
WaveGetRiffSizeHint()
|
||||
static WaveRiffSizeHint WaveGetRiffSizeHint()
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_WAVE_RIFF_CHUNK_SIZE);
|
||||
|
||||
@@ -1469,8 +1455,7 @@ WaveGetRiffSizeHint()
|
||||
return RiffSizeNoHint;
|
||||
}
|
||||
|
||||
static WaveTruncationHint
|
||||
WaveGetTruncationHint()
|
||||
static WaveTruncationHint WaveGetTruncationHint()
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_WAVE_TRUNCATION);
|
||||
|
||||
@@ -1489,8 +1474,7 @@ WaveGetTruncationHint()
|
||||
return TruncNoHint;
|
||||
}
|
||||
|
||||
static WaveFactChunkHint
|
||||
WaveGetFactChunkHint()
|
||||
static WaveFactChunkHint WaveGetFactChunkHint()
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_WAVE_FACT_CHUNK);
|
||||
|
||||
@@ -1509,8 +1493,7 @@ WaveGetFactChunkHint()
|
||||
return FactNoHint;
|
||||
}
|
||||
|
||||
static void
|
||||
WaveFreeChunkData(WaveChunk *chunk)
|
||||
static void WaveFreeChunkData(WaveChunk *chunk)
|
||||
{
|
||||
if (chunk->data != NULL) {
|
||||
SDL_free(chunk->data);
|
||||
@@ -1519,8 +1502,7 @@ WaveFreeChunkData(WaveChunk *chunk)
|
||||
chunk->size = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
WaveNextChunk(SDL_RWops *src, WaveChunk *chunk)
|
||||
static int WaveNextChunk(SDL_RWops *src, WaveChunk *chunk)
|
||||
{
|
||||
Uint32 chunkheader[2];
|
||||
Sint64 nextposition = chunk->position + chunk->length;
|
||||
@@ -1552,8 +1534,7 @@ WaveNextChunk(SDL_RWops *src, WaveChunk *chunk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t length)
|
||||
static int WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t length)
|
||||
{
|
||||
WaveFreeChunkData(chunk);
|
||||
|
||||
@@ -1562,7 +1543,7 @@ WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t length)
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
chunk->data = (Uint8 *) SDL_malloc(length);
|
||||
chunk->data = (Uint8 *)SDL_malloc(length);
|
||||
if (chunk->data == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -1581,30 +1562,32 @@ WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
WaveReadChunkData(SDL_RWops *src, WaveChunk *chunk)
|
||||
static int WaveReadChunkData(SDL_RWops *src, WaveChunk *chunk)
|
||||
{
|
||||
return WaveReadPartialChunkData(src, chunk, chunk->length);
|
||||
}
|
||||
|
||||
typedef struct WaveExtensibleGUID {
|
||||
typedef struct WaveExtensibleGUID
|
||||
{
|
||||
Uint16 encoding;
|
||||
Uint8 guid[16];
|
||||
} WaveExtensibleGUID;
|
||||
|
||||
/* Some of the GUIDs that are used by WAVEFORMATEXTENSIBLE. */
|
||||
#define WAVE_FORMATTAG_GUID(tag) {(tag) & 0xff, (tag) >> 8, 0, 0, 0, 0, 16, 0, 128, 0, 0, 170, 0, 56, 155, 113}
|
||||
#define WAVE_FORMATTAG_GUID(tag) \
|
||||
{ \
|
||||
(tag) & 0xff, (tag) >> 8, 0, 0, 0, 0, 16, 0, 128, 0, 0, 170, 0, 56, 155, 113 \
|
||||
}
|
||||
static WaveExtensibleGUID extensible_guids[] = {
|
||||
{PCM_CODE, WAVE_FORMATTAG_GUID(PCM_CODE)},
|
||||
{MS_ADPCM_CODE, WAVE_FORMATTAG_GUID(MS_ADPCM_CODE)},
|
||||
{IEEE_FLOAT_CODE, WAVE_FORMATTAG_GUID(IEEE_FLOAT_CODE)},
|
||||
{ALAW_CODE, WAVE_FORMATTAG_GUID(ALAW_CODE)},
|
||||
{MULAW_CODE, WAVE_FORMATTAG_GUID(MULAW_CODE)},
|
||||
{IMA_ADPCM_CODE, WAVE_FORMATTAG_GUID(IMA_ADPCM_CODE)}
|
||||
{ PCM_CODE, WAVE_FORMATTAG_GUID(PCM_CODE) },
|
||||
{ MS_ADPCM_CODE, WAVE_FORMATTAG_GUID(MS_ADPCM_CODE) },
|
||||
{ IEEE_FLOAT_CODE, WAVE_FORMATTAG_GUID(IEEE_FLOAT_CODE) },
|
||||
{ ALAW_CODE, WAVE_FORMATTAG_GUID(ALAW_CODE) },
|
||||
{ MULAW_CODE, WAVE_FORMATTAG_GUID(MULAW_CODE) },
|
||||
{ IMA_ADPCM_CODE, WAVE_FORMATTAG_GUID(IMA_ADPCM_CODE) }
|
||||
};
|
||||
|
||||
static Uint16
|
||||
WaveGetFormatGUIDEncoding(WaveFormat *format)
|
||||
static Uint16 WaveGetFormatGUIDEncoding(WaveFormat *format)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < SDL_arraysize(extensible_guids); i++) {
|
||||
@@ -1615,8 +1598,7 @@ WaveGetFormatGUIDEncoding(WaveFormat *format)
|
||||
return UNKNOWN_CODE;
|
||||
}
|
||||
|
||||
static int
|
||||
WaveReadFormat(WaveFile *file)
|
||||
static int WaveReadFormat(WaveFile *file)
|
||||
{
|
||||
WaveChunk *chunk = &file->chunk;
|
||||
WaveFormat *format = &file->format;
|
||||
@@ -1677,8 +1659,7 @@ WaveReadFormat(WaveFile *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
WaveCheckFormat(WaveFile *file, size_t datalength)
|
||||
static int WaveCheckFormat(WaveFile *file, size_t datalength)
|
||||
{
|
||||
WaveFormat *format = &file->format;
|
||||
|
||||
@@ -1785,8 +1766,7 @@ WaveCheckFormat(WaveFile *file, size_t datalength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
int result;
|
||||
Uint32 chunkcount = 0;
|
||||
@@ -2051,7 +2031,7 @@ WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf,
|
||||
SDL_zerop(spec);
|
||||
spec->freq = format->frequency;
|
||||
spec->channels = (Uint8)format->channels;
|
||||
spec->samples = 4096; /* Good default buffer size */
|
||||
spec->samples = 4096; /* Good default buffer size */
|
||||
|
||||
switch (format->encoding) {
|
||||
case MS_ADPCM_CODE:
|
||||
@@ -2148,8 +2128,7 @@ SDL_LoadWAV_RW(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_b
|
||||
/* Since the WAV memory is allocated in the shared library, it must also
|
||||
be freed here. (Necessary under Win32, VC++)
|
||||
*/
|
||||
void
|
||||
SDL_FreeWAV(Uint8 *audio_buf)
|
||||
void SDL_FreeWAV(Uint8 *audio_buf)
|
||||
{
|
||||
SDL_free(audio_buf);
|
||||
}
|
||||
|
||||
@@ -26,14 +26,14 @@
|
||||
/* Define values for Microsoft WAVE format */
|
||||
/*******************************************/
|
||||
/* FOURCC */
|
||||
#define RIFF 0x46464952 /* "RIFF" */
|
||||
#define WAVE 0x45564157 /* "WAVE" */
|
||||
#define FACT 0x74636166 /* "fact" */
|
||||
#define LIST 0x5453494c /* "LIST" */
|
||||
#define BEXT 0x74786562 /* "bext" */
|
||||
#define JUNK 0x4B4E554A /* "JUNK" */
|
||||
#define FMT 0x20746D66 /* "fmt " */
|
||||
#define DATA 0x61746164 /* "data" */
|
||||
#define RIFF 0x46464952 /* "RIFF" */
|
||||
#define WAVE 0x45564157 /* "WAVE" */
|
||||
#define FACT 0x74636166 /* "fact" */
|
||||
#define LIST 0x5453494c /* "LIST" */
|
||||
#define BEXT 0x74786562 /* "bext" */
|
||||
#define JUNK 0x4B4E554A /* "JUNK" */
|
||||
#define FMT 0x20746D66 /* "fmt " */
|
||||
#define DATA 0x61746164 /* "data" */
|
||||
/* Format tags */
|
||||
#define UNKNOWN_CODE 0x0000
|
||||
#define PCM_CODE 0x0001
|
||||
@@ -49,13 +49,13 @@
|
||||
/* Stores the WAVE format information. */
|
||||
typedef struct WaveFormat
|
||||
{
|
||||
Uint16 formattag; /* Raw value of the first field in the fmt chunk data. */
|
||||
Uint16 encoding; /* Actual encoding, possibly from the extensible header. */
|
||||
Uint16 channels; /* Number of channels. */
|
||||
Uint32 frequency; /* Sampling rate in Hz. */
|
||||
Uint32 byterate; /* Average bytes per second. */
|
||||
Uint16 blockalign; /* Bytes per block. */
|
||||
Uint16 bitspersample; /* Currently supported are 8, 16, 24, 32, and 4 for ADPCM. */
|
||||
Uint16 formattag; /* Raw value of the first field in the fmt chunk data. */
|
||||
Uint16 encoding; /* Actual encoding, possibly from the extensible header. */
|
||||
Uint16 channels; /* Number of channels. */
|
||||
Uint32 frequency; /* Sampling rate in Hz. */
|
||||
Uint32 byterate; /* Average bytes per second. */
|
||||
Uint16 blockalign; /* Bytes per block. */
|
||||
Uint16 bitspersample; /* Currently supported are 8, 16, 24, 32, and 4 for ADPCM. */
|
||||
|
||||
/* Extra information size. Number of extra bytes starting at byte 18 in the
|
||||
* fmt chunk data. This is at least 22 for the extensible header.
|
||||
@@ -66,11 +66,12 @@ typedef struct WaveFormat
|
||||
Uint16 validsamplebits;
|
||||
Uint32 samplesperblock; /* For compressed formats. Can be zero. Actually 16 bits in the header. */
|
||||
Uint32 channelmask;
|
||||
Uint8 subformat[16]; /* A format GUID. */
|
||||
Uint8 subformat[16]; /* A format GUID. */
|
||||
} WaveFormat;
|
||||
|
||||
/* Stores information on the fact chunk. */
|
||||
typedef struct WaveFact {
|
||||
typedef struct WaveFact
|
||||
{
|
||||
/* Represents the state of the fact chunk in the WAVE file.
|
||||
* Set to -1 if the fact chunk is invalid.
|
||||
* Set to 0 if the fact chunk is not present
|
||||
@@ -101,7 +102,8 @@ typedef struct WaveChunk
|
||||
} WaveChunk;
|
||||
|
||||
/* Controls how the size of the RIFF chunk affects the loading of a WAVE file. */
|
||||
typedef enum WaveRiffSizeHint {
|
||||
typedef enum WaveRiffSizeHint
|
||||
{
|
||||
RiffSizeNoHint,
|
||||
RiffSizeForce,
|
||||
RiffSizeIgnoreZero,
|
||||
@@ -110,7 +112,8 @@ typedef enum WaveRiffSizeHint {
|
||||
} WaveRiffSizeHint;
|
||||
|
||||
/* Controls how a truncated WAVE file is handled. */
|
||||
typedef enum WaveTruncationHint {
|
||||
typedef enum WaveTruncationHint
|
||||
{
|
||||
TruncNoHint,
|
||||
TruncVeryStrict,
|
||||
TruncStrict,
|
||||
@@ -119,7 +122,8 @@ typedef enum WaveTruncationHint {
|
||||
} WaveTruncationHint;
|
||||
|
||||
/* Controls how the fact chunk affects the loading of a WAVE file. */
|
||||
typedef enum WaveFactChunkHint {
|
||||
typedef enum WaveFactChunkHint
|
||||
{
|
||||
FactNoHint,
|
||||
FactTruncate,
|
||||
FactStrict,
|
||||
@@ -139,7 +143,7 @@ typedef struct WaveFile
|
||||
*/
|
||||
Sint64 sampleframes;
|
||||
|
||||
void *decoderdata; /* Some decoders require extra data for a state. */
|
||||
void *decoderdata; /* Some decoders require extra data for a state. */
|
||||
|
||||
WaveRiffSizeHint riffhint;
|
||||
WaveTruncationHint trunchint;
|
||||
|
||||
@@ -28,17 +28,17 @@
|
||||
|
||||
/* Debug */
|
||||
#if 0
|
||||
# define LOGI(...) SDL_Log(__VA_ARGS__);
|
||||
#define LOGI(...) SDL_Log(__VA_ARGS__);
|
||||
#else
|
||||
# define LOGI(...)
|
||||
#define LOGI(...)
|
||||
#endif
|
||||
|
||||
typedef struct AAUDIO_Data
|
||||
{
|
||||
AAudioStreamBuilder *builder;
|
||||
void *handle;
|
||||
#define SDL_PROC(ret,func,params) ret (*func) params;
|
||||
# include "SDL_aaudiofuncs.h"
|
||||
#define SDL_PROC(ret, func, params) ret(*func) params;
|
||||
#include "SDL_aaudiofuncs.h"
|
||||
#undef SDL_PROC
|
||||
} AAUDIO_Data;
|
||||
static AAUDIO_Data ctx;
|
||||
@@ -48,28 +48,27 @@ static SDL_AudioDevice *captureDevice = NULL;
|
||||
|
||||
static int aaudio_LoadFunctions(AAUDIO_Data *data)
|
||||
{
|
||||
#define SDL_PROC(ret,func,params) \
|
||||
do { \
|
||||
data->func = SDL_LoadFunction(data->handle, #func); \
|
||||
if (! data->func) { \
|
||||
return SDL_SetError("Couldn't load AAUDIO function %s: %s", #func, SDL_GetError()); \
|
||||
} \
|
||||
#define SDL_PROC(ret, func, params) \
|
||||
do { \
|
||||
data->func = SDL_LoadFunction(data->handle, #func); \
|
||||
if (!data->func) { \
|
||||
return SDL_SetError("Couldn't load AAUDIO function %s: %s", #func, SDL_GetError()); \
|
||||
} \
|
||||
} while (0);
|
||||
#include "SDL_aaudiofuncs.h"
|
||||
#undef SDL_PROC
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aaudio_errorCallback( AAudioStream *stream, void *userData, aaudio_result_t error );
|
||||
void aaudio_errorCallback( AAudioStream *stream, void *userData, aaudio_result_t error )
|
||||
void aaudio_errorCallback(AAudioStream *stream, void *userData, aaudio_result_t error);
|
||||
void aaudio_errorCallback(AAudioStream *stream, void *userData, aaudio_result_t error)
|
||||
{
|
||||
LOGI( "SDL aaudio_errorCallback: %d - %s", error, ctx.AAudio_convertResultToText( error ) );
|
||||
LOGI("SDL aaudio_errorCallback: %d - %s", error, ctx.AAudio_convertResultToText(error));
|
||||
}
|
||||
|
||||
#define LIB_AAUDIO_SO "libaaudio.so"
|
||||
|
||||
static int
|
||||
aaudio_OpenDevice(_THIS, const char *devname)
|
||||
static int aaudio_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
@@ -92,7 +91,7 @@ aaudio_OpenDevice(_THIS, const char *devname)
|
||||
audioDevice = this;
|
||||
}
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, (sizeof *this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -114,11 +113,11 @@ aaudio_OpenDevice(_THIS, const char *devname)
|
||||
ctx.AAudioStreamBuilder_setFormat(ctx.builder, format);
|
||||
}
|
||||
|
||||
ctx.AAudioStreamBuilder_setErrorCallback( ctx.builder, aaudio_errorCallback, private );
|
||||
ctx.AAudioStreamBuilder_setErrorCallback(ctx.builder, aaudio_errorCallback, private);
|
||||
|
||||
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
|
||||
res = ctx.AAudioStreamBuilder_openStream(ctx.builder, &private->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
@@ -138,15 +137,15 @@ aaudio_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
|
||||
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
/* Allocate mixing buffer */
|
||||
if (!iscapture) {
|
||||
private->mixlen = this->spec.size;
|
||||
private->mixbuf = (Uint8 *) SDL_malloc(private->mixlen);
|
||||
private->mixbuf = (Uint8 *)SDL_malloc(private->mixlen);
|
||||
if (private->mixbuf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -165,8 +164,7 @@ aaudio_OpenDevice(_THIS, const char *devname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
aaudio_CloseDevice(_THIS)
|
||||
static void aaudio_CloseDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private = this->hidden;
|
||||
aaudio_result_t res;
|
||||
@@ -200,20 +198,18 @@ aaudio_CloseDevice(_THIS)
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
aaudio_GetDeviceBuf(_THIS)
|
||||
static Uint8 *aaudio_GetDeviceBuf(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private = this->hidden;
|
||||
return private->mixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
aaudio_PlayDevice(_THIS)
|
||||
static void aaudio_PlayDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private = this->hidden;
|
||||
aaudio_result_t res;
|
||||
int64_t timeoutNanoseconds = 1 * 1000 * 1000; /* 8 ms */
|
||||
res = ctx.AAudioStream_write(private->stream, private->mixbuf, private->mixlen / private->frame_size, timeoutNanoseconds);
|
||||
res = ctx.AAudioStream_write(private->stream, private->mixbuf, private->mixlen / private->frame_size, timeoutNanoseconds);
|
||||
if (res < 0) {
|
||||
LOGI("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
} else {
|
||||
@@ -233,13 +229,12 @@ aaudio_PlayDevice(_THIS)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
aaudio_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int aaudio_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private = this->hidden;
|
||||
aaudio_result_t res;
|
||||
int64_t timeoutNanoseconds = 8 * 1000 * 1000; /* 8 ms */
|
||||
res = ctx.AAudioStream_read(private->stream, buffer, buflen / private->frame_size, timeoutNanoseconds);
|
||||
res = ctx.AAudioStream_read(private->stream, buffer, buflen / private->frame_size, timeoutNanoseconds);
|
||||
if (res < 0) {
|
||||
LOGI("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
return -1;
|
||||
@@ -248,8 +243,7 @@ aaudio_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
return res * private->frame_size;
|
||||
}
|
||||
|
||||
static void
|
||||
aaudio_Deinitialize(void)
|
||||
static void aaudio_Deinitialize(void)
|
||||
{
|
||||
LOGI(__func__);
|
||||
if (ctx.handle) {
|
||||
@@ -267,8 +261,7 @@ aaudio_Deinitialize(void)
|
||||
LOGI("End AAUDIO %s", SDL_GetError());
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
aaudio_Init(SDL_AudioDriverImpl *impl)
|
||||
static SDL_bool aaudio_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
aaudio_result_t res;
|
||||
LOGI(__func__);
|
||||
@@ -343,7 +336,7 @@ void aaudio_PauseDevices(void)
|
||||
/* TODO: Handle multiple devices? */
|
||||
struct SDL_PrivateAudioData *private;
|
||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
|
||||
private = (struct SDL_PrivateAudioData *)audioDevice->hidden;
|
||||
|
||||
if (private->stream) {
|
||||
aaudio_result_t res = ctx.AAudioStream_requestPause(private->stream);
|
||||
@@ -364,7 +357,7 @@ void aaudio_PauseDevices(void)
|
||||
}
|
||||
|
||||
if (captureDevice != NULL && captureDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
|
||||
private = (struct SDL_PrivateAudioData *)captureDevice->hidden;
|
||||
|
||||
if (private->stream) {
|
||||
/* Pause() isn't implemented for 'capture', use Stop() */
|
||||
@@ -392,7 +385,7 @@ void aaudio_ResumeDevices(void)
|
||||
/* TODO: Handle multiple devices? */
|
||||
struct SDL_PrivateAudioData *private;
|
||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
|
||||
private = (struct SDL_PrivateAudioData *)audioDevice->hidden;
|
||||
|
||||
if (private->resume) {
|
||||
SDL_AtomicSet(&audioDevice->paused, 0);
|
||||
@@ -410,7 +403,7 @@ void aaudio_ResumeDevices(void)
|
||||
}
|
||||
|
||||
if (captureDevice != NULL && captureDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
|
||||
private = (struct SDL_PrivateAudioData *)captureDevice->hidden;
|
||||
|
||||
if (private->resume) {
|
||||
SDL_AtomicSet(&captureDevice->paused, 0);
|
||||
@@ -433,24 +426,24 @@ void aaudio_ResumeDevices(void)
|
||||
None of the standard state queries indicate any problem in my testing. And the error callback doesn't actually get called.
|
||||
But, AAudioStream_getTimestamp() does return AAUDIO_ERROR_INVALID_STATE
|
||||
*/
|
||||
SDL_bool aaudio_DetectBrokenPlayState( void )
|
||||
SDL_bool aaudio_DetectBrokenPlayState(void)
|
||||
{
|
||||
struct SDL_PrivateAudioData *private;
|
||||
int64_t framePosition, timeNanoseconds;
|
||||
aaudio_result_t res;
|
||||
|
||||
if (audioDevice == NULL || !audioDevice->hidden ) {
|
||||
if (audioDevice == NULL || !audioDevice->hidden) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
private = audioDevice->hidden;
|
||||
|
||||
res = ctx.AAudioStream_getTimestamp( private->stream, CLOCK_MONOTONIC, &framePosition, &timeNanoseconds );
|
||||
if ( res == AAUDIO_ERROR_INVALID_STATE ) {
|
||||
aaudio_stream_state_t currentState = ctx.AAudioStream_getState( private->stream );
|
||||
res = ctx.AAudioStream_getTimestamp(private->stream, CLOCK_MONOTONIC, &framePosition, &timeNanoseconds);
|
||||
if (res == AAUDIO_ERROR_INVALID_STATE) {
|
||||
aaudio_stream_state_t currentState = ctx.AAudioStream_getState(private->stream);
|
||||
/* AAudioStream_getTimestamp() will also return AAUDIO_ERROR_INVALID_STATE while the stream is still initially starting. But we only care if it silently went invalid while playing. */
|
||||
if ( currentState == AAUDIO_STREAM_STATE_STARTED ) {
|
||||
LOGI( "SDL aaudio_DetectBrokenPlayState: detected invalid audio device state: AAudioStream_getTimestamp result=%d, framePosition=%lld, timeNanoseconds=%lld, getState=%d", (int)res, (long long)framePosition, (long long)timeNanoseconds, (int)currentState );
|
||||
if (currentState == AAUDIO_STREAM_STATE_STARTED) {
|
||||
LOGI("SDL aaudio_DetectBrokenPlayState: detected invalid audio device state: AAudioStream_getTimestamp result=%d, framePosition=%lld, timeNanoseconds=%lld, getState=%d", (int)res, (long long)framePosition, (long long)timeNanoseconds, (int)currentState);
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <aaudio/AAudio.h>
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
@@ -42,12 +42,11 @@ struct SDL_PrivateAudioData
|
||||
/* Resume device if it was paused automatically */
|
||||
int resume;
|
||||
};
|
||||
|
||||
|
||||
void aaudio_ResumeDevices(void);
|
||||
void aaudio_PauseDevices(void);
|
||||
SDL_bool aaudio_DetectBrokenPlayState(void);
|
||||
|
||||
|
||||
#endif /* _SDL_aaudio_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -19,62 +19,61 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#define SDL_PROC_UNUSED(ret,func,params)
|
||||
#define SDL_PROC_UNUSED(ret, func, params)
|
||||
|
||||
SDL_PROC(const char *, AAudio_convertResultToText, (aaudio_result_t returnCode))
|
||||
SDL_PROC(const char *, AAudio_convertStreamStateToText, (aaudio_stream_state_t state))
|
||||
SDL_PROC(aaudio_result_t, AAudio_createStreamBuilder, (AAudioStreamBuilder** builder))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setDeviceId, (AAudioStreamBuilder* builder, int32_t deviceId))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setSampleRate, (AAudioStreamBuilder* builder, int32_t sampleRate))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setChannelCount, (AAudioStreamBuilder* builder, int32_t channelCount))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSamplesPerFrame, (AAudioStreamBuilder* builder, int32_t samplesPerFrame))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder* builder, aaudio_format_t format))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder* builder, aaudio_sharing_mode_t sharingMode))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder* builder, aaudio_direction_t direction))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder* builder, int32_t numFrames))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder* builder, aaudio_performance_mode_t mode))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder* builder, aaudio_usage_t usage)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder* builder, aaudio_content_type_t contentType)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder* builder, aaudio_input_preset_t inputPreset)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setAllowedCapturePolicy, (AAudioStreamBuilder* builder, aaudio_allowed_capture_policy_t capturePolicy)) /* API 29 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSessionId, (AAudioStreamBuilder* builder, aaudio_session_id_t sessionId)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPrivacySensitive, (AAudioStreamBuilder* builder, bool privacySensitive)) /* API 30 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setDataCallback, (AAudioStreamBuilder* builder, AAudioStream_dataCallback callback, void *userData))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setFramesPerDataCallback, (AAudioStreamBuilder* builder, int32_t numFrames))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setErrorCallback, (AAudioStreamBuilder* builder, AAudioStream_errorCallback callback, void *userData))
|
||||
SDL_PROC(aaudio_result_t , AAudioStreamBuilder_openStream, (AAudioStreamBuilder* builder, AAudioStream** stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStreamBuilder_delete, (AAudioStreamBuilder* builder))
|
||||
SDL_PROC_UNUSED(aaudio_result_t , AAudioStream_release, (AAudioStream* stream)) /* API 30 */
|
||||
SDL_PROC(aaudio_result_t , AAudioStream_close, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStream_requestStart, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStream_requestPause, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_result_t , AAudioStream_requestFlush, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStream_requestStop, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_stream_state_t, AAudioStream_getState, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_waitForStateChange, (AAudioStream* stream, aaudio_stream_state_t inputState, aaudio_stream_state_t *nextState, int64_t timeoutNanoseconds))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_read, (AAudioStream* stream, void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_write, (AAudioStream* stream, const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_setBufferSizeInFrames, (AAudioStream* stream, int32_t numFrames))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getBufferSizeInFrames, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerBurst, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getBufferCapacityInFrames, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerDataCallback, (AAudioStream* stream))
|
||||
SDL_PROC(int32_t, AAudioStream_getXRunCount, (AAudioStream* stream))
|
||||
SDL_PROC(int32_t, AAudioStream_getSampleRate, (AAudioStream* stream))
|
||||
SDL_PROC(int32_t, AAudioStream_getChannelCount, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getSamplesPerFrame, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getDeviceId, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_format_t, AAudioStream_getFormat, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_sharing_mode_t, AAudioStream_getSharingMode, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_performance_mode_t, AAudioStream_getPerformanceMode, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_direction_t, AAudioStream_getDirection, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesWritten, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesRead, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_session_id_t, AAudioStream_getSessionId, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_getTimestamp, (AAudioStream* stream, clockid_t clockid, int64_t *framePosition, int64_t *timeNanoseconds))
|
||||
SDL_PROC_UNUSED(aaudio_usage_t, AAudioStream_getUsage, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_content_type_t, AAudioStream_getContentType, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_input_preset_t, AAudioStream_getInputPreset, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_allowed_capture_policy_t, AAudioStream_getAllowedCapturePolicy, ( AAudioStream* stream)) /* API 29 */
|
||||
SDL_PROC_UNUSED(bool, AAudioStream_isPrivacySensitive, (AAudioStream* stream)) /* API 30 */
|
||||
|
||||
SDL_PROC(aaudio_result_t, AAudio_createStreamBuilder, (AAudioStreamBuilder * *builder))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setDeviceId, (AAudioStreamBuilder * builder, int32_t deviceId))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setSampleRate, (AAudioStreamBuilder * builder, int32_t sampleRate))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setChannelCount, (AAudioStreamBuilder * builder, int32_t channelCount))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSamplesPerFrame, (AAudioStreamBuilder * builder, int32_t samplesPerFrame))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder * builder, aaudio_format_t format))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * builder, aaudio_sharing_mode_t sharingMode))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder * builder, aaudio_input_preset_t inputPreset)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setAllowedCapturePolicy, (AAudioStreamBuilder * builder, aaudio_allowed_capture_policy_t capturePolicy)) /* API 29 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSessionId, (AAudioStreamBuilder * builder, aaudio_session_id_t sessionId)) /* API 28 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPrivacySensitive, (AAudioStreamBuilder * builder, bool privacySensitive)) /* API 30 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setDataCallback, (AAudioStreamBuilder * builder, AAudioStream_dataCallback callback, void *userData))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setFramesPerDataCallback, (AAudioStreamBuilder * builder, int32_t numFrames))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setErrorCallback, (AAudioStreamBuilder * builder, AAudioStream_errorCallback callback, void *userData))
|
||||
SDL_PROC(aaudio_result_t, AAudioStreamBuilder_openStream, (AAudioStreamBuilder * builder, AAudioStream **stream))
|
||||
SDL_PROC(aaudio_result_t, AAudioStreamBuilder_delete, (AAudioStreamBuilder * builder))
|
||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_release, (AAudioStream * stream)) /* API 30 */
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_close, (AAudioStream * stream))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_requestStart, (AAudioStream * stream))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_requestPause, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_requestFlush, (AAudioStream * stream))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_requestStop, (AAudioStream * stream))
|
||||
SDL_PROC(aaudio_stream_state_t, AAudioStream_getState, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_waitForStateChange, (AAudioStream * stream, aaudio_stream_state_t inputState, aaudio_stream_state_t *nextState, int64_t timeoutNanoseconds))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_read, (AAudioStream * stream, void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_write, (AAudioStream * stream, const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_setBufferSizeInFrames, (AAudioStream * stream, int32_t numFrames))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getBufferSizeInFrames, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerBurst, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getBufferCapacityInFrames, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerDataCallback, (AAudioStream * stream))
|
||||
SDL_PROC(int32_t, AAudioStream_getXRunCount, (AAudioStream * stream))
|
||||
SDL_PROC(int32_t, AAudioStream_getSampleRate, (AAudioStream * stream))
|
||||
SDL_PROC(int32_t, AAudioStream_getChannelCount, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getSamplesPerFrame, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(int32_t, AAudioStream_getDeviceId, (AAudioStream * stream))
|
||||
SDL_PROC(aaudio_format_t, AAudioStream_getFormat, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(aaudio_sharing_mode_t, AAudioStream_getSharingMode, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(aaudio_performance_mode_t, AAudioStream_getPerformanceMode, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(aaudio_direction_t, AAudioStream_getDirection, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesWritten, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesRead, (AAudioStream * stream))
|
||||
SDL_PROC_UNUSED(aaudio_session_id_t, AAudioStream_getSessionId, (AAudioStream * stream)) /* API 28 */
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_getTimestamp, (AAudioStream * stream, clockid_t clockid, int64_t *framePosition, int64_t *timeNanoseconds))
|
||||
SDL_PROC_UNUSED(aaudio_usage_t, AAudioStream_getUsage, (AAudioStream * stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_content_type_t, AAudioStream_getContentType, (AAudioStream * stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_input_preset_t, AAudioStream_getInputPreset, (AAudioStream * stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_allowed_capture_policy_t, AAudioStream_getAllowedCapturePolicy, (AAudioStream * stream)) /* API 29 */
|
||||
SDL_PROC_UNUSED(bool, AAudioStream_isPrivacySensitive, (AAudioStream * stream)) /* API 30 */
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h> /* For kill() */
|
||||
#include <signal.h> /* For kill() */
|
||||
#include <string.h>
|
||||
|
||||
#include "../SDL_audio_c.h"
|
||||
@@ -43,64 +43,46 @@
|
||||
#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
|
||||
#endif
|
||||
|
||||
static int (*ALSA_snd_pcm_open)
|
||||
(snd_pcm_t **, const char *, snd_pcm_stream_t, int);
|
||||
static int (*ALSA_snd_pcm_close) (snd_pcm_t * pcm);
|
||||
static snd_pcm_sframes_t (*ALSA_snd_pcm_writei)
|
||||
(snd_pcm_t *, const void *, snd_pcm_uframes_t);
|
||||
static snd_pcm_sframes_t (*ALSA_snd_pcm_readi)
|
||||
(snd_pcm_t *, void *, snd_pcm_uframes_t);
|
||||
static int (*ALSA_snd_pcm_recover) (snd_pcm_t *, int, int);
|
||||
static int (*ALSA_snd_pcm_prepare) (snd_pcm_t *);
|
||||
static int (*ALSA_snd_pcm_drain) (snd_pcm_t *);
|
||||
static const char *(*ALSA_snd_strerror) (int);
|
||||
static size_t(*ALSA_snd_pcm_hw_params_sizeof) (void);
|
||||
static size_t(*ALSA_snd_pcm_sw_params_sizeof) (void);
|
||||
static void (*ALSA_snd_pcm_hw_params_copy)
|
||||
(snd_pcm_hw_params_t *, const snd_pcm_hw_params_t *);
|
||||
static int (*ALSA_snd_pcm_hw_params_any) (snd_pcm_t *, snd_pcm_hw_params_t *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_access)
|
||||
(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_access_t);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_format)
|
||||
(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_format_t);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_channels)
|
||||
(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_channels)
|
||||
(const snd_pcm_hw_params_t *, unsigned int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_rate_near)
|
||||
(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_period_size_near)
|
||||
(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_period_size)
|
||||
(const snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_periods_min)
|
||||
(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_periods_first)
|
||||
(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_periods)
|
||||
(const snd_pcm_hw_params_t *, unsigned int *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_buffer_size_near)
|
||||
(snd_pcm_t *pcm, snd_pcm_hw_params_t *, snd_pcm_uframes_t *);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_buffer_size)
|
||||
(const snd_pcm_hw_params_t *, snd_pcm_uframes_t *);
|
||||
static int (*ALSA_snd_pcm_hw_params) (snd_pcm_t *, snd_pcm_hw_params_t *);
|
||||
static int (*ALSA_snd_pcm_sw_params_current) (snd_pcm_t *,
|
||||
snd_pcm_sw_params_t *);
|
||||
static int (*ALSA_snd_pcm_sw_params_set_start_threshold)
|
||||
(snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t);
|
||||
static int (*ALSA_snd_pcm_sw_params) (snd_pcm_t *, snd_pcm_sw_params_t *);
|
||||
static int (*ALSA_snd_pcm_nonblock) (snd_pcm_t *, int);
|
||||
static int (*ALSA_snd_pcm_open)(snd_pcm_t **, const char *, snd_pcm_stream_t, int);
|
||||
static int (*ALSA_snd_pcm_close)(snd_pcm_t *pcm);
|
||||
static snd_pcm_sframes_t (*ALSA_snd_pcm_writei)(snd_pcm_t *, const void *, snd_pcm_uframes_t);
|
||||
static snd_pcm_sframes_t (*ALSA_snd_pcm_readi)(snd_pcm_t *, void *, snd_pcm_uframes_t);
|
||||
static int (*ALSA_snd_pcm_recover)(snd_pcm_t *, int, int);
|
||||
static int (*ALSA_snd_pcm_prepare)(snd_pcm_t *);
|
||||
static int (*ALSA_snd_pcm_drain)(snd_pcm_t *);
|
||||
static const char *(*ALSA_snd_strerror)(int);
|
||||
static size_t (*ALSA_snd_pcm_hw_params_sizeof)(void);
|
||||
static size_t (*ALSA_snd_pcm_sw_params_sizeof)(void);
|
||||
static void (*ALSA_snd_pcm_hw_params_copy)(snd_pcm_hw_params_t *, const snd_pcm_hw_params_t *);
|
||||
static int (*ALSA_snd_pcm_hw_params_any)(snd_pcm_t *, snd_pcm_hw_params_t *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_access)(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_access_t);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_format)(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_format_t);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_channels)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *, unsigned int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_rate_near)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_period_size_near)(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_period_size)(const snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_periods_min)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_periods_first)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_periods)(const snd_pcm_hw_params_t *, unsigned int *, int *);
|
||||
static int (*ALSA_snd_pcm_hw_params_set_buffer_size_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *, snd_pcm_uframes_t *);
|
||||
static int (*ALSA_snd_pcm_hw_params_get_buffer_size)(const snd_pcm_hw_params_t *, snd_pcm_uframes_t *);
|
||||
static int (*ALSA_snd_pcm_hw_params)(snd_pcm_t *, snd_pcm_hw_params_t *);
|
||||
static int (*ALSA_snd_pcm_sw_params_current)(snd_pcm_t *,
|
||||
snd_pcm_sw_params_t *);
|
||||
static int (*ALSA_snd_pcm_sw_params_set_start_threshold)(snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t);
|
||||
static int (*ALSA_snd_pcm_sw_params)(snd_pcm_t *, snd_pcm_sw_params_t *);
|
||||
static int (*ALSA_snd_pcm_nonblock)(snd_pcm_t *, int);
|
||||
static int (*ALSA_snd_pcm_wait)(snd_pcm_t *, int);
|
||||
static int (*ALSA_snd_pcm_sw_params_set_avail_min)
|
||||
(snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t);
|
||||
static int (*ALSA_snd_pcm_sw_params_set_avail_min)(snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t);
|
||||
static int (*ALSA_snd_pcm_reset)(snd_pcm_t *);
|
||||
static int (*ALSA_snd_device_name_hint) (int, const char *, void ***);
|
||||
static char* (*ALSA_snd_device_name_get_hint) (const void *, const char *);
|
||||
static int (*ALSA_snd_device_name_free_hint) (void **);
|
||||
static int (*ALSA_snd_device_name_hint)(int, const char *, void ***);
|
||||
static char *(*ALSA_snd_device_name_get_hint)(const void *, const char *);
|
||||
static int (*ALSA_snd_device_name_free_hint)(void **);
|
||||
static snd_pcm_sframes_t (*ALSA_snd_pcm_avail)(snd_pcm_t *);
|
||||
#ifdef SND_CHMAP_API_VERSION
|
||||
static snd_pcm_chmap_t* (*ALSA_snd_pcm_get_chmap) (snd_pcm_t *);
|
||||
static int (*ALSA_snd_pcm_chmap_print) (const snd_pcm_chmap_t *map, size_t maxlen, char *buf);
|
||||
static snd_pcm_chmap_t *(*ALSA_snd_pcm_get_chmap)(snd_pcm_t *);
|
||||
static int (*ALSA_snd_pcm_chmap_print)(const snd_pcm_chmap_t *map, size_t maxlen, char *buf);
|
||||
#endif
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
|
||||
@@ -110,8 +92,7 @@ static int (*ALSA_snd_pcm_chmap_print) (const snd_pcm_chmap_t *map, size_t maxle
|
||||
static const char *alsa_library = SDL_AUDIO_DRIVER_ALSA_DYNAMIC;
|
||||
static void *alsa_handle = NULL;
|
||||
|
||||
static int
|
||||
load_alsa_sym(const char *fn, void **addr)
|
||||
static int load_alsa_sym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(alsa_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
@@ -123,14 +104,14 @@ load_alsa_sym(const char *fn, void **addr)
|
||||
}
|
||||
|
||||
/* cast funcs to char* first, to please GCC's strict aliasing rules. */
|
||||
#define SDL_ALSA_SYM(x) \
|
||||
if (!load_alsa_sym(#x, (void **) (char *) &ALSA_##x)) return -1
|
||||
#define SDL_ALSA_SYM(x) \
|
||||
if (!load_alsa_sym(#x, (void **)(char *)&ALSA_##x)) \
|
||||
return -1
|
||||
#else
|
||||
#define SDL_ALSA_SYM(x) ALSA_##x = x
|
||||
#endif
|
||||
|
||||
static int
|
||||
load_alsa_syms(void)
|
||||
static int load_alsa_syms(void)
|
||||
{
|
||||
SDL_ALSA_SYM(snd_pcm_open);
|
||||
SDL_ALSA_SYM(snd_pcm_close);
|
||||
@@ -180,8 +161,7 @@ load_alsa_syms(void)
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
|
||||
|
||||
static void
|
||||
UnloadALSALibrary(void)
|
||||
static void UnloadALSALibrary(void)
|
||||
{
|
||||
if (alsa_handle != NULL) {
|
||||
SDL_UnloadObject(alsa_handle);
|
||||
@@ -189,8 +169,7 @@ UnloadALSALibrary(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
LoadALSALibrary(void)
|
||||
static int LoadALSALibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
if (alsa_handle == NULL) {
|
||||
@@ -210,13 +189,11 @@ LoadALSALibrary(void)
|
||||
|
||||
#else
|
||||
|
||||
static void
|
||||
UnloadALSALibrary(void)
|
||||
static void UnloadALSALibrary(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
LoadALSALibrary(void)
|
||||
static int LoadALSALibrary(void)
|
||||
{
|
||||
load_alsa_syms();
|
||||
return 0;
|
||||
@@ -224,8 +201,7 @@ LoadALSALibrary(void)
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */
|
||||
|
||||
static const char *
|
||||
get_audio_device(void *handle, const int channels)
|
||||
static const char *get_audio_device(void *handle, const int channels)
|
||||
{
|
||||
const char *device;
|
||||
|
||||
@@ -234,7 +210,7 @@ get_audio_device(void *handle, const int channels)
|
||||
}
|
||||
|
||||
/* !!! FIXME: we also check "SDL_AUDIO_DEVICE_NAME" at the higher level. */
|
||||
device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */
|
||||
device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */
|
||||
if (device != NULL) {
|
||||
return device;
|
||||
}
|
||||
@@ -248,49 +224,50 @@ get_audio_device(void *handle, const int channels)
|
||||
return "default";
|
||||
}
|
||||
|
||||
|
||||
/* This function waits until it is possible to write a full sound buffer */
|
||||
static void
|
||||
ALSA_WaitDevice(_THIS)
|
||||
static void ALSA_WaitDevice(_THIS)
|
||||
{
|
||||
#if SDL_ALSA_NON_BLOCKING
|
||||
const snd_pcm_sframes_t needed = (snd_pcm_sframes_t) this->spec.samples;
|
||||
const snd_pcm_sframes_t needed = (snd_pcm_sframes_t)this->spec.samples;
|
||||
while (SDL_AtomicGet(&this->enabled)) {
|
||||
const snd_pcm_sframes_t rc = ALSA_snd_pcm_avail(this->hidden->pcm_handle);
|
||||
if ((rc < 0) && (rc != -EAGAIN)) {
|
||||
/* Hmm, not much we can do - abort */
|
||||
fprintf(stderr, "ALSA snd_pcm_avail failed (unrecoverable): %s\n",
|
||||
ALSA_snd_strerror(rc));
|
||||
ALSA_snd_strerror(rc));
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return;
|
||||
} else if (rc < needed) {
|
||||
const Uint32 delay = ((needed - (SDL_max(rc, 0))) * 1000) / this->spec.freq;
|
||||
SDL_Delay(SDL_max(delay, 10));
|
||||
} else {
|
||||
break; /* ready to go! */
|
||||
break; /* ready to go! */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* !!! FIXME: is there a channel swizzler in alsalib instead? */
|
||||
/*
|
||||
* https://bugzilla.libsdl.org/show_bug.cgi?id=110
|
||||
* "For Linux ALSA, this is FL-FR-RL-RR-C-LFE
|
||||
* and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR"
|
||||
*/
|
||||
#define SWIZ6(T) \
|
||||
static void swizzle_alsa_channels_6_##T(void *buffer, const Uint32 bufferlen) { \
|
||||
T *ptr = (T *) buffer; \
|
||||
Uint32 i; \
|
||||
for (i = 0; i < bufferlen; i++, ptr += 6) { \
|
||||
T tmp; \
|
||||
tmp = ptr[2]; ptr[2] = ptr[4]; ptr[4] = tmp; \
|
||||
tmp = ptr[3]; ptr[3] = ptr[5]; ptr[5] = tmp; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SWIZ6(T) \
|
||||
static void swizzle_alsa_channels_6_##T(void *buffer, const Uint32 bufferlen) \
|
||||
{ \
|
||||
T *ptr = (T *)buffer; \
|
||||
Uint32 i; \
|
||||
for (i = 0; i < bufferlen; i++, ptr += 6) { \
|
||||
T tmp; \
|
||||
tmp = ptr[2]; \
|
||||
ptr[2] = ptr[4]; \
|
||||
ptr[4] = tmp; \
|
||||
tmp = ptr[3]; \
|
||||
ptr[3] = ptr[5]; \
|
||||
ptr[5] = tmp; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* !!! FIXME: is there a channel swizzler in alsalib instead? */
|
||||
/* !!! FIXME: this screams for a SIMD shuffle operation. */
|
||||
@@ -299,31 +276,32 @@ static void swizzle_alsa_channels_6_##T(void *buffer, const Uint32 bufferlen) {
|
||||
* For Linux ALSA, this appears to be FL-FR-RL-RR-C-LFE-SL-SR
|
||||
* and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-SL-SR-RL-RR"
|
||||
*/
|
||||
#define SWIZ8(T) \
|
||||
static void swizzle_alsa_channels_8_##T(void *buffer, const Uint32 bufferlen) { \
|
||||
T *ptr = (T *) buffer; \
|
||||
Uint32 i; \
|
||||
for (i = 0; i < bufferlen; i++, ptr += 6) { \
|
||||
const T center = ptr[2]; \
|
||||
const T subwoofer = ptr[3]; \
|
||||
const T side_left = ptr[4]; \
|
||||
const T side_right = ptr[5]; \
|
||||
const T rear_left = ptr[6]; \
|
||||
const T rear_right = ptr[7]; \
|
||||
ptr[2] = rear_left; \
|
||||
ptr[3] = rear_right; \
|
||||
ptr[4] = center; \
|
||||
ptr[5] = subwoofer; \
|
||||
ptr[6] = side_left; \
|
||||
ptr[7] = side_right; \
|
||||
} \
|
||||
}
|
||||
#define SWIZ8(T) \
|
||||
static void swizzle_alsa_channels_8_##T(void *buffer, const Uint32 bufferlen) \
|
||||
{ \
|
||||
T *ptr = (T *)buffer; \
|
||||
Uint32 i; \
|
||||
for (i = 0; i < bufferlen; i++, ptr += 6) { \
|
||||
const T center = ptr[2]; \
|
||||
const T subwoofer = ptr[3]; \
|
||||
const T side_left = ptr[4]; \
|
||||
const T side_right = ptr[5]; \
|
||||
const T rear_left = ptr[6]; \
|
||||
const T rear_right = ptr[7]; \
|
||||
ptr[2] = rear_left; \
|
||||
ptr[3] = rear_right; \
|
||||
ptr[4] = center; \
|
||||
ptr[5] = subwoofer; \
|
||||
ptr[6] = side_left; \
|
||||
ptr[7] = side_right; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHANNEL_SWIZZLE(x) \
|
||||
x(Uint64) \
|
||||
x(Uint32) \
|
||||
x(Uint16) \
|
||||
x(Uint8)
|
||||
x(Uint64) \
|
||||
x(Uint32) \
|
||||
x(Uint16) \
|
||||
x(Uint8)
|
||||
|
||||
CHANNEL_SWIZZLE(SWIZ6)
|
||||
CHANNEL_SWIZZLE(SWIZ8)
|
||||
@@ -332,53 +310,59 @@ CHANNEL_SWIZZLE(SWIZ8)
|
||||
#undef SWIZ6
|
||||
#undef SWIZ8
|
||||
|
||||
|
||||
/*
|
||||
* Called right before feeding this->hidden->mixbuf to the hardware. Swizzle
|
||||
* channels from Windows/Mac order to the format alsalib will want.
|
||||
*/
|
||||
static void
|
||||
swizzle_alsa_channels(_THIS, void *buffer, Uint32 bufferlen)
|
||||
static void swizzle_alsa_channels(_THIS, void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
switch (this->spec.channels) {
|
||||
#define CHANSWIZ(chans) \
|
||||
case chans: \
|
||||
switch ((this->spec.format & (0xFF))) { \
|
||||
case 8: swizzle_alsa_channels_##chans##_Uint8(buffer, bufferlen); break; \
|
||||
case 16: swizzle_alsa_channels_##chans##_Uint16(buffer, bufferlen); break; \
|
||||
case 32: swizzle_alsa_channels_##chans##_Uint32(buffer, bufferlen); break; \
|
||||
case 64: swizzle_alsa_channels_##chans##_Uint64(buffer, bufferlen); break; \
|
||||
default: SDL_assert(!"unhandled bitsize"); break; \
|
||||
} \
|
||||
return;
|
||||
#define CHANSWIZ(chans) \
|
||||
case chans: \
|
||||
switch ((this->spec.format & (0xFF))) { \
|
||||
case 8: \
|
||||
swizzle_alsa_channels_##chans##_Uint8(buffer, bufferlen); \
|
||||
break; \
|
||||
case 16: \
|
||||
swizzle_alsa_channels_##chans##_Uint16(buffer, bufferlen); \
|
||||
break; \
|
||||
case 32: \
|
||||
swizzle_alsa_channels_##chans##_Uint32(buffer, bufferlen); \
|
||||
break; \
|
||||
case 64: \
|
||||
swizzle_alsa_channels_##chans##_Uint64(buffer, bufferlen); \
|
||||
break; \
|
||||
default: \
|
||||
SDL_assert(!"unhandled bitsize"); \
|
||||
break; \
|
||||
} \
|
||||
return;
|
||||
|
||||
CHANSWIZ(6);
|
||||
CHANSWIZ(8);
|
||||
#undef CHANSWIZ
|
||||
default: break;
|
||||
#undef CHANSWIZ
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SND_CHMAP_API_VERSION
|
||||
/* Some devices have the right channel map, no swizzling necessary */
|
||||
static void
|
||||
no_swizzle(_THIS, void *buffer, Uint32 bufferlen)
|
||||
static void no_swizzle(_THIS, void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
}
|
||||
#endif /* SND_CHMAP_API_VERSION */
|
||||
|
||||
|
||||
static void
|
||||
ALSA_PlayDevice(_THIS)
|
||||
static void ALSA_PlayDevice(_THIS)
|
||||
{
|
||||
const Uint8 *sample_buf = (const Uint8 *) this->hidden->mixbuf;
|
||||
const Uint8 *sample_buf = (const Uint8 *)this->hidden->mixbuf;
|
||||
const int frame_size = ((SDL_AUDIO_BITSIZE(this->spec.format)) / 8) *
|
||||
this->spec.channels;
|
||||
snd_pcm_uframes_t frames_left = ((snd_pcm_uframes_t) this->spec.samples);
|
||||
this->spec.channels;
|
||||
snd_pcm_uframes_t frames_left = ((snd_pcm_uframes_t)this->spec.samples);
|
||||
|
||||
this->hidden->swizzle_func(this, this->hidden->mixbuf, frames_left);
|
||||
|
||||
while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) {
|
||||
while (frames_left > 0 && SDL_AtomicGet(&this->enabled)) {
|
||||
int status = ALSA_snd_pcm_writei(this->hidden->pcm_handle,
|
||||
sample_buf, frames_left);
|
||||
|
||||
@@ -410,29 +394,27 @@ ALSA_PlayDevice(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
ALSA_GetDeviceBuf(_THIS)
|
||||
static Uint8 *ALSA_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return this->hidden->mixbuf;
|
||||
}
|
||||
|
||||
static int
|
||||
ALSA_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int ALSA_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
Uint8 *sample_buf = (Uint8 *) buffer;
|
||||
Uint8 *sample_buf = (Uint8 *)buffer;
|
||||
const int frame_size = ((SDL_AUDIO_BITSIZE(this->spec.format)) / 8) *
|
||||
this->spec.channels;
|
||||
this->spec.channels;
|
||||
const int total_frames = buflen / frame_size;
|
||||
snd_pcm_uframes_t frames_left = total_frames;
|
||||
snd_pcm_uframes_t wait_time = frame_size / 2;
|
||||
|
||||
SDL_assert((buflen % frame_size) == 0);
|
||||
|
||||
while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) {
|
||||
while (frames_left > 0 && SDL_AtomicGet(&this->enabled)) {
|
||||
int status;
|
||||
|
||||
status = ALSA_snd_pcm_readi(this->hidden->pcm_handle,
|
||||
sample_buf, frames_left);
|
||||
sample_buf, frames_left);
|
||||
|
||||
if (status == -EAGAIN) {
|
||||
ALSA_snd_pcm_wait(this->hidden->pcm_handle, wait_time);
|
||||
@@ -459,14 +441,12 @@ ALSA_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
return (total_frames - frames_left) * frame_size;
|
||||
}
|
||||
|
||||
static void
|
||||
ALSA_FlushCapture(_THIS)
|
||||
static void ALSA_FlushCapture(_THIS)
|
||||
{
|
||||
ALSA_snd_pcm_reset(this->hidden->pcm_handle);
|
||||
}
|
||||
|
||||
static void
|
||||
ALSA_CloseDevice(_THIS)
|
||||
static void ALSA_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->pcm_handle) {
|
||||
/* Wait for the submitted audio to drain
|
||||
@@ -481,8 +461,7 @@ ALSA_CloseDevice(_THIS)
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static int
|
||||
ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params)
|
||||
static int ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
int status;
|
||||
snd_pcm_hw_params_t *hwparams;
|
||||
@@ -496,49 +475,48 @@ ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params)
|
||||
/* Attempt to match the period size to the requested buffer size */
|
||||
persize = this->spec.samples;
|
||||
status = ALSA_snd_pcm_hw_params_set_period_size_near(
|
||||
this->hidden->pcm_handle, hwparams, &persize, NULL);
|
||||
if ( status < 0 ) {
|
||||
this->hidden->pcm_handle, hwparams, &persize, NULL);
|
||||
if (status < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Need to at least double buffer */
|
||||
periods = 2;
|
||||
status = ALSA_snd_pcm_hw_params_set_periods_min(
|
||||
this->hidden->pcm_handle, hwparams, &periods, NULL);
|
||||
if ( status < 0 ) {
|
||||
this->hidden->pcm_handle, hwparams, &periods, NULL);
|
||||
if (status < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = ALSA_snd_pcm_hw_params_set_periods_first(
|
||||
this->hidden->pcm_handle, hwparams, &periods, NULL);
|
||||
if ( status < 0 ) {
|
||||
this->hidden->pcm_handle, hwparams, &periods, NULL);
|
||||
if (status < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* "set" the hardware with the desired parameters */
|
||||
status = ALSA_snd_pcm_hw_params(this->hidden->pcm_handle, hwparams);
|
||||
if ( status < 0 ) {
|
||||
if (status < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
this->spec.samples = persize;
|
||||
|
||||
/* This is useful for debugging */
|
||||
if ( SDL_getenv("SDL_AUDIO_ALSA_DEBUG") ) {
|
||||
if (SDL_getenv("SDL_AUDIO_ALSA_DEBUG")) {
|
||||
snd_pcm_uframes_t bufsize;
|
||||
|
||||
ALSA_snd_pcm_hw_params_get_buffer_size(hwparams, &bufsize);
|
||||
|
||||
fprintf(stderr,
|
||||
"ALSA: period size = %ld, periods = %u, buffer size = %lu\n",
|
||||
persize, periods, bufsize);
|
||||
"ALSA: period size = %ld, periods = %u, buffer size = %lu\n",
|
||||
persize, periods, bufsize);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ALSA_OpenDevice(_THIS, const char *devname)
|
||||
static int ALSA_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
int status = 0;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
@@ -565,9 +543,9 @@ ALSA_OpenDevice(_THIS, const char *devname)
|
||||
/* Open the audio device */
|
||||
/* Name of device should depend on # channels in spec */
|
||||
status = ALSA_snd_pcm_open(&pcm_handle,
|
||||
get_audio_device(this->handle, this->spec.channels),
|
||||
iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
|
||||
SND_PCM_NONBLOCK);
|
||||
get_audio_device(this->handle, this->spec.channels),
|
||||
iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
|
||||
SND_PCM_NONBLOCK);
|
||||
|
||||
if (status < 0) {
|
||||
return SDL_SetError("ALSA: Couldn't open audio device: %s", ALSA_snd_strerror(status));
|
||||
@@ -704,18 +682,18 @@ ALSA_OpenDevice(_THIS, const char *devname)
|
||||
/* Allocate mixing buffer */
|
||||
if (!iscapture) {
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
|
||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
|
||||
}
|
||||
|
||||
#if !SDL_ALSA_NON_BLOCKING
|
||||
#if !SDL_ALSA_NON_BLOCKING
|
||||
if (!iscapture) {
|
||||
ALSA_snd_pcm_nonblock(pcm_handle, 0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* We're ready to rock and roll. :-) */
|
||||
return 0;
|
||||
@@ -728,10 +706,9 @@ typedef struct ALSA_Device
|
||||
struct ALSA_Device *next;
|
||||
} ALSA_Device;
|
||||
|
||||
static void
|
||||
add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSeen)
|
||||
static void add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSeen)
|
||||
{
|
||||
ALSA_Device *dev = SDL_malloc(sizeof (ALSA_Device));
|
||||
ALSA_Device *dev = SDL_malloc(sizeof(ALSA_Device));
|
||||
char *desc;
|
||||
char *handle = NULL;
|
||||
char *ptr;
|
||||
@@ -751,7 +728,7 @@ add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSee
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
desc = (char *) name;
|
||||
desc = (char *)name;
|
||||
}
|
||||
|
||||
SDL_assert(name != NULL);
|
||||
@@ -788,11 +765,9 @@ add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSee
|
||||
*pSeen = dev;
|
||||
}
|
||||
|
||||
|
||||
static ALSA_Device *hotplug_devices = NULL;
|
||||
|
||||
static void
|
||||
ALSA_HotplugIteration(void)
|
||||
static void ALSA_HotplugIteration(void)
|
||||
{
|
||||
void **hints = NULL;
|
||||
ALSA_Device *dev;
|
||||
@@ -807,7 +782,7 @@ ALSA_HotplugIteration(void)
|
||||
int bestmatch = 0xFFFF;
|
||||
size_t match_len = 0;
|
||||
int defaultdev = -1;
|
||||
static const char * const prefixes[] = {
|
||||
static const char *const prefixes[] = {
|
||||
"hw:", "sysdefault:", "default:", NULL
|
||||
};
|
||||
|
||||
@@ -850,7 +825,7 @@ ALSA_HotplugIteration(void)
|
||||
|
||||
/* if we didn't find a device name prefix we like at all... */
|
||||
if ((match == NULL) && (defaultdev != i)) {
|
||||
continue; /* ...skip anything that isn't the default device. */
|
||||
continue; /* ...skip anything that isn't the default device. */
|
||||
}
|
||||
|
||||
name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
|
||||
@@ -876,7 +851,7 @@ ALSA_HotplugIteration(void)
|
||||
prev = NULL;
|
||||
for (dev = unseen; dev; dev = next) {
|
||||
next = dev->next;
|
||||
if ( (SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture)) ) {
|
||||
if ((SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture))) {
|
||||
if (prev) {
|
||||
prev->next = next;
|
||||
} else {
|
||||
@@ -908,7 +883,7 @@ ALSA_HotplugIteration(void)
|
||||
|
||||
ALSA_snd_device_name_free_hint(hints);
|
||||
|
||||
hotplug_devices = seen; /* now we have a known-good list of attached devices. */
|
||||
hotplug_devices = seen; /* now we have a known-good list of attached devices. */
|
||||
|
||||
/* report anything still in unseen as removed. */
|
||||
for (dev = unseen; dev; dev = next) {
|
||||
@@ -925,8 +900,7 @@ ALSA_HotplugIteration(void)
|
||||
static SDL_atomic_t ALSA_hotplug_shutdown;
|
||||
static SDL_Thread *ALSA_hotplug_thread;
|
||||
|
||||
static int SDLCALL
|
||||
ALSA_HotplugThread(void *arg)
|
||||
static int SDLCALL ALSA_HotplugThread(void *arg)
|
||||
{
|
||||
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
|
||||
|
||||
@@ -937,17 +911,16 @@ ALSA_HotplugThread(void *arg)
|
||||
SDL_Delay(100);
|
||||
}
|
||||
|
||||
ALSA_HotplugIteration(); /* run the check. */
|
||||
ALSA_HotplugIteration(); /* run the check. */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ALSA_DetectDevices(void)
|
||||
static void ALSA_DetectDevices(void)
|
||||
{
|
||||
ALSA_HotplugIteration(); /* run once now before a thread continues to check. */
|
||||
ALSA_HotplugIteration(); /* run once now before a thread continues to check. */
|
||||
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
SDL_AtomicSet(&ALSA_hotplug_shutdown, 0);
|
||||
@@ -956,8 +929,7 @@ ALSA_DetectDevices(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
ALSA_Deinitialize(void)
|
||||
static void ALSA_Deinitialize(void)
|
||||
{
|
||||
ALSA_Device *dev;
|
||||
ALSA_Device *next;
|
||||
@@ -982,8 +954,7 @@ ALSA_Deinitialize(void)
|
||||
UnloadALSALibrary();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
ALSA_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool ALSA_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
if (LoadALSALibrary() < 0) {
|
||||
return SDL_FALSE;
|
||||
@@ -1003,10 +974,9 @@ ALSA_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->SupportsNonPow2Samples = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap ALSA_bootstrap = {
|
||||
"alsa", "ALSA PCM audio", ALSA_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
||||
@@ -31,11 +31,10 @@
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
static SDL_AudioDevice* audioDevice = NULL;
|
||||
static SDL_AudioDevice* captureDevice = NULL;
|
||||
static SDL_AudioDevice *audioDevice = NULL;
|
||||
static SDL_AudioDevice *captureDevice = NULL;
|
||||
|
||||
static int
|
||||
ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_AudioFormat test_format;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
@@ -49,7 +48,7 @@ ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
audioDevice = this;
|
||||
}
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, (sizeof *this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -77,32 +76,27 @@ ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ANDROIDAUDIO_PlayDevice(_THIS)
|
||||
static void ANDROIDAUDIO_PlayDevice(_THIS)
|
||||
{
|
||||
Android_JNI_WriteAudioBuffer();
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
ANDROIDAUDIO_GetDeviceBuf(_THIS)
|
||||
static Uint8 *ANDROIDAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return Android_JNI_GetAudioBuffer();
|
||||
}
|
||||
|
||||
static int
|
||||
ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
return Android_JNI_CaptureAudioBuffer(buffer, buflen);
|
||||
}
|
||||
|
||||
static void
|
||||
ANDROIDAUDIO_FlushCapture(_THIS)
|
||||
static void ANDROIDAUDIO_FlushCapture(_THIS)
|
||||
{
|
||||
Android_JNI_FlushCapturedAudio();
|
||||
}
|
||||
|
||||
static void
|
||||
ANDROIDAUDIO_CloseDevice(_THIS)
|
||||
static void ANDROIDAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
/* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread
|
||||
so it's safe to terminate the Java side buffer and AudioTrack
|
||||
@@ -118,8 +112,7 @@ ANDROIDAUDIO_CloseDevice(_THIS)
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool ANDROIDAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = ANDROIDAUDIO_OpenDevice;
|
||||
@@ -134,7 +127,7 @@ ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap ANDROIDAUDIO_bootstrap = {
|
||||
@@ -147,7 +140,7 @@ void ANDROIDAUDIO_PauseDevices(void)
|
||||
/* TODO: Handle multiple devices? */
|
||||
struct SDL_PrivateAudioData *private;
|
||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
|
||||
private = (struct SDL_PrivateAudioData *)audioDevice->hidden;
|
||||
if (SDL_AtomicGet(&audioDevice->paused)) {
|
||||
/* The device is already paused, leave it alone */
|
||||
private->resume = SDL_FALSE;
|
||||
@@ -159,7 +152,7 @@ void ANDROIDAUDIO_PauseDevices(void)
|
||||
}
|
||||
|
||||
if (captureDevice != NULL && captureDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
|
||||
private = (struct SDL_PrivateAudioData *)captureDevice->hidden;
|
||||
if (SDL_AtomicGet(&captureDevice->paused)) {
|
||||
/* The device is already paused, leave it alone */
|
||||
private->resume = SDL_FALSE;
|
||||
@@ -177,7 +170,7 @@ void ANDROIDAUDIO_ResumeDevices(void)
|
||||
/* TODO: Handle multiple devices? */
|
||||
struct SDL_PrivateAudioData *private;
|
||||
if (audioDevice != NULL && audioDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
|
||||
private = (struct SDL_PrivateAudioData *)audioDevice->hidden;
|
||||
if (private->resume) {
|
||||
SDL_AtomicSet(&audioDevice->paused, 0);
|
||||
private->resume = SDL_FALSE;
|
||||
@@ -186,7 +179,7 @@ void ANDROIDAUDIO_ResumeDevices(void)
|
||||
}
|
||||
|
||||
if (captureDevice != NULL && captureDevice->hidden != NULL) {
|
||||
private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
|
||||
private = (struct SDL_PrivateAudioData *)captureDevice->hidden;
|
||||
if (private->resume) {
|
||||
SDL_AtomicSet(&captureDevice->paused, 0);
|
||||
private->resume = SDL_FALSE;
|
||||
@@ -195,7 +188,7 @@ void ANDROIDAUDIO_ResumeDevices(void)
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#else
|
||||
|
||||
void ANDROIDAUDIO_ResumeDevices(void) {}
|
||||
void ANDROIDAUDIO_PauseDevices(void) {}
|
||||
@@ -203,4 +196,3 @@ void ANDROIDAUDIO_PauseDevices(void) {}
|
||||
#endif /* SDL_AUDIO_DRIVER_ANDROID */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#endif
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
||||
@@ -32,21 +32,20 @@
|
||||
#define DEBUG_COREAUDIO 0
|
||||
|
||||
#if DEBUG_COREAUDIO
|
||||
#define CHECK_RESULT(msg) \
|
||||
if (result != noErr) { \
|
||||
printf("COREAUDIO: Got error %d from '%s'!\n", (int) result, msg); \
|
||||
SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \
|
||||
return 0; \
|
||||
}
|
||||
#define CHECK_RESULT(msg) \
|
||||
if (result != noErr) { \
|
||||
printf("COREAUDIO: Got error %d from '%s'!\n", (int)result, msg); \
|
||||
SDL_SetError("CoreAudio error (%s): %d", msg, (int)result); \
|
||||
return 0; \
|
||||
}
|
||||
#else
|
||||
#define CHECK_RESULT(msg) \
|
||||
if (result != noErr) { \
|
||||
SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \
|
||||
return 0; \
|
||||
}
|
||||
#define CHECK_RESULT(msg) \
|
||||
if (result != noErr) { \
|
||||
SDL_SetError("CoreAudio error (%s): %d", msg, (int)result); \
|
||||
return 0; \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
static const AudioObjectPropertyAddress devlist_address = {
|
||||
kAudioHardwarePropertyDevices,
|
||||
@@ -66,10 +65,9 @@ typedef struct AudioDeviceList
|
||||
static AudioDeviceList *output_devs = NULL;
|
||||
static AudioDeviceList *capture_devs = NULL;
|
||||
|
||||
static SDL_bool
|
||||
add_to_internal_dev_list(const int iscapture, AudioDeviceID devId)
|
||||
static SDL_bool add_to_internal_dev_list(const int iscapture, AudioDeviceID devId)
|
||||
{
|
||||
AudioDeviceList *item = (AudioDeviceList *) SDL_malloc(sizeof (AudioDeviceList));
|
||||
AudioDeviceList *item = (AudioDeviceList *)SDL_malloc(sizeof(AudioDeviceList));
|
||||
if (item == NULL) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
@@ -85,16 +83,14 @@ add_to_internal_dev_list(const int iscapture, AudioDeviceID devId)
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
addToDevList(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data)
|
||||
static void addToDevList(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data)
|
||||
{
|
||||
if (add_to_internal_dev_list(iscapture, devId)) {
|
||||
SDL_AddAudioDevice(iscapture, name, spec, (void *) ((size_t) devId));
|
||||
SDL_AddAudioDevice(iscapture, name, spec, (void *)((size_t)devId));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
||||
static void build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
UInt32 size = 0;
|
||||
@@ -107,7 +103,7 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
||||
if (result != kAudioHardwareNoError)
|
||||
return;
|
||||
|
||||
devs = (AudioDeviceID *) alloca(size);
|
||||
devs = (AudioDeviceID *)alloca(size);
|
||||
if (devs == NULL)
|
||||
return;
|
||||
|
||||
@@ -116,7 +112,7 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
||||
if (result != kAudioHardwareNoError)
|
||||
return;
|
||||
|
||||
max = size / sizeof (AudioDeviceID);
|
||||
max = size / sizeof(AudioDeviceID);
|
||||
for (i = 0; i < max; i++) {
|
||||
CFStringRef cfstr = NULL;
|
||||
char *ptr = NULL;
|
||||
@@ -146,7 +142,7 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
||||
if (result != noErr)
|
||||
continue;
|
||||
|
||||
buflist = (AudioBufferList *) SDL_malloc(size);
|
||||
buflist = (AudioBufferList *)SDL_malloc(size);
|
||||
if (buflist == NULL)
|
||||
continue;
|
||||
|
||||
@@ -166,13 +162,13 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
||||
if (spec.channels == 0)
|
||||
continue;
|
||||
|
||||
size = sizeof (sampleRate);
|
||||
size = sizeof(sampleRate);
|
||||
result = AudioObjectGetPropertyData(dev, &freqaddr, 0, NULL, &size, &sampleRate);
|
||||
if (result == noErr) {
|
||||
spec.freq = (int) sampleRate;
|
||||
spec.freq = (int)sampleRate;
|
||||
}
|
||||
|
||||
size = sizeof (CFStringRef);
|
||||
size = sizeof(CFStringRef);
|
||||
result = AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr);
|
||||
if (result != kAudioHardwareNoError)
|
||||
continue;
|
||||
@@ -180,10 +176,9 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
||||
len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
|
||||
kCFStringEncodingUTF8);
|
||||
|
||||
ptr = (char *) SDL_malloc(len + 1);
|
||||
ptr = (char *)SDL_malloc(len + 1);
|
||||
usable = ((ptr != NULL) &&
|
||||
(CFStringGetCString
|
||||
(cfstr, ptr, len + 1, kCFStringEncodingUTF8)));
|
||||
(CFStringGetCString(cfstr, ptr, len + 1, kCFStringEncodingUTF8)));
|
||||
|
||||
CFRelease(cfstr);
|
||||
|
||||
@@ -202,16 +197,15 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
||||
#if DEBUG_COREAUDIO
|
||||
printf("COREAUDIO: Found %s device #%d: '%s' (devid %d)\n",
|
||||
((iscapture) ? "capture" : "output"),
|
||||
(int) i, ptr, (int) dev);
|
||||
(int)i, ptr, (int)dev);
|
||||
#endif
|
||||
addfn(ptr, &spec, iscapture, dev, addfndata);
|
||||
}
|
||||
SDL_free(ptr); /* addfn() would have copied the string. */
|
||||
SDL_free(ptr); /* addfn() would have copied the string. */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_audio_device_list(AudioDeviceList **list)
|
||||
static void free_audio_device_list(AudioDeviceList **list)
|
||||
{
|
||||
AudioDeviceList *item = *list;
|
||||
while (item) {
|
||||
@@ -222,17 +216,15 @@ free_audio_device_list(AudioDeviceList **list)
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
COREAUDIO_DetectDevices(void)
|
||||
static void COREAUDIO_DetectDevices(void)
|
||||
{
|
||||
build_device_list(SDL_TRUE, addToDevList, NULL);
|
||||
build_device_list(SDL_FALSE, addToDevList, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
build_device_change_list(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data)
|
||||
static void build_device_change_list(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data)
|
||||
{
|
||||
AudioDeviceList **list = (AudioDeviceList **) data;
|
||||
AudioDeviceList **list = (AudioDeviceList **)data;
|
||||
AudioDeviceList *item;
|
||||
for (item = *list; item != NULL; item = item->next) {
|
||||
if (item->devid == devId) {
|
||||
@@ -241,12 +233,11 @@ build_device_change_list(const char *name, SDL_AudioSpec *spec, const int iscapt
|
||||
}
|
||||
}
|
||||
|
||||
add_to_internal_dev_list(iscapture, devId); /* new device, add it. */
|
||||
SDL_AddAudioDevice(iscapture, name, spec, (void *) ((size_t) devId));
|
||||
add_to_internal_dev_list(iscapture, devId); /* new device, add it. */
|
||||
SDL_AddAudioDevice(iscapture, name, spec, (void *)((size_t)devId));
|
||||
}
|
||||
|
||||
static void
|
||||
reprocess_device_list(const int iscapture, AudioDeviceList **list)
|
||||
static void reprocess_device_list(const int iscapture, AudioDeviceList **list)
|
||||
{
|
||||
AudioDeviceList *item;
|
||||
AudioDeviceList *prev = NULL;
|
||||
@@ -263,7 +254,7 @@ reprocess_device_list(const int iscapture, AudioDeviceList **list)
|
||||
if (item->alive) {
|
||||
prev = item;
|
||||
} else {
|
||||
SDL_RemoveAudioDevice(iscapture, (void *) ((size_t) item->devid));
|
||||
SDL_RemoveAudioDevice(iscapture, (void *)((size_t)item->devid));
|
||||
if (prev) {
|
||||
prev->next = item->next;
|
||||
} else {
|
||||
@@ -276,8 +267,7 @@ reprocess_device_list(const int iscapture, AudioDeviceList **list)
|
||||
}
|
||||
|
||||
/* this is called when the system's list of available audio devices changes. */
|
||||
static OSStatus
|
||||
device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data)
|
||||
static OSStatus device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data)
|
||||
{
|
||||
reprocess_device_list(SDL_TRUE, &capture_devs);
|
||||
reprocess_device_list(SDL_FALSE, &output_devs);
|
||||
@@ -285,7 +275,6 @@ device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectP
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int open_playback_devices;
|
||||
static int open_capture_devices;
|
||||
static int num_open_devices;
|
||||
@@ -337,16 +326,14 @@ static void interruption_begin(_THIS)
|
||||
|
||||
static void interruption_end(_THIS)
|
||||
{
|
||||
if (this != NULL && this->hidden != NULL && this->hidden->audioQueue != NULL
|
||||
&& this->hidden->interrupted
|
||||
&& AudioQueueStart(this->hidden->audioQueue, NULL) == AVAudioSessionErrorCodeNone) {
|
||||
if (this != NULL && this->hidden != NULL && this->hidden->audioQueue != NULL && this->hidden->interrupted && AudioQueueStart(this->hidden->audioQueue, NULL) == AVAudioSessionErrorCodeNone) {
|
||||
this->hidden->interrupted = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@interface SDLInterruptionListener : NSObject
|
||||
|
||||
@property (nonatomic, assign) SDL_AudioDevice *device;
|
||||
@property(nonatomic, assign) SDL_AudioDevice *device;
|
||||
|
||||
@end
|
||||
|
||||
@@ -354,7 +341,7 @@ static void interruption_end(_THIS)
|
||||
|
||||
- (void)audioSessionInterruption:(NSNotification *)note
|
||||
{
|
||||
@synchronized (self) {
|
||||
@synchronized(self) {
|
||||
NSNumber *type = note.userInfo[AVAudioSessionInterruptionTypeKey];
|
||||
if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan) {
|
||||
interruption_begin(self.device);
|
||||
@@ -366,7 +353,7 @@ static void interruption_end(_THIS)
|
||||
|
||||
- (void)applicationBecameActive:(NSNotification *)note
|
||||
{
|
||||
@synchronized (self) {
|
||||
@synchronized(self) {
|
||||
interruption_end(self.device);
|
||||
}
|
||||
}
|
||||
@@ -502,9 +489,9 @@ static BOOL update_audio_session(_THIS, SDL_bool open, SDL_bool allow_playandrec
|
||||
this->hidden->interruption_listener = CFBridgingRetain(listener);
|
||||
} else {
|
||||
SDLInterruptionListener *listener = nil;
|
||||
listener = (SDLInterruptionListener *) CFBridgingRelease(this->hidden->interruption_listener);
|
||||
listener = (SDLInterruptionListener *)CFBridgingRelease(this->hidden->interruption_listener);
|
||||
[center removeObserver:listener];
|
||||
@synchronized (listener) {
|
||||
@synchronized(listener) {
|
||||
listener.device = NULL;
|
||||
}
|
||||
}
|
||||
@@ -514,25 +501,23 @@ static BOOL update_audio_session(_THIS, SDL_bool open, SDL_bool allow_playandrec
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* The AudioQueue callback */
|
||||
static void
|
||||
outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
|
||||
static void outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
|
||||
{
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData;
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *)inUserData;
|
||||
|
||||
/* This flag is set before this->mixer_lock is destroyed during
|
||||
shutdown, so check it before grabbing the mutex, and then check it
|
||||
again _after_ in case we blocked waiting on the lock. */
|
||||
if (SDL_AtomicGet(&this->shutdown)) {
|
||||
return; /* don't do anything, since we don't even want to enqueue this buffer again. */
|
||||
return; /* don't do anything, since we don't even want to enqueue this buffer again. */
|
||||
}
|
||||
|
||||
SDL_LockMutex(this->mixer_lock);
|
||||
|
||||
if (SDL_AtomicGet(&this->shutdown)) {
|
||||
SDL_UnlockMutex(this->mixer_lock);
|
||||
return; /* don't do anything, since we don't even want to enqueue this buffer again. */
|
||||
return; /* don't do anything, since we don't even want to enqueue this buffer again. */
|
||||
}
|
||||
|
||||
if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
|
||||
@@ -540,7 +525,7 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
|
||||
SDL_memset(inBuffer->mAudioData, this->spec.silence, inBuffer->mAudioDataBytesCapacity);
|
||||
} else if (this->stream) {
|
||||
UInt32 remaining = inBuffer->mAudioDataBytesCapacity;
|
||||
Uint8 *ptr = (Uint8 *) inBuffer->mAudioData;
|
||||
Uint8 *ptr = (Uint8 *)inBuffer->mAudioData;
|
||||
|
||||
while (remaining > 0) {
|
||||
if (SDL_AudioStreamAvailable(this->stream) == 0) {
|
||||
@@ -566,14 +551,14 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
|
||||
}
|
||||
} else {
|
||||
UInt32 remaining = inBuffer->mAudioDataBytesCapacity;
|
||||
Uint8 *ptr = (Uint8 *) inBuffer->mAudioData;
|
||||
Uint8 *ptr = (Uint8 *)inBuffer->mAudioData;
|
||||
|
||||
while (remaining > 0) {
|
||||
UInt32 len;
|
||||
if (this->hidden->bufferOffset >= this->hidden->bufferSize) {
|
||||
/* Generate the data */
|
||||
(*this->callbackspec.callback)(this->callbackspec.userdata,
|
||||
this->hidden->buffer, this->hidden->bufferSize);
|
||||
this->hidden->buffer, this->hidden->bufferSize);
|
||||
this->hidden->bufferOffset = 0;
|
||||
}
|
||||
|
||||
@@ -581,8 +566,7 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
|
||||
if (len > remaining) {
|
||||
len = remaining;
|
||||
}
|
||||
SDL_memcpy(ptr, (char *)this->hidden->buffer +
|
||||
this->hidden->bufferOffset, len);
|
||||
SDL_memcpy(ptr, (char *)this->hidden->buffer + this->hidden->bufferOffset, len);
|
||||
ptr = ptr + len;
|
||||
remaining -= len;
|
||||
this->hidden->bufferOffset += len;
|
||||
@@ -596,20 +580,19 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
|
||||
SDL_UnlockMutex(this->mixer_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer,
|
||||
const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions,
|
||||
const AudioStreamPacketDescription *inPacketDescs)
|
||||
static void inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer,
|
||||
const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions,
|
||||
const AudioStreamPacketDescription *inPacketDescs)
|
||||
{
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData;
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *)inUserData;
|
||||
|
||||
if (SDL_AtomicGet(&this->shutdown)) {
|
||||
return; /* don't do anything. */
|
||||
return; /* don't do anything. */
|
||||
}
|
||||
|
||||
/* ignore unless we're active. */
|
||||
if (!SDL_AtomicGet(&this->paused) && SDL_AtomicGet(&this->enabled)) {
|
||||
const Uint8 *ptr = (const Uint8 *) inBuffer->mAudioData;
|
||||
const Uint8 *ptr = (const Uint8 *)inBuffer->mAudioData;
|
||||
UInt32 remaining = inBuffer->mAudioDataByteSize;
|
||||
while (remaining > 0) {
|
||||
UInt32 len = this->hidden->bufferSize - this->hidden->bufferOffset;
|
||||
@@ -634,35 +617,32 @@ inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer
|
||||
AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
static const AudioObjectPropertyAddress alive_address =
|
||||
{
|
||||
static const AudioObjectPropertyAddress alive_address = {
|
||||
kAudioDevicePropertyDeviceIsAlive,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMain
|
||||
};
|
||||
|
||||
static OSStatus
|
||||
device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data)
|
||||
static OSStatus device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data)
|
||||
{
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) data;
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *)data;
|
||||
SDL_bool dead = SDL_FALSE;
|
||||
UInt32 isAlive = 1;
|
||||
UInt32 size = sizeof (isAlive);
|
||||
UInt32 size = sizeof(isAlive);
|
||||
OSStatus error;
|
||||
|
||||
if (!SDL_AtomicGet(&this->enabled)) {
|
||||
return 0; /* already known to be dead. */
|
||||
return 0; /* already known to be dead. */
|
||||
}
|
||||
|
||||
error = AudioObjectGetPropertyData(this->hidden->deviceID, &alive_address,
|
||||
0, NULL, &size, &isAlive);
|
||||
|
||||
if (error == kAudioHardwareBadDeviceError) {
|
||||
dead = SDL_TRUE; /* device was unplugged. */
|
||||
dead = SDL_TRUE; /* device was unplugged. */
|
||||
} else if ((error == kAudioHardwareNoError) && (!isAlive)) {
|
||||
dead = SDL_TRUE; /* device died in some other way. */
|
||||
dead = SDL_TRUE; /* device died in some other way. */
|
||||
}
|
||||
|
||||
if (dead) {
|
||||
@@ -673,20 +653,18 @@ device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectProperty
|
||||
}
|
||||
|
||||
/* macOS calls this when the default device changed (if we have a default device open). */
|
||||
static OSStatus
|
||||
default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inUserData)
|
||||
static OSStatus default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inUserData)
|
||||
{
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData;
|
||||
#if DEBUG_COREAUDIO
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *)inUserData;
|
||||
#if DEBUG_COREAUDIO
|
||||
printf("COREAUDIO: default device changed for SDL audio device %p!\n", this);
|
||||
#endif
|
||||
SDL_AtomicSet(&this->hidden->device_change_flag, 1); /* let the audioqueue thread pick up on this when safe to do so. */
|
||||
#endif
|
||||
SDL_AtomicSet(&this->hidden->device_change_flag, 1); /* let the audioqueue thread pick up on this when safe to do so. */
|
||||
return noErr;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
COREAUDIO_CloseDevice(_THIS)
|
||||
static void COREAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
const SDL_bool iscapture = this->iscapture;
|
||||
int i;
|
||||
@@ -694,7 +672,7 @@ COREAUDIO_CloseDevice(_THIS)
|
||||
/* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */
|
||||
/* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */
|
||||
#if MACOSX_COREAUDIO
|
||||
if (this->handle != NULL) { /* we don't register this listener for default devices. */
|
||||
if (this->handle != NULL) { /* we don't register this listener for default devices. */
|
||||
AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
|
||||
}
|
||||
#endif
|
||||
@@ -708,7 +686,7 @@ COREAUDIO_CloseDevice(_THIS)
|
||||
}
|
||||
|
||||
if (this->hidden->thread) {
|
||||
SDL_assert(SDL_AtomicGet(&this->shutdown) != 0); /* should have been set by SDL_audio.c */
|
||||
SDL_assert(SDL_AtomicGet(&this->shutdown) != 0); /* should have been set by SDL_audio.c */
|
||||
SDL_WaitThread(this->hidden->thread, NULL);
|
||||
}
|
||||
|
||||
@@ -726,7 +704,7 @@ COREAUDIO_CloseDevice(_THIS)
|
||||
if (open_devices[i] == this) {
|
||||
--num_open_devices;
|
||||
if (i < num_open_devices) {
|
||||
SDL_memmove(&open_devices[i], &open_devices[i+1], sizeof(open_devices[i])*(num_open_devices - i));
|
||||
SDL_memmove(&open_devices[i], &open_devices[i + 1], sizeof(open_devices[i]) * (num_open_devices - i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -748,12 +726,11 @@ COREAUDIO_CloseDevice(_THIS)
|
||||
}
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
static int
|
||||
prepare_device(_THIS)
|
||||
static int prepare_device(_THIS)
|
||||
{
|
||||
void *handle = this->handle;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
AudioDeviceID devid = (AudioDeviceID) ((size_t) handle);
|
||||
AudioDeviceID devid = (AudioDeviceID)((size_t)handle);
|
||||
OSStatus result = noErr;
|
||||
UInt32 size = 0;
|
||||
UInt32 alive = 0;
|
||||
@@ -766,23 +743,20 @@ prepare_device(_THIS)
|
||||
};
|
||||
|
||||
if (handle == NULL) {
|
||||
size = sizeof (AudioDeviceID);
|
||||
size = sizeof(AudioDeviceID);
|
||||
addr.mSelector =
|
||||
((iscapture) ? kAudioHardwarePropertyDefaultInputDevice :
|
||||
kAudioHardwarePropertyDefaultOutputDevice);
|
||||
((iscapture) ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice);
|
||||
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
|
||||
0, NULL, &size, &devid);
|
||||
CHECK_RESULT("AudioHardwareGetProperty (default device)");
|
||||
}
|
||||
|
||||
addr.mSelector = kAudioDevicePropertyDeviceIsAlive;
|
||||
addr.mScope = iscapture ? kAudioDevicePropertyScopeInput :
|
||||
kAudioDevicePropertyScopeOutput;
|
||||
addr.mScope = iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
|
||||
|
||||
size = sizeof (alive);
|
||||
size = sizeof(alive);
|
||||
result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive);
|
||||
CHECK_RESULT
|
||||
("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
|
||||
CHECK_RESULT("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
|
||||
|
||||
if (!alive) {
|
||||
SDL_SetError("CoreAudio: requested device exists, but isn't alive.");
|
||||
@@ -790,7 +764,7 @@ prepare_device(_THIS)
|
||||
}
|
||||
|
||||
addr.mSelector = kAudioDevicePropertyHogMode;
|
||||
size = sizeof (pid);
|
||||
size = sizeof(pid);
|
||||
result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid);
|
||||
|
||||
/* some devices don't support this property, so errors are fine here. */
|
||||
@@ -803,8 +777,7 @@ prepare_device(_THIS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
assign_device_to_audioqueue(_THIS)
|
||||
static int assign_device_to_audioqueue(_THIS)
|
||||
{
|
||||
const AudioObjectPropertyAddress prop = {
|
||||
kAudioDevicePropertyDeviceUID,
|
||||
@@ -814,7 +787,7 @@ assign_device_to_audioqueue(_THIS)
|
||||
|
||||
OSStatus result;
|
||||
CFStringRef devuid;
|
||||
UInt32 devuidsize = sizeof (devuid);
|
||||
UInt32 devuidsize = sizeof(devuid);
|
||||
result = AudioObjectGetPropertyData(this->hidden->deviceID, &prop, 0, NULL, &devuidsize, &devuid);
|
||||
CHECK_RESULT("AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID)");
|
||||
result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize);
|
||||
@@ -824,8 +797,7 @@ assign_device_to_audioqueue(_THIS)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
prepare_audioqueue(_THIS)
|
||||
static int prepare_audioqueue(_THIS)
|
||||
{
|
||||
const AudioStreamBasicDescription *strdesc = &this->hidden->strdesc;
|
||||
const int iscapture = this->iscapture;
|
||||
@@ -833,7 +805,8 @@ prepare_audioqueue(_THIS)
|
||||
int i, numAudioBuffers = 2;
|
||||
AudioChannelLayout layout;
|
||||
double MINIMUM_AUDIO_BUFFER_TIME_MS;
|
||||
const double msecs = (this->spec.samples / ((double) this->spec.freq)) * 1000.0;;
|
||||
const double msecs = (this->spec.samples / ((double)this->spec.freq)) * 1000.0;
|
||||
;
|
||||
|
||||
SDL_assert(CFRunLoopGetCurrent() != NULL);
|
||||
|
||||
@@ -845,7 +818,7 @@ prepare_audioqueue(_THIS)
|
||||
CHECK_RESULT("AudioQueueNewOutput");
|
||||
}
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#if MACOSX_COREAUDIO
|
||||
if (!assign_device_to_audioqueue(this)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -859,7 +832,7 @@ prepare_audioqueue(_THIS)
|
||||
/* If this fails, oh well, we won't notice a device had an extraordinary event take place. */
|
||||
AudioObjectAddPropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Calculate the final parameters for this audio specification */
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
@@ -916,12 +889,12 @@ prepare_audioqueue(_THIS)
|
||||
MINIMUM_AUDIO_BUFFER_TIME_MS = 40.0;
|
||||
}
|
||||
#endif
|
||||
if (msecs < MINIMUM_AUDIO_BUFFER_TIME_MS) { /* use more buffers if we have a VERY small sample set. */
|
||||
if (msecs < MINIMUM_AUDIO_BUFFER_TIME_MS) { /* use more buffers if we have a VERY small sample set. */
|
||||
numAudioBuffers = ((int)SDL_ceil(MINIMUM_AUDIO_BUFFER_TIME_MS / msecs) * 2);
|
||||
}
|
||||
|
||||
this->hidden->numAudioBuffers = numAudioBuffers;
|
||||
this->hidden->audioBuffer = SDL_calloc(1, sizeof (AudioQueueBufferRef) * numAudioBuffers);
|
||||
this->hidden->audioBuffer = SDL_calloc(1, sizeof(AudioQueueBufferRef) * numAudioBuffers);
|
||||
if (this->hidden->audioBuffer == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return 0;
|
||||
@@ -948,24 +921,23 @@ prepare_audioqueue(_THIS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
audioqueue_thread(void *arg)
|
||||
static int audioqueue_thread(void *arg)
|
||||
{
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *)arg;
|
||||
int rc;
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#if MACOSX_COREAUDIO
|
||||
const AudioObjectPropertyAddress default_device_address = {
|
||||
this->iscapture ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMain
|
||||
};
|
||||
|
||||
if (this->handle == NULL) { /* opened the default device? Register to know if the user picks a new default. */
|
||||
if (this->handle == NULL) { /* opened the default device? Register to know if the user picks a new default. */
|
||||
/* we don't care if this fails; we just won't change to new default devices, but we still otherwise function in this case. */
|
||||
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &default_device_address, default_device_changed, this);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
rc = prepare_audioqueue(this);
|
||||
if (!rc) {
|
||||
@@ -982,14 +954,14 @@ audioqueue_thread(void *arg)
|
||||
while (!SDL_AtomicGet(&this->shutdown)) {
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1);
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#if MACOSX_COREAUDIO
|
||||
if ((this->handle == NULL) && SDL_AtomicGet(&this->hidden->device_change_flag)) {
|
||||
const AudioDeviceID prev_devid = this->hidden->deviceID;
|
||||
SDL_AtomicSet(&this->hidden->device_change_flag, 0);
|
||||
|
||||
#if DEBUG_COREAUDIO
|
||||
#if DEBUG_COREAUDIO
|
||||
printf("COREAUDIO: audioqueue_thread is trying to switch to new default device!\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* if any of this fails, there's not much to do but wait to see if the user gives up
|
||||
and quits (flagging the audioqueue for shutdown), or toggles to some other system
|
||||
@@ -1007,26 +979,25 @@ audioqueue_thread(void *arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!this->iscapture) { /* Drain off any pending playback. */
|
||||
const CFTimeInterval secs = (((this->spec.size / (SDL_AUDIO_BITSIZE(this->spec.format) / 8)) / this->spec.channels) / ((CFTimeInterval) this->spec.freq)) * 2.0;
|
||||
if (!this->iscapture) { /* Drain off any pending playback. */
|
||||
const CFTimeInterval secs = (((this->spec.size / (SDL_AUDIO_BITSIZE(this->spec.format) / 8)) / this->spec.channels) / ((CFTimeInterval)this->spec.freq)) * 2.0;
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, secs, 0);
|
||||
}
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
#if MACOSX_COREAUDIO
|
||||
if (this->handle == NULL) {
|
||||
/* we don't care if this fails; we just won't change to new default devices, but we still otherwise function in this case. */
|
||||
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_device_address, default_device_changed, this);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
COREAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int COREAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
AudioStreamBasicDescription *strdesc;
|
||||
SDL_AudioFormat test_format;
|
||||
@@ -1062,7 +1033,7 @@ COREAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
|
||||
/* Stop CoreAudio from doing expensive audio rate conversion */
|
||||
@autoreleasepool {
|
||||
AVAudioSession* session = [AVAudioSession sharedInstance];
|
||||
AVAudioSession *session = [AVAudioSession sharedInstance];
|
||||
[session setPreferredSampleRate:this->spec.freq error:nil];
|
||||
this->spec.freq = (int)session.sampleRate;
|
||||
#if TARGET_OS_TV
|
||||
@@ -1106,7 +1077,7 @@ COREAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!test_format) { /* shouldn't happen, but just in case... */
|
||||
if (!test_format) { /* shouldn't happen, but just in case... */
|
||||
return SDL_SetError("%s: Unsupported audio format", "coreaudio");
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
@@ -1131,7 +1102,7 @@ COREAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
/* This has to init in a new thread so it can get its own CFRunLoop. :/ */
|
||||
this->hidden->ready_semaphore = SDL_CreateSemaphore(0);
|
||||
if (!this->hidden->ready_semaphore) {
|
||||
return -1; /* oh well. */
|
||||
return -1; /* oh well. */
|
||||
}
|
||||
|
||||
this->hidden->thread = SDL_CreateThreadInternal(audioqueue_thread, "AudioQueue thread", 512 * 1024, this);
|
||||
@@ -1151,10 +1122,9 @@ COREAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
|
||||
#if !MACOSX_COREAUDIO
|
||||
static int
|
||||
COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
static int COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
AVAudioSession* session = [AVAudioSession sharedInstance];
|
||||
AVAudioSession *session = [AVAudioSession sharedInstance];
|
||||
|
||||
if (name != NULL) {
|
||||
*name = NULL;
|
||||
@@ -1164,9 +1134,8 @@ COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
spec->channels = [session outputNumberOfChannels];
|
||||
return 0;
|
||||
}
|
||||
#else /* MACOSX_COREAUDIO */
|
||||
static int
|
||||
COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
#else /* MACOSX_COREAUDIO */
|
||||
static int COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
AudioDeviceID devid;
|
||||
AudioBufferList *buflist;
|
||||
@@ -1205,7 +1174,7 @@ COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
|
||||
/* Get the Device ID */
|
||||
cfstr = NULL;
|
||||
size = sizeof (AudioDeviceID);
|
||||
size = sizeof(AudioDeviceID);
|
||||
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
|
||||
0, NULL, &size, &devid);
|
||||
|
||||
@@ -1215,7 +1184,7 @@ COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
|
||||
if (name != NULL) {
|
||||
/* Use the Device ID to get the name */
|
||||
size = sizeof (CFStringRef);
|
||||
size = sizeof(CFStringRef);
|
||||
result = AudioObjectGetPropertyData(devid, &nameaddr, 0, NULL, &size, &cfstr);
|
||||
|
||||
if (result != noErr) {
|
||||
@@ -1223,8 +1192,8 @@ COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
}
|
||||
|
||||
len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
|
||||
kCFStringEncodingUTF8);
|
||||
devname = (char *) SDL_malloc(len + 1);
|
||||
kCFStringEncodingUTF8);
|
||||
devname = (char *)SDL_malloc(len + 1);
|
||||
usable = ((devname != NULL) &&
|
||||
(CFStringGetCString(cfstr, devname, len + 1, kCFStringEncodingUTF8)));
|
||||
CFRelease(cfstr);
|
||||
@@ -1256,13 +1225,13 @@ COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
return SDL_SetError("%s: Default Device Sample Rate not found", "coreaudio");
|
||||
}
|
||||
|
||||
spec->freq = (int) sampleRate;
|
||||
spec->freq = (int)sampleRate;
|
||||
|
||||
result = AudioObjectGetPropertyDataSize(devid, &bufaddr, 0, NULL, &size);
|
||||
if (result != noErr)
|
||||
return SDL_SetError("%s: Default Device Data Size not found", "coreaudio");
|
||||
|
||||
buflist = (AudioBufferList *) SDL_malloc(size);
|
||||
buflist = (AudioBufferList *)SDL_malloc(size);
|
||||
if (buflist == NULL)
|
||||
return SDL_SetError("%s: Default Device Buffer List not found", "coreaudio");
|
||||
|
||||
@@ -1286,8 +1255,7 @@ COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
}
|
||||
#endif /* MACOSX_COREAUDIO */
|
||||
|
||||
static void
|
||||
COREAUDIO_Deinitialize(void)
|
||||
static void COREAUDIO_Deinitialize(void)
|
||||
{
|
||||
#if MACOSX_COREAUDIO
|
||||
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
|
||||
@@ -1296,8 +1264,7 @@ COREAUDIO_Deinitialize(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
COREAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool COREAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = COREAUDIO_OpenDevice;
|
||||
@@ -1317,7 +1284,7 @@ COREAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->SupportsNonPow2Samples = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap COREAUDIO_bootstrap = {
|
||||
|
||||
@@ -41,21 +41,20 @@ static SDL_bool SupportsIMMDevice = SDL_FALSE;
|
||||
#endif /* HAVE_MMDEVICEAPI_H */
|
||||
|
||||
/* DirectX function pointers for audio */
|
||||
static void* DSoundDLL = NULL;
|
||||
typedef HRESULT (WINAPI *fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
|
||||
typedef HRESULT (WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
|
||||
typedef HRESULT (WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID,LPDIRECTSOUNDCAPTURE8 *,LPUNKNOWN);
|
||||
typedef HRESULT (WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID);
|
||||
static void *DSoundDLL = NULL;
|
||||
typedef HRESULT(WINAPI *fnDirectSoundCreate8)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
|
||||
typedef HRESULT(WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
|
||||
typedef HRESULT(WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID, LPDIRECTSOUNDCAPTURE8 *, LPUNKNOWN);
|
||||
typedef HRESULT(WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
|
||||
static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL;
|
||||
static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL;
|
||||
static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL;
|
||||
static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL;
|
||||
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
|
||||
static void
|
||||
DSOUND_Unload(void)
|
||||
static void DSOUND_Unload(void)
|
||||
{
|
||||
pDirectSoundCreate8 = NULL;
|
||||
pDirectSoundEnumerateW = NULL;
|
||||
@@ -68,9 +67,7 @@ DSOUND_Unload(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
DSOUND_Load(void)
|
||||
static int DSOUND_Load(void)
|
||||
{
|
||||
int loaded = 0;
|
||||
|
||||
@@ -80,17 +77,19 @@ DSOUND_Load(void)
|
||||
if (DSoundDLL == NULL) {
|
||||
SDL_SetError("DirectSound: failed to load DSOUND.DLL");
|
||||
} else {
|
||||
/* Now make sure we have DirectX 8 or better... */
|
||||
#define DSOUNDLOAD(f) { \
|
||||
p##f = (fn##f) SDL_LoadFunction(DSoundDLL, #f); \
|
||||
if (!p##f) loaded = 0; \
|
||||
}
|
||||
loaded = 1; /* will reset if necessary. */
|
||||
/* Now make sure we have DirectX 8 or better... */
|
||||
#define DSOUNDLOAD(f) \
|
||||
{ \
|
||||
p##f = (fn##f)SDL_LoadFunction(DSoundDLL, #f); \
|
||||
if (!p##f) \
|
||||
loaded = 0; \
|
||||
}
|
||||
loaded = 1; /* will reset if necessary. */
|
||||
DSOUNDLOAD(DirectSoundCreate8);
|
||||
DSOUNDLOAD(DirectSoundEnumerateW);
|
||||
DSOUNDLOAD(DirectSoundCaptureCreate8);
|
||||
DSOUNDLOAD(DirectSoundCaptureEnumerateW);
|
||||
#undef DSOUNDLOAD
|
||||
#undef DSOUNDLOAD
|
||||
|
||||
if (!loaded) {
|
||||
SDL_SetError("DirectSound: System doesn't appear to have DX8.");
|
||||
@@ -104,8 +103,7 @@ DSOUND_Load(void)
|
||||
return loaded;
|
||||
}
|
||||
|
||||
static int
|
||||
SetDSerror(const char *function, int code)
|
||||
static int SetDSerror(const char *function, int code)
|
||||
{
|
||||
const char *error;
|
||||
|
||||
@@ -151,14 +149,12 @@ SetDSerror(const char *function, int code)
|
||||
return SDL_SetError("%s: %s (0x%x)", function, error, code);
|
||||
}
|
||||
|
||||
static void
|
||||
DSOUND_FreeDeviceHandle(void *handle)
|
||||
static void DSOUND_FreeDeviceHandle(void *handle)
|
||||
{
|
||||
SDL_free(handle);
|
||||
}
|
||||
|
||||
static int
|
||||
DSOUND_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
static int DSOUND_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
#if HAVE_MMDEVICEAPI_H
|
||||
if (SupportsIMMDevice) {
|
||||
@@ -168,29 +164,27 @@ DSOUND_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static BOOL CALLBACK
|
||||
FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
|
||||
static BOOL CALLBACK FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
|
||||
{
|
||||
const int iscapture = (int) ((size_t) data);
|
||||
if (guid != NULL) { /* skip default device */
|
||||
const int iscapture = (int)((size_t)data);
|
||||
if (guid != NULL) { /* skip default device */
|
||||
char *str = WIN_LookupAudioDeviceName(desc, guid);
|
||||
if (str != NULL) {
|
||||
LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID));
|
||||
SDL_memcpy(cpyguid, guid, sizeof (GUID));
|
||||
LPGUID cpyguid = (LPGUID)SDL_malloc(sizeof(GUID));
|
||||
SDL_memcpy(cpyguid, guid, sizeof(GUID));
|
||||
|
||||
/* Note that spec is NULL, because we are required to connect to the
|
||||
* device before getting the channel mask and output format, making
|
||||
* this information inaccessible at enumeration time
|
||||
*/
|
||||
SDL_AddAudioDevice(iscapture, str, NULL, cpyguid);
|
||||
SDL_free(str); /* addfn() makes a copy of this string. */
|
||||
SDL_free(str); /* addfn() makes a copy of this string. */
|
||||
}
|
||||
}
|
||||
return TRUE; /* keep enumerating. */
|
||||
return TRUE; /* keep enumerating. */
|
||||
}
|
||||
|
||||
static void
|
||||
DSOUND_DetectDevices(void)
|
||||
static void DSOUND_DetectDevices(void)
|
||||
{
|
||||
#if HAVE_MMDEVICEAPI_H
|
||||
if (SupportsIMMDevice) {
|
||||
@@ -204,9 +198,7 @@ DSOUND_DetectDevices(void)
|
||||
#endif /* HAVE_MMDEVICEAPI_H*/
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
DSOUND_WaitDevice(_THIS)
|
||||
static void DSOUND_WaitDevice(_THIS)
|
||||
{
|
||||
DWORD status = 0;
|
||||
DWORD cursor = 0;
|
||||
@@ -263,8 +255,7 @@ DSOUND_WaitDevice(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DSOUND_PlayDevice(_THIS)
|
||||
static void DSOUND_PlayDevice(_THIS)
|
||||
{
|
||||
/* Unlock the buffer, allowing it to play */
|
||||
if (this->hidden->locked_buf) {
|
||||
@@ -274,8 +265,7 @@ DSOUND_PlayDevice(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
DSOUND_GetDeviceBuf(_THIS)
|
||||
static Uint8 *DSOUND_GetDeviceBuf(_THIS)
|
||||
{
|
||||
DWORD cursor = 0;
|
||||
DWORD junk = 0;
|
||||
@@ -316,14 +306,13 @@ DSOUND_GetDeviceBuf(_THIS)
|
||||
/* Lock the audio buffer */
|
||||
result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor,
|
||||
this->spec.size,
|
||||
(LPVOID *) & this->hidden->locked_buf,
|
||||
(LPVOID *)&this->hidden->locked_buf,
|
||||
&rawlen, NULL, &junk, 0);
|
||||
if (result == DSERR_BUFFERLOST) {
|
||||
IDirectSoundBuffer_Restore(this->hidden->mixbuf);
|
||||
result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor,
|
||||
this->spec.size,
|
||||
(LPVOID *) & this->
|
||||
hidden->locked_buf, &rawlen, NULL,
|
||||
(LPVOID *)&this->hidden->locked_buf, &rawlen, NULL,
|
||||
&junk, 0);
|
||||
}
|
||||
if (result != DS_OK) {
|
||||
@@ -333,8 +322,7 @@ DSOUND_GetDeviceBuf(_THIS)
|
||||
return this->hidden->locked_buf;
|
||||
}
|
||||
|
||||
static int
|
||||
DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
DWORD junk, cursor, ptr1len, ptr2len;
|
||||
@@ -343,7 +331,7 @@ DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
SDL_assert(buflen == this->spec.size);
|
||||
|
||||
while (SDL_TRUE) {
|
||||
if (SDL_AtomicGet(&this->shutdown)) { /* in case the buffer froze... */
|
||||
if (SDL_AtomicGet(&this->shutdown)) { /* in case the buffer froze... */
|
||||
SDL_memset(buffer, this->spec.silence, buflen);
|
||||
return buflen;
|
||||
}
|
||||
@@ -352,7 +340,7 @@ DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
return -1;
|
||||
}
|
||||
if ((cursor / this->spec.size) == h->lastchunk) {
|
||||
SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */
|
||||
SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -377,8 +365,7 @@ DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
return ptr1len;
|
||||
}
|
||||
|
||||
static void
|
||||
DSOUND_FlushCapture(_THIS)
|
||||
static void DSOUND_FlushCapture(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
DWORD junk, cursor;
|
||||
@@ -387,8 +374,7 @@ DSOUND_FlushCapture(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DSOUND_CloseDevice(_THIS)
|
||||
static void DSOUND_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->mixbuf != NULL) {
|
||||
IDirectSoundBuffer_Stop(this->hidden->mixbuf);
|
||||
@@ -411,8 +397,7 @@ DSOUND_CloseDevice(_THIS)
|
||||
number of audio chunks available in the created buffer. This is for
|
||||
playback devices, not capture.
|
||||
*/
|
||||
static int
|
||||
CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
||||
static int CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
||||
{
|
||||
LPDIRECTSOUND sndObj = this->hidden->sound;
|
||||
LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf;
|
||||
@@ -436,14 +421,14 @@ CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
||||
|
||||
/* Silence the initial audio buffer */
|
||||
result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes,
|
||||
(LPVOID *) & pvAudioPtr1, &dwAudioBytes1,
|
||||
(LPVOID *) & pvAudioPtr2, &dwAudioBytes2,
|
||||
(LPVOID *)&pvAudioPtr1, &dwAudioBytes1,
|
||||
(LPVOID *)&pvAudioPtr2, &dwAudioBytes2,
|
||||
DSBLOCK_ENTIREBUFFER);
|
||||
if (result == DS_OK) {
|
||||
SDL_memset(pvAudioPtr1, this->spec.silence, dwAudioBytes1);
|
||||
IDirectSoundBuffer_Unlock(*sndbuf,
|
||||
(LPVOID) pvAudioPtr1, dwAudioBytes1,
|
||||
(LPVOID) pvAudioPtr2, dwAudioBytes2);
|
||||
(LPVOID)pvAudioPtr1, dwAudioBytes1,
|
||||
(LPVOID)pvAudioPtr2, dwAudioBytes2);
|
||||
}
|
||||
|
||||
/* We're ready to go */
|
||||
@@ -454,8 +439,7 @@ CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
||||
number of audio chunks available in the created buffer. This is for
|
||||
capture devices, not playback.
|
||||
*/
|
||||
static int
|
||||
CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
||||
static int CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
||||
{
|
||||
LPDIRECTSOUNDCAPTURE capture = this->hidden->capture;
|
||||
LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &this->hidden->capturebuf;
|
||||
@@ -463,7 +447,7 @@ CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
||||
HRESULT result;
|
||||
|
||||
SDL_zero(format);
|
||||
format.dwSize = sizeof (format);
|
||||
format.dwSize = sizeof(format);
|
||||
format.dwFlags = DSCBCAPS_WAVEMAPPED;
|
||||
format.dwBufferBytes = bufsize;
|
||||
format.lpwfxFormat = wfmt;
|
||||
@@ -494,15 +478,14 @@ CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
DSOUND_OpenDevice(_THIS, const char *devname)
|
||||
static int DSOUND_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
const DWORD numchunks = 8;
|
||||
HRESULT result;
|
||||
SDL_bool tried_format = SDL_FALSE;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
SDL_AudioFormat test_format;
|
||||
LPGUID guid = (LPGUID) this->handle;
|
||||
LPGUID guid = (LPGUID)this->handle;
|
||||
DWORD bufsize;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
@@ -548,8 +531,8 @@ DSOUND_OpenDevice(_THIS, const char *devname)
|
||||
bufsize = numchunks * this->spec.size;
|
||||
if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) {
|
||||
SDL_SetError("Sound buffer size must be between %d and %d",
|
||||
(int) ((DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks),
|
||||
(int) (DSBSIZE_MAX / numchunks));
|
||||
(int)((DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks),
|
||||
(int)(DSBSIZE_MAX / numchunks));
|
||||
} else {
|
||||
int rc;
|
||||
WAVEFORMATEXTENSIBLE wfmt;
|
||||
@@ -565,8 +548,7 @@ DSOUND_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
wfmt.Samples.wValidBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
|
||||
|
||||
switch (this->spec.channels)
|
||||
{
|
||||
switch (this->spec.channels) {
|
||||
case 3: /* 3.0 (or 2.1) */
|
||||
wfmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER;
|
||||
break;
|
||||
@@ -601,7 +583,7 @@ DSOUND_OpenDevice(_THIS, const char *devname)
|
||||
wfmt.Format.nBlockAlign = wfmt.Format.nChannels * (wfmt.Format.wBitsPerSample / 8);
|
||||
wfmt.Format.nAvgBytesPerSec = wfmt.Format.nSamplesPerSec * wfmt.Format.nBlockAlign;
|
||||
|
||||
rc = iscapture ? CreateCaptureBuffer(this, bufsize, (WAVEFORMATEX*) &wfmt) : CreateSecondary(this, bufsize, (WAVEFORMATEX*) &wfmt);
|
||||
rc = iscapture ? CreateCaptureBuffer(this, bufsize, (WAVEFORMATEX *)&wfmt) : CreateSecondary(this, bufsize, (WAVEFORMATEX *)&wfmt);
|
||||
if (rc == 0) {
|
||||
this->hidden->num_buffers = numchunks;
|
||||
break;
|
||||
@@ -616,19 +598,17 @@ DSOUND_OpenDevice(_THIS, const char *devname)
|
||||
|
||||
if (!test_format) {
|
||||
if (tried_format) {
|
||||
return -1; /* CreateSecondary() should have called SDL_SetError(). */
|
||||
return -1; /* CreateSecondary() should have called SDL_SetError(). */
|
||||
}
|
||||
return SDL_SetError("%s: Unsupported audio format", "directsound");
|
||||
}
|
||||
|
||||
/* Playback buffers will auto-start playing in DSOUND_WaitDevice() */
|
||||
|
||||
return 0; /* good to go. */
|
||||
return 0; /* good to go. */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
DSOUND_Deinitialize(void)
|
||||
static void DSOUND_Deinitialize(void)
|
||||
{
|
||||
#if HAVE_MMDEVICEAPI_H
|
||||
if (SupportsIMMDevice) {
|
||||
@@ -639,9 +619,7 @@ DSOUND_Deinitialize(void)
|
||||
DSOUND_Unload();
|
||||
}
|
||||
|
||||
|
||||
static SDL_bool
|
||||
DSOUND_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool DSOUND_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
if (!DSOUND_Load()) {
|
||||
return SDL_FALSE;
|
||||
@@ -667,7 +645,7 @@ DSOUND_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->SupportsNonPow2Samples = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap DSOUND_bootstrap = {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
/* The DirectSound objects */
|
||||
struct SDL_PrivateAudioData
|
||||
|
||||
@@ -33,21 +33,19 @@
|
||||
|
||||
/* !!! FIXME: these should be SDL hints, not environment variables. */
|
||||
/* environment variables and defaults. */
|
||||
#define DISKENVR_OUTFILE "SDL_DISKAUDIOFILE"
|
||||
#define DISKDEFAULT_OUTFILE "sdlaudio.raw"
|
||||
#define DISKENVR_INFILE "SDL_DISKAUDIOFILEIN"
|
||||
#define DISKDEFAULT_INFILE "sdlaudio-in.raw"
|
||||
#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY"
|
||||
#define DISKENVR_OUTFILE "SDL_DISKAUDIOFILE"
|
||||
#define DISKDEFAULT_OUTFILE "sdlaudio.raw"
|
||||
#define DISKENVR_INFILE "SDL_DISKAUDIOFILEIN"
|
||||
#define DISKDEFAULT_INFILE "sdlaudio-in.raw"
|
||||
#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY"
|
||||
|
||||
/* This function waits until it is possible to write a full sound buffer */
|
||||
static void
|
||||
DISKAUDIO_WaitDevice(_THIS)
|
||||
static void DISKAUDIO_WaitDevice(_THIS)
|
||||
{
|
||||
SDL_Delay(_this->hidden->io_delay);
|
||||
}
|
||||
|
||||
static void
|
||||
DISKAUDIO_PlayDevice(_THIS)
|
||||
static void DISKAUDIO_PlayDevice(_THIS)
|
||||
{
|
||||
const size_t written = SDL_RWwrite(_this->hidden->io,
|
||||
_this->hidden->mixbuf,
|
||||
@@ -62,14 +60,12 @@ DISKAUDIO_PlayDevice(_THIS)
|
||||
#endif
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
DISKAUDIO_GetDeviceBuf(_THIS)
|
||||
static Uint8 *DISKAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return _this->hidden->mixbuf;
|
||||
}
|
||||
|
||||
static int
|
||||
DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = _this->hidden;
|
||||
const int origbuflen = buflen;
|
||||
@@ -78,9 +74,9 @@ DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
|
||||
if (h->io) {
|
||||
const size_t br = SDL_RWread(h->io, buffer, 1, buflen);
|
||||
buflen -= (int) br;
|
||||
buffer = ((Uint8 *) buffer) + br;
|
||||
if (buflen > 0) { /* EOF (or error, but whatever). */
|
||||
buflen -= (int)br;
|
||||
buffer = ((Uint8 *)buffer) + br;
|
||||
if (buflen > 0) { /* EOF (or error, but whatever). */
|
||||
SDL_RWclose(h->io);
|
||||
h->io = NULL;
|
||||
}
|
||||
@@ -92,15 +88,12 @@ DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
return origbuflen;
|
||||
}
|
||||
|
||||
static void
|
||||
DISKAUDIO_FlushCapture(_THIS)
|
||||
static void DISKAUDIO_FlushCapture(_THIS)
|
||||
{
|
||||
/* no op...we don't advance the file pointer or anything. */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
DISKAUDIO_CloseDevice(_THIS)
|
||||
static void DISKAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (_this->hidden->io != NULL) {
|
||||
SDL_RWclose(_this->hidden->io);
|
||||
@@ -109,9 +102,7 @@ DISKAUDIO_CloseDevice(_THIS)
|
||||
SDL_free(_this->hidden);
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
get_filename(const SDL_bool iscapture, const char *devname)
|
||||
static const char *get_filename(const SDL_bool iscapture, const char *devname)
|
||||
{
|
||||
if (devname == NULL) {
|
||||
devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE);
|
||||
@@ -122,8 +113,7 @@ get_filename(const SDL_bool iscapture, const char *devname)
|
||||
return devname;
|
||||
}
|
||||
|
||||
static int
|
||||
DISKAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int DISKAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
void *handle = _this->handle;
|
||||
/* handle != NULL means "user specified the placeholder name on the fake detected device list" */
|
||||
@@ -152,7 +142,7 @@ DISKAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
|
||||
/* Allocate mixing buffer */
|
||||
if (!iscapture) {
|
||||
_this->hidden->mixbuf = (Uint8 *) SDL_malloc(_this->spec.size);
|
||||
_this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->spec.size);
|
||||
if (_this->hidden->mixbuf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -160,24 +150,22 @@ DISKAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO,
|
||||
"You are using the SDL disk i/o audio driver!\n");
|
||||
"You are using the SDL disk i/o audio driver!\n");
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO,
|
||||
" %s file [%s].\n", iscapture ? "Reading from" : "Writing to",
|
||||
fname);
|
||||
" %s file [%s].\n", iscapture ? "Reading from" : "Writing to",
|
||||
fname);
|
||||
|
||||
/* We're ready to rock and roll. :-) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
DISKAUDIO_DetectDevices(void)
|
||||
static void DISKAUDIO_DetectDevices(void)
|
||||
{
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *) 0x1);
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *) 0x2);
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)0x1);
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)0x2);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
DISKAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool DISKAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = DISKAUDIO_OpenDevice;
|
||||
@@ -194,7 +182,7 @@ DISKAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->SupportsNonPow2Samples = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap DISKAUDIO_bootstrap = {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
#include <stdio.h> /* For perror() */
|
||||
#include <string.h> /* For strerror() */
|
||||
#include <stdio.h> /* For perror() */
|
||||
#include <string.h> /* For strerror() */
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
@@ -40,16 +40,12 @@
|
||||
#include "../SDL_audiodev_c.h"
|
||||
#include "SDL_dspaudio.h"
|
||||
|
||||
|
||||
static void
|
||||
DSP_DetectDevices(void)
|
||||
static void DSP_DetectDevices(void)
|
||||
{
|
||||
SDL_EnumUnixAudioDevices(0, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
DSP_CloseDevice(_THIS)
|
||||
static void DSP_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->audio_fd >= 0) {
|
||||
close(this->hidden->audio_fd);
|
||||
@@ -58,9 +54,7 @@ DSP_CloseDevice(_THIS)
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
DSP_OpenDevice(_THIS, const char *devname)
|
||||
static int DSP_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
|
||||
@@ -203,11 +197,12 @@ DSP_OpenDevice(_THIS, const char *devname)
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
/* Determine the power of two of the fragment size */
|
||||
for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec);
|
||||
for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec)
|
||||
;
|
||||
if ((0x01U << frag_spec) != this->spec.size) {
|
||||
return SDL_SetError("Fragment size must be a power of two");
|
||||
}
|
||||
frag_spec |= 0x00020000; /* two fragments, for low latency */
|
||||
frag_spec |= 0x00020000; /* two fragments, for low latency */
|
||||
|
||||
/* Set the audio buffering parameters */
|
||||
#ifdef DEBUG_AUDIO
|
||||
@@ -231,7 +226,7 @@ DSP_OpenDevice(_THIS, const char *devname)
|
||||
/* Allocate mixing buffer */
|
||||
if (!iscapture) {
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
|
||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -242,9 +237,7 @@ DSP_OpenDevice(_THIS, const char *devname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
DSP_PlayDevice(_THIS)
|
||||
static void DSP_PlayDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
if (write(h->audio_fd, h->mixbuf, h->mixlen) == -1) {
|
||||
@@ -256,27 +249,24 @@ DSP_PlayDevice(_THIS)
|
||||
#endif
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
DSP_GetDeviceBuf(_THIS)
|
||||
static Uint8 *DSP_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return this->hidden->mixbuf;
|
||||
}
|
||||
|
||||
static int
|
||||
DSP_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int DSP_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
return (int)read(this->hidden->audio_fd, buffer, buflen);
|
||||
}
|
||||
|
||||
static void
|
||||
DSP_FlushCapture(_THIS)
|
||||
static void DSP_FlushCapture(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
audio_buf_info info;
|
||||
if (ioctl(h->audio_fd, SNDCTL_DSP_GETISPACE, &info) == 0) {
|
||||
while (info.bytes > 0) {
|
||||
char buf[512];
|
||||
const size_t len = SDL_min(sizeof (buf), info.bytes);
|
||||
const size_t len = SDL_min(sizeof(buf), info.bytes);
|
||||
const ssize_t br = read(h->audio_fd, buf, len);
|
||||
if (br <= 0) {
|
||||
break;
|
||||
@@ -287,22 +277,20 @@ DSP_FlushCapture(_THIS)
|
||||
}
|
||||
|
||||
static SDL_bool InitTimeDevicesExist = SDL_FALSE;
|
||||
static int
|
||||
look_for_devices_test(int fd)
|
||||
static int look_for_devices_test(int fd)
|
||||
{
|
||||
InitTimeDevicesExist = SDL_TRUE; /* note that _something_ exists. */
|
||||
InitTimeDevicesExist = SDL_TRUE; /* note that _something_ exists. */
|
||||
/* Don't add to the device list, we're just seeing if any devices exist. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
DSP_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool DSP_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
InitTimeDevicesExist = SDL_FALSE;
|
||||
SDL_EnumUnixAudioDevices(0, look_for_devices_test);
|
||||
if (!InitTimeDevicesExist) {
|
||||
SDL_SetError("dsp: No such audio device");
|
||||
return SDL_FALSE; /* maybe try a different backend. */
|
||||
return SDL_FALSE; /* maybe try a different backend. */
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
@@ -317,10 +305,9 @@ DSP_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap DSP_bootstrap = {
|
||||
"dsp", "OSS /dev/dsp standard audio", DSP_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
@@ -37,7 +37,7 @@ struct SDL_PrivateAudioData
|
||||
Uint8 *mixbuf;
|
||||
int mixlen;
|
||||
};
|
||||
#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */
|
||||
#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */
|
||||
|
||||
#endif /* SDL_dspaudio_h_ */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -25,15 +25,14 @@
|
||||
#include "../SDL_audio_c.h"
|
||||
#include "SDL_dummyaudio.h"
|
||||
|
||||
static int
|
||||
DUMMYAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int DUMMYAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
_this->hidden = (void *) 0x1; /* just something non-NULL */
|
||||
return 0; /* always succeeds. */
|
||||
_this->hidden = (void *)0x1; /* just something non-NULL */
|
||||
|
||||
return 0; /* always succeeds. */
|
||||
}
|
||||
|
||||
static int
|
||||
DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
/* Delay to make this sort of simulate real audio input. */
|
||||
SDL_Delay((_this->spec.samples * 1000) / _this->spec.freq);
|
||||
@@ -43,8 +42,7 @@ DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
return buflen;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
DUMMYAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool DUMMYAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = DUMMYAUDIO_OpenDevice;
|
||||
@@ -54,7 +52,7 @@ DUMMYAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap DUMMYAUDIO_bootstrap = {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
||||
@@ -32,10 +32,10 @@
|
||||
!!! FIXME: true always once pthread support becomes widespread. Revisit this code
|
||||
!!! FIXME: at some point and see what needs to be done for that! */
|
||||
|
||||
static void
|
||||
FeedAudioDevice(_THIS, const void *buf, const int buflen)
|
||||
static void FeedAudioDevice(_THIS, const void *buf, const int buflen)
|
||||
{
|
||||
const int framelen = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels;
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
MAIN_THREAD_EM_ASM({
|
||||
var SDL3 = Module['SDL3'];
|
||||
var numChannels = SDL3.audio.currentOutputBuffer['numberOfChannels'];
|
||||
@@ -50,10 +50,10 @@ FeedAudioDevice(_THIS, const void *buf, const int buflen)
|
||||
}
|
||||
}
|
||||
}, buf, buflen / framelen);
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
}
|
||||
|
||||
static void
|
||||
HandleAudioProcess(_THIS)
|
||||
static void HandleAudioProcess(_THIS)
|
||||
{
|
||||
SDL_AudioCallback callback = this->callbackspec.callback;
|
||||
const int stream_len = this->callbackspec.size;
|
||||
@@ -69,12 +69,12 @@ HandleAudioProcess(_THIS)
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->stream == NULL) { /* no conversion necessary. */
|
||||
if (this->stream == NULL) { /* no conversion necessary. */
|
||||
SDL_assert(this->spec.size == stream_len);
|
||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len);
|
||||
} else { /* streaming/converting */
|
||||
} else { /* streaming/converting */
|
||||
int got;
|
||||
while (SDL_AudioStreamAvailable(this->stream) < ((int) this->spec.size)) {
|
||||
while (SDL_AudioStreamAvailable(this->stream) < ((int)this->spec.size)) {
|
||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len);
|
||||
if (SDL_AudioStreamPut(this->stream, this->work_buffer, stream_len) == -1) {
|
||||
SDL_AudioStreamClear(this->stream);
|
||||
@@ -93,8 +93,7 @@ HandleAudioProcess(_THIS)
|
||||
FeedAudioDevice(this, this->work_buffer, this->spec.size);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleCaptureProcess(_THIS)
|
||||
static void HandleCaptureProcess(_THIS)
|
||||
{
|
||||
SDL_AudioCallback callback = this->callbackspec.callback;
|
||||
const int stream_len = this->callbackspec.size;
|
||||
@@ -105,6 +104,7 @@ HandleCaptureProcess(_THIS)
|
||||
return;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
MAIN_THREAD_EM_ASM({
|
||||
var SDL3 = Module['SDL3'];
|
||||
var numChannels = SDL3.capture.currentCaptureBuffer.numberOfChannels;
|
||||
@@ -125,13 +125,14 @@ HandleCaptureProcess(_THIS)
|
||||
}
|
||||
}
|
||||
}, this->work_buffer, (this->spec.size / sizeof (float)) / this->spec.channels);
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
/* okay, we've got an interleaved float32 array in C now. */
|
||||
|
||||
if (this->stream == NULL) { /* no conversion necessary. */
|
||||
if (this->stream == NULL) { /* no conversion necessary. */
|
||||
SDL_assert(this->spec.size == stream_len);
|
||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len);
|
||||
} else { /* streaming/converting */
|
||||
} else { /* streaming/converting */
|
||||
if (SDL_AudioStreamPut(this->stream, this->work_buffer, this->spec.size) == -1) {
|
||||
SDL_AtomicSet(&this->enabled, 0);
|
||||
}
|
||||
@@ -142,15 +143,14 @@ HandleCaptureProcess(_THIS)
|
||||
if (got != stream_len) {
|
||||
SDL_memset(this->work_buffer, this->callbackspec.silence, stream_len);
|
||||
}
|
||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len); /* Send it to the app. */
|
||||
callback(this->callbackspec.userdata, this->work_buffer, stream_len); /* Send it to the app. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
EMSCRIPTENAUDIO_CloseDevice(_THIS)
|
||||
static void EMSCRIPTENAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
MAIN_THREAD_EM_ASM({
|
||||
var SDL3 = Module['SDL3'];
|
||||
if ($0) {
|
||||
@@ -189,14 +189,14 @@ EMSCRIPTENAUDIO_CloseDevice(_THIS)
|
||||
SDL3.audioContext = undefined;
|
||||
}
|
||||
}, this->iscapture);
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL3 namespace? --ryan. */
|
||||
#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL3 namespace? --ryan. */
|
||||
SDL_free(this->hidden);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_AudioFormat test_format;
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
@@ -204,6 +204,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
|
||||
/* based on parts of library_sdl.js */
|
||||
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
/* create context */
|
||||
result = MAIN_THREAD_EM_ASM_INT({
|
||||
if (typeof(Module['SDL3']) === 'undefined') {
|
||||
@@ -228,6 +229,8 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
return SDL3.audioContext === undefined ? -1 : 0;
|
||||
}, iscapture);
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
if (result < 0) {
|
||||
return SDL_SetError("Web Audio API is not available!");
|
||||
}
|
||||
@@ -249,7 +252,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
this->spec.format = test_format;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL3 namespace? --ryan. */
|
||||
#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL3 namespace? --ryan. */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc((sizeof *this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
@@ -261,12 +264,13 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
|
||||
/* limit to native freq */
|
||||
this->spec.freq = EM_ASM_INT_V({
|
||||
var SDL3 = Module['SDL3'];
|
||||
return SDL3.audioContext.sampleRate;
|
||||
var SDL3 = Module['SDL3'];
|
||||
return SDL3.audioContext.sampleRate;
|
||||
});
|
||||
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
if (iscapture) {
|
||||
/* The idea is to take the capture media stream, hook it up to an
|
||||
audio graph where we can pass it through a ScriptProcessorNode
|
||||
@@ -338,17 +342,16 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
SDL3.audio.scriptProcessorNode['connect'](SDL3.audioContext['destination']);
|
||||
}, this->spec.channels, this->spec.samples, HandleAudioProcess, this);
|
||||
}
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device)
|
||||
static void EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice *device)
|
||||
{
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
SDL_bool available, capture_available;
|
||||
|
||||
@@ -362,6 +365,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->LockDevice = impl->UnlockDevice = EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock;
|
||||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
/* check availability */
|
||||
available = MAIN_THREAD_EM_ASM_INT({
|
||||
if (typeof(AudioContext) !== 'undefined') {
|
||||
@@ -371,11 +375,13 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
}
|
||||
return false;
|
||||
});
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
if (!available) {
|
||||
SDL_SetError("No audio context available");
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
capture_available = available && MAIN_THREAD_EM_ASM_INT({
|
||||
if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) {
|
||||
return true;
|
||||
@@ -384,6 +390,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
}
|
||||
return false;
|
||||
});
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
impl->HasCaptureSupport = capture_available ? SDL_TRUE : SDL_FALSE;
|
||||
impl->OnlyHasDefaultCaptureDevice = capture_available ? SDL_TRUE : SDL_FALSE;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
||||
@@ -41,8 +41,7 @@ extern "C"
|
||||
|
||||
/* !!! FIXME: have the callback call the higher level to avoid code dupe. */
|
||||
/* The Haiku callback for handling the audio buffer */
|
||||
static void
|
||||
FillSound(void *device, void *stream, size_t len,
|
||||
static void FillSound(void *device, void *stream, size_t len,
|
||||
const media_raw_audio_format & format)
|
||||
{
|
||||
SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
|
||||
@@ -84,8 +83,7 @@ FillSound(void *device, void *stream, size_t len,
|
||||
SDL_UnlockMutex(audio->mixer_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
HAIKUAUDIO_CloseDevice(_THIS)
|
||||
static void HAIKUAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (_this->hidden->audio_obj) {
|
||||
_this->hidden->audio_obj->Stop();
|
||||
@@ -99,8 +97,7 @@ static const int sig_list[] = {
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGWINCH, 0
|
||||
};
|
||||
|
||||
static inline void
|
||||
MaskSignals(sigset_t * omask)
|
||||
static inline void MaskSignals(sigset_t * omask)
|
||||
{
|
||||
sigset_t mask;
|
||||
int i;
|
||||
@@ -112,15 +109,13 @@ MaskSignals(sigset_t * omask)
|
||||
sigprocmask(SIG_BLOCK, &mask, omask);
|
||||
}
|
||||
|
||||
static inline void
|
||||
UnmaskSignals(sigset_t * omask)
|
||||
static inline void UnmaskSignals(sigset_t * omask)
|
||||
{
|
||||
sigprocmask(SIG_SETMASK, omask, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
HAIKUAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int HAIKUAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
media_raw_audio_format format;
|
||||
SDL_AudioFormat test_format;
|
||||
@@ -207,14 +202,12 @@ HAIKUAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
HAIKUAUDIO_Deinitialize(void)
|
||||
static void HAIKUAUDIO_Deinitialize(void)
|
||||
{
|
||||
SDL_QuitBeApp();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HAIKUAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool HAIKUAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Initialize the Be Application, if it's not already started */
|
||||
if (SDL_InitBeApp() < 0) {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
||||
@@ -26,36 +26,33 @@
|
||||
#include "SDL_jackaudio.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
|
||||
|
||||
static jack_client_t * (*JACK_jack_client_open) (const char *, jack_options_t, jack_status_t *, ...);
|
||||
static int (*JACK_jack_client_close) (jack_client_t *);
|
||||
static void (*JACK_jack_on_shutdown) (jack_client_t *, JackShutdownCallback, void *);
|
||||
static int (*JACK_jack_activate) (jack_client_t *);
|
||||
static int (*JACK_jack_deactivate) (jack_client_t *);
|
||||
static void * (*JACK_jack_port_get_buffer) (jack_port_t *, jack_nframes_t);
|
||||
static int (*JACK_jack_port_unregister) (jack_client_t *, jack_port_t *);
|
||||
static void (*JACK_jack_free) (void *);
|
||||
static const char ** (*JACK_jack_get_ports) (jack_client_t *, const char *, const char *, unsigned long);
|
||||
static jack_nframes_t (*JACK_jack_get_sample_rate) (jack_client_t *);
|
||||
static jack_nframes_t (*JACK_jack_get_buffer_size) (jack_client_t *);
|
||||
static jack_port_t * (*JACK_jack_port_register) (jack_client_t *, const char *, const char *, unsigned long, unsigned long);
|
||||
static jack_port_t * (*JACK_jack_port_by_name) (jack_client_t *, const char *);
|
||||
static const char * (*JACK_jack_port_name) (const jack_port_t *);
|
||||
static const char * (*JACK_jack_port_type) (const jack_port_t *);
|
||||
static int (*JACK_jack_connect) (jack_client_t *, const char *, const char *);
|
||||
static int (*JACK_jack_set_process_callback) (jack_client_t *, JackProcessCallback, void *);
|
||||
static jack_client_t *(*JACK_jack_client_open)(const char *, jack_options_t, jack_status_t *, ...);
|
||||
static int (*JACK_jack_client_close)(jack_client_t *);
|
||||
static void (*JACK_jack_on_shutdown)(jack_client_t *, JackShutdownCallback, void *);
|
||||
static int (*JACK_jack_activate)(jack_client_t *);
|
||||
static int (*JACK_jack_deactivate)(jack_client_t *);
|
||||
static void *(*JACK_jack_port_get_buffer)(jack_port_t *, jack_nframes_t);
|
||||
static int (*JACK_jack_port_unregister)(jack_client_t *, jack_port_t *);
|
||||
static void (*JACK_jack_free)(void *);
|
||||
static const char **(*JACK_jack_get_ports)(jack_client_t *, const char *, const char *, unsigned long);
|
||||
static jack_nframes_t (*JACK_jack_get_sample_rate)(jack_client_t *);
|
||||
static jack_nframes_t (*JACK_jack_get_buffer_size)(jack_client_t *);
|
||||
static jack_port_t *(*JACK_jack_port_register)(jack_client_t *, const char *, const char *, unsigned long, unsigned long);
|
||||
static jack_port_t *(*JACK_jack_port_by_name)(jack_client_t *, const char *);
|
||||
static const char *(*JACK_jack_port_name)(const jack_port_t *);
|
||||
static const char *(*JACK_jack_port_type)(const jack_port_t *);
|
||||
static int (*JACK_jack_connect)(jack_client_t *, const char *, const char *);
|
||||
static int (*JACK_jack_set_process_callback)(jack_client_t *, JackProcessCallback, void *);
|
||||
|
||||
static int load_jack_syms(void);
|
||||
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_JACK_DYNAMIC
|
||||
|
||||
static const char *jack_library = SDL_AUDIO_DRIVER_JACK_DYNAMIC;
|
||||
static void *jack_handle = NULL;
|
||||
|
||||
/* !!! FIXME: this is copy/pasted in several places now */
|
||||
static int
|
||||
load_jack_sym(const char *fn, void **addr)
|
||||
static int load_jack_sym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(jack_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
@@ -67,11 +64,11 @@ load_jack_sym(const char *fn, void **addr)
|
||||
}
|
||||
|
||||
/* cast funcs to char* first, to please GCC's strict aliasing rules. */
|
||||
#define SDL_JACK_SYM(x) \
|
||||
if (!load_jack_sym(#x, (void **) (char *) &JACK_##x)) return -1
|
||||
#define SDL_JACK_SYM(x) \
|
||||
if (!load_jack_sym(#x, (void **)(char *)&JACK_##x)) \
|
||||
return -1
|
||||
|
||||
static void
|
||||
UnloadJackLibrary(void)
|
||||
static void UnloadJackLibrary(void)
|
||||
{
|
||||
if (jack_handle != NULL) {
|
||||
SDL_UnloadObject(jack_handle);
|
||||
@@ -79,8 +76,7 @@ UnloadJackLibrary(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
LoadJackLibrary(void)
|
||||
static int LoadJackLibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
if (jack_handle == NULL) {
|
||||
@@ -102,13 +98,11 @@ LoadJackLibrary(void)
|
||||
|
||||
#define SDL_JACK_SYM(x) JACK_##x = x
|
||||
|
||||
static void
|
||||
UnloadJackLibrary(void)
|
||||
static void UnloadJackLibrary(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
LoadJackLibrary(void)
|
||||
static int LoadJackLibrary(void)
|
||||
{
|
||||
load_jack_syms();
|
||||
return 0;
|
||||
@@ -116,9 +110,7 @@ LoadJackLibrary(void)
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_JACK_DYNAMIC */
|
||||
|
||||
|
||||
static int
|
||||
load_jack_syms(void)
|
||||
static int load_jack_syms(void)
|
||||
{
|
||||
SDL_JACK_SYM(jack_client_open);
|
||||
SDL_JACK_SYM(jack_client_close);
|
||||
@@ -140,23 +132,20 @@ load_jack_syms(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
jackShutdownCallback(void *arg) /* JACK went away; device is lost. */
|
||||
static void jackShutdownCallback(void *arg) /* JACK went away; device is lost. */
|
||||
{
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *)arg;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
SDL_SemPost(this->hidden->iosem); /* unblock the SDL thread. */
|
||||
SDL_SemPost(this->hidden->iosem); /* unblock the SDL thread. */
|
||||
}
|
||||
|
||||
// !!! FIXME: implement and register these!
|
||||
//typedef int(* JackSampleRateCallback)(jack_nframes_t nframes, void *arg)
|
||||
//typedef int(* JackBufferSizeCallback)(jack_nframes_t nframes, void *arg)
|
||||
// typedef int(* JackSampleRateCallback)(jack_nframes_t nframes, void *arg)
|
||||
// typedef int(* JackBufferSizeCallback)(jack_nframes_t nframes, void *arg)
|
||||
|
||||
static int
|
||||
jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg)
|
||||
static int jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg)
|
||||
{
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *)arg;
|
||||
jack_port_t **ports = this->hidden->sdlports;
|
||||
const int total_channels = this->spec.channels;
|
||||
const int total_frames = this->spec.samples;
|
||||
@@ -168,9 +157,9 @@ jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg)
|
||||
}
|
||||
|
||||
for (channelsi = 0; channelsi < total_channels; channelsi++) {
|
||||
float *dst = (float *) JACK_jack_port_get_buffer(ports[channelsi], nframes);
|
||||
float *dst = (float *)JACK_jack_port_get_buffer(ports[channelsi], nframes);
|
||||
if (dst) {
|
||||
const float *src = ((float *) this->hidden->iobuffer) + channelsi;
|
||||
const float *src = ((float *)this->hidden->iobuffer) + channelsi;
|
||||
int framesi;
|
||||
for (framesi = 0; framesi < total_frames; framesi++) {
|
||||
*(dst++) = *src;
|
||||
@@ -179,14 +168,12 @@ jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SemPost(this->hidden->iosem); /* tell SDL thread we're done; refill the buffer. */
|
||||
return 0; /* success */
|
||||
SDL_SemPost(this->hidden->iosem); /* tell SDL thread we're done; refill the buffer. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* This function waits until it is possible to write a full sound buffer */
|
||||
static void
|
||||
JACK_WaitDevice(_THIS)
|
||||
static void JACK_WaitDevice(_THIS)
|
||||
{
|
||||
if (SDL_AtomicGet(&this->enabled)) {
|
||||
if (SDL_SemWait(this->hidden->iosem) == -1) {
|
||||
@@ -195,27 +182,24 @@ JACK_WaitDevice(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
JACK_GetDeviceBuf(_THIS)
|
||||
static Uint8 *JACK_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return (Uint8 *) this->hidden->iobuffer;
|
||||
return (Uint8 *)this->hidden->iobuffer;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
jackProcessCaptureCallback(jack_nframes_t nframes, void *arg)
|
||||
static int jackProcessCaptureCallback(jack_nframes_t nframes, void *arg)
|
||||
{
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *)arg;
|
||||
if (SDL_AtomicGet(&this->enabled)) {
|
||||
jack_port_t **ports = this->hidden->sdlports;
|
||||
const int total_channels = this->spec.channels;
|
||||
const int total_frames = this->spec.samples;
|
||||
int channelsi;
|
||||
|
||||
|
||||
for (channelsi = 0; channelsi < total_channels; channelsi++) {
|
||||
const float *src = (const float *) JACK_jack_port_get_buffer(ports[channelsi], nframes);
|
||||
const float *src = (const float *)JACK_jack_port_get_buffer(ports[channelsi], nframes);
|
||||
if (src) {
|
||||
float *dst = ((float *) this->hidden->iobuffer) + channelsi;
|
||||
float *dst = ((float *)this->hidden->iobuffer) + channelsi;
|
||||
int framesi;
|
||||
for (framesi = 0; framesi < total_frames; framesi++) {
|
||||
*dst = *(src++);
|
||||
@@ -225,14 +209,13 @@ jackProcessCaptureCallback(jack_nframes_t nframes, void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SemPost(this->hidden->iosem); /* tell SDL thread we're done; new buffer is ready! */
|
||||
return 0; /* success */
|
||||
SDL_SemPost(this->hidden->iosem); /* tell SDL thread we're done; new buffer is ready! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
JACK_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int JACK_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
SDL_assert(buflen == this->spec.size); /* we always fill a full buffer. */
|
||||
SDL_assert(buflen == this->spec.size); /* we always fill a full buffer. */
|
||||
|
||||
/* Wait for JACK to fill the iobuffer */
|
||||
if (SDL_SemWait(this->hidden->iosem) == -1) {
|
||||
@@ -243,15 +226,12 @@ JACK_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
return buflen;
|
||||
}
|
||||
|
||||
static void
|
||||
JACK_FlushCapture(_THIS)
|
||||
static void JACK_FlushCapture(_THIS)
|
||||
{
|
||||
SDL_SemWait(this->hidden->iosem);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
JACK_CloseDevice(_THIS)
|
||||
static void JACK_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->client) {
|
||||
JACK_jack_deactivate(this->hidden->client);
|
||||
@@ -276,8 +256,7 @@ JACK_CloseDevice(_THIS)
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static int
|
||||
JACK_OpenDevice(_THIS, const char *devname)
|
||||
static int JACK_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
/* Note that JACK uses "output" for capture devices (they output audio
|
||||
data to us) and "input" for playback (we input audio data to them).
|
||||
@@ -297,7 +276,7 @@ JACK_OpenDevice(_THIS, const char *devname)
|
||||
int i;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof (*this->hidden));
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -325,7 +304,7 @@ JACK_OpenDevice(_THIS, const char *devname)
|
||||
const char *type = JACK_jack_port_type(dport);
|
||||
const int len = SDL_strlen(type);
|
||||
/* See if type ends with "audio" */
|
||||
if (len >= 5 && !SDL_memcmp(type+len-5, "audio", 5)) {
|
||||
if (len >= 5 && !SDL_memcmp(type + len - 5, "audio", 5)) {
|
||||
audio_ports[channels++] = i;
|
||||
}
|
||||
}
|
||||
@@ -333,7 +312,6 @@ JACK_OpenDevice(_THIS, const char *devname)
|
||||
return SDL_SetError("No physical JACK ports available");
|
||||
}
|
||||
|
||||
|
||||
/* !!! FIXME: docs say about buffer size: "This size may change, clients that depend on it must register a bufsize_callback so they will be notified if it does." */
|
||||
|
||||
/* Jack pretty much demands what it wants. */
|
||||
@@ -346,23 +324,23 @@ JACK_OpenDevice(_THIS, const char *devname)
|
||||
|
||||
this->hidden->iosem = SDL_CreateSemaphore(0);
|
||||
if (!this->hidden->iosem) {
|
||||
return -1; /* error was set by SDL_CreateSemaphore */
|
||||
return -1; /* error was set by SDL_CreateSemaphore */
|
||||
}
|
||||
|
||||
this->hidden->iobuffer = (float *) SDL_calloc(1, this->spec.size);
|
||||
this->hidden->iobuffer = (float *)SDL_calloc(1, this->spec.size);
|
||||
if (!this->hidden->iobuffer) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
/* Build SDL's ports, which we will connect to the device ports. */
|
||||
this->hidden->sdlports = (jack_port_t **) SDL_calloc(channels, sizeof (jack_port_t *));
|
||||
this->hidden->sdlports = (jack_port_t **)SDL_calloc(channels, sizeof(jack_port_t *));
|
||||
if (this->hidden->sdlports == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
for (i = 0; i < channels; i++) {
|
||||
char portname[32];
|
||||
SDL_snprintf(portname, sizeof (portname), "sdl_jack_%s_%d", sdlportstr, i);
|
||||
SDL_snprintf(portname, sizeof(portname), "sdl_jack_%s_%d", sdlportstr, i);
|
||||
this->hidden->sdlports[i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
|
||||
if (this->hidden->sdlports[i] == NULL) {
|
||||
return SDL_SetError("jack_port_register failed");
|
||||
@@ -397,14 +375,12 @@ JACK_OpenDevice(_THIS, const char *devname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
JACK_Deinitialize(void)
|
||||
static void JACK_Deinitialize(void)
|
||||
{
|
||||
UnloadJackLibrary();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
JACK_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool JACK_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
if (LoadJackLibrary() < 0) {
|
||||
return SDL_FALSE;
|
||||
@@ -431,7 +407,7 @@ JACK_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap JACK_bootstrap = {
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_N3DS
|
||||
|
||||
|
||||
/* N3DS Audio driver */
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
@@ -36,32 +35,27 @@ static SDL_AudioDevice *audio_device;
|
||||
static void FreePrivateData(_THIS);
|
||||
static int FindAudioFormat(_THIS);
|
||||
|
||||
static SDL_INLINE void
|
||||
contextLock(_THIS)
|
||||
static SDL_INLINE void contextLock(_THIS)
|
||||
{
|
||||
LightLock_Lock(&this->hidden->lock);
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
contextUnlock(_THIS)
|
||||
static SDL_INLINE void contextUnlock(_THIS)
|
||||
{
|
||||
LightLock_Unlock(&this->hidden->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
N3DSAUD_LockAudio(_THIS)
|
||||
static void N3DSAUD_LockAudio(_THIS)
|
||||
{
|
||||
contextLock(this);
|
||||
}
|
||||
|
||||
static void
|
||||
N3DSAUD_UnlockAudio(_THIS)
|
||||
static void N3DSAUD_UnlockAudio(_THIS)
|
||||
{
|
||||
contextUnlock(this);
|
||||
}
|
||||
|
||||
static void
|
||||
N3DSAUD_DspHook(DSP_HookType hook)
|
||||
static void N3DSAUD_DspHook(DSP_HookType hook)
|
||||
{
|
||||
if (hook == DSPHOOK_ONCANCEL) {
|
||||
contextLock(audio_device);
|
||||
@@ -72,12 +66,11 @@ N3DSAUD_DspHook(DSP_HookType hook)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
AudioFrameFinished(void *device)
|
||||
static void AudioFrameFinished(void *device)
|
||||
{
|
||||
bool shouldBroadcast = false;
|
||||
unsigned i;
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) device;
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *)device;
|
||||
|
||||
contextLock(this);
|
||||
|
||||
@@ -95,13 +88,12 @@ AudioFrameFinished(void *device)
|
||||
contextUnlock(this);
|
||||
}
|
||||
|
||||
static int
|
||||
N3DSAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int N3DSAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
Result ndsp_init_res;
|
||||
Uint8 *data_vaddr;
|
||||
float mix[12];
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof *this->hidden);
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof *this->hidden);
|
||||
|
||||
if (this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
@@ -140,14 +132,14 @@ N3DSAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size);
|
||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->spec.size);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
|
||||
|
||||
data_vaddr = (Uint8 *) linearAlloc(this->hidden->mixlen * NUM_BUFFERS);
|
||||
data_vaddr = (Uint8 *)linearAlloc(this->hidden->mixlen * NUM_BUFFERS);
|
||||
if (data_vaddr == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -186,8 +178,7 @@ N3DSAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
N3DSAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int N3DSAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
/* Delay to make this sort of simulate real audio input. */
|
||||
SDL_Delay((this->spec.samples * 1000) / this->spec.freq);
|
||||
@@ -197,8 +188,7 @@ N3DSAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
return buflen;
|
||||
}
|
||||
|
||||
static void
|
||||
N3DSAUDIO_PlayDevice(_THIS)
|
||||
static void N3DSAUDIO_PlayDevice(_THIS)
|
||||
{
|
||||
size_t nextbuf;
|
||||
size_t sampleLen;
|
||||
@@ -217,15 +207,14 @@ N3DSAUDIO_PlayDevice(_THIS)
|
||||
|
||||
contextUnlock(this);
|
||||
|
||||
memcpy((void *) this->hidden->waveBuf[nextbuf].data_vaddr,
|
||||
memcpy((void *)this->hidden->waveBuf[nextbuf].data_vaddr,
|
||||
this->hidden->mixbuf, sampleLen);
|
||||
DSP_FlushDataCache(this->hidden->waveBuf[nextbuf].data_vaddr, sampleLen);
|
||||
|
||||
ndspChnWaveBufAdd(0, &this->hidden->waveBuf[nextbuf]);
|
||||
}
|
||||
|
||||
static void
|
||||
N3DSAUDIO_WaitDevice(_THIS)
|
||||
static void N3DSAUDIO_WaitDevice(_THIS)
|
||||
{
|
||||
contextLock(this);
|
||||
while (!this->hidden->isCancelled &&
|
||||
@@ -235,14 +224,12 @@ N3DSAUDIO_WaitDevice(_THIS)
|
||||
contextUnlock(this);
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
N3DSAUDIO_GetDeviceBuf(_THIS)
|
||||
static Uint8 *N3DSAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return this->hidden->mixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
N3DSAUDIO_CloseDevice(_THIS)
|
||||
static void N3DSAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
contextLock(this);
|
||||
|
||||
@@ -262,8 +249,7 @@ N3DSAUDIO_CloseDevice(_THIS)
|
||||
FreePrivateData(this);
|
||||
}
|
||||
|
||||
static void
|
||||
N3DSAUDIO_ThreadInit(_THIS)
|
||||
static void N3DSAUDIO_ThreadInit(_THIS)
|
||||
{
|
||||
s32 current_priority;
|
||||
svcGetThreadPriority(¤t_priority, CUR_THREAD_HANDLE);
|
||||
@@ -273,8 +259,7 @@ N3DSAUDIO_ThreadInit(_THIS)
|
||||
svcSetThreadPriority(CUR_THREAD_HANDLE, current_priority);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
N3DSAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
static SDL_bool N3DSAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = N3DSAUDIO_OpenDevice;
|
||||
@@ -304,15 +289,14 @@ AudioBootStrap N3DSAUDIO_bootstrap = {
|
||||
/**
|
||||
* Cleans up all allocated memory, safe to call with null pointers
|
||||
*/
|
||||
static void
|
||||
FreePrivateData(_THIS)
|
||||
static void FreePrivateData(_THIS)
|
||||
{
|
||||
if (!this->hidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->hidden->waveBuf[0].data_vaddr) {
|
||||
linearFree((void *) this->hidden->waveBuf[0].data_vaddr);
|
||||
linearFree((void *)this->hidden->waveBuf[0].data_vaddr);
|
||||
}
|
||||
|
||||
if (this->hidden->mixbuf) {
|
||||
@@ -324,8 +308,7 @@ FreePrivateData(_THIS)
|
||||
this->hidden = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
FindAudioFormat(_THIS)
|
||||
static int FindAudioFormat(_THIS)
|
||||
{
|
||||
SDL_bool found_valid_format = SDL_FALSE;
|
||||
Uint16 test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
|
||||
@@ -43,15 +43,12 @@
|
||||
|
||||
/* #define DEBUG_AUDIO */
|
||||
|
||||
static void
|
||||
NETBSDAUDIO_DetectDevices(void)
|
||||
static void NETBSDAUDIO_DetectDevices(void)
|
||||
{
|
||||
SDL_EnumUnixAudioDevices(0, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
NETBSDAUDIO_Status(_THIS)
|
||||
static void NETBSDAUDIO_Status(_THIS)
|
||||
{
|
||||
#ifdef DEBUG_AUDIO
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
@@ -117,12 +114,11 @@ NETBSDAUDIO_Status(_THIS)
|
||||
this->spec.format,
|
||||
this->spec.size);
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
#endif /* DEBUG_AUDIO */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
NETBSDAUDIO_PlayDevice(_THIS)
|
||||
static void NETBSDAUDIO_PlayDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
int written;
|
||||
@@ -141,17 +137,14 @@ NETBSDAUDIO_PlayDevice(_THIS)
|
||||
#endif
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
NETBSDAUDIO_GetDeviceBuf(_THIS)
|
||||
static Uint8 *NETBSDAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return this->hidden->mixbuf;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
NETBSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen)
|
||||
static int NETBSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen)
|
||||
{
|
||||
Uint8 *buffer = (Uint8 *) _buffer;
|
||||
Uint8 *buffer = (Uint8 *)_buffer;
|
||||
int br;
|
||||
|
||||
br = read(this->hidden->audio_fd, buffer, buflen);
|
||||
@@ -167,30 +160,28 @@ NETBSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
NETBSDAUDIO_FlushCapture(_THIS)
|
||||
static void NETBSDAUDIO_FlushCapture(_THIS)
|
||||
{
|
||||
audio_info_t info;
|
||||
size_t remain;
|
||||
Uint8 buf[512];
|
||||
|
||||
if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
|
||||
return; /* oh well. */
|
||||
return; /* oh well. */
|
||||
}
|
||||
|
||||
remain = (size_t) (info.record.samples * (SDL_AUDIO_BITSIZE(this->spec.format) / 8));
|
||||
remain = (size_t)(info.record.samples * (SDL_AUDIO_BITSIZE(this->spec.format) / 8));
|
||||
while (remain > 0) {
|
||||
const size_t len = SDL_min(sizeof (buf), remain);
|
||||
const size_t len = SDL_min(sizeof(buf), remain);
|
||||
const int br = read(this->hidden->audio_fd, buf, len);
|
||||
if (br <= 0) {
|
||||
return; /* oh well. */
|
||||
return; /* oh well. */
|
||||
}
|
||||
remain -= br;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NETBSDAUDIO_CloseDevice(_THIS)
|
||||
static void NETBSDAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->audio_fd >= 0) {
|
||||
close(this->hidden->audio_fd);
|
||||
@@ -199,8 +190,7 @@ NETBSDAUDIO_CloseDevice(_THIS)
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static int
|
||||
NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
SDL_AudioFormat test_format;
|
||||
@@ -239,8 +229,7 @@ NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
* Use the device's native sample rate so the kernel doesn't have to
|
||||
* resample.
|
||||
*/
|
||||
this->spec.freq = iscapture ?
|
||||
hwinfo.record.sample_rate : hwinfo.play.sample_rate;
|
||||
this->spec.freq = iscapture ? hwinfo.record.sample_rate : hwinfo.play.sample_rate;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -305,7 +294,7 @@ NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
if (!iscapture) {
|
||||
/* Allocate mixing buffer */
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
|
||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -318,8 +307,7 @@ NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
NETBSDAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool NETBSDAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->DetectDevices = NETBSDAUDIO_DetectDevices;
|
||||
@@ -333,10 +321,9 @@ NETBSDAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap NETBSDAUDIO_bootstrap = {
|
||||
"netbsd", "NetBSD audio", NETBSDAUDIO_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
@@ -41,7 +41,7 @@ struct SDL_PrivateAudioData
|
||||
float next_frame;
|
||||
};
|
||||
|
||||
#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */
|
||||
#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */
|
||||
|
||||
#endif /* SDL_netbsdaudio_h_ */
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
#include <android/log.h>
|
||||
|
||||
#if 0
|
||||
#define LOG_TAG "SDL_openslES"
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
|
||||
#define LOG_TAG "SDL_openslES"
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
||||
//#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGV(...)
|
||||
#else
|
||||
@@ -69,9 +69,9 @@
|
||||
#define SL_SPEAKER_TOP_BACK_RIGHT ((SLuint32) 0x00020000)
|
||||
*/
|
||||
#define SL_ANDROID_SPEAKER_STEREO (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT)
|
||||
#define SL_ANDROID_SPEAKER_QUAD (SL_ANDROID_SPEAKER_STEREO | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT)
|
||||
#define SL_ANDROID_SPEAKER_5DOT1 (SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY)
|
||||
#define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT)
|
||||
#define SL_ANDROID_SPEAKER_QUAD (SL_ANDROID_SPEAKER_STEREO | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT)
|
||||
#define SL_ANDROID_SPEAKER_5DOT1 (SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY)
|
||||
#define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT)
|
||||
|
||||
/* engine interfaces */
|
||||
static SLObjectItf engineObject = NULL;
|
||||
@@ -97,8 +97,8 @@ static SLAndroidSimpleBufferQueueItf recorderBufferQueue = NULL;
|
||||
static const char *sldevaudiorecorderstr = "SLES Audio Recorder";
|
||||
static const char *sldevaudioplayerstr = "SLES Audio Player";
|
||||
|
||||
#define SLES_DEV_AUDIO_RECORDER sldevaudiorecorderstr
|
||||
#define SLES_DEV_AUDIO_PLAYER sldevaudioplayerstr
|
||||
#define SLES_DEV_AUDIO_RECORDER sldevaudiorecorderstr
|
||||
#define SLES_DEV_AUDIO_PLAYER sldevaudioplayerstr
|
||||
static void openslES_DetectDevices( int iscapture )
|
||||
{
|
||||
LOGI( "openSLES_DetectDevices()" );
|
||||
@@ -127,8 +127,7 @@ static void openslES_DestroyEngine(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
openslES_CreateEngine(void)
|
||||
static int openslES_CreateEngine(void)
|
||||
{
|
||||
const SLInterfaceID ids[1] = { SL_IID_VOLUME };
|
||||
const SLboolean req[1] = { SL_BOOLEAN_FALSE };
|
||||
@@ -182,17 +181,15 @@ error:
|
||||
}
|
||||
|
||||
/* this callback handler is called every time a buffer finishes recording */
|
||||
static void
|
||||
bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
|
||||
static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) context;
|
||||
struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *)context;
|
||||
|
||||
LOGV("SLES: Recording Callback");
|
||||
SDL_SemPost(audiodata->playsem);
|
||||
}
|
||||
|
||||
static void
|
||||
openslES_DestroyPCMRecorder(_THIS)
|
||||
static void openslES_DestroyPCMRecorder(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
||||
SLresult result;
|
||||
@@ -223,8 +220,7 @@ openslES_DestroyPCMRecorder(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
openslES_CreatePCMRecorder(_THIS)
|
||||
static int openslES_CreatePCMRecorder(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
||||
SLDataFormat_PCM format_pcm;
|
||||
@@ -251,8 +247,8 @@ openslES_CreatePCMRecorder(_THIS)
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
LOGI("Try to open %u hz %u bit chan %u %s samples %u",
|
||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
|
||||
/* configure audio source */
|
||||
loc_dev.locatorType = SL_DATALOCATOR_IODEVICE;
|
||||
@@ -266,13 +262,13 @@ openslES_CreatePCMRecorder(_THIS)
|
||||
loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
||||
loc_bufq.numBuffers = NUM_BUFFERS;
|
||||
|
||||
format_pcm.formatType = SL_DATAFORMAT_PCM;
|
||||
format_pcm.numChannels = this->spec.channels;
|
||||
format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */
|
||||
format_pcm.formatType = SL_DATAFORMAT_PCM;
|
||||
format_pcm.numChannels = this->spec.channels;
|
||||
format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */
|
||||
format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
|
||||
format_pcm.containerSize = SDL_AUDIO_BITSIZE(this->spec.format);
|
||||
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
|
||||
format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
|
||||
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
|
||||
format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
|
||||
|
||||
audioSnk.pLocator = &loc_bufq;
|
||||
audioSnk.pFormat = &format_pcm;
|
||||
@@ -322,7 +318,7 @@ openslES_CreatePCMRecorder(_THIS)
|
||||
}
|
||||
|
||||
/* Create the sound buffers */
|
||||
audiodata->mixbuff = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size);
|
||||
audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * this->spec.size);
|
||||
if (audiodata->mixbuff == NULL) {
|
||||
LOGE("mixbuffer allocate - out of memory");
|
||||
goto failed;
|
||||
@@ -362,17 +358,15 @@ failed:
|
||||
}
|
||||
|
||||
/* this callback handler is called every time a buffer finishes playing */
|
||||
static void
|
||||
bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
|
||||
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) context;
|
||||
struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *)context;
|
||||
|
||||
LOGV("SLES: Playback Callback");
|
||||
SDL_SemPost(audiodata->playsem);
|
||||
}
|
||||
|
||||
static void
|
||||
openslES_DestroyPCMPlayer(_THIS)
|
||||
static void openslES_DestroyPCMPlayer(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
||||
SLresult result;
|
||||
@@ -404,8 +398,7 @@ openslES_DestroyPCMPlayer(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
openslES_CreatePCMPlayer(_THIS)
|
||||
static int openslES_CreatePCMPlayer(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
||||
SLDataLocator_AndroidSimpleBufferQueue loc_bufq;
|
||||
@@ -433,7 +426,7 @@ openslES_CreatePCMPlayer(_THIS)
|
||||
|
||||
if (!test_format) {
|
||||
/* Didn't find a compatible format : */
|
||||
LOGI( "No compatible audio format, using signed 16-bit audio" );
|
||||
LOGI("No compatible audio format, using signed 16-bit audio");
|
||||
test_format = AUDIO_S16SYS;
|
||||
}
|
||||
this->spec.format = test_format;
|
||||
@@ -446,16 +439,16 @@ openslES_CreatePCMPlayer(_THIS)
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
LOGI("Try to open %u hz %s %u bit chan %u %s samples %u",
|
||||
this->spec.freq, SDL_AUDIO_ISFLOAT(this->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
this->spec.freq, SDL_AUDIO_ISFLOAT(this->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
|
||||
/* configure audio source */
|
||||
loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
||||
loc_bufq.numBuffers = NUM_BUFFERS;
|
||||
|
||||
format_pcm.formatType = SL_DATAFORMAT_PCM;
|
||||
format_pcm.numChannels = this->spec.channels;
|
||||
format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */
|
||||
format_pcm.formatType = SL_DATAFORMAT_PCM;
|
||||
format_pcm.numChannels = this->spec.channels;
|
||||
format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */
|
||||
format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
|
||||
format_pcm.containerSize = SDL_AUDIO_BITSIZE(this->spec.format);
|
||||
|
||||
@@ -465,8 +458,7 @@ openslES_CreatePCMPlayer(_THIS)
|
||||
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
|
||||
}
|
||||
|
||||
switch (this->spec.channels)
|
||||
{
|
||||
switch (this->spec.channels) {
|
||||
case 1:
|
||||
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT;
|
||||
break;
|
||||
@@ -511,7 +503,7 @@ openslES_CreatePCMPlayer(_THIS)
|
||||
}
|
||||
|
||||
audioSrc.pLocator = &loc_bufq;
|
||||
audioSrc.pFormat = SDL_AUDIO_ISFLOAT(this->spec.format) ? (void*)&format_pcm_ex : (void*)&format_pcm;
|
||||
audioSrc.pFormat = SDL_AUDIO_ISFLOAT(this->spec.format) ? (void *)&format_pcm_ex : (void *)&format_pcm;
|
||||
|
||||
/* configure audio sink */
|
||||
loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
|
||||
@@ -572,7 +564,7 @@ openslES_CreatePCMPlayer(_THIS)
|
||||
}
|
||||
|
||||
/* Create the sound buffers */
|
||||
audiodata->mixbuff = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size);
|
||||
audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * this->spec.size);
|
||||
if (audiodata->mixbuff == NULL) {
|
||||
LOGE("mixbuffer allocate - out of memory");
|
||||
goto failed;
|
||||
@@ -595,10 +587,9 @@ failed:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
openslES_OpenDevice(_THIS, const char *devname)
|
||||
static int openslES_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
|
||||
this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, (sizeof *this->hidden));
|
||||
if (this->hidden == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -624,12 +615,10 @@ openslES_OpenDevice(_THIS, const char *devname)
|
||||
} else {
|
||||
return SDL_SetError("Open device failed!");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
openslES_WaitDevice(_THIS)
|
||||
static void openslES_WaitDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
||||
|
||||
@@ -639,8 +628,7 @@ openslES_WaitDevice(_THIS)
|
||||
SDL_SemWait(audiodata->playsem);
|
||||
}
|
||||
|
||||
static void
|
||||
openslES_PlayDevice(_THIS)
|
||||
static void openslES_PlayDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
||||
SLresult result;
|
||||
@@ -674,8 +662,7 @@ openslES_PlayDevice(_THIS)
|
||||
/* */
|
||||
/* okay.. */
|
||||
|
||||
static Uint8 *
|
||||
openslES_GetDeviceBuf(_THIS)
|
||||
static Uint8 *openslES_GetDeviceBuf(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
||||
|
||||
@@ -683,8 +670,7 @@ openslES_GetDeviceBuf(_THIS)
|
||||
return audiodata->pmixbuff[audiodata->next_buffer];
|
||||
}
|
||||
|
||||
static int
|
||||
openslES_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int openslES_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = this->hidden;
|
||||
SLresult result;
|
||||
@@ -711,8 +697,7 @@ openslES_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
return this->spec.size;
|
||||
}
|
||||
|
||||
static void
|
||||
openslES_CloseDevice(_THIS)
|
||||
static void openslES_CloseDevice(_THIS)
|
||||
{
|
||||
/* struct SDL_PrivateAudioData *audiodata = this->hidden; */
|
||||
|
||||
@@ -727,8 +712,7 @@ openslES_CloseDevice(_THIS)
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
openslES_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool openslES_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
LOGI("openslES_Init() called");
|
||||
|
||||
@@ -740,13 +724,13 @@ openslES_Init(SDL_AudioDriverImpl * impl)
|
||||
|
||||
/* Set the function pointers */
|
||||
/* impl->DetectDevices = openslES_DetectDevices; */
|
||||
impl->OpenDevice = openslES_OpenDevice;
|
||||
impl->WaitDevice = openslES_WaitDevice;
|
||||
impl->PlayDevice = openslES_PlayDevice;
|
||||
impl->GetDeviceBuf = openslES_GetDeviceBuf;
|
||||
impl->OpenDevice = openslES_OpenDevice;
|
||||
impl->WaitDevice = openslES_WaitDevice;
|
||||
impl->PlayDevice = openslES_PlayDevice;
|
||||
impl->GetDeviceBuf = openslES_GetDeviceBuf;
|
||||
impl->CaptureFromDevice = openslES_CaptureFromDevice;
|
||||
impl->CloseDevice = openslES_CloseDevice;
|
||||
impl->Deinitialize = openslES_DestroyEngine;
|
||||
impl->CloseDevice = openslES_CloseDevice;
|
||||
impl->Deinitialize = openslES_DestroyEngine;
|
||||
|
||||
/* and the capabilities */
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
@@ -26,15 +26,15 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
#define NUM_BUFFERS 2 /* -- Don't lower this! */
|
||||
#define NUM_BUFFERS 2 /* -- Don't lower this! */
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
Uint8 *mixbuff;
|
||||
int next_buffer;
|
||||
Uint8 *pmixbuff[NUM_BUFFERS];
|
||||
Uint8 *mixbuff;
|
||||
int next_buffer;
|
||||
Uint8 *pmixbuff[NUM_BUFFERS];
|
||||
SDL_sem *playsem;
|
||||
};
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ enum PW_READY_FLAGS
|
||||
{
|
||||
PW_READY_FLAG_BUFFER_ADDED = 0x1,
|
||||
PW_READY_FLAG_STREAM_READY = 0x2,
|
||||
PW_READY_FLAG_ALL_BITS = 0x3
|
||||
PW_READY_FLAG_ALL_BITS = 0x3
|
||||
};
|
||||
|
||||
#define PW_ID_TO_HANDLE(x) (void *)((uintptr_t)x)
|
||||
@@ -114,17 +114,16 @@ static struct pw_properties *(*PIPEWIRE_pw_properties_new)(const char *, ...)SPA
|
||||
static int (*PIPEWIRE_pw_properties_set)(struct pw_properties *, const char *, const char *);
|
||||
static int (*PIPEWIRE_pw_properties_setf)(struct pw_properties *, const char *, const char *, ...) SPA_PRINTF_FUNC(3, 4);
|
||||
|
||||
static int pipewire_version_major;
|
||||
static int pipewire_version_minor;
|
||||
static int pipewire_version_patch;
|
||||
static int pipewire_version_major;
|
||||
static int pipewire_version_minor;
|
||||
static int pipewire_version_patch;
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC
|
||||
|
||||
static const char *pipewire_library = SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC;
|
||||
static void *pipewire_handle = NULL;
|
||||
static void *pipewire_handle = NULL;
|
||||
|
||||
static int
|
||||
pipewire_dlsym(const char *fn, void **addr)
|
||||
static int pipewire_dlsym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(pipewire_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
@@ -140,8 +139,7 @@ pipewire_dlsym(const char *fn, void **addr)
|
||||
return -1; \
|
||||
}
|
||||
|
||||
static int
|
||||
load_pipewire_library()
|
||||
static int load_pipewire_library()
|
||||
{
|
||||
if ((pipewire_handle = SDL_LoadObject(pipewire_library))) {
|
||||
return 0;
|
||||
@@ -150,8 +148,7 @@ load_pipewire_library()
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
unload_pipewire_library()
|
||||
static void unload_pipewire_library()
|
||||
{
|
||||
if (pipewire_handle) {
|
||||
SDL_UnloadObject(pipewire_handle);
|
||||
@@ -163,21 +160,18 @@ unload_pipewire_library()
|
||||
|
||||
#define SDL_PIPEWIRE_SYM(x) PIPEWIRE_##x = x
|
||||
|
||||
static int
|
||||
load_pipewire_library()
|
||||
static int load_pipewire_library()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
unload_pipewire_library()
|
||||
static void unload_pipewire_library()
|
||||
{ /* Nothing to do */
|
||||
}
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC */
|
||||
|
||||
static int
|
||||
load_pipewire_syms()
|
||||
static int load_pipewire_syms()
|
||||
{
|
||||
SDL_PIPEWIRE_SYM(pw_get_library_version);
|
||||
SDL_PIPEWIRE_SYM(pw_init);
|
||||
@@ -219,8 +213,7 @@ pipewire_version_at_least(int major, int minor, int patch)
|
||||
(pipewire_version_major > major || pipewire_version_minor > minor || pipewire_version_patch >= patch);
|
||||
}
|
||||
|
||||
static int
|
||||
init_pipewire_library()
|
||||
static int init_pipewire_library()
|
||||
{
|
||||
if (!load_pipewire_library()) {
|
||||
if (!load_pipewire_syms()) {
|
||||
@@ -242,8 +235,7 @@ init_pipewire_library()
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
deinit_pipewire_library()
|
||||
static void deinit_pipewire_library()
|
||||
{
|
||||
PIPEWIRE_pw_deinit();
|
||||
unload_pipewire_library();
|
||||
@@ -254,8 +246,8 @@ struct node_object
|
||||
{
|
||||
struct spa_list link;
|
||||
|
||||
Uint32 id;
|
||||
int seq;
|
||||
Uint32 id;
|
||||
int seq;
|
||||
SDL_bool persist;
|
||||
|
||||
/*
|
||||
@@ -268,8 +260,8 @@ struct node_object
|
||||
void *userdata;
|
||||
|
||||
struct pw_proxy *proxy;
|
||||
struct spa_hook node_listener;
|
||||
struct spa_hook core_listener;
|
||||
struct spa_hook node_listener;
|
||||
struct spa_hook core_listener;
|
||||
};
|
||||
|
||||
/* A sink/source node used for stream I/O. */
|
||||
@@ -277,8 +269,8 @@ struct io_node
|
||||
{
|
||||
struct spa_list link;
|
||||
|
||||
Uint32 id;
|
||||
SDL_bool is_capture;
|
||||
Uint32 id;
|
||||
SDL_bool is_capture;
|
||||
SDL_AudioSpec spec;
|
||||
|
||||
const char *name; /* Friendly name */
|
||||
@@ -289,26 +281,25 @@ struct io_node
|
||||
|
||||
/* The global hotplug thread and associated objects. */
|
||||
static struct pw_thread_loop *hotplug_loop;
|
||||
static struct pw_core *hotplug_core;
|
||||
static struct pw_context *hotplug_context;
|
||||
static struct pw_registry *hotplug_registry;
|
||||
static struct spa_hook hotplug_registry_listener;
|
||||
static struct spa_hook hotplug_core_listener;
|
||||
static struct spa_list hotplug_pending_list;
|
||||
static struct spa_list hotplug_io_list;
|
||||
static int hotplug_init_seq_val;
|
||||
static SDL_bool hotplug_init_complete;
|
||||
static SDL_bool hotplug_events_enabled;
|
||||
static struct pw_core *hotplug_core;
|
||||
static struct pw_context *hotplug_context;
|
||||
static struct pw_registry *hotplug_registry;
|
||||
static struct spa_hook hotplug_registry_listener;
|
||||
static struct spa_hook hotplug_core_listener;
|
||||
static struct spa_list hotplug_pending_list;
|
||||
static struct spa_list hotplug_io_list;
|
||||
static int hotplug_init_seq_val;
|
||||
static SDL_bool hotplug_init_complete;
|
||||
static SDL_bool hotplug_events_enabled;
|
||||
|
||||
static char *pipewire_default_sink_id = NULL;
|
||||
static char *pipewire_default_sink_id = NULL;
|
||||
static char *pipewire_default_source_id = NULL;
|
||||
|
||||
/* The active node list */
|
||||
static SDL_bool
|
||||
io_list_check_add(struct io_node *node)
|
||||
static SDL_bool io_list_check_add(struct io_node *node)
|
||||
{
|
||||
struct io_node *n;
|
||||
SDL_bool ret = SDL_TRUE;
|
||||
SDL_bool ret = SDL_TRUE;
|
||||
|
||||
/* See if the node is already in the list */
|
||||
spa_list_for_each (n, &hotplug_io_list, link) {
|
||||
@@ -330,8 +321,7 @@ dup_found:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
io_list_remove(Uint32 id)
|
||||
static void io_list_remove(Uint32 id)
|
||||
{
|
||||
struct io_node *n, *temp;
|
||||
|
||||
@@ -351,8 +341,7 @@ io_list_remove(Uint32 id)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
io_list_sort()
|
||||
static void io_list_sort()
|
||||
{
|
||||
struct io_node *default_sink = NULL, *default_source = NULL;
|
||||
struct io_node *n, *temp;
|
||||
@@ -377,8 +366,7 @@ io_list_sort()
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
io_list_clear()
|
||||
static void io_list_clear()
|
||||
{
|
||||
struct io_node *n, *temp;
|
||||
|
||||
@@ -388,7 +376,7 @@ io_list_clear()
|
||||
}
|
||||
}
|
||||
|
||||
static struct io_node*
|
||||
static struct io_node *
|
||||
io_list_get_by_id(Uint32 id)
|
||||
{
|
||||
struct io_node *n, *temp;
|
||||
@@ -400,7 +388,7 @@ io_list_get_by_id(Uint32 id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct io_node*
|
||||
static struct io_node *
|
||||
io_list_get_by_path(char *path)
|
||||
{
|
||||
struct io_node *n, *temp;
|
||||
@@ -412,8 +400,7 @@ io_list_get_by_path(char *path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
node_object_destroy(struct node_object *node)
|
||||
static void node_object_destroy(struct node_object *node)
|
||||
{
|
||||
SDL_assert(node);
|
||||
|
||||
@@ -425,15 +412,13 @@ node_object_destroy(struct node_object *node)
|
||||
}
|
||||
|
||||
/* The pending node list */
|
||||
static void
|
||||
pending_list_add(struct node_object *node)
|
||||
static void pending_list_add(struct node_object *node)
|
||||
{
|
||||
SDL_assert(node);
|
||||
spa_list_append(&hotplug_pending_list, &node->link);
|
||||
}
|
||||
|
||||
static void
|
||||
pending_list_remove(Uint32 id)
|
||||
static void pending_list_remove(Uint32 id)
|
||||
{
|
||||
struct node_object *node, *temp;
|
||||
|
||||
@@ -444,8 +429,7 @@ pending_list_remove(Uint32 id)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pending_list_clear()
|
||||
static void pending_list_clear()
|
||||
{
|
||||
struct node_object *node, *temp;
|
||||
|
||||
@@ -454,10 +438,9 @@ pending_list_clear()
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
node_object_new(Uint32 id, const char *type, Uint32 version, const void *funcs, const struct pw_core_events *core_events)
|
||||
static void *node_object_new(Uint32 id, const char *type, Uint32 version, const void *funcs, const struct pw_core_events *core_events)
|
||||
{
|
||||
struct pw_proxy *proxy;
|
||||
struct pw_proxy *proxy;
|
||||
struct node_object *node;
|
||||
|
||||
/* Create the proxy object */
|
||||
@@ -470,7 +453,7 @@ node_object_new(Uint32 id, const char *type, Uint32 version, const void *funcs,
|
||||
node = PIPEWIRE_pw_proxy_get_user_data(proxy);
|
||||
SDL_zerop(node);
|
||||
|
||||
node->id = id;
|
||||
node->id = id;
|
||||
node->proxy = proxy;
|
||||
|
||||
/* Add the callbacks */
|
||||
@@ -484,8 +467,7 @@ node_object_new(Uint32 id, const char *type, Uint32 version, const void *funcs,
|
||||
}
|
||||
|
||||
/* Core sync points */
|
||||
static void
|
||||
core_events_hotplug_init_callback(void *object, uint32_t id, int seq)
|
||||
static void core_events_hotplug_init_callback(void *object, uint32_t id, int seq)
|
||||
{
|
||||
if (id == PW_ID_CORE && seq == hotplug_init_seq_val) {
|
||||
/* This core listener is no longer needed. */
|
||||
@@ -497,11 +479,10 @@ core_events_hotplug_init_callback(void *object, uint32_t id, int seq)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
core_events_interface_callback(void *object, uint32_t id, int seq)
|
||||
static void core_events_interface_callback(void *object, uint32_t id, int seq)
|
||||
{
|
||||
struct node_object *node = object;
|
||||
struct io_node *io = node->userdata;
|
||||
struct io_node *io = node->userdata;
|
||||
|
||||
if (id == PW_ID_CORE && seq == node->seq) {
|
||||
/*
|
||||
@@ -516,8 +497,7 @@ core_events_interface_callback(void *object, uint32_t id, int seq)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
core_events_metadata_callback(void *object, uint32_t id, int seq)
|
||||
static void core_events_metadata_callback(void *object, uint32_t id, int seq)
|
||||
{
|
||||
struct node_object *node = object;
|
||||
|
||||
@@ -527,11 +507,10 @@ core_events_metadata_callback(void *object, uint32_t id, int seq)
|
||||
}
|
||||
|
||||
static const struct pw_core_events hotplug_init_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_hotplug_init_callback };
|
||||
static const struct pw_core_events interface_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_interface_callback };
|
||||
static const struct pw_core_events metadata_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_metadata_callback };
|
||||
static const struct pw_core_events interface_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_interface_callback };
|
||||
static const struct pw_core_events metadata_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_metadata_callback };
|
||||
|
||||
static void
|
||||
hotplug_core_sync(struct node_object *node)
|
||||
static void hotplug_core_sync(struct node_object *node)
|
||||
{
|
||||
/*
|
||||
* Node sync events *must* come before the hotplug init sync events or the initial
|
||||
@@ -547,12 +526,11 @@ hotplug_core_sync(struct node_object *node)
|
||||
}
|
||||
|
||||
/* Helpers for retrieving values from params */
|
||||
static SDL_bool
|
||||
get_range_param(const struct spa_pod *param, Uint32 key, int *def, int *min, int *max)
|
||||
static SDL_bool get_range_param(const struct spa_pod *param, Uint32 key, int *def, int *min, int *max)
|
||||
{
|
||||
const struct spa_pod_prop *prop;
|
||||
struct spa_pod *value;
|
||||
Uint32 n_values, choice;
|
||||
struct spa_pod *value;
|
||||
Uint32 n_values, choice;
|
||||
|
||||
prop = spa_pod_find_prop(param, NULL, key);
|
||||
|
||||
@@ -581,11 +559,10 @@ get_range_param(const struct spa_pod *param, Uint32 key, int *def, int *min, int
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
get_int_param(const struct spa_pod *param, Uint32 key, int *val)
|
||||
static SDL_bool get_int_param(const struct spa_pod *param, Uint32 key, int *val)
|
||||
{
|
||||
const struct spa_pod_prop *prop;
|
||||
Sint32 v;
|
||||
Sint32 v;
|
||||
|
||||
prop = spa_pod_find_prop(param, NULL, key);
|
||||
|
||||
@@ -601,13 +578,12 @@ get_int_param(const struct spa_pod *param, Uint32 key, int *val)
|
||||
}
|
||||
|
||||
/* Interface node callbacks */
|
||||
static void
|
||||
node_event_info(void *object, const struct pw_node_info *info)
|
||||
static void node_event_info(void *object, const struct pw_node_info *info)
|
||||
{
|
||||
struct node_object *node = object;
|
||||
struct io_node *io = node->userdata;
|
||||
const char *prop_val;
|
||||
Uint32 i;
|
||||
struct io_node *io = node->userdata;
|
||||
const char *prop_val;
|
||||
Uint32 i;
|
||||
|
||||
if (info) {
|
||||
prop_val = spa_dict_lookup(info->props, PW_KEY_AUDIO_CHANNELS);
|
||||
@@ -624,11 +600,10 @@ node_event_info(void *object, const struct pw_node_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
node_event_param(void *object, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param)
|
||||
static void node_event_param(void *object, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param)
|
||||
{
|
||||
struct node_object *node = object;
|
||||
struct io_node *io = node->userdata;
|
||||
struct io_node *io = node->userdata;
|
||||
|
||||
/* Get the default frequency */
|
||||
if (io->spec.freq == 0) {
|
||||
@@ -650,8 +625,7 @@ node_event_param(void *object, int seq, uint32_t id, uint32_t index, uint32_t ne
|
||||
static const struct pw_node_events interface_node_events = { PW_VERSION_NODE_EVENTS, .info = node_event_info,
|
||||
.param = node_event_param };
|
||||
|
||||
static char*
|
||||
get_name_from_json(const char *json)
|
||||
static char *get_name_from_json(const char *json)
|
||||
{
|
||||
struct spa_json parser[2];
|
||||
char key[7]; /* "name" */
|
||||
@@ -673,8 +647,7 @@ get_name_from_json(const char *json)
|
||||
}
|
||||
|
||||
/* Metadata node callback */
|
||||
static int
|
||||
metadata_property(void *object, Uint32 subject, const char *key, const char *type, const char *value)
|
||||
static int metadata_property(void *object, Uint32 subject, const char *key, const char *type, const char *value)
|
||||
{
|
||||
struct node_object *node = object;
|
||||
|
||||
@@ -700,9 +673,8 @@ metadata_property(void *object, Uint32 subject, const char *key, const char *typ
|
||||
static const struct pw_metadata_events metadata_node_events = { PW_VERSION_METADATA_EVENTS, .property = metadata_property };
|
||||
|
||||
/* Global registry callbacks */
|
||||
static void
|
||||
registry_event_global_callback(void *object, uint32_t id, uint32_t permissions, const char *type, uint32_t version,
|
||||
const struct spa_dict *props)
|
||||
static void registry_event_global_callback(void *object, uint32_t id, uint32_t permissions, const char *type, uint32_t version,
|
||||
const struct spa_dict *props)
|
||||
{
|
||||
struct node_object *node;
|
||||
|
||||
@@ -711,12 +683,12 @@ registry_event_global_callback(void *object, uint32_t id, uint32_t permissions,
|
||||
const char *media_class = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
|
||||
|
||||
if (media_class) {
|
||||
const char *node_desc;
|
||||
const char *node_path;
|
||||
const char *node_desc;
|
||||
const char *node_path;
|
||||
struct io_node *io;
|
||||
SDL_bool is_capture;
|
||||
int desc_buffer_len;
|
||||
int path_buffer_len;
|
||||
SDL_bool is_capture;
|
||||
int desc_buffer_len;
|
||||
int path_buffer_len;
|
||||
|
||||
/* Just want sink and capture */
|
||||
if (!SDL_strcasecmp(media_class, "Audio/Sink")) {
|
||||
@@ -748,11 +720,11 @@ registry_event_global_callback(void *object, uint32_t id, uint32_t permissions,
|
||||
}
|
||||
|
||||
/* Begin setting the node properties */
|
||||
io->id = id;
|
||||
io->is_capture = is_capture;
|
||||
io->id = id;
|
||||
io->is_capture = is_capture;
|
||||
io->spec.format = AUDIO_F32; /* Pipewire uses floats internally, other formats require conversion. */
|
||||
io->name = io->buf;
|
||||
io->path = io->buf + desc_buffer_len;
|
||||
io->name = io->buf;
|
||||
io->path = io->buf + desc_buffer_len;
|
||||
SDL_strlcpy(io->buf, node_desc, desc_buffer_len);
|
||||
SDL_strlcpy(io->buf + desc_buffer_len, node_path, path_buffer_len);
|
||||
|
||||
@@ -772,8 +744,7 @@ registry_event_global_callback(void *object, uint32_t id, uint32_t permissions,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
registry_event_remove_callback(void *object, uint32_t id)
|
||||
static void registry_event_remove_callback(void *object, uint32_t id)
|
||||
{
|
||||
io_list_remove(id);
|
||||
pending_list_remove(id);
|
||||
@@ -783,8 +754,7 @@ static const struct pw_registry_events registry_events = { PW_VERSION_REGISTRY_E
|
||||
.global_remove = registry_event_remove_callback };
|
||||
|
||||
/* The hotplug thread */
|
||||
static int
|
||||
hotplug_loop_init()
|
||||
static int hotplug_loop_init()
|
||||
{
|
||||
int res;
|
||||
|
||||
@@ -827,8 +797,7 @@ hotplug_loop_init()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hotplug_loop_destroy()
|
||||
static void hotplug_loop_destroy()
|
||||
{
|
||||
if (hotplug_loop) {
|
||||
PIPEWIRE_pw_thread_loop_stop(hotplug_loop);
|
||||
@@ -837,7 +806,7 @@ hotplug_loop_destroy()
|
||||
pending_list_clear();
|
||||
io_list_clear();
|
||||
|
||||
hotplug_init_complete = SDL_FALSE;
|
||||
hotplug_init_complete = SDL_FALSE;
|
||||
hotplug_events_enabled = SDL_FALSE;
|
||||
|
||||
if (pipewire_default_sink_id != NULL) {
|
||||
@@ -870,8 +839,7 @@ hotplug_loop_destroy()
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
PIPEWIRE_DetectDevices()
|
||||
static void PIPEWIRE_DetectDevices()
|
||||
{
|
||||
struct io_node *io;
|
||||
|
||||
@@ -913,11 +881,10 @@ static const enum spa_audio_channel PIPEWIRE_channel_map_8[] = { SPA_AUDIO_CHANN
|
||||
|
||||
#define COPY_CHANNEL_MAP(c) SDL_memcpy(info->position, PIPEWIRE_channel_map_##c, sizeof(PIPEWIRE_channel_map_##c))
|
||||
|
||||
static void
|
||||
initialize_spa_info(const SDL_AudioSpec *spec, struct spa_audio_info_raw *info)
|
||||
static void initialize_spa_info(const SDL_AudioSpec *spec, struct spa_audio_info_raw *info)
|
||||
{
|
||||
info->channels = spec->channels;
|
||||
info->rate = spec->freq;
|
||||
info->rate = spec->freq;
|
||||
|
||||
switch (spec->channels) {
|
||||
case 1:
|
||||
@@ -981,14 +948,13 @@ initialize_spa_info(const SDL_AudioSpec *spec, struct spa_audio_info_raw *info)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output_callback(void *data)
|
||||
static void output_callback(void *data)
|
||||
{
|
||||
struct pw_buffer *pw_buf;
|
||||
struct pw_buffer *pw_buf;
|
||||
struct spa_buffer *spa_buf;
|
||||
Uint8 *dst;
|
||||
Uint8 *dst;
|
||||
|
||||
_THIS = (SDL_AudioDevice *)data;
|
||||
_THIS = (SDL_AudioDevice *)data;
|
||||
struct pw_stream *stream = this->hidden->stream;
|
||||
|
||||
/* Shutting down, don't do anything */
|
||||
@@ -1042,18 +1008,17 @@ output_callback(void *data)
|
||||
|
||||
spa_buf->datas[0].chunk->offset = 0;
|
||||
spa_buf->datas[0].chunk->stride = this->hidden->stride;
|
||||
spa_buf->datas[0].chunk->size = this->spec.size;
|
||||
spa_buf->datas[0].chunk->size = this->spec.size;
|
||||
|
||||
PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
input_callback(void *data)
|
||||
static void input_callback(void *data)
|
||||
{
|
||||
struct pw_buffer *pw_buf;
|
||||
struct pw_buffer *pw_buf;
|
||||
struct spa_buffer *spa_buf;
|
||||
Uint8 *src;
|
||||
_THIS = (SDL_AudioDevice *)data;
|
||||
Uint8 *src;
|
||||
_THIS = (SDL_AudioDevice *)data;
|
||||
struct pw_stream *stream = this->hidden->stream;
|
||||
|
||||
/* Shutting down, don't do anything */
|
||||
@@ -1075,7 +1040,7 @@ input_callback(void *data)
|
||||
if (!SDL_AtomicGet(&this->paused)) {
|
||||
/* Calculate the offset and data size */
|
||||
const Uint32 offset = SPA_MIN(spa_buf->datas[0].chunk->offset, spa_buf->datas[0].maxsize);
|
||||
const Uint32 size = SPA_MIN(spa_buf->datas[0].chunk->size, spa_buf->datas[0].maxsize - offset);
|
||||
const Uint32 size = SPA_MIN(spa_buf->datas[0].chunk->size, spa_buf->datas[0].maxsize - offset);
|
||||
|
||||
src += offset;
|
||||
|
||||
@@ -1103,8 +1068,7 @@ input_callback(void *data)
|
||||
PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
|
||||
static void stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
|
||||
{
|
||||
_THIS = data;
|
||||
|
||||
@@ -1115,7 +1079,7 @@ stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
|
||||
*/
|
||||
if (this->spec.size > buffer->buffer->datas[0].maxsize) {
|
||||
this->spec.samples = buffer->buffer->datas[0].maxsize / this->hidden->stride;
|
||||
this->spec.size = buffer->buffer->datas[0].maxsize;
|
||||
this->spec.size = buffer->buffer->datas[0].maxsize;
|
||||
}
|
||||
} else if (this->hidden->buffer == NULL) {
|
||||
/*
|
||||
@@ -1127,15 +1091,14 @@ stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
|
||||
* A packet size of 2 periods should be more than is ever needed.
|
||||
*/
|
||||
this->hidden->input_buffer_packet_size = SPA_MAX(this->spec.size, buffer->buffer->datas[0].maxsize) * 2;
|
||||
this->hidden->buffer = SDL_NewDataQueue(this->hidden->input_buffer_packet_size, this->hidden->input_buffer_packet_size);
|
||||
this->hidden->buffer = SDL_NewDataQueue(this->hidden->input_buffer_packet_size, this->hidden->input_buffer_packet_size);
|
||||
}
|
||||
|
||||
this->hidden->stream_init_status |= PW_READY_FLAG_BUFFER_ADDED;
|
||||
PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
|
||||
}
|
||||
|
||||
static void
|
||||
stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error)
|
||||
static void stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error)
|
||||
{
|
||||
_THIS = data;
|
||||
|
||||
@@ -1150,15 +1113,14 @@ stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stre
|
||||
|
||||
static const struct pw_stream_events stream_output_events = { PW_VERSION_STREAM_EVENTS,
|
||||
.state_changed = stream_state_changed_callback,
|
||||
.add_buffer = stream_add_buffer_callback,
|
||||
.process = output_callback };
|
||||
static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_EVENTS,
|
||||
.state_changed = stream_state_changed_callback,
|
||||
.add_buffer = stream_add_buffer_callback,
|
||||
.process = input_callback };
|
||||
.add_buffer = stream_add_buffer_callback,
|
||||
.process = output_callback };
|
||||
static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_EVENTS,
|
||||
.state_changed = stream_state_changed_callback,
|
||||
.add_buffer = stream_add_buffer_callback,
|
||||
.process = input_callback };
|
||||
|
||||
static int
|
||||
PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
||||
static int PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
/*
|
||||
* NOTE: The PW_STREAM_FLAG_RT_PROCESS flag can be set to call the stream
|
||||
@@ -1169,17 +1131,17 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
||||
*/
|
||||
static const enum pw_stream_flags STREAM_FLAGS = PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS;
|
||||
|
||||
char thread_name[PW_THREAD_NAME_BUFFER_LENGTH];
|
||||
Uint8 pod_buffer[PW_POD_BUFFER_LENGTH];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(pod_buffer, sizeof(pod_buffer));
|
||||
struct spa_audio_info_raw spa_info = { 0 };
|
||||
const struct spa_pod *params = NULL;
|
||||
char thread_name[PW_THREAD_NAME_BUFFER_LENGTH];
|
||||
Uint8 pod_buffer[PW_POD_BUFFER_LENGTH];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(pod_buffer, sizeof(pod_buffer));
|
||||
struct spa_audio_info_raw spa_info = { 0 };
|
||||
const struct spa_pod *params = NULL;
|
||||
struct SDL_PrivateAudioData *priv;
|
||||
struct pw_properties *props;
|
||||
const char *app_name, *stream_name, *stream_role, *error;
|
||||
Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
int res;
|
||||
struct pw_properties *props;
|
||||
const char *app_name, *stream_name, *stream_role, *error;
|
||||
Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
|
||||
SDL_bool iscapture = this->iscapture;
|
||||
int res;
|
||||
|
||||
/* Clamp the period size to sane values */
|
||||
const int min_period = PW_MIN_SAMPLES * SPA_MAX(this->spec.freq / PW_BASE_CLOCK_RATE, 1);
|
||||
@@ -1223,7 +1185,7 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
|
||||
|
||||
if (this->spec.samples < min_period) {
|
||||
this->spec.samples = min_period;
|
||||
this->spec.size = this->spec.samples * priv->stride;
|
||||
this->spec.size = this->spec.samples * priv->stride;
|
||||
}
|
||||
|
||||
SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)this->handle);
|
||||
@@ -1341,8 +1303,7 @@ static void PIPEWIRE_CloseDevice(_THIS)
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static int
|
||||
PIPEWIRE_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
static int PIPEWIRE_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
struct io_node *node;
|
||||
char *target;
|
||||
@@ -1380,8 +1341,7 @@ failed:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
PIPEWIRE_Deinitialize()
|
||||
static void PIPEWIRE_Deinitialize()
|
||||
{
|
||||
if (pipewire_initialized) {
|
||||
hotplug_loop_destroy();
|
||||
@@ -1390,8 +1350,7 @@ PIPEWIRE_Deinitialize()
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
|
||||
static SDL_bool PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
if (!pipewire_initialized) {
|
||||
if (init_pipewire_library() < 0) {
|
||||
@@ -1407,15 +1366,15 @@ PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
impl->DetectDevices = PIPEWIRE_DetectDevices;
|
||||
impl->OpenDevice = PIPEWIRE_OpenDevice;
|
||||
impl->CloseDevice = PIPEWIRE_CloseDevice;
|
||||
impl->Deinitialize = PIPEWIRE_Deinitialize;
|
||||
impl->DetectDevices = PIPEWIRE_DetectDevices;
|
||||
impl->OpenDevice = PIPEWIRE_OpenDevice;
|
||||
impl->CloseDevice = PIPEWIRE_CloseDevice;
|
||||
impl->Deinitialize = PIPEWIRE_Deinitialize;
|
||||
impl->GetDefaultAudioInfo = PIPEWIRE_GetDefaultAudioInfo;
|
||||
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
impl->SupportsNonPow2Samples = SDL_TRUE;
|
||||
impl->SupportsNonPow2Samples = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
struct pw_thread_loop *loop;
|
||||
struct pw_stream *stream;
|
||||
struct pw_context *context;
|
||||
struct SDL_DataQueue *buffer;
|
||||
struct pw_stream *stream;
|
||||
struct pw_context *context;
|
||||
struct SDL_DataQueue *buffer;
|
||||
|
||||
size_t input_buffer_packet_size;
|
||||
Sint32 stride; /* Bytes-per-frame */
|
||||
int stream_init_status;
|
||||
int stream_init_status;
|
||||
};
|
||||
|
||||
#endif /* SDL_pipewire_h_ */
|
||||
|
||||
@@ -31,10 +31,9 @@
|
||||
#include <ps2_audio_driver.h>
|
||||
|
||||
/* The tag name used by PS2 audio */
|
||||
#define PS2AUDIO_DRIVER_NAME "ps2"
|
||||
#define PS2AUDIO_DRIVER_NAME "ps2"
|
||||
|
||||
static int
|
||||
PS2AUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int PS2AUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
int i, mixlen;
|
||||
struct audsrv_fmt_t format;
|
||||
@@ -46,21 +45,20 @@ PS2AUDIO_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
||||
|
||||
/* These are the native supported audio PS2 configs */
|
||||
switch (this->spec.freq) {
|
||||
case 11025:
|
||||
case 12000:
|
||||
case 22050:
|
||||
case 24000:
|
||||
case 32000:
|
||||
case 44100:
|
||||
case 48000:
|
||||
this->spec.freq = this->spec.freq;
|
||||
break;
|
||||
default:
|
||||
this->spec.freq = 48000;
|
||||
break;
|
||||
case 11025:
|
||||
case 12000:
|
||||
case 22050:
|
||||
case 24000:
|
||||
case 32000:
|
||||
case 44100:
|
||||
case 48000:
|
||||
this->spec.freq = this->spec.freq;
|
||||
break;
|
||||
default:
|
||||
this->spec.freq = 48000;
|
||||
break;
|
||||
}
|
||||
|
||||
this->spec.samples = 512;
|
||||
@@ -69,8 +67,8 @@ PS2AUDIO_OpenDevice(_THIS, const char *devname)
|
||||
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
format.bits = this->spec.format == AUDIO_S8 ? 8 : 16;
|
||||
format.freq = this->spec.freq;
|
||||
format.bits = this->spec.format == AUDIO_S8 ? 8 : 16;
|
||||
format.freq = this->spec.freq;
|
||||
format.channels = this->spec.channels;
|
||||
|
||||
this->hidden->channel = audsrv_set_format(&format);
|
||||
@@ -89,7 +87,7 @@ PS2AUDIO_OpenDevice(_THIS, const char *devname)
|
||||
be a multiple of 64 bytes. Our sample count is already a multiple of
|
||||
64, so spec->size should be a multiple of 64 as well. */
|
||||
mixlen = this->spec.size * NUM_BUFFERS;
|
||||
this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen);
|
||||
this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
||||
if (this->hidden->rawbuf == NULL) {
|
||||
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||
}
|
||||
@@ -152,7 +150,7 @@ static void PS2AUDIO_Deinitialize(void)
|
||||
deinit_audio_driver();
|
||||
}
|
||||
|
||||
static SDL_bool PS2AUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool PS2AUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
if (init_audio_driver() < 0) {
|
||||
return SDL_FALSE;
|
||||
@@ -167,7 +165,7 @@ static SDL_bool PS2AUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->ThreadInit = PS2AUDIO_ThreadInit;
|
||||
impl->Deinitialize = PS2AUDIO_Deinitialize;
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap PS2AUDIO_bootstrap = {
|
||||
|
||||
@@ -26,20 +26,20 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
#define NUM_BUFFERS 2
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
/* The hardware output channel. */
|
||||
int channel;
|
||||
/* The raw allocated mixing buffer. */
|
||||
Uint8 *rawbuf;
|
||||
/* Individual mixing buffers. */
|
||||
Uint8 *mixbufs[NUM_BUFFERS];
|
||||
/* Index of the next available mixing buffer. */
|
||||
int next_buffer;
|
||||
/* The hardware output channel. */
|
||||
int channel;
|
||||
/* The raw allocated mixing buffer. */
|
||||
Uint8 *rawbuf;
|
||||
/* Individual mixing buffers. */
|
||||
Uint8 *mixbufs[NUM_BUFFERS];
|
||||
/* Index of the next available mixing buffer. */
|
||||
int next_buffer;
|
||||
};
|
||||
|
||||
#endif /* SDL_ps2audio_h_ */
|
||||
|
||||
@@ -36,10 +36,9 @@
|
||||
#include <pspthreadman.h>
|
||||
|
||||
/* The tag name used by PSP audio */
|
||||
#define PSPAUDIO_DRIVER_NAME "psp"
|
||||
#define PSPAUDIO_DRIVER_NAME "psp"
|
||||
|
||||
static int
|
||||
PSPAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int PSPAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
int format, mixlen, i;
|
||||
|
||||
@@ -61,7 +60,7 @@ PSPAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
format = PSP_AUDIO_FORMAT_MONO;
|
||||
} else {
|
||||
format = PSP_AUDIO_FORMAT_STEREO;
|
||||
this->spec.channels = 2; /* we're forcing the hardware to stereo. */
|
||||
this->spec.channels = 2; /* we're forcing the hardware to stereo. */
|
||||
}
|
||||
|
||||
/* PSP has some limitations with the Audio. It fully supports 44.1KHz (Mono & Stereo),
|
||||
@@ -72,7 +71,7 @@ PSPAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
} else {
|
||||
this->hidden->channel = sceAudioSRCChReserve(this->spec.samples, this->spec.freq, 2);
|
||||
}
|
||||
|
||||
|
||||
if (this->hidden->channel < 0) {
|
||||
free(this->hidden->rawbuf);
|
||||
this->hidden->rawbuf = NULL;
|
||||
@@ -86,7 +85,7 @@ PSPAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
be a multiple of 64 bytes. Our sample count is already a multiple of
|
||||
64, so spec->size should be a multiple of 64 as well. */
|
||||
mixlen = this->spec.size * NUM_BUFFERS;
|
||||
this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen);
|
||||
this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
||||
if (this->hidden->rawbuf == NULL) {
|
||||
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||
}
|
||||
@@ -155,8 +154,7 @@ static void PSPAUDIO_ThreadInit(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool PSPAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = PSPAUDIO_OpenDevice;
|
||||
@@ -172,7 +170,7 @@ PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
*/
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap PSPAUDIO_bootstrap = {
|
||||
|
||||
@@ -25,19 +25,20 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
#define NUM_BUFFERS 2
|
||||
|
||||
struct SDL_PrivateAudioData {
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
/* The hardware output channel. */
|
||||
int channel;
|
||||
int channel;
|
||||
/* The raw allocated mixing buffer. */
|
||||
Uint8 *rawbuf;
|
||||
Uint8 *rawbuf;
|
||||
/* Individual mixing buffers. */
|
||||
Uint8 *mixbufs[NUM_BUFFERS];
|
||||
Uint8 *mixbufs[NUM_BUFFERS];
|
||||
/* Index of the next available mixing buffer. */
|
||||
int next_buffer;
|
||||
int next_buffer;
|
||||
};
|
||||
|
||||
#endif /* SDL_pspaudio_h_ */
|
||||
|
||||
@@ -45,81 +45,79 @@
|
||||
/* should we include monitors in the device list? Set at SDL_Init time */
|
||||
static SDL_bool include_monitors = SDL_FALSE;
|
||||
|
||||
|
||||
#if (PA_API_VERSION < 12)
|
||||
/** Return non-zero if the passed state is one of the connected states */
|
||||
static SDL_INLINE int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
|
||||
static SDL_INLINE int PA_CONTEXT_IS_GOOD(pa_context_state_t x)
|
||||
{
|
||||
return x == PA_CONTEXT_CONNECTING || x == PA_CONTEXT_AUTHORIZING || x == PA_CONTEXT_SETTING_NAME || x == PA_CONTEXT_READY;
|
||||
}
|
||||
/** Return non-zero if the passed state is one of the connected states */
|
||||
static SDL_INLINE int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
|
||||
static SDL_INLINE int PA_STREAM_IS_GOOD(pa_stream_state_t x)
|
||||
{
|
||||
return x == PA_STREAM_CREATING || x == PA_STREAM_READY;
|
||||
}
|
||||
#endif /* pulseaudio <= 0.9.10 */
|
||||
|
||||
|
||||
static const char *(*PULSEAUDIO_pa_get_library_version) (void);
|
||||
static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto) (
|
||||
static const char *(*PULSEAUDIO_pa_get_library_version)(void);
|
||||
static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto)(
|
||||
pa_channel_map *, unsigned, pa_channel_map_def_t);
|
||||
static const char * (*PULSEAUDIO_pa_strerror) (int);
|
||||
static pa_mainloop * (*PULSEAUDIO_pa_mainloop_new) (void);
|
||||
static pa_mainloop_api * (*PULSEAUDIO_pa_mainloop_get_api) (pa_mainloop *);
|
||||
static int (*PULSEAUDIO_pa_mainloop_iterate) (pa_mainloop *, int, int *);
|
||||
static int (*PULSEAUDIO_pa_mainloop_run) (pa_mainloop *, int *);
|
||||
static void (*PULSEAUDIO_pa_mainloop_quit) (pa_mainloop *, int);
|
||||
static void (*PULSEAUDIO_pa_mainloop_free) (pa_mainloop *);
|
||||
static const char *(*PULSEAUDIO_pa_strerror)(int);
|
||||
static pa_mainloop *(*PULSEAUDIO_pa_mainloop_new)(void);
|
||||
static pa_mainloop_api *(*PULSEAUDIO_pa_mainloop_get_api)(pa_mainloop *);
|
||||
static int (*PULSEAUDIO_pa_mainloop_iterate)(pa_mainloop *, int, int *);
|
||||
static int (*PULSEAUDIO_pa_mainloop_run)(pa_mainloop *, int *);
|
||||
static void (*PULSEAUDIO_pa_mainloop_quit)(pa_mainloop *, int);
|
||||
static void (*PULSEAUDIO_pa_mainloop_free)(pa_mainloop *);
|
||||
|
||||
static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state) (
|
||||
static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state)(
|
||||
const pa_operation *);
|
||||
static void (*PULSEAUDIO_pa_operation_cancel) (pa_operation *);
|
||||
static void (*PULSEAUDIO_pa_operation_unref) (pa_operation *);
|
||||
static void (*PULSEAUDIO_pa_operation_cancel)(pa_operation *);
|
||||
static void (*PULSEAUDIO_pa_operation_unref)(pa_operation *);
|
||||
|
||||
static pa_context * (*PULSEAUDIO_pa_context_new) (pa_mainloop_api *,
|
||||
const char *);
|
||||
static int (*PULSEAUDIO_pa_context_connect) (pa_context *, const char *,
|
||||
pa_context_flags_t, const pa_spawn_api *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_list) (pa_context *, pa_sink_info_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_list) (pa_context *, pa_source_info_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_by_index) (pa_context *, uint32_t, pa_sink_info_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_by_index) (pa_context *, uint32_t, pa_source_info_cb_t, void *);
|
||||
static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (const pa_context *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_subscribe) (pa_context *, pa_subscription_mask_t, pa_context_success_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_context_set_subscribe_callback) (pa_context *, pa_context_subscribe_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_context_disconnect) (pa_context *);
|
||||
static void (*PULSEAUDIO_pa_context_unref) (pa_context *);
|
||||
static pa_context *(*PULSEAUDIO_pa_context_new)(pa_mainloop_api *,
|
||||
const char *);
|
||||
static int (*PULSEAUDIO_pa_context_connect)(pa_context *, const char *,
|
||||
pa_context_flags_t, const pa_spawn_api *);
|
||||
static pa_operation *(*PULSEAUDIO_pa_context_get_sink_info_list)(pa_context *, pa_sink_info_cb_t, void *);
|
||||
static pa_operation *(*PULSEAUDIO_pa_context_get_source_info_list)(pa_context *, pa_source_info_cb_t, void *);
|
||||
static pa_operation *(*PULSEAUDIO_pa_context_get_sink_info_by_index)(pa_context *, uint32_t, pa_sink_info_cb_t, void *);
|
||||
static pa_operation *(*PULSEAUDIO_pa_context_get_source_info_by_index)(pa_context *, uint32_t, pa_source_info_cb_t, void *);
|
||||
static pa_context_state_t (*PULSEAUDIO_pa_context_get_state)(const pa_context *);
|
||||
static pa_operation *(*PULSEAUDIO_pa_context_subscribe)(pa_context *, pa_subscription_mask_t, pa_context_success_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_context_set_subscribe_callback)(pa_context *, pa_context_subscribe_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_context_disconnect)(pa_context *);
|
||||
static void (*PULSEAUDIO_pa_context_unref)(pa_context *);
|
||||
|
||||
static pa_stream * (*PULSEAUDIO_pa_stream_new) (pa_context *, const char *,
|
||||
const pa_sample_spec *, const pa_channel_map *);
|
||||
static int (*PULSEAUDIO_pa_stream_connect_playback) (pa_stream *, const char *,
|
||||
const pa_buffer_attr *, pa_stream_flags_t, const pa_cvolume *, pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *,
|
||||
const pa_buffer_attr *, pa_stream_flags_t);
|
||||
static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (const pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_writable_size) (const pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_readable_size) (const pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t,
|
||||
pa_free_cb_t, int64_t, pa_seek_mode_t);
|
||||
static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *,
|
||||
pa_stream_success_cb_t, void *);
|
||||
static int (*PULSEAUDIO_pa_stream_peek) (pa_stream *, const void **, size_t *);
|
||||
static int (*PULSEAUDIO_pa_stream_drop) (pa_stream *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *,
|
||||
pa_stream_success_cb_t, void *);
|
||||
static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *);
|
||||
static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *);
|
||||
static pa_stream *(*PULSEAUDIO_pa_stream_new)(pa_context *, const char *,
|
||||
const pa_sample_spec *, const pa_channel_map *);
|
||||
static int (*PULSEAUDIO_pa_stream_connect_playback)(pa_stream *, const char *,
|
||||
const pa_buffer_attr *, pa_stream_flags_t, const pa_cvolume *, pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_connect_record)(pa_stream *, const char *,
|
||||
const pa_buffer_attr *, pa_stream_flags_t);
|
||||
static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state)(const pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_writable_size)(const pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_readable_size)(const pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_write)(pa_stream *, const void *, size_t,
|
||||
pa_free_cb_t, int64_t, pa_seek_mode_t);
|
||||
static pa_operation *(*PULSEAUDIO_pa_stream_drain)(pa_stream *,
|
||||
pa_stream_success_cb_t, void *);
|
||||
static int (*PULSEAUDIO_pa_stream_peek)(pa_stream *, const void **, size_t *);
|
||||
static int (*PULSEAUDIO_pa_stream_drop)(pa_stream *);
|
||||
static pa_operation *(*PULSEAUDIO_pa_stream_flush)(pa_stream *,
|
||||
pa_stream_success_cb_t, void *);
|
||||
static int (*PULSEAUDIO_pa_stream_disconnect)(pa_stream *);
|
||||
static void (*PULSEAUDIO_pa_stream_unref)(pa_stream *);
|
||||
static void (*PULSEAUDIO_pa_stream_set_write_callback)(pa_stream *, pa_stream_request_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_server_info)(pa_context *, pa_server_info_cb_t, void *);
|
||||
static pa_operation *(*PULSEAUDIO_pa_context_get_server_info)(pa_context *, pa_server_info_cb_t, void *);
|
||||
|
||||
static int load_pulseaudio_syms(void);
|
||||
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC
|
||||
|
||||
static const char *pulseaudio_library = SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC;
|
||||
static void *pulseaudio_handle = NULL;
|
||||
|
||||
static int
|
||||
load_pulseaudio_sym(const char *fn, void **addr)
|
||||
static int load_pulseaudio_sym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(pulseaudio_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
@@ -131,11 +129,11 @@ load_pulseaudio_sym(const char *fn, void **addr)
|
||||
}
|
||||
|
||||
/* cast funcs to char* first, to please GCC's strict aliasing rules. */
|
||||
#define SDL_PULSEAUDIO_SYM(x) \
|
||||
if (!load_pulseaudio_sym(#x, (void **) (char *) &PULSEAUDIO_##x)) return -1
|
||||
#define SDL_PULSEAUDIO_SYM(x) \
|
||||
if (!load_pulseaudio_sym(#x, (void **)(char *)&PULSEAUDIO_##x)) \
|
||||
return -1
|
||||
|
||||
static void
|
||||
UnloadPulseAudioLibrary(void)
|
||||
static void UnloadPulseAudioLibrary(void)
|
||||
{
|
||||
if (pulseaudio_handle != NULL) {
|
||||
SDL_UnloadObject(pulseaudio_handle);
|
||||
@@ -143,8 +141,7 @@ UnloadPulseAudioLibrary(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
LoadPulseAudioLibrary(void)
|
||||
static int LoadPulseAudioLibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
if (pulseaudio_handle == NULL) {
|
||||
@@ -166,13 +163,11 @@ LoadPulseAudioLibrary(void)
|
||||
|
||||
#define SDL_PULSEAUDIO_SYM(x) PULSEAUDIO_##x = x
|
||||
|
||||
static void
|
||||
UnloadPulseAudioLibrary(void)
|
||||
static void UnloadPulseAudioLibrary(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
LoadPulseAudioLibrary(void)
|
||||
static int LoadPulseAudioLibrary(void)
|
||||
{
|
||||
load_pulseaudio_syms();
|
||||
return 0;
|
||||
@@ -180,9 +175,7 @@ LoadPulseAudioLibrary(void)
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC */
|
||||
|
||||
|
||||
static int
|
||||
load_pulseaudio_syms(void)
|
||||
static int load_pulseaudio_syms(void)
|
||||
{
|
||||
SDL_PULSEAUDIO_SYM(pa_get_library_version);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_new);
|
||||
@@ -225,15 +218,13 @@ load_pulseaudio_syms(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SDL_INLINE int
|
||||
squashVersion(const int major, const int minor, const int patch)
|
||||
static SDL_INLINE int squashVersion(const int major, const int minor, const int patch)
|
||||
{
|
||||
return ((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF);
|
||||
}
|
||||
|
||||
/* Workaround for older pulse: pa_context_new() must have non-NULL appname */
|
||||
static const char *
|
||||
getAppName(void)
|
||||
static const char *getAppName(void)
|
||||
{
|
||||
const char *retval = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
|
||||
if (retval && *retval) {
|
||||
@@ -244,12 +235,12 @@ getAppName(void)
|
||||
return retval;
|
||||
} else {
|
||||
const char *verstr = PULSEAUDIO_pa_get_library_version();
|
||||
retval = "SDL Application"; /* the "oh well" default. */
|
||||
retval = "SDL Application"; /* the "oh well" default. */
|
||||
if (verstr != NULL) {
|
||||
int maj, min, patch;
|
||||
if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) {
|
||||
if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) {
|
||||
retval = NULL; /* 0.9.15+ handles NULL correctly. */
|
||||
retval = NULL; /* 0.9.15+ handles NULL correctly. */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -257,8 +248,7 @@ getAppName(void)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
WaitForPulseOperation(pa_mainloop *mainloop, pa_operation *o)
|
||||
static void WaitForPulseOperation(pa_mainloop *mainloop, pa_operation *o)
|
||||
{
|
||||
/* This checks for NO errors currently. Either fix that, check results elsewhere, or do things you don't care about. */
|
||||
if (mainloop && o) {
|
||||
@@ -270,8 +260,7 @@ WaitForPulseOperation(pa_mainloop *mainloop, pa_operation *o)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DisconnectFromPulseServer(pa_mainloop *mainloop, pa_context *context)
|
||||
static void DisconnectFromPulseServer(pa_mainloop *mainloop, pa_context *context)
|
||||
{
|
||||
if (context) {
|
||||
PULSEAUDIO_pa_context_disconnect(context);
|
||||
@@ -282,8 +271,7 @@ DisconnectFromPulseServer(pa_mainloop *mainloop, pa_context *context)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context)
|
||||
static int ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context)
|
||||
{
|
||||
pa_mainloop *mainloop = NULL;
|
||||
pa_context *context = NULL;
|
||||
@@ -299,7 +287,7 @@ ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context)
|
||||
}
|
||||
|
||||
mainloop_api = PULSEAUDIO_pa_mainloop_get_api(mainloop);
|
||||
SDL_assert(mainloop_api); /* this never fails, right? */
|
||||
SDL_assert(mainloop_api); /* this never fails, right? */
|
||||
|
||||
context = PULSEAUDIO_pa_context_new(mainloop_api, getAppName());
|
||||
if (context == NULL) {
|
||||
@@ -331,11 +319,10 @@ ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context)
|
||||
*_context = context;
|
||||
*_mainloop = mainloop;
|
||||
|
||||
return 0; /* connected and ready! */
|
||||
return 0; /* connected and ready! */
|
||||
}
|
||||
|
||||
static int
|
||||
ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
|
||||
static int ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
|
||||
{
|
||||
const int retval = ConnectToPulseServer_Internal(_mainloop, _context);
|
||||
if (retval < 0) {
|
||||
@@ -344,23 +331,20 @@ ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* This function waits until it is possible to write a full sound buffer */
|
||||
static void
|
||||
PULSEAUDIO_WaitDevice(_THIS)
|
||||
static void PULSEAUDIO_WaitDevice(_THIS)
|
||||
{
|
||||
/* this is a no-op; we wait in PULSEAUDIO_PlayDevice now. */
|
||||
}
|
||||
|
||||
static void WriteCallback(pa_stream *p, size_t nbytes, void *userdata)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = (struct SDL_PrivateAudioData *) userdata;
|
||||
struct SDL_PrivateAudioData *h = (struct SDL_PrivateAudioData *)userdata;
|
||||
/*printf("PULSEAUDIO WRITE CALLBACK! nbytes=%u\n", (unsigned int) nbytes);*/
|
||||
h->bytes_requested += nbytes;
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_PlayDevice(_THIS)
|
||||
static void PULSEAUDIO_PlayDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
int available = h->mixlen;
|
||||
@@ -395,15 +379,12 @@ PULSEAUDIO_PlayDevice(_THIS)
|
||||
/*printf("PULSEAUDIO PLAYDEVICE END! written=%d\n", written);*/
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
PULSEAUDIO_GetDeviceBuf(_THIS)
|
||||
static Uint8 *PULSEAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return this->hidden->mixbuf;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
const void *data = NULL;
|
||||
@@ -418,40 +399,40 @@ PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
h->capturelen -= cpy;
|
||||
if (h->capturelen == 0) {
|
||||
h->capturebuf = NULL;
|
||||
PULSEAUDIO_pa_stream_drop(h->stream); /* done with this fragment. */
|
||||
PULSEAUDIO_pa_stream_drop(h->stream); /* done with this fragment. */
|
||||
}
|
||||
return cpy; /* new data, return it. */
|
||||
return cpy; /* new data, return it. */
|
||||
}
|
||||
|
||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return -1; /* uhoh, pulse failed! */
|
||||
return -1; /* uhoh, pulse failed! */
|
||||
}
|
||||
|
||||
if (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0) {
|
||||
continue; /* no data available yet. */
|
||||
continue; /* no data available yet. */
|
||||
}
|
||||
|
||||
/* a new fragment is available! */
|
||||
PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
|
||||
SDL_assert(nbytes > 0);
|
||||
if (data == NULL) { /* NULL==buffer had a hole. Ignore that. */
|
||||
PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */
|
||||
/* If data == NULL, then the buffer had a hole, ignore that */
|
||||
if (data == NULL) {
|
||||
PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */
|
||||
} else {
|
||||
/* store this fragment's data, start feeding it to SDL. */
|
||||
/*printf("PULSEAUDIO: captured %d new bytes\n", (int) nbytes);*/
|
||||
h->capturebuf = (const Uint8 *) data;
|
||||
h->capturebuf = (const Uint8 *)data;
|
||||
h->capturelen = nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* not enabled? */
|
||||
return -1; /* not enabled? */
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_FlushCapture(_THIS)
|
||||
static void PULSEAUDIO_FlushCapture(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
const void *data = NULL;
|
||||
@@ -468,21 +449,20 @@ PULSEAUDIO_FlushCapture(_THIS)
|
||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return; /* uhoh, pulse failed! */
|
||||
return; /* uhoh, pulse failed! */
|
||||
}
|
||||
|
||||
if (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0) {
|
||||
break; /* no data available, so we're done. */
|
||||
break; /* no data available, so we're done. */
|
||||
}
|
||||
|
||||
/* a new fragment is available! Just dump it. */
|
||||
PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
|
||||
PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */
|
||||
PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_CloseDevice(_THIS)
|
||||
static void PULSEAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->stream) {
|
||||
if (this->hidden->capturebuf != NULL) {
|
||||
@@ -498,48 +478,44 @@ PULSEAUDIO_CloseDevice(_THIS)
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static void
|
||||
SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
static void SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
{
|
||||
if (i) {
|
||||
char **devname = (char **) data;
|
||||
char **devname = (char **)data;
|
||||
*devname = SDL_strdup(i->name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
|
||||
static void SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
|
||||
{
|
||||
if (i) {
|
||||
char **devname = (char **) data;
|
||||
char **devname = (char **)data;
|
||||
*devname = SDL_strdup(i->name);
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
FindDeviceName(struct SDL_PrivateAudioData *h, const SDL_bool iscapture, void *handle)
|
||||
static SDL_bool FindDeviceName(struct SDL_PrivateAudioData *h, const SDL_bool iscapture, void *handle)
|
||||
{
|
||||
const uint32_t idx = ((uint32_t) ((intptr_t) handle)) - 1;
|
||||
const uint32_t idx = ((uint32_t)((intptr_t)handle)) - 1;
|
||||
|
||||
if (handle == NULL) { /* NULL == default device. */
|
||||
if (handle == NULL) { /* NULL == default device. */
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
WaitForPulseOperation(h->mainloop,
|
||||
PULSEAUDIO_pa_context_get_source_info_by_index(h->context, idx,
|
||||
SourceDeviceNameCallback, &h->device_name));
|
||||
PULSEAUDIO_pa_context_get_source_info_by_index(h->context, idx,
|
||||
SourceDeviceNameCallback, &h->device_name));
|
||||
} else {
|
||||
WaitForPulseOperation(h->mainloop,
|
||||
PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx,
|
||||
SinkDeviceNameCallback, &h->device_name));
|
||||
PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx,
|
||||
SinkDeviceNameCallback, &h->device_name));
|
||||
}
|
||||
|
||||
return h->device_name != NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = NULL;
|
||||
SDL_AudioFormat test_format;
|
||||
@@ -604,7 +580,7 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
/* Allocate mixing buffer */
|
||||
if (!iscapture) {
|
||||
h->mixlen = this->spec.size;
|
||||
h->mixbuf = (Uint8 *) SDL_malloc(h->mixlen);
|
||||
h->mixbuf = (Uint8 *)SDL_malloc(h->mixlen);
|
||||
if (h->mixbuf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -640,9 +616,9 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname)
|
||||
h->stream = PULSEAUDIO_pa_stream_new(
|
||||
h->context,
|
||||
(name && *name) ? name : "Audio Stream", /* stream description */
|
||||
&paspec, /* sample format spec */
|
||||
&pacmap /* channel map */
|
||||
);
|
||||
&paspec, /* sample format spec */
|
||||
&pacmap /* channel map */
|
||||
);
|
||||
|
||||
if (h->stream == NULL) {
|
||||
return SDL_SetError("Could not set up PulseAudio stream");
|
||||
@@ -692,8 +668,7 @@ static char *default_source_name = NULL;
|
||||
|
||||
/* device handles are device index + 1, cast to void*, so we never pass a NULL. */
|
||||
|
||||
static SDL_AudioFormat
|
||||
PulseFormatToSDLFormat(pa_sample_format_t format)
|
||||
static SDL_AudioFormat PulseFormatToSDLFormat(pa_sample_format_t format)
|
||||
{
|
||||
switch (format) {
|
||||
case PA_SAMPLE_U8:
|
||||
@@ -716,11 +691,10 @@ PulseFormatToSDLFormat(pa_sample_format_t format)
|
||||
}
|
||||
|
||||
/* This is called when PulseAudio adds an output ("sink") device. */
|
||||
static void
|
||||
SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
static void SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
{
|
||||
SDL_AudioSpec spec;
|
||||
SDL_bool add = (SDL_bool) ((intptr_t) data);
|
||||
SDL_bool add = (SDL_bool)((intptr_t)data);
|
||||
if (i) {
|
||||
spec.freq = i->sample_spec.rate;
|
||||
spec.channels = i->sample_spec.channels;
|
||||
@@ -732,7 +706,7 @@ SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
spec.userdata = NULL;
|
||||
|
||||
if (add) {
|
||||
SDL_AddAudioDevice(SDL_FALSE, i->description, &spec, (void *) ((intptr_t) i->index+1));
|
||||
SDL_AddAudioDevice(SDL_FALSE, i->description, &spec, (void *)((intptr_t)i->index + 1));
|
||||
}
|
||||
|
||||
if (default_sink_path != NULL && SDL_strcmp(i->name, default_sink_path) == 0) {
|
||||
@@ -745,11 +719,10 @@ SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
}
|
||||
|
||||
/* This is called when PulseAudio adds a capture ("source") device. */
|
||||
static void
|
||||
SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
|
||||
static void SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
|
||||
{
|
||||
SDL_AudioSpec spec;
|
||||
SDL_bool add = (SDL_bool) ((intptr_t) data);
|
||||
SDL_bool add = (SDL_bool)((intptr_t)data);
|
||||
if (i) {
|
||||
/* Maybe skip "monitor" sources. These are just output from other sinks. */
|
||||
if (include_monitors || (i->monitor_of_sink == PA_INVALID_INDEX)) {
|
||||
@@ -763,7 +736,7 @@ SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *da
|
||||
spec.userdata = NULL;
|
||||
|
||||
if (add) {
|
||||
SDL_AddAudioDevice(SDL_TRUE, i->description, &spec, (void *) ((intptr_t) i->index+1));
|
||||
SDL_AddAudioDevice(SDL_TRUE, i->description, &spec, (void *)((intptr_t)i->index + 1));
|
||||
}
|
||||
|
||||
if (default_source_path != NULL && SDL_strcmp(i->name, default_source_path) == 0) {
|
||||
@@ -776,8 +749,7 @@ SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *da
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ServerInfoCallback(pa_context *c, const pa_server_info *i, void *data)
|
||||
static void ServerInfoCallback(pa_context *c, const pa_server_info *i, void *data)
|
||||
{
|
||||
if (default_sink_path != NULL) {
|
||||
SDL_free(default_sink_path);
|
||||
@@ -790,14 +762,13 @@ ServerInfoCallback(pa_context *c, const pa_server_info *i, void *data)
|
||||
}
|
||||
|
||||
/* This is called when PulseAudio has a device connected/removed/changed. */
|
||||
static void
|
||||
HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *data)
|
||||
static void HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *data)
|
||||
{
|
||||
const SDL_bool added = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW);
|
||||
const SDL_bool removed = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE);
|
||||
const SDL_bool changed = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_CHANGE);
|
||||
|
||||
if (added || removed || changed) { /* we only care about add/remove events. */
|
||||
if (added || removed || changed) { /* we only care about add/remove events. */
|
||||
const SDL_bool sink = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK);
|
||||
const SDL_bool source = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE);
|
||||
|
||||
@@ -806,45 +777,42 @@ HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, voi
|
||||
if (changed) {
|
||||
PULSEAUDIO_pa_context_get_server_info(hotplug_context, ServerInfoCallback, NULL);
|
||||
}
|
||||
PULSEAUDIO_pa_context_get_sink_info_by_index(hotplug_context, idx, SinkInfoCallback, (void*) ((intptr_t) added));
|
||||
PULSEAUDIO_pa_context_get_sink_info_by_index(hotplug_context, idx, SinkInfoCallback, (void *)((intptr_t)added));
|
||||
} else if ((added || changed) && source) {
|
||||
if (changed) {
|
||||
PULSEAUDIO_pa_context_get_server_info(hotplug_context, ServerInfoCallback, NULL);
|
||||
}
|
||||
PULSEAUDIO_pa_context_get_source_info_by_index(hotplug_context, idx, SourceInfoCallback, (void*) ((intptr_t) added));
|
||||
PULSEAUDIO_pa_context_get_source_info_by_index(hotplug_context, idx, SourceInfoCallback, (void *)((intptr_t)added));
|
||||
} else if (removed && (sink || source)) {
|
||||
/* removes we can handle just with the device index. */
|
||||
SDL_RemoveAudioDevice(source != 0, (void *) ((intptr_t) idx+1));
|
||||
SDL_RemoveAudioDevice(source != 0, (void *)((intptr_t)idx + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this runs as a thread while the Pulse target is initialized to catch hotplug events. */
|
||||
static int SDLCALL
|
||||
HotplugThread(void *data)
|
||||
static int SDLCALL HotplugThread(void *data)
|
||||
{
|
||||
pa_operation *o;
|
||||
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
|
||||
PULSEAUDIO_pa_context_set_subscribe_callback(hotplug_context, HotplugCallback, NULL);
|
||||
o = PULSEAUDIO_pa_context_subscribe(hotplug_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE, NULL, NULL);
|
||||
PULSEAUDIO_pa_operation_unref(o); /* don't wait for it, just do our thing. */
|
||||
PULSEAUDIO_pa_operation_unref(o); /* don't wait for it, just do our thing. */
|
||||
PULSEAUDIO_pa_mainloop_run(hotplug_mainloop, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_DetectDevices()
|
||||
static void PULSEAUDIO_DetectDevices()
|
||||
{
|
||||
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_server_info(hotplug_context, ServerInfoCallback, NULL));
|
||||
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_sink_info_list(hotplug_context, SinkInfoCallback, (void*) ((intptr_t) SDL_TRUE)));
|
||||
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_source_info_list(hotplug_context, SourceInfoCallback, (void*) ((intptr_t) SDL_TRUE)));
|
||||
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_sink_info_list(hotplug_context, SinkInfoCallback, (void *)((intptr_t)SDL_TRUE)));
|
||||
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_source_info_list(hotplug_context, SourceInfoCallback, (void *)((intptr_t)SDL_TRUE)));
|
||||
|
||||
/* ok, we have a sane list, let's set up hotplug notifications now... */
|
||||
hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
PULSEAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
static int PULSEAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
int i;
|
||||
int numdevices;
|
||||
@@ -875,8 +843,7 @@ PULSEAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
return SDL_SetError("Could not find default PulseAudio device");
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_Deinitialize(void)
|
||||
static void PULSEAUDIO_Deinitialize(void)
|
||||
{
|
||||
if (hotplug_thread) {
|
||||
PULSEAUDIO_pa_mainloop_quit(hotplug_mainloop, 0);
|
||||
@@ -908,8 +875,7 @@ PULSEAUDIO_Deinitialize(void)
|
||||
UnloadPulseAudioLibrary();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool PULSEAUDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
if (LoadPulseAudioLibrary() < 0) {
|
||||
return SDL_FALSE;
|
||||
@@ -937,7 +903,7 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->SupportsNonPow2Samples = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap PULSEAUDIO_bootstrap = {
|
||||
|
||||
@@ -43,7 +43,7 @@ struct SDL_PrivateAudioData
|
||||
Uint8 *mixbuf;
|
||||
int mixlen;
|
||||
|
||||
int bytes_requested; /* bytes of data the hardware wants _now_. */
|
||||
int bytes_requested; /* bytes of data the hardware wants _now_. */
|
||||
|
||||
const Uint8 *capturebuf;
|
||||
int capturelen;
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#define SIO_DEVANY "default"
|
||||
#endif
|
||||
|
||||
static struct sio_hdl * (*SNDIO_sio_open)(const char *, unsigned int, int);
|
||||
static struct sio_hdl *(*SNDIO_sio_open)(const char *, unsigned int, int);
|
||||
static void (*SNDIO_sio_close)(struct sio_hdl *);
|
||||
static int (*SNDIO_sio_setpar)(struct sio_hdl *, struct sio_par *);
|
||||
static int (*SNDIO_sio_getpar)(struct sio_hdl *, struct sio_par *);
|
||||
@@ -68,8 +68,7 @@ static void (*SNDIO_sio_initpar)(struct sio_par *);
|
||||
static const char *sndio_library = SDL_AUDIO_DRIVER_SNDIO_DYNAMIC;
|
||||
static void *sndio_handle = NULL;
|
||||
|
||||
static int
|
||||
load_sndio_sym(const char *fn, void **addr)
|
||||
static int load_sndio_sym(const char *fn, void **addr)
|
||||
{
|
||||
*addr = SDL_LoadFunction(sndio_handle, fn);
|
||||
if (*addr == NULL) {
|
||||
@@ -81,14 +80,14 @@ load_sndio_sym(const char *fn, void **addr)
|
||||
}
|
||||
|
||||
/* cast funcs to char* first, to please GCC's strict aliasing rules. */
|
||||
#define SDL_SNDIO_SYM(x) \
|
||||
if (!load_sndio_sym(#x, (void **) (char *) &SNDIO_##x)) return -1
|
||||
#define SDL_SNDIO_SYM(x) \
|
||||
if (!load_sndio_sym(#x, (void **)(char *)&SNDIO_##x)) \
|
||||
return -1
|
||||
#else
|
||||
#define SDL_SNDIO_SYM(x) SNDIO_##x = x
|
||||
#endif
|
||||
|
||||
static int
|
||||
load_sndio_syms(void)
|
||||
static int load_sndio_syms(void)
|
||||
{
|
||||
SDL_SNDIO_SYM(sio_open);
|
||||
SDL_SNDIO_SYM(sio_close);
|
||||
@@ -110,8 +109,7 @@ load_sndio_syms(void)
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC
|
||||
|
||||
static void
|
||||
UnloadSNDIOLibrary(void)
|
||||
static void UnloadSNDIOLibrary(void)
|
||||
{
|
||||
if (sndio_handle != NULL) {
|
||||
SDL_UnloadObject(sndio_handle);
|
||||
@@ -119,8 +117,7 @@ UnloadSNDIOLibrary(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
LoadSNDIOLibrary(void)
|
||||
static int LoadSNDIOLibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
if (sndio_handle == NULL) {
|
||||
@@ -140,13 +137,11 @@ LoadSNDIOLibrary(void)
|
||||
|
||||
#else
|
||||
|
||||
static void
|
||||
UnloadSNDIOLibrary(void)
|
||||
static void UnloadSNDIOLibrary(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
LoadSNDIOLibrary(void)
|
||||
static int LoadSNDIOLibrary(void)
|
||||
{
|
||||
load_sndio_syms();
|
||||
return 0;
|
||||
@@ -154,24 +149,19 @@ LoadSNDIOLibrary(void)
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
SNDIO_WaitDevice(_THIS)
|
||||
static void SNDIO_WaitDevice(_THIS)
|
||||
{
|
||||
/* no-op; SNDIO_sio_write() blocks if necessary. */
|
||||
}
|
||||
|
||||
static void
|
||||
SNDIO_PlayDevice(_THIS)
|
||||
static void SNDIO_PlayDevice(_THIS)
|
||||
{
|
||||
const int written = SNDIO_sio_write(this->hidden->dev,
|
||||
this->hidden->mixbuf,
|
||||
this->hidden->mixlen);
|
||||
|
||||
/* If we couldn't write, assume fatal error for now */
|
||||
if ( written == 0 ) {
|
||||
if (written == 0) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
#ifdef DEBUG_AUDIO
|
||||
@@ -179,8 +169,7 @@ SNDIO_PlayDevice(_THIS)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
size_t r;
|
||||
int revents;
|
||||
@@ -189,8 +178,7 @@ SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
/* Emulate a blocking read */
|
||||
r = SNDIO_sio_read(this->hidden->dev, buffer, buflen);
|
||||
while (r == 0 && !SNDIO_sio_eof(this->hidden->dev)) {
|
||||
if ((nfds = SNDIO_sio_pollfd(this->hidden->dev, this->hidden->pfd, POLLIN)) <= 0
|
||||
|| poll(this->hidden->pfd, nfds, INFTIM) < 0) {
|
||||
if ((nfds = SNDIO_sio_pollfd(this->hidden->dev, this->hidden->pfd, POLLIN)) <= 0 || poll(this->hidden->pfd, nfds, INFTIM) < 0) {
|
||||
return -1;
|
||||
}
|
||||
revents = SNDIO_sio_revents(this->hidden->dev, this->hidden->pfd);
|
||||
@@ -201,11 +189,10 @@ SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (int) r;
|
||||
return (int)r;
|
||||
}
|
||||
|
||||
static void
|
||||
SNDIO_FlushCapture(_THIS)
|
||||
static void SNDIO_FlushCapture(_THIS)
|
||||
{
|
||||
char buf[512];
|
||||
|
||||
@@ -214,19 +201,17 @@ SNDIO_FlushCapture(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
SNDIO_GetDeviceBuf(_THIS)
|
||||
static Uint8 *SNDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return this->hidden->mixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
SNDIO_CloseDevice(_THIS)
|
||||
static void SNDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if ( this->hidden->pfd != NULL ) {
|
||||
if (this->hidden->pfd != NULL) {
|
||||
SDL_free(this->hidden->pfd);
|
||||
}
|
||||
if ( this->hidden->dev != NULL ) {
|
||||
if (this->hidden->dev != NULL) {
|
||||
SNDIO_sio_stop(this->hidden->dev);
|
||||
SNDIO_sio_close(this->hidden->dev);
|
||||
}
|
||||
@@ -234,8 +219,7 @@ SNDIO_CloseDevice(_THIS)
|
||||
SDL_free(this->hidden);
|
||||
}
|
||||
|
||||
static int
|
||||
SNDIO_OpenDevice(_THIS, const char *devname)
|
||||
static int SNDIO_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
SDL_AudioFormat test_format;
|
||||
struct sio_par par;
|
||||
@@ -252,14 +236,14 @@ SNDIO_OpenDevice(_THIS, const char *devname)
|
||||
|
||||
/* Capture devices must be non-blocking for SNDIO_FlushCapture */
|
||||
if ((this->hidden->dev =
|
||||
SNDIO_sio_open(devname != NULL ? devname : SIO_DEVANY,
|
||||
iscapture ? SIO_REC : SIO_PLAY, iscapture)) == NULL) {
|
||||
SNDIO_sio_open(devname != NULL ? devname : SIO_DEVANY,
|
||||
iscapture ? SIO_REC : SIO_PLAY, iscapture)) == NULL) {
|
||||
return SDL_SetError("sio_open() failed");
|
||||
}
|
||||
|
||||
/* Allocate the pollfd array for capture devices */
|
||||
if (iscapture && (this->hidden->pfd =
|
||||
SDL_malloc(sizeof(struct pollfd) * SNDIO_sio_nfds(this->hidden->dev))) == NULL) {
|
||||
SDL_malloc(sizeof(struct pollfd) * SNDIO_sio_nfds(this->hidden->dev))) == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
@@ -325,7 +309,7 @@ SNDIO_OpenDevice(_THIS, const char *devname)
|
||||
|
||||
/* Allocate mixing buffer */
|
||||
this->hidden->mixlen = this->spec.size;
|
||||
this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
|
||||
this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen);
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -339,21 +323,18 @@ SNDIO_OpenDevice(_THIS, const char *devname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
SNDIO_Deinitialize(void)
|
||||
static void SNDIO_Deinitialize(void)
|
||||
{
|
||||
UnloadSNDIOLibrary();
|
||||
}
|
||||
|
||||
static void
|
||||
SNDIO_DetectDevices(void)
|
||||
static void SNDIO_DetectDevices(void)
|
||||
{
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *) 0x1);
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *) 0x2);
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)0x1);
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)0x2);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
SNDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool SNDIO_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
if (LoadSNDIOLibrary() < 0) {
|
||||
return SDL_FALSE;
|
||||
@@ -373,7 +354,7 @@ SNDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap SNDIO_bootstrap = {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
|
||||
@@ -36,11 +36,10 @@
|
||||
#include <psp2/audioout.h>
|
||||
#include <psp2/audioin.h>
|
||||
|
||||
#define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63)
|
||||
#define SCE_AUDIO_MAX_VOLUME 0x8000
|
||||
#define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63)
|
||||
#define SCE_AUDIO_MAX_VOLUME 0x8000
|
||||
|
||||
static int
|
||||
VITAAUD_OpenCaptureDevice(_THIS)
|
||||
static int VITAAUD_OpenCaptureDevice(_THIS)
|
||||
{
|
||||
this->spec.freq = 16000;
|
||||
this->spec.samples = 512;
|
||||
@@ -48,7 +47,7 @@ VITAAUD_OpenCaptureDevice(_THIS)
|
||||
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE , 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO);
|
||||
this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE, 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO);
|
||||
|
||||
if (this->hidden->port < 0) {
|
||||
return SDL_SetError("Couldn't open audio in port: %x", this->hidden->port);
|
||||
@@ -57,11 +56,10 @@ VITAAUD_OpenCaptureDevice(_THIS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
VITAAUD_OpenDevice(_THIS, const char *devname)
|
||||
static int VITAAUD_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
int format, mixlen, i, port = SCE_AUDIO_OUT_PORT_TYPE_MAIN;
|
||||
int vols[2] = {SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME};
|
||||
int vols[2] = { SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME };
|
||||
SDL_AudioFormat test_format;
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
@@ -96,7 +94,7 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
|
||||
be a multiple of 64 bytes. Our sample count is already a multiple of
|
||||
64, so spec->size should be a multiple of 64 as well. */
|
||||
mixlen = this->spec.size * NUM_BUFFERS;
|
||||
this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen);
|
||||
this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen);
|
||||
if (this->hidden->rawbuf == NULL) {
|
||||
return SDL_SetError("Couldn't allocate mixing buffer");
|
||||
}
|
||||
@@ -119,7 +117,7 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
|
||||
return SDL_SetError("Couldn't open audio out port: %x", this->hidden->port);
|
||||
}
|
||||
|
||||
sceAudioOutSetVolume(this->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
|
||||
sceAudioOutSetVolume(this->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
|
||||
|
||||
SDL_memset(this->hidden->rawbuf, 0, mixlen);
|
||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||
@@ -162,7 +160,7 @@ static void VITAAUD_CloseDevice(_THIS)
|
||||
}
|
||||
|
||||
if (!this->iscapture && this->hidden->rawbuf != NULL) {
|
||||
free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */
|
||||
free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */
|
||||
this->hidden->rawbuf = NULL;
|
||||
}
|
||||
}
|
||||
@@ -191,8 +189,7 @@ static void VITAAUD_ThreadInit(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
VITAAUD_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool VITAAUD_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = VITAAUD_OpenDevice;
|
||||
@@ -209,7 +206,7 @@ VITAAUD_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap VITAAUD_bootstrap = {
|
||||
|
||||
@@ -25,19 +25,20 @@
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
#define NUM_BUFFERS 2
|
||||
|
||||
struct SDL_PrivateAudioData {
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
/* The hardware input/output port. */
|
||||
int port;
|
||||
int port;
|
||||
/* The raw allocated mixing buffer. */
|
||||
Uint8 *rawbuf;
|
||||
Uint8 *rawbuf;
|
||||
/* Individual mixing buffers. */
|
||||
Uint8 *mixbufs[NUM_BUFFERS];
|
||||
Uint8 *mixbufs[NUM_BUFFERS];
|
||||
/* Index of the next available mixing buffer. */
|
||||
int next_buffer;
|
||||
int next_buffer;
|
||||
};
|
||||
|
||||
#endif /* _SDL_vitaaudio_h */
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
/* These constants aren't available in older SDKs */
|
||||
#ifndef AUDCLNT_STREAMFLAGS_RATEADJUST
|
||||
#define AUDCLNT_STREAMFLAGS_RATEADJUST 0x00100000
|
||||
#define AUDCLNT_STREAMFLAGS_RATEADJUST 0x00100000
|
||||
#endif
|
||||
#ifndef AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY
|
||||
#define AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY 0x08000000
|
||||
@@ -44,17 +44,15 @@
|
||||
#endif
|
||||
|
||||
/* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */
|
||||
static const IID SDL_IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483,{ 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2 } };
|
||||
static const IID SDL_IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0,{ 0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17 } };
|
||||
static const IID SDL_IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483, { 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2 } };
|
||||
static const IID SDL_IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0, { 0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17 } };
|
||||
|
||||
static void
|
||||
WASAPI_DetectDevices(void)
|
||||
static void WASAPI_DetectDevices(void)
|
||||
{
|
||||
WASAPI_EnumerateEndpoints();
|
||||
}
|
||||
|
||||
static SDL_INLINE SDL_bool
|
||||
WasapiFailed(_THIS, const HRESULT err)
|
||||
static SDL_INLINE SDL_bool WasapiFailed(_THIS, const HRESULT err)
|
||||
{
|
||||
if (err == S_OK) {
|
||||
return SDL_FALSE;
|
||||
@@ -71,39 +69,38 @@ WasapiFailed(_THIS, const HRESULT err)
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
|
||||
static int UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
|
||||
{
|
||||
/* Since WASAPI requires us to handle all audio conversion, and our
|
||||
device format might have changed, we might have to add/remove/change
|
||||
the audio stream that the higher level uses to convert data, so
|
||||
SDL keeps firing the callback as if nothing happened here. */
|
||||
|
||||
if ( (this->callbackspec.channels == this->spec.channels) &&
|
||||
(this->callbackspec.format == this->spec.format) &&
|
||||
(this->callbackspec.freq == this->spec.freq) &&
|
||||
(this->callbackspec.samples == this->spec.samples) ) {
|
||||
if ((this->callbackspec.channels == this->spec.channels) &&
|
||||
(this->callbackspec.format == this->spec.format) &&
|
||||
(this->callbackspec.freq == this->spec.freq) &&
|
||||
(this->callbackspec.samples == this->spec.samples)) {
|
||||
/* no need to buffer/convert in an AudioStream! */
|
||||
SDL_FreeAudioStream(this->stream);
|
||||
this->stream = NULL;
|
||||
} else if ( (oldspec->channels == this->spec.channels) &&
|
||||
(oldspec->format == this->spec.format) &&
|
||||
(oldspec->freq == this->spec.freq) ) {
|
||||
} else if ((oldspec->channels == this->spec.channels) &&
|
||||
(oldspec->format == this->spec.format) &&
|
||||
(oldspec->freq == this->spec.freq)) {
|
||||
/* The existing audio stream is okay to keep using. */
|
||||
} else {
|
||||
/* replace the audiostream for new format */
|
||||
SDL_FreeAudioStream(this->stream);
|
||||
if (this->iscapture) {
|
||||
this->stream = SDL_NewAudioStream(this->spec.format,
|
||||
this->spec.channels, this->spec.freq,
|
||||
this->callbackspec.format,
|
||||
this->callbackspec.channels,
|
||||
this->callbackspec.freq);
|
||||
this->spec.channels, this->spec.freq,
|
||||
this->callbackspec.format,
|
||||
this->callbackspec.channels,
|
||||
this->callbackspec.freq);
|
||||
} else {
|
||||
this->stream = SDL_NewAudioStream(this->callbackspec.format,
|
||||
this->callbackspec.channels,
|
||||
this->callbackspec.freq, this->spec.format,
|
||||
this->spec.channels, this->spec.freq);
|
||||
this->callbackspec.channels,
|
||||
this->callbackspec.freq, this->spec.format,
|
||||
this->spec.channels, this->spec.freq);
|
||||
}
|
||||
|
||||
if (!this->stream) {
|
||||
@@ -113,7 +110,7 @@ UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
|
||||
|
||||
/* make sure our scratch buffer can cover the new device spec. */
|
||||
if (this->spec.size > this->work_buffer_len) {
|
||||
Uint8 *ptr = (Uint8 *) SDL_realloc(this->work_buffer, this->spec.size);
|
||||
Uint8 *ptr = (Uint8 *)SDL_realloc(this->work_buffer, this->spec.size);
|
||||
if (ptr == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
@@ -124,16 +121,14 @@ UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void ReleaseWasapiDevice(_THIS);
|
||||
|
||||
static SDL_bool
|
||||
RecoverWasapiDevice(_THIS)
|
||||
static SDL_bool RecoverWasapiDevice(_THIS)
|
||||
{
|
||||
ReleaseWasapiDevice(this); /* dump the lost device's handles. */
|
||||
ReleaseWasapiDevice(this); /* dump the lost device's handles. */
|
||||
|
||||
if (this->hidden->default_device_generation) {
|
||||
this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration);
|
||||
this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration);
|
||||
}
|
||||
|
||||
/* this can fail for lots of reasons, but the most likely is we had a
|
||||
@@ -148,26 +143,25 @@ RecoverWasapiDevice(_THIS)
|
||||
|
||||
this->hidden->device_lost = SDL_FALSE;
|
||||
|
||||
return SDL_TRUE; /* okay, carry on with new device details! */
|
||||
return SDL_TRUE; /* okay, carry on with new device details! */
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
RecoverWasapiIfLost(_THIS)
|
||||
static SDL_bool RecoverWasapiIfLost(_THIS)
|
||||
{
|
||||
const int generation = this->hidden->default_device_generation;
|
||||
SDL_bool lost = this->hidden->device_lost;
|
||||
|
||||
if (!SDL_AtomicGet(&this->enabled)) {
|
||||
return SDL_FALSE; /* already failed. */
|
||||
return SDL_FALSE; /* already failed. */
|
||||
}
|
||||
|
||||
if (!this->hidden->client) {
|
||||
return SDL_TRUE; /* still waiting for activation. */
|
||||
return SDL_TRUE; /* still waiting for activation. */
|
||||
}
|
||||
|
||||
if (!lost && (generation > 0)) { /* is a default device? */
|
||||
const int newgen = SDL_AtomicGet(this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration);
|
||||
if (generation != newgen) { /* the desired default device was changed, jump over to it. */
|
||||
if (generation != newgen) { /* the desired default device was changed, jump over to it. */
|
||||
lost = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
@@ -175,33 +169,30 @@ RecoverWasapiIfLost(_THIS)
|
||||
return lost ? RecoverWasapiDevice(this) : SDL_TRUE;
|
||||
}
|
||||
|
||||
static Uint8 *
|
||||
WASAPI_GetDeviceBuf(_THIS)
|
||||
static Uint8 *WASAPI_GetDeviceBuf(_THIS)
|
||||
{
|
||||
/* get an endpoint buffer from WASAPI. */
|
||||
BYTE *buffer = NULL;
|
||||
|
||||
while (RecoverWasapiIfLost(this) && this->hidden->render) {
|
||||
if (!WasapiFailed(this, IAudioRenderClient_GetBuffer(this->hidden->render, this->spec.samples, &buffer))) {
|
||||
return (Uint8 *) buffer;
|
||||
return (Uint8 *)buffer;
|
||||
}
|
||||
SDL_assert(buffer == NULL);
|
||||
}
|
||||
|
||||
return (Uint8 *) buffer;
|
||||
return (Uint8 *)buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_PlayDevice(_THIS)
|
||||
static void WASAPI_PlayDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->render != NULL) { /* definitely activated? */
|
||||
if (this->hidden->render != NULL) { /* definitely activated? */
|
||||
/* WasapiFailed() will mark the device for reacquisition or removal elsewhere. */
|
||||
WasapiFailed(this, IAudioRenderClient_ReleaseBuffer(this->hidden->render, this->spec.samples, 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_WaitDevice(_THIS)
|
||||
static void WASAPI_WaitDevice(_THIS)
|
||||
{
|
||||
while (RecoverWasapiIfLost(this) && this->hidden->client && this->hidden->event) {
|
||||
DWORD waitResult = WaitForSingleObjectEx(this->hidden->event, 200, FALSE);
|
||||
@@ -228,8 +219,7 @@ WASAPI_WaitDevice(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
static int WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
SDL_AudioStream *stream = this->hidden->capturestream;
|
||||
const int avail = SDL_AudioStreamAvailable(stream);
|
||||
@@ -261,7 +251,7 @@ WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
if ((ret == AUDCLNT_S_BUFFER_EMPTY) || !frames) {
|
||||
WASAPI_WaitDevice(this);
|
||||
} else if (ret == S_OK) {
|
||||
const int total = ((int) frames) * this->hidden->framesize;
|
||||
const int total = ((int)frames) * this->hidden->framesize;
|
||||
const int cpy = SDL_min(buflen, total);
|
||||
const int leftover = total - cpy;
|
||||
const SDL_bool silent = (flags & AUDCLNT_BUFFERFLAGS_SILENT) ? SDL_TRUE : SDL_FALSE;
|
||||
@@ -271,15 +261,15 @@ WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
} else {
|
||||
SDL_memcpy(buffer, ptr, cpy);
|
||||
}
|
||||
|
||||
|
||||
if (leftover > 0) {
|
||||
ptr += cpy;
|
||||
if (silent) {
|
||||
SDL_memset(ptr, this->spec.silence, leftover); /* I guess this is safe? */
|
||||
SDL_memset(ptr, this->spec.silence, leftover); /* I guess this is safe? */
|
||||
}
|
||||
|
||||
if (SDL_AudioStreamPut(stream, ptr, leftover) == -1) {
|
||||
return -1; /* uhoh, out of memory, etc. Kill device. :( */
|
||||
return -1; /* uhoh, out of memory, etc. Kill device. :( */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,36 +280,34 @@ WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* unrecoverable error. */
|
||||
return -1; /* unrecoverable error. */
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_FlushCapture(_THIS)
|
||||
static void WASAPI_FlushCapture(_THIS)
|
||||
{
|
||||
BYTE *ptr = NULL;
|
||||
UINT32 frames = 0;
|
||||
DWORD flags = 0;
|
||||
|
||||
if (!this->hidden->capture) {
|
||||
return; /* not activated yet? */
|
||||
return; /* not activated yet? */
|
||||
}
|
||||
|
||||
/* just read until we stop getting packets, throwing them away. */
|
||||
while (SDL_TRUE) {
|
||||
const HRESULT ret = IAudioCaptureClient_GetBuffer(this->hidden->capture, &ptr, &frames, &flags, NULL, NULL);
|
||||
if (ret == AUDCLNT_S_BUFFER_EMPTY) {
|
||||
break; /* no more buffered data; we're done. */
|
||||
break; /* no more buffered data; we're done. */
|
||||
} else if (WasapiFailed(this, ret)) {
|
||||
break; /* failed for some other reason, abort. */
|
||||
break; /* failed for some other reason, abort. */
|
||||
} else if (WasapiFailed(this, IAudioCaptureClient_ReleaseBuffer(this->hidden->capture, frames))) {
|
||||
break; /* something broke. */
|
||||
break; /* something broke. */
|
||||
}
|
||||
}
|
||||
SDL_AudioStreamClear(this->hidden->capturestream);
|
||||
}
|
||||
|
||||
static void
|
||||
ReleaseWasapiDevice(_THIS)
|
||||
static void ReleaseWasapiDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->client) {
|
||||
IAudioClient_Stop(this->hidden->client);
|
||||
@@ -358,20 +346,17 @@ ReleaseWasapiDevice(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_CloseDevice(_THIS)
|
||||
static void WASAPI_CloseDevice(_THIS)
|
||||
{
|
||||
WASAPI_UnrefDevice(this);
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_RefDevice(_THIS)
|
||||
void WASAPI_RefDevice(_THIS)
|
||||
{
|
||||
SDL_AtomicIncRef(&this->hidden->refcount);
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_UnrefDevice(_THIS)
|
||||
void WASAPI_UnrefDevice(_THIS)
|
||||
{
|
||||
if (!SDL_AtomicDecRef(&this->hidden->refcount)) {
|
||||
return;
|
||||
@@ -388,8 +373,7 @@ WASAPI_UnrefDevice(_THIS)
|
||||
}
|
||||
|
||||
/* This is called once a device is activated, possibly asynchronously. */
|
||||
int
|
||||
WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||
int WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||
{
|
||||
/* !!! FIXME: we could request an exclusive mode stream, which is lower latency;
|
||||
!!! it will write into the kernel's audio buffer directly instead of
|
||||
@@ -404,7 +388,7 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||
!!! do in any case. */
|
||||
const SDL_AudioSpec oldspec = this->spec;
|
||||
const AUDCLNT_SHAREMODE sharemode = AUDCLNT_SHAREMODE_SHARED;
|
||||
UINT32 bufsize = 0; /* this is in sample frames, not samples, not bytes. */
|
||||
UINT32 bufsize = 0; /* this is in sample frames, not samples, not bytes. */
|
||||
REFERENCE_TIME default_period = 0;
|
||||
IAudioClient *client = this->hidden->client;
|
||||
IAudioRenderClient *render = NULL;
|
||||
@@ -435,7 +419,7 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||
SDL_assert(waveformat != NULL);
|
||||
this->hidden->waveformat = waveformat;
|
||||
|
||||
this->spec.channels = (Uint8) waveformat->nChannels;
|
||||
this->spec.channels = (Uint8)waveformat->nChannels;
|
||||
|
||||
/* Make sure we have a valid format that we can convert to whatever WASAPI wants. */
|
||||
wasapi_format = WaveFormatToSDLFormat(waveformat);
|
||||
@@ -502,10 +486,10 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||
if (this->iscapture) {
|
||||
this->hidden->capturestream = SDL_NewAudioStream(this->spec.format, this->spec.channels, this->spec.freq, this->spec.format, this->spec.channels, this->spec.freq);
|
||||
if (!this->hidden->capturestream) {
|
||||
return -1; /* already set SDL_Error */
|
||||
return -1; /* already set SDL_Error */
|
||||
}
|
||||
|
||||
ret = IAudioClient_GetService(client, &SDL_IID_IAudioCaptureClient, (void**) &capture);
|
||||
ret = IAudioClient_GetService(client, &SDL_IID_IAudioCaptureClient, (void **)&capture);
|
||||
if (FAILED(ret)) {
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't get capture client service", ret);
|
||||
}
|
||||
@@ -517,9 +501,9 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't start capture", ret);
|
||||
}
|
||||
|
||||
WASAPI_FlushCapture(this); /* MSDN says you should flush capture endpoint right after startup. */
|
||||
WASAPI_FlushCapture(this); /* MSDN says you should flush capture endpoint right after startup. */
|
||||
} else {
|
||||
ret = IAudioClient_GetService(client, &SDL_IID_IAudioRenderClient, (void**) &render);
|
||||
ret = IAudioClient_GetService(client, &SDL_IID_IAudioRenderClient, (void **)&render);
|
||||
if (FAILED(ret)) {
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't get render client service", ret);
|
||||
}
|
||||
@@ -536,14 +520,12 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||
return UpdateAudioStream(this, &oldspec);
|
||||
}
|
||||
|
||||
return 0; /* good to go. */
|
||||
return 0; /* good to go. */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
WASAPI_OpenDevice(_THIS, const char *devname)
|
||||
static int WASAPI_OpenDevice(_THIS, const char *devname)
|
||||
{
|
||||
LPCWSTR devid = (LPCWSTR) this->handle;
|
||||
LPCWSTR devid = (LPCWSTR)this->handle;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
@@ -553,9 +535,9 @@ WASAPI_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
||||
WASAPI_RefDevice(this); /* so CloseDevice() will unref to zero. */
|
||||
WASAPI_RefDevice(this); /* so CloseDevice() will unref to zero. */
|
||||
|
||||
if (!devid) { /* is default device? */
|
||||
if (!devid) { /* is default device? */
|
||||
this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration);
|
||||
} else {
|
||||
this->hidden->devid = SDL_wcsdup(devid);
|
||||
@@ -565,7 +547,7 @@ WASAPI_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
|
||||
if (WASAPI_ActivateDevice(this, SDL_FALSE) == -1) {
|
||||
return -1; /* already set error. */
|
||||
return -1; /* already set error. */
|
||||
}
|
||||
|
||||
/* Ready, but waiting for async device activation.
|
||||
@@ -579,26 +561,22 @@ WASAPI_OpenDevice(_THIS, const char *devname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_ThreadInit(_THIS)
|
||||
static void WASAPI_ThreadInit(_THIS)
|
||||
{
|
||||
WASAPI_PlatformThreadInit(this);
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_ThreadDeinit(_THIS)
|
||||
static void WASAPI_ThreadDeinit(_THIS)
|
||||
{
|
||||
WASAPI_PlatformThreadDeinit(this);
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_Deinitialize(void)
|
||||
static void WASAPI_Deinitialize(void)
|
||||
{
|
||||
WASAPI_PlatformDeinit();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WASAPI_Init(SDL_AudioDriverImpl * impl)
|
||||
static SDL_bool WASAPI_Init(SDL_AudioDriverImpl *impl)
|
||||
{
|
||||
if (WASAPI_PlatformInit() == -1) {
|
||||
return SDL_FALSE;
|
||||
@@ -620,13 +598,13 @@ WASAPI_Init(SDL_AudioDriverImpl * impl)
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->SupportsNonPow2Samples = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
AudioBootStrap WASAPI_bootstrap = {
|
||||
"wasapi", "WASAPI", WASAPI_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_WASAPI */
|
||||
#endif /* SDL_AUDIO_DRIVER_WASAPI */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -45,26 +45,24 @@ static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL;
|
||||
static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL;
|
||||
|
||||
/* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */
|
||||
static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32,{ 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } };
|
||||
static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32, { 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } };
|
||||
|
||||
int
|
||||
WASAPI_PlatformInit(void)
|
||||
int WASAPI_PlatformInit(void)
|
||||
{
|
||||
if (SDL_IMMDevice_Init() < 0) {
|
||||
return -1; /* This is set by SDL_IMMDevice_Init */
|
||||
}
|
||||
|
||||
libavrt = LoadLibrary(TEXT("avrt.dll")); /* this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now! */
|
||||
libavrt = LoadLibrary(TEXT("avrt.dll")); /* this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now! */
|
||||
if (libavrt) {
|
||||
pAvSetMmThreadCharacteristicsW = (pfnAvSetMmThreadCharacteristicsW) GetProcAddress(libavrt, "AvSetMmThreadCharacteristicsW");
|
||||
pAvRevertMmThreadCharacteristics = (pfnAvRevertMmThreadCharacteristics) GetProcAddress(libavrt, "AvRevertMmThreadCharacteristics");
|
||||
pAvSetMmThreadCharacteristicsW = (pfnAvSetMmThreadCharacteristicsW)GetProcAddress(libavrt, "AvSetMmThreadCharacteristicsW");
|
||||
pAvRevertMmThreadCharacteristics = (pfnAvRevertMmThreadCharacteristics)GetProcAddress(libavrt, "AvRevertMmThreadCharacteristics");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformDeinit(void)
|
||||
void WASAPI_PlatformDeinit(void)
|
||||
{
|
||||
if (libavrt) {
|
||||
FreeLibrary(libavrt);
|
||||
@@ -77,11 +75,10 @@ WASAPI_PlatformDeinit(void)
|
||||
SDL_IMMDevice_Quit();
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformThreadInit(_THIS)
|
||||
void WASAPI_PlatformThreadInit(_THIS)
|
||||
{
|
||||
/* this thread uses COM. */
|
||||
if (SUCCEEDED(WIN_CoInitialize())) { /* can't report errors, hope it worked! */
|
||||
if (SUCCEEDED(WIN_CoInitialize())) { /* can't report errors, hope it worked! */
|
||||
this->hidden->coinitialized = SDL_TRUE;
|
||||
}
|
||||
|
||||
@@ -92,8 +89,7 @@ WASAPI_PlatformThreadInit(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformThreadDeinit(_THIS)
|
||||
void WASAPI_PlatformThreadDeinit(_THIS)
|
||||
{
|
||||
/* Set this thread back to normal priority. */
|
||||
if (this->hidden->task && pAvRevertMmThreadCharacteristics) {
|
||||
@@ -107,8 +103,7 @@ WASAPI_PlatformThreadDeinit(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
{
|
||||
IMMDevice *device = NULL;
|
||||
HRESULT ret;
|
||||
@@ -119,7 +114,7 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
}
|
||||
|
||||
/* this is not async in standard win32, yay! */
|
||||
ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **) &this->hidden->client);
|
||||
ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&this->hidden->client);
|
||||
IMMDevice_Release(device);
|
||||
|
||||
if (FAILED(ret)) {
|
||||
@@ -128,33 +123,29 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
}
|
||||
|
||||
SDL_assert(this->hidden->client != NULL);
|
||||
if (WASAPI_PrepDevice(this, isrecovery) == -1) { /* not async, fire it right away. */
|
||||
if (WASAPI_PrepDevice(this, isrecovery) == -1) { /* not async, fire it right away. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; /* good to go. */
|
||||
return 0; /* good to go. */
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_EnumerateEndpoints(void)
|
||||
void WASAPI_EnumerateEndpoints(void)
|
||||
{
|
||||
SDL_IMMDevice_EnumerateEndpoints(SDL_FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
return SDL_IMMDevice_GetDefaultAudioInfo(name, spec, iscapture);
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformDeleteActivationHandler(void *handler)
|
||||
void WASAPI_PlatformDeleteActivationHandler(void *handler)
|
||||
{
|
||||
/* not asynchronous. */
|
||||
SDL_assert(!"This function should have only been called on WinRT.");
|
||||
}
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */
|
||||
#endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
|
||||
@@ -51,13 +51,13 @@ using namespace Windows::Media::Devices;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
static Platform::String^ SDL_PKEY_AudioEngine_DeviceFormat = L"{f19f064d-082c-4e27-bc73-6882a1bb8e4c} 0";
|
||||
static Platform::String ^ SDL_PKEY_AudioEngine_DeviceFormat = L"{f19f064d-082c-4e27-bc73-6882a1bb8e4c} 0";
|
||||
|
||||
static void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid);
|
||||
static void WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid);
|
||||
extern "C" {
|
||||
SDL_atomic_t SDL_IMMDevice_DefaultPlaybackGeneration;
|
||||
SDL_atomic_t SDL_IMMDevice_DefaultCaptureGeneration;
|
||||
SDL_atomic_t SDL_IMMDevice_DefaultPlaybackGeneration;
|
||||
SDL_atomic_t SDL_IMMDevice_DefaultCaptureGeneration;
|
||||
}
|
||||
|
||||
/* This is a list of device id strings we have inflight, so we have consistent pointers to the same device. */
|
||||
@@ -71,20 +71,20 @@ static DevIdList *deviceid_list = NULL;
|
||||
|
||||
class SDL_WasapiDeviceEventHandler
|
||||
{
|
||||
public:
|
||||
public:
|
||||
SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture);
|
||||
~SDL_WasapiDeviceEventHandler();
|
||||
void OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ args);
|
||||
void OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ args);
|
||||
void OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args);
|
||||
void OnEnumerationCompleted(DeviceWatcher^ sender, Platform::Object^ args);
|
||||
void OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args);
|
||||
void OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args);
|
||||
SDL_semaphore* completed;
|
||||
void OnDeviceAdded(DeviceWatcher ^ sender, DeviceInformation ^ args);
|
||||
void OnDeviceRemoved(DeviceWatcher ^ sender, DeviceInformationUpdate ^ args);
|
||||
void OnDeviceUpdated(DeviceWatcher ^ sender, DeviceInformationUpdate ^ args);
|
||||
void OnEnumerationCompleted(DeviceWatcher ^ sender, Platform::Object ^ args);
|
||||
void OnDefaultRenderDeviceChanged(Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args);
|
||||
void OnDefaultCaptureDeviceChanged(Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args);
|
||||
SDL_semaphore *completed;
|
||||
|
||||
private:
|
||||
private:
|
||||
const SDL_bool iscapture;
|
||||
DeviceWatcher^ watcher;
|
||||
DeviceWatcher ^ watcher;
|
||||
Windows::Foundation::EventRegistrationToken added_handler;
|
||||
Windows::Foundation::EventRegistrationToken removed_handler;
|
||||
Windows::Foundation::EventRegistrationToken updated_handler;
|
||||
@@ -93,29 +93,27 @@ private:
|
||||
};
|
||||
|
||||
SDL_WasapiDeviceEventHandler::SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture)
|
||||
: iscapture(_iscapture)
|
||||
, completed(SDL_CreateSemaphore(0))
|
||||
: iscapture(_iscapture), completed(SDL_CreateSemaphore(0))
|
||||
{
|
||||
if (!completed)
|
||||
return; // uhoh.
|
||||
return; // uhoh.
|
||||
|
||||
Platform::String^ selector = _iscapture ? MediaDevice::GetAudioCaptureSelector() :
|
||||
MediaDevice::GetAudioRenderSelector();
|
||||
Platform::Collections::Vector<Platform::String^> properties;
|
||||
Platform::String ^ selector = _iscapture ? MediaDevice::GetAudioCaptureSelector() : MediaDevice::GetAudioRenderSelector();
|
||||
Platform::Collections::Vector<Platform::String ^> properties;
|
||||
properties.Append(SDL_PKEY_AudioEngine_DeviceFormat);
|
||||
watcher = DeviceInformation::CreateWatcher(selector, properties.GetView());
|
||||
if (!watcher)
|
||||
return; // uhoh.
|
||||
return; // uhoh.
|
||||
|
||||
// !!! FIXME: this doesn't need a lambda here, I think, if I make SDL_WasapiDeviceEventHandler a proper C++/CX class. --ryan.
|
||||
added_handler = watcher->Added += ref new TypedEventHandler<DeviceWatcher^, DeviceInformation^>([this](DeviceWatcher^ sender, DeviceInformation^ args) { OnDeviceAdded(sender, args); } );
|
||||
removed_handler = watcher->Removed += ref new TypedEventHandler<DeviceWatcher^, DeviceInformationUpdate^>([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceRemoved(sender, args); } );
|
||||
updated_handler = watcher->Updated += ref new TypedEventHandler<DeviceWatcher^, DeviceInformationUpdate^>([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceUpdated(sender, args); } );
|
||||
completed_handler = watcher->EnumerationCompleted += ref new TypedEventHandler<DeviceWatcher^, Platform::Object^>([this](DeviceWatcher^ sender, Platform::Object^ args) { OnEnumerationCompleted(sender, args); } );
|
||||
added_handler = watcher->Added += ref new TypedEventHandler<DeviceWatcher ^, DeviceInformation ^>([this](DeviceWatcher ^ sender, DeviceInformation ^ args) { OnDeviceAdded(sender, args); });
|
||||
removed_handler = watcher->Removed += ref new TypedEventHandler<DeviceWatcher ^, DeviceInformationUpdate ^>([this](DeviceWatcher ^ sender, DeviceInformationUpdate ^ args) { OnDeviceRemoved(sender, args); });
|
||||
updated_handler = watcher->Updated += ref new TypedEventHandler<DeviceWatcher ^, DeviceInformationUpdate ^>([this](DeviceWatcher ^ sender, DeviceInformationUpdate ^ args) { OnDeviceUpdated(sender, args); });
|
||||
completed_handler = watcher->EnumerationCompleted += ref new TypedEventHandler<DeviceWatcher ^, Platform::Object ^>([this](DeviceWatcher ^ sender, Platform::Object ^ args) { OnEnumerationCompleted(sender, args); });
|
||||
if (iscapture) {
|
||||
default_changed_handler = MediaDevice::DefaultAudioCaptureDeviceChanged += ref new TypedEventHandler<Platform::Object^, DefaultAudioCaptureDeviceChangedEventArgs^>([this](Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args) { OnDefaultCaptureDeviceChanged(sender, args); } );
|
||||
default_changed_handler = MediaDevice::DefaultAudioCaptureDeviceChanged += ref new TypedEventHandler<Platform::Object ^, DefaultAudioCaptureDeviceChangedEventArgs ^>([this](Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args) { OnDefaultCaptureDeviceChanged(sender, args); });
|
||||
} else {
|
||||
default_changed_handler = MediaDevice::DefaultAudioRenderDeviceChanged += ref new TypedEventHandler<Platform::Object^, DefaultAudioRenderDeviceChangedEventArgs^>([this](Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args) { OnDefaultRenderDeviceChanged(sender, args); } );
|
||||
default_changed_handler = MediaDevice::DefaultAudioRenderDeviceChanged += ref new TypedEventHandler<Platform::Object ^, DefaultAudioRenderDeviceChangedEventArgs ^>([this](Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args) { OnDefaultRenderDeviceChanged(sender, args); });
|
||||
}
|
||||
watcher->Start();
|
||||
}
|
||||
@@ -142,17 +140,16 @@ SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ info)
|
||||
void SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher ^ sender, DeviceInformation ^ info)
|
||||
{
|
||||
SDL_assert(sender == this->watcher);
|
||||
char *utf8dev = WIN_StringToUTF8(info->Name->Data());
|
||||
if (utf8dev) {
|
||||
WAVEFORMATEXTENSIBLE fmt;
|
||||
Platform::Object^ obj = info->Properties->Lookup(SDL_PKEY_AudioEngine_DeviceFormat);
|
||||
Platform::Object ^ obj = info->Properties->Lookup(SDL_PKEY_AudioEngine_DeviceFormat);
|
||||
if (obj) {
|
||||
IPropertyValue^ property = (IPropertyValue^) obj;
|
||||
Platform::Array<unsigned char>^ data;
|
||||
IPropertyValue ^ property = (IPropertyValue ^) obj;
|
||||
Platform::Array<unsigned char> ^ data;
|
||||
property->GetUInt8Array(&data);
|
||||
SDL_memcpy(&fmt, data->Data, SDL_min(data->Length, sizeof(WAVEFORMATEXTENSIBLE)));
|
||||
} else {
|
||||
@@ -164,41 +161,35 @@ SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher^ sender, DeviceInforma
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_WasapiDeviceEventHandler::OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ info)
|
||||
void SDL_WasapiDeviceEventHandler::OnDeviceRemoved(DeviceWatcher ^ sender, DeviceInformationUpdate ^ info)
|
||||
{
|
||||
SDL_assert(sender == this->watcher);
|
||||
WASAPI_RemoveDevice(this->iscapture, info->Id->Data());
|
||||
}
|
||||
|
||||
void
|
||||
SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args)
|
||||
void SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher ^ sender, DeviceInformationUpdate ^ args)
|
||||
{
|
||||
SDL_assert(sender == this->watcher);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_WasapiDeviceEventHandler::OnEnumerationCompleted(DeviceWatcher^ sender, Platform::Object^ args)
|
||||
void SDL_WasapiDeviceEventHandler::OnEnumerationCompleted(DeviceWatcher ^ sender, Platform::Object ^ args)
|
||||
{
|
||||
SDL_assert(sender == this->watcher);
|
||||
SDL_SemPost(this->completed);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_WasapiDeviceEventHandler::OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args)
|
||||
void SDL_WasapiDeviceEventHandler::OnDefaultRenderDeviceChanged(Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args)
|
||||
{
|
||||
SDL_assert(this->iscapture);
|
||||
SDL_AtomicAdd(&SDL_IMMDevice_DefaultPlaybackGeneration, 1);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_WasapiDeviceEventHandler::OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args)
|
||||
void SDL_WasapiDeviceEventHandler::OnDefaultCaptureDeviceChanged(Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args)
|
||||
{
|
||||
SDL_assert(!this->iscapture);
|
||||
SDL_AtomicAdd(&SDL_IMMDevice_DefaultCaptureGeneration, 1);
|
||||
}
|
||||
|
||||
|
||||
static SDL_WasapiDeviceEventHandler *playback_device_event_handler;
|
||||
static SDL_WasapiDeviceEventHandler *capture_device_event_handler;
|
||||
|
||||
@@ -238,10 +229,11 @@ void WASAPI_EnumerateEndpoints(void)
|
||||
SDL_SemWait(capture_device_event_handler->completed);
|
||||
}
|
||||
|
||||
struct SDL_WasapiActivationHandler : public RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler >
|
||||
struct SDL_WasapiActivationHandler : public RuntimeClass<RuntimeClassFlags<ClassicCom>, FtmBase, IActivateAudioInterfaceCompletionHandler>
|
||||
{
|
||||
SDL_WasapiActivationHandler() : device(nullptr) {}
|
||||
STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation *operation);
|
||||
STDMETHOD(ActivateCompleted)
|
||||
(IActivateAudioInterfaceAsyncOperation *operation);
|
||||
SDL_AudioDevice *device;
|
||||
};
|
||||
|
||||
@@ -254,23 +246,20 @@ SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOpera
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformDeleteActivationHandler(void *handler)
|
||||
void WASAPI_PlatformDeleteActivationHandler(void *handler)
|
||||
{
|
||||
((SDL_WasapiActivationHandler *) handler)->Release();
|
||||
((SDL_WasapiActivationHandler *)handler)->Release();
|
||||
}
|
||||
|
||||
int
|
||||
WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
{
|
||||
LPCWSTR devid = _this->hidden->devid;
|
||||
Platform::String^ defdevid;
|
||||
Platform::String ^ defdevid;
|
||||
|
||||
if (devid == nullptr) {
|
||||
defdevid = _this->iscapture ? MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default) : MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);
|
||||
@@ -286,11 +275,11 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
return SDL_SetError("Failed to allocate WASAPI activation handler");
|
||||
}
|
||||
|
||||
handler.Get()->AddRef(); // we hold a reference after ComPtr destructs on return, causing a Release, and Release ourselves in WASAPI_PlatformDeleteActivationHandler(), etc.
|
||||
handler.Get()->AddRef(); // we hold a reference after ComPtr destructs on return, causing a Release, and Release ourselves in WASAPI_PlatformDeleteActivationHandler(), etc.
|
||||
handler.Get()->device = _this;
|
||||
_this->hidden->activation_handler = handler.Get();
|
||||
|
||||
WASAPI_RefDevice(_this); /* completion handler will unref it. */
|
||||
WASAPI_RefDevice(_this); /* completion handler will unref it. */
|
||||
IActivateAudioInterfaceAsyncOperation *async = nullptr;
|
||||
const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);
|
||||
|
||||
@@ -337,22 +326,20 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformThreadInit(_THIS)
|
||||
void WASAPI_PlatformThreadInit(_THIS)
|
||||
{
|
||||
// !!! FIXME: set this thread to "Pro Audio" priority.
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformThreadDeinit(_THIS)
|
||||
void WASAPI_PlatformThreadDeinit(_THIS)
|
||||
{
|
||||
// !!! FIXME: set this thread to "Pro Audio" priority.
|
||||
}
|
||||
|
||||
/* Everything below was copied from SDL_wasapi.c, before it got moved to SDL_immdevice.c! */
|
||||
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
|
||||
extern "C" SDL_AudioFormat
|
||||
WaveFormatToSDLFormat(WAVEFORMATEX *waveformat)
|
||||
@@ -376,8 +363,7 @@ WaveFormatToSDLFormat(WAVEFORMATEX *waveformat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid)
|
||||
static void WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid)
|
||||
{
|
||||
DevIdList *i;
|
||||
DevIdList *next;
|
||||
@@ -399,8 +385,7 @@ WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid)
|
||||
static void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid)
|
||||
{
|
||||
DevIdList *devidlist;
|
||||
SDL_AudioSpec spec;
|
||||
@@ -410,22 +395,22 @@ WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENS
|
||||
phones and tablets, where you might have an internal speaker and a headphone jack and expect both to be
|
||||
available and switch automatically. (!!! FIXME...?) */
|
||||
|
||||
/* see if we already have this one. */
|
||||
/* see if we already have this one. */
|
||||
for (devidlist = deviceid_list; devidlist; devidlist = devidlist->next) {
|
||||
if (SDL_wcscmp(devidlist->str, devid) == 0) {
|
||||
return; /* we already have this. */
|
||||
return; /* we already have this. */
|
||||
}
|
||||
}
|
||||
|
||||
devidlist = (DevIdList *)SDL_malloc(sizeof(*devidlist));
|
||||
if (devidlist == NULL) {
|
||||
return; /* oh well. */
|
||||
return; /* oh well. */
|
||||
}
|
||||
|
||||
devid = SDL_wcsdup(devid);
|
||||
if (!devid) {
|
||||
SDL_free(devidlist);
|
||||
return; /* oh well. */
|
||||
return; /* oh well. */
|
||||
}
|
||||
|
||||
devidlist->str = (WCHAR *)devid;
|
||||
@@ -439,6 +424,6 @@ WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENS
|
||||
SDL_AddAudioDevice(iscapture, devname, &spec, (void *)devid);
|
||||
}
|
||||
|
||||
#endif // SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__)
|
||||
#endif // SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__)
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
Reference in New Issue
Block a user