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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////. S5 C# f' z  u2 e) e
//1,生成动态连接库时,要#define USE_SPEECH_DLL,( W" t  B4 S. C" e: O5 r6 r
//      并且#define LANE_SPEECH_EXPORTS2 O$ J4 [5 ]! }$ T+ i8 G
//2,使用动态连接库时,要#define USE_SPEECH_DLL! B+ _4 O' y( R3 o7 n$ d9 c
//3,声称和使用静态连接库时,什么都不需要: t2 Z0 V/ p$ Q2 R) I
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),
: o. }. v9 o- T//      动态连接库就不用调用了。4 p6 l4 A/ e' _$ C. V
////////////////////////////////////////////////////////* P5 R- Y( [6 m: N" u
#ifndef LANE_SPEECH_H4 W- n5 t# m8 {& L; }" X
#define LANE_SPEECH_H
9 m7 K: F/ ]( J6 ^
+ F1 M  N" ]- E* F% [& [#include <windows.h>
3 O) m0 Y/ q* p' \4 \#define _ATL_APARTMENT_THREADED; q2 _* g9 c- y# B
#include <atlbase.h>" I( n+ F5 D7 [% _1 R
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
$ }# l( f  B* k3 s- h#include <atlcom.h>
* X4 U5 ]+ }9 \4 t4 s#include <sphelper.h>   //sapi需要的头文件1 P; R3 y4 v. @) r
/ R" m; g0 o9 `4 J
//-----生成动态连接库和静态库的处理----------------
; \6 @, e/ l" _3 Q#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类, v0 A' s3 @( Y1 \$ z6 U0 M

+ T/ I" O4 d5 k- m7 s) r#ifdef LANE_SPEECH_EXPORTS
; I$ z0 X3 D4 I8 A" O   #define LANE_SPEECH_DLL __declspec(dllexport)
, p. d9 j5 B0 D- D" z  t) Z9 n( Y#else
' k+ e! z2 D$ r0 x   #define LANE_SPEECH_DLL __declspec(dllimport)9 P# h& l, }) g# B3 T: P
#endif
8 L' I& i- h. P" e. [
6 q( L' }& V6 N8 u& [//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关& c; O" ?" v& g6 e  F* y
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。* g  m  j+ V1 j& W
#pragma warning( disable : 4251 )2 d4 \7 S$ ~% w& `- u% z& \
( |; w9 F7 E% t: U7 L3 I
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)$ B: L) f) X& \% k7 B6 m4 _
#define LANE_SPEECH_DLL
& E6 I" p2 d9 }$ u5 W
2 n- m+ h6 Q. ]6 J+ c& i& S#endif //USE_SPEECH_DLL8 j2 K8 |; N  O7 V$ ?
" D9 A' S% i8 `8 n% |% k1 o) G

; S  J; \* {" q7 q; i9 _//***************************常量***********************
+ g( j; n! g" s4 q6 }2 g) f% z2 Y9 I+ N" B. ]
/////////公共常量-----------------# S' Q  S. e: f; N5 D1 O
const DWORD   SP_CHINESE = 0x0000; //简体中文.+ I  }4 q3 P# @
const DWORD   SP_ENGLISH = 0x0001; //英语.
/ b6 }/ j0 F! M, C6 U
( [: c# ?- z8 w/////////CTTS常量-----------------# ?) b: c( B) L" f2 F' M* q. h7 u
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。# l9 v' x; u6 v) E5 u
/ D) E' y; i, z. X8 r) q% M
/////////SR常量-------------------+ a7 p; K& B% t1 z9 o
const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。
: v4 }, ]& O) j7 }2 \8 Bconst DWORD   SR_INPROC = 0x0000; //独享类型的SR.' E3 [6 G- P9 ^' ~! d" `( V
const DWORD   SR_SHARE = 0x0001; //共享类型的SR.
% G' h# ^  w0 Z" [
$ W8 e7 l( N  S: x6 A  g! ~' W2 K//以下常量仅作例子用。
% y8 l0 Q* r% R+ r9 _' _#define VID_TopLevelRule 9000   //顶级规则ID0 u/ u+ L' |4 a3 F# ^0 `" y8 q# O2 N( }: ^
#define VID_SubLevelRule1 9001   //子规则ID
! z4 b3 P/ D- p# G8 ^#define VID_SubLevelRule2 9002   //子规则ID
, S8 ~+ F2 a% V#define VID_SubLevelRule3 9003   //子规则ID
+ \, Q: F3 p" C' W* h: O2 k' l) _, V5 \6 l! y

2 p  G& v2 ?8 z//*************************类声明************************
4 `1 J( E$ w( r2 C3 r& q& \& Z4 L" d9 Q( ^4 [9 X3 I% ^3 z, Z. @
' q9 X) Q! Y! h$ a! J5 L
class CSR;
: ?1 s/ y& \" _///////////////////////////////////////////////////////////////////////
, [# Q5 F! r& }- K  C///////////////////////////////////////////////////////////////////////! \4 o1 c6 r3 r  a6 d( _4 c1 x( q- \
//9 t  j% J. C" Z; Y+ i) I3 [7 f9 N" u
//         CTTS4 w6 u+ V, d* V6 S0 D
//
$ O/ A3 m5 v+ L$ t6 k$ U///////////////////////////////////////////////////////////////////////
1 ~- Y( k, p3 r2 w, J& S5 j& t///////////////////////////////////////////////////////////////////////
! U' l: o3 k- b2 W* j3 G3 \
  N- f. V5 ?' E# C' R( L7 `class LANE_SPEECH_DLL   CTTS9 s2 B% K; u+ Z1 R9 M1 Z! w& N; Z
{) V% @+ a% |# f& y' H% N
protected:
2 r) Z4 w7 |( k5 t: t+ h4 a9 w) tHWND       m_hWnd;     // 关联的窗口句柄。" S1 y  F) O) _# O/ T2 b" c, _

