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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
6 y1 A4 z" ~" ?! v' W//1,生成动态连接库时,要#define USE_SPEECH_DLL,
. j9 |9 n) Y: d* a//      并且#define LANE_SPEECH_EXPORTS5 G1 b, i. z/ ~# \
//2,使用动态连接库时,要#define USE_SPEECH_DLL. Q* s8 J7 H: ]; T5 G& q5 J
//3,声称和使用静态连接库时,什么都不需要
- N* |2 n! k8 M" v# g, o' ?% l; @9 H  m//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),; x9 ~7 X3 \2 M. q" @
//      动态连接库就不用调用了。! d* V8 z+ i" ^5 m  v
////////////////////////////////////////////////////////
8 S" u- d- D+ \  W- f5 M  I#ifndef LANE_SPEECH_H
0 A4 j" ]  [/ L) h#define LANE_SPEECH_H
2 \" `; c5 J2 U' u7 z% S2 o  Z) r  A+ k: o( X
#include <windows.h>
& s. L9 i6 v# b6 f#define _ATL_APARTMENT_THREADED" A1 _1 _) ^  ^# j$ p& H
#include <atlbase.h>
0 I3 o/ p: r5 y& k) r. O- 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 _Module
# H- e4 t' o/ P- R5 i; |#include <atlcom.h>
: O( F  s* |+ N% A/ F. @. [#include <sphelper.h>   //sapi需要的头文件* M2 }) U  e) ~2 T% F- q
, w5 L' o# t3 Y$ q) g
//-----生成动态连接库和静态库的处理----------------
2 P: I7 X* p+ g+ V8 k* ?! i2 l#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
: @6 ?( B8 G% B7 Q
0 \8 }; S6 x  }6 f$ h#ifdef LANE_SPEECH_EXPORTS2 G# {6 J& T7 O2 a8 P
   #define LANE_SPEECH_DLL __declspec(dllexport)
5 n% u2 x- ~8 \( C$ E#else
. S/ y* A) j7 @& |   #define LANE_SPEECH_DLL __declspec(dllimport)0 n3 _* f$ @# L, b7 U
#endif
2 `  M; X- A4 X7 e  C, W1 l5 U' B! U& X' C; O' M* U
//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关* h' s2 w  @+ n# y+ h0 j: q
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
. a# C( P6 E; _! R! `+ O( [#pragma warning( disable : 4251 )
8 H* \' q: W8 x7 g. t) C# R. \7 Q, e/ a$ A1 U6 o% B
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)/ r2 ]3 p3 l! h; c* ?3 G$ o
#define LANE_SPEECH_DLL
2 z1 U; k4 ~: ]% K! W' n2 n4 E8 s! l/ _. @. r1 n7 h
#endif //USE_SPEECH_DLL- }' b# Y: [! \# F& a9 z
# T" _5 ?) |: s  P

