我正在尝试使用闪存中的窗口傅里叶级数来制作频率分析仪,但是我的窗口大小会极大地影响系数的大小。
我正在使用教科书中的公式计算每一帧的系数:
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 是44100 hz的音频单声道采样。我每抓取一个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);
所以问题是当我有时改变窗口时,两个系数的幅度变得非常大,而且它不是线性的。当窗口是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,...
所以平均尺寸不会增加。我不确定我是否做错了什么,我是否正确地思考这个问题?
答案 0 :(得分:3)
傅里叶系数对任何矩形窗口大小(FFT / DFT长度N)敏感,该矩形窗口大小不是所分析的任何重复波形的周期的精确倍。
想一想。如果你只切断正弦波的一部分,而你碰巧切掉的部分会留下大部分正面或大部分为负的波瓣,那么这可能会使你的结果偏向一些加权的正或负量。当你移动窗口或改变它的长度时,一个周期的不同部分你的信号将被这个斩波留下,导致不同的结果。
有些人称之为频谱泄漏,有些人称之为带有窗口函数的卷积(显式或隐含)。您可以对此进行补偿,但通常使用具有非矩形窗口函数的足够长的固定长度FFT(Hamming或Von Hann,et.al。)会更容易。答案 1 :(得分:0)
为了对结果进行标准化,您需要将值除以N.然后,您应该获得与N无关的或多或少的一致值。