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