23

低速のCPU、コードサイズ、RAMなどの限られたリソースで、電子チューナーやソフトウェアチューナーと同様に、音符のピッチを検出するのに最適な方法はありますか?

使用する必要があります:

  • キスFFT
  • FFTW
  • 離散ウェーブレット変換
  • 自己相関
  • ゼロクロッシング分析
  • オクターブ間隔のフィルター

他の?

一言で言えば、私がやろうとしているのは、任意の(合理的な)楽器で演奏された、中央Cから2オクターブ下から2オクターブ上にある単一の音符を認識することです。半音の20%以内にしたいのですが、つまり、ユーザーがフラットすぎたりシャープすぎたりする場合は、それを区別する必要があります。ただし、チューニングに必要な精度は必要ありません。

4

5 に答える 5

15

それほど正確な精度が必要ない場合は、FFTで十分です。 最初にオーディオのチャンクをウィンドウ処理して、明確に定義されたピークを取得してから、最初の重要なピークを見つけます。

ビン幅=サンプリングレート/FFTサイズ:

基本的な範囲は20Hz〜7 kHzであるため、14kHzのサンプリングレートで十分です。次の「標準」サンプリングレートは22050Hzです。

FFTサイズは、必要な精度によって決定されます。FFT出力は周波数が線形ですが、楽音は周波数が対数であるため、最悪の場合の精度は低周波数になります。20 Hzでの半音の20%の場合、1.2 Hzの幅が必要です。これは、 18545のFFT長を意味します。次の2の累乗は215= 32768です。これは1.5秒のデータであり、ラップトップのプロセッサの計算に3ミリ秒かかります。

これは「ミッシングファンダメンタル」のある信号では機能せず、「最初の重要な」ピークを見つけるのはやや困難です(高調波はファンダメンタルよりも高いことが多いため)が、状況に合った方法を見つけることができます。

自己相関と倍音の積スペクトルは、倍音の1つではなく、波の真の基本波を見つけるのに優れていますが、非調和性をうまく処理できるとは思いません。ピアノやギターなどのほとんどの楽器は不調和です(調和はわずかに鋭いです。彼らがどうあるべきか)。しかし、それは本当にあなたの状況に依存します。

また、 Chirp-Z変換を使用して、対象の特定の周波数帯域内でのみ計算することにより、さらに多くのプロセッササイクルを節約できます。

比較のために、Pythonでいくつかの異なるメソッドを作成しました。

于 2009-11-28T08:35:23.943 に答える
13

ピッチ認識をリアルタイムで (かつ半音の 1/100 以内の精度で) 実行したい場合、唯一の希望はゼロクロッシング アプローチです。そして、それはかすかな希望です。申し訳ありません。ゼロクロッシングは、わずか数波長のデータからピッチを推定でき、スマートフォンの処理能力で実行できますが、波長を測定する際の小さなエラーが推定周波数に大きなエラーをもたらすため、特に正確ではありません. ギター シンセサイザー (数波長だけでギターの弦からピッチを推測する) のようなデバイスは、測定値をスケールの音符に量子化することによって機能します。これは目的に合うかもしれませんが、ゼロクロスは単純な波形ではうまく機能しますが、より複雑な楽器の音ではうまく機能しなくなる傾向があることに注意してください。

私のアプリケーション (スマートフォンで動作するソフトウェア シンセサイザー) では、単一の楽器の音符の録音をウェーブテーブル合成の原料として使用します。特定のピッチで音符を生成するには、録音の基本ピッチを正確に知る必要があります。半音の 1/1000 以内 (実際には 1/100 の精度しか必要ありませんが、これについては OCD です)。ゼロクロッシング アプローチは、これに対して不正確すぎます。FFT ベースのアプローチは、不正確すぎるか、遅すぎます (または両方の場合もあります)。

