[具身智能-468]:语音识别:分帧 (Framing) 加窗 (Windowing)
这两个步骤是语音信号处理中最基础、也最关键的“预处理”环节。如果把语音识别比作“看图说话”那么分帧和加窗就是把一卷长长的胶卷剪成一张张清晰的照片以便计算机逐张分析。简单来说它们的任务是解决语音信号的“非平稳性”和“边界突变”问题。下面我为你详细拆解这两个过程1. 分帧化整为零以静制动为什么要分帧语音信号在宏观上是非平稳的。比如你说“你好”发“n”音时声带振动发“i”音时舌头位置改变频率特性一直在变。如果直接把整句话拿去分析计算机只能得到一堆混乱的平均值无法分辨出具体的发音。但是语音信号在极短的时间内通常20~30 毫秒是准平稳的。也就是说在这一瞬间声道的形状和振动特性基本保持不变。怎么做我们将长音频切成一个个短小的片段每一段称为一“帧”时域信号。帧长通常设为20ms ~ 30ms例如 25ms。这足够包含一个音素的特征又足够短以维持平稳假设。帧移相邻两帧起始点的间隔通常设为10ms。10ms长度移动一次“帧”。重叠因为帧移10ms小于帧长25ms所以相邻帧之间会有 15ms 的重叠区域。作用防止切分时正好把一个音素切成两半导致信息丢失保证特征的平滑过渡。2. 加窗平滑边界防止“泄漏”为什么要加窗当你把一段信号强行切断分帧时每一帧的起点和终点往往不是从 0 开始、到 0 结束的。这种突然的截断会在信号边缘产生突变。在做傅里叶变换频谱分析时这种突变会被误认为是高频信号导致能量扩散到整个频谱中这种现象叫频谱泄漏。这会严重干扰识别效果。怎么做我们需要给每一帧数据乘以一个窗函数。这个函数的形状像一个“窗户”中间高两边低趋近于 0。汉明窗这是语音识别中最常用的窗函数。公式* **效果**它让每一帧信号的两端平滑地衰减到接近 0消除了边界突变从而极大减少了频谱泄漏。 Python 代码实现我们可以使用Librosa库轻松实现这两个步骤也可以手动通过NumPy理解其原理。方案一使用 Librosa推荐工业界标准Librosa内部已经封装好了分帧和加窗的逻辑。pythonimport librosa import numpy as np # 1. 加载音频 y, sr librosa.load(test_audio.wav, sr16000) # 2. 分帧与加窗 (Librosa 默认使用汉明窗) # n_fft: 窗长 (通常等于帧长如 25ms - 400点) # hop_length: 帧移 (如 10ms - 160点) # windowhamm: 指定使用汉明窗 frames librosa.util.frame(y, frame_length400, hop_length160, axis0) # 对每一帧加汉明窗 windowed_frames frames * np.hamming(400) print(f原始音频长度: {len(y)}) print(f分帧后形状: {windowed_frames.shape}) # 输出示例: (帧数, 400)每一行就是一帧加窗后的数据方案二手动实现原理加深理解如果你想看底层的数学过程pythondef manual_framing(signal, frame_size400, hop_size160): # 1. 补零防止最后一帧数据不足 pad_length (len(signal) // hop_size 1) * hop_size - len(signal) frame_size padded_signal np.append(signal, np.zeros(pad_length)) # 2. 计算帧数 num_frames (len(padded_signal) - frame_size) // hop_size 1 # 3. 构建汉明窗 hamming_window 0.54 - 0.46 * np.cos(2 * np.pi * np.arange(frame_size) / (frame_size - 1)) # 4. 循环切片并加窗 framed_signal [] for i in range(num_frames): start i * hop_size end start frame_size frame padded_signal[start:end] # 核心步骤乘以窗函数 frame * hamming_window framed_signal.append(frame) return np.array(framed_signal) # 使用示例 # frames manual_framing(audio_data) 总结表格步骤核心动作目的关键参数分帧切片将非平稳信号变为短时平稳信号帧长 25ms帧移 10ms加窗乘积消除切片带来的边界突变防止频谱泄漏汉明窗做完这两步你就得到了一堆干净的、短小的波形片段接下来就可以对每一帧单独做傅里叶变换提取出梅尔频谱图了。