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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////* V* @) Z( e. ]) k7 e
//1,生成动态连接库时,要#define USE_SPEECH_DLL,
$ r0 B7 |+ \7 t( T/ M& e//      并且#define LANE_SPEECH_EXPORTS/ q  E$ T& T% ]/ z9 L
//2,使用动态连接库时,要#define USE_SPEECH_DLL
! e3 F3 f, C, C5 a0 J* _& j9 D//3,声称和使用静态连接库时,什么都不需要$ x# J4 W  y, ]; ?& ~, J
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),
2 v1 {5 ?. V! I9 B  c//      动态连接库就不用调用了。+ ^- ^( D' {' j; I# d& q" O- q$ n
////////////////////////////////////////////////////////
: J8 z$ @9 H0 c* S, w& `1 j9 B#ifndef LANE_SPEECH_H) i( a5 i% [; A, U
#define LANE_SPEECH_H
9 I" ?( {3 u" d) K, {
$ d: B; f, M  H# G7 N#include <windows.h>
: v1 r( U  {  {4 {#define _ATL_APARTMENT_THREADED) A% b. _6 w  [9 A; ?! \  j
#include <atlbase.h>
- g. H0 G$ ?+ Sextern 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 _Module0 \  e/ H5 N7 ~
#include <atlcom.h>
$ L$ t5 w3 l+ j#include <sphelper.h>   //sapi需要的头文件
3 B; N7 ~' r; R$ d* G/ F
$ j( B( E9 O/ l* h5 {//-----生成动态连接库和静态库的处理----------------, W" Z- t' z5 K& V! H
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
5 @( n8 e; Z1 s6 G3 ?( L  [& n5 K$ y7 b: {8 O! \, e- A! e. \
#ifdef LANE_SPEECH_EXPORTS  x+ T* p- s2 H6 ?5 D" F8 i
   #define LANE_SPEECH_DLL __declspec(dllexport)/ u; ?$ R' o  C2 j0 Y5 K; k4 O5 A
#else& N: l! \2 F7 Z- ~! c$ n9 f2 B! c+ \+ q
   #define LANE_SPEECH_DLL __declspec(dllimport)
; P! g* J) w7 {* E#endif
7 J) V; Z6 P3 k( s  N2 J2 y
' a7 R1 P/ Y# r8 d//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关2 {4 e8 x& D# ^+ s' r9 U% q  t
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。8 T# g5 \: }2 P* ~
#pragma warning( disable : 4251 )
; y. v5 u$ @$ _' H
9 F# L% _& v: ~  U) I% N( f#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)" Z/ n; k! Y2 E& N0 g2 t. ~
#define LANE_SPEECH_DLL  h1 U) G# p5 L& d2 S; z

$ B' R$ \3 F9 v#endif //USE_SPEECH_DLL3 z8 O9 C4 G/ v1 b  V# o: G
. v2 V. f8 a- I( N4 I9 z
9 P) ~7 e, h: h/ Y( M4 C
//***************************常量***********************
# W. J+ U. Z* Z2 _% p2 c8 [- ^) U
7 W' K( B3 l- f1 F. L. D' s/////////公共常量-----------------
7 O4 A& |6 A( O% econst DWORD   SP_CHINESE = 0x0000; //简体中文.
, v: h1 X6 R8 P) y& L$ M5 dconst DWORD   SP_ENGLISH = 0x0001; //英语.; Y0 `; V5 o2 [, U! o: C" U2 C

0 W' E, w; Z, r/////////CTTS常量-----------------
1 p  U2 X' N, dconst UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。8 R& w, D9 j5 V$ `# i) [& a4 I5 n
9 j- Q, k  _; @
/////////SR常量-------------------
3 R7 _' N$ G( Z6 J. L1 J8 {+ G- rconst UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。; I& y* r7 Y; Q7 z3 \! B8 o% |) D
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.# ~. n. n% t, s9 Q5 P$ I# G$ Y
const DWORD   SR_SHARE = 0x0001; //共享类型的SR.# s! Q9 P! S) M" a1 S  ]

  {) X* q% {/ n//以下常量仅作例子用。
. }, E8 x" M% [: y& B( H! P#define VID_TopLevelRule 9000   //顶级规则ID
$ E" W# k6 Z) ^#define VID_SubLevelRule1 9001   //子规则ID( l  n, ~$ C' o4 G% A: G
#define VID_SubLevelRule2 9002   //子规则ID
; y5 _  @# Z4 v( {; r#define VID_SubLevelRule3 9003   //子规则ID
, J% g. _" x  ]5 c; h4 Q) Y# X/ p; S5 |6 \/ j$ ^2 o5 q8 k

' C- m3 F4 C0 @2 ^, A/ y//*************************类声明************************
9 ~1 N" b# }4 C+ E* N# K) }* R$ \

+ |/ w7 P$ V) J- Lclass CSR;* J* d/ [. ]/ w2 V/ E- P" ~8 q
///////////////////////////////////////////////////////////////////////% P; ]+ m. @- ^3 E* v" }5 X" s$ F
///////////////////////////////////////////////////////////////////////
8 E) k5 o7 @5 O//( N7 z; Y; S: M  H) m, [! e0 x1 T
//         CTTS
9 G, g9 U1 U# a; q//: B4 u6 ]2 r: m0 A# M
///////////////////////////////////////////////////////////////////////0 D% `+ Z5 q9 c, T/ U( O
///////////////////////////////////////////////////////////////////////
5 m( C1 s. ~3 A
8 ]8 ~' L. Y* f  G5 U) k/ Nclass LANE_SPEECH_DLL   CTTS7 L' V9 Z% d3 m' ]6 l
{4 y6 N2 R" {' t1 ^0 d  N" O
protected:
# H' b# J) W  L: A0 AHWND       m_hWnd;     // 关联的窗口句柄。4 Y; o& G; S2 W/ v

2 S/ n1 w& M% N# c3 ^CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。
- ~0 e, H( U. aCComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。: {. `0 m- J! c
CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)
0 O. h; H2 |) T0 E: VCComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
  ^% }9 w4 E# y- `, h1 C$ [+ n$ d& J3 a
public:7 v  K( |- x5 h+ l( E- i
//********************************初始化部分********************
. H6 i( T! [4 m; K
$ N) H8 X5 T4 Z7 e////////////////////////////////////////////////////////////////////
  A# h1 }0 X1 z4 M; s//功能: 保存与识别引擎关联的窗口句柄。8 `: i; h0 L' l2 {
//参数: hWnd:要关联的窗口句柄。
  l9 K8 P  M0 ^( M//返回值: 无。
, K( f* {% L$ `% j////////////////////////////////////////////////////////////////////
5 ~! f( C) @2 K! PCTTS ( const HWND hWnd );
0 @3 J) @" ~& N2 J& l' j2 D; J( _: Y# |0 w, X! n
////////////////////////////////////////////////////////////////////
$ Y$ o5 K2 x1 W, u4 `//功能: 释放所有的对象。2 `6 ^9 k9 |6 [8 B; ^6 J
//参数: 无。
8 s. g$ V9 P$ A4 k//返回值: 无。
& P( U8 ^' b$ s////////////////////////////////////////////////////////////////////5 x+ y; C; D6 I" d- E3 F" I
~CTTS ();
7 c. a9 r( a0 h- t) n5 Z( W+ e  {6 V* z4 [1 r% q
////////////////////////////////////////////////////////////////////) |) C! S8 q; G$ c) T" u; {: K
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。
6 b9 a9 H1 b" ~- R- p2 r( n: q% N//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
  h" w" }3 l% U0 g& S3 Y0 g  _9 Y4 q//    SP_ENGLISH为英文。3 f- q$ Y) _7 F: \3 E0 w& U
//返回值: HRESULT类型。" m, H* V( `: k+ y
////////////////////////////////////////////////////////////////////; d' ]3 e& O7 }: E' ]* u1 d) [
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );
# @) L8 {2 }; d) o: h$ ^2 N/ E) ]
0 w2 N4 J) B4 Q* m/ s6 c////////////////////////////////////////////////////////////////////5 \# a+ J6 |" B3 ^" B" ]+ d2 w
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,7 O( V/ W4 t* Q* v+ c
//    通知事件。- j3 w$ C8 ^6 S1 s. S
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,4 c9 r2 Z3 T7 I  V
//    SP_CHINESE为中文,SP_ENGLISH为英文。( n1 ~0 V( R' M# u' q$ n5 w
//返回值: HRESULT类型。6 U: `! K& R. A
////////////////////////////////////////////////////////////////////. k# H6 H' g, P
HRESULT Create ( const CSR * pSR,
$ e$ W2 ~% t& r5 k       const DWORD dwLanguage = SP_CHINESE );
5 w- z$ s8 T, b/ r9 |$ ^. G! p' Z4 ~5 J4 Q
6 G' U0 ]% G9 r7 L& m9 O; w; r; ~
//********************************设置部分***************************************
: s4 u- @; P/ s6 a
0 [6 `  K2 q  q  `+ c: @1 N- I9 y////////////////////////////////////////////////////////////////////( U- \1 R4 n1 s7 r! Y
//功能: 设置朗读声音的语言种类。
7 X; h9 n! G- m! l$ N0 `//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。5 l, k: |  L; ^% K/ W/ r. l) t
//返回值: HRESULT类型。" k  j/ ?6 @* L) P: I/ N& T
////////////////////////////////////////////////////////////////////
2 o( k9 U) _. Z1 Q$ |0 tHRESULT SetLanguage ( const DWORD dwLanguage );
7 p- S+ Z" R3 F# v
/ _4 [+ d' d2 u/ ?////////////////////////////////////////////////////////////////////4 m! Y5 p9 ]& k- N/ b
//功能: 设置要处理的的事件。6 ]( z* T) E' `- I* Y$ H; j
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
6 ]9 q* R) M$ H! q//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事+ V) ~& h' n+ l( a) H6 U( I
//    件都会收到通知。) N7 b+ w+ h& O& |# n4 g
//返回值: HRESULT。5 g1 j3 G/ ]) F2 P2 F5 G' ~! }1 w
////////////////////////////////////////////////////////////////////6 g, ?8 }8 _& h8 [! v; f
HRESULT SetInterest ( const ULONGLONG   ullInterest );* p3 O- z& W6 A( |: r* E

& z* ~) C2 p0 l% ?7 o, ?////////////////////////////////////////////////////////////////////
/ Q$ I+ n( V6 t$ F//功能: 设置朗读声音的音量。
  G  P$ I& Q8 n9 x//参数: usVolume:音量数值应该从0到1002 S6 x1 P5 t8 M! J* v: u
//返回值: 无。8 @- S  r$ s) t1 y/ s
////////////////////////////////////////////////////////////////////( \/ [+ J3 z! v! Y/ t$ a; V* o
void SetVolume ( USHORT usVolume );, p$ g/ v9 C/ b2 n* P5 p

; u1 O2 w  L* y////////////////////////////////////////////////////////////////////5 K0 T# y! R/ E7 D2 h
//功能: 得到朗读声音的音量。
' u' L; q" X+ ]3 T9 l//参数: 无。
/ M# [- L# z# l7 R: e; z+ v1 f//返回值: 音量数值,应该从0到100。3 m! ~& G8 g5 ?& b2 R1 U4 M
////////////////////////////////////////////////////////////////////
* z: B( p4 q. o9 h- q$ ]8 ]USHORT GetVolume ( );/ F8 J" d. j, V. ^4 ]0 B- ?

) W9 Q. P- v0 o2 W////////////////////////////////////////////////////////////////////! ~- \& n1 L8 b, A2 {3 N
//功能: 设置朗读声音的音速。
' _8 z" j1 {7 f3 a! _$ ]//参数: RateAdjust:音速,参数范围从-10到10。; q4 m7 Y1 e* R8 f/ i' {' R8 ]: L
//返回值: 无。( \' |3 Y8 U  N/ g: j+ F7 k" c
////////////////////////////////////////////////////////////////////
7 J: F. h' B. u' Y4 Z1 @void SetRate ( LONG RateAdjust );
2 \( L! }, D( m: `( S  u3 {* a# p  h* A. n% W  h& \
////////////////////////////////////////////////////////////////////. A% ?0 K9 i3 X6 P0 U
//功能: 得到朗读声音的音速。
( _7 s% R. [9 Z0 s6 ^  Y//参数: 无。
9 w7 U  C, f9 l' o//返回值: 音速,参数范围从-10到10。) X! Q- c7 m: P3 J& F$ @5 M$ t
////////////////////////////////////////////////////////////////////
! b) D; \8 O# m2 |  Q/ e  z. BLONG GetRate ( );
6 g, U6 `( I7 J' b/ T  G( F
( M$ S& b- B7 g* v////////////////////////////////////////////////////////////////////
2 L1 E, k; w1 d0 k* ?5 T3 S//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。" Z8 U" Y  {! T: _
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。, k* F8 T  ]+ q9 W9 X. r  _# R& s" N
//返回值: HRESULT。* b& G' q! o# X. n  e* `
////////////////////////////////////////////////////////////////////8 ^* X) w+ K, o. c: g, N
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");6 m% |# |2 b: \+ w; `+ t: f

3 m  K3 U2 w4 k7 }! e: E////////////////////////////////////////////////////////////////////& N/ R4 @+ z2 C# J+ @
//功能: 设置朗读的声音从音箱输出。# x( w9 L# o2 x, _. G  I
//参数: 无。9 g: j% \' s9 e- ^8 h& C# _: t
//返回值: HRESULT。
8 x: @+ M: B: e! M////////////////////////////////////////////////////////////////////
1 S4 c- o2 K9 l4 c0 |0 |HRESULT UnSetOutputWithWav ();- o- H# z$ e6 c7 @; I' r7 F
) D' V  A. |3 r/ Z
5 q2 t& u/ l8 p
//**********************播放语音,文本到语音转换部分*****************************% S( x' U. ^, D8 L  Y
6 M: L- q/ z3 T) S- U) k% @1 d
////////////////////////////////////////////////////////////////////# i: O* J6 z) s5 h/ l" ^" n2 i
//功能: 停止朗读。如果朗读为同步方式,则不能停止。/ w. y' O8 n9 H+ |% x( ^, D7 P) u& Z
//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记' T2 ^0 C) s, O5 @6 N# C
//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
- P& C! Z3 q$ b" K$ ], Y//    SVSFIsXML为朗读带xml标记的文本。
& a+ R1 h' D5 z//返回值: HRESULT。
) t2 l- p  l5 l1 J////////////////////////////////////////////////////////////////////# x% r5 V1 D* F
HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );" g3 u  k7 @2 ]" ~
$ o7 k8 x  l( z5 [
////////////////////////////////////////////////////////////////////* `( [9 A" Z) c/ b9 r0 j* Y
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
. w* j' F% V: P//参数: 无。
) R+ ]0 l8 K/ c# e//返回值: 无。
: u9 S9 X( ]8 y5 h4 `////////////////////////////////////////////////////////////////////
! B& F4 m6 b. h. c* x# E5 S( ^# avoid Stop ( );
2 S( D: U2 ~* [8 P% C- {# y4 [3 a! O8 L+ a! {+ j" J1 ^' J- H" \& N
////////////////////////////////////////////////////////////////////9 P, J, ^9 ~! c: y. e& P
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
- }3 x, \. V5 s. j7 d! D' \. A9 H//参数: 无。) x) l4 z% e' ~) }$ f6 V; h7 X
//返回值: 无。
3 Y+ g- Q) g! K) G' X$ t5 L////////////////////////////////////////////////////////////////////7 ~/ z. b& r- F
void Pause ();& ?8 W8 w/ {" |# t5 X
; z3 t0 _. S% c6 W
////////////////////////////////////////////////////////////////////
2 E* N& J: P  o& k/ y4 P  ]//功能: 从暂停的地方继续朗读。
: a; q8 @/ P5 u7 d4 o5 Y" A//参数: 无。4 [( }$ I$ j  Z. @# m% ]% Q' j
//返回值: 无。
* W% U: B8 l8 c1 k, E////////////////////////////////////////////////////////////////////
3 t' B6 ]4 ]( S  l4 f' F4 K3 t* Cvoid Resume ();
% i& i: Z/ U8 Q7 B, i1 ~# v: o2 Y, G5 ?* B, K* {4 k7 ]6 ^

. n3 _  s: F+ y" v: A& u# U//********************************处理事件部分***********************************% r& y7 ]+ r8 ]

* W, u1 P3 i; O2 e$ opublic:
3 f( X0 |  a+ C; Q* t////////////////////////////////////////////////////////////////////
1 R+ u$ V' H& P2 o5 k% u% n3 }//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。  H2 D: Q4 {2 x6 Q% o) T/ \
//参数: 无。
' m  M7 T3 H" t) O5 }5 J: ?  `//返回值: 无。
$ O7 I8 `" }  k5 _1 l* b; O" ~////////////////////////////////////////////////////////////////////
) e2 x* B! s% ~" b& G, lvoid ProcessTTSEvent ();
$ E3 ], Q" q0 a/ Z5 i2 O4 Q2 C5 x1 e) k' Z, ~- q
" w% j- T( f# I* c! N
////////////////////////////////////////////////////////////////////
6 A0 d9 s: o$ i0 H5 i( Y//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
5 r) g6 h9 l! K3 U- ^' O//参数: 无。
" p7 U9 A& d: |4 S. O9 O//返回值: 无。
1 l; i1 l- T( {////////////////////////////////////////////////////////////////////
" P! X, H$ {3 V, c4 lvirtual void OnStreamStart ();. J( P3 _2 f" T& k! ~

% @5 W- ^. e/ Y5 ?. u////////////////////////////////////////////////////////////////////9 f3 W% v1 t8 A4 T! p* }
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。! V6 x: s6 S' n7 }
//参数: 无。; h5 H' J2 u: ]; L% u
//返回值: 无。
# P( K. D; Z( _, @; l! z3 ~////////////////////////////////////////////////////////////////////8 `6 X8 i) ?, i2 i
virtual void OnStreamEnd ();
# ~. b/ X  T4 W- @6 p: V: [};. O6 l+ Y4 n5 P' |6 p/ b# i4 i! D

# a6 N: W0 H/ `" B  E% e' J: D8 u5 o# p
///////////////////////////////////////////////////////////////////////3 C. ?) u6 S5 a2 q) s- O
///////////////////////////////////////////////////////////////////////
1 B, ?3 d9 ?7 F8 B7 A//         CSR
2 X& u! _; \) a9 a9 |9 ^9 k//: N2 s2 q; c$ L5 |  n: [1 I
///////////////////////////////////////////////////////////////////////3 m5 u( o& e0 m) {9 o
///////////////////////////////////////////////////////////////////////5 Z" a% c% F; X4 j- m

1 \. P( A3 X: ]" U- eclass LANE_SPEECH_DLL   CSR
3 a: V4 i: C6 p1 z- N6 J. j{" f1 Y, K* T- n7 g
6 F' h7 d$ ~$ [+ W7 H( w% p
protected:* F& c* m  {( N3 C4 R
HWND m_hWnd;
5 k5 ~: ]- w$ ]% Y. i3 j, ^3 M
public:
- t$ Z; T/ b3 c, {& h" pCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。5 N% Y* Q( b2 W: @3 y5 l
CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。' ?" J- n) d$ `+ [6 _
CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。
$ B/ v* x/ r* ]2 M" sCComPtr<ISpStream>    m_pInputStream; // 流()的接口。
+ a& k% {% O. w4 L" gCComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。1 n( o9 h% B8 s- m. @: ~
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
) X5 Z5 \) q7 Npublic:* H( I  B+ E8 u! y; l& o; U
static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
2 W8 n: K6 E+ h! g/ Y' P/ S9 @: O4 S% T

8 t7 N. [6 P1 Z" c5 J: _  Tprotected:
5 v4 i3 |  W" q9 |# q//***************************辅助功能部分****************************************9 c3 ?( q5 y/ ~2 ?8 Q5 L
: ~  D2 W; k. v7 n8 H7 T0 y
////////////////////////////////////////////////////////////////////
: o/ b, ^! `: @5 o! L//GrammarID加一,每个GrammerID必须不同。
3 u, N' W3 q: }7 e////////////////////////////////////////////////////////////////////
5 {: o7 k1 y9 s: ]4 Ystatic void UpdateGrammerID ( );( @) [8 O" ^: T4 W0 u
0 p" d8 j. t# r, G) v

: ~4 b3 @4 _- s& }public:
7 R% I! ~' O6 ?; d////////////////////////////////////////////////////////////////////
6 X+ B. U! C! ^* Q) B) a" }//功能: 友员。TTS中的从SR引擎中建立voice对象。
8 Z4 l. C7 o( G* W3 }//参数: pSRContext:SR上下文对象的指针。
- A7 L+ \; j1 j) e//返回值: HRESULT类型。2 E8 I7 Y; a- r* t, J* f+ v
////////////////////////////////////////////////////////////////////
/ X7 Y: c0 \% ?7 ifriend HRESULT CTTS::Create ( const CSR * pSR,' }8 N0 S( I$ ?" B, q( P6 \- S# f
          const DWORD dwLanguage );
" b5 b; N  Y/ D# B
$ f/ e( J4 z4 W
- m' {3 b  |5 I) o9 X//****************************初始化部分*****************************************! z6 x' P- S/ j
$ `2 j: P& [" K7 j4 m6 N" y
////////////////////////////////////////////////////////////////////
, H, Y9 O2 M( B3 O- m+ U# ~//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。, x- T7 \4 Q6 N; m: j& x
//参数: hWnd:要关联的窗口句柄。7 j8 D7 r3 ?8 I- o6 H9 o- ]
//返回值: 无。
3 [" `/ t' X; }  b/ N6 v////////////////////////////////////////////////////////////////////
0 v4 ^6 v; Q! b: T/ M! m# D+ |# RCSR ( HWND hWnd );  v% N: o" Q5 M8 L! H5 A# d

5 P( ^8 V- X8 G+ b, U' j////////////////////////////////////////////////////////////////////. }" c+ I. C0 @9 c5 O7 F5 {
//功能: 释放所有的对象。& U1 z" m$ a9 i- g: E' n$ O7 t2 r0 a
//参数: 无。* T# W! }5 K- f7 r7 z
//返回值: 无。7 f+ U* @# m1 l( Q' T, t
////////////////////////////////////////////////////////////////////
( R6 V( E5 x% |$ T~CSR ( );
. }) e" `2 j, P/ R( U1 z; a2 R8 e! d5 q4 W
////////////////////////////////////////////////////////////////////' B8 _3 W; E) B) @* N4 i0 L
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,
) w% M  B7 G8 L+ `. y//    加载文法文件。& i  N  ?* A' |" |5 [
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。' j7 _% i4 A$ ?/ `- f# s9 H
//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。8 w5 |9 z" o1 E1 e3 R$ l
//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。9 N  C% q& l3 |" |6 R% d
//返回值: HRESULT类型。
$ @2 M: u) [1 I////////////////////////////////////////////////////////////////////, `& D3 a$ }. M$ `# ~8 U
HRESULT Create (const DWORD   SRType,
7 ]6 {, n( p8 L% ~5 }3 o+ ^; v      const WCHAR   *pwcGramFileName = L"grammar.xml",
/ H2 D8 W) p5 g$ d7 C8 M2 o! o      const DWORD   dwLanguage = SP_CHINESE );
; K. d, ]9 T( @4 J4 Z& A) k/ ~7 `+ g, A6 `7 b. u, W

; M8 i! i2 x- H. J/ l& M# g8 C5 N//**********************************设置部分*************************************/ a- Q) [7 k  h, C+ y* b

1 Z  ]! a; Q; _( A+ j! h9 @////////////////////////////////////////////////////////////////////
3 [8 |: a# R* t5 u- u//功能: 设置要处理的上下文接受的事件。) U6 ^' Z- d; E) [
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
* s. X! z* Z7 l" t0 [" @! }5 m1 w& ~//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事) e$ i! C. h# h9 T0 z
//    件都会收到通知。
: H$ q7 k# B; ]- V: X0 o//返回值: HRESULT。4 X4 {- E- Y* J/ ^5 @1 ]
////////////////////////////////////////////////////////////////////; g* P; Q, m/ j
HRESULT SetInterest ( const ULONGLONG   ullInterest );
! w) Y* L" i' J1 r8 c$ S6 Q
# Z% O- j6 ~( e$ j8 U+ f: k8 J4 p////////////////////////////////////////////////////////////////////1 n1 P9 }% B$ L% T0 ^  {4 K  K1 n
//功能: 设置某个规则的状态(激活或者取消激活)。" u# O9 e1 X# E- F1 d- A0 ~
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,% |$ B- l+ s( u- i; ^) G4 w
//    FALSE表示取消激活。
2 \2 |! W6 D3 e' U) e: M: M. k//返回值: HRESULT。: A6 \. \% r, ?3 c: D
////////////////////////////////////////////////////////////////////
1 e# I3 \' S& [HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
6 P+ j" B( ^/ L. y5 X3 ?5 X
9 F4 w0 l, K; f& g# B- t" w7 d# e% N* [2 _9 f* L3 M% r
////////////////////////////////////////////////////////////////////
% \& n9 U! I- P//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
  [* }! B+ }- Z3 @* v; ~//    风输入。
) h2 _! c0 f3 X) `5 t, K//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。1 z: b$ m0 T& c8 R8 E
//返回值: HRESULT。
3 |0 J2 y1 p* b  a1 \, d" C////////////////////////////////////////////////////////////////////
* n$ F2 _6 I3 |1 G9 W: SHRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );6 y; W; l5 L' h$ x) b
1 o3 E. g% T3 x6 |# {9 V
////////////////////////////////////////////////////////////////////3 e/ S9 q% D  n3 t+ {3 y( \7 {4 c
//功能: 取消从.wav文件识别。恢复从麦克风识别。
! `/ B& X9 f' o' I5 @0 X' Z# g8 y//参数: 无。" L- ~+ C: s" T% U" V! _+ y2 J
//返回值: HRESULT。+ V( X1 r5 r  |1 k- P
////////////////////////////////////////////////////////////////////
6 n% ~$ `2 t) E0 ]HRESULT UnSetInputWithWav ( );
3 b/ K0 o0 ^- p6 p4 n; F3 W9 x0 D4 w$ ?8 M: T* m. P
//***********************识别开始,结束,识别结果的处理**************************5 ]- x/ y' z& ?* r

) _! `- E% r4 B4 c; ?////////////////////////////////////////////////////////////////////
: r" u3 i  E6 x2 e% W9 v# ]//功能: 识别开始(将所有规则激活)。7 u3 S7 o( J6 l
//参数: 无6 \3 w! K& l( `! h1 Q9 v
//返回值: 无。0 k+ {8 c9 X; m7 j* f' H6 ?
////////////////////////////////////////////////////////////////////& C/ `, i7 s, O
void StartRecognize ( );
" A# z+ C3 j, G0 U) b7 Q! A' ]
' f2 P; F9 x9 _! ]9 q( r' v////////////////////////////////////////////////////////////////////4 F7 c2 w1 R# B+ U
//功能: 识别结束(将所有规则取消激活)。% R) p# r4 w  A* ]) E
//参数: 无。2 F! Y, i7 H; S
//返回值: 无。5 D3 \8 Y* r1 V' J
////////////////////////////////////////////////////////////////////
9 K# j/ ?' c- l. z! T: ?* `void EndRecognize ( );/ J9 C: {) C* M8 e  D
9 y2 s+ S- o" U, p* P* O( @# @
public:
; J6 j4 }  K4 E' g+ l  ?! F////////////////////////////////////////////////////////////////////
2 i2 @. ?. e) P//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
4 I- c% u; Q! P) |6 B3 W2 F+ A//参数: 无。
; m0 ^1 B; X0 a1 `' k: i//返回值: 无。; K- C( Q' l3 `1 z
////////////////////////////////////////////////////////////////////8 `7 V) N# J$ x+ O1 R
void ProcessRecoEvent ( );1 F- ~) |# I9 P$ b  i+ n
& _+ r8 z, E! D" m' b$ q
protected:
; f. e" n4 x& [% [; N////////////////////////////////////////////////////////////////////* ~: r, A+ A  Y  _3 v: S
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。
& q: l4 [) A9 q8 r1 S- l9 c& z//参数: pPhrase:ISpPhrase类型。
0 W) v& a" W. J9 R- Z//返回值: 无。
, N, ]0 h: S5 `' K$ ~4 X1 @8 e$ N////////////////////////////////////////////////////////////////////
1 r$ W# m! T% e0 S( @' x/ Vvoid OnRecoSuccess ( ISpPhrase *pPhrase );
7 u8 F7 Q- P! L* ]8 W3 s! q! v. b8 i# s$ Q/ A
public:
% H' W% ^4 |8 |8 H8 H1 o0 d% r////////////////////////////////////////////////////////////////////6 c% f$ O- v% v. Q: F8 L5 {
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
6 \& q9 O; D0 |  G" K//    需要在派生类重载。规则ID必须以常量形式预先定义。
% }2 I8 B5 L) ?4 e+ e//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
$ Y( F# h) ]" t* v//返回值: 无。) o4 ?: E5 Q, j  E
////////////////////////////////////////////////////////////////////) w$ u* ]0 v4 M1 q) v5 k# P' z
virtual void ExecuteCommand ( const ULONG ulRuleID,  F7 p5 W  R8 Z2 L" p
          const ULONG ulVal );1 u5 z% |9 x. M) R, H  ]0 T
. ^& J# B8 w# ~! d2 m: C2 y
////////////////////////////////////////////////////////////////////
- I- d% t$ J3 V9 W3 G8 X2 C* ]9 |. p//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。! t" ?. R/ w  E9 e" U) A
//参数: 无。
' i! s; p6 A+ T* ]- O9 D//返回值: 无。
2 }" B+ e* b. A7 W/ W; s# A////////////////////////////////////////////////////////////////////) ?! ~6 ]# M! z# X1 K2 P" s+ `  l  `) `
virtual void OnRecoFail ();
: G" ^* y  t; I% B$ c9 v) ?: X, R$ u9 g4 ?
////////////////////////////////////////////////////////////////////
4 x  M; l1 ?& f& L4 j# B4 A//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。" i2 x) I6 G% p9 F% q
//参数: 无。
; t' }( P% h6 ^$ p//返回值: 无。0 |; _3 h1 M8 S- r
////////////////////////////////////////////////////////////////////) U8 x! n$ d; U( D$ ^
virtual void OnStreamStart ();, \( w& x7 D2 ?7 M! _! l
$ Z+ }$ S3 F+ ~, `
////////////////////////////////////////////////////////////////////( ^* d" d7 ^8 |1 D$ a( H; @
//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。) j2 X: T  [5 }- l; Y9 }( h
//参数: 无。4 ~! P) |# @. n' F( @
//返回值: 无。7 r* X* Z8 [( i9 v" P. T+ B6 a
////////////////////////////////////////////////////////////////////
- {3 b: i' X1 S3 pvirtual void OnStreamEnd ();: g  p8 m- r( `$ s9 r$ U; u

