AVAudioEngine 下采样问题 [英] AVAudioEngine downsample issue

查看:23
本文介绍了AVAudioEngine 下采样问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在对从麦克风中提取的音频进行下采样时遇到问题.我正在使用 AVAudioEngine 通过以下代码从麦克风中获取样本:

I'm having an issue with downsampling audio taken from the microphone. I'm using AVAudioEngine to take samples from the microphone with the following code:

assert(self.engine.inputNode != nil)
let input = self.engine.inputNode!

let audioFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 8000, channels: 1, interleaved: false)    
let mixer = AVAudioMixerNode()
engine.attach(mixer)
engine.connect(input, to: mixer, format: input.inputFormat(forBus: 0))

do {
    try engine.start()

    mixer.installTap(onBus: 0, bufferSize: 1024, format: audioFormat, block: {
            (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in
        //some code here
    })

} catch let error {
    print(error.localizedDescription)
}

此代码在 iPhone 5s 上运行良好,因为麦克风输入为 8000Hz,并且缓冲区会填充来自麦克风的数据.

This code works great on the iPhone 5s since the microphone input is 8000Hz, and the buffer gets filled with data from the microphone.

问题是我希望能够从 iPhone 6s(及更高版本)录制麦克风以 16000Hz 录制的内容.奇怪的是,如果我将 mixernode 与引擎 mainmixernode(使用以下代码)连接起来:

The problem is that I want to be able to record from iPhone 6s (and upwards) which microphone records with 16000Hz. And whats weird is that if I connect the mixernode with the engines mainmixernode (with the following code):

engine.connect(mixer, to: mainMixer, format: audioFormat)

这确实有效,而且我得到的缓冲区的格式为 8000Hz,并且声音完全降采样了,唯一的问题是声音也从我不想要的扬声器发出(如果我不想要连接它缓冲区为空).

this actually works, and the buffer I get has the format of 8000Hz and the sound comes out perfectly downsampled, only problem is that the sound also comes out from the speaker which I don't want (and if I don't connect it the buffer is empty).

有人知道如何解决这个问题吗?

Does anyone know how to resolve this issue?

非常感谢任何帮助、输入或想法.

Any help, input or thought is very much appreciated.

推荐答案

另一种方法,在 Swift 5 中使用 AVAudioConverter

let engine = AVAudioEngine()


func setup() {

    let input = engine.inputNode
    let bus = 0
    let inputFormat = input.outputFormat(forBus: bus )
    guard let outputFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 8000, channels: 1, interleaved: true), let converter = AVAudioConverter(from: inputFormat, to: outputFormat) else{
        return
    }

    input.installTap(onBus: bus, bufferSize: 1024, 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
            }
        }

        if 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)
        }
    }
    do {
        try engine.start()
    } catch { print(error) }
}

这篇关于AVAudioEngine 下采样问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