I am trying to convert AVAudioPCMBuffer
from Float32 44.1kHz to Int16 8kHz. I use AVAudioConverter
. But after the conversion I get corrupted data. When I read data every 100ms from microphone I get every 800th sample broken (first sample in the read data). Broken sample looks as follows:
broken sample
It's just one sample out of 800 but it sounds like really annoying click every 100ms. Here is a piece of my code:
...
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
}
When I write buffer without any conversion I get clear sound without corruption. If I read data every 200ms every 1600th sample will be corrupted. So it's only the first sample from every buffer I get is corrupted.
I really don't know what is wrong with my code and why it works like that. Is there any error?
P.S. I don't really care about the conversion, all I need is get 16 bit PCM 8kHz raw audio data from microphone. If anyone knows how to do that the other way I'd really appreciate your help.