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