4. 音频信号中的梳状滤波效应模拟
任务目标
生成一段由多个正弦波叠加而成的音频信号,通过一个简单的梳状滤波器(前馈结构)进行处理,并输出处理前后的音频文件供试听对比,从而直观感知梳状滤波器的“梳齿”状频谱特性对音频信号的影响。
实现原理
梳状滤波器通过在信号上叠加一个延迟后的自身副本实现。前馈梳状滤波器的时域表达式为:y[n] = x[n] + g * x[n - D],其中 D 为延迟样本数,g 为反馈增益。其频率响应呈现周期性峰谷,形似梳齿。本案例使用Python和NumPy实现信号生成与滤波,并将结果写入WAV文件。
完整代码
import numpy as np
from scipy.io import wavfile
# 参数设置
sr = 44100 # 采样率
duration = 3.0 # 时长(秒)
freqs = [220, 440, 880, 1760] # 四个正弦波频率(Hz)
amps = [0.5, 0.3, 0.2, 0.1] # 对应幅度
D = int(0.005 * sr) # 延迟5ms
g = 0.7 # 反馈增益
# 1. 生成多正弦叠加信号
t = np.arange(int(sr * duration)) / sr
x = np.zeros_like(t)
for f, a in zip(freqs, amps):
x += a * np.sin(2 * np.pi * f * t)
# 归一化到[-1, 1]
x = x / np.max(np.abs(x))
# 2. 前馈梳状滤波
y = np.zeros_like(x)
y[:D] = x[:D] # 前D个样本无延迟分量
for n in range(D, len(x)):
y[n] = x[n] + g * x[n - D]
# 归一化
y = y / np.max(np.abs(y))
# 3. 写入WAV文件(16-bit PCM)
wavfile.write('original.wav', sr, (x * 32767).astype(np.int16))
wavfile.write('comb_filtered.wav', sr, (y * 32767).astype(np.int16))
print("已生成 original.wav 和 comb_filtered.wav")
print(f"延迟时间: {D/sr*1000:.1f} ms, 增益: {g}")
运行方式
- 安装依赖:
pip install numpy scipy - 将上述代码保存为
comb_sim.py并运行:python comb_sim.py
验证方法
- 文件生成检查:运行后当前目录应出现
original.wav和comb_filtered.wav两个文件。 - 频谱验证(可选):使用以下代码检查滤波后频谱在延迟频率的整数倍处出现凹陷:
from scipy.fft import rfft, rfftfreq
import matplotlib.pyplot as plt
for name in ['original.wav', 'comb_filtered.wav']:
sr, data = wavfile.read(name)
spec = np.abs(rfft(data[:sr])) # 取前1秒
freqs_axis = rfftfreq(sr, 1/sr)
plt.figure()
plt.plot(freqs_axis[:5000], spec[:5000])
plt.title(name)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Magnitude')
plt.show()
预期在 1/D 的整数倍频率(即200Hz, 400Hz, 600Hz...)附近出现周期性凹陷,而原始信号频谱在这些频率处无此规律。
- 听感验证:播放两个WAV文件,滤波后信号中440Hz和880Hz分量明显减弱(因它们恰位于梳齿谷点附近),整体音色变“空”变“薄”。
关键说明
本案例中四个正弦波频率(220, 440, 880, 1760Hz)均为200Hz的整数倍,而延迟5ms对应的梳齿谷点恰在200Hz的整数倍处,因此滤波后所有分量均被不同程度衰减,效果显著。若需保留某些频率,可调整延迟时间或输入信号频率。