, h- Z9 t% j7 E, I0 u- y$ l//***************************常量***********************
+ ]" ]: W* |+ E) t/ d6 ?& k  K# J) q4 t
/////////公共常量-----------------
( F( \$ R0 j" @) s, K; f5 Bconst DWORD   SP_CHINESE = 0x0000; //简体中文.
5 e% g5 z0 i, |( K& Sconst DWORD   SP_ENGLISH = 0x0001; //英语.
( V1 b: A* d" x* d& J3 |3 v6 k6 ]! o: o
/////////CTTS常量-----------------0 h" e, x5 T6 ^* V
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。; l! I0 t- I+ Z/ C& e' W$ C
+ N* K! L( S6 ^4 J
/////////SR常量-------------------
; s! X$ e$ D9 Nconst UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。5 ?" e; E4 g* |* T! `8 E
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
3 x: b! x# E( _0 x  P+ x% uconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.
# z% O/ K8 c$ Z* q: {- ]1 Y( t
. \$ @  h' [( o, j- y//以下常量仅作例子用。
  F4 Z4 G# |4 U0 \) v" {% }#define VID_TopLevelRule 9000   //顶级规则ID
0 X- A: u4 c) k) \5 i#define VID_SubLevelRule1 9001   //子规则ID
2 b4 T  \4 }( b; F* L  L- E#define VID_SubLevelRule2 9002   //子规则ID
. \8 Q8 f1 n6 O9 y3 y. ?5 Q#define VID_SubLevelRule3 9003   //子规则ID$ K! ^: Y1 J% w: t$ l* r. ?6 C( `
* w  J, r* m4 [# C9 T
2 Z/ E/ I) d# h! S8 U
//*************************类声明************************2 o6 }4 |  X% ~5 B9 _9 Q2 J

* ]3 L5 ?. X, \7 ^4 j6 _1 r8 L' U
, q2 Z. z4 v7 _, S' eclass CSR;
2 |$ z3 A  }# y& k0 C: h& W///////////////////////////////////////////////////////////////////////7 Q, o4 Y- _; [9 w; p' Y
///////////////////////////////////////////////////////////////////////+ }# T5 g8 [6 B* g# M
//+ y% @# u8 A2 T' F* k1 U- y2 O9 l7 P
//         CTTS
1 q/ I9 o8 k* L1 y7 W//3 s3 e* R1 E  e8 E" G1 M9 h- s* V
///////////////////////////////////////////////////////////////////////- f( U# d" o9 `  \0 N
//////////////////////////////////////////////////////////////////////// s" V8 E2 ]' K

8 p$ T( u2 ~' Z) X' Vclass LANE_SPEECH_DLL   CTTS
! c) X$ @  C* W$ ^/ I3 n{& w+ R& K& Z  Q2 o! s2 _6 A, K
protected:+ S9 _5 d, T7 |; v8 Q! y$ w- H
HWND       m_hWnd;     // 关联的窗口句柄。
9 f5 y9 u& m- ~
2 l. g, A" u* f4 i8 tCComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。, p3 V# u. W# f& W" `3 U
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
5 w/ A8 b  G5 j# f9 H6 RCComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)9 i& p4 ]) l3 m2 L3 T8 d* O1 u9 x
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。8 O0 r, o" ~2 a& t7 }

8 Q4 I( F. B; w. ?* h$ apublic:% V0 n0 h6 U2 C5 x; m' M8 U5 Z: P' S' E
//********************************初始化部分********************6 I" V* N$ a, J' Q

+ }, O/ m+ \' a4 K0 o: Z////////////////////////////////////////////////////////////////////" l- W1 G7 s  e% G: ]$ ^
//功能: 保存与识别引擎关联的窗口句柄。4 e- q+ L$ X* L! J& R
//参数: hWnd:要关联的窗口句柄。
# K0 I, }0 R& |/ n( j//返回值: 无。# @0 Z+ r: h7 U: o( x& g% P9 S9 e! g
////////////////////////////////////////////////////////////////////
- G- q4 l  ^* ^1 O5 QCTTS ( const HWND hWnd );
# x. {2 ]* N) A) J' j3 r6 j! a3 k# f0 u; F6 S4 I
////////////////////////////////////////////////////////////////////
6 H: J8 c1 I: }  l! @8 K* m" P  `8 p//功能: 释放所有的对象。- t% p; I% P2 l! x( u0 X/ l, p) Q( e
//参数: 无。' \$ n" \! _9 h' a% ~- z- n
//返回值: 无。9 s( J) _, w" G. ^( M7 n5 D7 n
////////////////////////////////////////////////////////////////////
! ]! ]; ^+ ?# ^" v. k5 z  Z~CTTS ();# [  G9 X' {# l; }) S' n3 i
; t* A# O: M. r) L* t0 J0 V
////////////////////////////////////////////////////////////////////; C7 F0 |- m& B
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。- |' Y( {! w" M: F8 a
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
' u* V& Z% s( e& j& V//    SP_ENGLISH为英文。$ Q# }" n. ]) v. @; B
//返回值: HRESULT类型。
! F! d* c" K# N1 a////////////////////////////////////////////////////////////////////
4 U; G4 B1 M9 z& F7 gHRESULT Create( const DWORD dwLanguage = SP_CHINESE );( ^1 `# V8 S# J" v- e% l

( t* R  Z. s" L////////////////////////////////////////////////////////////////////
2 F5 q% r6 Y7 I; R* c//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
6 M# S/ {3 G4 n- Y4 u$ u0 q//    通知事件。
6 j/ s, s. {. F0 R: N9 f6 }//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,+ ?* F' d" ]3 I% m) A/ P
//    SP_CHINESE为中文,SP_ENGLISH为英文。5 J0 B* r- {; R& U
//返回值: HRESULT类型。) I2 c9 O: Q& H7 e
////////////////////////////////////////////////////////////////////
9 M. ~  a3 g* q1 W+ J" |* i" r; KHRESULT Create ( const CSR * pSR,
9 A1 @, l9 v, L: Y4 |6 q       const DWORD dwLanguage = SP_CHINESE );- V1 A, h# V9 e: V7 J/ X7 |! b+ Z

$ q  d% x5 `7 q/ h: A- k3 S
) `& W# x  I- ]+ D# T; w8 w4 r/ l//********************************设置部分***************************************
9 S  f# Z8 @9 [- m2 l
" {- p/ {' w* f6 m5 x$ T////////////////////////////////////////////////////////////////////
) \" c1 g# }- w4 t//功能: 设置朗读声音的语言种类。& R9 ^" ]' C" [6 G& @, F/ P
//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
) K8 W/ X3 q# u; l9 {" w, |7 e! G. ^//返回值: HRESULT类型。/ W, [4 p1 [9 s$ |
////////////////////////////////////////////////////////////////////
$ B2 m$ p+ [4 `9 F. B( N3 BHRESULT SetLanguage ( const DWORD dwLanguage );
+ E1 ~' [6 N8 i4 d' U$ G6 b* [2 [0 x9 n. Y/ T
////////////////////////////////////////////////////////////////////
1 ]8 Q7 ?- v9 p1 i) j//功能: 设置要处理的的事件。5 n& T4 ^  a7 s- E7 ]3 \
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
4 k8 N& Y6 p, ]2 [- S//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
* j( I' N9 a4 W. ?/ e  C: n//    件都会收到通知。* U8 V' A( z( B: m) r1 |7 @
//返回值: HRESULT。" a% k" R3 G& c& @  @$ s  g& Y
////////////////////////////////////////////////////////////////////3 ^6 o; H/ w. H8 _/ Z( \
HRESULT SetInterest ( const ULONGLONG   ullInterest );
0 ]7 Y7 z& z7 t% S) }7 `3 x: w. Q/ x8 A2 L& p: r# U/ v: V6 x: a
////////////////////////////////////////////////////////////////////( n! p" a" J( Q  s7 ?0 E* O# J2 A
//功能: 设置朗读声音的音量。# Z- B+ ^3 {! j
//参数: usVolume:音量数值应该从0到100
: W2 n' N/ s: R//返回值: 无。
0 g6 r1 f" r3 e! G  J; c9 w////////////////////////////////////////////////////////////////////
  p( I! n% O7 P7 ]void SetVolume ( USHORT usVolume );
+ J3 v3 k5 c( Q" k
( v, G3 B# U4 L$ l7 P////////////////////////////////////////////////////////////////////, d. @& Q  _% H3 l* z2 ?
//功能: 得到朗读声音的音量。
$ H5 Y3 i& d- z9 `; _8 g1 Q. V//参数: 无。: V/ w; H8 S+ ]2 {
//返回值: 音量数值,应该从0到100。
# ^6 m2 ?0 b$ C: F: v( D////////////////////////////////////////////////////////////////////2 c$ Y$ J; Q) Z' z! u
USHORT GetVolume ( );( n  E2 J; ^6 r: U
3 r" I& a2 `% X! h
////////////////////////////////////////////////////////////////////4 x$ b5 o  Y3 A# S- D! o
//功能: 设置朗读声音的音速。
0 P8 K. k7 p, p//参数: RateAdjust:音速,参数范围从-10到10。
0 Z7 D9 b8 s! p0 N+ f3 o//返回值: 无。
: ^% Q' a) M3 ^8 g  D, U8 \% d////////////////////////////////////////////////////////////////////3 r6 b, M" P# U3 I( q1 \: ]
void SetRate ( LONG RateAdjust );
# L' u& P# {, r. R$ a2 {  S2 s! X' _
4 F: J* o  ]% j! Q) h6 l////////////////////////////////////////////////////////////////////
& u" u: `' \4 c* n5 p9 P" \//功能: 得到朗读声音的音速。; d" A! M8 p' W# j
//参数: 无。
5 K2 @) C* Q& p9 R//返回值: 音速,参数范围从-10到10。, h# Y" Q/ ?$ a  Y+ ?+ g) D
////////////////////////////////////////////////////////////////////( M! T# A3 D6 p; {7 z3 K) c
LONG GetRate ( );
# f9 k( O5 V7 d! i6 X
) B& H, \8 G+ r////////////////////////////////////////////////////////////////////
- I4 U  t# j, F+ }9 o# {//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。# H- n5 v+ v" s+ |+ a. u
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。' g( l3 R, F. d2 n* d
//返回值: HRESULT。, W; F. W8 x0 ^
////////////////////////////////////////////////////////////////////3 g; Q5 y* l+ L6 k' C$ K' _8 p6 X
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");6 p+ I% X0 W6 Z/ n8 z1 V, w( m

