Search code examples
iosswiftcore-audioswift3

Extracting data from AudioBufferList in Swift 3


I'm trying to extract the native [Float] array out of a rendered AudioBufferList where the audio unit's stream is set up for 32-bit floating point. In Swift 1 & 2 I did this:

    var monoSamples = [Float]()
    for i in 0..<Int(inNumberFrames) {
        withUnsafePointer(to: &bufferList.mBuffers.mData, {
            let ptr = $0
            let newPtr = ptr + i
            let sample = unsafeBitCast(newPtr.pointee, to: Float.self)
            monoSamples.append(sample)
        })
    }

Undoubtedly not the fastest method, but it worked. In Swift 3 this compiles without error but at runtime I get a crash:

fatal error: can't unsafeBitCast between types of different sizes

That's a bit surprising; Swift's Float is 32-bit and the stream's data is 32-bit.

What I'd like to do is simply:

    withUnsafeMutablePointer(to: &bufferList.mBuffers.mData, {
        let monoSamples = [Float](UnsafeBufferPointer(start: $0, count:Int(inNumberFrames)))
    })

But there I get a compile error:

Expression type '[Float]' is ambiguous without more context

What's the right way to do this?


Solution

  • If you un-converted your code to Swift 2, it does not work. You may have modified too much when converting your code to Swift 3.

    Try this:

    var monoSamples = [Float]()
    let ptr = bufferList.mBuffers.mData?.assumingMemoryBound(to: Float.self)
    monoSamples.append(contentsOf: UnsafeBufferPointer(start: ptr, count: Int(inNumberFrames)))