2. 计算音频的短时能量

任务目标

对一段语音信号施加系数为0.97的一阶预加重滤波器,并对比滤波前后的频谱差异,验证高频分量得到提升。

实现原理

预加重滤波器传递函数为 H(z) = 1 - 0.97·z⁻¹,对应时域差分方程:

y[n] = x[n] - 0.97·x[n-1]

该操作抑制低频、相对提升高频,用于平衡语音信号的高频衰减。本案例使用Python生成一个包含低频主导与高频成分的合成信号作为输入,完成滤波并对比频谱。

完整代码

import numpy as np
import matplotlib.pyplot as plt

# 参数设置
fs = 16000          # 采样率 16kHz
duration = 0.1      # 100ms
n = np.arange(int(fs * duration))
t = n / fs

# 合成语音模拟信号:基频200Hz + 低幅高频3000Hz + 噪声
f0, f1 = 200, 3000
x = (0.8 * np.sin(2 * np.pi * f0 * t) +
     0.15 * np.sin(2 * np.pi * f1 * t) +
     0.02 * np.random.randn(len(t)))

# 预加重滤波:y[n] = x[n] - 0.97 * x[n-1]
alpha = 0.97
y = np.zeros_like(x)
y[0] = x[0]
for i in range(1, len(x)):
    y[i] = x[i] - alpha * x[i-1]

# 计算频谱(幅度谱,取前一半频率)
def magnitude_spectrum(signal, fs):
    spec = np.fft.rfft(signal)
    freq = np.fft.rfftfreq(len(signal), 1/fs)
    return freq, np.abs(spec)

freq_x, mag_x = magnitude_spectrum(x, fs)
freq_y, mag_y = magnitude_spectrum(y, fs)

# 绘制时域与频域对比
fig, axes = plt.subplots(2, 2, figsize=(12, 8))

axes[0,0].plot(t, x)
axes[0,0].set_title('原始信号 (时域)')
axes[0,0].set_xlabel('时间 (s)')

axes[0,1].plot(t, y, color='orange')
axes[0,1].set_title('预加重后信号 (时域)')
axes[0,1].set_xlabel('时间 (s)')

axes[1,0].semilogy(freq_x, mag_x)
axes[1,0].set_title('原始信号频谱')
axes[1,0].set_xlabel('频率 (Hz)')
axes[1,0].set_ylabel('幅度')

axes[1,1].semilogy(freq_y, mag_y, color='orange')
axes[1,1].set_title('预加重后频谱')
axes[1,1].set_xlabel('频率 (Hz)')
axes[1,1].set_ylabel('幅度')

plt.tight_layout()
plt.savefig('preemphasis_result.png', dpi=100)
plt.show()

# 打印3000Hz附近幅度对比(取2900-3100Hz范围均值)
band = (freq_x > 2900) & (freq_x < 3100)
print(f'3000Hz附近原始幅度均值: {mag_x[band].mean():.4f}')
print(f'3000Hz附近滤波后幅度均值: {mag_y[band].mean():.4f}')
print(f'高频增益倍数: {mag_y[band].mean() / mag_x[band].mean():.2f}')

运行方式

  1. 安装依赖:pip install numpy matplotlib
  2. 将上述代码保存为 preemphasis.py,执行 python preemphasis.py

验证方法

  • 程序生成 preemphasis_result.png,包含四个子图:原始/滤波后的时域波形与频谱。
  • 观察频谱对比图:滤波后3000Hz附近的幅度应明显高于原始信号,而200Hz附近的低频幅度基本不变或略有下降。
  • 控制台输出的高频增益倍数应大于1(典型值在2~5之间,取决于合成信号中高频成分的原始幅度),证明预加重确实提升了高频分量。

预期输出

由于合成信号中3000Hz分量幅度为0.15,经预加重后该频率处幅度约提升至0.15×|1-0.97·e^(-j2π·3000/16000)|≈0.15×1.93≈0.29,因此控制台输出的增益倍数约为1.9~2.0(受噪声影响略有波动)。频谱图中高频段曲线整体上移,低频段基本重合。