单片机语音识别程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
最近想做语音识别玩玩,网上查了查,找到一个用Atmega32实现的语音识别机械车
地址是:/e ... h8_css34/index.html 貌似是利用带通滤波取得频谱(或者叫功率谱?),看不太懂.我决定用DFT 算法,因为它节约内存
DFT程序借借鉴了 hendry 单片机 DTMF 软解码算法的实现
/forum.php?m ... &highlight=dtmf
//--------------------------------------------------
//DFT运算
//注意,ad是有符号数,无符号的AD值需减128
//返回值为1表示已经计算了功率谱
//--------------------------------------------------
U8 dft(S8 ad)
{
U8 i;
U8 offset;//查表指针
U32 temp;
//ad-=128;//去直流分量
for(i=0;i { offset=tabp;//取查表指针 s_dft_image += (S16)ad * sintab[offset];//>>8; offset+=PI2/4;//偏移1/4周期为cos表 s_dft_real += (S16)ad * sintab[offset];//>>8;//cos表 tabp+=tabinc;//指针下移 } s_dft_p ++; if (s_dft_p == NSAMP) //采样点已达到设定值,计算功率 { s_dft_p = 0; //点数清0 for (i = 0; i < NFREQ; i ++)//每个频点计算功率 { s_dft_real/=NSAMP*6; //除以合适的值能使得功率在一字节内 s_dft_image/=NSAMP*6; temp=s_dft_real*s_dft_real + s_dft_image*s_dft_image; if(temp>65535)temp=65535; s_dft_real = sqrt16(temp); //s_dft_real = sqrt32(((s_dft_real*s_dft_real) + (s_dft_image*s_dft_image))); } return 1; } return 0; } 本程序流程大概是这样: 定时读取ADC,计算5个频率点的实部与虚部,采集64点后计算5个频率点的功率,称之为功率谱 当功率值达到一定值后,认为是一帧语音开始,此后计算的34次功率谱分别存入数组中. 若是在训练状态,则将这34个功率谱存入模板数组,训练完毕后进入识别状态. 在识别状态下,用这34个功率谱去与模板匹配,找出误差最小的,若误差小于一定值,则识别成功. 目前程序只识别两个命令,识别率还不太理想,偶尔会有误码. 如果把模板存进EEPROM,则可以增加命令的个数. 程序量较小,占用内存也小,可以很方便的移植到AVR单片机. 电路用了AGC,就是把2SK30A当作可变电阻,GS间负电压越大,DS间电阻越大. 据说可以用发光二极管+光敏电阻来做AGC. 初步的实验也可以用电脑音频输出串联电容到ADC输入口,至少这样每次放出来的声音是一样的,便于验证 频谱计算是否正确. 附件中有一个用VB写的查看波形的程序,只需通过串口向它发送数据就行了,格式是0xAA+数据字节数+数据 识别结果.jpg里每行最后一个字节是结果,为0表示未能识别,前10行是对命令1的识别,后10行是对命令2的识别 语音识别电路.jpg(250.7 KB, 下载次数: 4) 1和2的频谱.jpg(164.77 KB, 下载次数: 1)编译结果.jpg(31.53 KB, 下载次数: 0) 多波形显示4.rar 55.31 KB, 下载次数: 17 语音识别程序.rar 51.5 KB, 下载次数: 21