nul*_*ife 5 audio core-audio swift avaudioengine swift3
我在对从麦克风中提取的音频进行下采样时遇到问题。我正在使用 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)
}
Run Code Online (Sandbox Code Playgroud)
此代码在 iPhone 5s 上运行良好,因为麦克风输入为 8000Hz,并且缓冲区填充了来自麦克风的数据。
问题是我希望能够从 iPhone 6s(及更高版本)录制麦克风以 16000Hz 录制的内容。奇怪的是,如果我将 mixernode 与引擎 mainmixernode 连接起来(使用以下代码):
engine.connect(mixer, to: mainMixer, format: audioFormat)
Run Code Online (Sandbox Code Playgroud)
这实际上是有效的,我得到的缓冲区的格式为 8000Hz,声音完全降采样,唯一的问题是声音也从我不想要的扬声器发出(如果我不连接它缓冲区为空)。
有谁知道如何解决这个问题?
非常感谢任何帮助、输入或想法。
另一种方法是使用AVAudioConverterSwift 5
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) }
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2821 次 |
| 最近记录: |