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