语音识别是机器通过识别和理解过程把人类的语音信号转变为相应文本或命令的技术,其根本目的是研究出一种具有听觉功能的机器。本设计研究孤立词语音识别系统及其在 STM32 嵌入式平台上的实现。识别流程是:预滤波、ADC、分帧、端点检测、预加重、加窗、特征提取、特征匹配。端点检测(VAD)采用短时幅度和短时过零率相结合。检测出有效语音后,根据人耳 听觉感知特性,计算每帧语音的 Mel 频率倒谱系数(MFCC)。然后采用动态时间弯折(DTW)算法与特征模板相匹配,最终输出识别结果。先用 Matlab 对上述算法进行仿真,经多次试验得出算法中所需各系数的最优值。然后将算法移植到 STM32 嵌入式平台, 移植过程中根据嵌入式平台存储空间相对较小、计算能力也相对较弱的实际情况,对算法进行优化。最终设计并制作出基于
STM32 的孤立词语音识别系统。
本设计的孤立词语音识别是语音识别技术中较为基本的,算法实现也较简单,适合于在嵌入式平台中实现一些简单的语音控制功能。以往类似系统大都基于 ARM9、ARM11、DSP、SOC 等。这些平台系统规模较大、开发和维护的难度较大、成本也相对较高。STM32 是意法半导体(ST)公司推出的基于 ARM Cortex-M3 内核的高性能单片机。上市之后,由于其出色的性能、低廉的价格,很快被运用到众多产品中。经测试,STM32F103VET6 单片机拥有能够满足本系统孤立词语音识别所需的运算和存储能力。所以在本系统中采用 STM32F103VET6 作为主控制器,采集并识别语音信号。
一,系统设计任务要求
本系统利用单片机设计了一个孤立词语音识别系统,能够识别 0~9、 “上”、“下”、“左”、“右”14 个汉语语音指令。系统通过触摸式 LCD 与用户交互。
本设计的主要要求如下:
1.采集外部声音信号,转换为数字信号并存储。
2.在采集到的声音信号中找出有效语音信号的开始和结束点。
3.分析检测到的有效语音,得出语音信号特征。
4.对每个待识别的语音指令,建立特征模版。
5.比较输入语音信号特征与特征模版,识别输入的语音信号
6.显示系统操作界面,并能够接受用户控制。
系统硬件由音频放大模块、MCU、触摸屏、电源四部分组成。音频放大模块完成对外部声音信号的采集和放大。将声音信号转化为电信号,并放大到 0~3V。MCU 的 ADC 参考电压为其电源电压 3.3V。音频放大模块的输出信号不超出 MCU ADC 的电压范围,并且能够获得最大的量化精度。MCU 对音频放大模块输入的声音信号进行 AD 转换。然后提取并识别信号特征。另外,MCU 还控制触摸屏的显示和读取触摸屏点击位置。触摸屏负责显示操作界面,并接收用户操作。电源为电池供电。
系统硬件框图
本系统中采集一个汉语语音指令。录音时间长度 2s,以 8KHz 16bit 采样率对语音进行采集,所需存储空间为 32KB,另外加上语音处理、特征提取及特征匹配等中间步骤所需 RAM 空间不会超过 64KB。而 STM32F103VET6 带有 512KB Flash 和 64KB RAM。所以 STM32F103VET6 在程序空间上能够满足。语音识别中最耗时的部分是特征提取中的快速傅立叶变换换。一般来说,孤立词语音识别中有效语音时间长度小于 1s。语音信号一般 10~30ms 为一帧,本系统中按 20ms 一帧,帧移(相邻两帧的重叠部分)
10ms,这样一个语音指令不超过 100 帧。在 8KHz 16bit 的采样率下,20ms 为 160 采样点 。STM32 固件库所提供的 16 位、1024 点 FFT,在内核以 72MHz 运行时每次运算仅需 2.138ms。完成 100 帧数据的 FFT 所需时间为 213.8ms,加上其他处理所需时间,识别一个语音指令耗时不会超过 0.5s。所以在程序运行时间上 STM32F103VET6 也能够满足需要,能够进行实时的孤立词语音识别。
二、 音频信号采集方案选择
音频信号采集多采用音频编解码芯片,例如 UDA1341、VS1003 等。此类芯片能够提供丰富的功能,且系统一致性较好,但它们成本较高。本系统是一个低成本解决方案,并且只需要采集音频信号。因此不宜采用那些专用的音频编解码芯片。
在本系统的音频放大模块中使用小型话筒完成声电信号转换,两个 9014 三极管构成两级共基极放大电路。在每一级中加电压负反馈,稳定放大倍数。
语音信号的频带为 300~3400Hz,根据抽样定理,抽样频率设为 8000Hz就足以完成对语音信号的采集。在本系统中 TIM1被设置为 ADC触发信号源。TIM时钟源为系统时钟 72MHz。经 100分频,变为 720KHz。计数模式为向上递增,自动重载值为 90, 即计数值从 0递增到 90再返回 0。比较匹配值设为 0~90间任意一个数值 ,则每秒可发出 8000次比较匹配事件。ADC每秒完成 8000次 A/D转换,即抽样频率为 8KHz。
三,采样软件算法
对采集到的音频信号进行预处理、端点检测、特征提取、模板训练、特征匹配的一些列处理,最终识别输入语音。 系统软件流程图如下图所示。
语音信号的预处理主要包括: ADC、分帧、数据加窗、预加重。
语音信号的频率范围通常取 100Hz~3400Hz,因为这个频段包含绝大部分的语音信息,对语音识别的意义最大。根据采样定律, 要不失真地对 3400Hz 的信号进行采样,需要的最低采样率是 6800Hz。为了提高精度,常用的 A/D 采样率在 8kHz 到 12kHz。语音信号有一个重要的特性:短时性。由于人在说话中,清音与浊音交替出现,并且每种音通常只延续很短的一段时间。因此, 从波形上看,语音信号具有很强的“时变特性”。在浊音段落中它有很强的周期性,在清音段落中又具有噪声特性,而且浊音和清音的特征也在不断变化之中。如图 1.4 所示,其特性是随时间变化的,所以它是一个非稳态过程。但从另一方面看,由于语音的形成过程是与发音器官的运动密切相关的,这种物理性的运动比起声音振动速度来说是缓慢的(如图 1.5 所示)。因此在一个短时间范围内,其特性变化很小或保持不变,可以将其看做一个准稳态过程。我们可以用平稳过程的分析处理方法来分析处 理语音信号。
基于以上考虑,对语音信号的分析处理必须采用短时分析法,也就是分帧。语音信号通常在 10ms~30ms 之间保持相对平稳。在本设计中,每帧取 20ms。为了使前后帧之间保持平滑过渡,帧移 10ms,即前后帧之间交叠 10ms。
四、 端点检测算法选择
语音端点检测(VAD),也称为语音活动性检测,主要应用在语音处理中的语音编解码,语音识别及单信道语音增强等领域。语音 端点检测的基本方法可以用一句话来表达:从输入信号中提取一个或一系列的对比特征参数,然后将其和一个或一系列的门限 阀值进行比较(如图 3-2)。如果超过门限则表示当前为有音段;否则表示当前为无音段。门限阀值通常是根据无音段时的特征确 定的。但是由于语音和环境噪声的不断变化,使得这一判决过程变得非常复杂。通常语音端点检测是在语音帧的基础上进行的, 语音帧的长度在 10ms~30ms 不等。一个好的语音端点检测算法必须具有对各种噪声的鲁棒性,同时要简单、适应性能好、时 延小、且易于实时实现。 在高信噪比的情况下,常用的检测方法大体上有以下几种:短时能量、短时过零率。这些方法都是利用了语音和噪声的特征参 数,因此判别效果较好。并且它们实现简单,计算量相对较小,因而得到广泛的应用。 短时能量定义如下式: (1-6) 式中 N 为帧长,E 为一帧的短时能量值。 短时能量主要有以下几个方面的应用:首先短时能量可以区分清音和浊音,因为浊音的能量要比清音的大得多;其次可以用短 时能量对有声段和无声段进行判定,以及连字分界等。短时能量由于是对信号进行平方运算,因而人为增加了高低信号之间的 差距。更重要的的是平方运算的结果很大,容易产生数据溢出。解决这些问题的简单方法是采用短时平均幅度值来表示能量的
4.1 音频信号采集电路设计 音频信号采集电路原理图如下
4.2 语音预处理算法设计
语音信号预处理包括: 语音信号采集、分帧、数据加窗、预加重。 语音信号采集就是将外部模拟的语音信号,转换为 MCU 可处理和识别的数字信号的过程。在本设计中,通过 MCU 内部的定时 器、模数转换器以及 DMA 控制器实现了对音频信号采集模块输入语音信号的数字化。其处理流程如下图所示。
在程序中,控制语音信号采集的函数如下。
分帧就是将采集到的语音数据分割成相同长度的片段,以用于短时分析。本设计中取 20ms 即 160 点为一帧,帧移 10ms 即 80 点。为了适应 MCU 存储空间有限的实际情况,分帧并没有被单独设计和占用单独的空间,而是在读语音数据缓冲区的时候按照 帧长帧移的顺序依次读取。 由于端点检测属于时域分析,并不需要加窗和预加重,所以本设计中,分帧和预加重都加在端点检测之后提取 MFCC 之前。
4.3 端点检测算法设计
本设计采用短时幅度和短时过零率相结合的端点检测算法。 首先去缓冲区前 300ms 作为背景噪声,提取背景噪声参数。用于后续端点检测。背景噪声参数由以下结构体定义。
提取函数为 void noise_atap(const u16* noise,u16 n_len,atap_tag* atap),其提取过程如下。
然后根据提取到的短时过零率和短时幅度计算有效语音起始和结束点。有效语音端点由以下结构体定义。
端点检测函数为 void VAD(const u16 *vc, u16 buf_len, valid_tag *valid_voice, atap_tag *atap_arg)。其流程图如下。
4.4 特征提取算法设计及优化
本设计选用 12 阶 MFCC 作为语音特征。此步是整个算法流程中最耗时也是优化空间最大的部分。因此,在程序设计中,沿用经 典算法的同时做了大量的针对 STM32 嵌入式平台的优化工作。优化的中心思想是:尽量少使用或不使用浮点运算;使用整型数, 其运算结果应尽量大以减少舍入噪声,但必须保证数据不会溢出;空间换时间。 FFT 函数是 u32* fft(s16* dat_buf, u16 buf_len)。它封装了了 ST 提供的 STM32 固件库里的 void cr4_fft_1024_stm32(void *pssOUT, void *pssIN, u16 Nbin)函数。cr4_fft_1024_stm32()输入参数是有符号数,包括实数和虚数,但语音数据只包括实数 部分,虚数用 0 填充,fft 点数超出输入数据长度时,超过部分用 0 填充。cr4_fft_1024_stm32()输出数据包括实数和虚数,应 该取其绝对值,即平方和的根。 语音特征用如下结构体定义。
获取 MFCC 的函数是
void get_mfcc(valid_tag *valid, v_ftr_tag *v_ftr, atap_tag *atap_arg)。
获取 MFCC 的一般步骤在上一章 已有论述,在此介绍移植到 MCU 上需做的优化。 预加重的高通滤波系数为 0.95,如果直接使用,则需要进行浮点运算,尽量避免,故使用 y(n)=x(n)-x(n-1)×95/100。加汉明窗 窗函数值如果每次都要重新计算,则需要进行三角函数运算,耗时严重,效率低下。但其数值是一定的,因此事先计算好 160 点的汉明窗值。存于数组中 const u16 hamm[],使用时直接读取。FFT 函数直接输入 ADC 转换过的值-2048~2047,其输出频 谱幅值过小,舍入误差较大。数据输入前需作放大处理。vc_temp[i]=(s16)(temp*hamm[i]/(hamm_top/10));此句代码在实现加 窗的同时,将语音数据放大 10 倍。Mel 三角滤波器的中心频率和数值的计算涉及到对数运算,不宜直接计算,也实现计算好的 数值存于 Flash 中,使用时直接读取。还有其他的优化措施,详见附件代码。
void get_mfcc(valid_tag *valid, v_ftr_tag *v_ftr, atap_tag *atap_arg)
函数流程如下。
4.5 模板训练算法设计
本设计模板训练采用冗余模板算法,即每个语音指令存储 4 个特征模板,识别时输入特征分别与每个特征模板相比较,匹配距 离最小的,就是识别结果。这 4 个特征模板存储于 MCU Flash 后端,模板训练时,将模板存于指定的 Flash 地址。为了保证保 存的特征模板不被擦除或被其他代码或数据占用,需设置编译器的地址范围。
4.6 特征匹配算法设计
本设计特征匹配算法采用 DTW(动态时间弯折)。其原理在上一章已有论述,在此不再赘述。其流程如下。
最后原理样机经过设计方案论证,设计了相应的硬件电路和系统软件,制作了电路原理样机并进行单机调试,结果表明,所设计的 电路和软件能完成基本的测试功能。 采用 STM32F103VET6 单片机构建语音识别系统,通过此系统对语音信号进行采集、前端放大、AD 转换、预处理、MFCC 特征 提取、模板训练、DTW 特征匹配的一系列步骤,完成孤立词语音识别的预期目标。 本设计目前也存在一些不足,例如语音信号采集模块的动态范围不足,当说话声音较大或较小时,会出现无法识别的现象,需 加上自动增益控制功能。语音识别时,录音控制不方便,最好能够改进为完全通过语音控制。特征模板仅仅用 12 阶 MFCC 略显 不足,可添加 MFCC 一阶差分。