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