/ _0 T3 m: d% h4 R; ACComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。6 i( |5 F: o- M" w6 l
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。8 C$ `& C/ t2 [, t# W, j! ], H
CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)
( n1 M1 B; [: _9 ^CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。3 O# z3 i: X4 y3 _$ q2 ]

) M5 \& F* D6 @" [public:
2 @4 a8 T) j; h, q! N//********************************初始化部分********************0 B6 @: X" M! |/ [4 l

, i" z6 h& D' x) B/ X////////////////////////////////////////////////////////////////////
# s5 G& {! U; X6 t8 Y7 `//功能: 保存与识别引擎关联的窗口句柄。
9 W; C. {( V" f//参数: hWnd:要关联的窗口句柄。
" u8 V2 V) d; @1 v7 n1 j- F6 c2 Y1 \//返回值: 无。
' }: p! H7 ^8 B////////////////////////////////////////////////////////////////////
" r2 e8 D. A% u/ U' _$ M. u  ECTTS ( const HWND hWnd );8 Y& e) ~- |% G, {- k
4 D( e! P8 H% z2 y* g% m
////////////////////////////////////////////////////////////////////- s$ b0 F4 k( }% n4 c
//功能: 释放所有的对象。) s' i. Z, Z/ S; G
//参数: 无。
. `2 V5 z- c% {+ x//返回值: 无。
% D% b+ ~$ j- _! q7 b////////////////////////////////////////////////////////////////////
; z! J5 O: Q3 [* j0 [& W5 J~CTTS ();
! }( Y$ W5 w) D) X8 H+ N  q8 [" F  p/ m) B; M8 V! K
////////////////////////////////////////////////////////////////////
, H& R- z( G( ~( q5 x) N, L0 P, f//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。
/ L9 k' \7 N( R, g0 V) m//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,0 o& q, ?$ }/ O( L
//    SP_ENGLISH为英文。
8 g, Z. q6 @, |3 K, K+ [//返回值: HRESULT类型。& g0 C/ ?% \; ?6 Y8 x, n% F- q
////////////////////////////////////////////////////////////////////
: U: y4 [+ G. w) c+ THRESULT Create( const DWORD dwLanguage = SP_CHINESE );+ }6 q$ y6 B9 R
/ y: h) |" T7 q" B0 m' n
////////////////////////////////////////////////////////////////////
! ]6 a& Z  r: W% ~( t//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
3 d* B8 d: o6 ]9 x, P' m* g5 p//    通知事件。
% [$ V. e/ w) a: j- r- G//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类," I: Y0 z+ E1 q9 {
//    SP_CHINESE为中文,SP_ENGLISH为英文。
7 m8 V: B  \6 k//返回值: HRESULT类型。
4 E& Y6 u4 T7 v( }* H9 Y+ ]0 J////////////////////////////////////////////////////////////////////7 R" e9 B' V+ Y6 n/ U
HRESULT Create ( const CSR * pSR,- R$ p7 I' j, Y# n1 z0 B& L
       const DWORD dwLanguage = SP_CHINESE );% @* g: Q* a+ B9 q; A, g

' N+ E) c. l2 |* z5 f6 U6 ~2 x) O1 t( ]; U6 z+ O8 D: v
//********************************设置部分***************************************3 _& V$ b' |, {" c0 J* s
6 I; y% w- q, k/ O
////////////////////////////////////////////////////////////////////
/ {& c* M# \" n: t//功能: 设置朗读声音的语言种类。
/ T7 ~4 V; k, J4 H* a, E3 @- u//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。  I# D1 Q( P2 Y( R. u3 b7 y
//返回值: HRESULT类型。
# O- x/ [. s) d/ V////////////////////////////////////////////////////////////////////0 l- O: ]% ~1 z6 \! {! Z% J2 m0 \
HRESULT SetLanguage ( const DWORD dwLanguage );
5 c+ q# }' a8 `* C. q# @0 X6 C) z) [6 M
////////////////////////////////////////////////////////////////////
6 b& C1 y$ h* f% _" f0 U//功能: 设置要处理的的事件。
  R) C+ [* |7 d& _//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
6 U7 X. D) [& b! e. A//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事5 C% C: S6 C5 B) [+ h6 s5 }6 C; e
//    件都会收到通知。8 H8 t% T$ `5 G5 W. Q' L
//返回值: HRESULT。0 Z9 ~. r- J6 N2 C6 K: y
////////////////////////////////////////////////////////////////////& U3 K. k; m( C2 I
HRESULT SetInterest ( const ULONGLONG   ullInterest );
9 c. X4 s' Y) ~# D
. J' h: t( ?& t) Q* T////////////////////////////////////////////////////////////////////! U! x# f0 m$ B0 W. }( x; I
//功能: 设置朗读声音的音量。: q: q  u, J' v' [2 d
//参数: usVolume:音量数值应该从0到1004 K  a, H) f$ T  {
//返回值: 无。+ x+ i: C; D, N- S  E
///////////////////////////////////////////////////////////////////// L  D7 s* T3 \8 }
void SetVolume ( USHORT usVolume );3 G, m) B- u/ C7 Q7 b4 i' q& B

6 u- e' z' f% g: m6 y////////////////////////////////////////////////////////////////////7 L# h! l( U  c7 _" g: b
//功能: 得到朗读声音的音量。' Q: N; f9 U* o* @7 p! N
//参数: 无。
0 L" p* i% r% [( k//返回值: 音量数值,应该从0到100。8 Q& x8 C' \+ G3 x" g; F- t
////////////////////////////////////////////////////////////////////
: S5 [. S. ]& D* ]9 k3 MUSHORT GetVolume ( );
; B  r3 `' \6 a3 \1 X
3 q2 ]4 U) r9 m9 e- E3 u8 S' U////////////////////////////////////////////////////////////////////7 B& b8 |& p0 Y# c
//功能: 设置朗读声音的音速。7 [) P2 l! v, u: t  _
//参数: RateAdjust:音速,参数范围从-10到10。
5 y$ z1 \- s* K9 Z" U; Z//返回值: 无。
% B8 ]  N, T/ \! R8 P////////////////////////////////////////////////////////////////////
  V2 c' T( p% R* b" `+ A, N9 \' Hvoid SetRate ( LONG RateAdjust );
# X  c/ F' a3 ^' p
4 m5 X4 H4 i+ _2 L% M7 R/ @7 B////////////////////////////////////////////////////////////////////
  Z4 y1 V4 s9 Q  A7 _! q$ x//功能: 得到朗读声音的音速。- `0 \2 r6 W1 U) C0 R
//参数: 无。
  ?- ]5 n2 v* {4 q" Q* y+ a//返回值: 音速,参数范围从-10到10。
) F. V8 F( S3 E) ~" H* \////////////////////////////////////////////////////////////////////
9 Y0 X/ @4 C0 u. `, V9 ~LONG GetRate ( );
" ]! O" P* z1 i: i+ K
) q! _% v' X+ ]6 D////////////////////////////////////////////////////////////////////7 N, d1 @0 [2 V: m. w
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。& G. J0 t5 L5 o4 L' X8 p' W
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
6 a, {: O' U* }) n8 e7 F//返回值: HRESULT。% `! w3 T+ d. u% ^( e/ Z  l! c1 K( B
////////////////////////////////////////////////////////////////////
# ~1 N0 O. g# g2 m1 O; wHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");8 x# [9 F0 [/ u' W# }

- \! W* n/ w/ @& y* ?: B- g/ i////////////////////////////////////////////////////////////////////, G  T. u0 o5 f
//功能: 设置朗读的声音从音箱输出。5 Y2 d# I. R5 E! H
//参数: 无。2 ~' e) v) f0 P8 V6 |
//返回值: HRESULT。
5 b. ]' U  A9 ^* n" f8 [5 Y$ i////////////////////////////////////////////////////////////////////1 w3 w# m" `2 w" x+ t% d. p2 a
HRESULT UnSetOutputWithWav ();8 J$ F% \& V0 u8 d8 v
# |5 E3 F7 B( e# Q* i( e' \

/ o% |, B7 {! ?. h: J3 b//**********************播放语音,文本到语音转换部分*****************************6 I$ |' @/ ?' ~* F9 c: g
: y8 l4 f/ K& L8 J6 `
////////////////////////////////////////////////////////////////////0 c- c1 }$ l; h& T8 o0 `" q
//功能: 停止朗读。如果朗读为同步方式,则不能停止。* E8 I; R1 P! j6 ?% C; F8 `
//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记8 ^8 s3 `3 r+ z6 A$ T8 k
//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,7 s, v: ]+ @+ Q8 e
//    SVSFIsXML为朗读带xml标记的文本。
" Z  E: q  P8 |$ L( i/ O//返回值: HRESULT。
  E$ N9 y% O4 D. Z* Q////////////////////////////////////////////////////////////////////
& V3 }7 i! p: ^$ p' H8 r# A- SHRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
4 Q' k' M- {; w2 e) K; f, }/ [6 r" e) v3 Z! M
////////////////////////////////////////////////////////////////////6 `( v9 |+ q( ]* \( ?1 U
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
3 D7 c4 D; g9 T9 C5 M# d& z//参数: 无。
& y( Y: ^1 H' @' K% x3 z//返回值: 无。
( C/ x: C, a  A5 {. p////////////////////////////////////////////////////////////////////
. T3 f; ?1 ^$ A0 z9 \void Stop ( );& b0 O: `- X" l( |6 G, w9 j' l
) N; a; w# E! M/ K- G
////////////////////////////////////////////////////////////////////
* X; F* B+ y- V# w! I. `//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
, Z8 p# [7 T4 r& i$ o//参数: 无。' _8 Y1 S+ H) L" X6 I. {+ l8 w3 G
//返回值: 无。
: A+ k% m% g8 j  S- y, i8 }7 J5 \+ A////////////////////////////////////////////////////////////////////: Q( q& h* Y9 a, f( m" X% }
void Pause ();2 l' ^: \2 ?( m$ Q  F1 H, ~
0 z) `. t5 k0 i( E9 N' ]8 B1 Y: d
////////////////////////////////////////////////////////////////////
5 E' i- I; ]' w//功能: 从暂停的地方继续朗读。+ R7 J9 O' Y/ W8 \5 _3 P  Q( z
//参数: 无。3 s2 \4 v& q$ i9 a5 P
//返回值: 无。& D; B6 a+ C: N. ~7 w% K% w0 g$ t- S
///////////////////////////////////////////////////////////////////// L# G3 l! Y4 g/ s1 g/ W5 {8 V
void Resume ();
& [% Y6 I( b) a2 t" W" Z
9 V5 I6 V. h  u3 j* v$ h
5 E2 k3 T; q2 \, p//********************************处理事件部分***********************************! r& s( [# B1 @/ \8 O

* s- J4 q+ V9 J5 J- ppublic:
8 ?0 r) f  G# X; [////////////////////////////////////////////////////////////////////
" j( `/ E4 q0 g8 k: ^. c//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。4 j; M/ E% R+ b6 m) ^' @' O2 z
//参数: 无。
( ?/ U# r, _* F* z. R//返回值: 无。. p8 D2 Z4 j$ a+ y& I  v4 m# p! q
////////////////////////////////////////////////////////////////////5 t  I# R; O4 R5 E! ]- s
void ProcessTTSEvent ();
: h+ x3 T. Y4 I7 Z. a9 d, J+ a$ k0 H0 B( g9 Y2 k, p
9 i  w( I1 s! ~" W1 m6 a
////////////////////////////////////////////////////////////////////" `9 A% {. v1 D5 [( I8 v4 Q
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。1 `* c* S2 `; {: F2 n$ B
//参数: 无。
5 N9 {# |8 Q% M+ v6 J8 h5 D9 w//返回值: 无。& G) p: N. ]7 M# H5 O+ M
////////////////////////////////////////////////////////////////////
. ]. O2 T* D1 b9 C% c8 fvirtual void OnStreamStart ();
! V( @- S6 \7 n1 j: d( L2 I" i/ z3 r8 i
////////////////////////////////////////////////////////////////////
2 u1 ], A/ m+ k//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。3 z( n( A* ?- u
//参数: 无。. p1 [* a$ W8 A1 F! s/ V
//返回值: 无。
# j/ l! M  h/ V////////////////////////////////////////////////////////////////////
( u- ^8 z& o. [  F# fvirtual void OnStreamEnd ();3 a; P$ C( y! O
};
3 ]9 [/ N3 D% H: B. [2 ^) X/ F( s
7 W2 K% U" R# D0 b, w' P
* M% z# P0 X$ E6 J///////////////////////////////////////////////////////////////////////5 B7 M( c$ }; Z4 W3 M. _
///////////////////////////////////////////////////////////////////////
  F6 y7 s& @1 {//         CSR6 r( a0 b, v+ O' j
//
% D9 l# C  z" o! K6 B: L///////////////////////////////////////////////////////////////////////2 e, {& ]5 n/ K: j
///////////////////////////////////////////////////////////////////////
# u2 ^& U2 G) o+ e5 K$ A! U. B0 o- ~% X9 l
class LANE_SPEECH_DLL   CSR3 T" E, `' A& P1 `" ?
{
- o2 [: c9 j! [) M9 v) W( c, c5 X3 T. W" G2 l
protected:
( p; n; q  G8 x2 O* ?% CHWND m_hWnd;
! h" c0 V5 F0 P6 A5 Z, Y& {
1 }: A* M8 s7 t6 |: l/ p- Opublic:
& X, h$ F( w6 uCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
5 v6 d. H( P' }& }CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。" q3 V% u+ ]. I# ?9 r7 R4 W
CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。
' g7 g. k. Q- A) ^( HCComPtr<ISpStream>    m_pInputStream; // 流()的接口。
. ^/ V0 l4 e% u8 |# \  y$ C4 \CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。3 ?. s& g7 r. M7 Y, F3 n7 L
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)+ {- M3 c' ?+ y$ r' P8 D- O! q& n
public:  u( M" @( v/ K. B6 g' H: z
static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。( e9 }$ _. v9 X2 m
6 e' w' l5 w0 a) I! B
$ }5 s% [- ?5 V" @: t1 b
protected:
: k& `; O+ E0 f//***************************辅助功能部分****************************************0 c. N5 x2 F* k& V, D4 @  y
( }: C6 A! J7 ?. p2 \  C3 F
////////////////////////////////////////////////////////////////////. |/ a$ n7 V$ V- q! Z& M4 {
//GrammarID加一,每个GrammerID必须不同。
, E  t% H+ ?4 F' O5 @' R////////////////////////////////////////////////////////////////////& r8 _+ j5 j1 K9 _4 P
static void UpdateGrammerID ( );  Q  C9 d: }. R$ o; M' V1 Q  ^9 D
) g) H$ X6 Y" {! F8 l- G+ j) p* }
& t. ]5 H8 f# w$ C/ S
public:2 e3 d# L/ T2 f2 W' b! h& m2 F
////////////////////////////////////////////////////////////////////3 }0 m& I: P# B* w3 ]7 }$ R) I
//功能: 友员。TTS中的从SR引擎中建立voice对象。
  I6 D' ~" ~# B+ O  O//参数: pSRContext:SR上下文对象的指针。7 T; O* K& L  F- L- o2 D
//返回值: HRESULT类型。
; v2 n9 z1 L: p2 b( D////////////////////////////////////////////////////////////////////% U, a# x/ D' p  [
friend HRESULT CTTS::Create ( const CSR * pSR,6 g2 _) G, X5 J
          const DWORD dwLanguage );
3 _, b# I* K& u) ~$ p7 [. u1 }& o/ v& d

. Y. s  z8 c/ u/ F; N  C7 M# a; Z# c//****************************初始化部分*****************************************
' l& ]9 o3 Q: y! v  @& Y- |
0 _! V5 v+ P# R  x* \9 W& o////////////////////////////////////////////////////////////////////; K9 o& ]0 `" s
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。8 y8 w% Q7 \* Q% g% [" N  I6 D
//参数: hWnd:要关联的窗口句柄。1 q, w. D. o. a9 B5 u
//返回值: 无。
8 j0 a2 F" F( q9 X$ F) Z8 t* C////////////////////////////////////////////////////////////////////, ^' \8 M/ U. X9 \: `0 h4 O
CSR ( HWND hWnd );: y4 V- ?4 c" w' W& p! u* [

0 z1 P0 z% b$ K: g; K% ]! ?  g& T, G////////////////////////////////////////////////////////////////////
, r4 K8 ^; m/ n; K4 r//功能: 释放所有的对象。
- A, t9 P1 i. C. J% q//参数: 无。
* {# Q6 V$ R* x//返回值: 无。
& H7 o( H1 s3 x7 {- N4 \////////////////////////////////////////////////////////////////////# [" `; X6 p4 U3 j' n/ M! I
~CSR ( );7 g6 H* i  l6 ~8 |6 ]  @

" Q9 m" C' r/ m: v+ v; G# W////////////////////////////////////////////////////////////////////
9 v7 X" B, ~! D, P% c//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,0 S) X( J' ]  T4 k
//    加载文法文件。1 h" Q% x% h/ t
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
; e" e  {/ I2 @0 V' `3 r& D$ ~//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。; b7 T0 O' [9 Q4 Y: \; x! J2 H$ p$ F
//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。9 R" C! K2 @$ U, J( H2 q
//返回值: HRESULT类型。8 n; E! Z% E8 H7 Q% ?1 Y1 N
////////////////////////////////////////////////////////////////////
) j- b$ n0 y/ h8 }3 x1 uHRESULT Create (const DWORD   SRType,! V. L7 v% J% x" _7 L
      const WCHAR   *pwcGramFileName = L"grammar.xml",
- \4 ]% |: ?. l      const DWORD   dwLanguage = SP_CHINESE );
! P( b6 W: ^; N3 N* H# \+ [. Y- r( ]( g6 z; E
# H$ g4 C5 T* o- W) r
//**********************************设置部分*************************************; z2 U- q/ A. V
3 Z! d: _; F8 {' _" r* @4 ]2 I6 ]
////////////////////////////////////////////////////////////////////. D2 i. u6 K  \0 ~1 Z+ ^
//功能: 设置要处理的上下文接受的事件。) {, r  P9 m& \0 d5 [
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
5 K" J& R0 \+ g7 `3 F8 A; m//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
( `, e$ ^( c4 h* _2 J' m- H# [: O2 O//    件都会收到通知。
/ A$ ~8 [$ ~* C//返回值: HRESULT。2 X. C2 k" ^5 V+ I/ k
////////////////////////////////////////////////////////////////////
1 R$ O2 ]3 A4 L: h5 @% kHRESULT SetInterest ( const ULONGLONG   ullInterest );  Z5 L4 {+ \5 I; ]( g7 O9 c; E% Q
7 x' {, B; E# g  [1 |+ j1 f
////////////////////////////////////////////////////////////////////7 M2 n) L7 X. T( R- f! S
//功能: 设置某个规则的状态(激活或者取消激活)。
; p1 l* I  \  R9 Z; y# t//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,0 y% M0 L  `, P: G' {
//    FALSE表示取消激活。4 K7 u- R7 u) x1 r- r% Y
//返回值: HRESULT。& I. w4 M0 k+ g; L
////////////////////////////////////////////////////////////////////
: z! O! P4 s: v! e; rHRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );' J; s0 r- d9 k
0 Y3 T3 B! K! b  ^
; s6 Y9 _# s. r8 h! `: |
////////////////////////////////////////////////////////////////////
7 P# F+ R& Q& `; |: h/ p//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
. R" J# O/ ?: ^1 M5 ^" c1 H8 ]6 ]. ]//    风输入。
5 O# i  }3 D. Y# T& x9 s; h//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。' V/ c# }- A8 {, G5 V% ~6 H
//返回值: HRESULT。
& F2 @; r- x  i$ g  |  w////////////////////////////////////////////////////////////////////( K/ }1 o8 V0 ]. O0 v& y
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
3 J$ r7 ]& A% r; ~- I! p0 A4 q3 g  w- ^8 T1 g, P
////////////////////////////////////////////////////////////////////
, N" {/ U2 t) ^% M! l! [//功能: 取消从.wav文件识别。恢复从麦克风识别。4 M. G4 x" [# ~
//参数: 无。( ]& G- U& s) M6 B/ g
//返回值: HRESULT。: c$ o$ N" w* M% u  V- g& b/ X; _8 R
////////////////////////////////////////////////////////////////////2 O$ D+ a) R9 \0 |
HRESULT UnSetInputWithWav ( );
7 q) Z' K: e2 \: b, \7 c0 ]  G6 H. V/ r8 T# A
//***********************识别开始,结束,识别结果的处理**************************) _/ V9 f& F# N# W) o
$ O' d7 j6 @. F( r$ I
////////////////////////////////////////////////////////////////////
/ U) Y( z( l% M, `/ X0 V+ T//功能: 识别开始(将所有规则激活)。
( b6 X8 S/ V6 x# a) W6 n, F3 T//参数: 无1 W' u- B$ @0 t& w" J- E3 i
//返回值: 无。  _: I- r0 x# N# I
////////////////////////////////////////////////////////////////////# k8 v9 z" @" \5 Z& O+ F8 I* }
void StartRecognize ( );
: P) t. [8 a! t6 m8 `$ d
* X! m0 p+ R1 D! ]; W% k8 d////////////////////////////////////////////////////////////////////$ i5 y1 l7 c; \3 _/ b( K
//功能: 识别结束(将所有规则取消激活)。
9 O5 J$ s- I& P: k8 J2 D  [//参数: 无。
! d0 A8 Q: n  S6 v3 X/ v//返回值: 无。
2 ^. I& d3 |0 d' T$ u! S////////////////////////////////////////////////////////////////////3 Q3 ^8 D' Z1 w/ P4 c8 V
void EndRecognize ( );: u! Z2 x0 Y5 S& ]
+ W! }; G9 h8 a/ R) M
public:
8 O5 L+ p: Y' b* D+ W( F  ?////////////////////////////////////////////////////////////////////8 [* [: j  n/ q0 V1 f  C$ l
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
2 |2 z0 d5 R3 P0 J: |//参数: 无。: S: q6 E: w% o9 v7 w
//返回值: 无。
& ]4 P0 F+ Z! b4 O+ U  |& I# [+ ?1 T////////////////////////////////////////////////////////////////////
  {6 h9 A  v1 g+ Cvoid ProcessRecoEvent ( );4 ]; _* ]! N9 k: F+ X+ z2 ~
, h; v* _5 a. K* j& @( A5 M
protected:
/ K1 |  i; B0 E  \2 z9 K////////////////////////////////////////////////////////////////////2 _6 x# r# G9 I( P7 N( W
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。4 p: u, F8 y: @9 W) \& h
//参数: pPhrase:ISpPhrase类型。4 r0 U8 K1 v) B9 v
//返回值: 无。
# k! D1 z2 S' E* A0 `////////////////////////////////////////////////////////////////////$ {, L; g( o1 X) M+ N1 N
void OnRecoSuccess ( ISpPhrase *pPhrase );
! l, j# b/ Z, o/ k; a
# {  P: T+ Z6 n/ y( Fpublic:; c7 }* w  k% l- @7 o
////////////////////////////////////////////////////////////////////
* `( k/ N2 v+ l7 H3 |//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,' w" k. \: R; e3 W' B
//    需要在派生类重载。规则ID必须以常量形式预先定义。% B6 M$ Q: @+ Z& m. \4 ~
//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
4 t! }2 y9 q0 _" @( ~//返回值: 无。
, n' v. @# A  e- ^" v, H////////////////////////////////////////////////////////////////////
, {1 y$ P# ^, z4 V9 }6 kvirtual void ExecuteCommand ( const ULONG ulRuleID,
8 F$ f; A, w9 |5 J          const ULONG ulVal );7 q0 z- V9 Y( o, N, m* p
8 R8 y& i1 L  B5 |
////////////////////////////////////////////////////////////////////
; z9 Q. N9 ]% Q2 O8 R//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
6 }- T& A5 Z$ j( x//参数: 无。
6 P5 r& S0 B+ G& O# @  l//返回值: 无。
( J) H5 F9 i, A9 v$ l) b////////////////////////////////////////////////////////////////////; W5 M+ o; G1 {( D
virtual void OnRecoFail ();
7 V2 \5 B! p( ^7 \, H4 A
: {+ x6 B- U4 y2 T' `  Z////////////////////////////////////////////////////////////////////% t0 U" ~( u6 m. B2 R# ?
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
5 b+ N! [+ y9 K1 ]' b//参数: 无。
; I; c8 f$ S& A0 W; [//返回值: 无。
) S  u9 f0 x! R! z////////////////////////////////////////////////////////////////////
' r0 r8 n& f, V  x# X: Evirtual void OnStreamStart ();3 y. G6 Y( \! ~3 J
: D% [/ f( U) i; ?2 Z5 \
////////////////////////////////////////////////////////////////////
; I+ X, {; V$ j//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
9 s* ~% `0 M3 `, }: L1 K+ Y//参数: 无。# z: a- Q) f, F4 Z7 ^& t( r+ b& Z
//返回值: 无。
: o6 B; A- p0 y! P* k, d* I5 {////////////////////////////////////////////////////////////////////
0 S' e) e' n: X5 dvirtual void OnStreamEnd ();
1 U9 N) Y0 e) v% o0 z1 v) y8 D5 p$ E# T8 K" c1 c8 I! l- i
};
+ d  v. |3 T9 \% ?# L  S) P( D9 K
1 G& S9 W, c( Z5 n
5 `/ h6 X- ^/ S) t8 @
0 i7 S: q! n  z1 k* o+ ^/ q% z- l#endif    //LANE_SPEECH_DLL_H
6 q4 r6 C# A$ a; _! Q& k: \* o9 C6 f" f& \$ x7 ^5 l  P
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5 s% L6 Z2 @% T: y6 }2 ~
, v6 g2 f, r) F+ w7 V////////////////////////////////////////////////////////
: I& b, B- \9 _' S& H3 L//
  Q( W8 k* w4 U- `6 J7 Q// 文件:LaneSpeech.cpp
7 a% [( ?2 ?: h1 ]- T9 L/ X// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
: I8 t, K, R' b* C4 S+ s( z' s//    语音识别只支持命令模式,不支持连续模式' A9 L( X( D3 q) T4 u2 P
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908/ H) ?1 w( g0 G* N0 |  ]
// 日期: 2004.10% R! \( r: m% G& d2 S$ @3 p, L" H
// 版本:1.2
0 Z9 [+ W0 ?5 x0 c% b( [* N//
  J+ C9 @% Z+ G8 S  n//3 C4 ^# W3 Y! C
////////////////////////////////////////////////////////
, z( M; H& t- d0 S5 ]* m1 w' l* b+ Q; J! ^% c+ b# `) {" ?
9 q8 m5 o- T/ m8 H) i: i7 \
# S' M; ^& ~- n7 M
#include "LaneSpeech.h"2 h& ^" @2 k$ S: H
$ h- g9 e% t# S" J
//-----生成动态连接库和静态库的处理----------------& Y% o! X/ j$ T+ t# a: w, k! i
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类" Q' s# b3 B) D3 H
3 k" e# _( s% k9 H# U2 {& q
BOOL APIENTRY DllMain( HANDLE hModule, . |: Q# s/ g1 i7 n: N# c
                       DWORD ul_reason_for_call,
8 G  }0 H' q/ M1 E+ T% Y0 q                       LPVOID lpReserved$ ]: R! t* {2 {4 r5 O, [
      )
0 }. x$ T+ J5 Z# M. M4 w: `: I{
6 X/ X; H8 {( p+ O    switch (ul_reason_for_call)
; h' f% o* h- t; t: r' O! r0 Y3 L{8 |2 j2 D6 Y* ~& @) k4 l' Q( E  `
   case DLL_PROCESS_ATTACH:$ t* {, j: j+ W- @: @, F- \
    CoInitialize(NULL);
* y, J6 ]8 m3 N0 m. b# w7 w7 ~    break;0 f3 n  o' g2 X" v+ i
  1 y! e, z4 V+ S# i1 P' S9 Q0 ^2 X
   case DLL_THREAD_ATTACH:
0 i: v3 L% q/ f$ O- ~9 w! u8 ~    break;: f2 W5 U: y# e
  
2 }2 m0 _# T' l* b0 x7 a   case DLL_THREAD_DETACH:; b& O  S/ u0 B3 `6 D# @
    break;+ R8 T5 R+ z9 q2 t; O- t
  3 R* r" y* f& d* |) H0 L
   case DLL_PROCESS_DETACH:
0 {/ F. n8 n0 V! ^    CoUninitialize();& c( n& l: R/ V. Q3 a3 n7 y6 }9 _
    break;; f) W8 R, X2 y* O6 h* L2 `9 R' Y9 V
    }4 p7 j+ |/ F0 A. C+ D5 W
    return TRUE;
9 {1 ~0 p; X, D2 T( G- ?( ~" @}! T5 S6 w! s1 f7 W1 w) h

0 i  G( ]( {0 ~  _" D#endif //USE_SPEECH_DLL$ ?1 H  }% V% O) M; f& Z3 i
* {! X5 Q' t0 y+ V4 Q. f0 T0 x

$ w( y- D0 [5 b
! ?  M( c8 `; M( Z0 Q///////////////////////////////////////////////////////////////
6 ~; H! O! d7 W% r% f7 C5 _2 w+ v4 C
////////////////////////////////////////////////////////////////////) g, f' R  o9 T8 v* c3 R" @/ @
//功能: 弹出一个信息框。
( Q1 h+ z: @" w6 R8 \7 Y//参数: lpText:是对话框信息。lpCaption:对话框标题。
/ L3 K9 X* h% X! ]! I- B8 P//返回值: 无。) ~* A! u5 E* D
////////////////////////////////////////////////////////////////////
! b( P. S% v9 _; e, ?8 H/ cinline void ShowError ( const LPCTSTR lpText = "ERROR",
6 ^; N! u4 @8 W. d  R$ _1 d        const LPCTSTR lpCaption = "ERROR" )
1 p+ N# O( d7 N) k9 S{
/ p5 |. z% X  u   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
! S: `/ Q' O8 |+ j, S* a$ s}
2 X* I7 x  H" j) }2 t
$ V1 H$ ~9 c' H, n1 q. a  [( d////////////////////////////////////////////////////////////////////
% d7 }6 b* Y6 J8 ]5 f9 C//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。/ K/ A$ B& v( I" c
//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
; P; ]# J2 e; K& O" R% o//    lpCaption:对话框标题。3 h  j5 v; j$ [1 }! S2 m: t
//返回值: 有错则为FALSE,没错则返回TRUE。! L9 I, Q4 M# J
////////////////////////////////////////////////////////////////////7 P9 K3 J* O7 N: `
inline BOOL CheckHr ( const HRESULT &hr,
0 a5 |# W9 t* W" O# w8 d        const LPCTSTR lpText = "ERROR",4 M: p( N* b! j. E( F
        const LPCTSTR   lpCaption = "ERROR" )5 o) D5 U- |7 _
{% ~* B8 Y/ ~5 D2 ?& g# F
   if ( FAILED( hr ) ) {
; x/ b1 ~" y1 v- M: [/ ]    ShowError ( lpText, lpCaption );
. p% U. {4 G' {/ a    return FALSE;0 e8 d' y! w7 @) W
   }3 J, t& ]4 j4 y* ]% Z8 e; j
   return TRUE;
; ~0 U' K4 M' V. H/ ^}: T8 H+ }( A! Q% C3 k' Q

! Q2 D/ o) D% A/ P4 g+ H% T. |" y+ f! C/ n
///////////////////////////////////////////////////////////////////////' i3 L) K5 j& q: S3 b: U' ]
///////////////////////////////////////////////////////////////////////
9 w' b2 K: E5 E$ w3 ?/ B6 |/ O//- y) J. ^6 ?' c  t: u4 W1 x5 V1 s
//         CTTS
1 c, u$ `  ]) j; x//% u" |% |& Z( m& W
///////////////////////////////////////////////////////////////////////
( i3 G) j( |% [* G///////////////////////////////////////////////////////////////////////, J& Z$ x" W# b% A+ C2 L0 f0 D

: b, C- p! z4 b) Z2 [////////////////////////////////////////////////////////////////////: n! |$ I6 T* A
//保存关联窗口句柄。初始化COM。# h# n0 d% p* n7 \5 g" c$ X
////////////////////////////////////////////////////////////////////2 H# }5 {& O, o' [
CTTS::CTTS ( const HWND hWnd )
0 W' _3 v3 h% y/ {{
* _/ {( w2 _+ w& s3 Mm_hWnd    = hWnd;; U8 w4 p: a% l$ T% a& a
m_pVoice   = NULL;, ~3 X; Z1 g3 z& Y" w9 X" J- `) ^! k
m_pToken   = NULL;4 M$ R  ~  I, [4 K. p7 z4 {0 _6 v
m_pOutputStream = NULL;; T: X, D+ h+ S& W3 _
m_pAudio   = NULL;0 I' {+ z. \7 x$ ^! E, O9 N
}
0 O8 p  H0 Z& T& q! F! Z) A& W
3 \! d) M1 x! u% M: d////////////////////////////////////////////////////////////////////
+ H' _) H: w3 f0 B8 j//释放所有对象。
, L: J9 x- }& P3 \////////////////////////////////////////////////////////////////////, i" [% t; f6 I3 E
CTTS::~CTTS (): K& N  N! _; q: M( c
{8 l( [7 g9 V; x9 V$ ?
if( m_pToken) {  K" S6 s$ a# k' [* C! H
   m_pToken.Release();
9 B8 @$ }' y/ v1 @9 l& V* Z   m_pToken = NULL;
% G6 j; B) E2 C' L/ U3 Z8 F7 K+ q# v}
" N5 o$ A  ?# s' J& fif( m_pAudio ) {
0 C7 S) ?# J+ D0 D! N   m_pAudio.Release();" O% \. G# V5 u5 a/ \& e
   m_pAudio = NULL;+ e+ z- ^$ K& l) O& _
}0 H% Q% a8 `) M+ O0 W
if ( m_pOutputStream ) {
! p8 {0 C2 G! @" \2 g% n8 S   m_pOutputStream.Release();5 N% A9 E& u) C& ?; h
   m_pOutputStream = NULL;
1 b9 Z8 t8 x/ Z% H3 G}
! `9 p, I: D5 ^0 m9 Mif( m_pVoice ) {
& ^# i; N6 m5 k/ b% J9 g   m_pVoice.Release();  d. m, |% [6 Y3 T
   m_pVoice = NULL;% K3 Y% _  z' a
}
$ G+ M8 d2 {1 F5 F- x}
% ^8 P7 E# L+ T: H8 H
/ t( }, T. h/ s- y) T* M. q, M3 C////////////////////////////////////////////////////////////////////
0 K% I% \1 y3 O  u* u5 |. h! G//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。+ c3 l. B0 t9 g" f3 n4 k
////////////////////////////////////////////////////////////////////
& Y4 G2 F+ O' HHRESULT CTTS::Create( const CSR * pSR,
9 u, e+ s/ d/ t6 n7 }* V0 \       const DWORD dwLanguage )
6 r4 D* d7 m: Y9 q6 R{+ Q' ]0 j! H$ m& Z' @
HRESULT hr;
8 M$ n& g* q3 o7 t4 ^0 B0 F. n% Yhr = pSR->m_pSRContext->GetVoice ( &m_pVoice );  F% W9 S; F5 W2 O
if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
" ~' i7 h' z' S4 {1 P   return hr;
! A' ^9 r; `0 U# g+ v* I}, ]+ }- h: i6 h) Z

& b4 m6 Y2 s0 t0 g+ O- h, LSetLanguage ( dwLanguage );
$ u, G' t. H' K# C; l- a
* S. ?" p$ U0 p1 t- K5 i2 i, Uhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流( n4 T8 e4 J$ ~* |: L! F2 N# t
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {  n  A# Z$ o8 @! s* y
    return hr;
+ b9 t+ d) d, g; V* C. `+ V! T& C}
: Q+ L0 Y! `2 s. ]8 b- z9 [' s
$ z, \* z& f# I' O0 r, z//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM1 C0 U7 g+ P1 E9 w+ _
//SPEI_END_INPUT_STREAM 表示完成流输出。
9 j& p  D# a" q( D( E/ |+ V, Bhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |& [6 I% C. q2 E6 o6 t6 N# h
         SPFEI( SPEI_END_INPUT_STREAM ),
, [0 G& e0 r  K4 L& b0 a2 t) H            SPFEI( SPEI_START_INPUT_STREAM ) |' C- W  K) Q# H4 H) c  M
            SPFEI( SPEI_END_INPUT_STREAM ) );
