8

私はiPhone用にDemetriのPitchDetectorプロジェクトを実装し、2つの問題に直面しました。1)あらゆる種類のバックグラウンドノイズが周波数読み取りバナナを送信し、2)低周波数の音が正しくピッチングされていません。私はギターをチューニングしようとしましたが、高い弦が機能している間、チューナーは低いEを正しく識別できませんでした。

ピッチ検出コードはRIOInterface.mmにあり、次のようになります...

// get the data
AudioUnitRender(...);

// convert int16 to float
Convert(...);

// divide the signal into even-odd configuration
vDSP_ctoz((COMPLEX*)outputBuffer, 2, &A, 1, nOver2);

// apply the fft
vDSP_fft_zrip(fftSetup, &A, stride, log2n, FFT_FORWARD);

// convert split real form to split vector
vDSP_ztoc(&A, 1, (COMPLEX *)outputBuffer, 2, nOver2);

次に、Demetriは、次のように「支配的な」頻度を決定します。

float dominantFrequency = 0;
int bin = -1;
for (int i=0; i<n; i+=2) {
    float curFreq = MagnitudeSquared(outputBuffer[i], outputBuffer[i+1]);
    if (curFreq > dominantFrequency) {
        dominantFrequency = curFreq;
        bin = (i+1)/2;
    }
}
memset(outputBuffer, 0, n*sizeof(SInt16));

// Update the UI with our newly acquired frequency value.
[THIS->listener frequencyChangedWithValue:bin*(THIS->sampleRate/bufferCapacity)];

まず、ローパスフィルターを適用する必要があると思います...しかし、私はFFTの専門家ではなく、vDSP関数から返されたデータに対してどこでどのようにそれを行うのか正確にはわかりません。また、低周波数でコードの精度を向上させる方法もわかりません。支配的な周波数を決定する他のアルゴリズムがあるようですが、AppleのAccelerateフレームワークによって返されるデータを使用するときに、正しい方向へのキックを探します。

アップデート:

加速フレームワークには、実際にはいくつかのウィンドウ関数があります。このような基本的なウィンドウを設定します

windowSize = maxFrames;
transferBuffer = (float*)malloc(sizeof(float)*windowSize);
window = (float*)malloc(sizeof(float)*windowSize);
memset(window, 0, sizeof(float)*windowSize);
vDSP_hann_window(window, windowSize, vDSP_HANN_NORM); 

次に挿入して適用します

vDSP_vmul(outputBuffer, 1, window, 1, transferBuffer, 1, windowSize); 

vDSP_ctoz関数の前。次に、残りのコードをoutputBufferの代わりに「transferBuffer」を使用するように変更します...しかし、これまでのところ、最終的なピッチの推測に劇的な変化は見られません。

4

4 に答える 4

8

ピッチは、ピークマグニチュード周波数ビンと同じではありません(これは、AccelerateフレームワークのFFTが直接提供するものです)。したがって、ピーク周波数検出器はピッチ推定に信頼性がありません。ローパスフィルターは、ノートのファンダメンタルが欠落しているか非常に弱い場合(一部のボイス、ピアノ、ギターのサウンドで一般的)、および/またはそのスペクトルに強力な倍音がたくさんある場合には役立ちません。

ミュージカルサウンドの広帯域スペクトルまたはスペクトルグラフを見ると、問題がわかります。

通常、音楽のピッチをより信頼性の高い方法で推定するには、他の方法が必要です。これらのいくつかには、自己相関法(AMDF、ASDF)、ケプストラム/ケプストラム分析、調和積スペクトル、フェーズボコーダー、および/またはRAPT(ピッチ追跡のためのロバストアルゴリズム)やYAAPTなどの複合アルゴリズムが含まれます。FFTは、上記のメソッドの一部のサブパートとしてのみ役立ちます。

于 2011-08-24T20:35:38.350 に答える
3

少なくとも、FFTを計算する前に、時間領域データにウィンドウ関数を適用する必要があります。このステップがないと、パワースペクトルにアーティファクト(スペクトル漏れを参照)が含まれ、ピッチ情報を抽出する試みが妨げられます。

単純なHann(別名Hanning)ウィンドウで十分です。

于 2011-08-25T08:30:51.930 に答える
1

サンプルの頻度とブロックサイズはどれくらいですか?LowEは約80Hzであるため、キャプチャブロックがこの周波数で多くのサイクルをキャプチャするのに十分な長さであることを確認する必要があります。これは、フーリエ変換が周波数スペクトルをそれぞれ数Hz幅のビンに分割するためです。たとえば、44.1 kHzでサンプリングし、1024ポイントの時間領域サンプルがある場合、各ビンの幅は4410/1024 =43.07Hzになります。したがって、低いEは2番目のビンにあります。さまざまな理由(スペクトル漏れと有限の時間ブロックの性質に関係する)のために、実際には、FFT結果の最初の3つまたは4つのビンのデータを非常に疑わしいと見なす必要があります。

サンプルレートを8kHzに下げると、同じブロックサイズで7.8125Hz幅のビンが得られます。これで、低Eが10番目または11番目のビンになります。これははるかに優れています。より長いブロックサイズを使用することもできます。

そして、Paul Rが指摘しているように、スペクトル漏れを減らすためにウィンドウを使用する必要があります。

于 2011-08-25T09:14:02.947 に答える
1

iPhoneの周波数応答機能は100〜200 Hzを下回ります(例については、 http://blog.faberacoustical.com/2009/ios/iphone/iphone-microphone-frequency-response-comparison/を参照してください)。

低ギター弦の基本モードを検出しようとしている場合、マイクがフィルターとして機能し、関心のある周波数を抑制している可能性があります。取得できるfftデータの使用に関心がある場合は、いくつかのオプションがあります。検出しようとしているノートの周囲の周波数領域でデータをウィンドウ処理できるため、高音モードよりもマグニチュードが低い場合でも、最初のモードだけが表示されます(つまり、最初の弦を調整して配置するためのトグルがあります)。このモードで)。

または、サウンドデータをローパスフィルター処理することもできます。これは、時間領域で行うことも、周波数領域ですでに周波数領域のデータがあるため、さらに簡単に行うこともできます。非常に単純な時間領域ローパスフィルターは、時間移動平均フィルターを実行することです。非常に単純な周波数領域ローパスフィルターは、fftの大きさに、低周波数範囲で1を使用し、高周波数で線形(またはステップ)ランプダウンするベクトルを乗算することです。

于 2012-08-21T04:48:18.407 に答える