语音识别组件转化为控件的方法

2012-03-28 01:52夏俊杰杨青赵刚
电子设计工程 2012年14期
关键词:控件调用引擎

夏俊杰,杨青,赵刚

(1.四川大学四川成都610064;2.成都中医药大学四川成都611130)

在设计问诊系统时,使用Authorware开发工具进行开发,并且使用语音识别技术模拟医生问的过程。语音识别采用微软的语音开发包。微软语音开发包中语音识别引擎是以COM为基础构成的组件[1],但在Authorware中不能直接调用,而Authorware中使用控件是非常方便的。因此将语音识别接口编写成控件的形式,然后在Authorware中调用。这样就避免了编写语音识别的程序,减少编程的代码量,提高开发效率。文中就以语音识别组件为例来说明如何将COM组件转化成控件。

1 语音识别控件设计流程

COM组件和控件有一定的相似之处,都是基于COM原理[2]。COM组件和ActiveX控件都是模块程序供其它程序调用。如图1所示,COM组件的数据成员和控件中的方法类似;消息和事件类似。对于控件中的属性则可能与组件中数据成员和函数成员都相关,需根据情况而定。它们之间可以相互转化。

图1 COM组件和activex控件的对比Fig.1 Comparison of COMcomponent and ActiveX control

语音识别组件转化成控件的流程如图2所示。由于组件接口比较多,调用起来不方便,因此先将组件接口封装成一个C++类,这样只要调用C++的几个函数成员和数据成员就能调用引擎接口,使用比较方便。然后用VC设计一个语音识别控件。通过调用C++类的函数成员、数据成员和消息,在控件中添加相应的属性、方法和事件。对于控件中的方法可以调用类中的函数成员。对于控件中的事件可类中的消息关联起来。这样就可完成语音识别控件的设计。

图2 设计流程Fig.2 Process of designing

2 设计语音识别引擎接口封装类

SAPI的语音识别引擎SR提供了语音识别功能的一系列函数,封装在多个接口中。实现语音识别功能,主要使用ISpRecognizer、ISpRecoContext、ISpRecoGrammer等接口。Isp-Recognizer主要用于语音识别,将语音信号识别转换成文本信息。IspRecoContext主要用于发送和接受消息。IspRecoGrammer主要用于加载语法规则。实现语音识别步骤为[3]:

1)初始化COM

2)建立IspRecognizer对象,通常建立COM对象有2种方法,一种是使用COM库函数建立对象,使用CoCreateInstance()函数。另一种是使用智能指针建立COM对象,这种方法较常用。以建立IspRecognizer对象为例来说明。使用CcomPtr<IspRecognizer>m_pReco建立一个智能指针对象m_pReco,然后CcomPtr类中CoCreateInstance()函数创建IspRecognizer对象,即m_pReco.CoCreateInstance(…),然后就可使用m_pReco指针调用IspRecognizer接口中函数了。

3)创建IspRecoContext对象,设置消息的发送和接受。通过IspRecoContex接口中的SetNotifyWindowMessage()函数将消息传递到指定的窗口。并且调用其中的SetInterest()函数指定需要的某类特定消息。

4)建立IspRecoGrammer对象,加载语法规则。用Load Dictation()函数设置语音输入方式进行识别。

5)调用IspRecognizer接口函数,比如停止识别、暂停识别、语音训练、麦克风设置等。

为了调用方便,将语音识别接口写成一个类CMyReco,类中包括了语音识别接口的所有功能。

class CMyReco{

……

BOOL Initialize(HWND hWnd=NULL,BOOL bIsShared=TRUE);//初始化函数

BOOL Start();//开始识别

BOOL Stop();//停止识别

//获取识别出的文本

void GetRecoText(WCHAR**ppszCoMemText,ULONG ulStart=0,ULONG nlCount=-1);

CComPtr<ISpRecognizer>m_pREng;//创建智能指针

CComPtr<ISpRecoContext>m_pRecoCtxt;//创建智能指针

CComPtr<ISpRecoGrammar>m_pDictationGrammar;//创建智能指针

}

初始化函数将各种对象接口都建立了。初始化后就可以调用其他的如暂停、开始等函数。

3 语音识别控件制作

控件一般有方法、属性和事件3个组成成分[4]。将语音识别接口函数中的开始、停止、麦克风设置等函数作为控件中的方法;而识别出来的文本作为控件的属性;通知用户已产生文本的消息作为控件中的事件。下面说明制作语音识别控件的步骤:

1)利用VC++工具建立一个控件工程SREngine,将上面的CMyReco类文件加入到控件工程中。

2)初始化语音识别引擎

在CSREngineCtrl中添加WM_CREATE消息类型的消息响应函数OnCreate()。在该函数中实现语音识别初始化。

int CSREngineCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct){

……..

m_SpeechReco.Initialize(this->GetSafeHwnd());

…….

}

其中m_SpeechReco是类CMyReco的对象。