# |+ o0 b# t# G; ~8 b};
' a* ]% l) G  i; J
- T$ d: D  s1 A
. W& K. D5 f) o8 G
+ ^2 r! N  D: F) ^% A( j: e#endif    //LANE_SPEECH_DLL_H
2 U) T+ v; d6 e: _2 U4 o- y. K: h9 Q. ^8 O# t) t$ Y* g; b
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; e* t) h- C! @1 h  f3 L6 `  {3 {7 g# I  C& Y
////////////////////////////////////////////////////////* S4 D( r6 Z7 ^: y) E* S6 V
//
0 \- m* q: G# J( ?& i9 F" R4 O% v// 文件:LaneSpeech.cpp
; E# N8 x/ I2 a( I+ V// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
( H, \# d3 c$ \' l0 b- f: o( H7 g//    语音识别只支持命令模式,不支持连续模式
# y7 W% I0 M  @! e// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
' y- J$ _7 y# f" G+ V# [4 C; C// 日期: 2004.102 \4 M' W: C' d: {
// 版本:1.26 p$ W6 H! \- S
//
0 }# o" h$ r/ w( C0 x$ o//
1 |" T: H* q: _////////////////////////////////////////////////////////
. Q" k" q& g8 o; _, ~% L
+ e7 C8 H; r7 B* N+ H$ H9 d- i
7 F" B6 M& z! `
8 [! V. B4 J' U' p$ n8 z#include "LaneSpeech.h"
6 |5 M1 }2 M$ v" q3 j% r. m
6 \: ]) k/ K1 Q: ~" H4 Y( g. v//-----生成动态连接库和静态库的处理----------------
5 D8 k& X+ f2 ^3 l8 V#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类+ _7 W: m3 {5 r4 M; ^/ n

  c% p+ S$ c* L" E! bBOOL APIENTRY DllMain( HANDLE hModule, " m6 F4 k5 y6 l& H1 {6 K
                       DWORD ul_reason_for_call,
9 b- A4 B6 N* q2 m# i% B/ P7 V                       LPVOID lpReserved) c/ U+ m2 B& G# x& t; s$ B6 i
      )$ j' A' S1 Z2 A$ m; |# ~
{
! X& \! w7 u2 a( |  A    switch (ul_reason_for_call)
1 _+ C' X2 S3 K8 O, h: x{) P. h& ^! a+ ~$ C: @/ L8 d
   case DLL_PROCESS_ATTACH:& }8 ]1 [" ~) ~- F
    CoInitialize(NULL);" ~0 v- R* D/ b2 L" C% X
    break;* T# y/ H: _  D5 V
  3 r2 F5 l) y* M$ P
   case DLL_THREAD_ATTACH:
