I am trying to perform a FFT in swift using vDSP but when I call the absolute
function I get a bad access exception: Thread 3: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
. I suspect that I have made some error in managing the memory when using unsafe pointers, however I cannot figure out what it is.
static func test(signal: [Float]) -> [Float] {
let length = vDSP_Length(signal.count)
let log2n = vDSP_Length(ceil(log2(Float(length * 2))))
let fftSetup = vDSP.FFT(log2n: log2n, radix: .radix2, ofType: DSPSplitComplex.self)!
var forwardInputReal = [Float](signal) // Copy the signal here
var forwardInputImag = [Float](repeating: 0, count: Int(length))
var forwardOutputReal = [Float](repeating: 0, count: Int(length))
var forwardOutputImag = [Float](repeating: 0, count: Int(length))
var magnitudes = [Float](repeating: 0, count: Int(signal.count))
forwardInputReal.withUnsafeMutableBufferPointer { forwardInputRealPtr in
forwardInputImag.withUnsafeMutableBufferPointer { forwardInputImagPtr in
forwardOutputReal.withUnsafeMutableBufferPointer { forwardOutputRealPtr in
forwardOutputImag.withUnsafeMutableBufferPointer { forwardOutputImagPtr in
// Input
let forwardInput = DSPSplitComplex(realp: forwardInputRealPtr.baseAddress!, imagp: forwardInputImagPtr.baseAddress!)
// Output
var forwardOutput = DSPSplitComplex(realp: forwardOutputRealPtr.baseAddress!, imagp: forwardOutputImagPtr.baseAddress!)
fftSetup.forward(input: forwardInput, output: &forwardOutput)
vDSP.absolute(forwardOutput, result: &magnitudes)
}
}
}
}
return magnitudes
}
The same exception happened in my case when initializing a DCT transformer.
It looks like the library uses an FFT algorithm that requires the window size to be a power of two. Once I met this requirement and padded my data accordingly, the problem went away.