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