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