3)添加方法

实现停止语音识别、开始语音识别、麦克风设置、是否语音识别引擎等功能可以使用控件的方法实现。例如,用类向导向程序代码中添加方法SpStart。在CSREngineCtrl类的函数SpStart()中调用类CMyReco的Start()函数即可。在外部拖过要开始语音识别引擎,就可调用SpStart方法实现。其他功能的设计和开始语音识别功能的设计一样。

4)添加属性

为了获取识别的结果,在控件中添加一个属性用来保存识别出的文本。用类向导添加属性SRtext,同时添加了GetSRtext()和SetSRtext()两个函数。当外部程序读属性时,调用GetSRtext()函数。当设置属性是调用SetSRtext()函数。因此,在GetSRtext函数中添加获取语音识别结果的代码。

BSTR CSREngineCtrl::GetSRtext(){

CString strResult;strResult=m_strText;

return strResult.AllocSysString();

}

其中m_strText是一个CString类的对象,保存语音识别引擎识别出来的字符串。对SetSRText函数不需加代码。

5)添加事件

为了知道什么时候产生了识别出的文字,需要添加事件。用类向导添加事件SRResult,并且在CSREngineCtrl类中产生了FireSRResult()函数。在控件内部调用FireSRResult()函数,FireSRResult()函数调用FireEvent函数,从而对外部产生SRResult事件。另外当产生识别的文本时,语音识别引擎通过CMyReco类中自定义的消息WM_SREVENT进行通知。因此在CSREngineCtrl类中添加WM_SREVENT消息对应的消息响应函数OnSREvent()。在该函数中获取识别出的文本,并调用FireSRResult()函数。

LRESULT CSREngineCtrl::OnSREvent(WPARAM,LPARAM){

WCHAR*pwzText;

m_SpeechReco.GetRecoText(&pwzText);

m_strText=CString(pwzText);

FireSRResult();

……

}

这样当有文本被识别出来后,保存在m_strText中。然后调用FireSRResult()函数产生SRResult事件通知外部程序有识别出的文本,外部程序根据事件获取SRtext属性值,就可以获取语音识别出来的文本。

最后编译生成控件SREngine.ocx,那么在其他开发工具中就可调用了。

4 自定义语音识别控件运行效果

在Authorware中,使用“插入”菜单插入SREng控件。使用GetSpriteProperty()函数获取SRtext属性值,即获取从语音中识别出的文本。用CallSprite函数设置语音识别控件的开始、暂停等功能[5]。用一个交互图标进行对SRResult事件的响应,并对事件进行处理,即获取SRtext属性值,并显示在文本框中。最后界面如图3所示,输入语音即可识别输出文本。

图3 语音识别控件测试Fig.3 Test of speech recognition control test

5 结束语

文中介绍了COM组件和ActiveX控件的转化方法。通过一个语音识别的例子详细说明转化流程和方法。先将语音识别引擎接口封装成一个C++类,这是方便对语音引擎接口的调用。然后添加控件的属性、方法和事件设计控件。在控件方法和事件中,对类的函数成员或数据成员进行相应调用。最后,将控件在Authorware中运行得到较好效果。对于Authorware这样的专用开发工具可以利用COM与其他应用程序进行通信[6-7],也可提高开发效率。

[1] Microsoft Corporation.Microsoft Speech SDK[EB/OL].(2009-3-3)[2012-4-20].http://download.microsoft.com/download/B/4/3/B4314928-7B71-4336-9DE7-6FA4CF00B 7B3/sapi.chm.

[2] 潘爱民.COM原理与应用[M].北京:清华大学出版社,1999.

[3] 史俊.语音数控机床的研究与实现[D].沈阳:沈阳航空工业学院,2007.

[4] 孙鑫,余安萍.VC++深入详解[M].北京:电子工业出版社,2006.

[5] 孙伟.Authorware与Activex控件的高级通讯[J].集宁师专学报,2009,31(4):57-60.SUN Wei.A senior communication of authorware to the ActiveX control[J].Journal of Jining Teachers College,2009,31(4):57-60.

[6] 郑楠,徐良贤.COM组件技术在多媒体软件开发中的应用[J].计算机工程,2002,28(10):81-83.ZHENG Nan,XU Liang-xian.The application of COMin the development of mutimedia software[J].Computer Engineering,2002,28(10):81-83.

[7] Szyperski C.Component Software Beyond Object-oriented Programming[M].ACMPress,1998.

猜你喜欢
控件调用引擎
核电项目物项调用管理的应用研究
LabWindows/CVI下基于ActiveX技术的Excel调用
关于.net控件数组的探讨
蓝谷: “涉蓝”新引擎
基于系统调用的恶意软件检测技术研究
无形的引擎
基于Cocos2d引擎的PuzzleGame开发
ASP.NET服务器端验证控件的使用
利用RFC技术实现SAP系统接口通信
基于嵌入式MINIGUI控件子类化技术的深入研究与应用