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