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