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