This method handles the callback from installTap on the input node of AVAudioEngine. I confirmed that I am receiving mono float32 / 48000hz buffer data and I would like to convert it to mono int16 / 16000hz.
var converter: AVAudioConverter? = nil var convertBuffer: AVAudioPCMBuffer? = nil let targetFormat = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 16000, channels: 1, interleaved: false) func recordCallback(buffer: AVAudioPCMBuffer, time: AVAudioTime) { if converter == nil { convertBuffer = AVAudioPCMBuffer(pcmFormat: targetFormat, frameCapacity: buffer.frameCapacity) convertBuffer?.frameLength = convertBuffer!.frameCapacity converter = AVAudioConverter(from: buffer.format, to: convertBuffer!.format) converter?.sampleRateConverterAlgorithm = AVSampleRateConverterAlgorithm_Normal converter?.sampleRateConverterQuality = .max } guard let convertBuffer = convertBuffer else { return } log.info("Converter: \(self.converter!)") log.info("Converter buffer: \(self.convertBuffer!)") log.info("Converter buffer format: \(self.convertBuffer!.format)") log.info("Source buffer: \(buffer)") log.info("Source buffer format: \(buffer.format)") do { try converter!.convert(to: convertBuffer, from: buffer) } catch let error { log.error("Conversion error: \(error)") observer?.onError(EngineRecordTaskError.ConversionError(error: error)) return } … }
This gives me a useful error:
Conversion error: Error Domain=NSOSStatusErrorDomain Code=-50 "(null)"
If I use the alternative method .convert (to: error: withInputFrom :), it does not fill in NSError and does not fill in the target buffer - it fails.
Recorded Information:
Converter: <AVAudioConverter: 0x17001cd40> Converter buffer: < AVAudioPCMBuffer@0x17021e310 : 9600/9600 bytes> Converter buffer format: <AVAudioFormat 0x17448ba90: 1 ch, 16000 Hz, Int16> Source buffer: < AVAudioPCMBuffer@0x17021e1b0 : 19200/19200 bytes> Source buffer format: <AVAudioFormat 0x174480910: 1 ch, 48000 Hz, Float32> Conversion error: Error Domain=NSOSStatusErrorDomain Code=-50 "(null)"
Additional information from the debugger:
(lldb) po buffer.frameCapacity 4800 (lldb) po convertBuffer.frameCapacity 4800 (lldb) po buffer.frameLength 4800 (lldb) po convertBuffer.frameLength 4800
Here is the alternative conversion code I tried:
var conversionError: NSError? = nil converter!.convert(to: convertBuffer, error: &conversionError, withInputFrom: { (_, _) in return buffer }) if let conversionError = conversionError { log.error("Conversion error: \(conversionError)") observer?.onError(EngineRecordTaskError.ConversionError(error: conversionError)) return }