内容
汇亚网电子商务开发服务有限公司 技术主管
2002 年 11 月
序言
在这个教程中我们将使用IBM 的 Websphere Voice Toolkit 完成一个中文语音应用程序。在您使用这个教程之前,首先要在您的电脑上安装由 IBM 提供开发所需的WebSphere Voice Server SDK及一个集成开发环境,也就是本教程标题上所说的 Voice Toolkit。Websphere Voice Server SDK 中提供了中文语音库以及用于我们在开发中测试时使用的 WebSphere Voice Server。这两个软件包您可以通过这个网址下载:www-4.ibm.com/software/speech/enterprise/ep_11.html
在开始教程之前,我希望您对VoiceXML中出现的元素已经有大致的了解,以便您可以理解在本教程代码中出现的符号含义。如果你在这之前,已经对VoiceXML有所了解但对其如何实现没有一个直观的体验。我相信本教程中的程序将会打消您对这种语言在开发中文语音应用程序中的许多疑问。
我们创建的是一个语音快餐店的应用程序,顾客可以通过这个VoiceXML语音应用程序完成快餐食品的定购。那你会问了现在的电话自动应答系统也可以做到相应的服务功能,我们为什么还需要开发VoiceXML语音应用程序呢。在这个程序中最直观的体会到VoiceXML应用程序与传统的电话应答系统的不同之处在于,传统的电话应答系统通常是通过DTMF 来发出指令的。而基于VoiceXML的语音应用程序可以通过非特定人的语音发送相关的指令。所以使用VoiceXML技术开发的语音应用程序相对于传统的语音应用程序在用户界面方面有了质的飞跃。在教程后面的语音程序测试中您会有更深刻的体验。
开发前的软件设置
在第一次使用 Websphere Voice Toolkit 开发中文语音应用程序之前,我们还需要做几件事,首先,请先运行WebSphere Voice Server SDK中的Audio Setup - Simplified Chinese,这个程序的作用是检测你麦克风灵敏度及你周围环境中的噪声是否符合开发环境的最低要求。如果通过了这个测试您在开发测试的时候语音录入就可以正确识别您的口语指令了,其实对于VoiceXML这种应用了非特定人语音识别技术的应用程序对于环境噪声的要求相对于哪些语音输入软件来说是相当低的了。
图1、语音开发环境测试
其次,也是您开发的语音应用程序是否可以在测试环境中正确的发出中文TTS语音。启动 Voice Toolkit 然后选择菜单 Window =>Preferences ,在打开的参数选项Voice Toolkit 中的 Voice Language 一栏选为Simplified Chinese。如果您在同一个软件中开发其他的语言版本请将此项改为相应的语种,以便系统可以正确的输出 TTS语音。
图2 、更改发音语言
创建一个Voice项目
现在我们正式开始创建中文语音应用程序,首先是创建一个Voice Project 。在这个工程项目中我们可以创建以下几种文件:
VoiceXML:在这个文件中我们将创建用于语音应用程序的输入输出及相关的事件处理。
Grammar :在这类文件中建立语音识别的语法。如:JSGF Grammar File 、SRCL Grammar File。
Pronunciation :在这类文件中建立单词的发音标准。如:Pronunciation Pool File 、Pronunciation exception dictionary 。
Voice Toolkit为以上类型的文件提供了相应的编辑器及测试环境。
1.选择 File = > New = > Voice Project
2.在项目窗口内的 Project name 中输入您将创建的项目名称,本教程中的名称为 chinesevoice
3.点击 Finish 完成创建工作
图3 、创建Voice Toolkit项目
创建一个 VoiceXML 文件
在这个教程中我们将建立一个 VoiceXML文件,在这个文件中我们将实现VoiceXML语言输入和输出及基本的事件处理。首先我们来创建一个VoiceXML文件:
1、选择 File = > New = > VoiceXML File
2、在New VoiceXML File窗口内的VoiceXML file name 中输入您将创建的文件名称,本教程中的名称为welcome.vxml
3、选择 Finish 完成创建工作
图4、创建一个VoiceXML文件
现在您可以在VoiceXML编辑器中编写您的语音应用程序了
图5、VoiceXML 文件编辑器
我们先来看一下我们创建的语音快餐店应用程序中VoiceXML文件这部分使用的代码
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE vxml PUBLIC "vxml" "">
<vxml version="1.0">
<noinput>对不起 我什么都听不到</noinput>
<nomatch>我没听清 请您在重复一遍</nomatch>
<form id="welcome">
<grammar src="food.jsgf" type="application/x-jsgf"/>
<block>欢迎您访问 语音服务 快餐店</block>
<field name="foodkind">
<prompt>您是要中式快餐 还是要西式快餐</prompt>
<filled>
<if cond="foodkind == '中式'">
<goto nextitem="chinesefood"/>
<elseif cond="foodkind =='西式'"/>
<goto nextitem="westfood"/>
</if>
</filled>
</field>
<field name="chinesefood">
<prompt>我们这里有包子 饺子 豆腐脑 油条 炸糕 还有面条 你想吃那种呀</prompt>
<filled>
<if cond="chinesefood =='包子'">
<goto nextitem="exit"/>
<elseif cond="chinesefood =='饺子'"/>
<goto nextitem="exit"/>
<elseif cond="chinesefood == '豆腐脑'"/>
<goto nextitem="exit"/>
<elseif cond="chinesefood == '油条'"/>
<goto nextitem="exit"/>
<elseif cond="chinesefood == '炸糕'"/>
<goto nextitem="exit"/>
<elseif cond="chinesefood == '面条'"/>
<goto nextitem="exit"/>
</if>
</filled>
</field>
<field name="westfood">
<prompt>我们这里有汉堡包 薯条 派 你想吃那种呀</prompt>
<filled>
<if cond="westfood == '汉堡包'">
<goto nextitem="exit"/>
<elseif cond="westfood =='薯条'"/>
<goto nextitem="exit"/>
<elseif cond="westfood == '派'"/>
<goto nextitem="exit"/>
</if>
</filled>
</field>
<block name="exit">
您的订单已经被确认 欢迎您 再次光顾
<exit/>
</block>
</form>
</vxml>
事件处理元素
在VoiceXML的文件中我们首先在代码的开头加入了事件处理元素
<noinput>对不起 我什么都听不到</noinput>
<nomatch>我没听清 请您在重复一遍</nomatch>
<noinput>的作用是在于用户长时间没有发出指令,语音服务程序将发出相应的提示提醒用户,在这个程序里系统会发出“对不起,我什么都听不到”的提示语音。
<nomatch>的作用是在于当用户的语音指令没有和程序预先设定的值相匹配的时候发出相应的提示用户,在这个程序里系统会发出“我没听清,请您在重复一遍”的提示音。
口语语法元素
在这个VoiceXML文件中我们使用了外部口语语法调用
<grammar src="food.jsgf" type="application/x-jsgf"/>
VoiceXML的中的grammar元素是设定可能的口语语音输入,如果输入的设定值被识别则会返回一个字符串值。设定的语法可以是从外部文件那里下载或直接插入的用户定义的语法,也可以是内置的语法。grammar元素提供了6种内置的语法类型。包括:boolean、data、digits、currency、number和phone。 grammar元素中的 src属性的值是包含一个口语语法文件的URL。我们制定了一个food.jsgf作为本语音程序调用的外部口语语法文件。如何创建food.jsgf这个JSGF口语语法文件我将在后面的章节予以介绍。grammar的type属性是指语法的格式。
对话框
在这个VoiceXML文件中我们定义了一个窗体 也就是form元素 所有的发生在这个语音应用程序中的输入和输出都被封装在这个窗体中。
<form id="welcome">
......
</form>
form元素中的 id属性是用于标示窗体。在这个VoiceXML文件中我们给窗体设置的属性值为welcome。设置的这个id属性的值可以在goto 、submit等元素从另一个对话框导航到这个窗体时使用。
窗体项
在这个VoiceXML文件中我们使用了block这个元素
<block>欢迎您访问 语音服务 快餐店</block>
.......
<block name="exit">
您的订单已经被确认 欢迎您 再次光顾
<exit/>
</block>
block元素是一个窗体项,它封装的语句可以对变量的值进行输出、浏览、声明等。在我们的VoiceXML文件中的block元素中使用了 name 这个属性,并为其取值为exit 这个值可以被引用代码块的goto之类的其他元素调用。
在这个VoiceXML文件中我们还使用了另一个十分重要的窗体项,它与接收用户的输入有关这就是field元素。
<field name="chinesefood">
........
</field>
field元素用于接收来自用户的语音识别信息或是DTMF信息。在这个VoiceXML文件中我们建立的语音应用程序将接收来自用户的语音指令信息。如:当系统发出要吃中式的快餐还是西式快餐的询问时,用户可能会发出相应的语音指令 。field元素的name属性是用来存放用户的输入信息的变量。上段代码中我们设置的name属性的变量值为chinesefood ,这与我们在后面教程中的编写的JSGF语法中的<chinesefood>相同。
条件逻辑 与 转移
在这个VoiceXML文件中我们使用了 if和elseif 这两个条件逻辑元素以及 goto 这个转移元素,请看下面的代码。
<if cond="foodkind == '中式'">
<goto nextitem="chinesefood"/>
<elseif cond="foodkind =='西式'"/>
<goto nextitem="westfood"/>
</if>
if和elseif这两个元素可以用于条件逻辑,大家要记住else总是封装在if元素中。一个if 元素可以包括多个elseif元素。cond属性是个表达式,它的值可以计算为true,也可以计算为flase。如果在if 元素中发现一个cond属性的值计算为flase,那莫将计算下一个elseif cond的表达式。在我们创建的VoiceXML语音应用程序中,当回答为“西式”这条语音指令的时候 <elseif connd="foodkind == '西式’"/> 中的cond属性为true的时候。程序调用 goto 这个转移元素, nextitem属性的作用在于,当goto元素用于从窗体中的一个项目导航到另一个项目将会用到这个属性。
建立一个口语语法文件
现在准备建立一个JSGF口语语法文件。JSGF是Java Speech Grammar Format的缩写。它是一个独立于平台的用于口语识别的语法格式。
1、选择 File = > New = > JSGF Grammar File
2、在New JSFG Grammear File窗口内的JSGF grammar file name 中输入您将创建的文件名称,本教程中的名称为food.jsgf
3、选择 Finish 完成创建工作
图6、创建一个JSGF语法文件
现在您可以通过 JSGF语法编辑器编写你的口语语法文件了。
图7、JSGF语法文件编译器
我们先来看一下我们创建的语音快餐店应用程序中JSGF文件这部分使用的代码
#JSGF V1.0;
grammar food;
public <food> = <foodkind>{ this.foodkind = $ }
| <chinesefood> { this.chinesefood = $}
| <westfood> { this.westfood = $} ;
<foodkind> = 中式 | 西式 ;
<chinesefood> = 饺子 | 包子 | 面条| 豆腐脑 | 油条| 煎饼| 炸糕 ;
<westfood> = 汉堡包| 薯条| 派 ;
JSGF的文件结构比较的简单,主要有文件头及中间的语法主体部分组成。在代码中出现的 | 符号的含义代表语法判断选择。如:<westfood> = 汉堡包 | 薯条 | 派
当我们完成了口语语法文件的编写后,可以通过Voice Toolkit提供的Grammar Test Tool进行相应的口语语法测试。这个测试工具提供了语音及文本形势的测试,经过这里的口语语音测试后的JSGF Grammar文件,可以让我们提前了解语音应用程序识别口语语言及发音的能力,以便减少后期整个语音应用程序测试的难度。
图8、语法测试工具
整体测试
到这里我们已经完成了我们语音快餐店中使用的全部代码,下面我们正式开始整个的VoiceXML语音应用程序的测试工作。首先,激活welcome.vxml这个编辑器窗体,然后选择 Run => Run in Audio Mode 这时候我们启动了 VoiceXML的语音测试模式。(Voice Toolkit 提供了对于 VoiceXML的4种测试模式, 分别为 Run in Audio mode 、Run in Text mode 、Debug in Audio mode 、Debug in Text mode。 我推荐您在测试VoiceXML应用程序的时候选择Debug测试模式,这样便于跟踪整个VoiceXML语音应用程序的过程以便及时做出代码的调整。)
语音快餐店应用程序对会实例
SHOP:"欢迎您访问语音服务快餐店"
SHOP:"您是要中式快餐 还是要西式快餐"
USER:"中式"
SHOP:"我们这里有包子 饺子 豆腐脑 油条 炸糕 还有面条 你想吃那种呀"
USER:"包子"
SHOP:"您的订单已经被确认 欢迎您再次光顾"
上面这段对话来自测试过程,如果您在VoiceXML语音应用程序测试过程中进行了与上面这段对话相类似的对话过程,并且听到了电脑发出的“你的订单已经确认 欢迎您再次光顾”的时候,我现在要向您祝贺,您已经成功的完成了这个基于VoiceXML技术的中文语音应用程序的开发工作了。