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