I'm trying to call the function DSPSplitComplex
:
var real = [Float](input_windowed)
var imaginary = [Float](repeating: 0.0, count: input_windowed.count)
var splitComplex = DSPSplitComplex(realp: &real, imagp: &imaginary)
but that gives the warning:
Cannot use inout expression here; argument 'realp' must be a pointer that outlives the call to 'init(realp:imagp:)'
so after that I tried:
var splitComplex = DSPSplitComplex(
realp: UnsafeMutablePointer(mutating: real),
imagp: UnsafeMutablePointer(mutating: imaginary) )
and that gives the warning:
Initialization of 'UnsafeMutablePointer<Float>' results in a dangling pointer
so finally I tried this:
var splitComplex =
withUnsafeMutablePointer(to: &real) { realpPtr in
withUnsafeMutablePointer(to: &imaginary) { imaginaryPtr in
DSPSplitComplex(realp: realpPtr, imagp: imaginaryPtr)
}
}
and that gives the following compile error:
Cannot convert value of type 'UnsafeMutablePointer<[Float]>' to expected argument type 'UnsafeMutablePointer<Float>'
What is the correct way to call this function (and similar functions in the Accelerate framework) ?
You are very close. You just need a buffer pointer rather than a pointer to the array:
real.withUnsafeMutableBufferPointer { realp in
imaginary.withUnsafeMutableBufferPointer { imagp in
var splitComplex = DSPSplitComplex(realp: realp.baseAddress!,
imagp: imagp.baseAddress!)
// ...
}
}
Note the BufferPointer part of the calls.
For a full example, see Apple's FFT sample.
The key point of this syntax rather than your original approach is that it ensures that real
and imaginary
continue to exist for the lifetime of the pointers. In your original code, the arrays can be deallocated on the very next line, making splitComplex
hold dangling pointers.