DirectXのバッファーにサンプルを保持しています。これは、楽器から演奏およびキャプチャされたノートのサンプルです。サンプルの周波数を分析するにはどうすればよいですか(ギターチューナーのように)?FFTが関係していると思いますが、HOWTOへのポインタはありません。
7 に答える
FFTは周波数がどこにあるかを把握するのに役立ちますが、周波数が何であるかを正確に知ることはできません。FFTの各ポイントは周波数の「ビン」であるため、FFTにピークがある場合、必要な周波数はそのビン内のどこかにあるか、周波数の範囲であることがわかります。
本当に正確にしたい場合は、高解像度で多くのビン(=大量のメモリと大量の計算)を備えた長いFFTが必要です。また、ログスケールスペクトルの2次補間を使用して、低解像度FFTから真のピークを推測することもできます。これは、驚くほどうまく機能します。
計算コストが最も重要な場合は、信号をゼロ交差をカウントできる形式にしようと試みることができます。カウントすればするほど、測定はより正確になります。
ただし、ファンダメンタルが欠落している場合、これらはいずれも機能しません。:)
ここでいくつかの異なるアルゴリズムの概要を説明しましたが、補間されたFFTは通常最も正確です(ただし、これは基本波が最も強い高調波である場合にのみ機能します。それ以外の場合は、それを見つけるために賢くする必要があります)。 (これは、サイクルごとに1つの交差がある波形に対してのみ機能します)。これらの条件はどちらも一般的ではありません。
基本周波数を超える部分音は、ピアノやギターなどの多くの楽器では完全な倍音ではないことに注意してください。各パーシャルは、実際には少し調子がずれているか、不調和です。したがって、FFTの高周波ピークは、基本波の整数倍に正確に一致するわけではなく、波形は1つのサイクルから次のサイクルにわずかに変化し、自己相関が失われます。
本当に正確な周波数の読み取り値を取得するには、自己相関を使用して基本波を推測し、次に2次補間を使用して真のピークを見つけます。(CPUサイクルを節約するために、周波数領域で自己相関を行うことができます。)落とし穴はたくさんあり、使用する正しい方法は実際にはアプリケーションによって異なります。
周波数ベースではなく、時間ベースの他のアルゴリズムもあります。自己相関は、ピッチ検出のための比較的単純なアルゴリズムです。参考:http ://cnx.org/content/m11714/latest/
私は、自己相関およびその他の読み取り可能なアルゴリズムの C# 実装を作成しました。http://code.google.com/p/yaalp/をご覧ください。
http://code.google.com/p/yaalp/source/browse/#svn/trunk/csaudio/WaveAudio/WaveAudio ファイルを一覧表示します。必要なファイルは PitchDetection.cs です。
(プロジェクトは GPL です。コードを使用する場合は用語を理解してください)。
ギター チューナーは FFT や DFT を使用しません。通常、ゼロクロッシングのみをカウントします。一部の波形には他の波形よりもゼロ交差が多いため、基本周波数が得られない場合がありますが、通常は基本周波数の倍数を得ることができます。1 オクターブ以上ずれているかもしれませんが、音を出すにはこれで十分です。
ゼロ交差をカウントする前にローパス フィルタリングを行うと、通常、余分なゼロ交差を取り除くことができます。ローパスフィルターを調整するには、検出したい周波数の範囲についてある程度の知識が必要です
FFT(高速フーリエ変換)が実際に関係します。FFT を使用すると、任意のアナログ信号を固定周波数と可変振幅の単純な正弦波の和で近似できます。基本的に行うことは、サンプルを取得し、それを振幅->周波数のペアに分解してから、最大の振幅に対応する周波数を取得することです。
願わくば、別の SO リーダーが、私が理論とコードの間に残したギャップを埋めてくれることを願っています!
もう少し具体的に:
入力配列の生の PCM から始めると、基本的には波の振幅と時間のグラフになります。FFT を実行すると、入力サンプリング レートの 0 から 1/2 までの周波数の周波数ヒストグラムに変換されます。結果配列の各エントリの値は、対応するサブ周波数の「強さ」になります。
したがって、S サンプル/秒でサンプリングされたサイズ N の入力配列が与えられたルート周波数を見つけるには、次のようにします。
FFT(N, input, output);
max = max_i = 0;
for(i=0;i<N;i++)
if (output[i]>max) max_i = i;
root = S/2.0 * max_i/N ;
PCMオーディオ信号の基本周波数を取得するのは難しい作業であり、それについて話すことはたくさんあります...
とにかく、通常、時間ベースの方法はポリフォニック信号には適していません。これは、複数の基本周波数による異なる高調波成分の合計によって与えられる複雑な波が、最低周波数成分のみに依存するゼロ交差率を持つためです...周波数領域では、音符間の周波数間隔が線形ではなく指数スケールに従うため、FFT は最適な方法ではありません。これは、時間領域の解析ウィンドウのサイズが十分に大きくない場合、FFT メソッドで使用される一定の周波数分解能では、低周波数ノートを解決するには不十分である可能性があることを意味します。
より適切な方法は定数 Q 変換です。これは、異なる周波数の異なるサブバンドを取得するために、信号のローパス フィルター処理と 2 によるデシメーション (つまり、各ステップのサンプリング周波数を半分にする) のプロセスの後に DFT が適用されます。解像度。このようにして、DFT の計算が最適化されます。問題は、時間分解能も可変であり、下位のサブバンドで増加することです...
最後に、単一の音符の基本周波数を推定しようとしている場合は、FFT/DFT 法で問題ありません。ポリフォニック コンテキストでは状況が変わります。異なるサウンドの部分音が重なり合い、位相差に応じて振幅が加算/キャンセルされるため、単一のスペクトル ピークが異なるハーモニック コンテンツに属する (異なるノートに属する) 可能性があります。この場合の相関は良い結果をもたらさない...
DFTを適用し、結果から基本周波数を導き出します。DFT 情報をグーグルで検索すると、必要な情報が得られます。いくつかのリンクを紹介しますが、数学の知識に対する期待は大きく異なります。
幸運を。