3. 分帧与加窗

分帧与加窗 学习卡片

任务说明

本案例处理一段已知采样率的离散语音信号,实现两个核心操作:分帧(将连续采样点切分为固定长度的帧,相邻帧间有重叠)与加窗(对每一帧乘以汉明窗系数)。最终输出加窗后的时域帧数据,并计算其幅度谱,用于观察加窗对帧内信号及频谱的影响。

实现方案

采用Python与NumPy实现,不依赖额外音频文件。输入信号由两个不同频率的正弦波叠加合成,模拟包含浊音与清音成分的短时平稳信号。分帧参数为:帧长256点,帧移128点(50%重叠)。汉明窗按标准公式生成,逐点与帧数据相乘。对加窗后的帧执行FFT并取模,得到幅度谱。

连续语音信号 x[n], fs=16kHz 分帧 帧长256, 帧移128 汉明窗加权 w[n]·x_m[n] 加窗帧 + 频谱 时域/频域观测 关键参数 fs = 16000 Hz(采样率) frame_len = 256(帧长,对应16ms) hop = 128(帧移,50%重叠) N_fft = 512(FFT点数,零填充至512)

代码实现


import numpy as np

# ---------- 参数配置 ----------
fs = 16000                # 采样率 16kHz
frame_len = 256           # 帧长(16ms)
hop = 128                 # 帧移(50%重叠)
N_fft = 512               # FFT点数

# ---------- 生成测试信号(两正弦叠加,模拟语音段) ----------
t_total = 0.1             # 总时长 100ms
n_total = int(fs * t_total)
n = np.arange(n_total)
# 低频分量模拟浊音(200Hz),高频分量模拟清音(3000Hz)
x = 0.6 * np.sin(2 * np.pi * 200 * n / fs) + 0.4 * np.sin(2 * np.pi * 3000 * n / fs)

# ---------- 分帧 ----------
num_frames = 1 + (len(x) - frame_len) // hop
frames = np.zeros((num_frames, frame_len))
for i in range(num_frames):
    start = i * hop
    frames[i, :] = x[start:start + frame_len]

# ---------- 汉明窗 ----------
hamming_win = 0.54 - 0.46 * np.cos(2 * np.pi * np.arange(frame_len) / (frame_len - 1))

# ---------- 加窗 ----------
windowed_frames = frames * hamming_win

# ---------- 频谱计算(取第3帧作为观测对象) ----------
obs_idx = 2              # 观察第3帧(索引从0开始)
frame_td = windowed_frames[obs_idx]          # 加窗后时域帧
spectrum = np.abs(np.fft.rfft(frame_td, N_fft))  # 幅度谱
freq_axis = np.fft.rfftfreq(N_fft, 1 / fs)

# ---------- 输出观测数据 ----------
print("帧总数:", num_frames)
print("第3帧前10个加窗采样值:", np.round(frame_td[:10], 4))
print("第3帧幅度谱峰值频率(Hz):", freq_axis[np.argmax(spectrum)])
print("第3帧幅度谱前5个频点幅度:", np.round(spectrum[:5], 4))

运行与验证

运行方式:将上述代码保存为 framing_windowing.py,在已安装NumPy的Python环境中执行 python framing_windowing.py。

预期输出与判定标准:

  • 程序打印帧总数为 13(由100ms信号长度与分帧参数决定)。
  • 第3帧加窗后的时域采样值两端接近0(汉明窗两端为零),中间部分数值较大。
  • 幅度谱峰值频率应接近200Hz(因200Hz正弦分量幅度0.6大于3000Hz分量的0.4,主峰在低频处)。
  • 若打印的峰值频率在195~205Hz范围内,且帧首尾采样值明显小于帧中部,则说明分帧与汉明窗加窗实现正确。

验证逻辑:汉明窗在两端(n=0和n=255)系数为0.08,因此加窗后帧首尾应接近0;200Hz分量幅度更高,FFT主峰应出现在200Hz附近。观察这两点即可确认分帧与加窗链路自洽。