9 X+ d- F  m0 I8 o! V; tif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {. S$ r( h) z) c( n. j5 T. a
    return hr;
2 c- b5 I8 f; U; s5 o}& @7 V+ ^; j* A; b$ H* v' h

0 d8 m$ \& @% o$ Y7 e//设置通知消息4 ~! a; S2 z$ b1 u9 N
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
7 k1 a: i8 e1 r# Xif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {  h4 x, Z* i3 k: l& ]
    return hr;
6 q9 J8 B( k4 U  p# C4 M* }$ d) a7 x}! h# B4 \. g/ S9 F( a
# p* f0 B: e/ S4 c3 ?- m
return hr;6 ~) J9 |( F  N7 G/ N- z
}3 p" n0 A4 Y. F0 O7 c

. B( S. n8 ~( e; f////////////////////////////////////////////////////////////////////
  U1 _$ @7 r' w6 L! Y" C& v//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
5 t# L: x( F4 m/ F//并设置兴趣,设置通知事件。
& P9 N, r  Q0 X& m- E$ M////////////////////////////////////////////////////////////////////  l  d  O3 g' [2 @0 R8 e
HRESULT CTTS::Create( const DWORD dwLanguage )- m0 M' T# S7 U) {
{; c- K2 m8 h, V- g3 X0 A+ [! W  j
HRESULT hr;; d9 X2 E  f9 z- h- B8 X
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
8 `. M1 K( g9 z! _: @, b1 y; pif ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {
" S; Z; P7 ^" x6 c* h   return hr;( m" ^# j3 B: z/ `) e5 c* o
}
4 H* E- @* r8 Y& d& H% t2 \$ m
7 G7 J# W& H) C* eSetLanguage ( dwLanguage );7 u: v, ]3 }  h
" G2 J( v0 |! T: ]8 H: F
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流; i: k* Z6 @2 o+ M2 B
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
# C" n+ W2 ]' [+ m4 [    return hr;
4 B2 D( T  q* M: v) s- X; r}* l0 t0 @: f8 j0 i4 i1 {$ q2 j

/ g/ y. e1 s. j//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM4 R: s8 t5 ]1 Z
//SPEI_END_INPUT_STREAM 表示完成流输出。1 I+ p# G6 N4 W, @
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
- v+ C' [  H$ ~7 n         SPFEI( SPEI_END_INPUT_STREAM ),1 }7 N3 ?( ?/ e# p6 C: [1 s
            SPFEI( SPEI_START_INPUT_STREAM ) |5 T2 c5 _0 @3 g
            SPFEI( SPEI_END_INPUT_STREAM ) );, t# f; X3 Y! |4 l
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
6 _! g; h1 Q0 }  g( y0 {7 u. k    return hr;# k: ^' h9 b2 O/ ~
}
1 f# F9 Y4 R4 r: T, c2 c
! U5 e7 F7 q6 z- A: Y% d: m; ?! u//设置通知消息
: `4 y  P/ a' L. Ahr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
1 E, V& P0 C* H6 U( K6 f( ^/ pif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
+ E4 _& {; k7 I0 u6 z3 H    return hr;
9 L% ~- {7 N9 [3 e9 H9 }  X% k}7 G; ~8 ?' t& \: M

0 }7 t2 b: a2 m3 p: M, preturn hr;
9 v6 m* P; C) f9 X1 i3 Z}
# c1 T" |- {9 J, }6 b  K
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件
, z+ g% T7 L. |#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()* m! A& }" u+ R5 }9 J* ]! N
{$ j0 P7 Z$ x0 z% S7 e" U; B% X2 I, L
    ::CoInitialize(NULL);//初始化语音环境
$ R" R) f0 w$ F6 c  k: R8 D    ISpVoice * pSpVoice = NULL;//初始化语音变量
9 X& T: I5 n% G; x; g. ]0 L    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
, c& ~( Q' E* H0 X# h# i! z6 j4 f% G        cout << "Failed to create instance of ISpVoice!" << endl;   F& C* S, w' b' ~7 `
        return -1; 2 x% S/ V8 A9 d2 V; h; J9 Z
    }

