一尘不染

AVAudioEngine下采样问题

swift

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

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,并且缓冲区中充满了来自麦克风的数据。

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

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

这实际上是有效的,并且我得到的缓冲区的格式为8000Hz,声音可以完美地降采样,唯一的问题是声音也从我不想要的扬声器中发出(如果我不连接它,缓冲区为空)。

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

非常感谢任何帮助,意见或想法。


阅读 279

收藏
2020-07-07

共1个答案

一尘不染

我只需将混音器的音量更改为0即可解决此问题。

mixer.volume = 0

这使我能够利用引擎主混音器的强大功能将任何采样率重新采样到所需的采样率,而不会听到直接从扬声器传出的麦克风反馈环路。如果有人需要任何澄清,请告诉我。

现在这是我的代码:

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))
mixer.volume = 0
engine.connect(mixer, to: mainMixer, format: audioFormat)

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)
}
2020-07-07