1

我正在尝试使用Swift Accelerate 库将交错DSPComplex向量转换为向量。下面代码的最后一行产生错误DSPSplitComplexvDSP_ctozSegmentation fault: 11

我不明白vDSP_ctoz当我分配了大向量并且只尝试处理少量元素时,为什么会尝试访问越界内存。向量的大小为 2048,N(要处理的元素数量)的参数为vDSP_ctoz1。

我也尝试N在调用时使用不同的步幅和值vDSP_ctoz,但无济于事。

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

1 回答 1

2

DSPSplitComplex是一个包含指针数组的结构,因此您需要一个DSPSplitComplex元素并且必须为其realpimagp属性分配存储空间。

“步幅”参数不是以字节为单位,而是以“元素”为单位。所以你通过__IZ == 1是因为你想填充目标数组中的连续元素。

您必须传递__IC == 2源数组可能并不明显,即源数组的步幅以Float单位而不是 DSPComplex单位给出。这可以从 提到该功能有效的vDSP_ctoz文档中推断出来

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

当然,您最终必须释放内存。

于 2017-07-08T05:15:41.653 回答