|
|
////////////////////////////////////////////////////////4 L- p9 |" X. L
//1,生成动态连接库时,要#define USE_SPEECH_DLL,
4 }- _3 ?, ]; u: S9 W// 并且#define LANE_SPEECH_EXPORTS
; v" o Z, h% A8 u/ K+ x' G! n, v//2,使用动态连接库时,要#define USE_SPEECH_DLL, C. O( t- \$ B2 W) g. D
//3,声称和使用静态连接库时,什么都不需要3 Y. T. k# h4 {* E. e% D) ~; `1 Z
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),& e$ G' v" ~" s
// 动态连接库就不用调用了。
- L2 }$ D3 E5 n0 y ? g////////////////////////////////////////////////////////# U9 ~! l4 o- L+ w
#ifndef LANE_SPEECH_H' W* Q) n4 O* G
#define LANE_SPEECH_H
# W" [" h" k# S* f' ]( G% L
' ^5 y* E$ l' p! O% V#include <windows.h>1 W0 b/ _. P) n& H) P( k, s u
#define _ATL_APARTMENT_THREADED
5 d! Y! F J& B: J* D4 E+ F; ]#include <atlbase.h>9 c" r3 U, L4 F6 q% k6 o& Q+ T; W
extern CComModule _Module; //You may derive a class from CComModule and use it. if you want to override something,but do not change the name of _Module y5 `$ U1 e3 F* Z! @
#include <atlcom.h>4 c3 e( p/ T6 E- O+ c
#include <sphelper.h> //sapi需要的头文件% e4 I: U! Y- B3 j
" w; @, a/ @" Y, j! `' C//-----生成动态连接库和静态库的处理----------------
$ g4 ?+ [" x: c#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
$ e$ d" m# N2 U9 ]
" [) ^8 b- x1 F7 U3 o K6 h# q#ifdef LANE_SPEECH_EXPORTS
6 J% d, M- n, b4 Y: s0 R4 d #define LANE_SPEECH_DLL __declspec(dllexport)# r! p' W0 D$ f, n9 ]0 q
#else
* x. ?, n/ V5 p, d* T- f# D0 r6 k #define LANE_SPEECH_DLL __declspec(dllimport)
1 v! C+ a6 u( D! n$ f) K3 Z1 z#endif
7 [9 u/ F% c* _1 ]: b+ h1 K5 j9 k0 q3 P8 u
//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关
" b" G7 w1 h3 s w8 A//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
4 Q" V, X# o5 r& k1 Q#pragma warning( disable : 4251 ), k$ e. }( T/ o* @& M
- X% x% e F4 J+ R; V
#else //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)6 J* D( C% o! _+ q
#define LANE_SPEECH_DLL
: ~& S; @3 c* ?# B7 n! c+ `' p* R+ g& `* B8 l8 K) ~
#endif //USE_SPEECH_DLL, C$ w+ O# G! h3 h* D
. I. m5 T3 w3 c# j( P: t4 f8 d H& E
* U) Q+ R4 ^* Z8 A( g% y//***************************常量***********************
; A$ ^% T- {0 Y/ S+ o$ {. _1 i" `. Q: l% v* C
/////////公共常量-----------------
7 l1 C3 }1 I F) ?: }, W: F. _const DWORD SP_CHINESE = 0x0000; //简体中文., L) x5 i* a. G% }1 @
const DWORD SP_ENGLISH = 0x0001; //英语.2 ~5 N' C2 l- t1 r
/ K5 g/ {4 R8 D5 g
/////////CTTS常量-----------------
! m0 y+ i- @: Lconst UINT WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
4 M4 S; m/ T7 y) } Q. _% S& m7 Q. u- T; h: K! i' v
/////////SR常量-------------------
8 @/ V4 Z' p: f* n3 sconst UINT WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。
0 T- B5 s, N' Q( |0 K" Rconst DWORD SR_INPROC = 0x0000; //独享类型的SR.
3 m) r- `5 U7 }9 h! Aconst DWORD SR_SHARE = 0x0001; //共享类型的SR.+ G5 y' p+ t" q1 R# j
7 U0 K W5 N- ?/ K' E4 |
//以下常量仅作例子用。: F" s2 Z# W- {. @6 |
#define VID_TopLevelRule 9000 //顶级规则ID
+ {* W! H% C$ x _& B% ^#define VID_SubLevelRule1 9001 //子规则ID0 E# r2 R4 p: @7 e7 i) [
#define VID_SubLevelRule2 9002 //子规则ID
& e4 G' o6 I- j' M9 ?' Y0 T& I# M#define VID_SubLevelRule3 9003 //子规则ID0 \6 J! N* M" j! ~! g" d0 c
- ]* ^' @- B+ _ X) x
/ w8 {/ l* F2 }//*************************类声明************************
6 {" U4 v0 ^$ v) _5 w
6 {5 e' W4 {! d K$ {1 q- S% u& O( S
class CSR;
( z* y& a6 W) b; U///////////////////////////////////////////////////////////////////////* _ P; U3 I. ~- Y* q- A+ n4 a
///////////////////////////////////////////////////////////////////////
! o4 A0 p9 A8 |6 Z; |//0 d: {/ m+ A; B
// CTTS: q+ ~2 {. d+ I" C: A0 u( @( M
//$ t; e. v0 Y7 Q" g8 l
///////////////////////////////////////////////////////////////////////. {1 l1 X0 T: b9 I$ y0 L; h: a# _/ E
///////////////////////////////////////////////////////////////////////
* [$ p- o, M- W4 Q8 A4 v1 `" [9 D1 i/ t; u3 B1 v- o
class LANE_SPEECH_DLL CTTS! V! D' P3 u: \6 P% Q9 v
{. g3 Z/ g/ U. G; `% J" v" _! ^# I( r
protected:
1 K- ~5 }+ D1 c$ p+ g9 ~, T* QHWND m_hWnd; // 关联的窗口句柄。8 p" H+ Z& { j
$ {7 m+ Z8 I0 Y$ q$ G9 o: g% u
CComPtr<ISpVoice> m_pVoice; // 声音对象的指针。2 H. [, X6 B/ O. W
CComPtr<ISpObjectToken> m_pToken; // token对象的指针。
' C, K* b0 t; }4 BCComPtr<ISpAudio> m_pAudio; // 音频对象的指针。(用来保存原来默认的输入流)' H$ N) C3 O: w* U2 J# F) f) |
CComPtr<ISpStream> m_pOutputStream; // 输出到文件的流对象。
( C6 b4 H/ p, a8 }) C
4 p0 M0 z6 M* b3 Tpublic:
& u8 ?3 F; i( B }" C) i//********************************初始化部分********************
" V0 N7 t% ^* { f( b! Q+ g) G$ q: Q- P6 F, t3 F0 ?6 y
////////////////////////////////////////////////////////////////////
% v& p) K/ M1 F9 T& c//功能: 保存与识别引擎关联的窗口句柄。
+ Q+ g v" `) t6 w+ ?//参数: hWnd:要关联的窗口句柄。
' D4 {3 i7 p& C& Y* H5 M//返回值: 无。
; V6 v3 Q; T& K$ r& U////////////////////////////////////////////////////////////////////, J1 O9 a8 w9 C' X" R8 [
CTTS ( const HWND hWnd );9 @: @1 n3 K( g. Y$ z
5 J( @2 l% c" H( Y9 |////////////////////////////////////////////////////////////////////
: X7 Q% u. G1 ]' Z, {0 u6 R7 J# `//功能: 释放所有的对象。! E1 u+ a+ d6 H* L8 a/ o
//参数: 无。* }" I1 J5 L4 J: j' ~% W
//返回值: 无。% E( I6 }' g# A2 Z* i0 \# z0 ~
////////////////////////////////////////////////////////////////////* D0 w' U/ y. j2 j+ I1 b4 Q
~CTTS ();
3 d. E. I: Q# ~+ p; F) A( a' g1 |/ u6 {# \, v# v8 }0 B
////////////////////////////////////////////////////////////////////
9 h0 R: L5 J; E6 _//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。
" {* g" v5 E1 j. l//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,0 u, K" V( m' m
// SP_ENGLISH为英文。
$ S3 p6 u6 E+ y/ {/ |' v//返回值: HRESULT类型。
! q" P8 `( M6 B) c3 X0 l9 f5 s////////////////////////////////////////////////////////////////////3 V& `( K. q% O6 W. W
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );. F* A: M% ~8 S* O: s; B
; m8 G% A: o: b////////////////////////////////////////////////////////////////////
# R- k+ d3 U! X! w//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
1 W% Y$ i: ~9 m# y+ R// 通知事件。. u5 c' z. Q0 S. c8 F
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
% X+ X; ?4 ^3 ~) M// SP_CHINESE为中文,SP_ENGLISH为英文。 b& O9 g! x: t! u5 Y
//返回值: HRESULT类型。" R2 Q$ c1 l+ ^6 B
////////////////////////////////////////////////////////////////////. S9 p, _7 U8 I
HRESULT Create ( const CSR * pSR,6 c- J2 c/ W5 A! e; C |
const DWORD dwLanguage = SP_CHINESE );
& t/ l% ~2 |! v7 L9 i9 I1 W* Q
' p1 I6 a: C; Y7 _
7 e7 K3 o, T' N//********************************设置部分***************************************. l( ?# N& ?' q* I: V! u7 H2 s
( n* f3 N: R% a& D0 d, S////////////////////////////////////////////////////////////////////' p; D6 X9 [2 B) y ?5 I
//功能: 设置朗读声音的语言种类。
. j6 m1 l1 F R$ I//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
7 m* {0 b8 s [//返回值: HRESULT类型。
2 ^( T" V, C% ]! G////////////////////////////////////////////////////////////////////
; y& ^0 F1 X, |; [8 w- d& y1 HHRESULT SetLanguage ( const DWORD dwLanguage );
( j' }6 \2 Y) M7 }+ f
: |5 g; _' ]3 `* \/ K' ~3 g" Z) Z////////////////////////////////////////////////////////////////////6 W# l* O& w8 ?* n0 V5 B. J" j. C
//功能: 设置要处理的的事件。3 h. m* Y* N+ C4 d- W6 |
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
2 B3 J' P+ G/ p# C2 n; @// 设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事& \* x$ L9 ^/ K5 j ?& A
// 件都会收到通知。% g6 n! I! G$ F/ n5 k4 f0 ?% W
//返回值: HRESULT。
0 a8 X& q& q8 }1 d////////////////////////////////////////////////////////////////////$ Z7 L) r* F, [, M. B; u% `
HRESULT SetInterest ( const ULONGLONG ullInterest );
$ B) z/ d B: S a: q* {) X
E! @# G- x3 |$ r$ s& ~" h& p! ]////////////////////////////////////////////////////////////////////8 Z! Z* c; c) S) J I4 d& d
//功能: 设置朗读声音的音量。
3 v/ d3 {! I5 L/ @//参数: usVolume:音量数值应该从0到1004 u1 @: k- n' H( p3 }$ d
//返回值: 无。
* `2 G- Q6 B( h, ~3 ]////////////////////////////////////////////////////////////////////0 S4 [2 q7 I+ r) b
void SetVolume ( USHORT usVolume );! g7 U- o( |/ F, Z( w: h9 ?
6 P; D# E" [, a) v! f////////////////////////////////////////////////////////////////////1 p' e0 B6 M m3 a1 R
//功能: 得到朗读声音的音量。" N: t q: v( v
//参数: 无。5 q0 b/ U9 d2 V1 O) L' u
//返回值: 音量数值,应该从0到100。9 u( t) n0 e9 ~; e: ]9 Y
////////////////////////////////////////////////////////////////////7 u* t3 d+ S: x
USHORT GetVolume ( );
. ` W6 m, ^6 b6 L, { _7 \
; I% b) F! K0 N& ^' c' @////////////////////////////////////////////////////////////////////
) d4 D, Q1 [7 ?( h# J//功能: 设置朗读声音的音速。 x+ Z; ~& u$ F% F) t) W+ D
//参数: RateAdjust:音速,参数范围从-10到10。
! E5 `' a" _& }3 F//返回值: 无。
) h* [+ i9 N: X' Y! y+ G2 k///////////////////////////////////////////////////////////////////// z/ x% v9 K4 b1 D/ T2 r9 `
void SetRate ( LONG RateAdjust );* X+ @- b( S4 Z
$ \% k' J$ H% ] j: [////////////////////////////////////////////////////////////////////
3 F8 |% ]3 @$ `. F//功能: 得到朗读声音的音速。
- l5 @& `0 K) D+ k//参数: 无。
+ P+ _+ Q8 P7 c0 x; ?3 Q1 \//返回值: 音速,参数范围从-10到10。
0 r/ N( D6 h' C: T////////////////////////////////////////////////////////////////////4 M( t/ c2 @' b$ h" U( R
LONG GetRate ( );
6 Q5 z# m% g: d) n- f; p* e0 c. [
: P/ I# t: K5 ^5 ]- t/ T////////////////////////////////////////////////////////////////////3 J; ]' `8 |. {6 d5 C6 O
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。1 _) F5 b3 B6 ^ x+ r: h
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
+ X8 |, s/ P7 C//返回值: HRESULT。
- o4 J9 Z0 q( f1 O/ H: h+ ]+ D) B////////////////////////////////////////////////////////////////////
! d v9 C* B; U$ d% LHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");
7 {/ G; P0 x* f( l! R2 m0 T# w' B% s, H: v- e- i
////////////////////////////////////////////////////////////////////" u- K q5 F1 D- J
//功能: 设置朗读的声音从音箱输出。
" ?' ]/ T \5 i- G1 H3 v4 Q( l- y//参数: 无。$ K7 c, ?1 |! P- @7 B% ]
//返回值: HRESULT。2 d+ b& Z: Z) m+ P8 p2 F
////////////////////////////////////////////////////////////////////
( g. u3 O. z x& |" R* jHRESULT UnSetOutputWithWav ();, E. x- h# x$ g( B5 [6 r
1 B6 E7 Y# t/ M0 C5 @" Q7 |
( T% B9 q) J b+ O4 r
//**********************播放语音,文本到语音转换部分*****************************
' j( t# n2 e; A' B) f6 X0 a p
4 K6 O: n6 ~9 ]3 Q% R$ D# |' Y; m////////////////////////////////////////////////////////////////////% p& U4 F8 F/ J3 _" M7 A2 }$ m8 G
//功能: 停止朗读。如果朗读为同步方式,则不能停止。- @7 f2 F7 M* m( z# [8 \! [5 z
//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
: f8 \1 h3 V5 u$ n |; \$ ?// 的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,4 ]* e+ A+ H1 |! d2 t7 T
// SVSFIsXML为朗读带xml标记的文本。
: [- I+ `9 |5 _: H//返回值: HRESULT。
# m& R9 U* o8 W" F+ D' D1 {////////////////////////////////////////////////////////////////////
( O' s2 U8 Q( b6 {( h# u! O: Z EHRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
8 Z( ^# u/ ?7 q% z
+ Z2 |+ G/ x; k////////////////////////////////////////////////////////////////////
5 E* u) W1 z* @3 A5 k: g//功能: 停止朗读。如果朗读为同步方式,则不能停止。3 d! j1 {5 ]; \' ]5 {
//参数: 无。
+ Z8 L3 s7 P4 q1 U7 c3 q0 c//返回值: 无。8 x E* L+ U% V4 D+ Q
////////////////////////////////////////////////////////////////////
. s$ i6 ]2 j9 V- l) H7 qvoid Stop ( );
; {) Z4 p/ k9 ~, c, x, ?$ C# y: U, R( y$ }$ o* l
////////////////////////////////////////////////////////////////////. V9 T$ ~. E' l
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。( R6 P* G* ?# @( r) y* Z
//参数: 无。$ |) R3 E- B, h. D, f( P0 g
//返回值: 无。3 Q7 [! G% U1 J" M# y
////////////////////////////////////////////////////////////////////4 @8 J4 I* t# `" h2 [0 _
void Pause ();
1 \4 i8 |$ b' s$ P, e8 o6 X
7 Y# b! A' L1 G" B$ T; |6 d////////////////////////////////////////////////////////////////////
" F* }7 o5 _! y//功能: 从暂停的地方继续朗读。
+ r. P% t+ b6 v0 h* G3 F5 F; F//参数: 无。
+ h& g" i7 j, Z h+ Y( O6 R# L" W3 \//返回值: 无。
% `1 M+ F9 Z/ K0 y- K, r9 U# Y////////////////////////////////////////////////////////////////////& b7 s& l! x5 G8 K0 m
void Resume ();1 F+ h+ o! t, c: `% {( d! I! d
6 I" u# t! t" l$ n$ `
! {( U3 L" W l- ]& r3 _9 C//********************************处理事件部分*********************************** _$ G3 f5 I5 P$ B3 C `
1 ]5 o, O' j6 |! E
public:0 F9 o/ \* _' i
////////////////////////////////////////////////////////////////////
. d- [$ _+ @7 [- r( m. o* E//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。9 J3 G" _# w3 ^3 y
//参数: 无。
: u' g. `% K' \ f& K( b, _1 A//返回值: 无。
, G, G" u6 ?2 ]/ L( y////////////////////////////////////////////////////////////////////
" M# O7 m. C5 G9 }% I jvoid ProcessTTSEvent ();- R' n% F5 Y& V% N3 g% X: Z8 E6 u% `
9 }+ J* a. b I1 M
8 |0 O3 F, U5 B////////////////////////////////////////////////////////////////////
% w( A2 H# S: [) X. A//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
+ {3 G) b% m8 x) H: U//参数: 无。
- J& G5 T8 `; o s//返回值: 无。
' V2 {5 M: q0 k////////////////////////////////////////////////////////////////////* g2 P4 s+ o* x# X" J) T; J: ]
virtual void OnStreamStart ();: b% e) c# L/ c' }
8 T; \2 ?) P0 t4 S5 U1 z$ \3 j
////////////////////////////////////////////////////////////////////% m- l% K5 B) g% ^
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。! `0 V" ~8 m' D9 N$ v2 d
//参数: 无。9 h: @" J5 W5 ?: E
//返回值: 无。, {: h* w1 a B7 A
////////////////////////////////////////////////////////////////////
( |: B" n# |' @; F9 y" f, g6 B! jvirtual void OnStreamEnd ();2 @8 V( I% m3 b9 @4 R
};
+ D) D+ k C0 m, P( d- `, F
. V1 I9 _- ]8 `' U* L7 j8 D" n, _8 B# o5 ?
///////////////////////////////////////////////////////////////////////' }% V8 X! t7 c3 E
///////////////////////////////////////////////////////////////////////* m1 A1 R8 ^5 g4 b$ s: R
// CSR
. o; J# e# L" q//
% o% H8 ^; J c///////////////////////////////////////////////////////////////////////
4 }$ [ M& L0 K///////////////////////////////////////////////////////////////////////
: G5 D4 {7 z i: |* R; q+ f4 l, i& X6 P6 S
class LANE_SPEECH_DLL CSR, ?) o& u# c9 c
{
9 s, z4 x Z, S9 P5 F5 B8 U- X. D/ L- M n7 p( c, Q/ _! U# D: n
protected:8 W9 O8 i2 }# S. q, V9 D$ Z
HWND m_hWnd;
8 O5 m/ h, \5 ~) w! w$ X: g9 n& y. X0 B; L; n
public:
, y6 T4 a! U) M1 _8 K& R8 L- \CComPtr<ISpRecognizer> m_pSREngine; // 语音识别引擎(recognition)的接口。
6 t% B& E6 P# {$ N1 a9 Z: mCComPtr<ISpRecoContext> m_pSRContext; // 识别引擎上下文(context)的接口。; L7 l8 U3 z5 |* ^! N" E
CComPtr<ISpRecoGrammar> m_pSRGrammar; // 识别文法(grammar)的接口。, ] w) U* O8 j9 v0 N' f
CComPtr<ISpStream> m_pInputStream; // 流()的接口。
6 _7 S+ o7 M' f/ f. W; jCComPtr<ISpObjectToken> m_pToken; // 语音特征的(token)接口。- ^# }% ^) p- Z5 z
CComPtr<ISpAudio> m_pAudio; // 音频(Audio)的接口。(用来保存原来默认的输入流)
% _1 o* Z. R; spublic:0 d' H. R p# W/ x
static ULONGLONG ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。, O! Z+ l- L3 a+ ~5 t9 Z+ H
1 r( g5 \. X2 @' g. H$ _, f7 x) C, w% w3 z: A
protected:% ?; {2 V% D; r' o" n6 j% _0 W
//***************************辅助功能部分****************************************/ G3 h1 P, k& `2 T1 f3 f
5 X: {; M% T# D1 Y0 H////////////////////////////////////////////////////////////////////
6 V$ ^7 h, p) ~, u$ w0 |1 {* A6 H4 K8 Z//GrammarID加一,每个GrammerID必须不同。
1 t& Y; F% W# [) Z' _9 f7 _////////////////////////////////////////////////////////////////////
7 P4 j: T- X4 j# X: xstatic void UpdateGrammerID ( );
/ S: r: P# P( \9 u/ {/ ?; h) H2 H k! O, `) h
, \# C0 z m: n& X, K' Npublic:7 M$ E+ Q8 X/ t; C
////////////////////////////////////////////////////////////////////% h5 w& u5 s: M3 b: [
//功能: 友员。TTS中的从SR引擎中建立voice对象。6 `0 k- b7 u; t0 A; f8 I
//参数: pSRContext:SR上下文对象的指针。, |1 L& V/ u" J/ ` P! ?+ E
//返回值: HRESULT类型。5 B) S E( p# ?4 S; C
////////////////////////////////////////////////////////////////////7 u. j3 l; p/ R* ]& z
friend HRESULT CTTS::Create ( const CSR * pSR,
' _+ L$ c& \, Z6 Q% | const DWORD dwLanguage );4 ~ \8 C9 p" ?; u6 I7 b! s
6 W: {3 |9 m/ y3 W
, d3 Q: ?- O4 W5 S' ~) s//****************************初始化部分*****************************************8 y: k5 a. o( `6 Z- {7 \( z
5 p, c+ D) d3 m# U; Z////////////////////////////////////////////////////////////////////* u7 B9 I& x$ j" Y- k% m
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。
: h0 E3 G) f( N1 k2 I" x//参数: hWnd:要关联的窗口句柄。3 Y; ]! S; Q$ u! A- v7 X
//返回值: 无。
5 }! e1 i0 s @8 ^ g8 @////////////////////////////////////////////////////////////////////
7 {+ X! r6 a q$ r- _CSR ( HWND hWnd );
) z% h. k% N% \+ F& e/ @: z2 K( Z+ B
////////////////////////////////////////////////////////////////////
4 H5 ?; B; S' g( U//功能: 释放所有的对象。, F& j F- m! n. h* q9 d* p) k
//参数: 无。
" Q: e3 c) D/ y//返回值: 无。
7 K; @4 K7 m* V- n//////////////////////////////////////////////////////////////////// Q: a7 ]1 i. t! D
~CSR ( );
3 j: K( r1 U. c7 e U3 y* |; k: g# \; h# G) S: |) k
////////////////////////////////////////////////////////////////////" {7 T \; p6 p L
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,1 }8 J t) F! N8 a7 N
// 加载文法文件。+ U7 B% f- Z8 O+ G
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
/ v, G: _' h, p; v- J2 p. e2 `// pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
! M& k/ x9 T4 ~6 M// dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。& l9 @0 o/ x7 t, b4 {
//返回值: HRESULT类型。
^) w7 H( H1 [3 n _, G////////////////////////////////////////////////////////////////////
" g% w' ~2 I v0 D3 ~, FHRESULT Create (const DWORD SRType,
* s/ U2 O/ q0 u1 @5 L, T1 F( l const WCHAR *pwcGramFileName = L"grammar.xml",
0 a+ D; {" Q" z1 C1 C; I8 c+ q const DWORD dwLanguage = SP_CHINESE );* M/ u- s' C# n% E: m" i1 O
& y0 H' ]/ @2 E
6 H3 M1 h; h3 ~# X//**********************************设置部分*************************************7 q& e7 }1 m( {& N
. o8 e9 I7 |( m3 K' l/ l
////////////////////////////////////////////////////////////////////
! G# Z! Y( v! O. m- D//功能: 设置要处理的上下文接受的事件。* z, b& f4 ~# k `3 s
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
& n) i/ B9 s3 y// 设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事) E6 {6 V0 k, O# ~( k
// 件都会收到通知。% U6 O" ?( C5 S% U3 x) d+ `' c
//返回值: HRESULT。% |: h) n* g5 n8 Z, b; q: u
////////////////////////////////////////////////////////////////////& F+ J# S% y6 P
HRESULT SetInterest ( const ULONGLONG ullInterest );' J x$ z& Z7 q( \& f
/ f9 [: O' J1 [( e% L: f////////////////////////////////////////////////////////////////////" W; `5 D* b+ o. A
//功能: 设置某个规则的状态(激活或者取消激活)。2 w4 ?/ m5 z' K5 ~: Z0 f
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,7 n2 l" j- A2 X3 _5 i
// FALSE表示取消激活。
- b8 t [+ X; a6 c4 z. T4 O//返回值: HRESULT。) m0 r* h. D C3 }" N
////////////////////////////////////////////////////////////////////, z. j+ f' s( a! w9 p* X' g
HRESULT SetRuleState ( const WCHAR *pszName, const BOOL bFlag );7 o' a/ U' H9 [! V0 G2 W: T. P
8 e/ m: ~( b& s: c* V- w% }0 a0 M7 J0 O
////////////////////////////////////////////////////////////////////6 K6 `" i. `2 ^3 e
//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克! d" X) T2 {0 }3 k2 N
// 风输入。! q4 V5 o( w$ w- T+ m
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。0 z8 p: W0 l/ f/ ?* y% I
//返回值: HRESULT。9 {" ]+ C7 v5 y" G
////////////////////////////////////////////////////////////////////" z3 d8 h5 m; y" Z$ k
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
/ Q P0 i; I9 f# c3 S! {3 \- f2 n% x% A5 k: g/ x4 N% {0 E: q
////////////////////////////////////////////////////////////////////( h2 A: l* ]' _! w5 ^6 k" ^5 Q
//功能: 取消从.wav文件识别。恢复从麦克风识别。1 ?' F) W& [# y! `
//参数: 无。8 l1 ?2 Q0 j q
//返回值: HRESULT。
' p: ~4 ~8 j- g1 n3 a( \! q////////////////////////////////////////////////////////////////////
6 ?. K& M+ b3 V, }HRESULT UnSetInputWithWav ( );$ s" c5 [( q; r4 [! {: R3 q5 I% K O
) \0 L7 S) k4 r) \- t3 R//***********************识别开始,结束,识别结果的处理**************************
% g. W+ z$ q5 U4 n9 q
( r0 h: I* n3 b4 H. |: }8 W////////////////////////////////////////////////////////////////////* L H" ^; k- j& Y1 [
//功能: 识别开始(将所有规则激活)。. y# y# _1 I) [: f8 e" `; D3 Y
//参数: 无
9 q1 o; P6 E* {" i4 H: b Y//返回值: 无。
: Z/ Q( Z0 R# q! g3 k# }4 e; ^////////////////////////////////////////////////////////////////////# E9 O; {4 G `# L- W1 V8 ]- J3 x4 Z
void StartRecognize ( );
6 M& I. e" h, c- o9 k# Y* D" I& ?4 e9 h+ `
////////////////////////////////////////////////////////////////////
1 x4 X: j' J- N9 q1 Y//功能: 识别结束(将所有规则取消激活)。+ i3 _+ W# ?0 c. l# \: F
//参数: 无。
8 G$ M* H4 r u6 G l" d8 l//返回值: 无。
! Z# f" m4 D- F2 M; m////////////////////////////////////////////////////////////////////
5 s2 S* ]/ u) O/ `% v% C1 m, V avoid EndRecognize ( );
/ W2 r3 Z u2 L+ l. I _ O# u$ `4 S" V. g) @* z
public:
* q S" H$ [& \9 p////////////////////////////////////////////////////////////////////' g0 d, ~1 J9 M7 B
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。8 a1 D; h# p' B2 }
//参数: 无。
6 L2 F$ }; o% N//返回值: 无。8 H/ c; ?1 _% Z) }2 t, o& Z1 }3 ^
////////////////////////////////////////////////////////////////////
0 E. d6 A9 M; P4 Yvoid ProcessRecoEvent ( );
1 z$ V& ]6 Q' `1 ~+ ~
. X4 Z4 G. U' y/ _% [* ]! Y9 sprotected:
) S6 @) c& \& B- v////////////////////////////////////////////////////////////////////
' |1 z2 ?, O) {//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。( q4 N; o/ M' D& d
//参数: pPhrase:ISpPhrase类型。
1 H! A/ k6 w8 Z) t5 U% S3 \//返回值: 无。
% I% d- }( r7 h+ Z) p) S2 F2 Z////////////////////////////////////////////////////////////////////
8 j; L. z- m: ], z b8 P. s% Ivoid OnRecoSuccess ( ISpPhrase *pPhrase );/ f$ M8 m+ L. y$ d: J+ o" N
# B: ~7 d8 p' ?9 d' n
public:
; G- j5 Y( N7 Q, N' y# V4 B- l) g////////////////////////////////////////////////////////////////////% D8 b( s5 s: _, ]
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
4 l) o) T* s4 A& {4 _5 _2 o8 ]// 需要在派生类重载。规则ID必须以常量形式预先定义。
6 i! J6 q8 e: h4 Y//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。$ E% J4 E+ V1 v: j/ t
//返回值: 无。
6 _! q6 r- l% Y2 B" Q) E+ M$ u////////////////////////////////////////////////////////////////////$ i% X r1 N: Y5 x' S5 ?( a
virtual void ExecuteCommand ( const ULONG ulRuleID,
: J% Z$ X3 s- Y- o+ I8 t const ULONG ulVal );
) q" c! w2 b, c
9 S9 T1 z8 X$ w/ H% u* y; F////////////////////////////////////////////////////////////////////
. \$ T7 T3 c8 @: Z4 J! ~5 Y//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。) e, O) l( ~& r
//参数: 无。
7 E" G6 o/ V" J. t9 i; V//返回值: 无。
) G7 w' Y6 ^7 N- y0 n# S8 A////////////////////////////////////////////////////////////////////3 b' X8 Y7 _( k8 y9 l/ U7 R* h, `$ x
virtual void OnRecoFail ();
# [0 m( E8 W* B& n; Z* Y) E5 L4 E; K7 U7 M) `
////////////////////////////////////////////////////////////////////; ?) I8 P$ a8 Z
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。' t- i/ F# O7 f- O9 y" a9 l
//参数: 无。6 M; r4 g* A1 @
//返回值: 无。
; G: Q9 c* n O6 T. A+ [3 g5 |/ _////////////////////////////////////////////////////////////////////
4 F/ N" c3 I6 p7 e1 f5 r: evirtual void OnStreamStart ();
9 ~0 S1 Q0 V* T0 z1 B& Z
! z. V9 m' r9 ]$ i% U, y////////////////////////////////////////////////////////////////////
2 h2 P1 p% \6 |4 l: E1 [. i; i1 {9 @//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
6 l0 U7 S; r e% q3 K9 u9 X, V1 k2 V//参数: 无。
* t; b2 U" Q+ i$ q' b- f. Y# y( |//返回值: 无。
8 e6 K! T2 P* W; h) Z/ G////////////////////////////////////////////////////////////////////4 b5 e* H/ @" J3 J4 i+ v
virtual void OnStreamEnd ();
/ J3 Q6 t2 ` Q) B* t/ H e7 t, e7 l1 ^. T* w+ q; J. F1 P0 \
};
+ B7 |7 u) f" x/ D; D
6 ^: V _: f* h; c. `; [
/ @2 l- M8 I9 c2 Z( ? n
+ W) z J5 A z1 `#endif //LANE_SPEECH_DLL_H
: W% `& O5 k( o" l X- d& V5 A
. A+ |" {- t' s; W7 S///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* |& Z% U3 Q) c- z( I) t& q& t& P4 ~* z! [
////////////////////////////////////////////////////////! |, ~- I0 z7 T/ J2 m
// s) D7 `- M1 d9 P
// 文件:LaneSpeech.cpp8 F. B4 q- y B
// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
% m: J3 w: x* c3 v( _2 n7 v// 语音识别只支持命令模式,不支持连续模式
1 p* K3 O- @0 a: I// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
Q) X! R6 A! o3 j! e7 v3 W// 日期: 2004.100 x# L2 _/ f. r6 D5 z; @
// 版本:1.2& x. J( n9 {( Y6 D6 m+ p2 ]; \
//
7 t; [* N& [& W5 y6 b2 p//
- e$ ]) [4 X1 N- Q" \///////////////////////////////////////////////////////// k/ R1 K+ X4 A' |. q) ~
# H v& i5 U O* u6 G
) J% X' P* r/ j8 y+ m, L
# \/ P7 \4 b+ Q* M( l) L7 D: K$ L#include "LaneSpeech.h"9 M8 P8 Q9 I! g9 J) {: y( h( l
& L4 K- I3 c4 G& I* y
//-----生成动态连接库和静态库的处理----------------3 M6 o7 v8 ]" O( ]/ w! c- t3 B3 b6 e
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
- e: W; n) \* }, `3 S8 _ _4 W" _& C3 M* \( q" m+ D
BOOL APIENTRY DllMain( HANDLE hModule,
: A G9 b: A: Y7 @/ I! i DWORD ul_reason_for_call,
4 [* ~, @: o2 Q2 G$ T }! P" O LPVOID lpReserved9 X: I) @# [( ]. ~/ o
)# y1 Q# G, y$ F) t5 w
{ S& F+ c* n! t* q) y" E
switch (ul_reason_for_call)& i% U3 m: t& |# R( c v
{ m( J9 q" B+ j" Q
case DLL_PROCESS_ATTACH:4 i8 d( W3 f/ a3 Q3 q8 f( Q
CoInitialize(NULL);
9 M. L# u3 \/ Y6 @ break;. W8 l7 Z7 m, v) Y% ]* ^/ J
6 y) z4 [% Q5 a2 o9 | case DLL_THREAD_ATTACH:
1 {" j( A, e! K break;
8 c# c3 O: Q9 A) T- _+ a
# m/ {) }# S& F- T case DLL_THREAD_DETACH:
# I V% S- o! Q break;) i6 C* ]3 A. y( P' o' z& p
9 d! g' B! q0 U case DLL_PROCESS_DETACH:+ k$ }. j5 _2 j! S7 n: n" a
CoUninitialize();3 B3 C# m& Z w. R) V# @, p
break;: w7 V9 C) m( `5 A9 g! N# w
}0 X' T# g1 a7 Q- O4 A
return TRUE;% V, k" S1 S* s2 \ k) S
}
9 |! Z% w; {- x' o0 M* T& f0 F, v5 }
#endif //USE_SPEECH_DLL! I" \9 N4 F* @
. C, f# d7 ]% n2 B) F# }2 W4 S; @8 g6 i2 v. A& Z& O5 v5 g
4 `" I8 H# }/ ^1 v$ ]8 P
///////////////////////////////////////////////////////////////6 q# ], T7 ^6 P& N" B3 W Y
6 u$ v8 Y4 V6 e @, G. b////////////////////////////////////////////////////////////////////
: h9 G$ F& ?+ I H//功能: 弹出一个信息框。
0 r- b+ }) U B9 L& y//参数: lpText:是对话框信息。lpCaption:对话框标题。
' f g/ E1 ~/ @$ I: }$ h//返回值: 无。
/ T2 y; n+ B v, S////////////////////////////////////////////////////////////////////
' D9 N& J2 w- ]& B+ yinline void ShowError ( const LPCTSTR lpText = "ERROR",6 i _7 Y% E( e# G3 t% z$ T! D
const LPCTSTR lpCaption = "ERROR" )' Y6 v8 j# m0 v1 G
{# u4 D( E9 ]+ ]% ~/ T
::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
v& O3 j* e7 ]& {}7 G0 Z! O1 d7 b' j) c3 `* y
) n! k! ~% s$ H7 e$ C: F0 F3 g////////////////////////////////////////////////////////////////////
) v* @6 R; a) V, [5 V9 l//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。! `. F( I0 N% t2 {3 ^
//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
# V+ S. l* I4 X. Y" }% W/ F+ h% Q; P// lpCaption:对话框标题。
1 O; b3 P1 F. `6 h& `3 I//返回值: 有错则为FALSE,没错则返回TRUE。
4 i( R" {+ |8 T2 L, @( m////////////////////////////////////////////////////////////////////
( N, X5 |7 P2 Y# Sinline BOOL CheckHr ( const HRESULT &hr, n1 _ O, C' f& g: C$ ?
const LPCTSTR lpText = "ERROR",
9 ~4 b* G0 ^8 Z5 s: k: N( i8 o3 _) B const LPCTSTR lpCaption = "ERROR" )7 k' J- D7 N% G# T
{
V9 k2 o: J' ^" |) @# Q if ( FAILED( hr ) ) {
* q: t2 o- P& z ShowError ( lpText, lpCaption );+ j2 B3 @, a7 ^7 s
return FALSE;& k Q; s2 }) i8 w! ?
}+ n. |6 `+ a! ?# R$ Y: @
return TRUE;
2 {( ~! _* z, D: g}( X: p0 O- P' x; J# _ Y
5 Z7 [# I0 m3 N! u. D
/ Q9 s& o1 y7 A6 W( \) n///////////////////////////////////////////////////////////////////////
; l+ r$ g% d; v5 @0 j///////////////////////////////////////////////////////////////////////
5 | N- j5 x F- ~6 i5 t//
& N1 a4 f# M. h. @7 u I2 p. X// CTTS5 w# r0 M& s/ J
//
( h, Z# h; M5 U. N% W& U& l, `///////////////////////////////////////////////////////////////////////( x% T$ w: v0 f6 S8 _) v
///////////////////////////////////////////////////////////////////////
# p8 P3 }, `% i) Q! o! K
) E$ n$ \) [* _ V1 r0 Y////////////////////////////////////////////////////////////////////2 Z% w" w; k% W" i
//保存关联窗口句柄。初始化COM。
% d# Y8 U( Z, W( g& h+ t////////////////////////////////////////////////////////////////////
) z; @* Z% ^! S$ e3 X0 WCTTS::CTTS ( const HWND hWnd ); Z; [8 s6 w' X6 ?
{
- h! Z7 j" M8 K4 x, E& sm_hWnd = hWnd;
" |9 M5 B4 r- om_pVoice = NULL;# }; r, t* z; T& r, H
m_pToken = NULL;7 d# w; |' q* ~
m_pOutputStream = NULL;
5 e* ^ ~8 M4 J* s. J/ @; \m_pAudio = NULL;! L7 g( ~, d7 B( `+ E
}
: t- A0 Z9 m' J1 _- P [3 v4 a5 a5 d$ |# N& N" d9 p+ J" m
////////////////////////////////////////////////////////////////////+ {* t' q# \3 L( k* @
//释放所有对象。
4 _, q+ H9 L# b5 W% V9 J; t5 E////////////////////////////////////////////////////////////////////
8 s9 j5 I; i# `+ z* Y3 x4 u gCTTS::~CTTS ()/ H) |8 T& o, n/ r* H* A8 U+ C. w
{" _0 {2 Y- v( n
if( m_pToken) {
0 L7 j7 a5 n' |1 T) E6 ~$ Z) n+ G' q m_pToken.Release();
3 x% P: y5 C5 m6 l* R/ {; L! D m_pToken = NULL;) j" f7 m4 V0 r6 ]/ Y$ w: A8 H' y
}
8 `* `3 S3 Q* |if( m_pAudio ) {% Z, u [/ S$ [1 k& ~' F
m_pAudio.Release();! w' x) M" F5 C
m_pAudio = NULL;$ q) E3 E2 y5 S& C( a9 O( C0 I9 K$ \
}! H8 S* k6 l* `3 o' n7 a( x- [
if ( m_pOutputStream ) {$ r" H" d- U4 D7 Y3 N
m_pOutputStream.Release();: P0 o: }6 G$ s5 V7 w
m_pOutputStream = NULL;3 J, A$ G7 C+ O* X/ n; B% r
}
/ H4 {( K. I. \) f7 @" qif( m_pVoice ) {3 f) G# B& D* D B! q
m_pVoice.Release();
) z: g1 B- S4 }! H! Y' B m_pVoice = NULL;, Q) r) K \4 I, {- N
}
( O; N& V+ q3 L, l, l}+ ~- E. N6 b3 w$ V5 M1 G' D
4 }) u& p+ w# p7 ~9 P
////////////////////////////////////////////////////////////////////
+ B3 ~% H' N2 i2 o//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。( \- E) x; k0 |# Z7 e3 I3 U
////////////////////////////////////////////////////////////////////
3 t0 P) |% `7 A3 yHRESULT CTTS::Create( const CSR * pSR,
o) S8 @/ w& |/ X const DWORD dwLanguage )
: ~9 l2 U' Z* t- I{
' M4 g" Q3 ~2 y- T/ l! a$ gHRESULT hr;
! Y9 r& ^+ N, Y: Ghr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
+ f) O, V* i7 m' }4 Mif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {% j E2 [ y# d1 M# V
return hr;
# E! D2 \. I9 N* N1 o1 ]4 I}/ t S+ `! {/ r- C/ b
& V- g0 l8 ]8 L& h0 ySetLanguage ( dwLanguage );! T C9 J$ z+ E {
, G, \* R& {4 [2 E* c m& K1 U. x/ [
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流4 ?4 f6 u" |' y. r5 F
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
$ U7 k6 ^8 f* f% I9 P8 z/ ` return hr;* E% ? P! d& B1 R) f3 k
}
# Z O/ ]/ S) u7 G: u9 @, d3 ?
m- m! S3 n, O1 y) ?//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
! E' n4 J0 ]6 v) W5 d//SPEI_END_INPUT_STREAM 表示完成流输出。
6 W- }9 T5 ?+ y( Z) g9 O) ]hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |6 z# B9 ]7 a, Z/ I$ N' p
SPFEI( SPEI_END_INPUT_STREAM ),
6 D4 j3 B$ T/ q' O SPFEI( SPEI_START_INPUT_STREAM ) |
8 ^! \9 g3 U( _+ ]; r& z SPFEI( SPEI_END_INPUT_STREAM ) );
4 `/ S' l: V m: c1 g2 v# Tif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {% \' |3 ^- B) i" r% I3 i" O
return hr;% e' R$ h( D$ k
}
" q8 c& i$ F$ k" f2 T+ i
/ q8 s! m6 C8 k' a/ V6 }//设置通知消息2 `, z% t0 g0 U6 d. ~, ^1 T1 \( H1 X
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
0 \3 {" U" ~; U+ ~1 Cif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
$ k& {% I5 f, z: F0 x8 q5 Z return hr;% B6 Q( h$ Y* \7 I- C* K j
}% }7 Q6 m. w$ ~; d9 V- g
) N% `+ I, a/ t }9 `return hr;, w( Q* t: z9 k
}
* m# }" r, _) ?2 o' {) }; k: I' ?: E% F2 w5 @5 p. T3 Q
////////////////////////////////////////////////////////////////////
. N% e1 ?+ B, R7 E. |//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。6 O; L: L8 g9 N6 |7 @
//并设置兴趣,设置通知事件。% c0 l) @9 ~' _- o
////////////////////////////////////////////////////////////////////
. ~$ J5 s$ k- M5 k5 b5 lHRESULT CTTS::Create( const DWORD dwLanguage )" y1 G4 l: i4 |/ G2 M
{
' W1 z" S. r9 } l, P" sHRESULT hr;
* F4 n# e/ W0 z0 nhr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );* E! |) c7 J$ y" G+ w( C
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {
: m# g3 C; N9 S1 K return hr;5 A3 [5 B# T0 Y: v
}
- |+ |/ A. n1 E% O5 R: |
$ V8 W5 u D' F- S, ~9 D: \; c& XSetLanguage ( dwLanguage );
+ _% {* D) [: j! H) h; M& M/ f4 _1 [
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
4 c) x4 C; S- M: [" Mif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {% _) F$ G, u5 A' m( u3 w7 ?
return hr;# y3 z* w0 @/ [, ^
}% Q! J) R! u5 } S2 c1 K
, {: h# {- c7 c9 f- s" J4 _//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM; i6 Y) M- [ V2 R# `, J
//SPEI_END_INPUT_STREAM 表示完成流输出。
' y9 u7 R! z7 M& O, ghr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |+ t3 I( L2 l1 k! d+ A( f; T5 G
SPFEI( SPEI_END_INPUT_STREAM ),
, O* b3 d% w+ Y* L4 U3 t SPFEI( SPEI_START_INPUT_STREAM ) |( ], ?3 y( n& @. ^' b. z7 _
SPFEI( SPEI_END_INPUT_STREAM ) );
7 Z8 D" j; `& g' D( X2 {if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {3 H) ~& y2 _0 Z z
return hr;
1 O% k$ ^' ?8 [# z0 v; X}& l. M5 Y3 ~$ r+ U
2 t6 w& c5 p) _
//设置通知消息
( e* z5 m4 r' e+ M, ~hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );2 B% E- q3 y7 |, w5 b- f# S1 J
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
4 I% G# c, n* k0 `; | return hr;& L% M- x, L4 G9 ~
}2 u5 \# Q' K, M! m
. S$ Z6 O2 n, `% \- X' mreturn hr;$ r2 A8 V0 o" U. q) A& t$ j
}
! k0 Z( \3 k2 v5 u; `7 l- m |
|