Working with external multichannel audio interfaces

I am a novice when it comes to CoreAudio, so I got Kevin Avila's and Chris Adamson's book Learning CoreAudio and gave myself a crash course. I also downloaded the sample code for CAPlayThrough (https://developer.apple.com/library/content/samplecode/CAPlayThrough/Introduction/Intro.html) and was modifying items here and there to see what the effect it will have.


So the next step for me was to see if I can read the input from an external audio interface using the CAPlayThrough example. I have a 4 input channel interface (behringer uphoria 404 to be exact). So in system preferences, I selected the default input to be the audio interface and the default output to be the built in speakers on my MBP. Right off the bat I got an input from input channels 1 and 2 and was able to output it to my built in speakers. However the input channels 3 and 4 from the audio interface was not able to output any sound to the built in speakers. So I combed through the documentation and the closest documentation that mentioned using multi channels was this:


https://developer.apple.com/library/content/technotes/tn2091/_index.htm


So I took the example code of setting up the channel map and made this mapping for the input AudioUnit


SInt32 * channelMap;

UInt32 numOfChannels = asbd_dev1_in.mChannelsPerFrame;

UInt32 mapSize = numOfChannels *sizeof(SInt32);

channelMap = (SInt32 *)malloc(mapSize);

for(UInt32 i=0;i<numOfChannels;i++)

{

channelMap[i]=-1;

}

channelMap[0] = 0;

channelMap[1] = 1;

channelMap[2] = 0;

channelMap[3] = 1;

AudioUnitSetProperty(mInputUnit,

kAudioOutputUnitProperty_ChannelMap,

kAudioUnitScope_Output,

1,

channelMap,

mapSize);

free(channelMap)

Still the same results. However when I changed the channel map to just this:


channelMap[0] = 2;

channelMap[1] = 3;


I was able to get the sound from input channels 3 and 4 from the interface to the built in speakers, but not from input channels 1 and 2.


So I figured I have to map also the output AudioUnit channel map as well so this is the code that I used to set the channel map for the output AudioUnit


SInt32 * channelMap;

UInt32 numOfChannels = asbd_dev2_out.mChannelsPerFrame;

UInt32 mapSize = numOfChannels *sizeof(SInt32);

channelMap = (SInt32 *)malloc(mapSize);


for(UInt32 i=0;i<numOfChannels;i++)

{

channelMap[i]=-1;

}

channelMap[0] = 0;

channelMap[1] = 1;

channelMap[2] = 0;

channelMap[3] = 1;

AudioUnitSetProperty(mOutputUnit,

kAudioOutputUnitProperty_ChannelMap,

kAudioUnitScope_Input,

1,

channelMap,

mapSize);

free(channelMap);



Still the same results. The end goal is to be able to get the input from all 4 channels from my interface and output it to the default output device on my mac. I've looked into stereo mixer component types and everything, but it seems like they are more for other types of audio units to be connected into the Graph. I tried to create an AUNode for my input AudioUnit and connect it to a stereo mixer unit, but I ran into troubles of setting the AudioStreamBasicDescription for the mixer audiounit. If anyone has some pointers, guides or other documentation that I probably missed please let me know. Thanks!


UPDATE:


UPDATE:

These are some of the things that I have tried so far besides modifying the channel maps:

  1. I thought that maybe each physical input on my 4 channel interface needed an AudioUnit to represent it and choose which channel to get the input stream from with the channel map. But when setting up multiple AudioUnit for the input, the the last AudioUnit being set ended up acting as the default input. Further more, the AUGraph only allowed me to add 1 output node.
  2. Use the AudioUnit type
    kAudioUnitSubType_StereoMixer
    to combine multiple streams with multiple output render call backs. I was able to set up the render callbacks and properly link it to the stereo mixer AudioUnit, but wasn't sure how to connect the input streams to the output.