Implementing Multi-Channel Audio Recording on iOS with Built-In and External Mics

Hi there community,

First and foremost, a big thank you to everyone who takes the time to read this.

TL;DR: How, if even possible, can I record multiple audio streams simultaneously on an iOS application (iPad/iPhone)?

I'm working on a recorder for the iPad to gather data for a machine learning project focused on speech recognition. Our goal is to capture extensive speech data, which requires recording from multiple microphones. Specifically, I need to record from all mics connected to our Scarlett 4i4 audio interface and, most importantly, also record from the built-in mic on the iPad or iPhone at the same time.

As a newcomer to Swift development, I initially explored AVAudioRecorder. However, I quickly realized that it only supports one active audio node at a time, making multi-channel recording impossible. (perhaps you can proof me wrong, would make my day) Next, I transitioned to using AVAudioEngine, but encountered the same limitation: I couldn't manage to get input nodes for both the built-in mic and the Scarlett interface channels simultaneously. The application started behaving oddly, often resulting in identical audio data being recorded across all files.

Determined to find a solution, I delved deeper into the Core Audio framework, specifically using Audio Toolbox. My approach involved creating and configuring multiple Audio Units, each corresponding to a different audio input device. Here's a brief overview of my current implementation:

  1. Listing Available Input Devices: I used AVAudioSession to enumerate all available input devices.
  2. Creating Audio Units: For each device, I created an Audio Unit and attempted to configure it for recording.
  3. Setting Up Callbacks: I set up input and output callbacks to handle the audio processing.

Despite my efforts over the last few days, I haven't had much success. The callbacks for the Audio Units don't seem to be invoked correctly, and I'm struggling to achieve simultaneous multi-channel recording. Below is a snippet of my latest attempt:

let audioUnitCallback: AURenderCallback = { (
    inRefCon: UnsafeMutableRawPointer,
    ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>,
    inTimeStamp: UnsafePointer<AudioTimeStamp>,
    inBusNumber: UInt32,
    inNumberFrames: UInt32,
    ioData: UnsafeMutablePointer<AudioBufferList>?
) -> OSStatus in
    guard let ioData = ioData else {
        return noErr
    }

    print("Input callback invoked")

    let audioUnit = inRefCon.assumingMemoryBound(to: AudioUnit.self).pointee
    var bufferList = AudioBufferList(
        mNumberBuffers: 1,
        mBuffers: AudioBuffer(
            mNumberChannels: 1,
            mDataByteSize: 0,
            mData: nil
        )
    )

    let status = AudioUnitRender(audioUnit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList)
    if status != noErr {
        print("AudioUnitRender failed: \(status)")
        return status
    }

    // Copy rendered data to output buffer
    let buffer = UnsafeMutableAudioBufferListPointer(ioData)[0]
    buffer.mData?.copyMemory(from: bufferList.mBuffers.mData!, byteCount: Int(bufferList.mBuffers.mDataByteSize))
    buffer.mDataByteSize = bufferList.mBuffers.mDataByteSize

    print("Rendered audio data")

    return noErr
}

let outputCallback: AURenderCallback = { (
    inRefCon: UnsafeMutableRawPointer,
    ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>,
    inTimeStamp: UnsafePointer<AudioTimeStamp>,
    inBusNumber: UInt32,
    inNumberFrames: UInt32,
    ioData: UnsafeMutablePointer<AudioBufferList>?
) -> OSStatus in
    guard let ioData = ioData else {
        return noErr
    }

    print("Output callback invoked")

    // Process the output data if needed

    return noErr
}

In essence, I'm stuck and in need of guidance. Has anyone here successfully implemented multi-channel recording on iOS, especially involving both built-in microphones and external audio interfaces? Any shared experiences, insights, or suggestions on how to proceed would be immensely appreciated.

Thank you once again for your time and assistance!

Implementing Multi-Channel Audio Recording on iOS with Built-In and External Mics
 
 
Q