Skip to content

Instantly share code, notes, and snippets.

@ChunMinChang
Last active June 5, 2020 09:52
Show Gist options
  • Save ChunMinChang/ea74c8228745449873716e1d98ba956e to your computer and use it in GitHub Desktop.
Save ChunMinChang/ea74c8228745449873716e1d98ba956e to your computer and use it in GitHub Desktop.
CoreAudio Playground #coreaudio #multichannel_audio
CXX = g++
CFLAGS=-Wall -std=c++14
LIBRARIES = -framework AudioUnit -framework CoreAudio
all:
$(CC) $(CFLAGS) $(LIBRARIES) PreferredChannelLayout.cpp -o PreferredChannelLayout
clean:
rm PreferredChannelLayout
#include <iostream>
#include <cassert>
#include <AudioUnit/AudioUnit.h>
#include <CoreAudio/CoreAudio.h>
#define AU_OUT_BUS 0
#define AU_IN_BUS 1
#define DEBUG true // Set true to log the debugging messages.
#define LOG(...) DEBUG && fprintf(stdout, __VA_ARGS__)
OSStatus
get_preferred_channel_layout()
{
AudioUnit outputUnit;
AudioComponentDescription desc;
AudioComponent comp;
AudioDeviceID deviceId = 0;
UInt32 size;
OSStatus rv = noErr;
Boolean writable;
desc.componentType = kAudioUnitType_Output;
// desc.componentSubType = kAudioUnitSubType_DefaultOutput;
desc.componentSubType = kAudioUnitSubType_HALOutput;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
comp = AudioComponentFindNext(NULL, &desc);
if (comp == NULL) {
LOG("%d: Could not find default audio output hardware.", rv);
return rv;
}
rv = AudioComponentInstanceNew(comp, &outputUnit);
if (rv != noErr) {
LOG("%d: Could not link default audio output hardware to the audio unit.", rv);
return rv;
}
// Check if we have IO
UInt32 hasIO = 0;
size = sizeof(hasIO);
rv = AudioUnitGetProperty(outputUnit,
kAudioOutputUnitProperty_HasIO,
kAudioUnitScope_Output,
AU_OUT_BUS,
&hasIO,
&size);
if (!hasIO) {
LOG("%d: No audio output for this audio unit.", rv);
return rv;
}
// Get the current device
size = sizeof(deviceId);
rv = AudioUnitGetProperty(outputUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Output,
AU_OUT_BUS,
&deviceId,
&size);
if (rv != noErr) {
LOG("%d: Could not get current audio output device.", rv);
return rv;
}
LOG("device id: %d\n", deviceId);
// Get the default channel layout
size = 0;
rv = AudioUnitGetPropertyInfo(outputUnit,
kAudioDevicePropertyPreferredChannelLayout,
kAudioUnitScope_Output,
AU_OUT_BUS,
&size,
&writable);
if (rv != noErr) {
LOG("%d: Could not get size of kAudioDevicePropertyPreferredChannelLayout.", rv);
return rv;
}
assert(size > 0 && writable);
AudioChannelLayout output_hw_layout;
rv = AudioUnitGetProperty(outputUnit,
kAudioDevicePropertyPreferredChannelLayout,
kAudioUnitScope_Output,
AU_OUT_BUS,
&output_hw_layout,
&size);
if (rv != noErr) {
LOG("%d: Could not get kAudioDevicePropertyPreferredChannelLayout.", rv);
return rv;
}
if (output_hw_layout.mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions) {
// kAudioChannelLayoutTag_UseChannelBitmap
// kAudioChannelLayoutTag_Mono
// kAudioChannelLayoutTag_Stereo
// ....
LOG("%d: We only handle UseChannelDescriptions for now.", rv);
return rv;
}
LOG("channel layout:\n");
for (UInt32 i = 0; i < output_hw_layout.mNumberChannelDescriptions; ++i) {
LOG("[%d] %d(0x%x)\n", i, output_hw_layout.mChannelDescriptions[i].mChannelLabel, output_hw_layout.mChannelDescriptions[i].mChannelLabel);
}
return rv;
}
int main()
{
get_preferred_channel_layout();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment