Search code examples
swiftaudioavfoundation

How do you access multiple channels in AVAudioEngine playback?


I have an audio file with 5.1 channels. How do I get access to a buffer containing all of this information during playback?

The setup is roughly like this

    engine.attach(playerNode)
        
    engine.connect(playerNode, to: engine.mainMixerNode, format: audioFile.processingFormat)
    engine.prepare()
        
    try? engine.start()

File loading and playback is pretty standard, I think.

    let audioFile: AVAudioFile = try? .init(forReading: url, commonFormat: AVAudioCommonFormat.pcmFormatFloat32, interleaved: false)

    // ...
    
    playerNode.scheduleFile(audioFile, at: nil)

Then I used a tap on the bus to get access to the buffer.

    let format: AVAudioFormat = engine.mainMixerNode.outputFormat(forBus: 0)

    engine.mainMixerNode.installTap(
        onBus: 0,
        bufferSize: 1024,
        format: format
    ) { buffer, time in

        // Do something cool with buffer, but buffer only has two channels.

        for channel in 0..<buffer.format.channelCount {
        }
    }

Questions:

  • Is a tap on the the bus the right way to get hold of this data? Os there a better way?
  • How do I get at the data for more than two channels?

Solution

  • Install your tap on the playerNode and don't bother specifying the format:

    playerNode.installTap(
        onBus: 0,
        bufferSize: 1024,
        format: nil
    ) { buffer, time in
    
        // 6 channel buffer
        for channel in 0..<buffer.format.channelCount {
        }
    }