John Scalo John Scalo - 2 months ago 20
iOS Question

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?

Answer

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)))
Comments