2011-10-12 11 views
7

私はNAudioを使用したオーディオプレーヤーを持っており、各周波数帯域に対してリアルタイムの強度を表示したいと考えています。 Iイベントが1024個のサンプルのブロック毎にトリガ有するNAudio周波数帯域強度

:私がしたいどの

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

は、各周波数帯の強度を表す数値の配列です。ウィンドウを16のバンドに分割したいとします。より低音域がある場合、それはこのようになります。例えば

:これはそのデータで可能であるならば、私はそのイベントハンドラに何を

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

を置く必要がありますか?

データ到着(複合[])は既に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つのバンドに入ると思うし、私はあまり低音を持っていないシャキーラをプレイしています。

ありがとうございます!

答えて

8

あなたはおそらくここに対処したい二つの別々の問題があります。

(1)窓関数

あなたはそうあなたがspectral leakageを取得します、FFTに先立って、データへのwindow functionを適用する必要があります非常に汚れたスペクトルになります。スペクトル漏れの1つの不愉快な副作用は、何らかの重要なDC(0Hz)成分があると、棒グラフに表示されているような1/fの形状になります。

(2)ログ振幅/周波数

人間の聴覚の軸は、両方の強度及び周波数軸に本質的に対数的です。それだけでなく、スピーチや音楽は、スペクトルの低周波数部分でより多くのエネルギーを持つ傾向があります。強度対周波数のより快適で有意な表示を得るために、我々は通常、振幅軸と周波数軸の両方を対数にします。この軸大きさの場合には、通常、それぞれであるかもしれない、あなたはおそらくグループバンドに自分のビンになるでしょう周波数軸の場合、すなわち、フルスケール再

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に変換します。

+1

あなたは私のヒーローです。笑。 –

+0

ウィンドウについては、BlackmannHarrisWindowが使用されていることがわかります。しかし、私はまだ10xLog10()を試していませんでしたが、グラフがどのように変化するかを見ていきます。そして0HzのDCビンを取り除きます。 –

+0

オクターブビンをバンドコレクションに適用した後でも、まだ奇妙な数字が残っていますが、左側にはまだ多すぎます...私はyスケールの数値をdBに変換しました –