; O$ d3 `7 ^* B+ @! R////////////////////////////////////////////////////////////////////3 Y, ?! N/ z; Q3 J
//功能: 设置朗读的声音从音箱输出。: g7 }# S8 ?, R6 H. D
//参数: 无。
0 h6 b0 b8 f0 d) B8 u//返回值: HRESULT。; b4 w  W4 {7 f3 n
////////////////////////////////////////////////////////////////////' K4 k0 m2 u/ G+ I4 p
HRESULT UnSetOutputWithWav ();
, O" m3 T+ O7 }% H9 D- T6 i; n3 W' ?9 ^% l* ~

* B  s, e5 K4 a$ M5 I//**********************播放语音,文本到语音转换部分*****************************$ {9 N3 q- M4 p' Y, M
% Y: [; [" P2 y) D
////////////////////////////////////////////////////////////////////9 z$ q% `$ T! j% g  D! [6 B
//功能: 停止朗读。如果朗读为同步方式,则不能停止。! Z# e! c  a" g
//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记2 Q7 L: h* x% `8 A" u
//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,, h( R% j+ ]9 L& }5 i
//    SVSFIsXML为朗读带xml标记的文本。
4 N# _2 x4 k/ [: E" o//返回值: HRESULT。
% ]+ l9 x6 i; O$ j  v- e* M////////////////////////////////////////////////////////////////////
  G2 ]" g  Q) e0 S' AHRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
0 e* t5 V9 l5 a& P
  Z( m- f. b6 c, g* z////////////////////////////////////////////////////////////////////
, {7 j- E5 |" S7 m2 e//功能: 停止朗读。如果朗读为同步方式,则不能停止。3 |1 X- v) G& a& g1 K$ l$ Q% ^' _
//参数: 无。6 `. z; q* c2 Z
//返回值: 无。& Q: }+ I: e  [
////////////////////////////////////////////////////////////////////
$ ?7 x! Z7 r! X0 Q5 s7 K( Z! k0 qvoid Stop ( );& ^2 }; N! b( A5 {3 m

: o0 _" J8 T  N////////////////////////////////////////////////////////////////////( M+ i. K$ I1 S& n, y' E6 F' H
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。. E0 o3 E. A& q  s5 L' K5 {
//参数: 无。
7 c5 b% {4 ^/ C$ N, q. O/ j//返回值: 无。1 n, u; O% e2 y% A4 M  \
////////////////////////////////////////////////////////////////////
# g$ ?  G' t; `0 cvoid Pause ();, P; ~' \9 h" y5 \8 _

( S+ g) |+ }9 ~* W0 a////////////////////////////////////////////////////////////////////
% Z6 C6 j2 j9 T4 k4 n* E7 O//功能: 从暂停的地方继续朗读。, I3 l! ^1 C; H8 ]
//参数: 无。) m1 @" i8 G$ s# [0 z2 s) B
//返回值: 无。8 |$ q# a  P( h2 y
////////////////////////////////////////////////////////////////////
  s& d: Q' J( h7 O0 p) evoid Resume ();4 M& ]2 Z) U9 ], T1 g! ~

  A. M! |" B; N& {& U: b& x
' L7 R# f" z9 s- G//********************************处理事件部分***********************************9 `, ^: i! D( M5 ~/ _/ \% i) y% b5 \

( v- z1 n+ U) B& K  a  n. J  p, jpublic:
7 T% [9 H, X" t' D+ h% y% e////////////////////////////////////////////////////////////////////7 _# r- n6 y, `- c; g8 @3 ]
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
0 M  \3 t' B! g* O& B( y//参数: 无。
, p9 q2 w) U0 L0 O% H! s' \//返回值: 无。) f) S9 u$ j, z, g
////////////////////////////////////////////////////////////////////, T( {& a# d: e, n
void ProcessTTSEvent ();
7 c6 A3 Q* I2 m) x( E
- W+ ~  Q2 ]& R7 G$ U- c- E% E
7 R# Z) i& v: G$ d////////////////////////////////////////////////////////////////////
" ^, G5 r# X" r9 c6 \//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。' ]: L, X' R1 ^  _9 n6 D- Q$ W6 ?
//参数: 无。4 C* s+ N. g! p& t* I! z' O
//返回值: 无。, T; H4 K* [% R# R
////////////////////////////////////////////////////////////////////1 W, [* a2 G# @) `! [8 ^: Q
virtual void OnStreamStart ();4 M! @) k! @4 g: ^8 L

" U/ Q. j; L: s* H////////////////////////////////////////////////////////////////////' P  ^' I# i6 _+ G
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
. w$ n. J; m4 ?1 `: Z% V$ U1 J" q//参数: 无。
$ T# `" Z: P8 i$ \- Y  ^//返回值: 无。
3 M. S6 `% w3 r: j6 r; b////////////////////////////////////////////////////////////////////$ h, m  }4 @1 j, S% d, ?8 |
virtual void OnStreamEnd ();
6 d: W& v; h/ E- u$ b};* D# O8 e- X( v; d% V
' D% j( r0 `2 L$ `0 Y2 q

& J6 p8 u) Z! n: U4 t/ J///////////////////////////////////////////////////////////////////////9 K( l  ^1 Z+ |% a' H# V; {1 D
///////////////////////////////////////////////////////////////////////9 M) j. t6 \: ]8 K
//         CSR
2 l" c4 P( p1 l5 n% L. x//, f& {' R+ D9 }& u, N- l+ F7 A
///////////////////////////////////////////////////////////////////////+ c$ Y2 J* J) C( P
///////////////////////////////////////////////////////////////////////, _; a! \! a! T( n
" v1 n# o. r6 w  N
class LANE_SPEECH_DLL   CSR) J& Q3 F- t! e8 ]* b
{
4 m- o( O' ^7 [' h
. {0 w& i  k( ?6 ?- Iprotected:
" d% n9 {. I5 P. yHWND m_hWnd;
' {  L. Y- b( {) s( U# f
9 c$ I9 N6 N, h0 f# Opublic:4 P+ l6 m. W8 B
CComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
6 B9 G8 e- q4 }# b% ?' vCComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。2 a# j" D5 Q0 X, n
CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。
9 m4 I/ b) [4 rCComPtr<ISpStream>    m_pInputStream; // 流()的接口。
8 j8 X9 F+ J% fCComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。
" s- N/ s7 O+ U% BCComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)8 L9 j9 C8 @1 s8 g
public:, v% D  S6 U+ R5 D8 p# A' i
static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。3 h7 d+ P) I) z% ?% z

' V- h' j8 i3 e6 ]3 S0 {
& Z5 T! V5 @% r3 f3 d/ y. K3 cprotected:1 G/ y2 b0 _9 `, {1 i# S
//***************************辅助功能部分****************************************
+ q+ L, X9 ]! A- k9 f4 N
9 f; m8 j5 o8 d3 Q% v, b////////////////////////////////////////////////////////////////////
6 P5 E/ S% L$ C9 N6 k//GrammarID加一,每个GrammerID必须不同。" U0 E2 E, i1 _% p
////////////////////////////////////////////////////////////////////2 d  x2 U5 E+ J; M, {7 `1 K+ b
static void UpdateGrammerID ( );$ n4 M- l6 Z2 C% I* v
1 w6 ^& u) K9 M5 _7 G) ?' s. K
9 [, P6 t) ~5 X; A1 l
public:, |# G- x2 g- f( D" y6 I
////////////////////////////////////////////////////////////////////
5 _# x4 P8 t- w3 i4 m! w//功能: 友员。TTS中的从SR引擎中建立voice对象。
- \1 V0 r2 ~8 u+ W; Y% K7 O/ ~4 \//参数: pSRContext:SR上下文对象的指针。
9 h6 w; c) E) y6 d* S1 C* ]- j//返回值: HRESULT类型。
, V/ W- F6 N% u* q////////////////////////////////////////////////////////////////////
# h( y% ~8 ~% L" }8 {friend HRESULT CTTS::Create ( const CSR * pSR,  g; R5 \" N2 F5 f. x
          const DWORD dwLanguage );; y. M6 t6 b" ]0 n; O( z: X) Z
