C语言 实施汉恩窗

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3555318/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:17:26  来源:igfitidea点击:

Implement Hann Window

csignal-processingfftfftw

提问by Tim

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.

我获取传入数据块并将它们通过 fftw 以获取一些光谱信息。一切似乎都在工作,但是我认为我遇到了一些混叠问题。

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?

我一直在努力研究如何在我的数据块上实现 hann 窗口。谷歌让我失败了例子。我应该查看任何想法或链接?

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...

感谢 Oli 指出我实际尝试解决的问题是频谱泄漏,而不是混叠...

回答by Joonas Pulakka

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 nas you go), and that's it.

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];
}

回答by Oliver Charlesworth

Not an answer to your question, but an aside on your problem. Windowing helps solve spectral leakageproblems, not aliasingproblems.

不是你问题的答案,而是你的问题的旁白。加窗有助于解决频谱泄漏问题,而不是混叠问题。

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.

如果您有混叠,那么您从根本上就搞砸了。您要么需要提高采样率,要么在采样之前放入(更好的)抗混叠滤波器。

回答by herohuyongtao

The complete function that is equivalent to MATLAB's hanning.mcan be found here:

hanning.m可以在此处找到与 MATLAB 等效的完整函数:

/*  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);
}

回答by Gordon Slysz

Why not use Math.NET's Hann windowing implementation?

为什么不使用 Math.NET 的 Hann 窗口实现?

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

位于此处:https: //numerics.mathdotnet.com/api/MathNet.Numerics/Window.htm

回答by Simon Walker

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].

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

回答by Alan Corey

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.

这很好,但大多数人可能希望在数千个充满数据的数组上执行此操作。您可以在程序初始化时填充一个仅包含常数乘法器的数组(使用您提供给 FFT 的相同大小的数组),然后将实际数组中的每个点乘以乘法器数组中的每个点。比每次都重新计算所有这些余弦更快/更便宜。