# K" J1 `. s. t% l/ ~    break;
8 a; u1 k; s# F  Z& x1 Y8 k8 b  0 f9 H3 ]0 ]* U1 {( Y3 y% [
   case DLL_THREAD_DETACH:
; a& E& M+ o2 w/ e6 _( V' K    break;' r% W- q8 A, c' Q# W; c1 M* D3 z) g
  
9 c' i5 P- ?+ k9 W- L   case DLL_PROCESS_DETACH:
0 G9 n- |" ^7 i. \    CoUninitialize();
7 a) G" O4 @) h8 v, V    break;* t1 [8 Z2 ^  j5 F- D4 v; }8 V. m
    }
3 R1 l7 G% G! C$ g$ W    return TRUE;
( w: G& h6 q% H2 X- j}
% Y& i3 {. m" G8 j- y2 Y! r, ^0 I, s1 T
#endif //USE_SPEECH_DLL. h3 [9 g7 @# o9 y, ]

/ n. ~& h$ E; A7 {: P2 Y
. V7 t8 Q1 @4 ?$ ^; `
7 D) I5 T. c* }" X///////////////////////////////////////////////////////////////
8 J. `3 g7 R. T/ j! Y* g; U
. N; w, h7 k; I////////////////////////////////////////////////////////////////////
5 l) ~3 a' k3 k+ ]//功能: 弹出一个信息框。
% d  o" s( V7 i- R  t//参数: lpText:是对话框信息。lpCaption:对话框标题。  M# Z6 O/ q) W- l5 b
//返回值: 无。) T- z# o( |; Q( ?( `* t, q0 [$ N5 ^, C2 n
////////////////////////////////////////////////////////////////////( w  Q: B( F3 R  @5 q6 E" {
inline void ShowError ( const LPCTSTR lpText = "ERROR",! D0 f# H' z! Y* d, _7 g: e3 W
        const LPCTSTR lpCaption = "ERROR" )
/ D; O' f8 C+ G  T{
6 d# e% ?4 F$ z3 E* t2 f7 [# Z   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );- o4 _  d) }$ b
}
( M+ x# X. Y7 b. l3 S( k+ F  q& Q1 h, l' i6 B, Q$ f% F
///////////////////////////////////////////////////////////////////// R: T* i1 b. n9 v5 y
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
" N; G+ i) e: L+ \//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。4 I0 M; F7 R- j5 q; J4 ^) a
//    lpCaption:对话框标题。( M& N) J  J( g* g
//返回值: 有错则为FALSE,没错则返回TRUE。
4 P1 k: K; q2 _8 b3 W////////////////////////////////////////////////////////////////////3 k7 [( E5 d( v: y$ a0 I4 k
inline BOOL CheckHr ( const HRESULT &hr,
% j& w* }5 }% \# Y. g8 `5 S' X8 S% W        const LPCTSTR lpText = "ERROR",
, A( }5 ]& q( i7 {2 s& b( b3 x        const LPCTSTR   lpCaption = "ERROR" )$ T) n1 _& T4 e
{
- I, X6 ?- E: X4 I   if ( FAILED( hr ) ) {
6 O9 h) a/ s: Z# }8 m" l+ h0 C    ShowError ( lpText, lpCaption );$ t8 H1 L6 m. f8 }% D; Y3 u( j8 Y
    return FALSE;
7 T! J  ?7 w5 z, ^% P$ g8 N9 o9 |   }
6 R) y6 x4 Q+ A/ r0 E   return TRUE;
0 X/ D9 R8 v) ?}
' `- a( ?/ ~. g
4 {8 J7 N. w. f, k3 R/ U$ P. B! {0 q$ _5 E
///////////////////////////////////////////////////////////////////////7 Z" v8 b; T( Y, S* V
///////////////////////////////////////////////////////////////////////
8 f# M( _/ q" ?) L% k' k$ t//) h4 D5 r8 b8 x5 f
//         CTTS
+ D$ q" v! a7 T% k, ?- X//
8 {6 ]% C; f+ ^" ~: b: |' M; g///////////////////////////////////////////////////////////////////////
0 D5 g7 R9 r9 ?9 p& v///////////////////////////////////////////////////////////////////////0 z( d  O1 g1 Z' a( |2 N9 @
! l& h5 o" N$ x; \( }% H+ w
////////////////////////////////////////////////////////////////////; m% C$ S! V& l$ S% w, {2 R
//保存关联窗口句柄。初始化COM。
. M0 J4 e- _/ U////////////////////////////////////////////////////////////////////
9 @2 O# n; m* b3 E, {. b3 I; MCTTS::CTTS ( const HWND hWnd )
3 U6 m- H, k# ?0 C- i4 l3 q{
4 B- {' z2 Y$ L8 lm_hWnd    = hWnd;
  }. c) E2 w( K" T7 v; l9 f/ i  em_pVoice   = NULL;/ Z6 g' q+ y2 F2 Q. B
m_pToken   = NULL;
# V) d* i, ^! W, s, R$ J$ am_pOutputStream = NULL;7 h  R/ b, ~* {# F
m_pAudio   = NULL;
$ C+ B! s8 o% @% F/ V}* s+ h5 T$ V5 t5 X

; V1 @1 V+ p& W# L////////////////////////////////////////////////////////////////////
2 o$ l+ d& E+ K. R: l' h; F//释放所有对象。3 A" s5 o4 W4 T, j3 \7 r, U9 T- |
////////////////////////////////////////////////////////////////////
. \4 `2 u0 C0 M/ N. ^1 a* CCTTS::~CTTS ()
% m- d% T1 b3 k/ S& A! X& c) r{9 Z6 q* F' [5 I6 @& a; D
if( m_pToken) {
' Q$ w( c' M) |1 Y3 n   m_pToken.Release();
5 K: J% ~' d8 F   m_pToken = NULL;5 ]0 }8 J! a- a2 }. y" @
}
+ C& d2 V# G9 S3 Y, k# Hif( m_pAudio ) {
1 u* f  C( T4 u7 D+ }: @1 A9 U   m_pAudio.Release();
0 |  J# c" h# N+ G* i   m_pAudio = NULL;5 Z( Y: \  B# D
}0 C/ Y6 D% `) N$ ]2 k
if ( m_pOutputStream ) {6 Q, [5 R! M% @5 S5 [8 g2 W5 v# h
   m_pOutputStream.Release();
+ f6 ]/ B4 K# k1 e, S! R$ d   m_pOutputStream = NULL;3 m# E% x6 n3 A0 d& a" `
}
  J& E) g: T# g- A& _if( m_pVoice ) {/ t  o- S( B. A+ s$ y' D
   m_pVoice.Release();& l! ~3 q- R% B6 p
   m_pVoice = NULL;
