2017-07-07 4 views
1

J'essaie de convertir un vecteur DSPComplex entrelacé en un vecteur DSPSplitComplex en utilisant vDSP_ctoz à partir de la bibliothèque Swift Accelerate. Je ne comprends pas pourquoi vDSP_ctoz essaye d'accéder à la mémoire hors-limite quand j'ai alloué de grands vecteurs et essaye seulement de traiter un petit nombre d'éléments . Les vecteurs sont de taille 2048 et l'argument pour N (nombre d'éléments à traiter) dans vDSP_ctoz est 1.Erreur de segmentation à l'aide de Swift Accelerate vDSP_ctoz

J'ai aussi essayé d'utiliser différents pas et N valeurs lors de l'appel vDSP_ctoz, en vain.

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

Répondre

2

DSPSplitComplex est une structure contenant des tableaux pointeurs, si vous avez besoin d'un seul élément DSPSplitComplex et doit allouer le stockage pour ses realp et imagp propriétés. Les arguments "stride" ne sont pas mesurés en octets mais en unités "élément". Vous passez donc __IZ == 1 car vous souhaitez remplir les éléments contigus dans les tableaux de destination.

Il peut ne pas être évident que vous devez passer __IC == 2 pour le tableau source, à savoir la foulée du tableau source est donnée dans Float unités et non en unités DSPComplex. Cela peut être déduit de la vDSP_ctoz documentation qui mentionne que la fonction fait effectivement

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

Enfin, le dernier argument de vDSP_ctoz est le nombre d'éléments à traiter .

Mettre tous ensemble, c'est comment il devrait fonctionner:

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

et bien sûr vous devez libérer la mémoire par la suite.