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