2010-08-24 56 views
5

我接收传入数据块并通过fftw传递它们以获取一些光谱信息。一切似乎都在工作,但我认为我正在得到一些别名问题。执行Hann窗口

我一直在努力解决如何在我的数据块上实现汉纳窗口。谷歌已经失败了我的例子。我应该看的任何想法或链接?

double dataIn[2048] > /* windowing here? */ > FFT > double freqBins[2048] 

更新

感谢奥利您指出我其实想解决的问题是频谱泄漏,不走样......

回答

13

http://en.wikipedia.org/wiki/Hann_function。从定义来看,这个实现非常简单。只需使用w(n)函数作为乘数,循环遍历所有样本(随时更改n),就是这样。

for (int i = 0; i < 2048; i++) { 
    double multiplier = 0.5 * (1 - cos(2*PI*i/2047)); 
    dataOut[i] = multiplier * dataIn[i]; 
} 
2

维基百科是你的朋友:Hanning window

当然你的谷歌搜索提出了维基百科?无论如何,只需创建一个函数返回一个长度为N的汉宁系数数组,并将该数组乘以dataIn[2048]

2

不是你的问题的答案,而是抛开你的问题。窗口帮助解决频谱泄漏问题问题,而不是别名问题。

当波形的频率分量不是采样率的精确整数倍数时,会出现频谱泄漏效应。

如果你有别名,那么你基本上是搞砸了。您需要提高采样率,或者在采样之前放入(更好)抗锯齿滤波器。

2

完整的功能相当于MATLAB的hanning.m可以发现here

/* function w = hanning(varargin) 
% HANNING Hanning window. 
% HANNING(N) returns the N-point symmetric Hanning window in a column 
% vector. Note that the first and last zero-weighted window samples 
% are not included. 
% 
% HANNING(N,'symmetric') returns the same result as HANNING(N). 
% 
% HANNING(N,'periodic') returns the N-point periodic Hanning window, 
% and includes the first zero-weighted window sample. 
% 
% NOTE: Use the HANN function to get a Hanning window which has the 
%   first and last zero-weighted samples.ep 
    itype = 1 --> periodic 
    itype = 0 --> symmetric 
    default itype=0 (symmetric) 

    Copyright 1988-2004 The MathWorks, Inc. 
% $Revision: 1.11.4.3 $ $Date: 2007/12/14 15:05:04 $ 
*/ 

float *hanning(int N, short itype) 
{ 
    int half, i, idx, n; 
    float *w; 

    w = (float*) calloc(N, sizeof(float)); 
    memset(w, 0, N*sizeof(float)); 

    if(itype==1) //periodic function 
     n = N-1; 
    else 
     n = N; 

    if(n%2==0) 
    { 
     half = n/2; 
     for(i=0; i<half; i++) //CALC_HANNING Calculates Hanning window samples. 
      w[i] = 0.5 * (1 - cos(2*PI*(i+1)/(n+1))); 

     idx = half-1; 
     for(i=half; i<n; i++) { 
      w[i] = w[idx]; 
      idx--; 
     } 
    } 
    else 
    { 
     half = (n+1)/2; 
     for(i=0; i<half; i++) //CALC_HANNING Calculates Hanning window samples. 
      w[i] = 0.5 * (1 - cos(2*PI*(i+1)/(n+1))); 

     idx = half-2; 
     for(i=half; i<n; i++) { 
      w[i] = w[idx]; 
      idx--; 
     } 
    } 

    if(itype==1) //periodic function 
    { 
     for(i=N-1; i>=1; i--) 
      w[i] = w[i-1]; 
     w[0] = 0.0; 
    } 
    return(w); 
} 
0

这是好的,但大多数人可能想这样做,对成千上万的阵列充分的数据。您可以在程序初始化时使用一个恒定乘法器阵列(使用您输入到FFT中的相同大小的阵列),然后将实数组中的每个点乘以乘法器阵列中的每个点。比每次重复使用所有这些余弦更快/更便宜。