加载中…
正文 字体大小:

基于Stm32,LD3320的非特定语音识别USB HID Keyboard实现

(2013-12-23 21:01:29)
标签:

stm32

ld3320

语音识别

usb

hid

分类: 电子科技

基于Stm32,LD3320的非特定语音识别USB HID Keyboard实现

………用声音跟机器沟通

    鉴于手头拥有一块ST官方的stm32f407VG discover板子以及一块ICRoute公司的LD3320语音识别芯片,因此总在琢磨利用这两块板子来捣鼓个什么东西,以打发无聊的周末。当然,这些东西绝对是跟工作毫无关系的,完全用于业余时间的技术储备以及打发无趣的空闲时间。

    随后,便决定基于这两块板子完成一个声控的PC USB Keyboard,这是一个非常有趣的玩意,因为这样,你就可以用声音跟没有感情的机器进行沟通了,简单来讲,你可以释放你的双手,无需敲击键盘便可以控制我们的电脑。这仅仅是一个demo,仅仅用于我的学习,因此整个工程使用的是Cortex-M4内核的stm32作为主控,并且移植uCOS-III操作系统作为任务管理,移植了USB作为HID标准设备。声控PC或许并没有市场也对于你不感兴趣,那么基于同样的原理,你可以用于声控小车,声控机器人,声控手机等等这些玩意。这篇文章以及这个demo可以作为你类似作品的参考和借鉴甚至是你吐槽的对象。当然,如果你是桂林电子科技大学的学弟或者学妹,若有兴趣用于你的作品,那么作为学长可以给你免费提供完整的源码工程,甚至是非工作时间的技术支持。

       首先,花两分钟看一下demo的视频演示:

    http://v.youku.com/v_show/id_XNjUyMDg3OTI0.html

在这个视频中,我首先跟系统进行了简单的人机对话,然后再使用声音命令使其打开USB HID,使其在PC上虚拟成为一个标准的HID Keyboard,然后使用声音控制PC进行一系列的操作,包括打开程序,切换程序,关闭程序等,最后做了一个流程实例,使用MCU中固化的一段代码完成在word中输入“just by launcher”字样并进行字体大小的调节,颜色切换,中文输入等。

下面是整个系统框图:

基于Stm32,LD3320的非特定语音识别USB <wbr>HID <wbr>Keyboard实现

实际上,整个系统的工作流程也非常的简单:LD3320检测语音输入并对语音进行识别,有识别结果则向MCU申请中断,MCU中断读取出识别结果,启动相应的识别任务,进行相关的操作。

    下面预览一下实物图:

基于Stm32,LD3320的非特定语音识别USB <wbr>HID <wbr>Keyboard实现

LD3320ICRoute公司生产的一款非特定语音识别芯片,它内置有非特定语音识别的DSP算法,支持动态添加50条识别指令,无需外挂其它辅助器件,单一芯片即可完成语音识别,并且直接支持mp3数据的语音播放。当然它需要一颗MCU与其通信来写入识别短语,以及需要播放音频时,写入音频数据,通信方式可选择并行方式或者串行SPI方式。这里我们的MCU选择SPI与其通信,SPI通信占用IO口少,传输速度快,实际上SPI因为是同步时钟传输,最快传输速率是可以达到10M的,但此款芯片ICRute官方说明最快支持1.5MSPI,实际上,已经足够用,本程序中SPI速度设为1M效果较好。需要特别注意的是,如果MCULD3320是使用杜邦线连接的话,强烈建议杜邦线要剥开来,以避免传输信号线间的串扰,导致寄存器读写失败!

所谓的非特定语音识别,指的是该语音识别不针对特定音色音调的人,不需要对其进行语音训练,即使是不同年龄不同性别的人,只要说出同一个拼音的词语,那么它就能够识别,识别准确率高达95%。现在语音识别应用方面也很广,例如智能手机、智能电视等,高富帅应该熟知的iphone 4S里面就有与手机对话的功能。最近非常流行的乐视S60超级电视遥控器中一样拥有语音控制的功能,不过我只在其功能演示的视频中看到,并没有实际用过,不过我想基于互联网的条件下,绝大多数语音识别都是使用云端完成,也就是客户端所要做的事情就是将语音采集然后数据原封不动传输到云端,云端服务器完成对该语音的识别处理然后再返回识别结果到客户端,例如现在Goggle搜索中的语音输入功能。云端识别的优点在于识别准确度可以做到非常高,但是缺点一样很明显,离线状态下无法完成语音识别。此demo中用到的LD3320自带识别算法,如果相对云端识别存在一定的差距自然是可以理解的。

       要使用这款芯片无需到处找资料了,ICRoute在其官网上已经提供了详细完整的pdf文档,以及两个示例程序,示例程序可以看成是提供了驱动代码,详情可以登陆,并且在使用该芯片的过程中遇到的技术问题也可以直接邮件咨询。在开发过程中,我就曾发过邮件发起过咨询,虽然我用的模块并非他们的官方模块,但他们都非常热情的及时给予了回复。前面已经提到,该芯片既可以完成语音的识别,也可以用来播放mp3音频。由于两个功能会用到芯片很多的公用资源,因此在两种模式下切换的时候切记需要完整的进行一次初始化操作。

