找回密码
 注册
搜索
查看: 5301|回复: 2

基于Microsoft Speech SDK 5.1的集成微软语音识别与语音合成代码的类代码(1)

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
6 l: q' x; B& R+ n5 e5 r3 l//1,生成动态连接库时,要#define USE_SPEECH_DLL," [0 z( c" ?9 i3 l# n  [  W
//      并且#define LANE_SPEECH_EXPORTS. R! o; u9 c. G+ x5 s, q0 G
//2,使用动态连接库时,要#define USE_SPEECH_DLL
. _$ n; V5 U4 L% t0 M  G* }. A//3,声称和使用静态连接库时,什么都不需要2 o' r. u0 k9 u
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),
3 N5 O9 K7 x4 D' \//      动态连接库就不用调用了。  {* X+ J# I+ \% @5 ]
////////////////////////////////////////////////////////3 v2 _% q4 W8 b/ g  q
#ifndef LANE_SPEECH_H5 f$ H& i: s+ M1 ^' P8 A
#define LANE_SPEECH_H
8 x: u# _; P  l4 A$ E$ [1 l$ V& d
#include <windows.h>
3 M3 |- f1 S4 P#define _ATL_APARTMENT_THREADED
/ ~/ N" s# ^. C! T#include <atlbase.h>
# r( I& z) P9 U( S  I1 i' gextern 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$ H& A, T* W' |% V
#include <atlcom.h>
& k. G* A5 W4 H3 D8 s) S#include <sphelper.h>   //sapi需要的头文件
5 z+ S2 L" I" b2 V1 b" v
. t- |% R- H+ e% z//-----生成动态连接库和静态库的处理----------------: }: ?) G# u+ p1 e
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类" e5 d3 i; l# O) t) j! I
0 Q. w& s& ~. d) [5 s% H) V
#ifdef LANE_SPEECH_EXPORTS% E- }/ O3 f" e
   #define LANE_SPEECH_DLL __declspec(dllexport)- A! Q- r1 m9 R1 q3 U
#else3 @# l0 {4 {9 o
   #define LANE_SPEECH_DLL __declspec(dllimport)
