How does Mac’s Core Audio read audio device info?

Jacob su
3 min readNov 25, 2019

--

I recently received a mission to track os x’s audio device name and volume. As I know, there is a Core Audio framework to interact with mac’s audio hardware and this post intends to record my first experience with this framework.

My first experience with Core Audio’s document was not so delightful, especially when I open the above almost blank document page, It seems there are no samples, just a table, and the StackOverflow was more useful than this official document. After I know how to read default audio devices and track its volume, then I knew how to use the official document. So this post would explain what the basic Core Audio structs and functions look like with my simple sample, it would not cover all the topics of Core Audio, but I thought after that you would know how to use the official’s concise document.

Question one: How to get the default Audio Input Device?

Question two: How to listen to the default audio Input Device changed?

Question three: How to get the default audio input Device volume?

We need to invoke the function, getDefaultAudioInputDevice, in Question one.

Question four: How to listen to the default audio input device volume changed?

To be strict, it’s not a correct sample to listen to the default audio input device’s volume, it’s a perfect sample to listen to an audio input device’s volume, we know the default audio input device could be changed if there were multiple ones to select, so we need to listen to the default audio input device change first, then listen to the new audio device and stop listen the older audio device when user selected another audio input device.

There is a bug in above Question Two and Four, it seems the AudioObjectRemovePropertyListenerBlockdidn’t work, I confirmed it is. But my app needs to register the listener during the whole life of my app, there are no remove the listener case, So I keep the vulnerable API. But if my app needs to remove the listener I should consider this bug, and use obj-c or another API AudioObjectPropertyListenerProc in swift.

From the above four questions, we can get a blurred impression of how the basic structs in the Core Audio framework look like, then we would be inlighted how to read its official document.

The structs inside the Core Audio were being organized in a tree struct, the root one is kAudioObjectSystemObject, the other ones are the properties of the root element, in order to get the property we need an address.

var audioInputAddress = AudioObjectPropertyAddress( mSelector: kAudioHardwarePropertyDefaultInputDevice, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMaster)

then use the function AudioObjectGetPropertyData to read the property, check the Question one, of course, we can use AudioObjectSetPropertyData to write property to the element. Not just we can read/write to the element’s property, we can also listen to the property changes.

AudioObjectAddPropertyListenerBlock

ref questions two and four. With that knowledge in mind, I thought I wouldn’t so dizzy when look thought the official API documentation.

--

--