Last active
June 5, 2020 09:52
-
-
Save ChunMinChang/ea74c8228745449873716e1d98ba956e to your computer and use it in GitHub Desktop.
CoreAudio Playground #coreaudio #multichannel_audio
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CXX = g++ | |
CFLAGS=-Wall -std=c++14 | |
LIBRARIES = -framework AudioUnit -framework CoreAudio | |
all: | |
$(CC) $(CFLAGS) $(LIBRARIES) PreferredChannelLayout.cpp -o PreferredChannelLayout | |
clean: | |
rm PreferredChannelLayout |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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