, V& f5 e" E4 C* j( V#endif
6 P$ m& N& e! T* H3 P) x7 S
' h) D% M8 X8 h0 Q! Q//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关
  [/ E6 j% g( {1 g9 O- g% U. J, F//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
- c5 R: }, w' z/ D" e3 W#pragma warning( disable : 4251 )
8 V: L) `- l* c3 e9 B0 I4 b: f- e& O1 |( @. _* [9 i5 Q
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空). |# D3 e- W  k2 }
#define LANE_SPEECH_DLL; Y; ^6 q% R- W5 K. E8 E8 m
" u  ?3 Z# I! b! C/ o: t
#endif //USE_SPEECH_DLL
1 |1 \/ D) t! z5 j7 v0 c% y, r  M  O7 `: [4 \
- p3 r  T. _" ]1 k
//***************************常量***********************
8 m2 p# a; I+ O( P( ~1 C8 M' j3 J! |" w8 |2 z% H9 s
/////////公共常量-----------------; K4 B- [2 H: E; x3 U1 j
const DWORD   SP_CHINESE = 0x0000; //简体中文.
% o- I6 e% h4 p# w4 c$ a5 T; \const DWORD   SP_ENGLISH = 0x0001; //英语.' V, ?! `; s! u% W

4 Z: j6 O1 v# _4 ?/////////CTTS常量-----------------
' c% Q& n& f5 h  x& ~: fconst UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。9 _6 D; P2 ~; ^) V7 |6 J
5 \4 ^3 l7 ]4 ?
/////////SR常量-------------------
+ p& J- L. n$ K+ P9 w! u5 c/ h" R; H; cconst UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。
, ^2 [) F7 b9 S8 rconst DWORD   SR_INPROC = 0x0000; //独享类型的SR." q# ?# k; {& v  ^; k. l- [1 `0 G
const DWORD   SR_SHARE = 0x0001; //共享类型的SR." K' w% b$ T! i) _4 q
0 I4 _& p' K* t* I( l, W" H
//以下常量仅作例子用。8 R+ G. L' q7 Z, P
#define VID_TopLevelRule 9000   //顶级规则ID
$ @" L9 H% J' C: A) r$ p#define VID_SubLevelRule1 9001   //子规则ID
. d4 ?. f! B( a( }#define VID_SubLevelRule2 9002   //子规则ID3 h- {. L1 Q7 v3 `2 ]( ~- g
#define VID_SubLevelRule3 9003   //子规则ID7 {% i2 _9 y) m- t

, f, q: V( Y2 {' [6 o8 s; z, n
' `5 n/ d( l. b6 _1 ]9 y; {//*************************类声明************************
! x8 Q4 J6 _9 X& F' n: A) E3 z0 s- O8 ^* a# h! I( C
$ Z- m. n8 N9 F' M. T4 n
class CSR;
5 l: y0 B3 b3 F///////////////////////////////////////////////////////////////////////$ D- n5 W: @3 g: J+ O+ B
///////////////////////////////////////////////////////////////////////& \9 q6 k% l* ]' y, y; ~
//2 t, ?3 ^- ?! k) B- [2 y
//         CTTS
8 {" Y: n$ D0 E. h. B//
8 J& ^$ I! r1 p! l///////////////////////////////////////////////////////////////////////% i3 I5 S3 l( B$ d0 T! P1 k5 f
///////////////////////////////////////////////////////////////////////. T; }9 @$ Q8 y8 |6 O
! c- d7 Z# |! P+ \! w2 a
class LANE_SPEECH_DLL   CTTS
3 [& O) [$ f- Z5 J0 S1 m9 \5 }/ W0 r{! t1 i9 i7 n- n* A& I- W
protected:& i% M+ R, T/ i" D+ |2 \6 K5 \' Z
HWND       m_hWnd;     // 关联的窗口句柄。
9 r1 W7 g; X% _7 D( g3 `$ K9 k# }6 a) ?) o' k
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。9 m% t8 y1 f# E- @
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。% _& [( @5 v2 ]. ^* D7 m$ R7 w# Q4 S8 f
CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)
0 F: f; t  x% }/ u$ b9 z, sCComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。: v& Y  L8 }) H

9 J2 P5 i3 s3 C7 u  b+ @1 r0 mpublic:
# z+ d1 j7 K/ B" f4 \//********************************初始化部分********************  v1 n9 W. ^" n% F
$ Z8 `0 L, l% N. M" b2 W
////////////////////////////////////////////////////////////////////6 d; u5 K+ J& z3 \9 X- j& s
//功能: 保存与识别引擎关联的窗口句柄。% v$ j2 O- w2 r; _5 @
//参数: hWnd:要关联的窗口句柄。2 W# {6 W! C2 ~/ d) N
//返回值: 无。' X% r% ^( K( @6 @5 r: V5 j
////////////////////////////////////////////////////////////////////6 p) ]' O0 q3 k, N0 h
CTTS ( const HWND hWnd );- W' v3 G* U* ]

8 Y! I  C5 ?  Y7 I7 n$ I# ]////////////////////////////////////////////////////////////////////8 |4 s( T$ c5 L
//功能: 释放所有的对象。
9 ~7 e& b# C  p2 f; o' R$ F0 S//参数: 无。: t+ L1 t4 Y$ B# b( |
//返回值: 无。
! K9 @+ ]2 |3 u2 M: q# V% D4 e1 c////////////////////////////////////////////////////////////////////, @' I* `& ]) H3 L- y
~CTTS ();7 }$ z2 ]/ v9 _. \+ e4 f4 g
+ n% H  K" a" L  _- h
///////////////////////////////////////////////////////////////////// C2 r) u  @* s) N# a1 J  C9 ~
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。( v4 X  U' Z- U6 x- w: ]
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
0 q7 s. r0 N1 J7 D& [//    SP_ENGLISH为英文。+ _8 X3 s( L5 `& [! c2 r
//返回值: HRESULT类型。: o$ O8 x4 {$ h; m2 [& l, G$ l0 l
////////////////////////////////////////////////////////////////////, K9 q! l6 \: e+ z/ X  l. M
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );
. t! w; G  i& y2 I4 A, k+ f$ s) s/ f1 z% y8 u
////////////////////////////////////////////////////////////////////% c) a$ C) o0 c; y: h
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
% n, c$ F4 ^* s//    通知事件。
% V+ ]& X4 w4 Z+ N//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
  z1 I0 |) P+ G//    SP_CHINESE为中文,SP_ENGLISH为英文。
0 b$ I6 q# t4 S" t. S/ z( G. R! B& U//返回值: HRESULT类型。
- v( ~+ v4 [9 Y( T9 X# ?" i////////////////////////////////////////////////////////////////////
/ L6 S; _7 {% V$ C+ l% lHRESULT Create ( const CSR * pSR,6 b) n! R7 h2 \) W$ t
       const DWORD dwLanguage = SP_CHINESE );. J/ S; n5 j6 G1 H

$ \* T# v* |: j* w$ A
$ M, {" R, N3 f//********************************设置部分***************************************
, R' ]1 U3 M5 _7 y. h# k4 k. y4 X3 V$ }- N3 J  C$ V% Z
////////////////////////////////////////////////////////////////////
, E3 {/ g# U/ Q//功能: 设置朗读声音的语言种类。
  r+ {8 s+ V* C+ ]% K. _7 U//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
6 m% K/ g3 b' U  S$ T6 ~, |//返回值: HRESULT类型。
4 c9 D; p' Z0 t////////////////////////////////////////////////////////////////////
" M/ H/ S( q0 M; h7 [  q; cHRESULT SetLanguage ( const DWORD dwLanguage );
+ u( F& x% o) J; l# Y. M9 C: _, U( C7 g2 r
////////////////////////////////////////////////////////////////////6 l2 m; q% F% J1 x: w
//功能: 设置要处理的的事件。
0 v# B% L7 h; z% X//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
  B' ?) G0 n7 R& H# \//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事) V7 @& T3 S" i2 r- l' R: ^7 ?$ A
//    件都会收到通知。
& d; @( s9 a  l: c, Z' v; u//返回值: HRESULT。) z5 r9 R# o( E7 P# `. Y5 O) Q  ^
////////////////////////////////////////////////////////////////////1 g. r4 Z8 P) n! U5 @" k7 O; a$ |
HRESULT SetInterest ( const ULONGLONG   ullInterest );
1 \1 b& y( t( ~; E$ G4 C% q7 g% Z; K: y, n5 m; {
////////////////////////////////////////////////////////////////////( U& m  {) o! L- h5 _' x
//功能: 设置朗读声音的音量。* @; j( F  ]8 r6 ?( v( m
//参数: usVolume:音量数值应该从0到100* l5 E+ h% I+ i  q% ?5 d# [
//返回值: 无。
" p  N# Q' v, O. I6 @0 M6 O6 L////////////////////////////////////////////////////////////////////
) G/ m3 ?/ s  @9 Qvoid SetVolume ( USHORT usVolume );
; O0 x* _  `2 C3 Q
- y/ A7 v, w" i///////////////////////////////////////////////////////////////////// n) q* g" R: d6 q- X
//功能: 得到朗读声音的音量。
+ a$ E) L9 g6 f5 {8 s3 t//参数: 无。
% U; I8 Y$ X/ q$ y7 t//返回值: 音量数值,应该从0到100。" `) j+ b2 Q5 _! u* L
////////////////////////////////////////////////////////////////////
' U9 q4 H. n" u, W& a( dUSHORT GetVolume ( );- A- {4 C2 \  z, j0 E6 l

. c# X8 {6 X& C" [. |& M////////////////////////////////////////////////////////////////////! J2 Q3 Z/ r. G: r: ?7 u+ v: M
//功能: 设置朗读声音的音速。
9 B: k4 M) {$ V# B; W: F* ?2 e//参数: RateAdjust:音速,参数范围从-10到10。! O+ r4 n. @8 a! g7 |" X+ s
//返回值: 无。
  O+ v$ m5 v6 L( U5 K( Y- e////////////////////////////////////////////////////////////////////2 q9 ^) j% ~3 @9 C. Q
void SetRate ( LONG RateAdjust );
, [6 l1 L) i1 f7 y! P1 z# d! X. e4 }, i, C# e& K! ~% z
////////////////////////////////////////////////////////////////////6 d) x) ?6 c# P
//功能: 得到朗读声音的音速。8 ^1 C( \- i% k1 C
//参数: 无。
1 M3 W3 D& L+ F0 X. G//返回值: 音速,参数范围从-10到10。) s' G; x0 o" m2 e: z% ?
////////////////////////////////////////////////////////////////////
. ~" T3 r+ \) p7 ^LONG GetRate ( );6 C  ]+ e( N/ R
) y2 o& C( h# Q3 a; L
////////////////////////////////////////////////////////////////////8 ^9 e# K6 _3 X, n9 C6 S
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。, M, W( q# Y5 J; Y* ~9 l
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。) R( g0 L7 t; v- y. A+ Q% X
//返回值: HRESULT。5 D) u8 e6 q/ N- |! N; M
////////////////////////////////////////////////////////////////////
# Q; Z  [' H- |/ Q9 n8 j# [4 nHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");3 c7 _; z& e* F7 U' `0 P8 ]7 E

  D( @  d" q- Q) v: K////////////////////////////////////////////////////////////////////# s6 T' ^! I% o! U4 J; h4 X
//功能: 设置朗读的声音从音箱输出。
0 o* e0 e2 g" A' o' {, B/ A- k//参数: 无。* V  y! e  P  \$ W
//返回值: HRESULT。
3 p( a2 U" K  \% m3 T////////////////////////////////////////////////////////////////////
8 O& u# J# @: ^HRESULT UnSetOutputWithWav ();
+ m$ ?# v/ D" b( x, r
# [# J. H/ r8 y6 u7 ^7 @; \9 P8 ]1 \/ ^% f% ^7 q! J
//**********************播放语音,文本到语音转换部分*****************************
5 T9 f* @  o0 v" I/ H6 i+ [
2 [& F  H  i7 [  s' i0 R////////////////////////////////////////////////////////////////////
& p/ E& F) U+ c) W- K//功能: 停止朗读。如果朗读为同步方式,则不能停止。
$ G+ N3 |' _5 U% q- j//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记, K2 Y. e( A/ s2 h' V' V3 l
//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,8 i' B! O8 F$ f3 y+ z
//    SVSFIsXML为朗读带xml标记的文本。
$ `4 a. @+ }' s//返回值: HRESULT。# [) }' F' S& O
////////////////////////////////////////////////////////////////////- I! a) a0 M2 _( e3 N/ E
HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );6 E2 u8 e1 S2 ]( N
! h" G& O% i0 n5 F$ r1 U
////////////////////////////////////////////////////////////////////
$ F2 ^# v& e' _$ A//功能: 停止朗读。如果朗读为同步方式,则不能停止。, v! J/ T9 _0 p2 T9 G6 ]( h
//参数: 无。
( Y! ~( [9 M: y: e" X' e/ Z+ h//返回值: 无。- R% X& j* z+ L7 Q  j4 A) N
////////////////////////////////////////////////////////////////////
& G6 b# ?: d% |8 Zvoid Stop ( );
8 `" S6 z$ @* R, E, H
* z' @. F* b1 C- N8 ?////////////////////////////////////////////////////////////////////
( G* U& P- r. _& ]* S( Y  \//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
& d  s3 F* a# D5 }( x- }//参数: 无。8 K* F1 B8 g3 `; N
//返回值: 无。
+ ]- ]! m; q* o8 k) z////////////////////////////////////////////////////////////////////+ U( l# w$ w, K6 `7 a% H5 J0 L
void Pause ();
7 g: r5 b4 H: a5 j7 [, r1 ~- {3 p) }2 J
////////////////////////////////////////////////////////////////////
) J+ K- V1 G% E//功能: 从暂停的地方继续朗读。
' h( h& T( d5 r1 T9 K  x9 Q//参数: 无。- q  [0 n; G9 K* M) F
//返回值: 无。/ a' s4 G$ y5 {1 Z8 J9 h# c
////////////////////////////////////////////////////////////////////
! w) g/ x7 ]' C% R" vvoid Resume ();
( ~0 w% u5 z$ s" s+ H) @/ |
. |$ d0 D* k  h7 A2 T
" O) p; m8 o! m/ t//********************************处理事件部分***********************************( U( v7 {( S* }  n8 d- b

* n5 @3 Q9 L+ @9 X. Fpublic:) i+ ~7 e+ f4 \! ^8 n
////////////////////////////////////////////////////////////////////- K+ z; `# Z* h: H% N6 P
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
7 S+ q- A- Y3 w- h3 e! D+ D' u6 h//参数: 无。# r  B1 I8 W" t5 \
//返回值: 无。
" }: ~1 q+ o6 M8 `! O////////////////////////////////////////////////////////////////////& M* E8 G. J* S, q$ o
void ProcessTTSEvent ();' @" F( ~. f) ~  ]

2 e2 @8 B+ J8 [2 `+ F8 T+ n: c5 K5 B1 o: ~! N4 m- b
////////////////////////////////////////////////////////////////////, L6 i; z% [1 s
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
" m5 P  [8 _, G//参数: 无。
# P6 O5 C' e9 A' W6 |//返回值: 无。
' Y# W4 ~' V& G////////////////////////////////////////////////////////////////////: i! b, B; R8 s4 T$ B
virtual void OnStreamStart ();
$ z) o  ^- N6 r! `1 i2 h5 G' ~# b  [  p: q
////////////////////////////////////////////////////////////////////+ v, B5 j) r+ Q+ H
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
% p/ O$ L2 r% @1 C$ E; u//参数: 无。( v" M% j7 N' S/ r, m" x' h: C6 `8 x
//返回值: 无。
+ S/ l, u% O2 M! l+ Z////////////////////////////////////////////////////////////////////
; \0 x# |7 @* Z& o3 z7 T6 Cvirtual void OnStreamEnd ();$ x6 T4 o- Q! Q, f9 y. O
};$ c# h1 i. b+ ^+ V3 [+ R

% P! x" [# u  C3 ~2 M2 X- V8 A" r' k8 G
///////////////////////////////////////////////////////////////////////( \9 i8 X  d1 `  h( V  z
///////////////////////////////////////////////////////////////////////  x/ [" ]7 t2 y( J6 W
//         CSR- r# @8 ?9 Z! U' \* A
//
0 X0 P5 E; G" Y0 a  D# o///////////////////////////////////////////////////////////////////////
% Q+ s0 v' r+ e( {2 E1 B% U3 Y+ b///////////////////////////////////////////////////////////////////////
/ }: b: \* h/ {! ]9 |6 V
4 `" y" w& l' v4 B& Qclass LANE_SPEECH_DLL   CSR
3 [% j( Q3 x8 z& q{3 O  q; D. M& A

3 I0 q0 c- n; \/ F# K$ H7 sprotected:
% J+ R2 z+ f/ U, wHWND m_hWnd;  }9 j! U& d$ |1 a+ f7 B3 Q" f

" A8 Q- J9 ?5 U" X+ Dpublic:- ^+ {( a9 j- z4 y" J
CComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。3 L9 l$ |4 ^( G! |& ]& P5 y7 k# k; ?
CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。1 Q  Q3 T$ k4 Z, g# M: C, |
CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。% t6 ]2 z5 i# `/ K# \! s
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。+ r$ L3 k. G' d! }4 i
CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。$ n: q, q/ |7 v
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)- V6 Y3 [, ?3 P' m3 s) b: G0 \5 B* s2 p
public:
6 r' J+ ~& M- a, mstatic ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。! m$ d% W/ ]1 a# D
& u" v2 b0 c! ?3 N
- m6 s: |; O% E8 w* d/ o2 O& B; G
protected:/ t: b2 O7 Z- ]( I
//***************************辅助功能部分****************************************) P. B2 z2 J; H' k; |( w
$ A) J4 S) Z% }; j4 Y+ ]! i+ q9 F/ B
////////////////////////////////////////////////////////////////////
; R  I% Q1 r" M' I9 R) ~0 L, \//GrammarID加一,每个GrammerID必须不同。. S" C1 A/ Z# @
////////////////////////////////////////////////////////////////////7 q+ p9 o) T* i3 u9 \" m
static void UpdateGrammerID ( );
  b1 N# b# f8 q& N
4 G0 m; v# z% p3 O3 U; c8 R) C
, @' _% O7 Z4 j/ U8 cpublic:
! T3 y6 r9 e/ q////////////////////////////////////////////////////////////////////
% x4 h3 Q/ [1 ~1 x+ m, _//功能: 友员。TTS中的从SR引擎中建立voice对象。
3 a# t+ L/ y: K//参数: pSRContext:SR上下文对象的指针。3 F3 b* R% Y) x
//返回值: HRESULT类型。3 Q) j4 P+ z& H1 B2 b* ^  h
////////////////////////////////////////////////////////////////////
/ b9 I' M, h5 W0 X! F2 v5 Y6 afriend HRESULT CTTS::Create ( const CSR * pSR,
! L$ _) a# i& p, r" P          const DWORD dwLanguage );
) M% [9 I+ u, B& J4 c5 e* c
* ]! {5 ]) G) [: D6 b
) x3 s5 c4 o9 @, H2 C8 j6 J+ T( c+ `//****************************初始化部分*****************************************/ e. P6 h2 [% I( w4 e

* [7 D  G# g- _8 J9 a, k/ t////////////////////////////////////////////////////////////////////" `  F% x  N& S! \1 k  \
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。* j, Z7 V* J+ N& i6 L# b3 f
//参数: hWnd:要关联的窗口句柄。3 M6 Q  O: c8 H4 n( f$ C3 X  P
//返回值: 无。
; c. L* U$ V3 q: }////////////////////////////////////////////////////////////////////# R5 f0 M( y) h5 }; }( R
CSR ( HWND hWnd );
- S% _( U8 n- C, h$ S1 _9 W0 o+ O
4 B8 A- L; O4 W. z  X) F////////////////////////////////////////////////////////////////////
! R; h/ r5 v  f( _" G5 D% K//功能: 释放所有的对象。
1 P; o2 J* D( w% O% W$ ^//参数: 无。/ w& Y% d5 ^1 \0 w7 o
//返回值: 无。
1 u) x0 @! d/ l; b1 n) ^6 i, f////////////////////////////////////////////////////////////////////7 ^0 f' s* ?" J8 X; X
~CSR ( );. i  N6 T( V& }) N( J
% v( C. V! O9 O: ^# o! ~8 d
////////////////////////////////////////////////////////////////////9 {; r2 l. ]" q
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,$ F& Z: b2 y/ {
//    加载文法文件。# v% C; P% g9 Z$ ]  y$ [
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
7 m  U( q0 L8 P5 L//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
0 p) M( m' T* b+ l8 z' Y/ ~* w//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。/ ]) {4 |* N) z/ y  z' t' q; f. U
//返回值: HRESULT类型。4 U' G9 }9 O: r) b# _1 T) ^4 }3 ]
////////////////////////////////////////////////////////////////////
* o9 ~! b5 w' W8 p- FHRESULT Create (const DWORD   SRType,
& V) ]% i: L' z8 a2 |7 k, |      const WCHAR   *pwcGramFileName = L"grammar.xml",
# a- M5 l. @! h- R; E      const DWORD   dwLanguage = SP_CHINESE );
: W& j( A  d9 U( g, i
1 H$ Z. t9 Q6 `" m  f* `# z& B+ u
6 b' Y) ^0 C6 L0 g& t9 o//**********************************设置部分*************************************
+ r( H" h* G, o% w* P1 s! `
( D  f% H# Z* P8 _( Y# H////////////////////////////////////////////////////////////////////: Q* u6 R# B& j4 m- X# W( @9 D4 C; S
//功能: 设置要处理的上下文接受的事件。7 k0 d7 T# y5 n6 V$ i" J" K
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,3 `) G& |+ j8 O) A
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事) k- S; b: J5 I
//    件都会收到通知。' J9 x- A7 u' G  N2 U
//返回值: HRESULT。
8 t. f( Z3 o- f; I////////////////////////////////////////////////////////////////////
: a  A' Q* Z. N, OHRESULT SetInterest ( const ULONGLONG   ullInterest );* C5 O0 P5 `. Y: G$ E$ j; J
4 T6 [4 o0 ?1 |6 W7 t' z0 R
////////////////////////////////////////////////////////////////////  d2 H% \2 C. p4 z+ t* ?
//功能: 设置某个规则的状态(激活或者取消激活)。
7 o& i3 u# G/ d* [9 ]. L//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,) X! C& ~, Y) d9 r* F: a+ H7 S# ]1 L' r
//    FALSE表示取消激活。* [- [- _" f6 |, U: ~
//返回值: HRESULT。7 E6 |2 N- P3 M' a9 M4 o5 s) e
////////////////////////////////////////////////////////////////////
5 h) u0 |8 d+ w- UHRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
) x9 d, s" y, t1 b0 ]# ]. A
) L; V: ~2 z$ q8 P* [( e( D$ U# u4 m
////////////////////////////////////////////////////////////////////
4 g4 T% }( N: ~6 k6 Q1 g//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克  ~- A0 ^9 j3 F7 s- p6 g
//    风输入。
9 O; Y8 j& A4 t3 F//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
. b. N7 P4 o% T7 [0 w& Q7 _//返回值: HRESULT。8 E; v. Q8 }% z* S% {, i
////////////////////////////////////////////////////////////////////
6 A& W+ u) ~2 P- v  e& fHRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
) t: Y' }: |1 Y- a9 P2 S0 `- l" ]# m" t3 b, z
////////////////////////////////////////////////////////////////////0 r2 @) w# F& O5 y2 T5 E
//功能: 取消从.wav文件识别。恢复从麦克风识别。- o$ }7 b1 Y9 Y, L7 @$ }
//参数: 无。0 u- Z& N" \! n% {; e- f6 a
//返回值: HRESULT。  U8 u0 v; l/ R9 u8 T  D2 X
////////////////////////////////////////////////////////////////////
* t% I  k& ]! g. G8 K% VHRESULT UnSetInputWithWav ( );/ h6 |8 n& |. A. s4 a2 X

0 Q3 V, h/ O  k* E: T//***********************识别开始,结束,识别结果的处理**************************
) H8 D% j7 D8 B, F5 E% \" t& B& u, P
- h# Q- f/ s7 B////////////////////////////////////////////////////////////////////
3 M( H# T2 U) ~# S. d//功能: 识别开始(将所有规则激活)。
1 Q! ^$ m4 E+ Q# R* d: C//参数: 无% W& ^- B3 \9 u1 g$ P5 i# F% [
//返回值: 无。
% P9 o* ^: `1 x' g! l( ]2 O  B////////////////////////////////////////////////////////////////////
) M" s+ I  `2 {) c0 avoid StartRecognize ( );
, y, x, V* w& ]( M+ u- K/ n9 K) ?
1 I6 h5 m5 O5 U% \////////////////////////////////////////////////////////////////////& H+ ~( p2 l3 N: A1 p& ?  w
//功能: 识别结束(将所有规则取消激活)。2 X' R7 v, n9 d; g4 }- o0 f; z
//参数: 无。
- u/ w$ w, r' g7 @3 u//返回值: 无。
/ h6 q8 y1 J, y' |" U$ p& n////////////////////////////////////////////////////////////////////+ B  H" i) I  h
void EndRecognize ( );
9 I* T# z0 ^( _% f& b3 [+ a
5 r$ u7 f! f( C% i7 g8 hpublic:$ K) A# `$ `4 P& N# V
////////////////////////////////////////////////////////////////////
8 C* I1 i0 l) k" S//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
, N/ S" N1 N% I) q  H: Z1 D7 z//参数: 无。2 x; N' [4 s3 D3 @& I2 `5 z
//返回值: 无。
& W' h7 M$ V3 O6 T& `- M* d////////////////////////////////////////////////////////////////////
, O, d) Z- Q( n4 d- S6 K3 r, l! nvoid ProcessRecoEvent ( );
. X! H, {" I- j( K4 H* L6 i3 E9 u0 \, k  f2 J
protected:
5 P% C2 k4 L( A9 @( l  o////////////////////////////////////////////////////////////////////( G  X" C+ ]& M- h8 }$ M
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。% i3 q* I, W9 C' s& Q; F
//参数: pPhrase:ISpPhrase类型。( v. s9 J1 B% N; {- A# ?# y
//返回值: 无。
7 R+ a) o' e% \! p7 ]9 d////////////////////////////////////////////////////////////////////
% P5 K& ~% X0 Q7 Y" C+ h: \. evoid OnRecoSuccess ( ISpPhrase *pPhrase );
9 w) U) e) _9 R9 _/ c
8 J6 t; m' i2 b1 hpublic:
' a+ k9 o: R8 F. A////////////////////////////////////////////////////////////////////
0 p  J# j5 }/ D//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,7 \# p& g$ H) u& D& v0 ?
//    需要在派生类重载。规则ID必须以常量形式预先定义。
- ?' Q2 c. U/ p, Q0 H8 T! {. ]//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
3 v$ f) B0 Q; Z2 r) V8 ?' L! b//返回值: 无。7 }4 f9 ?9 J4 X0 m2 C0 Y/ p
////////////////////////////////////////////////////////////////////
( g" n" i0 X. m9 Yvirtual void ExecuteCommand ( const ULONG ulRuleID,% u# U! n" q* K) L
          const ULONG ulVal );
- t* b1 X; r: J, _! h9 K2 n- ]* X8 C$ d' g/ k& p
////////////////////////////////////////////////////////////////////
) u3 y* d, d& ^1 B6 E) c; l//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
& G6 @* f3 e( J; K- @& x* Z//参数: 无。' k9 N- S0 b/ q- J1 x
//返回值: 无。
( F- N: h+ }( y1 z////////////////////////////////////////////////////////////////////0 G0 X1 w% Y. E/ q9 U7 l+ W
virtual void OnRecoFail ();3 I; }. N3 E: Q% b# u

, e7 |0 P: a  S+ ~# A6 _////////////////////////////////////////////////////////////////////
2 ^# Q* O2 R7 F//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。+ B9 N8 D: }+ f5 y; E
//参数: 无。( f! T1 N9 P2 w& q  E
//返回值: 无。
  K. o) j: J% u6 t" R////////////////////////////////////////////////////////////////////$ _/ q+ y7 w0 ]- m
