2017-11-22 16 views
1

私のアプリケーション内でサウンドを処理しています。 DSPアルゴリズムはC++で記述されています。データをC++に渡し、その結果をSwiftのオーディオサブシステムに渡す必要があります。出力にそれだけでコピー今、入力を[[Float]]配列をObjective-C++に渡すことができません

#define BufferSize 10240 

@interface EffectsWrapper : NSObject 
- (void) processBuffer: (float * _Nonnull *_Nonnull) dataIn ofSize: (int) dataSize intoOutputBuffer: (float * _Nonnull *_Nonnull) dataOut; 
@end 

@implementation EffectsWrapper 
- (void) processBuffer: (float * _Nonnull *_Nonnull) dataIn ofSize: (int) dataSize intoOutputBuffer: (float * _Nonnull *_Nonnull) dataOut 
{ 
    for(int channel = 0; channel < 2; channel ++) 
    { 
     for(int i = 0; i < dataSize; i ++) 
     { 
      float data = dataIn[channel][i]; 
      dataOut[channel][i] = data; 
     } 
    } 
} 
@end 

あなたが見ることができるように:

は、私が書いた Objective-C++クラスを C++にデータを渡します。

このメソッドの呼び出しは、MyClassのプロパティとして説明されているMTAudioProcessingTapProcessCallbackクロージャ内で実行されます。 EffectsWrapperもこのクラスのプロパティです。

は、「プロセス」のデータは、最初に、私はのように入力と出力アレイを作成するには、次の

var dataIn: [[Float]] = Array(repeating: Array(repeating: 0.0, count: framesCount), count: 2) 
var dataOut: [[Float]] = Array(repeating: Array(repeating: 0.0, count: framesCount), count: 2) 

第二に、私は、データを持つ入力配列を埋めます。そして私はそうのようなEffectsWrapper.processメソッドを呼び出します。

let dataInPtr = UnsafeMutablePointer(mutating: [UnsafeMutablePointer(mutating: dataIn[0]), UnsafeMutablePointer(mutating: dataIn[1])]) 
let dataOutPtr = UnsafeMutablePointer(mutating: [UnsafeMutablePointer(mutating: dataOut[0]), UnsafeMutablePointer(mutating: dataOut[1])]) 
myClass.effectsWrapper.processBuffer(dataInPtr, ofSize: Int32(framesCount), intoOutputBuffer: dataOutPtr) 

問題がEffectsWrapper内のデータは完全にゴミであるということです。時々、それは私に割り当てエラーを投げる。そして、私が作成するポインタが、必要とする配列の要素ではなく、メモリ内のいくつかのランダムな場所を指している理由はわかりません。

助けてください。

答えて

0

問題はここに

let dataInPtr = UnsafeMutablePointer(mutating: [UnsafeMutablePointer(mutating: dataIn[0]), UnsafeMutablePointer(mutating: dataIn[1])]) 

のようなそのコードが配列からUnsafePointer Sを作成するを橋渡し暗黙的に使用しています。これらのポインタは、後で使用するために(間接的に)保存されます。これは未定義の動作です。 UnsafePointerUnsafeMutablePointerのマニュアルは、https://developer.apple.com/documentation/swift/unsafepointerhttps://developer.apple.com/documentation/swift/unsafemutablepointerです。そこに述べたように、インスタンスのか 配列の要素の暗黙のブリッジを介して作成

ポインタが呼び出される 関数の実行中にのみ有効です。 関数の実行後に使用するポインタをエスケープすることは、未定義の動作です。特に、UnsafePointerイニシャライザを呼び出すときに暗黙的に ブリッジを使用しないでください。

この問題を解決する方法を理解する前に、Swiftとラッパーの間で受け渡しされる入力または出力バッファーがメモリ内の領域であるような方法でラッパーを書く可能性を検討する必要がありますチャネルデータは連続して記憶される。バッファはポインタの配列として扱われる必要はなく、Objective-C(++)とSwiftの間で浮動小数点の配列を渡す方が簡単です。

+0

私は1D配列を使い、 '&'演算子を使ってポインタを渡すことに決めました。とにかく 'C++'はオーディオチャンネルを別々の配列として扱います。魅力のように動作します。 –

関連する問題