2010-08-24 22 views
5

Tomo bloques de datos entrantes y los paso por fftw para obtener información espectral. Todo parece estar funcionando, sin embargo, creo que estoy recibiendo algunos problemas de aliasing.Implementar Hann Window

He estado tratando de encontrar la manera de implementar una ventana de Hann en mis bloques de datos. Google me ha fallado por ejemplos. ¿Alguna idea o enlace que debería estar mirando?

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

actualización

Gracias a Oli por señalar el problema que en realidad estoy tratando de arreglar es espectral fugas, NO aliasing ...

Respuesta

13

http://en.wikipedia.org/wiki/Hann_function. La implementación se sigue de la definición bastante simple. Simplemente use la función w(n) como multiplicador, recorra todas sus muestras (cambiando n sobre la marcha), y eso es todo.

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

Wikipedia es su amigo: Hanning window

Seguramente tu google ha surgido con wikipedia ?! De todos modos, solo cree una función que devuelva una matriz de longitud N con los coeficientes de Hanning y multiplique esta matriz por su dataIn[2048].

2

No es una respuesta a tu pregunta, pero aparte de tu problema. El uso de ventanas ayuda a resolver problemas de fuga espectral, no aliasing problemas.

Los efectos de fuga espectral ocurren cuando los componentes de frecuencia de su forma de onda no son submúltiplos enteros exactos de su frecuencia de muestreo.

Si tiene aliasing, entonces está fundamentalmente atornillado. Necesitará aumentar su frecuencia de muestreo o colocar un (mejor) filtro anti-aliasing antes de muestrear.

2

La función completa que es equivalente a MATLAB de hanning.m se puede encontrar 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

Esto está muy bien, pero la mayoría de la gente probablemente quiere hacer esto en miles de conjuntos completos de datos. Puede llenar una matriz de multiplicadores constantes solo una vez que la inicialización de su programa (utilice la matriz de mismo tamaño que alimenta a FFT) y luego simplemente multiplique cada punto en su matriz real por cada punto en la matriz multiplicadora. Más rápido/más barato que tomar todos esos cosenos una vez más.