以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 XML在语音技术中的应用 』   (http://bbs.xml.org.cn/list.asp?boardid=47)
----  openvxi使用简单例子求助  (http://bbs.xml.org.cn/dispbbs.asp?boardid=47&rootid=&id=61488)


--  作者:佛间花
--  发布时间:4/17/2008 4:57:00 PM

--  openvxi使用简单例子求助
现在我想用openvxi解析vxml文档,假如我希望在a.vxml中有:按键1转到b.vxml,按键2转到c.vxml,谁能给出这个a.vxml文档?我在看voicexml2.0规范的时候有点晕,看的几个例子都是要求语音输入的。
还有,因为没有条件,希望那个按键输入可以是键盘输入,如果这样的话,我需要修改openvxi的哪部分代码?如果是rec部分,那具体的地方是哪?希望各位高手给出回答,多谢。
--  作者:zlei12
--  发布时间:4/19/2008 12:04:00 PM

--  
<menu id = "mainmemu_in_a.vxml">
 <prompt>
  中文请按1,英文请按2
 </prompt>
 <choice dtmf = "1" next = "b.vxml#menu_b" />
 <choice dtmf = "2" next = "c.vxml#menu_c" />
</menu>
注意,如果不指定menu_b,仅写b.vxml指的是转到b.vxml中的一个Form/Menu。一般的,指定具体Form/Menu名可读性更佳。

模拟测试请修改osbrec.cpp中的OSBrecRecognize()方法。由于该接口同时支持ASR输入,其输出参数VXIrecRecognitionResult结构有一定复杂度。最新版是否是该cpp文件,请自行确认。


--  作者:佛间花
--  发布时间:4/23/2008 11:14:00 AM

--  
多谢!
--  作者:佛间花
--  发布时间:4/29/2008 9:35:00 PM

--  
zlei12大哥,能给我解释一下OSBrecRecognize()方法中的几个变量的意义吗?比如value,input等,我在用getdtmf函数收码的时候传递进来的参数是什么类型?传递给那个变量?
--  作者:zlei12
--  发布时间:4/30/2008 7:53:00 PM

--  
由于代码被修改了,故无法直接给出原示例中各变量的具体含义。下面就作为输出参数的VXIrecRecognitionResult结构进行解释,并说明如何将收号/识别结果返回解释器。请参见VXIrec.h中的struct VXIrecRecognitionResult的定义。

1) status是识别结果码:
    REC_STATUS_SUCCESS表示识别成功;
    REC_STATUS_FAILURE表示没有匹配的识别结果,对应vxml脚本的nomatch事件;
    REC_STATUS_TIMEOUT表示超时没有输入(指按键或说话),对应noinput事件;
    REC_STATUS_DISCONNECT表示识别过程中主叫方挂机了;
    REC_STATUS_ERROR表示识别中处理了错误。
2) mode表示本次识别的模式:
    REC_INPUT_MODE_DTMF表示仅支持收号;
    REC_INPUT_MODE_SPEECH表示仅支持语音输入;
    REC_INPUT_MODE_DTMF_SPEECH,表示支持混合输入。
    每次输入的模式可以在vxml中通过<property>指定。
3) waveform表示识别的原始语音流,我在实现没有用它(设为NULL)。
4) results表示识别结果,对于语音识别的n-best我理解不深。目前,只是返回一个最佳结果,而没有返回多个可能结果然后再通过vxml脚本请用户进一步选择。如果是DTMF输入,那肯定只有一个结果。
      result有三层数据结构。最外层是一个数组(VXIVector),目前我实现中该数组总是一个元素(Element)。该元素是一个map类型,需要返回5对<name,value>:
1> 第一对的name是REC_GRAMMAR, 值是一个OSBrecGrammar的指针,指向一个本次识别匹配的语法结构;
2> 第二对的name是REC_RAW,值又是一个数组(VXIVector);目前我在该数组中也只有一个元素,即识别结果的字符串;
3> 第三对的name是REC_KEYS,值也又是一个数组(VXIVector);目前我在该数组中也只有一个元素,即常量L"best_answer";应该是保留了原示例代码,顺便请注意宽字符问题;
4>第四 对的name是REC_VALUES,值也又是一个数组(VXIVector);目前我在该数组中也只有一个元素,即识别结果的字符串。到底REC_RAW还是REC_VALUES在起作用没有测试,目前实现中两者内容一样;
5>第五对的name是REC_CONF,表示识别概率,因为没有返回多个结果,任意0-1间的float均可。值也又是一个数组(VXIVector);目前我在该数组中也只有一个元素,保留了原示例代码中的0.95F。
5) Destroy,需要设置一个函数指针,用于解释器释放该结构的内存。函数原型是void RecognitionResultDestroy(VXIrecRecognitionResult **Result),实现中需要删除三处内存:
1> 如果waveform不为NULL, 用VXIContentDestroy释放;
2> 用VXIVectorDestroy释放results这个VXIVector;
3> 删除VXIrecRecognitionResult结构本身。