语音识别的初始化主要分为四个步骤:

1. 通用初始化(包括PLL,模拟电路等),通用初始化就是语音识别以及语音播放都适用的初始化。LD3320内部集成PLL,根据时钟频率正确配置PLL是语音识别ADC采样和语音播放DA输出的保证,不过非常方便的是,我们只需要修改下面代码中的CLK_IN这个宏定义即可

PLL.png

2. 初始化ASR一些参数,这参数主要包括设置语音检测的灵敏度、起始语音的时间、背景噪音时间,灵敏度并不是越高越好,灵敏度越高误触发的可能性越大,因此要根据实际环境设置一个合适的值。起始语音时间为当芯片检测到多长的语音时决策为一次真正的语音开始,背景噪音时间为当芯片检测到语音多久没有输入之后判断为语音的结束。

灵敏度等配置.png

3.      写入识别短语

写入识别短语.png

例如我这是我的工程中写入的识别短语,每一个识别短语都包含一个短语ID,短语通过拼音直接写入即可。例如程序启动识别之后,我说出关闭窗口这个短语,那么芯片会识别到然后产生中断,返回该短语的IDID_GuanBi,那么MCU中就可以根据ID知道我说的是什么命令,然后再根据该命令执行相应的操作即可。并且为了提高识别的准确度,还可以设置垃圾词语,垃圾词语实际上跟普通短语是一样的。上面的程序中我将关闭窗口设为垃圾短语,假如不这么设置,那么有可能出现的情况是,我说出关闭,那么语音识别对存储的短语进行匹配打分,那么关闭窗口这条短语可能就会被打80分,其它已经没有比他分高的了,那么自然选返回匹配高分的短语IDID_GuanBi,这就造成了误识别。设置 垃圾短语之后,关闭这个短语存在,那么它的匹配得分很可能是99分,那么自然就会返回设置的ID49,这样就相当于滤去了混淆的词语。

当然,还可以设置不同的短语为同一个ID,例如视频中我的口令确定回车实际上都是同一个效果:按下键盘上的回车键。因为它们拥有同一个ID

虽然,LD3320最多只支持50条短语,但是它是可以动态改变的,在不同的语音模式下可以动态的修改不同的识别短语,也可以使得同一短语在不同模式下做不同的操作。例如视频中,我第一次说“你好”,它是用英文回答我的,当我使用“能说中文吗”这个命令使其切换到中文模式时,第二次说“你好”,它便用中文来回答我了。因此我认为50条短语的约束实际上还是可以满足很多场合的应用的。

4.      启动语音识别

打开MIC输入,启动AD采样,激活DSP,启动ASR模块

启动语音识别.png

以上的四个步骤便是一次语音识别的代码,详细的代码可以参考ICRoute提供的官方代码。当然,官方代码中每一次语音识别都需要重复进行以上的四个步骤,实际上,假如你的模块一直工作在语音识别功能,并且没有复位的状态下,只需要每次启动识别都执行一次步骤4就可以了,这样可以节约不少时间,提高语音识别的响应速度。可以发现,在我的视频中,启动USB HID之后的操作,系统没有再返回声音,那就是我已经将LD3320锁定在语音识别功能了,不再做功能切换,以提高响应速度。

MP3语音播放为以下三个步骤

1.      调用通用的初始化,与语音识别的一样,只是PLL的设置寄存器不同

2.      设置内部反馈,设置内部增益,启动为MP3模块,激活DSP,设置输出音量等

启动为mp3模块.png

3.      向模块写入mp3数据。

只要不断的往LD3320送入mp3数据,LD3320就能直接播出,这里的MP3数据为一个数组的形式,并且直接存储在MCU的内部flash中,此款MCU拥有1Mflash,即使在我移植μCOS之后,仍然足够我放几个语音数据进行挥霍。当然MCU放不下的可以存放在外部存储介质上。

如何得到MP3音频,需要将MP3转换成什么数据才能给芯片播放,这点官方文档都未提及到,经过尝试,终于得到一个比较合适的方案。

(1)    使用Balabolka软件将需要的文字转换成mp3语音

文字转语音.png

这个软件完全免费,调用系统自带的SAPI即可将文字转换成mp3音频,系统默认有中文的Lili和英文的AnnaLili可以念中文和英文,但是Anna只认识英文。从视频中听到的声音来看,英语念的还是非常标准的,吧。

选项/音档” 中设置生成的音频格式为16K16bit格式

音档.png

接着选择菜单文件/保存音档” 即可将文字转成.mp3格式的音频。

(2)    使用winhex打开生成的mp3文件

winhex打开mp3.png

在数据的起始:“右键/选块开始”

块开始.png

在数据的末端:“右键/选块结尾”

块结尾.png

在数据中间任意地方: 右键/编辑”

选编辑.png

然后出现的菜单中: 复制选块/C源码”

选C源码.png

这样,找个txt文档,粘贴,就得到一个数组格式的数据了

txt粘贴.png

