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