語(yǔ)音識(shí)別是機(jī)器通過(guò)識(shí)別和理解過(guò)程把人類的語(yǔ)音信號(hào)轉(zhuǎn)變?yōu)橄鄳?yīng)文本或命令的技術(shù),其根本目的是研究出一種具有聽(tīng)覺(jué)功能的機(jī)器。本設(shè)計(jì)研究孤立詞語(yǔ)音識(shí)別系統(tǒng)及其在STM32嵌入式平臺(tái)上的實(shí)現(xiàn)。識(shí)別流程是:預(yù)濾波、ADC、分幀、端點(diǎn)檢測(cè)、預(yù)加重、加窗、特征提取、特征匹配。端點(diǎn)檢測(cè)(VAD)采用短時(shí)幅度和短時(shí)過(guò)零率相結(jié)合。檢測(cè)出有效語(yǔ)音后,根據(jù)人耳聽(tīng)覺(jué)感知特性,計(jì)算每幀語(yǔ)音的Mel頻率倒譜系數(shù)(MFCC)。然后采用動(dòng)態(tài)時(shí)間彎折(DTW)算法與特征模板相匹配,最終輸出識(shí)別結(jié)果。先用Matlab對(duì)上述算法進(jìn)行仿真,經(jīng)多次試驗(yàn)得出算法中所需各系數(shù)的最優(yōu)值。然后將算法移植到STM32嵌入式平臺(tái),移植過(guò)程中根據(jù)嵌入式平臺(tái)存儲(chǔ)空間相對(duì)較小、計(jì)算能力也相對(duì)較弱的實(shí)際情況,對(duì)算法進(jìn)行優(yōu)化。最終設(shè)計(jì)并制作出基于STM32的孤立詞語(yǔ)音識(shí)別系統(tǒng)。
從技術(shù)上講,語(yǔ)音識(shí)別屬于多維模式識(shí)別和智能接口的范疇。它是一項(xiàng)集聲學(xué)、語(yǔ)音學(xué)、計(jì)算機(jī)、信息處理、人工智能等于一身的綜合技術(shù),可廣泛應(yīng)用在信息處理、通信和電子系統(tǒng)、自動(dòng)控制等領(lǐng)域。
國(guó)際上對(duì)語(yǔ)音識(shí)別的研究始于20世紀(jì)50年代。由于語(yǔ)音識(shí)別本身所固有的難度,人們提出了各種條件下的研究任務(wù),并有此產(chǎn)生了不同的研究領(lǐng)域。這些領(lǐng)域包括:針對(duì)說(shuō)話人,可分為特定說(shuō)話人語(yǔ)音識(shí)別和非特定說(shuō)話人語(yǔ)音識(shí)別;針對(duì)詞匯量,可劃分為小詞匯量、中詞匯量和大詞匯量的識(shí)別,按說(shuō)話方式,可分為孤立詞識(shí)別和連續(xù)語(yǔ)音等。最簡(jiǎn)單的研究領(lǐng)域是特定說(shuō)話人、小詞匯量、孤立詞的識(shí)別,而最難的研究領(lǐng)域是非特定人、大詞匯量、連續(xù)語(yǔ)音識(shí)別。
在進(jìn)入新世紀(jì)之前,語(yǔ)音識(shí)別技術(shù)大都只在特定行業(yè)或場(chǎng)所中使用或者僅僅停留在實(shí)驗(yàn)室,處于探索和試驗(yàn)中。最近十年由于消費(fèi)電子行業(yè)的興起和移動(dòng)互聯(lián)網(wǎng)技術(shù)的爆發(fā)。越來(lái)越多的自動(dòng)化和自能化產(chǎn)品走進(jìn)人們的日常生活。語(yǔ)音識(shí)別技術(shù)也隨之進(jìn)入大眾的視線,并開(kāi)始為更多人所了解和使用。例如語(yǔ)音門(mén)禁、智能電視上的語(yǔ)音換臺(tái)、智能手機(jī)上的語(yǔ)音撥號(hào)、語(yǔ)音控制等等。語(yǔ)音識(shí)別技術(shù)正在由過(guò)去的實(shí)驗(yàn)探索邁入實(shí)用化階段。我們有理由相信會(huì)有越來(lái)越多的產(chǎn)品用到語(yǔ)音識(shí)別技術(shù),它與人工智能能技術(shù)的結(jié)合將會(huì)是一個(gè)重要的發(fā)展方向。語(yǔ)音識(shí)別技術(shù)最終會(huì)改變?nèi)伺c機(jī)器之間的交互方式,使之更加自然、便捷、輕松。
本設(shè)計(jì)的孤立詞語(yǔ)音識(shí)別是語(yǔ)音識(shí)別技術(shù)中較為基本的,算法實(shí)現(xiàn)也較簡(jiǎn)單,適合于在嵌入式平臺(tái)中實(shí)現(xiàn)一些簡(jiǎn)單的語(yǔ)音控制功能。以往類似系統(tǒng)大都基于ARM9、ARM11、DSP、SOC等。這些平臺(tái)系統(tǒng)規(guī)模較大、開(kāi)發(fā)和維護(hù)的難度較大、成本也相對(duì)較高。STM32是意法半導(dǎo)體(ST)公司推出的基于ARM Cortex-M3內(nèi)核的高性能單片機(jī)。上市之后,由于其出色的性能、低廉的價(jià)格,很快被運(yùn)用到眾多產(chǎn)品中。經(jīng)測(cè)試,STM32F103VET6單片機(jī)擁有能夠滿足本系統(tǒng)孤立詞語(yǔ)音識(shí)別所需的運(yùn)算和存儲(chǔ)能力。所以在本系統(tǒng)中采用STM32F103VET6作為主控制器,采集并識(shí)別語(yǔ)音信號(hào)。以低廉的成本,高效的算法完成了孤立詞語(yǔ)音識(shí)別的設(shè)計(jì)目標(biāo)。本系統(tǒng)主要涉及的內(nèi)容如下述:
語(yǔ)音信號(hào)的采集和前端放大、防混疊濾波、模數(shù)轉(zhuǎn)換。
語(yǔ)音信號(hào)預(yù)處理,包括預(yù)加重、分幀、加窗。
語(yǔ)音信號(hào)端點(diǎn)檢測(cè),檢測(cè)輸入信號(hào)中有效語(yǔ)音的起始和結(jié)束點(diǎn)
語(yǔ)音信號(hào)特征提取。提取有效語(yǔ)音中每幀語(yǔ)音信號(hào)的Mel頻率倒譜系數(shù)(MFCC)系數(shù)。
模板訓(xùn)練,對(duì)每個(gè)語(yǔ)音指令采集多個(gè)語(yǔ)音樣本,根據(jù)語(yǔ)音樣本獲取每個(gè)語(yǔ)音指令的特征模板。
特征匹配,使用動(dòng)態(tài)時(shí)間規(guī)整(DWT)算法計(jì)算輸入語(yǔ)音信號(hào)與各模板的匹配距離。識(shí)別輸入的語(yǔ)音信號(hào)。
系統(tǒng)硬件電路設(shè)計(jì),人機(jī)界面設(shè)計(jì)。
第一章 方案論證及選擇1.1系統(tǒng)設(shè)計(jì)任務(wù)要求本系統(tǒng)利用單片機(jī)設(shè)計(jì)了一個(gè)孤立詞語(yǔ)音識(shí)別系統(tǒng),能夠識(shí)別0~9、 “上”、“下”、“左”、“右”14個(gè)漢語(yǔ)語(yǔ)音指令。系統(tǒng)通過(guò)觸摸式LCD與用戶交互。
本設(shè)計(jì)的主要要求如下:
1.采集外部聲音信號(hào),轉(zhuǎn)換為數(shù)字信號(hào)并存儲(chǔ)。
2.在采集到的聲音信號(hào)中找出有效語(yǔ)音信號(hào)的開(kāi)始和結(jié)束點(diǎn)。
3.分析檢測(cè)到的有效語(yǔ)音,得出語(yǔ)音信號(hào)特征。
4.對(duì)每個(gè)待識(shí)別的語(yǔ)音指令,建立特征模版。
5.比較輸入語(yǔ)音信號(hào)特征與特征模版,識(shí)別輸入的語(yǔ)音信號(hào)
6.顯示系統(tǒng)操作界面,并能夠接受用戶控制。
1.2硬件選擇1.2.1 硬件方案總體介紹系統(tǒng)硬件由音頻放大模塊、MCU、觸摸屏、電源四部分組成。音頻放大模塊完成對(duì)外部聲音信號(hào)的采集和放大。將聲音信號(hào)轉(zhuǎn)化為電信號(hào),并放大到0~3V。MCU的ADC參考電壓為其電源電壓3.3V。音頻放大模塊的輸出信號(hào)不超出MCU ADC的電壓范圍,并且能夠獲得最大的量化精度。MCU對(duì)音頻放大模塊輸入的聲音信號(hào)進(jìn)行AD轉(zhuǎn)換。然后提取并識(shí)別信號(hào)特征。另外,MCU還控制觸摸屏的顯示和讀取觸摸屏點(diǎn)擊位置。觸摸屏負(fù)責(zé)顯示操作界面,并接收用戶操作。電源為電池供電。
系統(tǒng)硬件結(jié)構(gòu)圖如圖1.1所示。
圖1.1系統(tǒng)硬件總體結(jié)構(gòu)圖
1.2.2 MCU選擇傳統(tǒng)上孤立詞語(yǔ)音識(shí)別多采用語(yǔ)音識(shí)別專用芯片,例如凌陽(yáng)SPCE061A、LD3320等。此種方案設(shè)計(jì)簡(jiǎn)單,開(kāi)發(fā)周期較短,但可拓展性較差,一般只能識(shí)別特定的語(yǔ)音,或者識(shí)別語(yǔ)音指令的個(gè)數(shù)有限制。且專用芯片價(jià)格一般相對(duì)較高,對(duì)系統(tǒng)成本控制不利。
STM32F103VET6是意法半導(dǎo)體(ST)推出的高性能32位Cortex-M3內(nèi)核單片機(jī),帶有ADC、DAC、USB、CAN、SDIO、USART、SPI、IIC、FSMC、RTC、TIM、GPIO、DMA等大量片上外設(shè)。Cortex-M3內(nèi)核屬于ARM公司推出的最新架構(gòu)ARMv7中的M系列,側(cè)重于低成本、低功耗、高性能。其最高主頻可達(dá)72MHz, 1.25 DMIPS/MHz的運(yùn)算能力,三級(jí)流水線另加分支預(yù)測(cè),并且還帶有單周期乘法器和硬件除法器。相比較ARM7TDMI內(nèi)核,Cortex-M3在性能上有較大的提升。
STM32F103VET6內(nèi)置3個(gè)一共21通道的12位ADC,采樣頻率最高可達(dá)1MHz。12通道DMA控制器,可訪問(wèn)系統(tǒng)Flash、SRAM、片上外設(shè),能夠處理內(nèi)存到外設(shè)、外設(shè)到內(nèi)存的DMA請(qǐng)求。11個(gè)16位定時(shí)器,其中T1、T2、T3、T4、T5、T8可連接到ADC控制器,在每次定時(shí)器捕獲/比較事件到來(lái)時(shí)自動(dòng)觸發(fā)ADC開(kāi)始一次A/D轉(zhuǎn)換。A/D轉(zhuǎn)換完成后可自動(dòng)觸發(fā)DMA控制器將轉(zhuǎn)換后的數(shù)據(jù)依次傳送至SRAM的數(shù)據(jù)緩沖區(qū)。因此STM32F103VET6能夠進(jìn)行精確且高效的A/D轉(zhuǎn)換。能夠滿足音頻信號(hào)采集的需求。
STM32F103VET6的FSMC(Flexible Static Memory Controller,可變靜態(tài)存儲(chǔ)控制器)能夠根據(jù)不同的外部存儲(chǔ)器類型,發(fā)出相應(yīng)的數(shù)據(jù)/地址/控制信號(hào)類型以匹配信號(hào)的速度。FSMC連接至LCD控制器,可將LCD控制器配置為外部NOR Flash。在系統(tǒng)需要訪問(wèn)LCD時(shí),自動(dòng)生成滿足LCD控制器要求的讀寫(xiě)時(shí)序,能夠精確、快速地完成對(duì)LCD界面顯示的控制。內(nèi)置3個(gè)最高可達(dá)18Mbit/s的SPI控制器,與觸摸屏控制器相連能夠?qū)崿F(xiàn)觸摸屏點(diǎn)擊位置檢測(cè)。
本系統(tǒng)中采集一個(gè)漢語(yǔ)語(yǔ)音指令。錄音時(shí)間長(zhǎng)度2s,以8KHz 16bit采樣率對(duì)語(yǔ)音進(jìn)行采集,所需存儲(chǔ)空間為32KB,另外加上語(yǔ)音處理、特征提取及特征匹配等中間步驟所需RAM空間不會(huì)超過(guò)64KB。而STM32F103VET6帶有512KB Flash和64KB RAM。所以STM32F103VET6在程序空間上能夠滿足。語(yǔ)音識(shí)別中最耗時(shí)的部分是特征提取中的快速傅立葉變換換。一般來(lái)說(shuō),孤立詞語(yǔ)音識(shí)別中有效語(yǔ)音時(shí)間長(zhǎng)度小于1s。語(yǔ)音信號(hào)一般10~30ms為一幀,本系統(tǒng)中按20ms一幀,幀移(相鄰兩幀的重疊部分)10ms,這樣一個(gè)語(yǔ)音指令不超過(guò)100幀。在8KHz 16bit的采樣率下,20ms為160采樣點(diǎn) 。STM32固件庫(kù)所提供的16位、1024點(diǎn)FFT,在內(nèi)核以72MHz運(yùn)行時(shí)每次運(yùn)算僅需2.138ms。完成100幀數(shù)據(jù)的FFT所需時(shí)間為213.8ms,加上其他處理所需時(shí)間,識(shí)別一個(gè)語(yǔ)音指令耗時(shí)不會(huì)超過(guò)0.5s。所以在程序運(yùn)行時(shí)間上STM32F103VET6也能夠滿足需要,能夠進(jìn)行實(shí)時(shí)的孤立詞語(yǔ)音識(shí)別。
基于以上論證,本系統(tǒng)選用STM32F103VET6作為主控MCU。
1.2.3音頻信號(hào)采集方案選擇音頻信號(hào)采集多采用音頻編解碼芯片,例如UDA1341、VS1003等。此類芯片能夠提供豐富的功能,且系統(tǒng)一致性較好,但它們成本較高。本系統(tǒng)是一個(gè)低成本解決方案,并且只需要采集音頻信號(hào)。因此不宜采用那些專用的音頻編解碼芯片。
在本系統(tǒng)的音頻放大模塊中使用小型話筒完成聲電信號(hào)轉(zhuǎn)換,兩個(gè)9014三極管構(gòu)成兩級(jí)共基極放大電路。在每一級(jí)中加電壓負(fù)反饋,穩(wěn)定放大倍數(shù)。
語(yǔ)音信號(hào)的頻帶為300~3400Hz,根據(jù)抽樣定理,抽樣頻率設(shè)為8000Hz就足以完成對(duì)語(yǔ)音信號(hào)的采集。在本系統(tǒng)中TIM1被設(shè)置為ADC觸發(fā)信號(hào)源。TIM時(shí)鐘源為系統(tǒng)時(shí)鐘72MHz。經(jīng)100分頻,變?yōu)?20KHz。計(jì)數(shù)模式為向上遞增,自動(dòng)重載值為90,即計(jì)數(shù)值從0遞增到90再返回0。比較匹配值設(shè)為0~90間任意一個(gè)數(shù)值 ,則每秒可發(fā)出8000次比較匹配事件。ADC每秒完成8000次A/D轉(zhuǎn)換,即抽樣頻率為8KHz。
1.2.4顯示及操作界面選擇觸摸屏作為一種新的輸入設(shè)備,它是目前最簡(jiǎn)單、方便、自然的一種人機(jī)交互方式。LCD觸摸屏是一種可接收觸摸點(diǎn)擊輸入信號(hào)的感應(yīng)式液晶顯示裝置。當(dāng)接觸或點(diǎn)擊屏幕時(shí),觸摸控制器可讀取觸摸點(diǎn)位置,如此可通過(guò)屏幕直接接受用戶的操作。相比較機(jī)械式按鈕,觸摸屏在操作上更加直觀生動(dòng)。綜合考慮,本設(shè)計(jì)中采用2.5寸240×320分辨率的LCD觸摸屏實(shí)現(xiàn)界面顯示和操作。
1.3算法選擇1.3.1軟件算法總體介紹對(duì)采集到的音頻信號(hào)進(jìn)行預(yù)處理、端點(diǎn)檢測(cè)、特征提取、模板訓(xùn)練、特征匹配的一些列處理,最終識(shí)別輸入語(yǔ)音。
系統(tǒng)軟件流程圖如下圖所示。
1.3.2預(yù)處理算法選擇語(yǔ)音信號(hào)的預(yù)處理主要包括: ADC、分幀、數(shù)據(jù)加窗、預(yù)加重。
語(yǔ)音信號(hào)的頻率范圍通常取100Hz~3400Hz,因?yàn)檫@個(gè)頻段包含絕大部分的語(yǔ)音信息,對(duì)語(yǔ)音識(shí)別的意義最大。根據(jù)采樣定律,要不失真地對(duì)3400Hz的信號(hào)進(jìn)行采樣,需要的最低采樣率是6800Hz。為了提高精度,常用的A/D采樣率在8kHz到12kHz。
語(yǔ)音信號(hào)有一個(gè)重要的特性:短時(shí)性。由于人在說(shuō)話中,清音與濁音交替出現(xiàn),并且每種音通常只延續(xù)很短的一段時(shí)間。因此,從波形上看,語(yǔ)音信號(hào)具有很強(qiáng)的“時(shí)變特性”。在濁音段落中它有很強(qiáng)的周期性,在清音段落中又具有噪聲特性,而且濁音和清音的特征也在不斷變化之中。如圖1.4所示,其特性是隨時(shí)間變化的,所以它是一個(gè)非穩(wěn)態(tài)過(guò)程。但從另一方面看,由于語(yǔ)音的形成過(guò)程是與發(fā)音器官的運(yùn)動(dòng)密切相關(guān)的,這種物理性的運(yùn)動(dòng)比起聲音振動(dòng)速度來(lái)說(shuō)是緩慢的(如圖1.5所示)。因此在一個(gè)短時(shí)間范圍內(nèi),其特性變化很小或保持不變,可以將其看做一個(gè)準(zhǔn)穩(wěn)態(tài)過(guò)程。我們可以用平穩(wěn)過(guò)程的分析處理方法來(lái)分析處理語(yǔ)音信號(hào)。
圖1.4 語(yǔ)音“7”的時(shí)域波形
圖1.5 語(yǔ)音“7”清音段和濁音段的20ms短時(shí)波形
基于以上考慮,對(duì)語(yǔ)音信號(hào)的分析處理必須采用短時(shí)分析法,也就是分幀。語(yǔ)音信號(hào)通常在10ms~30ms之間保持相對(duì)平穩(wěn)。在本設(shè)計(jì)中,每幀取20ms。為了使前后幀之間保持平滑過(guò)渡,幀移10ms,即前后幀之間交疊10ms。
為了便于后續(xù)語(yǔ)音處理,需對(duì)分幀后的信號(hào)加窗。加窗方式如式(1-1)。
(1-1)
式中Y(n)是加窗后的信號(hào),y(n)是輸入信號(hào),w(n)是窗函數(shù),N是幀長(zhǎng)。
窗函數(shù)可以選擇矩形窗,即
(1-2)
圖1.6 矩形窗時(shí)域、頻域示意圖
或其他形式窗函數(shù),如漢明窗
(1-3)
圖1.7 漢明窗時(shí)域、頻域示意圖
這些窗函數(shù)的頻率響應(yīng)都具有低通特性,但不同的窗函數(shù)形狀將影響分幀后短時(shí)特征的特性。圖1.7和圖1.8分別給出了160點(diǎn)矩形窗和漢明窗的時(shí)域和頻域示意圖。從圖中可以看出漢明窗的帶寬大約是同樣寬度矩形窗帶寬的兩倍。同時(shí),在通帶外漢明窗的衰減比矩形窗大得多。矩形窗的主瓣較小,旁瓣較高;而漢明窗具有最寬的主瓣寬度和最低的旁瓣高度。
對(duì)語(yǔ)音信號(hào)分析來(lái)說(shuō),窗函數(shù)的形狀是非常重要的,矩形窗的譜平滑性較好,但波形細(xì)節(jié)易丟失,并且矩形窗會(huì)產(chǎn)生泄露現(xiàn)象。而漢明窗可以有效地克服泄露現(xiàn)象,應(yīng)用范圍也最為廣泛。基于以上論述,本設(shè)計(jì)選用漢明窗作為窗函數(shù)。圖1.9和圖1.10分別給出了一幀濁音加矩形窗和漢明窗后的時(shí)域和頻域效果。
圖1.8 加矩形窗
圖1.9 加漢明窗
由于人的發(fā)聲器官的固有特性,語(yǔ)音從嘴唇輻射將有6dB/倍頻的衰減。此種效應(yīng)主要表現(xiàn)在高頻信息的損失,對(duì)語(yǔ)音信號(hào)的特征提取會(huì)造成不利的影響。因此,必須對(duì)信號(hào)進(jìn)行高頻提升,即對(duì)信號(hào)進(jìn)行高頻的補(bǔ)償,使得信號(hào)頻譜平坦化,以便于進(jìn)行頻譜分析或聲道參數(shù)分析。預(yù)加重可以用具有6dB/倍頻提升高頻特性的預(yù)加重?cái)?shù)字濾波器實(shí)現(xiàn)。預(yù)加重濾波器一般是一階的,其系統(tǒng)函數(shù)和差分方程如式(1-4)
(1-4)
其中y(n)為提升后的輸出值,x(n)和x(n-1)分別為當(dāng)前時(shí)刻和前一時(shí)刻的輸入值。u接近于1,典型取值在0.94~0.97之間。本設(shè)計(jì)取0.95。預(yù)加重效果如圖1.11所示。
圖1.10 預(yù)加重效果圖
1.3.3端點(diǎn)檢測(cè)算法選擇語(yǔ)音端點(diǎn)檢測(cè)(VAD),也稱為語(yǔ)音活動(dòng)性檢測(cè),主要應(yīng)用在語(yǔ)音處理中的語(yǔ)音編解碼,語(yǔ)音識(shí)別及單信道語(yǔ)音增強(qiáng)等領(lǐng)域。語(yǔ)音端點(diǎn)檢測(cè)的基本方法可以用一句話來(lái)表達(dá):從輸入信號(hào)中提取一個(gè)或一系列的對(duì)比特征參數(shù),然后將其和一個(gè)或一系列的門(mén)限閥值進(jìn)行比較(如圖3-2)。如果超過(guò)門(mén)限則表示當(dāng)前為有音段;否則表示當(dāng)前為無(wú)音段。門(mén)限閥值通常是根據(jù)無(wú)音段時(shí)的特征確定的。但是由于語(yǔ)音和環(huán)境噪聲的不斷變化,使得這一判決過(guò)程變得非常復(fù)雜。通常語(yǔ)音端點(diǎn)檢測(cè)是在語(yǔ)音幀的基礎(chǔ)上進(jìn)行的,語(yǔ)音幀的長(zhǎng)度在10ms~30ms不等。一個(gè)好的語(yǔ)音端點(diǎn)檢測(cè)算法必須具有對(duì)各種噪聲的魯棒性,同時(shí)要簡(jiǎn)單、適應(yīng)性能好、時(shí)延小、且易于實(shí)時(shí)實(shí)現(xiàn)。
在高信噪比的情況下,常用的檢測(cè)方法大體上有以下幾種:短時(shí)能量、短時(shí)過(guò)零率。這些方法都是利用了語(yǔ)音和噪聲的特征參數(shù),因此判別效果較好。并且它們實(shí)現(xiàn)簡(jiǎn)單,計(jì)算量相對(duì)較小,因而得到廣泛的應(yīng)用。
短時(shí)能量定義如下式:
(1-6)
式中N為幀長(zhǎng),E為一幀的短時(shí)能量值。
短時(shí)能量主要有以下幾個(gè)方面的應(yīng)用:首先短時(shí)能量可以區(qū)分清音和濁音,因?yàn)闈嵋舻哪芰恳惹逡舻拇蟮枚?;其次可以用短時(shí)能量對(duì)有聲段和無(wú)聲段進(jìn)行判定,以及連字分界等。短時(shí)能量由于是對(duì)信號(hào)進(jìn)行平方運(yùn)算,因而人為增加了高低信號(hào)之間的差距。更重要的的是平方運(yùn)算的結(jié)果很大,容易產(chǎn)生數(shù)據(jù)溢出。解決這些問(wèn)題的簡(jiǎn)單方法是采用短時(shí)平均幅度值來(lái)表示能量的變化。其定義如下:
(1-7)
短時(shí)過(guò)零率是語(yǔ)音信號(hào)時(shí)域分析中最簡(jiǎn)單的一種特征,它指每幀內(nèi)信號(hào)通過(guò)零值的次數(shù),定義如下:
(1-8)
式中,sgn(x)是符號(hào)函數(shù),即
(1-9)
根據(jù)以上定義,清音由于類似于白噪聲,所以過(guò)零率較高。濁音的能量集中于低頻段,所以濁音信號(hào)的短時(shí)過(guò)零率較低。噪聲的短時(shí)過(guò)零率較高,這主要是因?yàn)檎Z(yǔ)音信號(hào)的能量主要集中在較低的頻率范圍內(nèi),而噪聲信號(hào)的能量主要集中于較高的頻段。這樣計(jì)算的短時(shí)過(guò)零率容易受到噪聲干擾。解決這個(gè)問(wèn)題的方法是對(duì)上述定義稍作修改,即設(shè)置一個(gè)門(mén)限T,將過(guò)零率的含義修改為跨過(guò)正負(fù)門(mén)限的次數(shù)。修改后的定義如下式:
(1-10)
這樣計(jì)算的短時(shí)過(guò)零率就有一定的抗干擾能力,即使存在隨機(jī)噪聲,只要它不超過(guò)正負(fù)門(mén)限所構(gòu)成的帶,就不會(huì)產(chǎn)生虛假過(guò)零率。
綜合考慮設(shè)計(jì)需要和系統(tǒng)處理能力,本設(shè)計(jì)采用短時(shí)幅度值和改進(jìn)后的短時(shí)過(guò)零率判斷語(yǔ)音起始和結(jié)束點(diǎn)。分別為短時(shí)幅度和短時(shí)過(guò)零率設(shè)置門(mén)限值。每次識(shí)別前,選定語(yǔ)音段前300ms作為背景噪聲,用以確定這兩個(gè)門(mén)限值,實(shí)現(xiàn)對(duì)背景噪聲的自適應(yīng)。具體的端點(diǎn)檢測(cè)方法如下。
判斷語(yǔ)音起始點(diǎn),要求能夠?yàn)V除突發(fā)性噪聲。突發(fā)性噪聲可以引起短時(shí)能量或過(guò)零率的數(shù)值很高,但是往往不能維持足夠長(zhǎng)的時(shí)間,如門(mén)窗的開(kāi)關(guān),物體的碰撞等引起的噪聲,這些都可以通過(guò)設(shè)定最短時(shí)間門(mén)限來(lái)判別。超過(guò)兩門(mén)限之一或全部,并且持續(xù)時(shí)間超過(guò)有效語(yǔ)音最短時(shí)間門(mén)限,返回最開(kāi)始超過(guò)門(mén)限的時(shí)間點(diǎn),將其標(biāo)記為有效語(yǔ)音起始點(diǎn)。判斷語(yǔ)音結(jié)束點(diǎn),要求不能丟棄連詞中間短暫的有可能被噪聲淹沒(méi)的“寂靜段”。這可以通過(guò)設(shè)定無(wú)聲段最長(zhǎng)時(shí)間門(mén)限來(lái)判別。同時(shí)低于兩門(mén)限,并且持續(xù)時(shí)間超過(guò)無(wú)聲最長(zhǎng)時(shí)間門(mén)限,返回最開(kāi)始低于門(mén)限的時(shí)間點(diǎn),將其標(biāo)記為有效語(yǔ)音結(jié)束點(diǎn)。
圖1.12和圖1.13分別給出了上述算法在一般信噪比和低信噪比情況下的端點(diǎn)檢測(cè)效果。從圖中可以看出上述算法能夠適應(yīng)一般的背景噪聲。在背景噪聲較高時(shí),上述算法無(wú)法準(zhǔn)確判斷語(yǔ)音起始結(jié)束點(diǎn)。但經(jīng)過(guò)試驗(yàn),當(dāng)信噪比低至圖1.13所示時(shí)時(shí)人耳也很難準(zhǔn)確辨識(shí)語(yǔ)音。所以上述算法在實(shí)際使用中能夠滿足端點(diǎn)檢測(cè)的需求。
圖1.11 一般信噪比下的端點(diǎn)檢測(cè)效果
圖1.12 低信噪比下的端點(diǎn)檢測(cè)效果
1.3.4特征提取算法選擇在語(yǔ)音識(shí)別系統(tǒng)中,模擬語(yǔ)音信號(hào)在完成A/D轉(zhuǎn)換后成為數(shù)字信號(hào)。此時(shí)的語(yǔ)音信號(hào)為時(shí)域的信號(hào),時(shí)域的信號(hào)難以進(jìn)行分析和處理,而且數(shù)據(jù)量龐大。通常的做法是對(duì)時(shí)域信號(hào)進(jìn)行變換,提取其中某種特定的參數(shù),通過(guò)一些更加能反映語(yǔ)音本質(zhì)特征的參數(shù)來(lái)進(jìn)行語(yǔ)音識(shí)別。特征提取是識(shí)別過(guò)程中一個(gè)非常重要的環(huán)節(jié),選取的特征直接影響到識(shí)別的結(jié)果。不同的特征對(duì)不同語(yǔ)音的敏感度也不一樣,優(yōu)秀的語(yǔ)音特征應(yīng)該對(duì)不同字音距離較大,而相同字音距離較小。
另外,特征值的數(shù)目也是一個(gè)重要的問(wèn)題。在滿足使用要求的情況下,所使用的特征數(shù)應(yīng)該盡量減少,以減少所涉及的計(jì)算量。但是過(guò)少的特征有可能無(wú)法恰當(dāng)?shù)拿枋鲈颊Z(yǔ)音,以致識(shí)別率下降。語(yǔ)音特征的提取方法是整個(gè)語(yǔ)音識(shí)別的基礎(chǔ),因此受到了廣泛的重視。通過(guò)近幾十年的發(fā)展,目前語(yǔ)音特征的提取方法主要有以下三類:
1.基于線性預(yù)測(cè)分析的提取方法。這一類的典型代表是線性預(yù)測(cè)倒譜系數(shù)LPCC。
2.基于頻譜分析的提取方法。這一類的典型代表是Mel頻率倒譜系數(shù)MFCC。
3.基于其它數(shù)字信號(hào)處理技術(shù)的特征分析方法。如小波分析、時(shí)頻分析、人工神經(jīng)網(wǎng)絡(luò)分析等。
目前的孤立詞語(yǔ)音識(shí)別系統(tǒng)大多采用前兩種語(yǔ)音特征提取方法。在本文中,借鑒前人對(duì)LPCC系數(shù)和MFCC系數(shù)的總結(jié)對(duì)比,采用Mel頻標(biāo)倒譜系數(shù)MFCC。
人類的耳蝸實(shí)質(zhì)上相當(dāng)于一個(gè)濾波器組,耳蝸的濾波作用在1000Hz以下為線性尺度,而1000Hz以上為對(duì)數(shù)尺度,這就使得人耳對(duì)低頻信號(hào)的分辨率高于對(duì)高頻信號(hào)的分辨率。根據(jù)這一特性,研究者根據(jù)心理學(xué)實(shí)驗(yàn)得到了類似于耳蝸?zhàn)饔玫囊唤M濾波器組,這就是Mel頻率濾波器組。Mel頻率可以用如下公式表示:
(1-11)
圖1.13 Mel頻率與實(shí)際頻率的對(duì)應(yīng)關(guān)系
對(duì)頻率軸的不均勻劃分是MFCC特征區(qū)別于普通倒譜特征的最重要特點(diǎn)。將頻率按照式(1-11)和圖1.13變換到Mel域后,Mel帶通濾波器組的中心頻率是按照Mel頻率刻度均勻排列的。在本設(shè)計(jì)中,MFCC倒譜系數(shù)的計(jì)算過(guò)程如下述。
1.對(duì)語(yǔ)音信號(hào)預(yù)加重、分幀、加漢明窗處理,然后進(jìn)行短時(shí)傅里葉變換,得出頻譜。
2.取頻譜平方,得能量譜。并用24個(gè)Mel三角帶通濾波器進(jìn)行濾波;由于每個(gè)頻帶的分量在人耳中是疊加的,因此將每個(gè)濾波器頻帶內(nèi)的能量進(jìn)行疊加,輸出Mel功率譜。
3.對(duì)每個(gè)濾波器的輸出值取對(duì)數(shù),得到相應(yīng)頻帶的對(duì)數(shù)功率譜。然后對(duì)24個(gè)對(duì)數(shù)功率進(jìn)行反離散余弦變換得到12個(gè)MFCC系數(shù),反離散余弦變換如式(1-12),式中M=24,L=12。
(1-12)
在本設(shè)計(jì)中采集語(yǔ)音信號(hào)的抽樣頻率是8000Hz,頻率范圍是0Hz~4000Hz。在此頻率范圍內(nèi)的Mel三角帶通濾波器組如下圖所示:
圖1.14 Mel三角濾波器組
與LPCC參數(shù)相比,MFCC參數(shù)具有以下優(yōu)點(diǎn):
1.語(yǔ)音的信息大多集中在低頻部分,而高頻部分易受環(huán)境噪聲干擾。MFCC參數(shù)將線性頻標(biāo)轉(zhuǎn)化為Mel頻標(biāo)。強(qiáng)調(diào)語(yǔ)音的低頻信息,從而突出了有利于識(shí)別的信息,屏蔽了噪聲的干擾。
2.MFCC參數(shù)沒(méi)有任何前提假設(shè),在各種情況下均可使用。而LPCC參數(shù)需要假定所處理的信號(hào)為AR信號(hào),對(duì)于動(dòng)態(tài)特性較強(qiáng)的輔音,這個(gè)假設(shè)并不是嚴(yán)格成立的。
因此,MFCC參數(shù)的抗噪聲特性是優(yōu)于LPCC參數(shù)的。在本設(shè)計(jì)中,采用的語(yǔ)音特征參數(shù)均為MFCC參數(shù)。
1.3.5特征匹配算法選擇要建立一個(gè)性能良好的語(yǔ)音識(shí)別系統(tǒng)僅有好的語(yǔ)音特征還不夠,還要有適當(dāng)?shù)恼Z(yǔ)音識(shí)別的模型和算法。在現(xiàn)階段,語(yǔ)音識(shí)別的過(guò)程是根據(jù)模式匹配的原則,計(jì)算未知語(yǔ)音模式與語(yǔ)音模板庫(kù)中的每一個(gè)模板的距離測(cè)度,從而得到最佳的匹配模式。目前,語(yǔ)音識(shí)別所應(yīng)用的模型匹配方法主要有動(dòng)態(tài)時(shí)間彎折(DTW:Dynamic Time Warping)、隱馬爾可夫模型(HMM:Hidden Markov Model)和人工神經(jīng)網(wǎng)絡(luò)(ANN:Artificial Neural Networks)等。當(dāng)今孤立詞識(shí)別領(lǐng)域最常用的識(shí)別算法是DTW和HMM。
DTW算法是較早的一種模式匹配和模型訓(xùn)練技術(shù),它應(yīng)用動(dòng)態(tài)規(guī)劃的方法成功解決了語(yǔ)音信號(hào)特征參數(shù)序列比較時(shí)時(shí)長(zhǎng)不等的難題,在孤立詞語(yǔ)音識(shí)別中獲得了良好的性能。DTW算法是建立在動(dòng)態(tài)規(guī)劃(DP:Dynamic Programming)的理論基礎(chǔ)上的。動(dòng)態(tài)規(guī)劃是一個(gè)很有效的方法來(lái)求取一個(gè)問(wèn)題的最佳解。其中心思想簡(jiǎn)單的說(shuō)可以描述為:在一條最佳的路徑上,其中任意一條子路徑也都必須是相關(guān)子問(wèn)題的最佳路徑,否則原路徑就不是最佳路徑。
HMM算法是數(shù)學(xué)上一類重要的雙重隨機(jī)模型,用概率統(tǒng)計(jì)的方法描述時(shí)變語(yǔ)音信號(hào),很好的描述了語(yǔ)音信號(hào)的整體非平穩(wěn)性和局部平穩(wěn)性。HMM的各狀態(tài)對(duì)應(yīng)語(yǔ)音信號(hào)的各平穩(wěn)段,各狀態(tài)之間以一定轉(zhuǎn)移概率相聯(lián)系,是一種較為理想的語(yǔ)音模型。HMM模型屬于統(tǒng)計(jì)語(yǔ)音識(shí)別,適用于大詞匯量、非特定人的語(yǔ)音識(shí)別系統(tǒng)。隨著現(xiàn)代計(jì)算機(jī)技術(shù)的迅猛發(fā)展,計(jì)算機(jī)的運(yùn)算速度迅速提高,隱馬爾科夫模型分析方法也得到了廣泛利用。該算法在識(shí)別階段計(jì)算量較少,適應(yīng)性強(qiáng),但是需要大量的前期訓(xùn)練工作,對(duì)系統(tǒng)資源的要求較多。
用于孤立詞識(shí)別,DTW算法與HMM算法在相同的環(huán)境條件下,識(shí)別效果相差不大,但是HMM算法要復(fù)雜得多,這主要體現(xiàn)在HMM算法在訓(xùn)練階段需要提供大量的語(yǔ)音數(shù)據(jù),通過(guò)反復(fù)計(jì)算才能得到模型參數(shù),而DTW算法的訓(xùn)練中幾乎不需要額外的計(jì)算。所以在孤立詞語(yǔ)音識(shí)別中,DTW算法得到更廣泛的應(yīng)用。
綜合比較DTW算法的工作量小,不需要大量的語(yǔ)音數(shù)據(jù),而且DTW算法適合孤立詞語(yǔ)音識(shí)別,且容易實(shí)現(xiàn),節(jié)省系統(tǒng)資源,比較方便移植到嵌入式系統(tǒng)中。所以本系統(tǒng)選擇DTW算法作為語(yǔ)音識(shí)別的核心算法。下面介紹DTW算法及其實(shí)現(xiàn)方法。
假設(shè)參考模板的特征矢量序列為,輸入語(yǔ)音特征矢量序列為 ,輸入語(yǔ)音特征矢量序列為
。DTW算法就是要尋找一個(gè)最佳的時(shí)間規(guī)整函數(shù),使待測(cè)語(yǔ)音的時(shí)間軸j非線性地映射到參考模板的時(shí)間軸i上,使總的累積失真量最小。
設(shè)時(shí)間規(guī)整函數(shù)為
(1-13)
式中N為匹配路徑長(zhǎng)度, 表示第n個(gè)匹配點(diǎn)是參考模板的第i(n)個(gè)特征矢量與待測(cè)模板的第j(n)個(gè)特征矢量構(gòu)成。兩者之間的距離
稱為局部匹配距離。DTW算法就是通過(guò)局部?jī)?yōu)化的方法實(shí)現(xiàn)匹配距離總和最小。
一般時(shí)間規(guī)整函數(shù)滿足一下約束:
1.單調(diào)性,規(guī)整函數(shù)單調(diào)增加。
2.起點(diǎn)終點(diǎn)約束,起點(diǎn)對(duì)起點(diǎn),終點(diǎn)對(duì)終點(diǎn)。
3.連續(xù)性,不允許跳過(guò)任何一點(diǎn)。
4.最大規(guī)整量不超過(guò)某一極限值。
M為窗寬。規(guī)整函數(shù)所處的區(qū)域位于平行四邊形內(nèi),本設(shè)計(jì)中將平行四邊形的約束區(qū)域端點(diǎn)放寬3點(diǎn)。局部路徑約束,用于限制當(dāng)?shù)趎步時(shí),后幾步存在幾種可能的路徑。本設(shè)計(jì)中DTW規(guī)整區(qū)域和局部路徑如圖1.16、圖1.17所示。
圖1.15 放寬端點(diǎn)限制的DTW規(guī)整區(qū)域
圖1.16 DTW局部路徑
本設(shè)計(jì)中DTW算法計(jì)算步驟:
1.初始化。令i(0)=j(0)=0,i(N)=I,j(N)=J,確定一個(gè)如圖1.16所示的規(guī)整約束區(qū)域Reg。它由一平行四邊形變化而來(lái)。此平行四邊形有兩個(gè)位于(1,1)和(I,J)的頂點(diǎn),相鄰兩條邊的斜率分別為2和1/2。
2.按照如圖1.17所示的路徑遞推求累計(jì)匹配距離。第n步匹配距離如下式
(1-14)
3.累計(jì)匹配距離除匹配步數(shù),得歸一化匹配距離。即輸入特征與特征模板之間的匹配距離。計(jì)算輸入特征與每一特征模板的匹配距離,匹配距離最小的特征模板與輸入特征有最大的相似性。
第二章 系統(tǒng)設(shè)計(jì)2.1硬件設(shè)計(jì)2.1.1 MCU及其最小系統(tǒng)電路設(shè)計(jì)經(jīng)過(guò)第一章的論證,選用意法半導(dǎo)體公司的STM32F103VET6單片機(jī)。
MCU輸入時(shí)鐘由8MHz晶振提供,經(jīng)MCU內(nèi)部PLL倍頻至72MHz。在每一個(gè)電源引腳上并接0.1uF去耦電容,以提高M(jìn)CU電源穩(wěn)定性和抗干擾性。
2.1.2 音頻信號(hào)采集電路設(shè)計(jì)音頻信號(hào)采集電路原理圖如下
圖2.6 音頻信號(hào)采集原理圖
2.1.3 LCD接口電路設(shè)計(jì)本設(shè)計(jì)中顯示器件選用2.4英寸TFT LCD顯示屏,LCD驅(qū)動(dòng)器是ILI9325 。
Thin Film Transistor (薄膜場(chǎng)效應(yīng)晶體管),是指液晶顯示器上的每一液晶象素點(diǎn)都是由集成在其后的薄膜晶體管來(lái)驅(qū)動(dòng)。從而可以做到高速度高亮度高對(duì)比度顯示屏幕信息。
ILI9325 是一個(gè)262144色的單芯片TFT LCD SoC 驅(qū)動(dòng)。 它提供240×320的分辨率, 172,800字節(jié)的圖形數(shù)據(jù)RAM ,并且?guī)в袃?nèi)部電源電路。它與控制器的接口可設(shè)置為16位并口、8位并口、SPI接口。在本設(shè)計(jì)中為了提高顯示數(shù)據(jù)的傳輸速率,采用了STM32F103VET6的FSMC(可變靜態(tài)存儲(chǔ)控制器)的16位并口作為MCU和ILI9325的接口。將ILI9325的數(shù)據(jù)和控制接口映射為外部存儲(chǔ)器。MCU傳送控制命令或顯示數(shù)據(jù)時(shí),自動(dòng)生成相應(yīng)的時(shí)序,避免了傳統(tǒng)上采用IO口模擬時(shí)序,提高了數(shù)據(jù)傳輸效率。
2.2軟件設(shè)計(jì)2.2.1 語(yǔ)音預(yù)處理算法設(shè)計(jì)語(yǔ)音信號(hào)預(yù)處理包括: 語(yǔ)音信號(hào)采集、分幀、數(shù)據(jù)加窗、預(yù)加重。
語(yǔ)音信號(hào)采集就是將外部模擬的語(yǔ)音信號(hào),轉(zhuǎn)換為MCU可處理和識(shí)別的數(shù)字信號(hào)的過(guò)程。在本設(shè)計(jì)中,通過(guò)MCU內(nèi)部的定時(shí)器、模數(shù)轉(zhuǎn)換器以及DMA控制器實(shí)現(xiàn)了對(duì)音頻信號(hào)采集模塊輸入語(yǔ)音信號(hào)的數(shù)字化。其處理流程如下圖所示。
圖2.9 語(yǔ)音信號(hào)數(shù)字化流程圖
在程序中,控制語(yǔ)音信號(hào)采集的函數(shù)如下。
1void record(void)
2{
3 delay_ms(atap_len_t); //延時(shí),規(guī)避點(diǎn)擊屏幕發(fā)出的噪聲
4 TIM_Cmd(TIM1, ENABLE); //開(kāi)啟定時(shí)器,開(kāi)始信號(hào)采集
5 GUI_ClrArea(&(Label[G_ctrl])); //顯示操作提示
6
7 GUI_DispStr(&(Label[G_ctrl]),“錄音中”);
8 delay_ms(atap_len_t); //開(kāi)始說(shuō)話之前,錄制一小段背景聲音,用以實(shí)現(xiàn)背景噪聲自適應(yīng)
9 //提示開(kāi)始說(shuō)話
10 set_label_backclor(&(Label[G_spk]), spk_clor);
11 //等待緩沖區(qū)數(shù)據(jù)更新完畢
12 while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);
13 TIM_Cmd(TIM1, DISABLE); //數(shù)據(jù)采集結(jié)束,關(guān)閉定時(shí)器
14 DMA_ClearFlag(DMA1_FLAG_TC1); //清數(shù)據(jù)傳輸完成標(biāo)志,以備下次使用
15 //提示開(kāi)始處理采集到的數(shù)據(jù)
16 set_label_backclor(&(Label[G_spk]), prc_clor);
17}
分幀就是將采集到的語(yǔ)音數(shù)據(jù)分割成相同長(zhǎng)度的片段,以用于短時(shí)分析。本設(shè)計(jì)中取20ms即160點(diǎn)為一幀,幀移10ms即80點(diǎn)。為了適應(yīng)MCU存儲(chǔ)空間有限的實(shí)際情況,分幀并沒(méi)有被單獨(dú)設(shè)計(jì)和占用單獨(dú)的空間,而是在讀語(yǔ)音數(shù)據(jù)緩沖區(qū)的時(shí)候按照幀長(zhǎng)幀移的順序依次讀取。
由于端點(diǎn)檢測(cè)屬于時(shí)域分析,并不需要加窗和預(yù)加重,所以本設(shè)計(jì)中,分幀和預(yù)加重都加在端點(diǎn)檢測(cè)之后提取MFCC之前。
2.2.2 端點(diǎn)檢測(cè)算法設(shè)計(jì)本設(shè)計(jì)采用短時(shí)幅度和短時(shí)過(guò)零率相結(jié)合的端點(diǎn)檢測(cè)算法。
首先去緩沖區(qū)前300ms作為背景噪聲,提取背景噪聲參數(shù)。用于后續(xù)端點(diǎn)檢測(cè)。背景噪聲參數(shù)由以下結(jié)構(gòu)體定義。
1typedef struct
2{
3 u32 mid_val; //語(yǔ)音段中值 相當(dāng)于有符號(hào)的0值 用于短時(shí)過(guò)零率計(jì)算
4 u16 n_thl; //噪聲閾值,用于短時(shí)過(guò)零率計(jì)算
5 u16 z_thl; //短時(shí)過(guò)零率閾值,超過(guò)此閾值,視為進(jìn)入過(guò)渡段。
6 u32 s_thl; //短時(shí)累加和閾值,超過(guò)此閾值,視為進(jìn)入過(guò)渡段。
7}atap_tag; //自適應(yīng)參數(shù)
提取函數(shù)為void noise_atap(const u16* noise,u16 n_len,atap_tag* atap),其提取過(guò)程如下。
圖2.10 背景噪聲參數(shù)提取流程
然后根據(jù)提取到的短時(shí)過(guò)零率和短時(shí)幅度計(jì)算有效語(yǔ)音起始和結(jié)束點(diǎn)。有效語(yǔ)音端點(diǎn)由以下結(jié)構(gòu)體定義。
1typedef struct
2{
3 u16 *start; //起始點(diǎn)
4 u16 *end; //結(jié)束點(diǎn)
5}valid_tag; //有效語(yǔ)音段
端點(diǎn)檢測(cè)函數(shù)為void VAD(const u16 *vc, u16 buf_len, valid_tag *valid_voice, atap_tag *atap_arg)。其流程圖如下。
圖2.11 端點(diǎn)檢測(cè)流程
2.2.3 特征提取算法設(shè)計(jì)及優(yōu)化本設(shè)計(jì)選用12階MFCC作為語(yǔ)音特征。此步是整個(gè)算法流程中最耗時(shí)也是優(yōu)化空間最大的部分。因此,在程序設(shè)計(jì)中,沿用經(jīng)典算法的同時(shí)做了大量的針對(duì)STM32嵌入式平臺(tái)的優(yōu)化工作。優(yōu)化的中心思想是:盡量少使用或不使用浮點(diǎn)運(yùn)算;使用整型數(shù),其運(yùn)算結(jié)果應(yīng)盡量大以減少舍入噪聲,但必須保證數(shù)據(jù)不會(huì)溢出;空間換時(shí)間。
FFT函數(shù)是u32* fft(s16* dat_buf, u16 buf_len)。它封裝了了ST提供的STM32固件庫(kù)里的void cr4_fft_1024_stm32(void *pssOUT, void *pssIN, u16 Nbin)函數(shù)。cr4_fft_1024_stm32()輸入?yún)?shù)是有符號(hào)數(shù),包括實(shí)數(shù)和虛數(shù),但語(yǔ)音數(shù)據(jù)只包括實(shí)數(shù)部分,虛數(shù)用0填充,fft點(diǎn)數(shù)超出輸入數(shù)據(jù)長(zhǎng)度時(shí),超過(guò)部分用0填充。cr4_fft_1024_stm32()輸出數(shù)據(jù)包括實(shí)數(shù)和虛數(shù),應(yīng)該取其絕對(duì)值,即平方和的根。
語(yǔ)音特征用如下結(jié)構(gòu)體定義。
1typedef struct
2{
3 u16 save_sign; //存儲(chǔ)標(biāo)記 用于判斷flash中特征模板是否有效
4 u16 frm_num; //幀數(shù)
5 s16 mfcc_dat[vv_frm_max*mfcc_num]; //MFCC轉(zhuǎn)換結(jié)果
6}v_ftr_tag;
獲取MFCC的函數(shù)是void get_mfcc(valid_tag *valid, v_ftr_tag *v_ftr, atap_tag *atap_arg)。獲取MFCC的一般步驟在上一章已有論述,在此介紹移植到MCU上需做的優(yōu)化。
預(yù)加重的高通濾波系數(shù)為0.95,如果直接使用,則需要進(jìn)行浮點(diǎn)運(yùn)算,盡量避免,故使用y(n)=x(n)-x(n-1)×95/100。加漢明窗窗函數(shù)值如果每次都要重新計(jì)算,則需要進(jìn)行三角函數(shù)運(yùn)算,耗時(shí)嚴(yán)重,效率低下。但其數(shù)值是一定的,因此事先計(jì)算好160點(diǎn)的漢明窗值。存于數(shù)組中const u16 hamm[],使用時(shí)直接讀取。FFT函數(shù)直接輸入ADC轉(zhuǎn)換過(guò)的值-2048~2047,其輸出頻譜幅值過(guò)小,舍入誤差較大。數(shù)據(jù)輸入前需作放大處理。vc_temp[ i]=(s16)(temp*hamm[ i]/(hamm_top/10));此句代碼在實(shí)現(xiàn)加窗的同時(shí),將語(yǔ)音數(shù)據(jù)放大10倍。Mel三角濾波器的中心頻率和數(shù)值的計(jì)算涉及到對(duì)數(shù)運(yùn)算,不宜直接計(jì)算,也實(shí)現(xiàn)計(jì)算好的數(shù)值存于Flash中,使用時(shí)直接讀取。還有其他的優(yōu)化措施,詳見(jiàn)附件代碼。
void get_mfcc(valid_tag *valid, v_ftr_tag *v_ftr, atap_tag *atap_arg)函數(shù)流程如下。
圖2.12 特征提取流程
2.2.4模板訓(xùn)練算法設(shè)計(jì)
本設(shè)計(jì)模板訓(xùn)練采用冗余模板算法,即每個(gè)語(yǔ)音指令存儲(chǔ)4個(gè)特征模板,識(shí)別時(shí)輸入特征分別與每個(gè)特征模板相比較,匹配距離最小的,就是識(shí)別結(jié)果。這4個(gè)特征模板存儲(chǔ)于MCU Flash后端,模板訓(xùn)練時(shí),將模板存于指定的Flash地址。為了保證保存的特征模板不被擦除或被其他代碼或數(shù)據(jù)占用,需設(shè)置編譯器的地址范圍。
2.2.5特征匹配算法設(shè)計(jì)
本設(shè)計(jì)特征匹配算法采用 DTW(動(dòng)態(tài)時(shí)間彎折)。其原理在上一章已有論述,在此不再贅述。其流程如下。
圖2.13 特征匹配流程
2.2.6顯示界面設(shè)計(jì)本設(shè)計(jì)在觸摸式LCD上實(shí)現(xiàn)了簡(jiǎn)單的GUI操作界面。能夠顯示中英文文本框、按鈕。
最基本元素為GUI_Area,定義如下。
1typedef struct
2{
3 u16 Left; //區(qū)域離屏幕左邊界的距離 像素
4 u16 Top; //區(qū)域離屏幕上邊界的距離 像素
5 u16 Width; //區(qū)域?qū)挾?像素
6 u16 Height; //區(qū)域高度 像素
7 u16 BackColor; //區(qū)域背景色
8 u16 ForeColor; //區(qū)域前景色
9}GUI_Area;
在此基礎(chǔ)上實(shí)現(xiàn)了以下函數(shù)。
1void wait_touch(void); //等待屏幕點(diǎn)擊
2u8 touch_area(GUI_Area *area); //判斷是否點(diǎn)擊指定區(qū)域
3void GUI_HideArea(GUI_Area *Area); //隱藏區(qū)域 顯示屏幕前景色
4void GUI_ClrArea(GUI_Area *Area); //清除區(qū)域 顯示區(qū)域背景色
5void GUI_DispStr(GUI_Area *Area,const u8 *str); //在區(qū)域內(nèi)顯示字符串
6void GUI_printf(GUI_Area *Area,char *fmt, 。。。); //printf函數(shù)在區(qū)域內(nèi)的實(shí)現(xiàn)
配合顯示界面,主函數(shù)流程如下。
圖2.14 主程序流程
第三章 系統(tǒng)制作及調(diào)試結(jié)果3.1系統(tǒng)制作與調(diào)試本系統(tǒng)的制作調(diào)試主要分為Matlab仿真、硬件調(diào)試、軟件調(diào)試。
經(jīng)過(guò)初步的分析設(shè)計(jì)后,Matlab中仿真算法。調(diào)節(jié)算法細(xì)節(jié),直至能夠較好地實(shí)現(xiàn)所需功能,再將其移植到MCU平臺(tái)上。在設(shè)計(jì)制作硬件電路的同時(shí),調(diào)試穿插進(jìn)行,應(yīng)用系統(tǒng)的硬件調(diào)試和軟件調(diào)試是分不開(kāi)的,許多硬件故障是在調(diào)試軟件時(shí)才發(fā)現(xiàn)的。但通常是先排除系統(tǒng)中明顯的硬件故障后才和軟件結(jié)合起來(lái)調(diào)試,如此有利于問(wèn)題的分析和解決,不會(huì)造成問(wèn)題的積累,從而可以節(jié)約大量的調(diào)試時(shí)間。軟件編程中,首先完成單元功能模塊的調(diào)試,然后進(jìn)行系統(tǒng)調(diào)試,整體上采用硬件調(diào)試的調(diào)試方法。
3.2制作與調(diào)試結(jié)果經(jīng)過(guò)制作與調(diào)試,實(shí)現(xiàn)了系統(tǒng)預(yù)設(shè)功能。實(shí)物圖如下。
圖3.1 實(shí)物圖 歡迎界面
圖3.2 實(shí)物圖 模板訓(xùn)練界面
圖3.3 實(shí)物圖 語(yǔ)音識(shí)別界面
結(jié) 論原理樣機(jī)經(jīng)過(guò)設(shè)計(jì)方案論證,設(shè)計(jì)了相應(yīng)的硬件電路和系統(tǒng)軟件,制作了電路原理樣機(jī)并進(jìn)行單機(jī)調(diào)試,結(jié)果表明,所設(shè)計(jì)的電路和軟件能完成基本的測(cè)試功能。
采用STM32F103VET6單片機(jī)構(gòu)建語(yǔ)音識(shí)別系統(tǒng),通過(guò)此系統(tǒng)對(duì)語(yǔ)音信號(hào)進(jìn)行采集、前端放大、AD轉(zhuǎn)換、預(yù)處理、MFCC特征提取、模板訓(xùn)練、DTW特征匹配的一系列步驟,完成孤立詞語(yǔ)音識(shí)別的預(yù)期目標(biāo)。
本設(shè)計(jì)目前也存在一些不足,例如語(yǔ)音信號(hào)采集模塊的動(dòng)態(tài)范圍不足,當(dāng)說(shuō)話聲音較大或較小時(shí),會(huì)出現(xiàn)無(wú)法識(shí)別的現(xiàn)象,需加上自動(dòng)增益控制功能。語(yǔ)音識(shí)別時(shí),錄音控制不方便,最好能夠改進(jìn)為完全通過(guò)語(yǔ)音控制。特征模板僅僅用12階MFCC略顯不足,可添加MFCC一階差分。
參考文獻(xiàn)[1] 韓紀(jì)慶、張磊、鄭鐵然。 語(yǔ)音信號(hào)處理。 北京:清華大學(xué)出版社[M],2004年9月
[2] 董辰輝、彭雪峰。 MATLAB 2008 全程指南。 北京:電子工業(yè)出版社[M],2009年3月
[3] 張雪英。 數(shù)字語(yǔ)音處理及MATLAB仿真。 北京:電子工業(yè)出版社[M],2011年7月
[4] 趙力。 語(yǔ)音信號(hào)處理 第2版。 北京:機(jī)械工業(yè)出版社[M],2011年6月
[5] 陳程。 機(jī)載環(huán)境下的語(yǔ)音識(shí)別技術(shù)及實(shí)現(xiàn)[J]。電子科技大學(xué)碩士學(xué)位論文,2008年5月
[6] 蔣子云。 基于ARM嵌入式孤立詞語(yǔ)音識(shí)別系統(tǒng)研究與實(shí)現(xiàn)[J]。 中南大學(xué)碩士學(xué)位論文, 2009年5月
[7] 白順先。 漢語(yǔ)孤立字語(yǔ)音識(shí)別技術(shù)的研究[J]。 西南交通大學(xué)碩士學(xué)位論文, 2009年6月
[8] 童紅。 孤立詞語(yǔ)音識(shí)別系統(tǒng)的技術(shù)研究[J]。 江蘇大學(xué)碩士學(xué)位論文, 2009年6月
[9] 汪冰。 小詞匯非特定人的孤立詞語(yǔ)音識(shí)別系統(tǒng)的研究與設(shè)計(jì)[J]。 廣東工業(yè)大學(xué)碩士學(xué)位論文, 2008年5月
[10] 黃振華。 孤立詞識(shí)別中的說(shuō)話人歸一化技術(shù)[J]。 上海大學(xué)碩士學(xué)位論文, 2009年1月
開(kāi)源
/********* main.C **********/
#include “includes.h”
#include “VAD.H”
#include “MFCC.H”
#include “DTW.H”
#include “GUI.H”
#include “flash.h”
#include “delay.h”
u16 VcBuf[VcBuf_Len];
atap_tag atap_arg;
valid_tag valid_voice[max_vc_con];
v_ftr_tag ftr;
typedef struct
{
u8 str[3];
}comm_tag;
comm_tag commstr[]={“0 ”,“1 ”,“2 ”,“3 ”,“4 ”,“5 ”,“6 ”,“7 ”,“8 ”,“9 ”,“上”,“下”,“前”,“后”,“左”,“右”,“大”,“小”};
#define sel_clor BRED
#define dis_sel_clor GRED
#define spk_clor BRED
#define prc_clor GRED
#define save_ok 0
#define VAD_fail 1
#define MFCC_fail 2
#define Flash_fail 3
void disp_comm(u8 comm)
{
GUI_ClrArea(&(Label[comm]));
GUI_DispStr(&(Label[comm]),(u8 *)(commstr[comm-G_comm_fst].str));
}
void set_comm_backclor(u8 comm, u16 backclor)
{
Label[comm].BackColor=backclor;
disp_comm(comm);
}
void set_label_backclor(GUI_Area *Label, u16 backclor)
{
Label-》BackColor=backclor;
GUI_ClrArea(Label);
}
void disp_home(void)
{
GUI_ClrArea(&Screen);
GUI_ClrArea(&(Label[G_wel]));
GUI_DispStr(&(Label[G_wel]),“歡迎使用”);
GUI_ClrArea(&(Label[G_neme]));
GUI_DispStr(&(Label[G_neme]),“孤立詞語(yǔ)音識(shí)別測(cè)試系統(tǒng)”);
GUI_ClrArea(&(Label[G_prc]));
GUI_DispStr(&(Label[G_prc]),“模板訓(xùn)練”);
GUI_ClrArea(&(Label[G_recg]));
GUI_DispStr(&(Label[G_recg]),“語(yǔ)音識(shí)別”);
GUI_ClrArea(&(Label[G_designer]));
GUI_DispStr(&(Label[G_designer]),“設(shè)計(jì)者:宋健”);
}
void record(void)
{
delay_ms(atap_len_t); //延時(shí),避免點(diǎn)擊屏幕發(fā)出的噪聲
TIM_Cmd(TIM1, ENABLE); //開(kāi)啟定時(shí)器,開(kāi)始信號(hào)采集
GUI_ClrArea(&(Label[G_ctrl])); //顯示操作提示
GUI_DispStr(&(Label[G_ctrl]),“錄音中”);
//開(kāi)始說(shuō)話之前,錄制一小段背景聲音,用以實(shí)現(xiàn)背景噪聲自適應(yīng)
delay_ms(atap_len_t);
//提示開(kāi)始說(shuō)話
set_label_backclor(&(Label[G_spk]), spk_clor);
//等待緩沖區(qū)數(shù)據(jù)更新完畢
while(DMA_GetFlagStatus(DMA1_FLAG_TC1)==RESET);
//數(shù)據(jù)采集結(jié)束,關(guān)閉定時(shí)器
TIM_Cmd(TIM1, DISABLE);
//清數(shù)據(jù)傳輸完成標(biāo)志,以備下次使用
DMA_ClearFlag(DMA1_FLAG_TC1);
//提示開(kāi)始處理采集到的數(shù)據(jù)
set_label_backclor(&(Label[G_spk]), prc_clor);
}
void disp_mdl_prc(void)
{
u16 i;
GUI_ClrArea(&Screen);
set_label_backclor(&(Label[G_cap]), BRED);
GUI_DispStr(&(Label[G_cap]),“開(kāi)始訓(xùn)練”);
for(i=G_comm_fst;i《=G_comm_lst;i++)
{
disp_comm(i);
}
GUI_ClrArea(&(Label[G_return]));
GUI_DispStr(&(Label[G_return]),“返回”);
}
u8 save_mdl(u16 *v_dat, u32 addr)
{
noise_atap(v_dat,atap_len,&atap_arg);
VAD(v_dat, VcBuf_Len, valid_voice, &atap_arg);
if(valid_voice[0].end==((void *)0))
{
return VAD_fail;
}
get_mfcc(&(valid_voice[0]),&ftr,&atap_arg);
if(ftr.frm_num==0)
{
return MFCC_fail;
}
return save_ftr_mdl(&ftr, addr);
}
void prc(void)
{
u32 i;
u8 prc_start=0;
u8 comm=G_comm_fst;
u8 prc_count=0;
u32 addr;
//v_ftr_tag *sav_ftr;
disp_mdl_prc();
set_comm_backclor(comm,sel_clor);
while(1)
{
wait_touch();
if(touch_area(&(Label[G_return])))
{
Label[G_cap].BackColor=GREEN;
Label[comm].BackColor=dis_sel_clor;
disp_home();
return;
}
else if(touch_area(&(Label[G_cap])))
{
delay_ms(150);
if(prc_start==0)
{
GUI_ClrArea(&(Label[G_cap]));
GUI_DispStr(&(Label[G_cap]),“停止訓(xùn)練”);
prc_start=1;
GUI_ClrArea(&(Label[G_ctrl]));
GUI_DispStr(&(Label[G_ctrl]),“開(kāi)始”);
GUI_ClrArea(&(Label[G_spk]));
GUI_ClrArea(&(Label[G_count]));
GUI_DispStr(&(Label[G_count]),“已訓(xùn)練0次”);
}
else
{
GUI_ClrArea(&(Label[G_cap]));
GUI_DispStr(&(Label[G_cap]),“開(kāi)始訓(xùn)練”);
prc_start=0;
prc_count=0;
GUI_HideArea(&(Label[G_ctrl]));
GUI_HideArea(&(Label[G_spk]));
GUI_HideArea(&(Label[G_stus]));
GUI_HideArea(&(Label[G_count]));
}
}
else if((touch_area(&(Label[G_ctrl])))&&(prc_start==1))
{
record();
GUI_ClrArea(&(Label[G_ctrl]));
GUI_DispStr(&(Label[G_ctrl]),“提取中”);
addr=ftr_start_addr+(comm-G_comm_fst)*size_per_comm+prc_count*size_per_ftr;
if(save_mdl(VcBuf, addr)==save_ok)
{
prc_count++;
GUI_ClrArea(&(Label[G_count]));
GUI_printf(&(Label[G_count]),“已訓(xùn)練%d次”,prc_count);
if(prc_count==ftr_per_comm)
{
prc_count=0;
}
GUI_ClrArea(&(Label[G_stus]));
GUI_DispStr(&(Label[G_stus]),“語(yǔ)音有效”);
/*
sav_ftr=(v_ftr_tag *)addr;
USART1_printf(“mask=%d ”,sav_ftr-》save_sign);
USART1_printf(“frm_num=%d”,sav_ftr-》frm_num);
for(i=0;i《((sav_ftr-》frm_num)*mfcc_num);i++)
{
USART1_printf(“%d,”,sav_ftr-》mfcc_dat[i]);
}
*/
}
else
{
GUI_ClrArea(&(Label[G_stus]));
GUI_DispStr(&(Label[G_stus]),“語(yǔ)音無(wú)效”);
}
GUI_ClrArea(&(Label[G_ctrl]));
GUI_DispStr(&(Label[G_ctrl]),“開(kāi)始”);
}
else if(prc_start==0)
{
for(i=G_comm_fst;i《=G_comm_lst;i++)
{
if(touch_area(&(Label[i])))
{
set_comm_backclor(comm,dis_sel_clor);
comm=i;
set_comm_backclor(comm,sel_clor);
break;
}
}
}
}
}
u8* spch_recg(u16 *v_dat, u32 *mtch_dis)
{
u16 i;
u32 ftr_addr;
u32 min_dis;
u16 min_comm;
u32 cur_dis;
v_ftr_tag *ftr_mdl;
noise_atap(v_dat, atap_len, &atap_arg);
VAD(v_dat, VcBuf_Len, valid_voice, &atap_arg);
if(valid_voice[0].end==((void *)0))
{
*mtch_dis=dis_err;
USART1_printf(“VAD fail ”);
return (void *)0;
}
get_mfcc(&(valid_voice[0]),&ftr,&atap_arg);
if(ftr.frm_num==0)
{
*mtch_dis=dis_err;
USART1_printf(“MFCC fail ”);
return (void *)0;
}
i=0;
min_comm=0;
min_dis=dis_max;
for(ftr_addr=ftr_start_addr; ftr_addr《ftr_end_addr; ftr_addr+=“size_per_ftr)
{
ftr_mdl=(v_ftr_tag*)ftr_addr;
//USART1_printf(”save_mask=%d “,ftr_mdl-》save_sign);
cur_dis=((ftr_mdl-》save_sign)==save_mask)?dtw(&ftr,ftr_mdl):dis_err;
//USART1_printf(”cur_dis=%d “,cur_dis);
if(cur_dis《min_dis)
{
min_dis=cur_dis;
min_comm=i;
}
i++;
}
min_comm/=ftr_per_comm;
//USART1_printf(”recg end “);
*mtch_dis=min_dis;
return (commstr[min_comm].str);
}
void disp_recg(void)
{
GUI_ClrArea(&Screen);
GUI_ClrArea(&(Label[G_cap]));
GUI_DispStr(&(Label[G_cap]),”語(yǔ)音識(shí)別“);
GUI_ClrArea(&(Label[G_ctrl]));
GUI_DispStr(&(Label[G_ctrl]),”開(kāi)始“);
GUI_ClrArea(&(Label[G_spk]));
GUI_ClrArea(&(Label[G_return]));
GUI_DispStr(&(Label[G_return]),”返回“);
}
void recg(void)
{
u8 *res;
u32 dis;
u32 recg_count=0;
disp_recg();
while(1)
{
wait_touch();
if(touch_area(&(Label[G_return])))
{
disp_home();
return;
}
else if(touch_area(&(Label[G_ctrl])))
{
record();
GUI_ClrArea(&(Label[G_ctrl]));
GUI_DispStr(&(Label[G_ctrl]),”識(shí)別中“);
res=spch_recg(VcBuf, &dis);
if(dis!=dis_err)
{
recg_count++;
GUI_ClrArea(&(Label[G_recg_res]));
GUI_printf(&(Label[G_recg_res]),”識(shí)別結(jié)果:%s“,(s8 *)res);
GUI_ClrArea(&(Label[G_mtch_dis]));
GUI_printf(&(Label[G_mtch_dis]),”匹配距離:%d“,dis);
GUI_ClrArea(&(Label[G_stus]));
GUI_DispStr(&(Label[G_stus]),”語(yǔ)音有效“);
GUI_ClrArea(&(Label[G_count]));
GUI_printf(&(Label[G_count]),”已識(shí)別%d次“,recg_count);
}
else
{
GUI_HideArea(&(Label[G_recg_res]));
GUI_HideArea(&(Label[G_mtch_dis]));
GUI_ClrArea(&(Label[G_stus]));
GUI_DispStr(&(Label[G_stus]),”語(yǔ)音無(wú)效“);
}
GUI_ClrArea(&(Label[G_ctrl]));
GUI_DispStr(&(Label[G_ctrl]),”開(kāi)始“);
}
}
}
int main(void)
{
BSP_Init();
USART1_printf(”SYS Init OK!“);
USART1_printf(”CPU Speed:%ld MHz“, BSP_CPU_ClkFreq() / 1000000L);
disp_home();
while(1)
{
wait_touch();
if(touch_area(&(Label[G_prc])))
{
prc();
}
else if(touch_area(&(Label[G_recg])))
{
recg();
}
}
}
評(píng)論