3 x) R" y( R) o/ b6 `

! G3 R  R3 q- F  M4 R* Q. G" @//****************************初始化部分*****************************************
! K1 ^8 f0 `; G) z- b: l8 n3 V: ^* p3 R7 e
////////////////////////////////////////////////////////////////////7 F& S- F9 b9 \8 _3 A
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。2 G% \$ \. R# J) {! c% M" }* C
//参数: hWnd:要关联的窗口句柄。3 j( ~' A' P% T/ D# D8 U6 F5 E
//返回值: 无。. g0 f/ L* N/ T- e3 W
////////////////////////////////////////////////////////////////////. Y! N9 e) a1 w8 M: r, f* x# I+ c0 p
CSR ( HWND hWnd );: v. O% \7 F0 W+ `9 I& s
; C9 n2 e7 g9 r' Z7 e
////////////////////////////////////////////////////////////////////7 G. q/ g* x+ [6 H& [( L# V. K
//功能: 释放所有的对象。$ E6 B. I' d: \' d! F0 i$ N
//参数: 无。
" G* h# D  Y8 E//返回值: 无。
  L: n' x# B5 b3 Z////////////////////////////////////////////////////////////////////
( J1 J* D) ]8 b4 d7 ~* t) F/ Z" y~CSR ( );
: B% Y, F+ F6 ~" s# }0 T. D& a) r$ A  d3 M7 {8 v
////////////////////////////////////////////////////////////////////
4 N: X/ G3 x) p//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,
* Y3 u6 `2 T' M//    加载文法文件。
/ t$ I. ?7 T4 Q  b5 A& y//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。" U8 j* `8 y- u" M  U4 l3 g
//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
- ?6 M, X) h" q//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。0 t2 t) N- |0 r5 K1 O) z3 v
//返回值: HRESULT类型。
5 S9 |/ e5 c2 j; r, Y1 Q' a////////////////////////////////////////////////////////////////////
, S! a' h: z9 S5 a/ X$ V5 Y$ hHRESULT Create (const DWORD   SRType,. i' q: N- }7 B
      const WCHAR   *pwcGramFileName = L"grammar.xml",- D5 p5 p- Y" b3 K9 x  l
      const DWORD   dwLanguage = SP_CHINESE );0 I; `- i# F# u; {5 W
( {  l2 @+ G2 P' |4 x

# o# N" E* }3 T//**********************************设置部分*************************************
( @" N* w% w8 P+ a0 N! v" A- z4 ], X5 c
////////////////////////////////////////////////////////////////////
( e$ o$ k4 p; [/ X0 R//功能: 设置要处理的上下文接受的事件。
3 E/ U6 X; l4 z- d& h/ i//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
( m7 X7 e3 W# u9 F% S//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
$ a6 g7 ?* d8 Y$ C! J! r* c//    件都会收到通知。
2 K  S8 u+ `% [1 h, G; Z//返回值: HRESULT。8 V7 P1 M) t4 u) x& L9 a
////////////////////////////////////////////////////////////////////) O( ?. o$ W4 s1 ?7 e
HRESULT SetInterest ( const ULONGLONG   ullInterest );! o8 K. m3 Q; U* i. W( T
6 F  J4 n+ s: a! B
////////////////////////////////////////////////////////////////////, Q% [" J* Y; l  U
//功能: 设置某个规则的状态(激活或者取消激活)。
! ?+ n- k/ R0 p//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,' M( t& R1 W6 r2 }: {+ G! h
//    FALSE表示取消激活。
# Q7 e7 N0 ]2 ~//返回值: HRESULT。
4 _6 I, f! l, d* K5 G8 z% K////////////////////////////////////////////////////////////////////: M, T; w/ Y" N' @( ?" ~
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
# c- j" I. s( z# p! Y* }
5 E$ A& a2 f4 o( p
0 t/ V! C) U6 K+ F0 Q8 |////////////////////////////////////////////////////////////////////
! s( c- m2 Y/ A: ?) b//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克. Y/ O' A) Z( @9 [! T/ h/ k/ _
//    风输入。% i0 }) g2 j$ Q+ C" o
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。9 p3 T; W+ v: }6 x/ M
//返回值: HRESULT。
' \) V0 C1 d9 x' x7 u////////////////////////////////////////////////////////////////////* J! P+ S5 S3 F* G8 [6 m6 t
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
' x$ r; A6 C+ |5 f9 ?
1 ?* c6 B, {6 P0 ?6 d& |2 U////////////////////////////////////////////////////////////////////( Q" e9 S6 P# j- a* m, Q
//功能: 取消从.wav文件识别。恢复从麦克风识别。
( o- L$ ?; ?9 l* }0 D//参数: 无。
2 S" Z: f0 M& {, B//返回值: HRESULT。( [- @# |+ I# e' S2 s4 B; X3 F% f
////////////////////////////////////////////////////////////////////$ s: _' c5 L9 b( ~% ]
HRESULT UnSetInputWithWav ( );
) [2 @% w9 Z  B$ B3 k) G4 M
2 G& d2 E( D' G5 x7 s) y//***********************识别开始,结束,识别结果的处理**************************0 D$ [9 |/ o' n: T8 M  y; N

) t; _6 C* K! P6 ]1 |2 t0 B6 S////////////////////////////////////////////////////////////////////% _% ]0 `9 q$ S- l
//功能: 识别开始(将所有规则激活)。2 B) f8 A# Z: @
//参数: 无0 z$ k; }0 m# D* J
//返回值: 无。
: e; l: v% W$ z1 ?1 o% D////////////////////////////////////////////////////////////////////
: a, ~9 ]4 t0 Avoid StartRecognize ( );# x& C/ e* B: P4 j

