I am not familiar with the handling of audio data and would appreciate your help.
I am trying to decode G711 µlaw raw data using AudioConverterFillComplexBuffer, but the decoding fails due to
kAudioConverterErr_InvalidInputSize(1768846202).
Below is the code I tried.
var inputFormat = AudioStreamBasicDescription(
mSampleRate: 8000,
mFormatID: kAudioFormatULaw,
mFormatFlags: 0,
mBytesPerPacket: 1,
mFramesPerPacket: 1,
mBytesPerFrame: 1,
mChannelsPerFrame: 1,
mBitsPerChannel: 8,
mReserved: 0
)
var outputFormat = AudioStreamBasicDescription(
mSampleRate: 44100.0,
mFormatID: kAudioFormatLinearPCM,
mFormatFlags: kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked,
mBytesPerPacket: 2,
mFramesPerPacket: 1,
mBytesPerFrame: 2,
mChannelsPerFrame: 1,
mBitsPerChannel: 16,
mReserved: 0
)
var converter: AudioConverterRef?
private func createAudioConverter() {
let result = AudioConverterNew(&inputFormat, &outputFormat, &converter)
if result != noErr {
print("err: Unable To CreateConverter")
}
}
struct G711Data {
var data: Data
var packetSize: Int
}
private let queue = DispatchQueue(label: "decode")
public func read(data: Data) -> AudioBufferList? {
// Input
let packetSize = data.count
var g711Data = G711Data(data: data, packetSize: packetSize)
// Output
var packets = outputFormat.mBytesPerPacket
let outputFrameCount = UInt32(data.count) / outputFormat.mBytesPerFrame
let outputBufferSize = outputFrameCount * outputFormat.mBytesPerFrame
var outputBufferList = AudioBufferList(
mNumberBuffers: 1,
mBuffers: AudioBuffer(
mNumberChannels: 1,
mDataByteSize: UInt32(outputBufferSize),
mData: UnsafeMutableRawPointer.allocate(byteCount: Int(outputBufferSize), alignment: MemoryLayout<UInt8>.alignment)
)
)
return queue.sync {
let status = AudioConverterFillComplexBuffer(converter!, ConverterCallback, &g711Data, &packets, &outputBufferList, nil)
guard status == noErr else {
print("AudioConverterFillComplexBuffer Err: \(status)") // ERROR!!!!
return nil
}
return outputBufferList
}
}
func ConverterCallback(_ converter: AudioConverterRef,
_ packetCount: UnsafeMutablePointer<UInt32>,
_ ioData: UnsafeMutablePointer<AudioBufferList>,
_ outPacketDescriptions: UnsafeMutablePointer<UnsafeMutablePointer<AudioStreamPacketDescription>?>?,
_ context: UnsafeMutableRawPointer?) -> OSStatus {
var g711Data = context!.assumingMemoryBound(to: G711Data.self).pointee
let packetSize = UInt32(g711Data.packetSize)
// Fill the input buffer with G711 data
ioData.pointee.mNumberBuffers = 1
ioData.pointee.mBuffers.mData = UnsafeMutableRawPointer.allocate(byteCount: g711Data.data.count, alignment: 0)
_ = g711Data.data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) in
memcpy((ioData.pointee.mBuffers.mData?.assumingMemoryBound(to: UInt8.self))!, bytes, Int(packetSize))
}
ioData.pointee.mBuffers.mDataByteSize = packetSize
outPacketDescriptions?.pointee = nil
packetCount.pointee = 1
return noErr
}
What am I doing wrong? Please help.
Thank you.