virtual void OnStreamStart ();' p9 u4 O) {8 M3 e4 Y  B9 I! o/ l8 q* Y

+ Y" u# i* ?0 z3 b////////////////////////////////////////////////////////////////////
( O. {9 Z) X! n% K. c- O//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
! n& r- l" J2 ]- I8 `//参数: 无。
4 N( k7 i7 l$ l//返回值: 无。, e: Y4 e+ U9 D2 m" Z
////////////////////////////////////////////////////////////////////6 p6 a& G1 z1 C. U% ^9 N
virtual void OnStreamEnd ();
. Y  q. M$ Z. K1 l
2 }3 s, \0 g! W. E3 {2 c7 G4 r: Z, q};
2 I" w$ _* j/ ]# P1 v: a
# C4 l  ~6 G! R- k+ L( w( q3 P7 q) I& [: }

% S4 |' X1 y1 B* c6 ^( K4 V#endif    //LANE_SPEECH_DLL_H, q. U/ B' ]9 ^, s% b* B
9 A" g3 n7 X: D% K( _: i
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
! s5 f6 W! `' j
! e/ t# U, D( p. S1 b( i////////////////////////////////////////////////////////
5 }1 f0 z' d/ B1 ]3 M3 Z/ r//, S5 z6 q  K" i1 X
// 文件:LaneSpeech.cpp
6 F# K0 a: a2 A, {// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
  a8 [/ I7 Y1 S$ R. _# h: t//    语音识别只支持命令模式,不支持连续模式
2 q/ \# j8 T8 T! n0 C" y// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908. O3 C6 @9 a+ g' ?) c
// 日期: 2004.101 ?% w' M) e/ ]9 H. g
// 版本:1.2% I6 J& x0 X: B5 }$ Q& w; o
// 7 c  V! t# g- g9 [7 p
//; X% t7 }0 z3 h$ y! ]
////////////////////////////////////////////////////////
6 ~0 G2 r3 A4 i/ `3 v0 H1 g3 o1 q' W, \5 U
" r% ?+ G  H3 z, f& K  O