この場合に私が見つけた最善のアプローチは、自己相関を使用することです。自己相関では、基本的にピッチを推測し、その対応する波長でサンプルの自己相関を測定します。もっともらしいピッチの範囲 (たとえば、A = 55 Hz から A = 880 Hz まで) を半音単位でスキャンすることにより、最も相関性の高いピッチを特定し、そのピッチの近くでより細かくスキャンして、より正確な値。

あなたに最適なアプローチは、これを何に使用しようとしているかによって完全に異なります。

于 2009-09-21T23:45:00.547 に答える
6

あなたが言及したすべての方法に精通しているわけではありませんが、何を選択するかは、主に入力データの性質に依存する必要があります。純音を分析していますか、それとも入力ソースに複数の音符がありますか? スピーチはあなたのインプットの特徴ですか?入力をサンプリングしなければならない時間の長さに制限はありますか? 精度と速度のトレードオフは可能ですか?

何を選択するかは、計算を時間空間で実行するか、周波数空間で実行するかによってもある程度異なります。時系列を周波数表現に変換するには時間がかかりますが、私の経験では、より良い結果が得られる傾向があります。

自己相関は、時間領域で 2 つの信号を比較します。単純な実装は単純ですが、計算に比較的コストがかかります。これは、元の信号とタイム シフトされた信号のすべてのポイント間のペアワイズ差分、続いて自己相関関数のターニング ポイントを特定するための差分、および対応する最小値の選択が必要になるためです。基本周波数。代替方法があります。たとえば、平均マグニチュード ディファレンシングは自己相関の非常に安価な形式ですが、精度が低下します。関数には基本波以外のピークが存在するため、すべての自己相関手法にはオクターブ エラーのリスクがあります。

ゼロクロス ポイントの測定は単純明快ですが、信号に複数の波形が存在する場合は問題が発生します。

周波数空間では、 FFTに基づく手法が目的には十分効率的である場合があります。1 つの例は、信号のパワー スペクトルを各高調波でダウンサンプリングされたバージョンと比較し、スペクトルを掛け合わせて明確なピークを生成することによってピッチを識別する高調波積スペクトル技術です。

これまでと同様に、問題と制約に最適な方法を経験的に判断するには、いくつかの手法をテストしてプロファイリングすることに代わるものはありません。

このような回答は、このトピックの表面をなぞるだけです。以前のリンクと同様に、さらに読むための関連する参考文献がいくつかあります。

于 2009-09-22T00:11:02.397 に答える
5

私のプロジェクトdanstunerでは、 Audacityからコードを取得しました。それは基本的にFFTを取り、FFTに3次曲線を置き、その曲線のピークを見つけることでピークパワーを見つけました。オクターブジャンプを防ぐ必要がありましたが、かなりうまく機能します。

Spectrum.cppを参照してください。

于 2009-09-21T23:17:29.873 に答える
5

通常のサウンドにはベース周波数よりもはるかに多くの倍音とゼロ交差があるため、ゼロ交差は機能しません。

私が(ホームサイドプロジェクトとして)実験したのはこれでした:

  1. 必要なサンプル レートで ADC を使用してサウンドをサンプリングします。
  2. 波形の短期的な正と負のピークのレベルを検出します (スライディング ウィンドウなど)。つまり、エンベロープ検出器です。
  3. 波形が正のエンベロープの 90% (またはその程度) 以内に入ると高くなり、波形が負のエンベロープの 90% 以内に入ると低くなる方形波を作成します。つまり、ヒステリシスのあるトラッキング方形波です。
  4. 必要な精度を得るために必要な数のサンプルを使用して、簡単なカウント/時間計算でその方形波の周波数を測定します。

ただし、電子キーボードからの入力では、一部の楽器の音で基本周波数の 2 倍 (次のオクターブ) を拾うことができることがわかりました。これは副次的なプロジェクトであり、他のことに移る前に解決策を実装することはできませんでした。しかし、FFT よりも CPU 負荷がはるかに少ないという点で有望だと思いました。

于 2009-09-22T00:03:43.680 に答える