7

NAudio を使用するオーディオ プレーヤーがあり、各周波数帯域のリアルタイムの強度を表示したいと考えています。

1024 サンプルのブロックごとにトリガーされるイベントがあります。

public void Update(Complex[] fftResults)
{
   // ??
}

私が欲しいのは、各周波数帯域の強度を示す数値の配列です。ウィンドウを 16 のバンドに分割したいとします。

たとえば、より多くの低音周波数がある場合、次のようになります。

░░░░░░░░░░░░░░░░
▓▓▓░░░░░░░░░░░░░
▓▓▓░░░░░░░░░░░░░
▓▓▓▓░░░░░░░░░░░░
▓▓▓▓▓░░░░░░░░░░░
▓▓▓▓▓▓▓▓░░░▓░░▓░

そのデータでこれが可能である場合、そのイベント ハンドラーに何を入れるべきですか?

入ってくるデータ (Complex[]) は既に FFT で変換されています。ステレオストリームです。

初挑戦:

    double[] bandIntensity = new double[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

    public void Update(Complex[] fftResults)
    {
        // using half fftResults because the others are just mirrored
        int band = 0;
        for (int n = 0; n < fftResults.Length/2; n++)
        {
            band = (int)((double)n / (fftResults.Length / 2) * bandIntensity.Length);
            bandIntensity[band] += Math.Sqrt(fftResults[n].X * fftResults[n].X + fftResults[n].Y * fftResults[n].Y);
            bandIntensity[band] /= 2;
        }
    }

上記は何かを行っていますが、最初の 2 つのバンドには入りすぎていると思います。私はシャキーラを演奏していますが、低音はあまりありません。

ありがとう!

4

1 に答える 1

10

ここでおそらく対処したい 2 つの別個の問題があります。

(1) ウィンドウ機能

FFT の前にウィンドウ関数をデータに適用する必要があります。そうしないと、スペクトルの漏れが発生し、スペクトルが非常に不鮮明になります。スペクトル漏れの不快な副作用の 1 つは、なんらかの重要な DC (0 Hz) 成分がある場合、棒グラフに表示されているような 1/f 形状になることです。

(2) 対数振幅・周波数軸

人間の聴覚は、基本的に強度軸と周波数軸の両方で対数的です。それだけでなく、スピーチや音楽は、スペクトルの低周波部分により多くのエネルギーを持つ傾向があります。強度対周波数をよりわかりやすく意味のある表示にするために、通常、振幅軸と周波数軸の両方を対数にします。振幅軸の場合、これは通常、dB をフルスケールでプロットすることによって処理されます。つまり、

magnitude_dB = 10 * log10(magnitude);

周波数軸の場合、おそらくビンをバンドにグループ化し、それぞれをオクターブ (2:1 の周波数範囲) にするか、より一般的には高解像度の 3 番目のオクターブにすることをお勧めします。したがって、10 個の「小節」だけが必要な場合は、次のオクターブ バンドを使用できます。

   25 -    50 Hz
   50 -   100 Hz
  100 -   200 Hz
  200 -   400 Hz
  400 -   800 Hz
  800 -  1600 Hz
 1600 -  3200 Hz
 3200 -  6400 Hz
 6400 - 12800 Hz
12800 - 20000 Hz

(サンプル レートが 44.1 kHz で、オーディオ入力ハードウェアの上限が 20 kHz であると仮定します)。

マグニチュード (dB) 強度スケールを持つことは、この種のアプリケーションではほぼ必須ですが、対数周波数軸はあまり重要ではないことに注意してください。そのため、既存の線形ビニングを試してみて、適用することで得られる効果を確認してください。時間領域のウィンドウ関数 (まだ持っていないと仮定します) と振幅スケールを dB に変換します。

于 2011-10-12T06:45:32.057 に答える