0

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.

burnsi
  • 6,194
  • 13
  • 17
  • 27
zones
  • 1
  • Does this answer your question? [Convert audio from iPhone microphone to iLBC](https://stackoverflow.com/questions/36887497/convert-audio-from-iphone-microphone-to-ilbc) – koen Jan 24 '23 at 11:58

0 Answers0