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