4、语音信号基础:采样、量化、帧、窗函数、时域与频域特征(MFCC、Mel频谱)的提取方法
TinyML语音交互设备的核心挑战在于:如何在资源受限的MCU(通常仅有几十KB RAM、几百KB Flash)上,从连续的空气振动中提取出足以区分“唤醒词”“命令词”与“环境噪声”的判别性信息。这要求我们深刻理解语音信号从模拟到数字、从时域到频域、从物理波形到特征向量的完整变换链路。本章将系统拆解这一链路中的每一个关键环节,并重点剖析MFCC与Mel频谱这两种在TinyML中最常用的特征提取方法。
4.1 采样与量化:从连续声波到离散数字
语音信号本质上是空气压力随时间变化的连续函数。要让微控制器理解语音,第一步就是通过模数转换器(ADC)将其离散化。这个过程包含两个核心操作:采样(时间离散化)和量化(幅度离散化)。
4.1.1 采样定理与采样率选择
根据奈奎斯特采样定理,采样率必须至少为信号最高频率的两倍,才能无失真地重建原始信号。对于语音交互设备,人声的主要能量集中在300Hz-3.4kHz(电话语音带宽),但为了保留更多摩擦音(如/s/、/sh/)的高频细节,TinyML设备通常采用16kHz采样率。这既能覆盖8kHz以内的频率成分,又不会像音频CD(44.1kHz)那样产生过高的数据率。
在资源受限的MCU上,采样率的选择直接影响后续所有处理环节的计算量。以16kHz采样、16bit量化为例,每秒产生32KB数据,1秒语音就需要32KB RAM——这几乎占满了许多低端MCU的全部内存。因此,实际系统中往往采用DMA(直接内存访问)方式将ADC数据直接搬运到内存缓冲区,避免CPU干预,同时配合环形缓冲区实现数据的连续流动。
4.1.2 量化与动态范围
量化是将连续的幅度值映射为有限个离散电平。16bit量化提供65536个电平,信噪比理论值约为96dB,足以覆盖从耳语到喊叫的动态范围。但在TinyML场景中,部分超低功耗芯片(如STM32L4系列)内置的ADC为12bit,此时需要谨慎处理:
- 增益控制:在模拟前端使用可编程增益放大器(PGA),根据环境噪声水平自动调整增益,避免削波或量化噪声过大。
- 直流偏置消除:麦克风输出通常带有1.2V左右的直流偏置,需要通过隔直电容或数字高通滤波去除,否则会占用大量动态范围。
- 抖动技术:在量化前叠加微弱的随机噪声(幅度为1/2 LSB),可以消除量化误差的周期性,改善低幅度信号的听感,但对识别任务影响不大。
4.2 预加重、分帧与窗函数:将连续语音切分为可处理单元
语音信号具有短时平稳性——在10-30ms的时间尺度内,声道的形状和激励源特性可以认为基本不变。因此,我们需要将长时语音切分为短帧,再对每一帧进行频谱分析。
4.2.1 预加重
语音信号的高频分量(2kHz以上)能量通常远低于低频分量,这源于声门激励的天然特性。预加重通过一个一阶高通滤波器来提升高频成分:
y[n] = x[n] - α * x[n-1]
其中α通常取0.95-0.97。预加重不仅能让频谱更加平坦,便于后续的频谱分析,还能减少数值计算中的动态范围问题。在定点MCU上,这个操作只需一次乘法和一次减法,成本极低。
4.2.2 分帧参数选择
分帧涉及两个关键参数:帧长和帧移。帧长决定了频率分辨率(Δf = fs / N),帧移决定了时间分辨率。在TinyML场景中,常用配置为:
| 参数 | 典型值 | 说明 |
|---|---|---|
| 帧长 | 400点(25ms) | 频率分辨率40Hz,足以区分元音共振峰 |
| 帧移 | 160点(10ms) | 相邻帧有60%重叠,保证时间连续性 |
| FFT点数 | 512 | 对400点补零至512,获得更精细的频谱插值 |
| 每帧特征维度 | 13(MFCC) | 不含能量项,或13+1=14维 |
对于1秒的语音,以10ms帧移计算,共产生约100帧(实际为(1000-25)/10+1≈98帧)。若模型需要固定输入长度,通常截取或填充至49帧(约0.5秒)或98帧(约1秒)。
4.2.3 窗函数的作用与选择
直接对截断的时域信号做FFT会产生频谱泄漏——信号在帧边界处的突变会在频域产生旁瓣。窗函数通过对帧内样本进行加权,使帧边界处的幅度平滑过渡到零。常用的窗函数包括:
- 汉明窗(Hamming):旁瓣峰值-43dB,主瓣宽度适中,是语音识别最常用的选择。公式为 w[n] = 0.54 - 0.46·cos(2πn/(N-1))。
- 汉宁窗(Hann):旁瓣衰减更快(-31dB),但主瓣稍宽,适合对频率分辨率要求不高的场景。
- 矩形窗:无加权,主瓣最窄但旁瓣高达-13dB,一般不用于语音特征提取。
在定点实现中,汉明窗系数可以预先计算并存储为Q15格式的查找表,避免运行时计算三角函数。对于400点窗口,仅需400×2字节=800字节的Flash存储。
4.3 从频谱到Mel刻度:模拟人耳听觉特性
人耳对频率的感知是非线性的:对低频(<1kHz)的分辨率较高,对高频(>4kHz)的分辨率较低。Mel刻度正是模拟这种非线性感知的频标。将线性频率f(Hz)转换为Mel频率的公式为:
mel(f) = 2595 * log10(1 + f / 700)
在特征提取中,我们并不直接计算Mel频率,而是设计一组三角带通滤波器,在Mel刻度上等间距排列,覆盖整个分析频带。每个滤波器的输出为该频带内的能量总和。
4.3.1 Mel滤波器组的设计
对于16kHz采样率,FFT点数为512时,有效频率范围为0-8kHz(对应256个频点)。设计26个Mel滤波器组的步骤如下:
- 将最低频率(通常为0或50Hz)和最高频率(通常为fs/2=8000Hz)转换为Mel刻度。
- 在Mel刻度上等间距取26+2=28个点(包括两端)。
- 将28个Mel值转换回线性频率,并映射到最近的FFT频点索引。
- 对每个滤波器,构造三角形窗口:中心频率处权重为1,两侧线性衰减至相邻滤波器中心处为0。
在MCU上,这26个滤波器可以预先计算为稀疏矩阵(每个滤波器仅覆盖约10-30个FFT频点),存储为uint16数组。计算时,只需对每个滤波器累加对应频点的能量乘以权重即可。
4.3.2 Mel频谱与MFCC的区别
Mel频谱是经过Mel滤波器组后的对数能量向量(通常26维),而MFCC在此基础上进一步做离散余弦变换(DCT),得到13维系数。两者的关系与适用场景如下:
| 特征类型 | 维度 | 计算量 | 适用场景 |
|---|---|---|---|
| Mel频谱(Log-Mel) | 26-40维 | 较低(无DCT) | 深度学习模型(CNN/Transformer),可直接作为2D输入 |
| MFCC | 13-20维 | 中等(需DCT) | 传统GMM/HMM、轻量级DNN、资源极受限场景 |
在TinyML实践中,Log-Mel特征正逐渐取代MFCC成为主流选择。原因在于:现代MCU上的神经网络模型(如Depthwise CNN)可以直接处理2D的Mel频谱图,而DCT去相关操作对神经网络而言并非必要,反而可能丢失信息。但MFCC在特征维度上更紧凑,适合RAM极小的场景。
4.4 MFCC完整提取流程与定点化实现
MFCC的完整提取流程可以归纳为以下七个步骤,每一步在MCU上都有对应的定点化优化策略:
输入:原始PCM数据(16kHz/16bit)
步骤1:预加重 y[n] = x[n] - 0.97*x[n-1]
步骤2:分帧 帧长400点,帧移160点
步骤3:加窗 乘以汉明窗系数(Q15格式)
步骤4:FFT 512点实数FFT(使用基-2算法)
步骤5:Mel滤波 26个三角滤波器,计算对数能量
步骤6:DCT 取前13个系数
步骤7:动态特征(可选)计算一阶差分(Delta)
输出:13维MFCC向量
4.4.1 定点化关键技巧
Cortex-M4F内核虽然支持硬件浮点单元(FPU),但浮点运算的功耗约为定点运算的3-5倍。在电池供电的TinyML设备中,推荐采用Q15定点格式:
- FFT实现:使用CMSIS-DSP库的arm_rfft_q15函数,512点FFT仅需约15μs(@80MHz),比浮点版本快2-3倍。
- 对数计算:使用查表法或线性插值。将输入映射到[0.5, 1.0]区间,查16bit对数表,误差控制在0.1%以内。
- DCT实现:利用DCT-II的快速算法,或直接使用CMSIS-DSP的arm_dct4_q15函数。
- 内存管理:整个特征提取过程需要约3-4KB的临时缓冲区(包括FFT工作区、Mel滤波器权重、窗函数表),需在初始化时静态分配。
4.4.2 案例:基于STM32L4的唤醒词特征提取优化
背景与约束:某智能家居项目需要在STM32L476(80MHz,64KB RAM)上实现“小智小智”唤醒词检测。要求特征提取延迟小于30ms,平均功耗低于1mA(3.3V供电)。
初始方案与问题:第一版直接使用浮点运算,调用标准库的sin/cos/log函数。实测单帧特征提取耗时8.2ms,功耗2.3mA,且Flash占用超出预算。
优化过程:
- 将FFT切换为CMSIS-DSP的q15版本,耗时降至1.8ms。
- 预计算汉明窗和Mel滤波器权重为Q15查表,避免运行时计算。
- 对数运算改为16bit查表+线性插值,精度损失0.3dB,耗时0.2ms。
- DCT使用arm_dct4_q15,耗时0.5ms。
结果对比:优化后单帧总耗时2.9ms(满足30ms预算),功耗降至0.8mA,Flash占用减少42%。识别准确率从98.2%微降至97.9%,在可接受范围内。
复盘经验:定点化不是简单的类型替换,需要配合查表、算法选择(如使用split-radix FFT)和内存复用。建议在项目初期就确定定点方案,避免后期大规模返工。
4.5 时域特征与频域特征的对比选择
除了MFCC和Mel频谱,TinyML中还会用到一些轻量级的时域特征。理解它们的适用边界有助于在资源与性能之间做出权衡:
| 特征类型 | 计算量 | 维度 | 物理含义 | TinyML适用性 |
|---|---|---|---|---|
| 过零率(ZCR) | 极低 | 1 | 信号符号变化的频率,区分清音/浊音 | 适合作为辅助特征,用于VAD |
| 短时能量 | 极低 | 1 | 帧内样本平方和,反映音量变化 | 用于端点检测和增益控制 |
| 自相关函数 | 中等 | N | 检测基音周期 | 较少用于MCU,计算量偏高 |
| Mel频谱 | 中等 | 26-40 | 模拟人耳频率感知的能量分布 | 推荐用于CNN模型 |
| MFCC | 中等 | 13-20 | 倒谱域表示,去相关后更紧凑 | 适合DNN/线性模型 |
4.6 常见误区与工程复盘
在指导多个TinyML语音项目后,我总结了以下高频问题,供开发者规避:
- 误区一:采样率越高越好。实际上,44.1kHz采样会让FFT点数翻倍(1024点),计算量增加4倍,而语音识别性能几乎没有提升。16kHz是性价比最优的选择。
- 误区二:忽略直流偏置。许多麦克风模块输出带有1.2V偏置,若不通过高通滤波(截止频率50-100Hz)去除,会导致FFT的0频分量异常大,压缩其他频段的动态范围。
- 误区三:窗函数选择不当。在噪声环境下,矩形窗的频谱泄漏会放大噪声的旁瓣干扰。务必使用汉明窗或汉宁窗。
- 误区四:MFCC维度越多越好。在MCU上,13维MFCC已经能捕捉99%以上的语音判别信息。增加到20维只会增加DCT计算量和模型输入维度,对准确率提升有限。
- 误区五:忽视帧移对延迟的影响。帧移决定了特征提取的实时性。10ms帧移意味着每10ms产生一帧特征,若模型推理需要30ms,则系统总延迟为40ms——这已经接近交互延迟的感知阈值(100ms)。
语音特征提取是TinyML语音交互系统的“感知层”,其质量直接决定了后续模型的上限。在实际工程中,建议开发者先在PC端使用Python(librosa或torchaudio)验证特征参数的有效性,再移植到MCU上。同时,务必在目标硬件上测量每帧特征提取的实际耗时和功耗,因为不同MCU的FFT优化库性能差异可达5倍以上。掌握本章的采样、分帧、加窗、Mel滤波和MFCC提取方法,你就为后续的唤醒词模型训练和部署打下了坚实的基础。