coreaudio: Add support for SDL_GetDefaultAudioInfo (#6277)

Co-authored-by: Ethan Lee <flibitijibibo@gmail.com>
Co-authored-by: Ozkan Sezer <sezeroz@gmail.com>
This commit is contained in:
Jarod Hillman 2022-09-29 10:33:07 -04:00 committed by Ethan Lee
parent 69bbe4ce7d
commit 40893821f2
2 changed files with 159 additions and 0 deletions

View File

@ -1151,6 +1151,141 @@ COREAUDIO_OpenDevice(_THIS, const char *devname)
return (this->hidden->thread != NULL) ? 0 : -1;
}
#if !MACOSX_COREAUDIO
static int
COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
{
AVAudioSession* session = [AVAudioSession sharedInstance];
if (name != NULL) {
*name = NULL;
}
SDL_zerop(spec);
spec->freq = [session sampleRate];
spec->channels = [session outputNumberOfChannels];
return 0;
}
#else /* MACOSX_COREAUDIO */
static int
COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
{
AudioDeviceID devid;
AudioBufferList *buflist;
OSStatus result;
UInt32 size;
CFStringRef cfstr;
char *devname;
int usable;
double sampleRate;
AudioObjectPropertyAddress addr = {
iscapture ? kAudioHardwarePropertyDefaultInputDevice
: kAudioHardwarePropertyDefaultOutputDevice,
iscapture ? kAudioDevicePropertyScopeInput
: kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
AudioObjectPropertyAddress nameaddr = {
kAudioObjectPropertyName,
iscapture ? kAudioDevicePropertyScopeInput
: kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
AudioObjectPropertyAddress freqaddr = {
kAudioDevicePropertyNominalSampleRate,
iscapture ? kAudioDevicePropertyScopeInput
: kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
AudioObjectPropertyAddress bufaddr = {
kAudioDevicePropertyStreamConfiguration,
iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
/* Get the Device ID */
cfstr = NULL;
size = sizeof (AudioDeviceID);
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
0, NULL, &size, &devid);
if (result != noErr) {
return SDL_SetError("%s: Default Device ID not found", "coreaudio");
}
if (name != NULL) {
/* Use the Device ID to get the name */
size = sizeof (CFStringRef);
result = AudioObjectGetPropertyData(devid, &nameaddr, 0, NULL, &size, &cfstr);
if (result != noErr) {
return SDL_SetError("%s: Default Device Name not found", "coreaudio");
}
CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
kCFStringEncodingUTF8);
devname = (char *) SDL_malloc(len + 1);
usable = ((devname != NULL) &&
(CFStringGetCString(cfstr, devname, len + 1, kCFStringEncodingUTF8)));
CFRelease(cfstr);
if (usable) {
usable = 0;
len = strlen(devname);
/* Some devices have whitespace at the end...trim it. */
while ((len > 0) && (devname[len - 1] == ' ')) {
len--;
usable = len;
}
}
if (usable) {
devname[len] = '\0';
}
*name = devname;
}
/* Uses the Device ID to get the spec */
SDL_zerop(spec);
sampleRate = 0;
size = sizeof(sampleRate);
result = AudioObjectGetPropertyData(devid, &freqaddr, 0, NULL, &size, &sampleRate);
if (result != noErr) {
return SDL_SetError("%s: Default Device Sample Rate not found", "coreaudio");
}
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);
if (buflist == NULL)
return SDL_SetError("%s: Default Device Buffer List not found", "coreaudio");
result = AudioObjectGetPropertyData(devid, &bufaddr, 0, NULL,
&size, buflist);
if (result == noErr) {
UInt32 j;
for (j = 0; j < buflist->mNumberBuffers; j++) {
spec->channels += buflist->mBuffers[j].mNumberChannels;
}
}
SDL_free(buflist);
if (spec->channels == 0) {
return SDL_SetError("%s: Default Device has no channels!", "coreaudio");
}
return 0;
}
#endif /* MACOSX_COREAUDIO */
static void
COREAUDIO_Deinitialize(void)
{
@ -1168,6 +1303,7 @@ COREAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->OpenDevice = COREAUDIO_OpenDevice;
impl->CloseDevice = COREAUDIO_CloseDevice;
impl->Deinitialize = COREAUDIO_Deinitialize;
impl->GetDefaultAudioInfo = COREAUDIO_GetDefaultAudioInfo;
#if MACOSX_COREAUDIO
impl->DetectDevices = COREAUDIO_DetectDevices;

View File

@ -40,6 +40,8 @@ print_devices(int iscapture)
int
main(int argc, char **argv)
{
char *deviceName;
SDL_AudioSpec spec;
int n;
/* Enable standard application logging */
@ -69,6 +71,27 @@ main(int argc, char **argv)
print_devices(0);
print_devices(1);
if (SDL_GetDefaultAudioInfo(&deviceName, &spec, 0) < 0) {
SDL_Log("Error when calling SDL_GetDefaultAudioInfo: %s\n", SDL_GetError());
} else {
SDL_Log("Default Output Name: %s\n", deviceName != NULL ? deviceName : "unknown");
SDL_free(deviceName);
SDL_Log("Sampling Rate: %d\n", spec.freq);
SDL_Log("Number of Channels: %d\n", spec.channels);
SDL_Log("Audio Format: %d\n", spec.format);
}
if (SDL_GetDefaultAudioInfo(&deviceName, &spec, 1) < 0) {
SDL_Log("Error when calling SDL_GetDefaultAudioInfo: %s\n", SDL_GetError());
} else {
SDL_Log("Default Capture Name: %s\n", deviceName != NULL ? deviceName : "unknown");
SDL_free(deviceName);
SDL_Log("Sampling Rate: %d\n", spec.freq);
SDL_Log("Number of Channels: %d\n", spec.channels);
SDL_Log("Audio Format: %d\n", spec.format);
}
SDL_Quit();
return 0;
}