2017-02-21 23 views
1

Swift 2からSwift 3への次のポインタの初期化をどのように変換できますか?Swift 2からSwift 3へのポインタの変換

var values: [Double] 
... 
var valuesAsComplex : UnsafeMutablePointer<DSPDoubleComplex>? 
values.withUnsafeBufferPointer { (resultPointer: UnsafeBufferPointer<Double>) -> Void in 
    valuesAsComplex = UnsafeMutablePointer<DSPDoubleComplex>(resultPointer.baseAddress) 
} 

更新: すべての答えのためにあなたに感謝。 ポインタを@Aderstedtとして永続的に再バインドすると動作しますが、結果を返すことはできません。何か案は?あなたはポインタ "再バインド" する必要が

// Create result 
var result = [Double](repeating: 0.0, count: N/2) 
var resultAsComplex : UnsafeMutablePointer<DSPDoubleComplex>? 
result.withUnsafeMutableBytes { 
    resultAsComplex = $0.baseAddress?.bindMemory(to: DSPDoubleComplex.self, capacity: result.count) 
} 

// Do complex->real inverse FFT. 
vDSP_fft_zripD(fftSetup!, &tempSplitComplex, 1, LOG_N, FFTDirection(FFT_INVERSE)); 

// This leaves result in packed format. Here we unpack it into a real vector. 
vDSP_ztocD(&tempSplitComplex, 1, resultAsComplex!, 2, N2); 

// Neither the forward nor inverse FFT does any scaling. Here we compensate for that. 
var scale : Double = 0.5/Double(N); 
vDSP_vsmulD(&result, 1, &scale, &result, 1, vDSP_Length(N)); 

return result 
+0

問題を示す*自己完結型*の例を提供できますか?入力、出力、および期待される出力? –

+0

@ martin-rありがとうございました!私はiOSカメラを使って心拍数モニタを作成したいと思います。私は30fpsでバックカメラから画像を読み込み、画像の平均色相を配列に格納しています。ノイズを除去するために、FFTとAccelerateフレームワークを使用してバンドパスフィルタを作成します。 私は自分のコードをgithubで共有しました。https://github.com/codifilo/camera-heart-rate/blob/master/CameraHeartRate/FFT.swift#L119 – codifilo

+0

正確には動作しません。 - デバッグのヘルプを求める質問(「なぜこのコードは動作しないのですか?」)には、目的の動作、特定の問題またはエラー、およびそれを再現するのに必要な最短コードが含まれている必要があります。**明確な問題文は他の読者には有用ではない。 「[mcve]の作成方法」も参照してください。 –

答えて

1

:閉鎖valuesAsComplex内部

values.withUnsafeMutableBufferPointer { 
    $0.baseAddress!.withMemoryRebound(to: DSPDoubleComplex.self, capacity: values.count/2) { 
     valuesAsComplex in 

     // ... 

    } 
} 

UnsafeMutablePointer<DSPDoubleComplex>で、DSP 関数に渡すことができます。

あなたは明記documentationとして閉鎖の 外に要素ストレージへのポインタを渡さないする必要があります。

ポインタ引数はクロージャの実行の期間中有効です。

偶然に動作できる

が、クロージャの 実行後、要素ストレージが同じ メモリアドレスのままであること(またはポインタ であるので、アレイはさらに、存在するという保証はありませんストレージの寿命を保証する強力な基準ではありません)。あなたは、非内DSPDoubleComplexとしてvaluesの内容にアクセスすることができているマーティン・Rの回答に加えて

tempSplitComplex = DSPDoubleSplitComplex(realp: &mag, imagp: &phase) 
    vDSP_ztocD(&tempSplitComplex, 1, &tempComplex, 2, N2); 

    tempComplex.withUnsafeMutableBufferPointer { 
     $0.baseAddress!.withMemoryRebound(to: Double.self, capacity: values.count * 2) { 
      complexAsDouble in 

      vDSP_rectD(complexAsDouble, 2, complexAsDouble, 2, N2); 
     } 
    } 

    vDSP_ctozD(&tempComplex, 2, &tempSplitComplex, 1, N2); 

var result = [Double](repeating: 0.0, count: N/2) 

    result.withUnsafeMutableBufferPointer { 
     $0.baseAddress!.withMemoryRebound(to: DSPDoubleComplex.self, capacity: result.count/2) { 
      resultAsComplex in 

      vDSP_ztocD(&tempSplitComplex, 1, resultAsComplex, 2, N2); 

     } 
    } 
+0

それは動作します。あなたの時間をありがとう。 – codifilo

-2

を、でしょう、あなたの場合は


閉鎖をエスケープすると、次のようにメモリを新しいタイプに永続的に再バインドすることもできます:

var values: [Double] = ... 

var valuesAsComplex : UnsafeMutablePointer<DSPDoubleComplex>? = nil 

values.withUnsafeMutableBytes { 
    valuesAsComplex = $0.baseAddress?.bindMemory(to: DSPDoubleComplex.self, capacity: values.count) 
} 

// You can access valuesAsComplex here: 
print("\(valuesAsComplex![0].real)") 

// ... and mutate it. 
valuesAsComplex![0].imag = 1 
+0

すべての 'withUnsafe ....'メソッドのクロージャに渡されるポインタは、クロージャの実行中だけ有効です。たとえばhttps://developer.apple.com/reference/foundation/data/1779823-withunsafemutablebytesの警告を参照してください。私が理解する限り、bindMemoryはポインタの有効性を拡張しません。 –

+0

上記の例では、クロージャの外側で 'valuesAsComplex'にアクセス(および変更)できます。 'bindMemory'のドキュメントには大きな赤い警告記号が付いているので、このアプローチを一般的に使うべきかどうかはわかりません。 – Aderstedt

+0

上記のリンクは間違っていました。私が意図したのはhttps://developer.apple.com/reference/swift/array/1538652-withunsafemutablebufferpointerです:* "ポインタの引数はクロージャの実行中だけ有効です。" * –

関連する問題