& H. ]& W' N% K9 B    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
4 n) j+ f0 f8 I2 h    ::CoUninitialize();//释放语音环境
& w7 s; b# b  o% b, i0 F
    return 0;
/ Z+ |4 s4 [; Q* z}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序) s4 k% y( S: W. {. _0 J( J. s

2 U2 f2 B0 E6 Z# u% _) s1 s/ K1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
- \  q0 P  `& f/ e2 f! c8 [% n$ `5 V
/ m9 h2 g- f7 E3 B" \/ C, B4 N3 M5 @http://download.microsoft.com/do ... -US/speechsdk51.exe   
7 X6 a1 w2 Y. u! XSpeech SDK 5.1安装包 (68   MB)     ! R7 H8 N( Y# K+ g
http://download.microsoft.com/do ... chsdk51LangPack.exe      ! e; P0 Y2 X- h. h. t+ E) Y
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
) q( Y1 G* x7 A' c) T' G& V- w2 X+ o
2.下载后,执行安装
' S% A+ V* Y, a% A8 H7 }. n- ?
/ L( d' B% k% y' _8 \下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
. d, o. l0 b. n/ Q5 n* T' C1 D! `* @$ q" H4 r2 Z( S
3.VC的环境配置
. v' u) Q/ B. _$ l: D: h
' E: @% _! m# `3 a& C2 t( G在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
. o$ e) D+ d( W, x
" _, p5 B, H& c工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
1 U0 A# N& ?% h. `8 x/ Z! w8 f! \4 u5 d" @5 e- P7 [" W
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~" w. V3 {2 b) N5 b9 x3 Z1 j: A; H- Q
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-4 23:22 , Processed in 0.016401 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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