实施汉恩窗

发布于 2024-09-15 09:20:56 字数 301 浏览 4 评论 0原文

我获取传入数据块并将它们通过 fftw 传递以获取一些光谱信息。一切似乎都正常,但我认为我遇到了一些别名问题。

我一直在尝试找出如何在我的数据块上实现汉恩窗口。谷歌的例子让我失望了。我应该查看任何想法或链接吗?

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

更新

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

甜警司 2024-09-22 09:20:56

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

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];
}
梦里南柯 2024-09-22 09:20:56

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

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

如果你有别名,那么你就彻底完蛋了。您需要提高采样率,或者在采样之前放入(更好的)抗锯齿滤波器。

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.

拥抱影子 2024-09-22 09:20:56

相当于MATLAB的hanning.m<的完整函数/a> 可以在此处找到:

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

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);
}
土豪我们做朋友吧 2024-09-22 09:20:56

为什么不使用 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];
}

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

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

小红帽 2024-09-22 09:20:56

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

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.

梦里梦着梦中梦 2024-09-22 09:20:56

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

当然你的谷歌搜索会找到维基百科?!无论如何,只需创建一个返回长度为 N 且包含汉宁系数的数组的函数,并将该数组乘以您的 dataIn[2048] 即可。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文