1

vDSP_desamp()ルーチンを使用して、常にキャプチャされているオーディオ信号のダウンサンプリングを実行しようとしています。Accelerate フレームワークのドキュメントによると、このルーチンは FIR フィルタリングとデシメーションを実行します。

ただし、FIR フィルタリングを実行するためにサンプル履歴を保存するために必要な循環バッファーの入力パラメーターが API に提供されていないため、競合があります。これにより、各関数呼び出し中にサンプル履歴がリセットされているか、私が知っているアルゴリズムとは異なるアルゴリズムが適用されていると思われます。

残念ながら、この関数は完全なブラック ボックスであり、フィルタリングの実行方法や信号の連続性を確保する方法についてのヒントはありません。

フィルタリングの連続性を得るために、前のバッファの最後の N サンプル (N はフィルタ タップの数) で各フレームをパディングすれば十分だと思いますか? を呼び出しvDSP_desamp()た後、これらの padding-sample 出力を破棄しますが、パディング サンプルが処理された後、サンプル履歴行が正しく初期化されるはずです。

の内部に関するヒントvDSP_desamp()は大歓迎です。

4

1 に答える 1

5

関数が完全なブラックボックスであると言うのはなぜですか? ドキュメントには、次の疑似コードが示されていますvDSP_desamp(A, I, F, C, N, P)

for (n = 0; n < N; ++n)
{
    sum = 0;
    for (p = 0; p < P; ++p)
        sum += A[n*I+p] * F[p];
    C[n] = sum;
}

/System/Library/Frameworks/Accelerate.framework/Frameworks/vecLib.framework/Headers/vDSP.hほぼすべての vDSP ルーチンに関する情報については、最近の OS X システムを調べることもできます。同じことを別の形で示しています。

for (n = 0; n < N; ++n)
    C[n] = sum(A[n*I+p] * F[p], 0 <= p < P);

このことから、各出力値が からまでの入力値C[n]の関数であることは明らかです。次の呼び出しの最初の出力値を現在の呼び出しと同じパターンで継続したい場合、現在の呼び出しの最後の出力値 (最後の出力値は になるため、最後の出力値は になります) と、次の値. これは、 で始まる入力値の関数になります。PA[n*I + 0]A[n*I + P-1]nN-1C[N-1]C[N]C[N]A[N*I + 0]A[N*I]

C[0]次に、次の呼び出しでそれを最初の出力値 と一致させます。でC[0]始まる入力値の関数になります。A[0*I + 0]A[0]

したがって、現在の呼び出しが終了した場所から次の呼び出しを続行するには、値をコピーしたり、その先にコピーしたりする必要がA[N*I]ありA[0]ます。A(これは、配列にデータを移動してから新しいデータを追加することで、配列を再利用していることを前提としています。A+N*I最初のパラメーターとして に渡すことで、データをそのまま使用することもできますvDSP_desamp。)

コピーする値の数は、Aafter (および含む)にある値の数になりますA[N*I]。たとえば、 にNumber値がAある場合は、次を使用できます。

memcpy(A+N*I, A, (Number - N*I) * sizeof *A);

次に、新しいデータを追加しますA[Number - N*I]memmove(送信元と送信先の範囲が重複している場合は、ではなくを使用する必要がありますがmemcpy、これは vDSP_desamp では珍しいことです。通常、連続する呼び出しで共有されるデータは、バッファー全体のごく一部です。)


注:擬似コードは、操作の基本的な数学を表しています。vDSP ルーチンの実際の演算は、パフォーマンス上の理由から、異なる方法で配置される場合があります。そのため、実際の結果には、疑似コードを直接使用して計算される値とは異なる丸め誤差が含まれる場合があります。

于 2013-10-15T15:02:58.747 に答える