2 I1 ]0 F0 R5 h8 a////////////////////////////////////////////////////////////////////6 ~* W7 {" M, H1 }5 ~6 i, T6 \
//功能: 识别结束(将所有规则取消激活)。" C4 A- i6 G6 B/ r
//参数: 无。* R! a( e% M7 U5 u5 w1 R
//返回值: 无。
* q5 Q& F6 Q* I7 ^- b* K////////////////////////////////////////////////////////////////////
( W: D% k7 w7 ~) g4 O, V. _void EndRecognize ( );
7 h" Y& m0 B- Q9 u9 U/ ]" P- P, a2 }5 ^: Z
public:
3 m0 D2 J9 f7 e$ j( |8 \# K7 M5 M4 p////////////////////////////////////////////////////////////////////. k0 l. l8 M3 S, W) w
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
/ X3 D( ?+ E9 I4 I//参数: 无。
/ ~$ u: o3 o# H) A# \//返回值: 无。
% O8 b1 K& }0 M! B9 o////////////////////////////////////////////////////////////////////% f2 Z0 G4 M" J$ Y# D2 J9 m
void ProcessRecoEvent ( );
6 }; w/ I( `' y6 F% x- W, u. k0 f+ X
; Z+ p1 T0 V6 E% z1 P$ @4 g+ Gprotected:8 A5 j* E6 Q1 n+ O- k/ \
////////////////////////////////////////////////////////////////////" W) F. j' M; B. q
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。
* K- B* |  v$ ]( U# N- @& J//参数: pPhrase:ISpPhrase类型。
- Z* _. S, B5 ~% v//返回值: 无。
9 y* g0 [+ {4 Q, A9 w////////////////////////////////////////////////////////////////////0 o6 J6 o3 f2 s, H" H( [
void OnRecoSuccess ( ISpPhrase *pPhrase );8 j# Z3 ?4 a0 y; r# t$ E
, o  L5 E2 o/ E: m  @$ f9 w: \
public:  ?. Y- f) g2 ]0 [
////////////////////////////////////////////////////////////////////: q! Z/ h# h5 O* P6 @
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
% G. b/ F4 O7 p5 h9 k//    需要在派生类重载。规则ID必须以常量形式预先定义。
* o, m. C" D% t# J//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
9 L' x& i7 ^  f& ?0 ]//返回值: 无。
+ }- {7 c% v( a% J  `; D////////////////////////////////////////////////////////////////////, I8 ]2 P3 B$ ~% l  c: Z6 O, E* P
virtual void ExecuteCommand ( const ULONG ulRuleID,, B0 o! c( F1 U' y7 f
          const ULONG ulVal );
% i4 N8 Q' N7 t( f9 e) n1 ]2 a* ?0 N% M( I7 p0 j4 _8 `
////////////////////////////////////////////////////////////////////1 e% |4 P7 x& y8 W0 U/ J: A$ u
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
8 D: P/ E. Q5 r4 R5 A( E) d//参数: 无。6 q# H0 k* e% r$ h* S6 H8 b1 e: {9 l5 ~
//返回值: 无。
0 V$ w2 F* h" p  B' ]////////////////////////////////////////////////////////////////////: S# J& n9 X# N9 K7 Q
virtual void OnRecoFail ();
/ d' X& c5 _+ {8 l: ]# B0 h; m; n  Z! a  K1 M" G* t/ m
////////////////////////////////////////////////////////////////////2 n4 s; }# q9 `. G$ i
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
3 \' M, `' P  A//参数: 无。+ D/ h. X% M: ?0 A% ^: {+ l
//返回值: 无。
9 R! J3 B4 T" Y; Q5 A( R$ [" E////////////////////////////////////////////////////////////////////, x- R& a! j1 _* k! R
virtual void OnStreamStart ();3 u: C/ B# M7 ^2 P* u' w- }
3 ^6 N) T- W" U+ Y2 w
////////////////////////////////////////////////////////////////////3 N- o# d" `' Q
//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
( f5 L. m; u4 k" p  Z//参数: 无。
- A+ l7 `% f4 q3 h" {8 X. `//返回值: 无。7 Z) |4 a7 L- F% x: l) Q& r# b+ q
////////////////////////////////////////////////////////////////////
# B/ n0 a" t  Avirtual void OnStreamEnd ();
9 y' D& |4 F: e3 D9 l9 S5 x$ l0 ~( x& S& O/ g
};* m1 G% l" q' H
1 N' l) U1 S2 a$ p
0 J. U5 c" L( ^. n* M' K+ z$ ?* X

6 M. U& C' b& D8 o: R- `' r& M#endif    //LANE_SPEECH_DLL_H
1 A' V# i' _4 y& m. k0 e; O# x0 c9 L+ Y& z) w7 J9 j+ q: S
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////% F( o9 w  {) w8 S- ^
- w4 d8 V3 _# A0 M  h$ D, x- A# p
////////////////////////////////////////////////////////2 R# G4 T5 F7 o" z
//
7 Z. T5 z8 W( D% ?4 j" ]' {// 文件:LaneSpeech.cpp& M* O0 Y% A+ P
// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能- k2 |' H/ W/ [8 W
//    语音识别只支持命令模式,不支持连续模式( w4 f$ P+ n1 B6 ?( J7 ~0 S" ^
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
' f- S/ [, N; G' {( ~// 日期: 2004.10
! `3 _2 V3 B8 m: s5 q8 O* E// 版本:1.2# V& U& l% _# d8 K/ m! A) J
// * a+ ^! _  j0 O* M
//* H3 c" B0 `( `6 ^9 L
////////////////////////////////////////////////////////2 w3 k7 r6 O! N2 O* _$ J

6 M; [* [1 A- c- @6 f
0 Q* ~+ g7 Y7 u( V5 w5 ?9 L. e& u7 [( f: l3 }
#include "LaneSpeech.h"2 d9 c0 ^) b) d( a4 k* H

$ F2 S& q/ m& c$ i//-----生成动态连接库和静态库的处理----------------% N$ @% h8 w( T" s6 i
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类+ J" B/ c4 m+ X1 ^* W

3 r, O5 g' Q/ }* Y6 S! O5 G3 t( XBOOL APIENTRY DllMain( HANDLE hModule,
" w6 d, q! w  h, m# |                       DWORD ul_reason_for_call,
6 ^$ `  f( v! T9 i2 r+ h- N: Z! I                       LPVOID lpReserved* a8 ?$ G' L' d  j5 R7 T  }
      )
( T9 M5 n; H; N6 n$ d{: N) k+ b, ~. x* e& i
    switch (ul_reason_for_call)
# a3 b  t) f4 _$ Y{
- \( l5 `( V+ z! ]   case DLL_PROCESS_ATTACH:
4 e3 i) `8 W8 L3 Y# w! f    CoInitialize(NULL);0 Q& {$ E' |- j. J
    break;
& `9 _3 f) r  E  
* k$ V( Z( w/ m" H   case DLL_THREAD_ATTACH:' Q) S$ _6 O& K* r; @. O
    break;
) ^' B$ `$ Q8 P4 @  P, g+ G' B' t  
2 ]+ D) O$ t& H, h! t! f   case DLL_THREAD_DETACH:
; d' \) i) q* F5 y/ {/ J5 m: G& q: Z    break;2 l% V' Z/ r  H% q
  
- g3 u6 I0 W8 A2 ?1 ~4 h; T   case DLL_PROCESS_DETACH:
* r3 c7 w  y& N5 f$ c. w# t+ u# ^$ D    CoUninitialize();" @3 u/ L( r6 U2 O5 ?' k. v
    break;
5 @" N1 P; x9 z  z) |$ _; V9 p    }
: a& R% m6 @9 W  ?' ~- |" l    return TRUE;
7 J4 b. L6 i+ [( ^  |}
8 M7 c7 c" O8 ?
- }  R9 r4 {, A: q, t#endif //USE_SPEECH_DLL
( o$ h7 Y8 ?% _4 @% v7 E7 j3 e8 V1 N2 ^$ a9 ]0 s3 S
$ d$ i3 @: X# v2 |) w/ V
  A8 M3 F1 @) j  Y
///////////////////////////////////////////////////////////////8 H; H" B" v1 T( ?5 O. r4 o

. X" F, |1 Y- X' v4 g& y* A////////////////////////////////////////////////////////////////////: E6 L. X3 |$ V" C2 ]! _# i% E% {
//功能: 弹出一个信息框。) D. \$ g# \8 m! u$ o" Y) ~! G
//参数: lpText:是对话框信息。lpCaption:对话框标题。  \: _: N3 z/ K6 ~; ?2 q
//返回值: 无。+ }8 g3 c8 N+ J$ u) t( M. j: ?
////////////////////////////////////////////////////////////////////, |3 @% g+ K- {* F- c5 h
inline void ShowError ( const LPCTSTR lpText = "ERROR",
8 y+ V8 L# a2 S$ {  e$ L        const LPCTSTR lpCaption = "ERROR" ), C3 N0 n% R: ~4 V
{
0 ]+ x' i7 r# Y$ k6 O9 m   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
  V  n& g  x1 V  D* B; \}' {* o: h7 n, b% N
$ d( m& H% @) q& r6 H
////////////////////////////////////////////////////////////////////4 X; T6 m% Q  }3 k
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
  G5 H( K+ p6 y6 u# |" o//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。" z' _% t7 d* b
//    lpCaption:对话框标题。
# \3 s- Q4 Q* Q( r" [//返回值: 有错则为FALSE,没错则返回TRUE。6 K: h& @, U9 c# f
////////////////////////////////////////////////////////////////////
6 H) B  r. S3 {inline BOOL CheckHr ( const HRESULT &hr,% T9 I; J+ h, q* g9 m1 b
        const LPCTSTR lpText = "ERROR",# Z5 k* U2 C; K1 Q
        const LPCTSTR   lpCaption = "ERROR" )* x2 L# Y  }/ r$ M6 y; }. H
{- o! Z% D" k/ b5 x) M4 i) H& ?
   if ( FAILED( hr ) ) {
: b- M- u" [1 I$ u' D    ShowError ( lpText, lpCaption );$ ?4 u- n0 N9 _0 I
    return FALSE;" h; _+ C5 j$ T* A( N) S
   }& ?) S7 s3 E: M) d
   return TRUE;) a( O% f3 f: n
}9 d2 y2 F. `; U- i

% \0 f' Y# c+ C; i4 O: {* h
3 o( C% c  Y7 k' t, g///////////////////////////////////////////////////////////////////////
! t7 S, W6 l6 j. X0 q: d///////////////////////////////////////////////////////////////////////0 h0 y, p+ G) H; M3 ?- q6 h" ~- ~
//
( B; v, I  V5 ]3 o6 ^//         CTTS
: Q" O0 B$ S% w4 O; w//
( C0 t! j8 h& Q4 ?0 i///////////////////////////////////////////////////////////////////////* }! m. m" g& ^" y
///////////////////////////////////////////////////////////////////////
- l9 J- V: ^4 k2 k* M' g
2 D5 G  H# U- b& x////////////////////////////////////////////////////////////////////
. }/ p% w( D8 W$ E! F//保存关联窗口句柄。初始化COM。
% @+ P1 p1 E/ e; Y& \$ b, ?////////////////////////////////////////////////////////////////////' B% H3 T. z3 u9 P; D/ N4 K
CTTS::CTTS ( const HWND hWnd )7 g0 M3 v- _6 k. W4 o/ E! q
{- _" @$ D* V5 I% d( s+ w- F" l% e
m_hWnd    = hWnd;
1 b; X! Q# S% A' q; K' hm_pVoice   = NULL;7 }7 I- Y" r0 c3 h! b, n0 Y* p
m_pToken   = NULL;. t' D+ q1 x) T; w, W6 X
m_pOutputStream = NULL;
2 c% `" ]# R+ l7 b8 b& Om_pAudio   = NULL;
2 \6 L/ @! s  @% `# G}" Q( n7 @  I7 @

( t9 F& [6 M- K; R8 R9 q////////////////////////////////////////////////////////////////////
7 h, R, }; E2 k//释放所有对象。
+ n' X% X, f& X////////////////////////////////////////////////////////////////////& `5 N: {  I8 @- `. C0 E9 O( L3 j
CTTS::~CTTS ()5 z" T' h& T4 h  y; c
{: W: {! `& D) b% v) C
if( m_pToken) {) e2 i, o% {* t. }) w7 d& b3 {, `
   m_pToken.Release();4 G4 s3 L4 e3 `
   m_pToken = NULL;+ D' [1 [* x1 I0 a! ?1 a6 y
}
' J' x; M  l: A0 Q+ |if( m_pAudio ) {8 U8 L2 u# H5 v% f
   m_pAudio.Release();
& e' ^' ^: `8 [. S4 _1 d& z# ~" t   m_pAudio = NULL;5 b! T0 `3 u: r
}: @. c7 F* L9 |# H' q
if ( m_pOutputStream ) {; F4 V; f0 C, e9 i: Y0 K
   m_pOutputStream.Release();
2 P( j2 f3 j5 }0 ^( F9 T: r. K   m_pOutputStream = NULL;
" ^4 M0 v% d1 @* E}- B/ o1 V$ J) m% j
if( m_pVoice ) {
( {$ H2 ^: z, }) }! {   m_pVoice.Release();$ J  \0 ?5 Y: u5 i
   m_pVoice = NULL;
! m! ~2 W( _+ z7 ^}
$ A) }2 ]$ @+ n( b, g}
! E, \2 J9 g0 N  F
& B( E1 h) ?! H' ?////////////////////////////////////////////////////////////////////
  K5 R! m" t  P0 [' _//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。
