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