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