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