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