2

我有一个 FFT 幅度谱,我想从中创建一个滤波器,选择性地通过周期性噪声源(例如正弦波杂散)并将与随机背景噪声相关的频率区间归零。我知道一旦这个过滤器IFFT回到时域,频率域中的急剧转换会产生振铃伪影......所以我想知道是否有任何经验法则如何平滑这种过滤器中的转换以避免这种情况铃声。

例如,如果 FFT 有 1M 频率区间,并且有五个杂散从背景噪声基底中伸出,我想将除与五个杂散中的每一个相关的峰值区间之外的所有区间归零。问题是如何处理相邻的支线箱以防止时域中的伪影。例如,是否应将支线箱每一侧的箱设置为 50% 幅度?是否应该在支线箱的两侧使用两个箱(最近的一个在 50%,下一个在 25% 等)?任何想法都非常感谢。谢谢!

4

1 回答 1

2

我喜欢以下方法:

  • 创建理想的幅度谱(记住使其关于 DC 对称)
  • 到时域的逆变换
  • 将块旋转一半的块大小
  • 应用 Hann 窗

我发现它可以产生相当平滑的频域结果,尽管我从未尝试过像你建议的那样尖锐的东西。您可能可以通过使用 Kaiser-Bessel 窗口来制作更清晰的过滤器,但您必须适当地选择参数。通过更锐利,我猜也许你可以将旁瓣减少 6 dB 左右。

这是一些示例 Matlab/Octave 代码。为了测试结果,我使用了freqz(h, 1, length(h)*10);.

function [ht, htrot, htwin] = ArbBandPass(N, freqs)
%# N = desired filter length
%# freqs = array of frequencies, normalized by pi, to turn into passbands
%# returns raw, rotated, and rotated+windowed coeffs in time domain

if any(freqs >= 1) || any(freqs <= 0)
    error('0 < passband frequency < 1.0 required to fit within (DC,pi)')
end

hf = zeros(N,1); %# magnitude spectrum from DC to 2*pi is intialized to 0
%# In Matlabs FFT, idx 1 -> DC, idx 2 -> bin 1, idx N/2 -> Fs/2 - 1, idx N/2 + 1 -> Fs/2, idx N -> bin -1
idxs = round(freqs * N/2)+1; %# indeces of passband freqs between DC and pi
hf(idxs) = 1; %# set desired positive frequencies to 1
hf(N - (idxs-2)) = 1; %# make sure 2-sided spectrum is symmetric, guarantees real filter coeffs in time domain
ht = ifft(hf); %# this will have a small imaginary part due to numerical error
if any(abs(imag(ht)) > 2*eps(max(abs(real(ht)))))
    warning('Imaginary part of time domain signal surprisingly large - is the spectrum symmetric?')
end
ht = real(ht); %# discard tiny imag part from numerical error
htrot = [ht((N/2 + 1):end) ; ht(1:(N/2))]; %# circularly rotate time domain block by N/2 points
win = hann(N, 'periodic'); %# might want to use a window with a flatter mainlobe
htwin = htrot .* win;
htwin = htwin .* (N/sum(win)); %# normalize peak amplitude by compensating for width of window lineshape
于 2010-09-30T06:57:48.750 回答