* Q$ u$ n5 W. a3 C' D7 Z#include "LaneSpeech.h"
$ c# F- b: f/ H2 c7 ]
, m2 ]9 ~; j2 D6 Z+ ]) D//-----生成动态连接库和静态库的处理----------------) `4 }, Q/ ~: y! H" L4 \
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类" p5 s6 }& [0 ]$ `1 ?5 n! ~; f$ a
8 B# j- w7 Q7 K" K& j, g2 x
BOOL APIENTRY DllMain( HANDLE hModule,
% n  C5 I# N# E) C- ?4 V" N                       DWORD ul_reason_for_call, / `8 F/ d8 X& D- Y0 {6 v
                       LPVOID lpReserved9 d0 u- j9 a# y# `8 s1 X2 L3 S0 X, P
      )
- `5 G' F  a  @8 H2 @{
, n* M3 ^. y* Q% s1 ?* t! \& f( |4 R    switch (ul_reason_for_call): ]( J+ L8 f( A, i$ F
{
! K3 J$ n; I0 [7 ?- @+ L   case DLL_PROCESS_ATTACH:2 s" i$ H+ r8 I$ D
    CoInitialize(NULL);
: z) P" v$ L+ L: t. E0 c, A- b5 I    break;
- W& v' Q  o# }$ H% B: ]  / o* j$ V8 J; F6 A+ F* p
   case DLL_THREAD_ATTACH:  u8 m3 G2 e# {2 O1 J
    break;
3 x. a" l/ D9 K1 _: p  
8 J; O3 z. A; Y# z6 Y+ [   case DLL_THREAD_DETACH:0 h9 {9 [; Z: j1 c
    break;7 j# W1 M" `( Q9 `9 J
  
$ c; z+ O9 ]) f   case DLL_PROCESS_DETACH:6 o5 H/ q: V9 S+ E4 @  |$ Q2 r& ~4 K
    CoUninitialize();
# V0 U0 B+ m4 ]$ H  A    break;6 ~2 _/ j$ ?' _2 V  B8 q% S3 G8 ^7 N
    }- e/ f0 M: T& Z7 w7 O8 j
    return TRUE;1 f2 U3 j& Z) S; M) f4 r
}
) \: t" T4 J1 N6 R5 j
& o' X% H' w" A6 j. @& x9 M#endif //USE_SPEECH_DLL: q6 a& T% b+ i- c

' z6 ~5 ]) w  y) O# [; w; [5 H/ P! J+ P

, d5 h9 v! {& x8 Q. D8 Z///////////////////////////////////////////////////////////////
. f  _% Y: v! |% I9 a) J. J; p8 a0 x5 Q+ B
////////////////////////////////////////////////////////////////////
+ O- @8 \. p/ W1 i3 Z//功能: 弹出一个信息框。, e4 Z; z% W( J, ^3 p7 X; W
//参数: lpText:是对话框信息。lpCaption:对话框标题。/ i  G* q  Y' n: r; a
//返回值: 无。/ H5 i) R4 q) L# b$ a/ H
////////////////////////////////////////////////////////////////////
  I0 S, X: j4 d& @+ D! Xinline void ShowError ( const LPCTSTR lpText = "ERROR",$ z6 W3 X) Z0 R& a1 c7 k
        const LPCTSTR lpCaption = "ERROR" )( g7 ^& C1 c/ G7 O0 C+ f  D
{) E2 J2 f- ^/ C( R
   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );' {  h# h0 _8 e0 U
}! m( {# z2 v: z/ U7 g/ S
8 }9 b% K6 G' u9 y2 s
////////////////////////////////////////////////////////////////////# p& m6 n# Y( i6 h. N
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。( D9 U! h8 G" g' \
//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。! a" k9 H( f8 `  f4 O; F1 }8 m
//    lpCaption:对话框标题。
2 t+ R3 V) k. ]7 A4 v5 |1 o//返回值: 有错则为FALSE,没错则返回TRUE。: {  |6 Y) y, h' _
////////////////////////////////////////////////////////////////////
- ]+ y) V" \, M( zinline BOOL CheckHr ( const HRESULT &hr,
/ Z& K7 Q( \- J" ?* W        const LPCTSTR lpText = "ERROR",' n$ t/ i! a6 p; ^
        const LPCTSTR   lpCaption = "ERROR" )
