我们正在开发一个从外部麦克风录制声音的项目。为了分析目的,我们需要大约5k Hz的采样率。
我们使用AvAudioEngine来录制声音。由于我们知道苹果设备无法以特定的速率进行录制,因此我们使用AVAudioConverter降低采样率。
但正如您所知,这类似于压缩,因此我们降低采样率越低,文件大小和时长也会相应减少。这目前正在发生(如果我在这方面有任何错误,请纠正我)。
问题
问题是,降低采样率会缩短文件长度,并影响计算和分析。例如,一小时的录音被降级为45分钟。假设我们对5分钟的时间间隔进行分析,那么这将导致错误。
最好的解决方案是什么?
查询
我们在互联网上搜索过,但我们无法弄清楚installTap上的缓冲区大小会产生什么影响。在当前代码中,我们将其设置为2688。
有人可以澄清吗?
代码
let bus = 0
let inputNode = engine.inputNode
let equalizer = AVAudioUnitEQ(numberOfBands: 2)
equalizer.bands[0].filterType = .lowPass
equalizer.bands[0].frequency = 3000
equalizer.bands[0].bypass = false
equalizer.bands[1].filterType = .highPass
equalizer.bands[1].frequency = 1000
equalizer.bands[1].bypass = false
engine.attach(equalizer) //Attach equalizer
// Connect nodes
engine.connect(inputNode, to: equalizer, format: inputNode.inputFormat(forBus: 0))
engine.connect(equalizer, to: engine.mainMixerNode, format: inputNode.inputFormat(forBus: 0))
// call before creating converter because this changes the mainMixer's output format
engine.prepare()
let outputFormat = AVAudioFormat(commonFormat: .pcmFormatInt16,
sampleRate: 5000,
channels: 1,
interleaved: false)!
// Downsampling converter
guard let converter: AVAudioConverter = AVAudioConverter(from: engine.mainMixerNode.outputFormat(forBus: 0), to: outputFormat) else {
print("Can't convert in to this format")
return
}
engine.mainMixerNode.installTap(onBus: bus, bufferSize: 2688, format: nil) { (buffer, time) 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: 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)
if status == .haveData {
// Process with converted buffer
}
}
do {
try engine.start()
} catch {
print("Can't start the engine: \(error)")
}
预期结果
我们可以接受对缓冲区的压缩,但我们希望输出文件具有相同的录制时长。如果我们录制10分钟,则输出文件应该包含10分钟的数据。