Actionscript 3 傅里叶系数的结果对窗口大小非常敏感?

Actionscript 3 傅里叶系数的结果对窗口大小非常敏感?,actionscript-3,math,signal-processing,fft,frequency-analysis,Actionscript 3,Math,Signal Processing,Fft,Frequency Analysis,我试图在flash中使用加窗傅里叶级数制作一个频率分析器,但我的窗口的大小会极大地影响系数的大小 我使用教科书中的公式计算每一帧的系数: 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*处的时域值。

我试图在flash中使用加窗傅里叶级数制作一个频率分析器,但我的窗口的大小会极大地影响系数的大小

我使用教科书中的公式计算每一帧的系数:

     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);
数字是以赫兹为单位的频率,frameba是44100赫兹音频的单声道采样。我每次抓取frameba时都调用此函数,它对应于以下代码:

        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);
当我将其设置为100ms时:

…,3.487381020768127,7.61046058045129,45.780152579896324,77.46963149803167,35.531672823487014,0.605785252694128

当我将其设置为500毫秒时:

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

所以它的平均尺寸不会一直增加。我不确定我是否做错了什么,我想的对吗?

为了规范化你的结果,你需要将这些值除以N。然后你应该得到与N无关的或多或少一致的值。

傅里叶系数对任何矩形窗口大小(FFT/DFT长度N)都很敏感这不是所分析的任何重复波形周期的精确倍数

想想看。如果你只切掉一个完整正弦波的一部分,而你恰巧切掉的部分留下了一个大部分为正或大部分为负的波瓣,那么这可能会使你的结果产生一些加权的正或负的偏差。当你移动你的窗口或者改变它的长度时,你的信号在一个周期中的不同部分会被这个斩波留下,导致不同的结果


有人称之为频谱泄漏,也有人称之为窗函数卷积(显式或隐式)。您可以对此进行补偿,但通常更容易使用足够长的固定长度FFT和非矩形窗口函数(Hamming或Von Hann,et.al.)。

是否有任何理由使用傅里叶级数而不是像这样漂亮的FFT库?这将需要你做大量的工作。我不认为这会有什么不同,因为N对于所有值都是相同的。@Prasad:可能是我不理解你的代码,但看起来你有一个固定的采样率(44.1 kHz),你改变了窗口持续时间,因此DFT中的采样数N,也会随窗口大小的比例而变化?是的,DFT会随窗口大小的不同而变化,因此它们本质上是标准化的。好的-首先添加一个窗口函数-这会消除一些问题-我想你会发现,如果你想比较不同大小的DFT,你仍然需要一个1/N项。这非常有趣,因为我试图产生一个单音频率信号,在某些帧它给了我正确的常数系数,在其他帧它给了我系数的周期性变化,这在我们没有以正确的倍数采样时是有意义的,希望我能正确地看到这一点。谢谢
   ...,0.7132093539701988,0.561741462535126,0.5303097469754452,0.6267107444675019,0.5205164960161707,0.4828724689303949,...