I see unexpected behavior when using AudioObjectGetPropertyData() to get the Channel Number Name or the Channel Category Name for the iPhone Microphone or the MacBook Pro Microphone audio devices. I am running macOS 14.4 Sonoma on a Intel MacBook Pro 15" 2019.
I have a test program that loops though all audio devices on a system, and all channels on each device. It uses AudioObjectGetPropertyData() to get the device name and manufacturer name and then iterate over the input and output channels getting Channel Number Name, Channel Name and Channel Category.
I would expect some of these values (like channel Name frequently is) to be empty CFStrings. Or for others to return FALSE to AudioObjectHasProperty() if the driver does not implement the property. And that is how things behave for most devices...
... except for the MacBook Pro Microphone and iPhone Microphone devices. There I get AudioObjectHasProperty() return TRUE but then a AudioObjectGetPropertyData() call with the exact same AudioObjectPropertyAddress returns with an error code 'WHAT'.
Took me a little while to realize the error cord being returned was 'WHAT' not 'what' and I added a modified checkError() function here to capture that and more.
So what surprised me is:
If AudioObjectHasProperty() returns TRUE then I expect that the matching AudioObjectGetPropertyData() works.
and
What the heck is 'WHAT'? I assume it is supposed to mean 'what' aka kAudioHardwareUnspecifiedError. Why is that actual error value not returned?
Are there other places that return 'WHAT' or capitalized versions of these standard OSStatus CoreAudio errors?
The example program is not complex but is too long for here so it's on GitHub at https://github.com/Darryl-Ramm/Wot
Here is some output from that program showing the unexpected behavior:
output.txt
Post
Replies
Boosts
Views
Activity
Hi
Hopefully a simple question. I just reached for AudioObjectShow() to help debug stuff and it does not appear to work on audio devices or audio streams. It prints nothing for them. It does work on AudiokAudioObjectSystemObject, I've not explored what else it does or does not work on. I could not find any other posts about this, it it expected to work? On all audio objects? I'm on macOS 14.4.
Here is a simple demo. AudioObjectShow() prints out info for the System AudiokAudioObjectSystemObject but then prints nothing as we loop through the audio devices in the system (and same for all streams on all these devices, but I'm not showing that here).
#include <CoreAudio/AudioHardware.h>
static const AudioObjectPropertyAddress devicesAddress = {
kAudioHardwarePropertyDevices,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMain
};
static const AudioObjectPropertyAddress nameAddress = {
kAudioObjectPropertyName,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMain
};
int main(int argc, const char *argv[]) {
UInt32 size;
AudioObjectID *audioDevices;
AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &devicesAddress, 0, NULL, &size);
audioDevices = (AudioObjectID *) malloc(size);
AudioObjectGetPropertyData(kAudioObjectSystemObject, &devicesAddress, 0, NULL, &size, audioDevices);
UInt32 nDevices = size / sizeof(AudioObjectID);
printf("--- AudioObjectShow(kAudioObjectSystemObject):\n");
AudioObjectShow(kAudioObjectSystemObject);
for (int i=0; i < nDevices; i++) {
printf("-------------------------------------------------\n");
printf("audioDevices[%d] = 0x%x\n", i, audioDevices[i]);
AudioObjectGetPropertyDataSize(audioDevices[i], &nameAddress, 0, NULL, &size);
CFStringRef cfString = malloc(size);
AudioObjectGetPropertyData(audioDevices[i], &nameAddress, 0, NULL, &size, &cfString);
CFShow(cfString);
//AudioObjectShow() give us anything?
printf("--- AudioObjectShow(audioDevices[%d]=0x%x):\n", i, audioDevices[i]);
AudioObjectShow(audioDevices[i]);
printf("---\n");
}
}
Start of output...
AudioObjectID: 0x1
Class: Audio System Object
Name: The Audio System Object
-------------------------------------------------
audioDevices[0] = 0xd2
Darryl\u2019s iPhone Microphone
--- AudioObjectShow(audioDevices[0]=0xd2):
---
-------------------------------------------------
audioDevices[1] = 0x41
LG UltraFine Display Audio
--- AudioObjectShow(audioDevices[1]=0x41):
---
-------------------------------------------------
audioDevices[2] = 0x3b
LG UltraFine Display Audio
--- AudioObjectShow(audioDevices[2]=0x3b):
---
-------------------------------------------------
audioDevices[3] = 0x5d
BlackHole 16ch
--- AudioObjectShow(audioDevices[3]=0x5d):
---
-------------------------------------------------