我接收傳入數據塊並通過fftw傳遞它們以獲取一些光譜信息。一切似乎都在工作,但我認爲我正在得到一些別名問題。執行Hann窗口
我一直在努力解決如何在我的數據塊上實現漢納窗口。谷歌已經失敗了我的例子。我應該看的任何想法或鏈接?
double dataIn[2048] > /* windowing here? */ > FFT > double freqBins[2048]
更新
感謝奧利您指出我其實想解決的問題是頻譜泄漏,不走樣......
我接收傳入數據塊並通過fftw傳遞它們以獲取一些光譜信息。一切似乎都在工作,但我認爲我正在得到一些別名問題。執行Hann窗口
我一直在努力解決如何在我的數據塊上實現漢納窗口。谷歌已經失敗了我的例子。我應該看的任何想法或鏈接?
double dataIn[2048] > /* windowing here? */ > FFT > double freqBins[2048]
更新
感謝奧利您指出我其實想解決的問題是頻譜泄漏,不走樣......
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];
}
維基百科是你的朋友:Hanning window
當然你的谷歌搜索提出了維基百科?無論如何,只需創建一個函數返回一個長度爲N的漢寧係數數組,並將該數組乘以dataIn[2048]
。
不是你的問題的答案,而是拋開你的問題。窗口幫助解決頻譜泄漏問題問題,而不是別名問題。
當波形的頻率分量不是採樣率的精確整數倍數時,會出現頻譜泄漏效應。
如果你有別名,那麼你基本上是搞砸了。您需要提高採樣率,或者在採樣之前放入(更好)抗鋸齒濾波器。
完整的功能相當於MATLAB的hanning.m
可以發現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);
}
爲什麼不使用Math.NET的漢寧窗執行?
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/Window.htm
這是好的,但大多數人可能想這樣做,對成千上萬的陣列充分的數據。您可以在程序初始化時使用一個恆定乘法器陣列(使用您輸入到FFT中的相同大小的陣列),然後將實數組中的每個點乘以乘法器陣列中的每個點。比每次重複使用所有這些餘弦更快/更便宜。