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

折月煮酒 提交于 2020-01-12 09:52:28

问题


I want to read the buffer from my microphone into an array, with 441khz 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 ?


回答1:


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: fmt, frameCapacity: AVAudioFrameCount(fmt.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()
}


来源:https://stackoverflow.com/questions/40821754/i-want-to-change-the-sample-rate-from-my-input-node-from-44100-to-8000

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!