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