4 ?" F$ b% Y8 @3 a  z////////////////////////////////////////////////////////////////////
) V9 |% \! B' C* S% {HRESULT CTTS::Create( const CSR * pSR,
/ Z. x5 G% Y8 f* q& n       const DWORD dwLanguage )
' |3 T- q4 C% e: ?% p2 A+ R$ G( {{
! L; c) ?* i& o" G: n5 n6 T3 BHRESULT hr;
7 z4 S9 K$ l7 W" Y* }" l' M8 k# Fhr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
3 w" V2 W1 C/ R7 J) B7 {2 @# J. Xif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
) x9 h/ d/ C% E% s   return hr;
" S/ U5 s4 P; L' U}
) C6 s7 Z; ?% G, _$ ?( U
7 K% \5 F( a$ ?SetLanguage ( dwLanguage );/ {  e0 U4 n2 K1 F8 i# ]
5 S" m" P/ \' Y
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流( V" u- A  O& k7 J7 `$ g# A
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
/ G, d0 p+ j" C6 r) q( R- X    return hr;8 o: \( M" R- A- [$ Z7 A& n* u4 l4 Z
}$ p* |: j) m# j/ L- I  n1 \6 H, ?3 ?

& X( B" e& p$ Q3 Z  Z//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
" `/ c7 I( E0 q- W- A( K3 o//SPEI_END_INPUT_STREAM 表示完成流输出。# A. x8 K. K2 ~
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
, D( W& z+ G8 A; X         SPFEI( SPEI_END_INPUT_STREAM ),0 w, m! ]7 p5 l$ m( i4 U
            SPFEI( SPEI_START_INPUT_STREAM ) |5 d. e/ f$ |5 X! P' }5 _1 J
            SPFEI( SPEI_END_INPUT_STREAM ) );
% g! {; Y9 T; h# M, M6 pif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
) c7 v* s. J9 H4 c7 J    return hr;
5 X$ x2 w, A5 l0 i: H& l+ s}/ t: u5 m! |5 r0 l! e

- A% a: y6 L3 H3 M& n2 y//设置通知消息
  Z7 Y/ \; t# f- E. Y0 s0 l$ g9 u6 zhr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
, w& v4 H5 b6 @8 c1 m1 J8 bif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {- F5 I* `  v3 r7 G
    return hr;; v% r9 }$ P+ `5 |  q1 V* a  r1 I
}, i; b: P6 k. X4 e9 e; V

5 ]$ V0 A2 C8 dreturn hr;4 w5 n, s' u/ k, Q( }9 q
}
. s; ^2 H& y; @
- t! `; w" x# k2 c* O& ^////////////////////////////////////////////////////////////////////) `0 c  [8 H) I# c2 N" e0 H
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
) s" w! }  \! D! s" J# Q% S//并设置兴趣,设置通知事件。
; w6 K4 T7 }& q0 g////////////////////////////////////////////////////////////////////2 O8 P$ |3 ?/ `3 ?3 R+ F
HRESULT CTTS::Create( const DWORD dwLanguage )
& n* ~! r& x% z0 U9 a3 E. P: r{' l/ Z9 z5 E$ T
HRESULT hr;, V+ B# f! k  t& E) Q1 R% ~
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );. W" r3 a3 U# w7 z+ A
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {) j$ B) r7 T( z. a! D- v9 b
   return hr;( t1 j" L* u$ o1 t5 _, l) j
}
1 U( ]! ]$ v9 t9 E4 y3 {
) n4 C0 Y- H$ v# C2 E; P+ @SetLanguage ( dwLanguage );- E' m0 O7 M& N: h4 U  s
: \' n1 L: n0 _# _! U; r" }7 o
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
+ L* @5 s, |& d7 O: A; e) rif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {) U) ~- G2 ^9 u0 z5 Q- k/ _* O. g2 `. |4 n
    return hr;6 t' b, N2 {, J. Q/ i& j; Y3 ]
}# M" ^- D6 E6 B) g8 Y( a

8 j5 y! H6 U( k2 W//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM. ~+ ]# W8 l# ~  K/ E
//SPEI_END_INPUT_STREAM 表示完成流输出。
* e; l; z" ?: \, r4 H" ~$ thr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
( K& C3 a+ `/ U0 \: C, v  ]         SPFEI( SPEI_END_INPUT_STREAM ),( P6 N! A3 `$ S8 j; m
            SPFEI( SPEI_START_INPUT_STREAM ) |% y1 V2 l$ e" T( s7 `( s
            SPFEI( SPEI_END_INPUT_STREAM ) );- }5 O" X  P' h8 \9 B; m
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
" d7 S. P+ |! w8 V    return hr;
  F. o6 k5 a( Z1 v( m}
* u# A4 H0 I3 e6 g+ d3 z# n  Q9 y  v* ~  ?; Y2 @( G- u
//设置通知消息
8 g, n) Y" c, X3 t" c) Whr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );( E& X; K; }8 L1 n" k
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {- s1 f/ p/ y7 ?( w% i  K) D2 \9 i
    return hr;( J4 Q' D/ i, G
}
: v  I7 Y' Q: U  ?% N# w! P9 y6 W  G/ e
return hr;
+ K! q, `9 A' l- U% u- U" c3 C}
( l0 ^( y; o4 U7 d3 v2 u0 d+ ^
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件# A4 e  j& o& A  `; w- ]
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
5 x$ n" k: C+ I* A* A, |' u( D{
( W" h3 ]. G. h& V    ::CoInitialize(NULL);//初始化语音环境
6 H; T% F" E# o& V4 {  {3 O; g    ISpVoice * pSpVoice = NULL;//初始化语音变量
' S2 t& D7 H% T. A5 G! F" n" Z    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
- ?: u# M4 t0 m        cout << "Failed to create instance of ISpVoice!" << endl; 3 w+ i& ?% q( `; q, y* H
        return -1;
3 B# ~9 J  o' u" e1 U0 ~) Q. _7 h1 @    }
/ K  ~" x. o( J- r$ W
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
. s, j7 h  c6 }; ?/ ]    ::CoUninitialize();//释放语音环境
1 {3 t  k) C1 J' l- n; u
    return 0;
