2010-08-24 10 views
5

Prendo blocchi di dati in arrivo e li passo attraverso fftw per ottenere alcune informazioni spettrali. Tutto sembra funzionare, tuttavia penso che sto ricevendo alcuni problemi di aliasing.Implementare Hann Window

Ho cercato di capire come implementare una finestra di hann sui miei blocchi di dati. Google mi ha mancato per gli esempi. Qualche idea o link dovrei guardare?

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

Aggiornamento

Grazie a Oli per sottolineare la questione In realtà sto cercando di risolvere è spettrale-perdite, NON aliasing ...

risposta

13

http://en.wikipedia.org/wiki/Hann_function. L'implementazione segue dalla definizione abbastanza direttamente. Basta usare la funzione w(n) come moltiplicatore, scorrere tutti i campioni (modificando n mentre si va), e il gioco è fatto.

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

Wikipedia è tuo amico: Hanning window

Sicuramente il tuo googling ha inventato wikipedia ?! In ogni caso basta creare una funzione che restituisca un array di lunghezza N con i coefficienti di Hanning e moltiplicare questo array con il tuo dataIn[2048].

2

Non una risposta alla tua domanda, ma una parte sul tuo problema. Windowing aiuta a risolvere perdite spettrali problemi, non aliasing problemi.

Gli effetti di dispersione spettrale si verificano quando i componenti di frequenza della forma d'onda non sono sub-multipli interi esatti della frequenza di campionamento.

Se hai aliasing, allora sei fondamentalmente fottuto. Dovrai aumentare la frequenza di campionamento o inserire un (migliore) filtro anti-aliasing prima di campionare.

2

La funzione completo che è equivalente a MATLAB di hanning.m possono essere trovati 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

Questo va bene, ma la maggior parte delle persone probabilmente vuole fare questo su migliaia di array pieno di dati. È possibile riempire una serie di moltiplicatori solo una volta durante l'inizializzazione del programma (utilizzare la stessa matrice di dimensioni che si alimenta alla FFT), quindi moltiplicare ogni punto della matrice reale per ogni punto della matrice moltiplicatore. Più veloce/più economico rispetto a prendere tutti quei cosini di nuovo ogni volta.