AVAudioConverter 损坏数据
AVAudioConverter corrupts data
我正在尝试将 AVAudioPCMBuffer
从 Float32 44.1kHz 转换为 Int16 8kHz。我使用 AVAudioConverter
。但是在转换之后我得到了损坏的数据。当我每 100 毫秒从麦克风读取一次数据时,每第 800 个样本就会被破坏(读取数据中的第一个样本)。破碎的样本如下所示:
broken sample
这只是 800 个样本中的一个,但听起来每 100 毫秒点击一次真的很烦人。
这是我的一段代码:
...
let outputFormat = AVAudioFormat(commonFormat: .pcmFormatInt16,
sampleRate: 8000,
channels: 1,
interleaved: false)!
let input = self.engine.inputNode
let bus = 0
let inputFormat = input.outputFormat(forBus: bus)
let bufferSize = inputFormat.sampleRate * 0.1 // Read every 100ms
input.installTap(onBus: bus, bufferSize: UInt32(bufferSize), format: inputFormat) { (buffer, time) -> Void in
let convertedBuffer = self.convertBuffer(buffer: buffer, from: inputFormat, to: outputFormat)
if self.isRecording {
self.inFile?.seekToEndOfFile()
let data = Data(buffer: UnsafeBufferPointer(start: convertedBuffer.int16ChannelData![0], count: Int(convertedBuffer.frameLength)))
self.inFile?.write(data)
}
...
func convertBuffer(buffer: AVAudioPCMBuffer,
from inputFormat: AVAudioFormat,
to outputFormat: AVAudioFormat) -> AVAudioPCMBuffer {
let converter = AVAudioConverter(from: inputFormat, to: outputFormat)!
let inputCallback: AVAudioConverterInputBlock = { inNumPackets, outStatus in
outStatus.pointee = .haveData
return buffer
}
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)
return convertedBuffer
}
当我在没有任何转换的情况下写入缓冲区时,我得到清晰的声音而没有损坏。如果我每 200 毫秒读取一次数据,每 1600 个样本都会被破坏。所以这只是我得到的每个缓冲区中的第一个样本被破坏了。
我真的不知道我的代码有什么问题,也不知道为什么会这样。有没有错误?
P.S。
我真的不关心转换,我只需要从麦克风获取 16 位 PCM 8kHz 原始音频数据。如果有人知道如何以其他方式做到这一点,我将非常感谢您的帮助。
音频转换器有内部状态。在每次调用 convertBuffer
时创建一个转换器而不是一个转换器应该可以解决这个问题。
我正在尝试将 AVAudioPCMBuffer
从 Float32 44.1kHz 转换为 Int16 8kHz。我使用 AVAudioConverter
。但是在转换之后我得到了损坏的数据。当我每 100 毫秒从麦克风读取一次数据时,每第 800 个样本就会被破坏(读取数据中的第一个样本)。破碎的样本如下所示:
broken sample
这只是 800 个样本中的一个,但听起来每 100 毫秒点击一次真的很烦人。 这是我的一段代码:
...
let outputFormat = AVAudioFormat(commonFormat: .pcmFormatInt16,
sampleRate: 8000,
channels: 1,
interleaved: false)!
let input = self.engine.inputNode
let bus = 0
let inputFormat = input.outputFormat(forBus: bus)
let bufferSize = inputFormat.sampleRate * 0.1 // Read every 100ms
input.installTap(onBus: bus, bufferSize: UInt32(bufferSize), format: inputFormat) { (buffer, time) -> Void in
let convertedBuffer = self.convertBuffer(buffer: buffer, from: inputFormat, to: outputFormat)
if self.isRecording {
self.inFile?.seekToEndOfFile()
let data = Data(buffer: UnsafeBufferPointer(start: convertedBuffer.int16ChannelData![0], count: Int(convertedBuffer.frameLength)))
self.inFile?.write(data)
}
...
func convertBuffer(buffer: AVAudioPCMBuffer,
from inputFormat: AVAudioFormat,
to outputFormat: AVAudioFormat) -> AVAudioPCMBuffer {
let converter = AVAudioConverter(from: inputFormat, to: outputFormat)!
let inputCallback: AVAudioConverterInputBlock = { inNumPackets, outStatus in
outStatus.pointee = .haveData
return buffer
}
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)
return convertedBuffer
}
当我在没有任何转换的情况下写入缓冲区时,我得到清晰的声音而没有损坏。如果我每 200 毫秒读取一次数据,每 1600 个样本都会被破坏。所以这只是我得到的每个缓冲区中的第一个样本被破坏了。
我真的不知道我的代码有什么问题,也不知道为什么会这样。有没有错误?
P.S。 我真的不关心转换,我只需要从麦克风获取 16 位 PCM 8kHz 原始音频数据。如果有人知道如何以其他方式做到这一点,我将非常感谢您的帮助。
音频转换器有内部状态。在每次调用 convertBuffer
时创建一个转换器而不是一个转换器应该可以解决这个问题。