- X: @; Z  n& ?* |2 a; h! ~+ q}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序1 z7 c1 ]3 e  ]7 A0 Q5 h' h. J

6 b+ ~! n- H" h$ k5 V. A1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
0 _6 y, S7 I* D3 n, v
$ h5 e) J7 I! w9 Q8 S( b7 Y6 X6 Bhttp://download.microsoft.com/do ... -US/speechsdk51.exe   
& Z9 C  ^+ p5 GSpeech SDK 5.1安装包 (68   MB)     
5 ~. v9 f# c) B3 @5 e( ihttp://download.microsoft.com/do ... chsdk51LangPack.exe      
" R1 t5 s$ l3 ]1 l2 r  o2 {  b中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
) e) p# T1 Z/ f+ ^2 E$ F  M4 o% ~, w8 i; t) ?( o
2.下载后,执行安装; [4 x: |" i, Y  V/ N. E6 p

3 Y* d$ i- I/ T8 Q+ N  |下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。2 m4 b+ L: G' a: p  ]5 i" V; R
9 ]: o% c2 h6 f1 k% {6 a
3.VC的环境配置
; M/ t' [8 l# @6 \4 Q2 _8 X# U& Q: y5 B$ u
在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
9 f' f  a! P* h! _7 s2 \) z) Q9 k, W3 t) s
工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.5 O, G; G$ A: P. t; F
4 O- A( M- V2 v. X+ |3 L& B
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
+ c/ m1 }3 s; b  G8 x4 b
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-8 20:22 , Processed in 0.039600 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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