Swift 3 UnsafeMutablePointer<Float> migration problem

Hi all,


Trying to migrate my code to Swift 3 but I can't seem to solve this problem. Need help!


I've got this audio buffer and a pointer to it's channel data... like this


var buffer: AVAudioPCMBuffer
var bufPtrs = [UnsafeMutablePointer<Float>]()
for index in 0..<outputChannelCount {
     let channelPtr = buffer.floatChannelData?[index]
      bufPtrs.append(channelPtr!)
}


Now I need to hand in this pointer to a C library function that does some resampling.


This function wants an UInt8 pointer to an array of UInt8 elements, like this...


func swr_convert(_ s: OpaquePointer!, _ out: UnsafeMutablePointer<UnsafeMutablePointer<UInt8>?>!, _ out_count: Int32, _ in: UnsafeMutablePointer<UnsafePointer<UInt8>?>!, _ in_count: Int32) -> Int32


Before Swift 3 I just used this code successfully.


numSamplesDecoded = swr_convert(audioPlayer.swrContext!,
                        UnsafeMutablePointer(bufPtrs),
                        frame.memory.nb_samples,
                        UnsafeMutablePointer(frame.memory.extended_data),
                        frame.memory.nb_samples)


But that doesn't work in Swift 3.


How do I reference this chunk of memory in Swift 3 so that the C library function will accept it?


I really don't understand the explanation in the documentation for Swift 3.


Please help / Jörgen

Replies

I came up with this solution. Don't know if it's safe or has any drawbacks compared to my Swift 2 solution...


let outBuffers = unsafeBitCast(UnsafeMutablePointer(mutating: bufPtrs), to: UnsafeMutablePointer<UnsafeMutablePointer<UInt8>?>.self)
let inBuffers = unsafeBitCast(frame?.pointee.extended_data, to: UnsafeMutablePointer<UnsafePointer<UInt8>?>.self)
                   
numSamplesDecoded = swr_convert(audioPlayer.swrContext!,
     outBuffers,
     (frame?.pointee.nb_samples)!,
     inBuffers,
     (frame?.pointee.nb_samples)!)


Any comments are welcome!

unsafeBitCast(_:to:)
is generally a last resort mechanism. Hopefully we can do better.

Note Before going further I strongly recommend you read the UnsafeRawPointer Migration doc, which covers a lot of the backstory here.

What does the C prototype for

swr_convert
look like?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

If the library routine really processes a data vector of floats (not bytes), then you might want to create a C wrapper function around that library routine that declares the correct vector types, and from Swift call your corrected C wrapper instead of the library routine directly.