(3)    将得到的数据放到程序中,加入const关键字,就可以存放在MCU中的flash中,随着程序一起下载到芯片中。需要播放语音时,就将这个数组的数据不断的送入LD3320即可。实际上,LD3320是带有一段FIFO的,数据是一段段的送入芯片中,如果数据不够用了,LD3320会跟MCU申请中断,索要播放数据。这里,我使用查询法送入数据

mp3送数据.png

主控芯片采用的stm32F407VGT6,该款芯片带1M flash192K RAM。在该芯片上移植μCOS-III操作系统,作为任务的管理和调度。μCOS-IIImicrium公司的第三代微控制器系统,与大家熟知的μCOS-II稍有不同,不应该看成是其升级版,而是一个全新的操作系统。μCOS-II在国内外被广泛应用于各类产品,其安全性、稳定性得到了美国航天局的认证,基本已经无可挑剔。新出的μCOS-III在国内应该还没有公司在产品上使用,因为它还在申请各项认证的过程中,安全稳定性仍然有顾虑,不过我相信,拿到证书是它迟早的事情,并且现有的μCOS-II已经足够使用,至少5年内,应该不会有公司会考虑用III替换II在产品上的。micrium官方网站已经提供了各个厂家芯片的移植例程,我们要弄到我们的目标板上,需要做的工作实际上不多。μCOS-III还有一个很有特色的地方就是,micrium开发了一个上位机软件,可以实时的检测各个任务的运行状态以及堆栈使用情况,这似乎是μCOS-III特有的福利,而这些完全可以不用在你的目标代码上加入任何监测程序,只要一个Jlink作为读取工具就可以了。

ucprobe.png

上面是我实际任务的运行时捕捉到的一个瞬态状况,可以从上面显而易见的看到CPU的使用率,各个任务当前的状态,以及各个任务堆栈使用情况。使用操作系统往往最难发现的致命错误便是堆栈的溢出,使用这个软件便可以 方便的观察各个任务堆栈实际使用情况,然后再重新分配一个合适大小的堆栈。我曾经尝试过试图将某一个任务的堆栈分配值与实际运行值相当,该软件检测时,便使用红色的进度条警告了该危险情况,这确实一个非常棒的调试软件。

Task ASR:就是我的语音识别任务,该任务由中断发送信号量,也就是在检测到语音输入并且正确执行之后才会执行该任务,否则该任务处于挂起状态

ASR任务.png

Task MP3:是语音播放任务,该任务等待的是ASR任务发送过来的信号量,也就是视频中,MCU判断我说了什么话,然后给我对应什么样的回答

MP3.png

Task USBInit:是USB初始化任务,也就是启动USB HID的时候才会激活,该任务等待的同样是ASR任务发送的信号量。当ASR任务判断我说的是启动USB”时,便向Task USBInit发送信号量,Task USBInit马上进入就绪状态,在无其它优先级更高的任务时,便执行USB初始化

USB初始化任务.png

Task_Keyboard:是向PC机发送键盘报文的任务,该任务同样由ASR任务触发,当ASR任务检测到PC机的控制语音时,便向Task_Keyboard发送信号量,使其发送对应的报文,模拟按键敲击的指令

keyboard任务.png

使用操作系统的好处就是,各个任务之间都是一个独立的无限循环体,可以方便的加入扩展功能。就如同我们可以方便的在系统上装入各种软件一样。使得整个系统的结构框架明朗易于维护和再开发。

USB 方面,ST官方也提供了USB驱动库,无论是主机、设备,都提供了完善的驱动程序,以及一些例程,例如USB mouseJoyTick等,不过很遗憾官方没有提供Keyboard的例程,不过在USB mouse上修改成为一个Keyboard是轻而易举的事情,只需要修改其描述符的一些参数,然后根据键盘的报文规则发送数据给PC即可。作为一个标准的USB HID Keyboard,它在任何电脑上都是可以无需驱动的,具有通用性。

既然MCU都已经变成一个Keyboard了,那么只要键盘能完成的一切操作,MCU都可完成,并且PC上的所有操作也都是可以通过键盘了完成的,这样一个基于LD3320stm32的声控USB Keyboard就已经完成了,理论上,可以通过声音控制电脑的任何操作。

在去年的12月份,我完成了一个2.4G无线游戏遥控器的作品,当时接收端,我同样是将stm32虚拟成一个keyboard,不过走的并不是USB协议,而是旧的PS2协议,这样我就需要一个PS2USB的设备,如果那个作品使用USB来虚拟Keyboard那将会更加的完美,在今年的10月,我特无聊买了一个北通的游戏手柄回来玩,发现体现效果跟我去年做的还是非常相似的,甚至在玩极品飞车时,使用氮气加速的操作也是一样。还真是一个比较有趣的东西。

我虽然试图将整个系统描述清楚,但是作为一个极其内向的青年,仍旧显得力不从心,或许阅读过后你仍旧有些疑问,你可以联系我的邮箱我们共同探讨一下 fpga@live.cn . 当然,是非工作时间。

                                             just by launcher@live.cn 2013.12.23

PDF文档,请移步至此处下载

0

阅读 评论 收藏 转载 喜欢 打印举报
已投稿到:
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有