- s8 L" ?1 E6 s9 g9 r: O3 C{6 T; z( Q! j# q
   if ( FAILED( hr ) ) {
9 G8 x& ?/ K/ _- F7 Y    ShowError ( lpText, lpCaption );+ \8 A2 {& K0 r" R6 B
    return FALSE;* B8 O) K1 e4 Q; _6 B8 W' P" v3 R
   }9 p+ o/ l/ M) N( k' r
   return TRUE;+ n" R/ h6 t1 j9 y/ Y
}
1 A( E# J5 R7 P( ^
# s0 @0 m0 G0 b$ W- O8 G, p0 t1 g/ ~# t- w/ v
///////////////////////////////////////////////////////////////////////9 S. [4 z) Y; I. y6 h
///////////////////////////////////////////////////////////////////////( U& ]% n+ o. T, H
//! E4 P8 D! D( g* U: w
//         CTTS, W, R9 {: c* R3 T
//* i2 t% N& v  j1 L: ?
///////////////////////////////////////////////////////////////////////
4 x2 j, Y  v# ?///////////////////////////////////////////////////////////////////////( Z* L' M0 C1 b

5 X7 I$ Q/ z8 m& g////////////////////////////////////////////////////////////////////
" e# o3 l0 I$ V6 g+ l* ^& t//保存关联窗口句柄。初始化COM。3 n6 E1 n$ s+ {' b% r
////////////////////////////////////////////////////////////////////
* g0 \+ ~3 K! ZCTTS::CTTS ( const HWND hWnd )3 T( d# q9 q- i
{
9 o1 J6 S; f' B8 f8 [! h& y5 xm_hWnd    = hWnd;
. Z6 S. Q) s* Vm_pVoice   = NULL;
, i2 Q5 |1 a7 c9 T8 u2 xm_pToken   = NULL;4 @- U( X& j. M3 C
m_pOutputStream = NULL;0 _5 y7 n5 E& e
m_pAudio   = NULL;
+ F" i! m5 U4 x1 b% B}
2 Z7 B: \! O0 J+ n9 s* P" N3 q2 h. A" t/ |
////////////////////////////////////////////////////////////////////
& {: s; v3 {- W9 W//释放所有对象。% Q' F! h" u$ S- {4 }/ ]
////////////////////////////////////////////////////////////////////
6 B* D/ ?. u' nCTTS::~CTTS ()
7 L& X! R6 j% A3 U{
& W% g, F  h- Q# |/ Sif( m_pToken) {' M2 h: p( g. E2 ~
   m_pToken.Release();2 t8 o0 O1 C, }4 ^4 Y- Q; F6 d
   m_pToken = NULL;
& f. z3 T7 r9 D1 c  F}9 Y) _7 g/ H( L% ]$ s( s4 o# `
if( m_pAudio ) {
( q7 Z/ f8 {$ `* X  ~" ~! i   m_pAudio.Release();
- Y; k% f# }& j7 x   m_pAudio = NULL;( v) U  |3 c* J( J5 Q/ |
}
; x* ]3 b) w* dif ( m_pOutputStream ) {/ A$ y$ o  d5 D* t) ^
   m_pOutputStream.Release();) x4 S1 @, {9 a; l+ F: ~
   m_pOutputStream = NULL;+ _5 C; Y5 p0 K! l# M" E" x* T
}
; _' d/ C" s2 lif( m_pVoice ) {
9 F: m' [, M4 P9 u, i, q+ V& w   m_pVoice.Release();
$ ^4 o9 Z- b; h8 D4 L   m_pVoice = NULL;
3 k9 q5 T( O. F, o) T}1 L2 }6 ?5 ~, \3 |! [8 {; V
}) T+ {0 {5 q$ L9 R$ Z
& \* a* o% n" |9 L: j
////////////////////////////////////////////////////////////////////
8 ]7 v) R1 `5 z* ~1 b$ R% I//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。+ ~! ]5 G. c# L# Q5 {( P" h
////////////////////////////////////////////////////////////////////
0 K+ @, r! x5 q+ v! NHRESULT CTTS::Create( const CSR * pSR,
2 n, I- f1 s' G& z3 i       const DWORD dwLanguage )9 n1 B" G% F- B) a# B3 h
{0 G1 T$ @: J8 {# b" c: {
HRESULT hr;
- O7 A3 p, a+ e7 Uhr = pSR->m_pSRContext->GetVoice ( &m_pVoice );. |1 l3 b( I! |6 N9 Z
if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {0 K! l% e9 c: L
   return hr;
% t" ^5 J, V% I" {}
/ `; f/ Q& Z8 v2 w2 a; O" v  F! Z% z5 N
SetLanguage ( dwLanguage );3 w8 s) t7 S1 T

% @, I$ |2 j+ H4 k/ H, H3 n" Ghr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流, R5 [; V' R9 e5 P# [+ t
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
! N1 [8 e: [5 i$ o, t8 _, r4 Q    return hr;
0 r6 ^6 T" b2 Z5 ?! }! F* a4 S}
* Y* l# O! z7 O6 Q
, y$ B# V. z+ Q7 _//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM# Q4 J5 V. ^" y) S
//SPEI_END_INPUT_STREAM 表示完成流输出。
* \( f* s7 o( U" g& A. @) ]hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
) {2 o* M2 c+ g         SPFEI( SPEI_END_INPUT_STREAM ),
  }2 f% s$ H. X# Y# b8 {            SPFEI( SPEI_START_INPUT_STREAM ) |
/ B% W" S  `* V. F  W            SPFEI( SPEI_END_INPUT_STREAM ) );
% D- }  Z9 w) a4 n( I2 ~if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {1 k- S% {0 p9 Z, @2 v
    return hr;& `/ E9 c* B/ d8 p0 s5 D) b' U- N
}# a! w9 |7 L4 R4 W3 M5 G
9 y7 B1 A9 Y, |8 {. L% a
//设置通知消息/ g6 {# m1 `( n/ c# c2 L  O2 y
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
( A, Y* g! @; G  |$ G  `if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
6 f$ p- K: M) l$ v5 A; _3 t    return hr;& J) L; {+ j  o4 d9 Z$ C
}) i* |- Y1 n8 G3 w" s/ ^+ o
2 C( B0 R9 k8 s/ u$ C  j2 p
return hr;
- m% J/ {7 w- u% n" O  _3 R}& Z: e' \* q: [& D1 m( p- H, a+ M

7 A" a& B2 Y+ Y" ~4 }- }6 Q////////////////////////////////////////////////////////////////////( T$ A  v  T2 Z* N  s) k; w% r+ R
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。: e, J' j1 i3 @! q' A8 h
//并设置兴趣,设置通知事件。
. d; U* ]( o" P. f& x////////////////////////////////////////////////////////////////////% b, M9 I# x( o2 W( S' ?% ^
HRESULT CTTS::Create( const DWORD dwLanguage )" t/ f% E( ?- Z8 W9 X
{6 A6 }! ~7 P& Q. O
HRESULT hr;
* g( a- @' ~3 b  `3 Nhr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
1 l6 f& Y# O- }1 s& c7 ]& h) M- qif ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {" M$ X. u! |  N6 N  N
   return hr;
! Z8 R: z5 @1 [}. g0 N- y  s2 Z) h8 e

2 T1 }5 w$ k( }3 R& V- oSetLanguage ( dwLanguage );
, C& O6 f* H6 k% V: c' T. f( z. N6 A; W; @/ Z
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流; G6 m9 C% f- k0 I( P" `
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {2 z  }/ W$ @1 {! V' S
    return hr;
) {* I; R1 [/ X8 ]2 y# ?$ b  H}
" |0 {# a0 ]. u- J6 F6 P" G$ I7 Z' n6 g+ y( l* d
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
; ^- m' O7 f# }* e  s: Y5 s//SPEI_END_INPUT_STREAM 表示完成流输出。
, a3 |/ \' A3 f" ~hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
$ s) `) y  X, o) ]" W; e7 K         SPFEI( SPEI_END_INPUT_STREAM ),
8 X3 d1 `9 U8 _: U/ ?5 l            SPFEI( SPEI_START_INPUT_STREAM ) |& s$ P9 N/ c5 j4 i! j
            SPFEI( SPEI_END_INPUT_STREAM ) );
& L% V# O1 W1 q1 Bif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
" M0 ?- o, v- a" ?9 }    return hr;7 `& B) s' N* d4 a* v& U
}+ ^- ]3 ]! P1 y7 g) P

+ l0 ~  ?, s0 n//设置通知消息$ N5 o: l7 `5 R2 h- ^
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );- e* ~6 R3 u+ i! g' w8 ]
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {2 t) m% ?0 a9 y# i7 m  k3 \" F
    return hr;% M. Z- H/ J2 v; `% N, E
}7 v/ D& q  ~6 q( r" G4 e, s
, m: T' t3 H7 ]! {# z( a! n
return hr;2 ^* j* ?; K9 p7 [  S9 V
}
4 d" q+ `- ~* P3 n- i
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

Microsoft Speech SDK5.1 语音识别(二)

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件: z) t7 p& a$ K" W8 v5 o* F6 V
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
7 M% X, ], L0 ?1 q{
9 o# y% @! k% f) j# C    ::CoInitialize(NULL);//初始化语音环境/ O$ w& ]6 s( G0 g$ C8 S
    ISpVoice * pSpVoice = NULL;//初始化语音变量9 A) l  z% ~, V3 j# X
    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
% _  U: `, Z0 j# M        cout << "Failed to create instance of ISpVoice!" << endl;
5 r5 S" @1 a7 Z% H, E5 l        return -1; 1 m* Z% v6 J/ l7 \7 u, L
    }

/ L( Q. b/ W/ Q' y9 g% j    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
. k+ v. y" K4 [' }# a5 E    ::CoUninitialize();//释放语音环境
# `) c* J! n& M! |
    return 0;
7 I! j. e% ~1 e- p4 b}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

 楼主| 发表于 2011-5-23 17:07:47 | 显示全部楼层

Microsoft Speech SDK5.1 语音识别(一)

VC6.0下开发Speech SDK5.1程序/ m& X8 S1 c! \6 }
" `: ^' g" `6 w$ F; t+ [
1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地  r0 T; v9 ]! L& Q  i! \

9 a) T) {: X+ k& q; d- C' ?. }http://download.microsoft.com/do ... -US/speechsdk51.exe   3 @8 e: `, s  T1 W, p2 C
Speech SDK 5.1安装包 (68   MB)     - \6 m2 o4 _: o* C: y
http://download.microsoft.com/do ... chsdk51LangPack.exe      / V+ r5 o3 i7 v) n# `
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  ! h2 p& z3 \4 O, e9 V. i, z( k$ x5 ]
" W- I+ D3 I" Z# r: T
2.下载后,执行安装8 [9 G# k( t: w% k2 A: }" h! \
; `9 r' Z7 s" u7 J- `; v
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。5 x4 a4 C. p! a1 r8 @/ d
5 `6 `: c7 |" ^- |1 n" A8 p
3.VC的环境配置! p2 y2 V1 h: W

4 G# R' X! u+ }1 @在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
5 q, W, A0 ^, }
$ [4 J3 l, ?9 w3 M8 j0 l0 a工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.: _0 N- ?& s0 r/ v/ y
2 n4 ~0 W" Q$ `+ U
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
* V- W& g/ N5 i& L
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2025-12-29 17:40 , Processed in 0.022863 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表