, w! Q% y; |  W  _8 @}
4 l9 {; Y# p' B, o3 K. E}% q# q* d3 |# A: F

, l1 Y# f; G. N# |2 |////////////////////////////////////////////////////////////////////6 \; u& u: S/ y7 b: k% ^$ j3 }
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。
4 K6 N( M' z+ r+ m; j' f////////////////////////////////////////////////////////////////////; `' I' n. [/ o# I! u! s* H
HRESULT CTTS::Create( const CSR * pSR,( b# @+ y# F. x4 J/ o4 X
       const DWORD dwLanguage )
' A& v5 P. O. Q) ?  |+ j0 E1 P{' C! J; T" x' v9 O2 H' P: T
HRESULT hr;
- u( W2 `3 e6 p7 W, @; Jhr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
7 B; }4 K6 N& N' R9 g4 o; [! E. a7 A  Kif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {2 N) L) I3 W0 ?* A) R
   return hr;
( U$ N0 V: V. U+ \. m0 j$ z}! f/ l* p& i) o$ A
$ q% l8 `" l: O; t  k- w
SetLanguage ( dwLanguage );' T; A2 G/ b3 _' {& h6 j6 a/ I
. n  m0 a; A* z$ f% G+ W
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流4 U, A4 X. I. H7 O
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {* V1 F+ `9 s* D
    return hr;2 {8 B4 P2 k6 X. {8 \  Q% h) l
}+ n4 K: K8 C; e. z5 q4 V% k

( |. w2 m- z9 Z/ ?2 F7 S//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
/ z. z. G* e2 ~5 |2 i1 F//SPEI_END_INPUT_STREAM 表示完成流输出。
9 ?4 B3 W6 b' `' d8 e/ V. Nhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |" ^$ X0 w& G0 ^' O- b: S
         SPFEI( SPEI_END_INPUT_STREAM ),) g& I2 S4 A# [; {, L/ o2 _0 o
            SPFEI( SPEI_START_INPUT_STREAM ) |% v" |0 m; h5 k; l/ b
            SPFEI( SPEI_END_INPUT_STREAM ) );, J& I4 I8 I9 l& B6 I* v
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {/ Q' B+ U' S# V2 z" o& U
    return hr;
8 A/ P: A. l8 y; ?}
& Y1 t6 z9 M# u8 e1 d# R. M) e
! v5 c5 Y9 E4 x3 Q. _//设置通知消息0 H/ U8 V# h# e; n, }1 d, C/ g
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );: ~4 E% @  r- N+ x
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {6 ?2 N) o; }; d; n- s7 O8 q
    return hr;& n* k1 m# n0 c6 @8 Z0 k% N
}
. A; z0 I* \5 A6 v; e: ]8 x! p( r6 _2 g* y
return hr;
8 w: L! S& y  g: e* i; W}- A5 f8 D. [4 p
' p  E: ]. }1 c; z# m
////////////////////////////////////////////////////////////////////2 x! c8 B2 q* w/ s; R. A
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
5 F$ |  ]# p, x' s6 v  A# f//并设置兴趣,设置通知事件。( C9 I4 i- R) J( Z. p
////////////////////////////////////////////////////////////////////
5 W2 k9 a1 [/ Y) o- M4 R$ k8 aHRESULT CTTS::Create( const DWORD dwLanguage )
  e) n. R: c: B% B8 E{! _) ?* D  e1 B" A  q& T
