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