Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I want to change the sample rate from my input node from 44100 to 8000

I want to read the buffer from my microphone into an array, with 44.1khz its working fine but with the sample rate 8khz it comes to an error

ERROR:    >avae> AVAudioIONodeImpl.mm:884: SetOutputFormat: required condition is false: format.sampleRate == hwFormat.sampleRate
2016-11-26 19:32:40.674 Atem[5800:1168274] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: format.sampleRate == hwFormat.sampleRate'

with my following code :

 var engine = AVAudioEngine()
    func setup() {

    print("new")
    let input = engine.inputNode!
    let bus = 0

    let mixer = AVAudioMixerNode()
    engine.attach(mixer)

    engine.connect(input, to: mixer, format: input.outputFormat(forBus: 0))
    //pcmFormatFloat64 -- pcmFormatFloat32
    print(engine.isRunning)
    let fmt = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 12000, channels: 1, interleaved: true)

    do {
        try engine.start()


     print(engine.isRunning)

        mixer.installTap(onBus: bus, bufferSize: 1024, format: fmt) { (buffer, time) -> Void in
            // 8kHz buffers!
            print(buffer.format)
        }
    }catch {
        //print("An error occurred \(error)")
        return
    }

}

can anyone help ?

like image 389
Osman Avatar asked Nov 26 '16 18:11

Osman


1 Answers

Updated answer this answer used to try to rate convert with taps and mixers, which does not work.

You can use an AVAudioConverter to do rate conversion on the AVAudioEngine inputNode:

let engine = AVAudioEngine()

func setup() {
    let input = engine.inputNode
    let bus = 0
    let inputFormat = input.outputFormat(forBus: 0)
    let outputFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 8000, channels: 1, interleaved: true)!

    let converter = AVAudioConverter(from: inputFormat, to: outputFormat)!

    input.installTap(onBus: bus, bufferSize: 512, format: inputFormat) { (buffer, time) -> Void in
        var newBufferAvailable = true

        let inputCallback: AVAudioConverterInputBlock = { inNumPackets, outStatus in
            if newBufferAvailable {
                outStatus.pointee = .haveData
                newBufferAvailable = false
                return buffer
            } else {
                outStatus.pointee = .noDataNow
                return nil
            }
        }

        let convertedBuffer = AVAudioPCMBuffer(pcmFormat: outputFormat, frameCapacity: AVAudioFrameCount(outputFormat.sampleRate) * buffer.frameLength / AVAudioFrameCount(buffer.format.sampleRate))!

        var error: NSError?
        let status = converter.convert(to: convertedBuffer, error: &error, withInputFrom: inputCallback)
        assert(status != .error)

        // 8kHz buffers!
        print(convertedBuffer.format)
    }

    try! engine.start()
}
like image 136
Rhythmic Fistman Avatar answered Nov 07 '22 05:11

Rhythmic Fistman