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