3. 梳状滤波器参数扫描

任务目标

编写Python脚本,对梳状滤波器(反馈式)的延迟长度 D 和反馈增益 g 进行参数扫描,绘制幅频响应曲线族,观察陷波频率随 D 变化、陷波深度随 g 变化的规律,并输出对比图。

核心原理

反馈式梳状滤波器的传递函数为:

H(z) = 1 / (1 − g·z−D)

其幅频响应在频率 f = (2k+1)/(2D)·fs(k为整数)处形成陷波。陷波深度由 g 决定:g 越接近1,陷波越深(理论趋于 −∞ dB)。本案例通过扫描 D 和 g,直接观察这两个参数的独立影响。

环境依赖

需要 numpy、matplotlib、scipy。安装命令:

pip install numpy matplotlib scipy

完整代码

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

fs = 8000          # 采样率 8kHz
N = 4096           # FFT点数
f = np.linspace(0, fs/2, N//2)  # 频率轴 0~4kHz

def comb_mag_response(D, g):
    """反馈式梳状滤波器幅频响应(dB)"""
    b = np.array([1.0])
    a = np.zeros(D + 1)
    a[0] = 1.0
    a[D] = -g
    w, h = signal.freqz(b, a, worN=N, fs=fs)
    return 20 * np.log10(np.abs(h) + 1e-12)

# ---------- 扫描1:固定 g=0.8,改变延迟 D ----------
g_fixed = 0.8
D_list = [4, 8, 16, 32]

plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
for D in D_list:
    mag = comb_mag_response(D, g_fixed)
    plt.plot(f, mag, label=f'D={D}')
plt.ylim(-60, 5)
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度 (dB)')
plt.title(f'固定 g={g_fixed}:延迟长度影响陷波频率')
plt.legend()
plt.grid(True, alpha=0.3)

# ---------- 扫描2:固定 D=16,改变增益 g ----------
D_fixed = 16
g_list = [0.5, 0.7, 0.9, 0.98]

plt.subplot(1, 2, 2)
for g in g_list:
    mag = comb_mag_response(D_fixed, g)
    plt.plot(f, mag, label=f'g={g}')
plt.ylim(-60, 5)
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度 (dB)')
plt.title(f'固定 D={D_fixed}:增益系数影响陷波深度')
plt.legend()
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('comb_param_scan.png', dpi=150)
plt.show()

运行方式

python comb_param_scan.py

验证方法与判定标准

  • 陷波频率验证:左图中,D=4 时第一个陷波应在 fs/(2D) = 8000/8 = 1000 Hz;D=8 时在 500 Hz;D=16 时在 250 Hz;D=32 时在 125 Hz。观察曲线谷底位置是否与上述频率一致。
  • 陷波深度验证:右图中,固定 D=16,第一个陷波频率为 250 Hz。g=0.5 时深度约 −6 dB,g=0.7 约 −10 dB,g=0.9 约 −20 dB,g=0.98 应低于 −30 dB。检查谷底深度是否随 g 增大而单调加深。
  • 图形输出:运行后生成 comb_param_scan.png,包含左右两个子图,曲线族区分清晰,图例完整。

预期输出说明

上述陷波频率与深度数值由传递函数解析式直接推出,非实测结果。实际运行生成的图形应与这些理论位置吻合,即谷底出现在对应频率处,且深度随 g 增大而增加。