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