2017-07-07 97 views
1

我試圖使用Swift Accelerate庫中的vDSP_ctoz將交錯的DSPComplex向量轉換爲DSPSplitComplex向量。下面的代碼的最後一行產生錯誤Segmentation fault: 11使用Swift Accelerate的分段錯誤vDSP_ctoz

我不明白爲什麼vDSP_ctoz會嘗試訪問超出界限的內存時,我已經分配了大型向量,只是試圖處理少量的元素。載體是大小2048和在vDSP_ctozN(數量的元件來處理的)的參數是1

我打電話vDSP_ctoz時,沒有效果使用不同的步幅和N值也嘗試。

// set stride values 
let dspComplexStride = MemoryLayout<DSPComplex>.stride 
let dspSplitComplexStride = MemoryLayout<DSPSplitComplex>.stride 

// make interleaved vector 
var interleaved = UnsafeMutablePointer<DSPComplex>.allocate(capacity: 2048) 
for index in 0..<16 { 
    interleaved[index] = DSPComplex(real: Float(2*index), imag: Float(2*index+1)) 
} 

// make split vector 
var splitComplex = UnsafeMutablePointer<DSPSplitComplex>.allocate(capacity: 2048) 
vDSP_ctoz(
    interleaved, dspComplexStride, splitComplex, dspSplitComplexStride, 1 
) 

回答

2

DSPSplitComplex是含有指針陣列的結構, 所以需要一個單一的DSPSplitComplex元素和必須分配 存儲其realpimagp和性質。

「stride」參數不是以字節爲單位,而是以「元素」單位進行度量。 所以你通過__IZ == 1是因爲你想在目標數組中填充連續元素 。

它可能不是顯而易見的是,你必須通過__IC == 2用於源陣列,即 源陣列的步幅在Float單元,而不是在 DSPComplex單位給出。這可以從vDSP_ctoz documentation 其中提到的是,有效地發揮作用確實

for (n = 0; n < N; ++n) 
{ 
    Z->realp[n*IZ] = C[n*IC/2].real; 
    Z->imagp[n*IZ] = C[n*IC/2].imag; 
} 

最後被推斷,的vDSP_ctoz的最後一個參數是元件以 過程的數目。

全部放在一起,這是它如何工作:

import Accelerate 

let N = 16 

var interleaved = UnsafeMutablePointer<DSPComplex>.allocate(capacity: N) 
for index in 0..<N { 
    interleaved[index] = DSPComplex(real: Float(2*index), imag: Float(2*index+1)) 
} 

let realp = UnsafeMutablePointer<Float>.allocate(capacity: N) 
let imagp = UnsafeMutablePointer<Float>.allocate(capacity: N) 
var splitComplex = DSPSplitComplex(realp: realp, imagp: imagp) 

vDSP_ctoz(interleaved, 2, &splitComplex, 1, vDSP_Length(N)) 

for index in 0..<N { 
    print(splitComplex.realp[index], splitComplex.imagp[index]) 
} 

,當然最終你必須要釋放內存。