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