好吧,我想我明白你的意思了。您需要一个 BPF,,它会根据幅度谱中的能量分布自动扩展其带宽。如果您有纯 1k Hz 正弦音调(在频域中,对应于位于 k rad/s 的狄拉克增量),您只想通过 1k中的频率Hz 范围,并且如果您有一个具有类似白噪声分布的瞬态事件,您需要一个全通滤波器来保留尖锐的攻击。H(z)ω0=±2π1±50
您需要的是一个谐振器滤波器 [1]:
H(z)=(1−λ)1+λ2−2λcos(2ω0)−−−−−−−−−−−−−−−−√1−(2λcos(ω0))z−1+λ2z−2,
值,它的行为如下所示:
λ∈[0,1]
因此对于,您将获得一个平坦的响应来捕捉瞬态事件,对于,您将在所需频率处获得一个局部滤波器。在这里,出于说明目的,我设置了更改所需的频率。λ→0λ→1w0=π/2w0=2πF0/Fs
要自动设置,您可以使用频谱平坦度估计器 [2]:λ
f=(∏N−1n=0x[n])1/N1N∑N−1n=0x[n],
这是f=1,当幅度谱完全平坦时,并且f=0,当幅度谱完全局部化时。因此,您可以使λ=1−f. 我编写了以下代码来举例说明如何应用此控件:
Fs=16e3;
F0=1e3;
w0 = 2*pi*F0/Fs;
x1 = [zeros(1,50),2*rand(1,50)-1];
x2 = 0.7*sin(w0.*[1:100])+0.3*rand(1,100);
x3 = 0.7*sin(3.5*w0.*[1:100])+0.3*rand(1,100);
y = [adaptiveResonatorFilter(x1,w0), adaptiveResonatorFilter(x2,w0), adaptiveResonatorFilter(x3,w0)];
plot([x1,x2,x3],'linewidth',2)
hold on
plot(y,'linewidth',2)
xlabel('Samples')
ylabel('Amplitude')
legend('Original','Filtered')
function y = adaptiveResonatorFilter(x,w0)
X = fft(x);
mX = abs(X);
mX = mX/max(mX);
sf = mean(mX,'g')/mean(mX,'a')
lambda = ifelse(0.5<1-sf, 0.99, 0.0)
B = (1-lambda)*sqrt(1+lambda^2-2*lambda*cos(2*w0));
A = [1,-2*lambda*cos(w0), lambda^2];
[H,W] = freqz(B,A,linspace(-pi,pi,length(mX)));
Y = X .* fftshift(H);
y = real(ifft(Y));
end
给出以下输出:
您可以看到瞬态部分保持不变,被噪声污染的 1k Hz 纯音已被清除,并且 3.5k Hz 纯音已被衰减,如您所愿。
注意:我将此作为“瞬态攻击”的定义。如果我误解了,请纠正我。
- M.维特利,P.普兰多尼。通信信号处理。EPFL 出版社。
- https://en.wikipedia.org/wiki/Spectral_flatness