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