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