1

フラッシュでウィンドウ化されたフーリエ級数を使用して周波数アナライザーを作成しようとしていますが、ウィンドウのサイズが係数の大きさに大きく影響します。

教科書の数式を使用して、すべてのフレームの係数を計算しています。

     N-1
Ak = SUM { cos(freq*n*deltax) * pcmFloatValue}
     n=0

     N-1
Bk = SUM { sin(freq*n*deltax) * pcmFloatValue}
     n=0

ここで、 deltaxはサンプル間の時間間隔であり、pcmFloatValueは* n *deltax*での時間領域の値です。教科書では、積分の限界は0から2PIで、積分はPIで除算されます...しかし、私はそれを任意の間隔で使用して除算をなくすことができると思いました。

したがって、周波数の大きさを取得するための私のコードはここにあります:

        var deltax:Number = 1 / 44100;
        var sumCos:Number = 0;
        var sumSin:Number = 0;
        var c:Number = 0;

        while (frameba.bytesAvailable > 32) {
            //trace("getMag", frameba.bytesAvailable);
            c++;
            var freq:Number = (number / (2 * Math.PI));
            var sample:Number = frameba.readFloat();

            sumCos += sample * deltax;
            sumCos *= Math.cos(freq * c * deltax)

            sumSin += sample * deltax;
            sumSin *=Math.sin(freq * c * deltax)
        }


        return Math.sqrt(sumCos * sumCos + sumSin * sumSin);

数値はHz単位の周波数であり、framebaは44100Hzでのオーディオのモノラルサンプリングです。この関数は、取得するフレームバごとに呼び出します。これは、次のコードに対応しています。

        var endCounter:Number = int(s.length / number); //get number of frames
        frameData = new Array();

        for ( var i:Number = 0; i < endCounter-1; i++) {
            var frameba:ByteArray = new ByteArray();

            var frameSize:Number = int((number / 1000) * 44100) * 4;
            monoba.readBytes(frameba, 0, frameSize);// grab new frame

            frameba.position = 0;
            var mag:Number=getMag(512, frameba); //this function is the code snippet i posted before this one
            frameData.push(mag*100000);

したがって、問題は、ウィンドウを時々変更すると、2つの係数の大きさが非常に大きくなり、線形ではないことです。ウィンドウが42ミリ秒の場合、次のような値が得られます。

    ...,0.46867691675958506,0.40119205703768124,1.076056196209733,0.4138200126843882,1.288280385823108,1.1605685308155427,...

100msに設定した場合:

...、3.487381020768127,7.610466058045129,45.780152579896324,77.46963149803167,35.531672823487014,0.6057853252694128、..

500msに設定した場合:

   ...,0.7132093539701988,0.561741462535126,0.5303097469754452,0.6267107444675019,0.5205164960161707,0.4828724689303949,...

そのため、平均サイズが増え続けることはありません。何か間違ったことをしているのかどうかわかりませんが、これについて正しく考えていますか?

4

2 に答える 2

3

フーリエ係数は、分析される反復波形の周期の 正確な倍数ではない長方形のウィンドウサイズ(FFT / DFT長さN)に敏感です。

考えてみてください。完全な正弦波の一部だけを切り落とし、たまたま切り落とした部分がほとんど正またはほとんど負のローブを残す場合、それはおそらく、加重された正または負の量によって結果にバイアスをかけます。ウィンドウを移動したり、ウィンドウの長さを変更したりすると、1周期のさまざまな部分がこのチョッピングによって残され、さまざまな結果が発生します。

スペクトル漏れと呼ばれるものもあれば、ウィンドウ関数(明示的または暗黙的)との畳み込みと呼ばれるものもあります。これを補うことはできますが、通常は、長方形以外のウィンドウ関数(HammingまたはVon Hannなど)で十分な長さの固定長FFTを使用する方が簡単です。

于 2011-08-26T00:05:07.443 に答える
0

結果を正規化するには、値をNで割る必要があります。次に、Nに依存しないほぼ一貫した値を取得する必要があります。

于 2011-08-25T23:10:32.270 に答える