#vDSPのSwift3対策
Swift3になってから、ポインタの扱いが変わりました。
vDSPはC/C++で書かれたライブラリで、関数はポインタの引数を当てる必要があります。
特にvDSPではオリジナルなデータ型が多く、Swiftでは型のキャストを行う頻度が高いです。
ここでは、Swift3にアップデートした際に生じた問題を、少しづつまとめていければと思います。
#DSPComplex型
vDSP_ctoz()を使用して、サンプルデータをDSPSplitComplex型に格納する際に、サンプルデータ (FloatもしくはDouble)からDSPComplex型に変換する必要があります。
正確には、[Float] or [Double]型からUnsafePointer型に変換します。
以前では
swift.swift
var buffer:[Float] = [Float](count:fftsize,repeatedValue:0.0)
/* buffer にサンプルデータ格納*/
let complexBuffer = UnsafePointer<DSPComplex>(&buffer)
vDSP_ctoz(complexBuffer, 2, &splitComplex, 1, self.ffthalfsize)
/*FFT*/
というふうに行なっていました。
Swift3ではここでエラーが起こります。
ここで、
swift3.swift
var buffer:[Float] = [Float](count:fftsize,repeatedValue:0.0)
/* buffer にサンプルデータ格納*/
let audioBufferComplex:UnsafePointer<DSPComplex> = UnsafeRawPointer(buffer).bindMemory(to: DSPComplex.self, capacity: buffer.count)
vDSP_ctoz(audioBufferComplex, 2, &splitComplex, 1, self.ffthalfsize)
/*FFT*/
Inversion FFT の場合では、とりあえず以下のように対応しました。
swift3.swift
var result = [Float](repeating: 0.0,count: Int(self.fftsize))
let resultAtComplex = UnsafeMutablePointer<DSPComplex>.allocate(capacity:result.count)
vDSP_fft_zrip(self.setup, &splitComplex, 1, self.log2n, FFTDirection(FFT_INVERSE))
vDSP_ztoc(&splitComplex, 1, resultAtComplex, 2, self.ffthalfsize)
let FloatP = UnsafeRawPointer(resultAtComplex).bindMemory(to: Float.self, capacity: result.count)
resultAtComplex.deallocate(capacity:result.count)
result = Array(UnsafeBufferPointer(start:FloatP,count:result.count))
他、問題や対策が見つかれば、その都度書き加えたいと思います。