I'm working on an audio recording app which uses an external USB Audio interface (e.g, Focusrite Scarlett Solo) connected to an iPhone.
When I run AVAudioSession.sharedInstance().currentRoute.inputs it returns the interface correctly.
1 element
- 0 : <AVAudioSessionPortDescription: 0x28307c650, type = USBAudio; name = Scarlett Solo USB; UID = AppleUSBAudioEngine:Focusrite:Scarlett Solo USB:130000:1,2; selectedDataSource = (null)>
Channels are returned correctly as well.
po AVAudioSession.sharedInstance().currentRoute.inputs.first?.channels
▿ Optional<Array<AVAudioSessionChannelDescription>>
▿ some : 2 elements
- 0 : <AVAudioSessionChannelDescription: 0x283070b60, name = Scarlett Solo USB 1; label = 4294967295 (0xffffffff); number = 1; port UID = AppleUSBAudioEngine:Focusrite:Scarlett Solo USB:130000:1,2>
- 1 : <AVAudioSessionChannelDescription: 0x283070b70, name = Scarlett Solo USB 2; label = 4294967295 (0xffffffff); number = 2; port UID = AppleUSBAudioEngine:Focusrite:Scarlett Solo USB:130000:1,2>
When I connect the inputNode to mainMixerNode in AVAudioEngine it uses multi-channel input so the Line/Instrument input is on the right channel and Microphone input is on the left.
How can I make it so that I use only the 2nd Channel (guitar) as a mono to be played back in both speakers?
I've been looking through some docs and discussions but could not find the answer.
I tried changing channels to 1 in audio format but as expected it plays the first channel in mono but I can't select 2nd channel to be played instead.
let input = engine.inputNode
let inputFormat = input.inputFormat(forBus: 0)
let preferredFormat = AVAudioFormat(
commonFormat: inputFormat.commonFormat,
sampleRate: inputFormat.sampleRate,
channels: 1,
interleaved: false
)!
engine.connect(input, to: engine.mainMixerNode, format: preferredFormat)
I had the same question asked on stack overflow as well and received a working answer there. https://stackoverflow.com/questions/75684026/choose-specific-input-channel-as-a-mono-input-from-usb-device-in-avaudiosession/76079369#76079369
It seems to be a pretty simple one by setting channel map on auAudioUnit of the input node.
engine.inputNode.auAudioUnit.channelMap = [1, 1]
1 is the channel 1 in this case. If you need to use channel 0 it would be [0, 0] and same would apply for other channels.