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