Результирующий коэффициент Фурье очень чувствителен к размеру окна? - PullRequest
1 голос
/ 25 августа 2011

Я пытаюсь сделать частотный анализатор, использующий оконные ряды Фурье во вспышке, но размер моего окна сильно влияет на величину коэффициентов.

Я использую формулу из учебника для расчета коэффициентов в каждом кадре:

     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 Гц. Я вызываю эту функцию каждый кадр, который я беру, что соответствует этому коду:

        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);

Так что проблема в том, что величина двух коэффициентов становится чрезвычайно большой, когда я иногда меняю окно, а оно не линейное. Когда окно составляет 42 миллисекунды, я получаю такие значения:

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

Когда я установил его на 100 мс:

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

Когда я устанавливаю его на 500 мс:

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

Так что он не продолжает увеличиваться в среднем размере. Я не уверен, что делаю что-то не так или нет, правильно ли я думаю об этом?

Ответы [ 2 ]

3 голосов
/ 26 августа 2011

Коэффициенты Фурье чувствительны к любому размеру прямоугольного окна (длина БПФ / ДПФ N), который не является точным кратным периоду любой анализируемой повторяющейся формы волны.

Подумай об этом. Если вы отрежете только часть полной синусоидальной волны, и часть, от которой вы откололесь, оставляет в основном положительную или в основном отрицательную долю, то это, вероятно, сместит ваш результат на некоторое взвешенное положительное или отрицательное значение. По мере того, как вы перемещаете окно или изменяете его длину, эта порция оставляет разные части одного периода вашего сигнала, что приводит к различным результатам.

Некоторые называют это спектральной утечкой, другие называют это сверткой с оконной функцией (явной или подразумеваемой). Вы можете компенсировать это, но обычно проще просто использовать достаточно длинную БПФ фиксированной длины с непрямоугольной оконной функцией (Hamming или Von Hann, et.al.).

0 голосов
/ 26 августа 2011

Чтобы нормализовать результаты, вам нужно разделить значения на N. Затем вы должны получить более или менее согласованные значения, которые не зависят от N.

...