English 中文(简体)
Implement Hann Window
原标题:

I take blocks of incoming data and pass them through fftw to get some spectral information. Everything seems to be working, however I think I m getting some aliasing issues.

I ve been trying to work out how to implement a hann window on my blocks of data. Google has failed me for examples. Any ideas or links I should be looking at?

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

Update

Thanks to Oli for pointing out the issue I m actually trying to fix is spectral-leakage, NOT aliasing...

最佳回答

http://en.wikipedia.org/wiki/Hann_function . The implementation follows from the definition quite straightforwardly. Just use the w(n) function as multiplier, loop through all your samples (changing n as you go), and that s it.

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

The complete function that is equivalent to MATLAB s hanning.m can be found 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);
}

Not an answer to your question, but an aside on your problem. Windowing helps solve spectral leakage problems, not aliasing problems.

Spectral-leakage effects occur when the frequency components of your waveform are not exact integer sub-multiples of your sample rate.

If you have aliasing, then you re fundamentally screwed. You ll either need to increase your sample rate, or put in a (better) anti-aliasing filter before you sample.

Why not use Math.NET s Hann windowing implementation?

double[] hannDoubles = MathNet.Numerics.Window.HannPeriodic(dataIn.Length);
for (int i = 0; i < dataIn.Length; i++)
{
    dataOut[i] = hannDoubles[i] * dataIn[i];
}

Located here: https://numerics.mathdotnet.com/api/MathNet.Numerics/Window.htm

Wikipedia is your friend: Hanning window

Surely your googling came up with wikipedia?! Anyway just create a function that returns an array of length N with the Hanning coefficients and multiply this array by your dataIn[2048].

This is fine but most people probably want to do this on thousands of arrays full of data. You can fill an array of just constant multipliers once as your program s initializing (use the same size array you feed to FFT) then just multiply each point in your real array by each point in the multiplier array. Faster/cheaper than taking all those cosines over again each time.





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签