HRESULT hr;# ]; d* a0 x8 T: B
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );; D& |% }! j3 G' P4 y& a
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {
$ y& _, L: n$ T- K* v; Y/ U1 V! e   return hr;8 o) M8 C# Q0 e9 N
}1 M5 N! g! E( H( [) S5 z

+ g& p, \8 g; f+ M# k! USetLanguage ( dwLanguage );
) q) n2 u; P- t# J5 j
1 f7 |+ a; ?! P8 h9 Qhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流* u# ]( v( z( S
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {% T) O; k. _1 B# a$ Z
    return hr;5 U2 h& g' [/ v1 Q
}
. d4 q. F( R; `& e3 t$ o4 l
0 E, `; i5 ]: t( l//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM% ~5 B! R1 Z6 [* Y/ r
//SPEI_END_INPUT_STREAM 表示完成流输出。
$ `% \2 G# c( L4 C1 Ahr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |8 Y. u* w/ R  ~8 D: \2 `7 e- D
         SPFEI( SPEI_END_INPUT_STREAM ),: }* U% C6 Q" [
            SPFEI( SPEI_START_INPUT_STREAM ) |
; C: K+ C- N. ~$ r+ Z) R            SPFEI( SPEI_END_INPUT_STREAM ) );
5 q2 g6 N) i/ n+ Lif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
) H, n' E; t5 k! X  X  s) r- D) A2 P    return hr;
3 M! U  j5 X6 |( N9 O8 X- l- u+ C}" {5 v0 F/ R7 V# U  ~( q
' r) l: e; t; H! Y' u5 g4 u
//设置通知消息
& }) j8 P+ |. A6 m  u1 {hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
+ j- N& }6 ~) @, X+ Jif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {5 g9 C4 P) q% g5 }( F
    return hr;
# K+ Z8 `+ F/ c6 U; W}
. C& i. H" V" ]7 Q# Y. ^$ K- e) V6 {* V1 z0 C
return hr;
: i3 U# U4 e0 _  f2 W}
9 Y# K. K0 [$ S2 Q- F* f2 e
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件5 E. ?0 I( K: X
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()$ l. [; {2 @9 o3 d% z0 ?
{
! t# D5 {5 b" J: T  K; u    ::CoInitialize(NULL);//初始化语音环境% A& G$ X( E" S( c! k) }
    ISpVoice * pSpVoice = NULL;//初始化语音变量
, |$ M" ?8 M' z/ n7 Z/ \. U/ y* E7 U    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
/ R/ C; D+ h6 h. [2 g! Z        cout << "Failed to create instance of ISpVoice!" << endl;
0 W, Y" R8 {4 `) i        return -1;
! I# `- y+ l# @* m    }
! e! }6 z" {( v4 h" \2 ^
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
7 l/ _4 h# }; ^* L+ O. h( U0 [4 ?    ::CoUninitialize();//释放语音环境

0 H9 X, _3 {  L  _+ n! v) Q; m    return 0;9 J1 O) t3 m) X
}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序* {8 n1 K% `; ?6 p: O$ Y
: [1 I. m4 c% D. x
1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
  L( @8 W2 i9 H/ k, R+ k" R
- a  W" R8 }* e: p2 V. W# X- Ahttp://download.microsoft.com/do ... -US/speechsdk51.exe   
5 y4 K$ T$ |0 ^3 m: ^Speech SDK 5.1安装包 (68   MB)     # z7 k" B: s" M% f  e- I0 A" R/ P# ^. A
http://download.microsoft.com/do ... chsdk51LangPack.exe      * E4 |: t/ x/ `1 l) I& T2 V# I! ?
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
- ~, f* x$ e7 q2 r/ |, L) k' G. ~$ E$ G2 z8 A) n
2.下载后,执行安装
: \. d" S+ v+ j& I! W, w, e
6 s# _& Z  V" }下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
0 @6 C  u, y! |$ B3 y/ Q. a, b% h( b1 H1 C1 [
3.VC的环境配置! b1 r* Y; S) N5 y- o% Q

" J* v# n9 h# z1 y  I在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
# h  B6 ]" s$ S2 G3 a. F8 u8 Y) B2 S
工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.9 t+ F) E5 o8 x" h* H7 |
3 e* |/ j% G% z. P
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~) ~/ O4 v: l) x9 J
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-6-18 04:47 , Processed in 0.021564 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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