Enjoy~~~


--  作者:佛间花
--  发布时间:5/5/2008 4:52:00 PM

--  
zlei12大哥,我想问一下,我在vxml文档中使用了record标签,其具体使用是这样的:
<record name="msg" beep="true" maxtime="10s" finalsilence="4000ms" type="audio/x-wav">
我想问一下这几个参数 比如name,maxtime,type等都传递给了openvxi中的哪几个参数?
我看到VXIrecRecord这个函数共有三个参数,为VXIrecInterface *pThis, const VXIMap *props,和 VXIrecRecordResult **recordResult,这三个参数中的哪一个或几个包涵了传递进来的参数?又是在何处被调用?如果我要扩充Rocord函数,应该将语音卡的录音函数的API置于何处?
--  作者:zlei12
--  发布时间:5/5/2008 7:08:00 PM

--  
参数通过const VXIMap *props传送,这是一个map结构,例如:
VXIInteger* pDtmfTerm = (VXIInteger*)VXIMapGetProperty(properties, REC_TERMINATED_ON_DTMF);
其中:
1) REC_TERMINATED_ON_DTMF表示是否按键可以打断录音,dtmfterm属性;
2) REC_TIMEOUT_COMPLETE表示多长的静音时间表示录音结束,finalsilence属性;
3) REC_MAX_RECORDING_TIME表示maxtime属性;
4) REC_RECORD_MIME_TYPE表示type属性。

理论上,可以在OSBrecRecord()中实现录音卡的录音API; 但是仅适用于一个解释线程的情况。如果是服务器端程序,需要考虑整个程序的体系架构。例如,Dialogic API可以异步调用性能更好,另外应避免多线程同步问题。

见谅匆匆,以后有时间再展开。


--  作者:佛间花
--  发布时间:5/6/2008 4:05:00 PM

--  
zlei12大哥,我想知道我应该如何获得name或者type等信息?比如我可以如此获得maxtime:
const VXIValue* val = VXIMapGetProperty(props, REC_MAX_RECORDING_TIME);
maxtime = VXIIntegerValue(reinterpret_cast<const VXIInteger *>(val));
但是我不知道该如何获得name、type等信息,请指教。
--  作者:zlei12
--  发布时间:5/6/2008 7:05:00 PM

--  
VXIString* pRecType = (VXIString*)VXIMapGetProperty(properties, REC_RECORD_MIME_TYPE);  // type
VXIInteger* pMaxTime = (VXIInteger*)VXIMapGetProperty(properties, REC_MAX_RECORDING_TIME); // maxtime
VXIInteger* pFinalSilence = (VXIInteger*)VXIMapGetProperty(properties, REC_TIMEOUT_COMPLETE); // final silence

name我未获取,故不清楚。另外,name相当于vmxl中的javascript变量,一般的不需要在实现中获取。


--  作者:佛间花
--  发布时间:5/6/2008 11:08:00 PM

--  
zlei12大哥,估计是版本不同,我的和你的用法不同,我在强制类型转换后无法取得VXIString类的value,我直接用int a=pRecType->GetLength();的时候他告诉我使用了未定义的类VXIString。但对于VXIInteger类型的值我都可以使用ValueBasic.cpp文件中定义的VXIIntegerValue()函数来获得value,但是改文件中却没有定义VXIStringValue();所以无法获取。我自己定义的时候还是出现错误,使用了未定义的类。

另name不是rocord标签中的name来传递的么?录音文件的名称不就是那个名称吗?为什么说他不需要在实现中获取?我用的声卡的api中函数的参数就有录音文件的名称,这和那个record标签的名称是同一个吗?


--  作者:zlei12
--  发布时间:5/7/2008 7:16:00 PM

--  
由于新版本我未下载,故无法确定问题所在, :-(

我贴的代码是在老版本的实现中正式使用的;一般的,基本数据结构一定会考虑向下兼容问题,故请考虑include文件等编译环境问题。

关于name示意vxml脚本片断如下:
<record name = "voicemail"
            type = "audio/vox"
            beep = "true"
            maxtime = "120s"
            dtmfterm = "true"
            finalsilence = "5000ms">
            <prompt>在听到提示音后留言</prompt>
</record>
...
<prompt>
       您的录音为 <value expr = "voicemail" />
</prompt>
注意,name名voicemail可以通过<prompt>回放;我将此方法用于请客户确认,通过菜单选择保存或是重新留言。这是规范定义的方式,规范并没有要求name是录音文件名。关于录音文件名问题,我个人的选择是自定义了一个<object>对象来保存语音文件。如果你选择在<record>中实现也是可以的。我是采用Dialogic或Wave API来录音的,录的均是语音流,故情况有所不同。不论何种情况这是一个实现问题,vxml规范本身没有特别的规定。

建议写一个枚举所有VXIMap内容的帮助类,然后将OpenVXI的参数全打印出来,:-)


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
5,736.328ms