How to fix the channel names of CoreAudio devices


#1

I just stumbled upon this code snippet in juce_mac_CoreAudio.cpp (JUCE 3.0.2):

#if JUCE_CLANG
// Very irritating that AudioDeviceGetProperty is marked as deprecated, since
// there seems to be no replacement way of getting the channel names.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif

if (AudioDeviceGetProperty (deviceID, chanNum + 1, input, kAudioDevicePropertyChannelNameCFString,
                            &size, &nameNSString) == noErr)
{
    name = nsStringToJuce (nameNSString);
    [nameNSString release];
}

#if JUCE_CLANG
 #pragma clang diagnostic pop
#endif

Accidentally, I just found out what Apple's replacement is. Apparently, the channels of a device are also its "elements", and the element value is the channel number starting with 1. And since the channels are the elements, the right AudioObjectProperty for the channel names is kAudioObjectPropertyElementName. Here's the AudioDevicePropertyAddress that you need to use:

AudioObjectPropertyAddress pa;
pa.mSelector = kAudioObjectPropertyElementName;
pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
pa.mElement = chanNum + 1;

...and with this you can get the channel names using the normal AudioObject interface. So the JUCE code snippet above would become:

if (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &nameNSString) == noErr)
{
    name = nsStringToJuce (nameNSString);
    [nameNSString release];
}

The same mechanism should apply to all other properties of the individual channels as well.

Maybe it helps - in case you want to get rid of that #pragma clang workaround...

Cheers,
Timur


#2

Much cleaner! When I added the original code, I searched all over to find out a better way to do it but couldn't find any info, so thanks!