AVAudioEngine 下采样问题 [英] AVAudioEngine downsample issue
问题描述
我在对从麦克风中提取的音频进行下采样时遇到问题.我正在使用 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屋!