分享

DIY: 实现自己的中文语音应用

 icecity1306 2018-02-24
强晟 和 刘盈
2008 年 10 月 28 日发布

语音技术

微软公司董事长比尔盖茨曾不止一次的提出,语音技术将越来越多得改变我们的生活。新一代的搜索引擎也将使用语音最为最终的输入手段;电脑键盘的作用将逐步减少,今后人们使用电脑时将不再是通过键盘输入文字,而是用语音来输入文字。

不可否认的是,如今的语音技术还未达到如他所述的成熟程度。但是一些简单的应用,例如语音拨号的功能已经被大家所接受。基于语音技术的自动应答系统在欧美已然流行开来,帮助像银行,移动运营商这样的大型服务性机构搭建无人电话语音服务,以此减少接线员的工作量,给大家的生活带来便利。

VXML 简介

Voice eXtensible Markup Language(简称 VXML)是被用来创建语音对话系统,可以调用语音合成以及语音识别服务,可以用来记录语音录入和连接电话系统。创建 VXML 语音的主要目的就是用 Web 开发的理念来开发交互式的语音应用。VXML 提供了基于 Menu 和基于 Form 的两套框架,整合了语音识别和语音合成两个关键服务,使得语音应用的开发变得更为方便和快捷。

VXML 的运行环境

VXML 和普通的标记语言一样,需要有浏览器进行解析;还需要提供语音识别和语音合成服务的应用服务器;有时也需要有 http 服务器提供文档服务;当然,如果需要与电话系统相连,就必须加上 VOIP (网络电话)的支持。如下图所示的就是 VXML 的运行环境:

图 1. VXML 运行环境
图 1. VXML 运行环境

一个企业级应用的系统框架

IVR (interactive voice-response services) 也就是自动应答服务,是使用 VXML 的典型企业级应用。IVR 和使用者通过电话,按键 (DTMF) 互动,如语音订票,语音查询,语音投票等。普通的 IVR 都是支持 VXML 的解析和提供了 sip 协议的支持,通过和 ASR ( 语音识别 ) 应用服务器以及 TTS( 语音合成 ) 应用服务器的集成,可以实现几乎所有的 VXML 封装的操作。

企业级的 VXML 应用需要如下的体系结构,以使用 IBM Voice Server (WVS) 为例:

图 2. 一个 VXML 具体应用的例子
图 2. 一个 VXML 具体应用的例子

点击查看大图

上图中的 IVR 事实上就是 VXML 解析器,通过解析 VXML,分发相应的工作给 WVS ,实现 VXML 封装的语音识别和语音合成的功能。

两个开源的实验环境

尝试 VXML,可以使用开源的项目 OpenVXI (见参考资源) 。OpenVXI 提供的是完整的 VXML 解析服务,同时也提供了有限语言的 TTS 支持。虽然暂时来看, OpenVXI 没有提供 ASR 的实现,但是 OpenVXI 提供了方便的回调函数的接口,因此可以很方便的嵌入外部 ASR 和 TTS 的服务。

尝试 VXML ,另一个选择是使用一个名为 Tadpole (见参考资源) 的 Firefox 浏览器上的开源插件。通过 Tadpole 的帮助, Firefox 平台因此具有 VXML 解析浏览器的功能。此架构的缺点是只支持 XHTML-Voice 标记语言,这个语言只能说是 VXML 语言的一个子集。

搭建自己的 VXML 中文应用 

从一个简单的例子开始

清单 1. 一个典型的 VXML 的例子
<?xml version="1.0" encoding="UTF-8" ?>
  
<vxml version="2.0" xml:lang="zh-CN" xmlns="http://www./2001/vxml">
  <meta name="GENERATOR" content="Voice demo"/>
  
<form id="head">
       <block>
               请问您需要何种服务?
               <audio src="BEEP.WAV"/>
               <goto next="#main"/> 
       </block>
</form>
  
<menu id="main">
  <choice next="menu_1.jsp">
  开空调
  </choice>
<choice dtmf="1" next="menu_1.vxml"/>
  
<choice next="menu_2.jsp ">
  开洗澡水                 
  </choice>
  <choice dtmf="2" next="menu_2.vxml"/>
  
  <choice next="menu_3.jsp">
  打开音响
  </choice>
  <choice dtmf="3" next="menu_3.vxml"/>
  
<catch event="noinput" count="1">
  <prompt> 请问您需要何种服务? <audio src="BEEP.WAV"/> </prompt>
  </catch>
  
  <catch event="noinput" count="2">
  <submit next="menu_whole.vxml"/>
  </catch>
  
  <catch event="nomatch">
       <prompt> 对不起,我没有听清,请再重复一遍。 <audio src="BEEP.WAV"/> </prompt>
  </catch>
  
</menu>
</vxml>

上述 VXML 是一个很简单的例子。我们可以看到,事实上 VXML 文件和普通的 html 文件并没有实质的不同,我们可以完全使用相同的思维方式去理解,唯一不同的是针对特殊的语音 VXML 应用了相应特别的标签,具体可以参考 w3 上有关 VXML 的规范(详见参考资源)。

