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