LoginSignup
5

More than 5 years have passed since last update.

[vDSP][Swift3] ポインタの扱い

Posted at

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

他、問題や対策が見つかれば、その都度書き加えたいと思います。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5