上面的例子,<block/> 标签是用来描述语音播放的属性,也就是需要使用语音合成的语句(直接输入词句可以得到语音输出),该标签也可包含需要播放的录音,可以使用 <audio/> 标签。<menu/> 标签就像 html 中的 <select/> 标签,只是将输入变成了语音,也就是,<choice/> 标签中指定的语句是可以被识别的,根据识别的结果,可以跳转到 <goto/> 标签中指定的 VXML 并继续执行。 <catch/> 标签也是很好理解的,它能接受并处理无输入超时和无法识别语音这两个事件。

综合起来看上面的例子,我们可以看出这是一个 VXML 最典型的应用,即根据语音输入,确定使用者需要的服务。把该 VXML 应用到电话系统中,就是现今应用最多的用语音技术替代接线员工作的模式。我们也可以理解为,用说话命令的方式,代替了普通电话服务热线那种按键的方式。

一个更深入的例子,与 java 层的交互

清单 2. 传递参数到 jsp 的例子(menu_3.vxml+playAudio.jsp)
menu_3.vxml:
<?xml version="1.0" encoding="UTF-8" ?>     
<vxml version="2.0" xml:lang="zh-CN" xmlns="http://www./2001/vxml">
  
<form id="head">
<block>
  请问你要播放那首歌曲?
  <audio src="BEEP.WAV"/>
  <goto next="#playsong"/> 
  </block>
</form>
  
<form id="playsong">
  <field name="song">
  <grammar type="application/srgs" src="songs.gram"/>
  <option dtmf="9" value="back"> 后退 </option>
  <filled>
  <if cond="songs == 'back'">
  <submit next="menu_whole.vxml"/>
  <submit next="playAudio.jsp" namelist="song"/> 
  </filled>
  </field> 
</form>
</vxml>
  
  
playAudio.jsp:
<?xml version="1.0" encoding="UTF-8" ?>            
<vxml version="2.0" xml:lang="zh-CN" xmlns="http://www./2001/vxml">
  
<%@page contentType="application/voicexml+xml; charset=UTF-8" %>
<%@page import="com.ibm.com.AudioPlayer"%>
  
<vxml version="2.0" xmlns="http://www./2001/vxml"
xmlns:xsi="http://www./2001/XMLSchema-instance"
xsi:schemaLocation="http://www./2001/vxml http://www./TR/voicexml20/vxml.xsd">
  
<%
       // Get the utterance from the html form
       request.setCharacterEncoding("UTF-8");
       String song = (String)request.getParameter("song");
       
       AudioPlayer audioPlayer = new AudioPlayer();
       audioPlayer.play(song);
%>
  
</vxml>

menu_3.vxml 是一个简化的略去错误处理的例子,我们也使用另一种常用的框架 <form/> 。该框架需要给定语音识别的期望结果,也就是 grammar 文件,然后进行语音匹配,得到识别结果。而 grammar 文件如 songs.gram ,可以简单得这样实现:

清单 3. 一个 grammar 的例子(songs.gram)
#ABNF 1.0 UTF-8;

language zh-CN;
mode voice;
root $songs;

public $songs= 北京欢迎你 | 我和你 | 为生命喝彩 ;

grammar 可以有 abnf 和 xml 两种格式,具体可以参考 w3 上关于 grammar 的规范(见参考资源)。事实上,menu_whole.vxml 中 <choice/> 标签就可以看成是一个可以自动生成的 grammar。使用 VXML 外部的 grammar 可以很方便加入新的可以被识别的结果。并且由于 grammar 支持类似正则表达式的构造方式,所以 grammar 可以很方便得构造一些规则驱动的识别结果集合,这个很大程度上减轻了应用开发人员在枚举识别结果时的工作量。

在 menu_3.vxml 和 playAudio.jsp 中,我们可以看到,通过 submit 的 namelist 属性,系统可以很方便的把识别结果传输给 java 层,利用 java 层强大的功能,可以实现很多操作。上面的例子只是一个很简单的播放歌曲的例子,假设如果在 java 层实现了所有的电器控制接口,那完全用语音控制电器这只在科幻电影中出现的应用,将成为现实。

搭建中文 VXML 系统的注意点

对于中文系统而言,首先,必须要保证语音识别引擎是完全支持中文的。其次,对于所有的 VXML,jsp 以及 grammar 文件,必须要按照统一的 UTF-8 的编码方式,并且在 jsp 层,需要对 request 对象设置编码方式。在这点上,中文的语音应用和普通的 web 应用是一致的。

结束语

使用 VXML 可以很方便得搭建中文的语音应用。虽然说现如今,语音识别技术还存在识别率的问题,并且也没有很完善的开源的语音识别引擎。但是,一些部分支持 VXML 的开源的解决方案已经出现,相信在不久的将来,技术将更加成熟,也将越来越普遍化。我相信,在科幻电影中才能看到的语音控制家电将会因此成为趋势。

参考资源

  • 访问OpenVXI 来查看 OpenVXI 的项目介绍。OpenVXI 提供的是完整的 VXML 解析服务,同时也提供了有限语言的 TTS 支持。(OpenVXI德语项目link:www.
  • 这是一个介绍使用Tadpole 的实例文章。过 Tadpole 的帮助, Firefox 平台因此具有 VXML 解析浏览器的功能。
  • 参考w3 上有关 VXML 的规范,学习写作 VXML。
  • 参考w3 上关于 grammar 的规范,学习学做 grammar 文件。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约