Skip to content

Instantly share code, notes, and snippets.

@icculus
Created December 27, 2024 21:33
Show Gist options
  • Save icculus/be608aa0dc237acbf9180d0ef1b99913 to your computer and use it in GitHub Desktop.
Save icculus/be608aa0dc237acbf9180d0ef1b99913 to your computer and use it in GitHub Desktop.
Changes to CoreAudio target between SDL 3.1.2 and main
diff --git a/src/audio/coreaudio/SDL_coreaudio.h b/src/audio/coreaudio/SDL_coreaudio.h
index cd64e3038..e00d835b0 100644
--- a/src/audio/coreaudio/SDL_coreaudio.h
+++ b/src/audio/coreaudio/SDL_coreaudio.h
@@ -60,7 +60,7 @@ struct SDL_PrivateAudioData
#ifdef MACOSX_COREAUDIO
AudioDeviceID deviceID;
#else
- SDL_bool interrupted;
+ bool interrupted;
CFTypeRef interruption_listener;
#endif
};
diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m
index 8de8d96c0..76b6e3269 100644
--- a/src/audio/coreaudio/SDL_coreaudio.m
+++ b/src/audio/coreaudio/SDL_coreaudio.m
@@ -48,19 +48,19 @@
typedef struct SDLCoreAudioHandle
{
AudioDeviceID devid;
- SDL_bool iscapture;
+ bool recording;
} SDLCoreAudioHandle;
-static SDL_bool TestCoreAudioDeviceHandleCallback(SDL_AudioDevice *device, void *handle)
+static bool TestCoreAudioDeviceHandleCallback(SDL_AudioDevice *device, void *handle)
{
const SDLCoreAudioHandle *a = (const SDLCoreAudioHandle *) device->handle;
const SDLCoreAudioHandle *b = (const SDLCoreAudioHandle *) handle;
- return (a->devid == b->devid) && (!!a->iscapture == !!b->iscapture);
+ return (a->devid == b->devid) && (!!a->recording == !!b->recording);
}
-static SDL_AudioDevice *FindCoreAudioDeviceByHandle(const AudioDeviceID devid, const SDL_bool iscapture)
+static SDL_AudioDevice *FindCoreAudioDeviceByHandle(const AudioDeviceID devid, const bool recording)
{
- SDLCoreAudioHandle handle = { devid, iscapture };
+ SDLCoreAudioHandle handle = { devid, recording };
return SDL_FindPhysicalAudioDeviceByCallback(TestCoreAudioDeviceHandleCallback, &handle);
}
@@ -70,13 +70,13 @@ static const AudioObjectPropertyAddress devlist_address = {
kAudioObjectPropertyElementMain
};
-static const AudioObjectPropertyAddress default_output_device_address = {
+static const AudioObjectPropertyAddress default_playback_device_address = {
kAudioHardwarePropertyDefaultOutputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMain
};
-static const AudioObjectPropertyAddress default_input_device_address = {
+static const AudioObjectPropertyAddress default_recording_device_address = {
kAudioHardwarePropertyDefaultInputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMain
@@ -98,11 +98,11 @@ static OSStatus DeviceAliveNotification(AudioObjectID devid, UInt32 num_addr, co
UInt32 size = sizeof(alive);
const OSStatus error = AudioObjectGetPropertyData(devid, addrs, 0, NULL, &size, &alive);
- SDL_bool dead = SDL_FALSE;
+ bool dead = false;
if (error == kAudioHardwareBadDeviceError) {
- dead = SDL_TRUE; // device was unplugged.
+ dead = true; // device was unplugged.
} else if ((error == kAudioHardwareNoError) && (!alive)) {
- dead = SDL_TRUE; // device died in some other way.
+ dead = true; // device died in some other way.
}
if (dead) {
@@ -127,7 +127,7 @@ static void RefreshPhysicalDevices(void)
{
UInt32 size = 0;
AudioDeviceID *devs = NULL;
- SDL_bool isstack;
+ bool isstack;
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &devlist_address, 0, NULL, &size) != kAudioHardwareNoError) {
return;
@@ -140,26 +140,26 @@ static void RefreshPhysicalDevices(void)
const UInt32 total_devices = (UInt32) (size / sizeof(AudioDeviceID));
for (UInt32 i = 0; i < total_devices; i++) {
- if (FindCoreAudioDeviceByHandle(devs[i], SDL_TRUE) || FindCoreAudioDeviceByHandle(devs[i], SDL_FALSE)) {
+ if (FindCoreAudioDeviceByHandle(devs[i], true) || FindCoreAudioDeviceByHandle(devs[i], false)) {
devs[i] = 0; // The system and SDL both agree it's already here, don't check it again.
}
}
// any non-zero items remaining in `devs` are new devices to be added.
- for (int iscapture = 0; iscapture < 2; iscapture++) {
+ for (int recording = 0; recording < 2; recording++) {
const AudioObjectPropertyAddress addr = {
kAudioDevicePropertyStreamConfiguration,
- iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
+ recording ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMain
};
const AudioObjectPropertyAddress nameaddr = {
kAudioObjectPropertyName,
- iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
+ recording ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMain
};
const AudioObjectPropertyAddress freqaddr = {
kAudioDevicePropertyNominalSampleRate,
- iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
+ recording ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMain
};
@@ -207,7 +207,7 @@ static void RefreshPhysicalDevices(void)
CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), kCFStringEncodingUTF8);
char *name = (char *)SDL_malloc(len + 1);
- SDL_bool usable = ((name != NULL) && (CFStringGetCString(cfstr, name, len + 1, kCFStringEncodingUTF8)));
+ bool usable = ((name != NULL) && (CFStringGetCString(cfstr, name, len + 1, kCFStringEncodingUTF8)));
CFRelease(cfstr);
@@ -224,15 +224,13 @@ static void RefreshPhysicalDevices(void)
name[len] = '\0';
#if DEBUG_COREAUDIO
- SDL_Log("COREAUDIO: Found %s device #%d: '%s' (devid %d)\n",
- ((iscapture) ? "capture" : "output"),
- (int)i, name, (int)dev);
+ SDL_Log("COREAUDIO: Found %s device #%d: '%s' (devid %d)\n", ((recording) ? "recording" : "playback"), (int)i, name, (int)dev);
#endif
SDLCoreAudioHandle *newhandle = (SDLCoreAudioHandle *) SDL_calloc(1, sizeof (*newhandle));
if (newhandle) {
newhandle->devid = dev;
- newhandle->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
- SDL_AudioDevice *device = SDL_AddAudioDevice(newhandle->iscapture, name, &spec, newhandle);
+ newhandle->recording = recording ? true : false;
+ SDL_AudioDevice *device = SDL_AddAudioDevice(newhandle->recording, name, &spec, newhandle);
if (device) {
AudioObjectAddPropertyListener(dev, &alive_address, DeviceAliveNotification, device);
} else {
@@ -254,35 +252,35 @@ static OSStatus DeviceListChangedNotification(AudioObjectID systemObj, UInt32 nu
return noErr;
}
-static OSStatus DefaultAudioDeviceChangedNotification(const SDL_bool iscapture, AudioObjectID inObjectID, const AudioObjectPropertyAddress *addr)
+static OSStatus DefaultAudioDeviceChangedNotification(const bool recording, AudioObjectID inObjectID, const AudioObjectPropertyAddress *addr)
{
AudioDeviceID devid;
UInt32 size = sizeof(devid);
if (AudioObjectGetPropertyData(inObjectID, addr, 0, NULL, &size, &devid) == noErr) {
- SDL_DefaultAudioDeviceChanged(FindCoreAudioDeviceByHandle(devid, iscapture));
+ SDL_DefaultAudioDeviceChanged(FindCoreAudioDeviceByHandle(devid, recording));
}
return noErr;
}
-static OSStatus DefaultOutputDeviceChangedNotification(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inUserData)
+static OSStatus DefaultPlaybackDeviceChangedNotification(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inUserData)
{
#if DEBUG_COREAUDIO
- SDL_Log("COREAUDIO: default output device changed!");
+ SDL_Log("COREAUDIO: default playback device changed!");
#endif
SDL_assert(inNumberAddresses == 1);
- return DefaultAudioDeviceChangedNotification(SDL_FALSE, inObjectID, inAddresses);
+ return DefaultAudioDeviceChangedNotification(false, inObjectID, inAddresses);
}
-static OSStatus DefaultInputDeviceChangedNotification(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inUserData)
+static OSStatus DefaultRecordingDeviceChangedNotification(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inUserData)
{
#if DEBUG_COREAUDIO
- SDL_Log("COREAUDIO: default input device changed!");
+ SDL_Log("COREAUDIO: default recording device changed!");
#endif
SDL_assert(inNumberAddresses == 1);
- return DefaultAudioDeviceChangedNotification(SDL_TRUE, inObjectID, inAddresses);
+ return DefaultAudioDeviceChangedNotification(true, inObjectID, inAddresses);
}
-static void COREAUDIO_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture)
+static void COREAUDIO_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording)
{
RefreshPhysicalDevices();
@@ -293,34 +291,34 @@ static void COREAUDIO_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioD
AudioDeviceID devid;
size = sizeof(AudioDeviceID);
- if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &default_output_device_address, 0, NULL, &size, &devid) == noErr) {
- SDL_AudioDevice *device = FindCoreAudioDeviceByHandle(devid, SDL_FALSE);
+ if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &default_playback_device_address, 0, NULL, &size, &devid) == noErr) {
+ SDL_AudioDevice *device = FindCoreAudioDeviceByHandle(devid, false);
if (device) {
- *default_output = device;
+ *default_playback = device;
}
}
- AudioObjectAddPropertyListener(kAudioObjectSystemObject, &default_output_device_address, DefaultOutputDeviceChangedNotification, NULL);
+ AudioObjectAddPropertyListener(kAudioObjectSystemObject, &default_playback_device_address, DefaultPlaybackDeviceChangedNotification, NULL);
size = sizeof(AudioDeviceID);
- if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &default_input_device_address, 0, NULL, &size, &devid) == noErr) {
- SDL_AudioDevice *device = FindCoreAudioDeviceByHandle(devid, SDL_TRUE);
+ if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &default_recording_device_address, 0, NULL, &size, &devid) == noErr) {
+ SDL_AudioDevice *device = FindCoreAudioDeviceByHandle(devid, true);
if (device) {
- *default_capture = device;
+ *default_recording = device;
}
}
- AudioObjectAddPropertyListener(kAudioObjectSystemObject, &default_input_device_address, DefaultInputDeviceChangedNotification, NULL);
+ AudioObjectAddPropertyListener(kAudioObjectSystemObject, &default_recording_device_address, DefaultRecordingDeviceChangedNotification, NULL);
}
#else // iOS-specific section follows.
-static SDL_bool session_active = SDL_FALSE;
+static bool session_active = false;
-static SDL_bool PauseOneAudioDevice(SDL_AudioDevice *device, void *userdata)
+static bool PauseOneAudioDevice(SDL_AudioDevice *device, void *userdata)
{
if (device->hidden && device->hidden->audioQueue && !device->hidden->interrupted) {
AudioQueuePause(device->hidden->audioQueue);
}
- return SDL_FALSE; // keep enumerating devices until we've paused them all.
+ return false; // keep enumerating devices until we've paused them all.
}
static void PauseAudioDevices(void)
@@ -328,12 +326,12 @@ static void PauseAudioDevices(void)
(void) SDL_FindPhysicalAudioDeviceByCallback(PauseOneAudioDevice, NULL);
}
-static SDL_bool ResumeOneAudioDevice(SDL_AudioDevice *device, void *userdata)
+static bool ResumeOneAudioDevice(SDL_AudioDevice *device, void *userdata)
{
if (device->hidden && device->hidden->audioQueue && !device->hidden->interrupted) {
AudioQueueStart(device->hidden->audioQueue, NULL);
}
- return SDL_FALSE; // keep enumerating devices until we've resumed them all.
+ return false; // keep enumerating devices until we've resumed them all.
}
static void ResumeAudioDevices(void)
@@ -344,7 +342,7 @@ static void ResumeAudioDevices(void)
static void InterruptionBegin(SDL_AudioDevice *device)
{
if (device != NULL && device->hidden->audioQueue != NULL) {
- device->hidden->interrupted = SDL_TRUE;
+ device->hidden->interrupted = true;
AudioQueuePause(device->hidden->audioQueue);
}
}
@@ -352,7 +350,7 @@ static void InterruptionBegin(SDL_AudioDevice *device)
static void InterruptionEnd(SDL_AudioDevice *device)
{
if (device != NULL && device->hidden != NULL && device->hidden->audioQueue != NULL && device->hidden->interrupted && AudioQueueStart(device->hidden->audioQueue, NULL) == AVAudioSessionErrorCodeNone) {
- device->hidden->interrupted = SDL_FALSE;
+ device->hidden->interrupted = false;
}
}
@@ -387,24 +385,24 @@ static void InterruptionEnd(SDL_AudioDevice *device)
typedef struct
{
- int output;
- int capture;
+ int playback;
+ int recording;
} CountOpenAudioDevicesData;
-static SDL_bool CountOpenAudioDevices(SDL_AudioDevice *device, void *userdata)
+static bool CountOpenAudioDevices(SDL_AudioDevice *device, void *userdata)
{
CountOpenAudioDevicesData *data = (CountOpenAudioDevicesData *) userdata;
if (device->hidden != NULL) { // assume it's open if hidden != NULL
- if (device->iscapture) {
- data->capture++;
+ if (device->recording) {
+ data->recording++;
} else {
- data->output++;
+ data->playback++;
}
}
- return SDL_FALSE; // keep enumerating until all devices have been checked.
+ return false; // keep enumerating until all devices have been checked.
}
-static SDL_bool UpdateAudioSession(SDL_AudioDevice *device, SDL_bool open, SDL_bool allow_playandrecord)
+static bool UpdateAudioSession(SDL_AudioDevice *device, bool open, bool allow_playandrecord)
{
@autoreleasepool {
AVAudioSession *session = [AVAudioSession sharedInstance];
@@ -437,9 +435,14 @@ static SDL_bool UpdateAudioSession(SDL_AudioDevice *device, SDL_bool open, SDL_b
category = AVAudioSessionCategoryPlayAndRecord;
}
}
- } else if (data.output && data.capture) {
- category = AVAudioSessionCategoryPlayAndRecord;
- } else if (data.capture) {
+ } else if (data.playback && data.recording) {
+ if (allow_playandrecord) {
+ category = AVAudioSessionCategoryPlayAndRecord;
+ } else {
+ // We already failed play and record with AVAudioSessionErrorCodeResourceNotAvailable
+ return false;
+ }
+ } else if (data.recording) {
category = AVAudioSessionCategoryRecord;
}
@@ -469,12 +472,12 @@ static SDL_bool UpdateAudioSession(SDL_AudioDevice *device, SDL_bool open, SDL_b
// Stop the current session so we don't interrupt other application audio
PauseAudioDevices();
[session setActive:NO error:nil];
- session_active = SDL_FALSE;
+ session_active = false;
if (![session setCategory:category mode:mode options:options error:&err]) {
NSString *desc = err.description;
SDL_SetError("Could not set Audio Session category: %s", desc.UTF8String);
- return SDL_FALSE;
+ return false;
}
}
} else {
@@ -482,33 +485,36 @@ static SDL_bool UpdateAudioSession(SDL_AudioDevice *device, SDL_bool open, SDL_b
// Stop the current session so we don't interrupt other application audio
PauseAudioDevices();
[session setActive:NO error:nil];
- session_active = SDL_FALSE;
+ session_active = false;
if (![session setCategory:category error:&err]) {
NSString *desc = err.description;
SDL_SetError("Could not set Audio Session category: %s", desc.UTF8String);
- return SDL_FALSE;
+ return false;
}
}
}
- if ((data.output || data.capture) && !session_active) {
+ if ((data.playback || data.recording) && !session_active) {
if (![session setActive:YES error:&err]) {
if ([err code] == AVAudioSessionErrorCodeResourceNotAvailable &&
category == AVAudioSessionCategoryPlayAndRecord) {
- return UpdateAudioSession(device, open, SDL_FALSE);
+ if (UpdateAudioSession(device, open, false)) {
+ return true;
+ } else {
+ return SDL_SetError("Could not activate Audio Session: Resource not available");
+ }
}
NSString *desc = err.description;
- SDL_SetError("Could not activate Audio Session: %s", desc.UTF8String);
- return SDL_FALSE;
+ return SDL_SetError("Could not activate Audio Session: %s", desc.UTF8String);
}
- session_active = SDL_TRUE;
+ session_active = true;
ResumeAudioDevices();
- } else if (!data.output && !data.capture && session_active) {
+ } else if (!data.playback && !data.recording && session_active) {
PauseAudioDevices();
[session setActive:NO error:nil];
- session_active = SDL_FALSE;
+ session_active = false;
}
if (open) {
@@ -545,38 +551,38 @@ static SDL_bool UpdateAudioSession(SDL_AudioDevice *device, SDL_bool open, SDL_b
}
}
- return SDL_TRUE;
+ return true;
}
#endif
-static int COREAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size)
+static bool COREAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size)
{
AudioQueueBufferRef current_buffer = device->hidden->current_buffer;
- SDL_assert(current_buffer != NULL); // should have been called from OutputBufferReadyCallback
+ SDL_assert(current_buffer != NULL); // should have been called from PlaybackBufferReadyCallback
SDL_assert(buffer == (Uint8 *) current_buffer->mAudioData);
current_buffer->mAudioDataByteSize = current_buffer->mAudioDataBytesCapacity;
device->hidden->current_buffer = NULL;
AudioQueueEnqueueBuffer(device->hidden->audioQueue, current_buffer, 0, NULL);
- return 0;
+ return true;
}
static Uint8 *COREAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
{
AudioQueueBufferRef current_buffer = device->hidden->current_buffer;
- SDL_assert(current_buffer != NULL); // should have been called from OutputBufferReadyCallback
+ SDL_assert(current_buffer != NULL); // should have been called from PlaybackBufferReadyCallback
SDL_assert(current_buffer->mAudioData != NULL);
*buffer_size = (int) current_buffer->mAudioDataBytesCapacity;
return (Uint8 *) current_buffer->mAudioData;
}
-static void OutputBufferReadyCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
+static void PlaybackBufferReadyCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
{
SDL_AudioDevice *device = (SDL_AudioDevice *)inUserData;
SDL_assert(inBuffer != NULL); // ...right?
SDL_assert(device->hidden->current_buffer == NULL); // shouldn't have anything pending
device->hidden->current_buffer = inBuffer;
- const SDL_bool okay = SDL_OutputAudioThreadIterate(device);
+ const bool okay = SDL_PlaybackAudioThreadIterate(device);
SDL_assert((device->hidden->current_buffer == NULL) || !okay); // PlayDevice should have enqueued and cleaned it out, unless we failed or shutdown.
// buffer is unexpectedly here? We're probably dying, but try to requeue this buffer with silence.
@@ -588,10 +594,10 @@ static void OutputBufferReadyCallback(void *inUserData, AudioQueueRef inAQ, Audi
}
}
-static int COREAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
+static int COREAUDIO_RecordDevice(SDL_AudioDevice *device, void *buffer, int buflen)
{
AudioQueueBufferRef current_buffer = device->hidden->current_buffer;
- SDL_assert(current_buffer != NULL); // should have been called from InputBufferReadyCallback
+ SDL_assert(current_buffer != NULL); // should have been called from RecordingBufferReadyCallback
SDL_assert(current_buffer->mAudioData != NULL);
SDL_assert(buflen >= (int) current_buffer->mAudioDataByteSize); // `cpy` makes sure this won't overflow a buffer, but we _will_ drop samples if this assertion fails!
const int cpy = SDL_min(buflen, (int) current_buffer->mAudioDataByteSize);
@@ -601,7 +607,7 @@ static int COREAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, in
return cpy;
}
-static void COREAUDIO_FlushCapture(SDL_AudioDevice *device)
+static void COREAUDIO_FlushRecording(SDL_AudioDevice *device)
{
AudioQueueBufferRef current_buffer = device->hidden->current_buffer;
if (current_buffer != NULL) { // also gets called at shutdown, when no buffer is available.
@@ -611,7 +617,7 @@ static void COREAUDIO_FlushCapture(SDL_AudioDevice *device)
}
}
-static void InputBufferReadyCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer,
+static void RecordingBufferReadyCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions,
const AudioStreamPacketDescription *inPacketDescs)
{
@@ -620,12 +626,12 @@ static void InputBufferReadyCallback(void *inUserData, AudioQueueRef inAQ, Audio
SDL_assert(inBuffer != NULL); // ...right?
SDL_assert(device->hidden->current_buffer == NULL); // shouldn't have anything pending
device->hidden->current_buffer = inBuffer;
- SDL_CaptureAudioThreadIterate(device);
+ SDL_RecordingAudioThreadIterate(device);
// buffer is unexpectedly here? We're probably dying, but try to requeue this buffer anyhow.
if (device->hidden->current_buffer != NULL) {
- SDL_assert(SDL_AtomicGet(&device->shutdown) != 0);
- COREAUDIO_FlushCapture(device); // just flush it manually, which will requeue it.
+ SDL_assert(SDL_GetAtomicInt(&device->shutdown) != 0);
+ COREAUDIO_FlushRecording(device); // just flush it manually, which will requeue it.
}
}
@@ -643,12 +649,12 @@ static void COREAUDIO_CloseDevice(SDL_AudioDevice *device)
}
if (device->hidden->thread) {
- SDL_assert(SDL_AtomicGet(&device->shutdown) != 0); // should have been set by SDL_audio.c
+ SDL_assert(SDL_GetAtomicInt(&device->shutdown) != 0); // should have been set by SDL_audio.c
SDL_WaitThread(device->hidden->thread, NULL);
}
#ifndef MACOSX_COREAUDIO
- UpdateAudioSession(device, SDL_FALSE, SDL_TRUE);
+ UpdateAudioSession(device, false, true);
#endif
if (device->hidden->ready_semaphore) {
@@ -662,7 +668,7 @@ static void COREAUDIO_CloseDevice(SDL_AudioDevice *device)
}
#ifdef MACOSX_COREAUDIO
-static int PrepareDevice(SDL_AudioDevice *device)
+static bool PrepareDevice(SDL_AudioDevice *device)
{
SDL_assert(device->handle != NULL); // this meant "system default" in SDL2, but doesn't anymore
@@ -680,7 +686,7 @@ static int PrepareDevice(SDL_AudioDevice *device)
UInt32 alive = 0;
size = sizeof(alive);
addr.mSelector = kAudioDevicePropertyDeviceIsAlive;
- addr.mScope = device->iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
+ addr.mScope = device->recording ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive);
CHECK_RESULT("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
if (!alive) {
@@ -698,14 +704,14 @@ static int PrepareDevice(SDL_AudioDevice *device)
device->hidden->deviceID = devid;
- return 0;
+ return true;
}
-static int AssignDeviceToAudioQueue(SDL_AudioDevice *device)
+static bool AssignDeviceToAudioQueue(SDL_AudioDevice *device)
{
const AudioObjectPropertyAddress prop = {
kAudioDevicePropertyDeviceUID,
- device->iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
+ device->recording ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMain
};
@@ -715,33 +721,31 @@ static int AssignDeviceToAudioQueue(SDL_AudioDevice *device)
result = AudioObjectGetPropertyData(device->hidden->deviceID, &prop, 0, NULL, &devuidsize, &devuid);
CHECK_RESULT("AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID)");
result = AudioQueueSetProperty(device->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize);
+ CFRelease(devuid); // Release devuid; we're done with it and AudioQueueSetProperty should have retained if it wants to keep it.
CHECK_RESULT("AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)");
-
- // !!! FIXME: do we need to CFRelease(devuid)?
-
- return 0;
+ return true;
}
#endif
-static int PrepareAudioQueue(SDL_AudioDevice *device)
+static bool PrepareAudioQueue(SDL_AudioDevice *device)
{
const AudioStreamBasicDescription *strdesc = &device->hidden->strdesc;
- const SDL_bool iscapture = device->iscapture;
+ const bool recording = device->recording;
OSStatus result;
SDL_assert(CFRunLoopGetCurrent() != NULL);
- if (iscapture) {
- result = AudioQueueNewInput(strdesc, InputBufferReadyCallback, device, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &device->hidden->audioQueue);
+ if (recording) {
+ result = AudioQueueNewInput(strdesc, RecordingBufferReadyCallback, device, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &device->hidden->audioQueue);
CHECK_RESULT("AudioQueueNewInput");
} else {
- result = AudioQueueNewOutput(strdesc, OutputBufferReadyCallback, device, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &device->hidden->audioQueue);
+ result = AudioQueueNewOutput(strdesc, PlaybackBufferReadyCallback, device, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &device->hidden->audioQueue);
CHECK_RESULT("AudioQueueNewOutput");
}
#ifdef MACOSX_COREAUDIO
- if (AssignDeviceToAudioQueue(device) < 0) {
- return -1;
+ if (!AssignDeviceToAudioQueue(device)) {
+ return false;
}
#endif
@@ -752,30 +756,39 @@ static int PrepareAudioQueue(SDL_AudioDevice *device)
SDL_zero(layout);
switch (device->spec.channels) {
case 1:
+ // a standard mono stream
layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
break;
case 2:
+ // a standard stereo stream (L R) - implied playback
layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
break;
case 3:
+ // L R LFE
layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_4;
break;
case 4:
+ // front left, front right, back left, back right
layout.mChannelLayoutTag = kAudioChannelLayoutTag_Quadraphonic;
break;
case 5:
- layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_0_A;
+ // L R LFE Ls Rs
+ layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_6;
break;
case 6:
- layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_1_A;
+ // L R C LFE Ls Rs
+ layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_12;
break;
case 7:
- // FIXME: Need to move channel[4] (BC) to channel[6]
- layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_6_1_A;
+ // L R C LFE Cs Ls Rs
+ layout.mChannelLayoutTag = kAudioChannelLayoutTag_WAVE_6_1;
break;
case 8:
- layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_7_1_A;
+ // L R C LFE Rls Rrs Ls Rs
+ layout.mChannelLayoutTag = kAudioChannelLayoutTag_WAVE_7_1;
break;
+ default:
+ return SDL_SetError("Unsupported audio channels");
}
if (layout.mChannelLayoutTag != 0) {
result = AudioQueueSetProperty(device->hidden->audioQueue, kAudioQueueProperty_ChannelLayout, &layout, sizeof(layout));
@@ -800,7 +813,7 @@ static int PrepareAudioQueue(SDL_AudioDevice *device)
device->hidden->numAudioBuffers = numAudioBuffers;
device->hidden->audioBuffer = SDL_calloc(numAudioBuffers, sizeof(AudioQueueBufferRef));
if (device->hidden->audioBuffer == NULL) {
- return -1;
+ return false;
}
#if DEBUG_COREAUDIO
@@ -820,56 +833,56 @@ static int PrepareAudioQueue(SDL_AudioDevice *device)
result = AudioQueueStart(device->hidden->audioQueue, NULL);
CHECK_RESULT("AudioQueueStart");
- return 0; // We're running!
+ return true; // We're running!
}
static int AudioQueueThreadEntry(void *arg)
{
SDL_AudioDevice *device = (SDL_AudioDevice *)arg;
- if (device->iscapture) {
- SDL_CaptureAudioThreadSetup(device);
+ if (device->recording) {
+ SDL_RecordingAudioThreadSetup(device);
} else {
- SDL_OutputAudioThreadSetup(device);
+ SDL_PlaybackAudioThreadSetup(device);
}
- if (PrepareAudioQueue(device) < 0) {
+ if (!PrepareAudioQueue(device)) {
device->hidden->thread_error = SDL_strdup(SDL_GetError());
- SDL_PostSemaphore(device->hidden->ready_semaphore);
+ SDL_SignalSemaphore(device->hidden->ready_semaphore);
return 0;
}
// init was successful, alert parent thread and start running...
- SDL_PostSemaphore(device->hidden->ready_semaphore);
+ SDL_SignalSemaphore(device->hidden->ready_semaphore);
- // This would be WaitDevice/WaitCaptureDevice in the normal SDL audio thread, but we get *BufferReadyCallback calls here to know when to iterate.
- while (!SDL_AtomicGet(&device->shutdown)) {
+ // This would be WaitDevice/WaitRecordingDevice in the normal SDL audio thread, but we get *BufferReadyCallback calls here to know when to iterate.
+ while (!SDL_GetAtomicInt(&device->shutdown)) {
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1);
}
- if (device->iscapture) {
- SDL_CaptureAudioThreadShutdown(device);
+ if (device->recording) {
+ SDL_RecordingAudioThreadShutdown(device);
} else {
// Drain off any pending playback.
const CFTimeInterval secs = (((CFTimeInterval)device->sample_frames) / ((CFTimeInterval)device->spec.freq)) * 2.0;
CFRunLoopRunInMode(kCFRunLoopDefaultMode, secs, 0);
- SDL_OutputAudioThreadShutdown(device);
+ SDL_PlaybackAudioThreadShutdown(device);
}
return 0;
}
-static int COREAUDIO_OpenDevice(SDL_AudioDevice *device)
+static bool COREAUDIO_OpenDevice(SDL_AudioDevice *device)
{
// Initialize all variables that we clean on shutdown
device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden));
if (device->hidden == NULL) {
- return -1;
+ return false;
}
#ifndef MACOSX_COREAUDIO
- if (!UpdateAudioSession(device, SDL_TRUE, SDL_TRUE)) {
- return -1;
+ if (!UpdateAudioSession(device, true, true)) {
+ return false;
}
// Stop CoreAudio from doing expensive audio rate conversion
@@ -878,7 +891,7 @@ static int COREAUDIO_OpenDevice(SDL_AudioDevice *device)
[session setPreferredSampleRate:device->spec.freq error:nil];
device->spec.freq = (int)session.sampleRate;
#ifdef SDL_PLATFORM_TVOS
- if (device->iscapture) {
+ if (device->recording) {
[session setPreferredInputNumberOfChannels:device->spec.channels error:nil];
device->spec.channels = (int)session.preferredInputNumberOfChannels;
} else {
@@ -887,7 +900,7 @@ static int COREAUDIO_OpenDevice(SDL_AudioDevice *device)
}
#else
// Calling setPreferredOutputNumberOfChannels seems to break audio output on iOS
- #endif /* SDL_PLATFORM_TVOS */
+ #endif // SDL_PLATFORM_TVOS
}
#endif
@@ -939,22 +952,22 @@ static int COREAUDIO_OpenDevice(SDL_AudioDevice *device)
strdesc->mBytesPerPacket = strdesc->mBytesPerFrame * strdesc->mFramesPerPacket;
#ifdef MACOSX_COREAUDIO
- if (PrepareDevice(device) < 0) {
- return -1;
+ if (!PrepareDevice(device)) {
+ return false;
}
#endif
// This has to init in a new thread so it can get its own CFRunLoop. :/
device->hidden->ready_semaphore = SDL_CreateSemaphore(0);
if (!device->hidden->ready_semaphore) {
- return -1; // oh well.
+ return false; // oh well.
}
char threadname[64];
SDL_GetAudioThreadName(device, threadname, sizeof(threadname));
- device->hidden->thread = SDL_CreateThreadInternal(AudioQueueThreadEntry, threadname, 0, device);
+ device->hidden->thread = SDL_CreateThread(AudioQueueThreadEntry, threadname, device);
if (!device->hidden->thread) {
- return -1;
+ return false;
}
SDL_WaitSemaphore(device->hidden->ready_semaphore);
@@ -967,25 +980,25 @@ static int COREAUDIO_OpenDevice(SDL_AudioDevice *device)
return SDL_SetError("%s", device->hidden->thread_error);
}
- return (device->hidden->thread != NULL) ? 0 : -1;
+ return (device->hidden->thread != NULL);
}
static void COREAUDIO_DeinitializeStart(void)
{
#ifdef MACOSX_COREAUDIO
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, DeviceListChangedNotification, NULL);
- AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_output_device_address, DefaultOutputDeviceChangedNotification, NULL);
- AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_input_device_address, DefaultInputDeviceChangedNotification, NULL);
+ AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_playback_device_address, DefaultPlaybackDeviceChangedNotification, NULL);
+ AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_recording_device_address, DefaultRecordingDeviceChangedNotification, NULL);
#endif
}
-static SDL_bool COREAUDIO_Init(SDL_AudioDriverImpl *impl)
+static bool COREAUDIO_Init(SDL_AudioDriverImpl *impl)
{
impl->OpenDevice = COREAUDIO_OpenDevice;
impl->PlayDevice = COREAUDIO_PlayDevice;
impl->GetDeviceBuf = COREAUDIO_GetDeviceBuf;
- impl->CaptureFromDevice = COREAUDIO_CaptureFromDevice;
- impl->FlushCapture = COREAUDIO_FlushCapture;
+ impl->RecordDevice = COREAUDIO_RecordDevice;
+ impl->FlushRecording = COREAUDIO_FlushRecording;
impl->CloseDevice = COREAUDIO_CloseDevice;
impl->DeinitializeStart = COREAUDIO_DeinitializeStart;
@@ -993,18 +1006,18 @@ static SDL_bool COREAUDIO_Init(SDL_AudioDriverImpl *impl)
impl->DetectDevices = COREAUDIO_DetectDevices;
impl->FreeDeviceHandle = COREAUDIO_FreeDeviceHandle;
#else
- impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
- impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
+ impl->OnlyHasDefaultPlaybackDevice = true;
+ impl->OnlyHasDefaultRecordingDevice = true;
#endif
- impl->ProvidesOwnCallbackThread = SDL_TRUE;
- impl->HasCaptureSupport = SDL_TRUE;
+ impl->ProvidesOwnCallbackThread = true;
+ impl->HasRecordingSupport = true;
- return SDL_TRUE;
+ return true;
}
AudioBootStrap COREAUDIO_bootstrap = {
- "coreaudio", "CoreAudio", COREAUDIO_Init, SDL_FALSE
+ "coreaudio", "CoreAudio", COREAUDIO_Init, false
};
#endif // SDL_AUDIO_DRIVER_COREAUDIO
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment