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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////& F% o) S% {: l& X
//1,生成动态连接库时,要#define USE_SPEECH_DLL,9 m8 H5 c) Y: I& E# Y* z
//      并且#define LANE_SPEECH_EXPORTS
, m" y" x; N7 }! [' V, m" u4 L//2,使用动态连接库时,要#define USE_SPEECH_DLL$ m6 d1 _5 u- u# L" j/ }' J
//3,声称和使用静态连接库时,什么都不需要
7 r9 {0 K# |* j! t: y1 q3 f3 B//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),
9 R& r# }- k; Q//      动态连接库就不用调用了。5 x9 R6 G0 ^0 q+ G  J/ l
////////////////////////////////////////////////////////8 U3 ~/ _% w( X% H$ Z: a# ?4 H$ N% g& x# p
#ifndef LANE_SPEECH_H, h& k4 B' K! v5 v1 }& U0 w4 O
#define LANE_SPEECH_H6 ?, I. b, D4 B: i; v
& p7 P9 P# g) o3 k: P9 N
#include <windows.h>- a$ ]! W' g- A. ]0 K. w1 H: w# f
#define _ATL_APARTMENT_THREADED) I, W: r, g- J& y7 {) @
#include <atlbase.h>5 J/ w: a5 E& Z; 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
8 }5 m% G4 U! Q8 f4 S* w' m#include <atlcom.h>: n  U& I9 O9 x+ R& Z& h& J
#include <sphelper.h>   //sapi需要的头文件1 J) ~- A) {. b- a6 J# z

( o& o% Y, t' C" K* S4 {) _2 R//-----生成动态连接库和静态库的处理----------------
; Y, k2 b) K$ U" X7 ^#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
$ `( x1 s, u) o& S9 F4 T' T: A# W5 h. X0 {" \: `
#ifdef LANE_SPEECH_EXPORTS" K* v/ n7 L% X
   #define LANE_SPEECH_DLL __declspec(dllexport)
+ {$ x8 x/ m& y0 K" x- ?#else" F: b2 }3 G/ s8 _
   #define LANE_SPEECH_DLL __declspec(dllimport); t) \, H+ U' Q1 V7 @
#endif6 l) a6 h' c4 D+ z3 E
7 _! g* t. f5 H( B  r
//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关) r% G; W) ], o, _
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
6 y& n+ B" X+ C#pragma warning( disable : 4251 )5 r" Z* |9 x1 G/ f. X# o' K
# \& }# x  C1 j
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)3 G' X/ ]; \: E4 \5 }, X
#define LANE_SPEECH_DLL2 O+ ~* \+ }: S
7 I. \! Z8 `* X0 b
#endif //USE_SPEECH_DLL5 f0 L7 G4 v$ u; }
) {3 x/ w; a: S
' {6 G! b- D  q7 \, B
//***************************常量***********************
0 B1 }" [1 X/ _; }$ a( Y8 }. W! {1 _4 G' d- G. ]
/////////公共常量-----------------5 D2 w% t8 s) g% Y+ o( Y5 a
const DWORD   SP_CHINESE = 0x0000; //简体中文.
8 ], H' m. J1 M3 @1 c# n! |const DWORD   SP_ENGLISH = 0x0001; //英语.$ b* x' J( |! s1 K+ J7 K
5 l* |0 Q! Q. T+ y8 W+ f
/////////CTTS常量-----------------
' m( E: ]9 N! i: X  R" Sconst UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
! {' w# [# V( u* g5 F
. j% }5 v% U6 S( j4 |/////////SR常量-------------------
4 O" r6 _# j0 a" Jconst UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。* l: r- V1 q  @
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
! }3 D, d0 H1 g2 t8 x# H2 Z4 yconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.  l8 D7 ?6 @7 r  s6 C

  N$ D: M+ c, n" {2 c//以下常量仅作例子用。  [/ K, ~4 W/ L- b! J9 l
#define VID_TopLevelRule 9000   //顶级规则ID+ n! ]/ [6 l' \) Q% o6 c5 [
#define VID_SubLevelRule1 9001   //子规则ID
5 f* z9 O  h6 s3 ?0 e#define VID_SubLevelRule2 9002   //子规则ID0 X, s; J! o: n1 @" t0 S$ N7 V
#define VID_SubLevelRule3 9003   //子规则ID
. C! k( M- [* W; r1 p5 g( }, f" O" O$ P* O2 j' {, O8 A! s

4 d7 h! J0 O* b7 Z" M//*************************类声明************************
# e8 c0 B7 V" c! G  W+ u, O: R% m; j$ r( _. o2 Q$ A% z
) g2 R' x/ @8 Y0 @
class CSR;# ]; {3 q1 m8 g( B
///////////////////////////////////////////////////////////////////////
9 t' c& w) w2 {2 I9 u///////////////////////////////////////////////////////////////////////6 C: j2 D: v: a3 y. v9 E
//
- a) u  s7 d  b! Q2 S* O- h//         CTTS
+ R' g1 ~# n" q- G7 R2 {+ ^//
. }* n* X5 x) [0 n; G/ [# D1 ^) T///////////////////////////////////////////////////////////////////////8 ?" \3 k; Q  z. e$ j; j7 d; l0 s
///////////////////////////////////////////////////////////////////////& D4 k. o. B7 o  y# R; }

) s1 a2 b/ H# `; A/ K) Gclass LANE_SPEECH_DLL   CTTS
( c+ r  B) `, h{0 g: J) b7 |5 }& i" `$ R" e
protected:
1 ^5 q5 i$ K" d* HHWND       m_hWnd;     // 关联的窗口句柄。- {: l; W$ K0 ^* \6 L- F

+ B" b+ y5 z( SCComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。" c, B5 U7 E1 l  g3 P" j
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
' ]+ V; j! `( c. f8 H+ x5 HCComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)
, l- y) k9 y4 q' X& {2 Q# Q9 W; }CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
6 A7 f. j* Y& B. R8 E* ?8 t
+ o# N7 @! i1 \public:
, V: m8 L# E5 H- Y& }/ m: w0 E//********************************初始化部分********************
3 s5 u# S/ ^) U- J. L( V7 I. t8 _8 }$ z& s+ Z; Z
////////////////////////////////////////////////////////////////////
4 F! I1 ?' |. D//功能: 保存与识别引擎关联的窗口句柄。
6 N; b: l. _  B- _1 }//参数: hWnd:要关联的窗口句柄。
% p7 Q: A6 \6 v//返回值: 无。
% q1 r$ _) N; k7 ~% T////////////////////////////////////////////////////////////////////
! u* s8 y) T/ z1 F' h# B9 }CTTS ( const HWND hWnd );3 B) N& D! ~  ^+ q1 S
3 g# D% G3 F7 T- k; d$ a/ d2 L
////////////////////////////////////////////////////////////////////
0 e! u; _, n- Y  e8 w! X3 [//功能: 释放所有的对象。
) T3 s! t! ^7 R; V$ u//参数: 无。+ R1 `4 D6 {( j/ @3 D
//返回值: 无。
4 Y7 @8 E" Z2 d" e! r////////////////////////////////////////////////////////////////////
: Q7 Z, r1 \, X' K~CTTS ();
' I3 V8 I) Z# O# D
2 ]" N5 q$ R6 F1 o////////////////////////////////////////////////////////////////////
, f! h. |" ]/ t/ b/ z3 Z" e//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。
2 Y+ k, p8 v% B) f//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
0 }$ [. r$ v) x0 o//    SP_ENGLISH为英文。8 L  T5 f. b+ o; J
//返回值: HRESULT类型。% l' P! u; x7 w" J7 A
////////////////////////////////////////////////////////////////////
" d# i" |4 P, n  w+ {4 `+ O& Z% b9 S/ LHRESULT Create( const DWORD dwLanguage = SP_CHINESE );9 D9 o& F+ Y$ W2 P
( m7 L& P) j" ]+ j
////////////////////////////////////////////////////////////////////
% J) ?4 r4 l8 e//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,: k  p/ L( m8 x4 c8 a
//    通知事件。4 [  e# z. ]/ S5 r
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
& \& @$ |8 B& r' m4 G# P//    SP_CHINESE为中文,SP_ENGLISH为英文。" y/ z2 B5 u* `! |. A8 `& d0 y* i9 H
//返回值: HRESULT类型。
' ]! u1 [4 ^) y& j2 m5 `3 x////////////////////////////////////////////////////////////////////
* \. n& M/ ]* HHRESULT Create ( const CSR * pSR,& r! W# v6 Q0 k5 D; g) y# ?/ x
       const DWORD dwLanguage = SP_CHINESE );% {; P2 g% A3 T1 b+ s! L+ L
4 w5 @: N) o( V: n" P5 S

) I6 D2 ^7 \. k1 q% n0 @6 k//********************************设置部分***************************************. Y, g" j6 D/ ]5 K" u) V1 a* ~7 x

+ H+ D7 k/ F- I, t////////////////////////////////////////////////////////////////////$ ]: F2 d7 e7 M8 E! J* T0 P
//功能: 设置朗读声音的语言种类。
- k+ e% }: y7 C//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。& _/ ?$ u: u$ r! n6 F3 h
//返回值: HRESULT类型。2 N2 H2 ?1 r) l  b& _, y; D( z
///////////////////////////////////////////////////////////////////// d6 d$ s: q( Y+ r# g  d/ L' y
HRESULT SetLanguage ( const DWORD dwLanguage );
+ m! b; T7 a8 s& o8 h' g) n4 J3 H/ t  z2 h0 i, a0 D0 r
////////////////////////////////////////////////////////////////////% b, W" I2 c) N8 _
//功能: 设置要处理的的事件。) L1 M* e. ]& n
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,# M$ m! W  n. ]) j. B* [1 \2 {
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
( `6 X% |' L3 p+ W# N; N; k* @4 H//    件都会收到通知。" h9 V  p) B7 d
//返回值: HRESULT。# s+ Y0 X2 {9 S6 C. Y/ B! m
////////////////////////////////////////////////////////////////////  h/ d/ K# `# O: s# h" ~7 k6 `- v
HRESULT SetInterest ( const ULONGLONG   ullInterest );* p0 p7 L# g" c! K8 Y

( e" A0 _1 @! E, a7 Z////////////////////////////////////////////////////////////////////
+ `4 e5 j/ A( E. X, W' C, }: a5 f//功能: 设置朗读声音的音量。
" J' v" Y" d& {$ K. ^. H//参数: usVolume:音量数值应该从0到1005 W, F) ~) d: s3 `! P/ s
//返回值: 无。+ i; x0 Y6 c+ z$ o$ k
////////////////////////////////////////////////////////////////////
6 ]. ?( N4 L% P2 }9 g$ [void SetVolume ( USHORT usVolume );
. ~- s0 {3 L& F0 f0 F+ p0 s0 ]5 e3 z3 s% F2 _
////////////////////////////////////////////////////////////////////
9 Q- k( F" T8 @//功能: 得到朗读声音的音量。
( |( J0 e" Z( L) \2 R0 u//参数: 无。& o7 a- r' y; k( M2 Q2 S( e
//返回值: 音量数值,应该从0到100。: P6 @3 V. v0 @
////////////////////////////////////////////////////////////////////0 A( a# E" v4 K" S% T' s
USHORT GetVolume ( );
+ G4 }4 i: n0 D. ]2 O. [; e) ^2 _) p4 C$ y; Z& g8 v
////////////////////////////////////////////////////////////////////
! }+ R7 l! L3 J1 e2 A& i//功能: 设置朗读声音的音速。
% ?- e  A8 s$ ]//参数: RateAdjust:音速,参数范围从-10到10。# x+ s3 n( c8 ~# U
//返回值: 无。
' L2 @( e1 X$ J5 c1 m////////////////////////////////////////////////////////////////////
! k( O* E! t5 Nvoid SetRate ( LONG RateAdjust );- p( f8 i8 [5 O. c  q4 H

; K2 B! G% S- A; N6 g- n5 m1 }* F  J////////////////////////////////////////////////////////////////////# l1 m$ @0 f: \# K4 u
//功能: 得到朗读声音的音速。) Z+ _! J$ E7 M( R9 }" F( v$ G& f
//参数: 无。
" q* X; I% s" `& S+ m( Y//返回值: 音速,参数范围从-10到10。' D# a- D/ ?" X5 N( B5 V( n7 ^
////////////////////////////////////////////////////////////////////+ C9 N) F' V* \& l3 L# f+ i- z8 C
LONG GetRate ( );
2 A, z0 j4 @2 o3 ^) ^& O: M; O' e4 K7 Q6 I  |
////////////////////////////////////////////////////////////////////# ~3 R) t: @: F) S5 X/ ~+ ^
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
0 b# l) o7 X' X//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。3 B( E& z0 [- D: O4 r6 T
//返回值: HRESULT。
& j  t7 Q% L5 s: N2 z////////////////////////////////////////////////////////////////////
6 _  p' q2 f6 \, T& qHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");
6 V& {8 B2 N* k( F% i( w# p: A/ x' ?% J0 H- F* y
////////////////////////////////////////////////////////////////////8 m% i. i$ u/ z8 B4 e# D$ _$ m3 I
//功能: 设置朗读的声音从音箱输出。" b, k7 @0 N- K+ O( i3 B( C5 s
//参数: 无。
$ s  s2 w8 j! \//返回值: HRESULT。" y/ q6 o+ o2 \& i+ }, n
////////////////////////////////////////////////////////////////////; @7 z! c3 ~2 ?7 A( F4 e
HRESULT UnSetOutputWithWav ();( b$ w  Z: I8 [, q. p) ^

; k7 a! Z7 ?0 R. k- @: H" m# h: z( k1 w; N6 Q! q% J* z
//**********************播放语音,文本到语音转换部分*****************************
: Q" _4 U4 ?7 Q1 Q  C8 @% q$ c* u; p0 r6 a" Z/ o% n5 Z- C
////////////////////////////////////////////////////////////////////% a$ W2 K  M7 ]3 f: t. g
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
  h" U& H2 P  E5 v2 K( Y//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
& K* O% N, A7 Q0 K- |4 o+ }. }//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,' t$ S+ o0 k5 m
//    SVSFIsXML为朗读带xml标记的文本。. ~7 d0 \' r: [- N% m, ^9 H
//返回值: HRESULT。3 g+ d+ G5 R* m
////////////////////////////////////////////////////////////////////! \4 c; K8 p' N0 I
HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
1 t1 t/ `. d1 Z: L  ^9 `5 e/ x/ n& Y7 H4 H, B2 `" O
////////////////////////////////////////////////////////////////////% `" b2 v1 Q% W5 ]
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
2 H: a8 ?8 z4 y+ O//参数: 无。5 p' p: y- i  G
//返回值: 无。
6 e6 u1 P% f9 B$ i////////////////////////////////////////////////////////////////////! Y  V' G8 @6 i5 ~. `
void Stop ( );$ a) q' f2 I% _5 G# _. a
! |/ p0 O( P6 l' A1 r, |! c8 ]
////////////////////////////////////////////////////////////////////
" V+ s8 V5 R$ }' _/ A  W//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。: K0 x* T, R+ R5 f" T7 V
//参数: 无。4 N, P& e5 P" s+ o
//返回值: 无。
: o7 [4 F' i: e6 R9 y% [////////////////////////////////////////////////////////////////////  b. j3 W  c; J: s9 ~/ P/ `
void Pause ();& i2 s& N& S1 E# W9 K( h8 A

7 I2 w& h7 N6 ~. v/ d////////////////////////////////////////////////////////////////////+ h% [/ X' T4 c, ?9 u2 t
//功能: 从暂停的地方继续朗读。
9 I4 W3 e$ K0 f* P//参数: 无。
& Q4 `/ `2 Z0 S//返回值: 无。% W5 Q! V4 Q! A
////////////////////////////////////////////////////////////////////" f% g  B2 P# T2 `/ x
void Resume ();5 l) o  o6 F9 W1 }) Z8 H( ~8 K
0 C/ ?1 t; l# j3 @; @8 v8 e: j# f

0 Y& J- j0 r# l0 {# a//********************************处理事件部分***********************************9 L* U- H* o8 ?  a0 v" m
/ m$ }2 T7 q$ h0 i( o
public:
! A! v1 h/ h# }6 o5 D& ]////////////////////////////////////////////////////////////////////
, l7 c  a0 F( S( x0 d% R4 L//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
2 G6 J6 c* Z2 H4 u//参数: 无。3 z  ?$ W+ K0 D9 E3 C& @: \+ n/ \
//返回值: 无。
2 B( H( R/ M1 \; f0 @////////////////////////////////////////////////////////////////////* Q% ?# f0 d! O+ T$ g0 Y5 z8 Z
void ProcessTTSEvent ();4 Y; J; x; c  A. m) X

  j( o( x6 a8 Q8 X- K2 V/ l; w
////////////////////////////////////////////////////////////////////" S4 Z  T* s0 u" }; ]
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
2 c7 K( j5 e; e, n; H//参数: 无。& V, {! C" C. G; r. V* J- W
//返回值: 无。1 @+ e% w! l/ e; l4 H
////////////////////////////////////////////////////////////////////7 @( ?. r+ W9 ^
virtual void OnStreamStart ();7 M& s4 X  d$ p
" t; a# i8 X, w1 l
////////////////////////////////////////////////////////////////////
- B  ?4 f& E# B) J2 ^$ q. @//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
) Z) d4 x) y5 S1 Y, W$ \3 \7 ]//参数: 无。  U- r! [# f8 h% u7 V
//返回值: 无。, [  X+ j+ V( g( [! O: h. f% p! t
////////////////////////////////////////////////////////////////////
4 ?& r# v" C0 Vvirtual void OnStreamEnd ();* q; ^( \: r5 X0 U; E, |! H; s7 h
};
/ b, |. J5 u, V( S* K( o- N) Y! ^2 p! G; I; u

3 Z& b! Q0 O' y# k4 m8 d///////////////////////////////////////////////////////////////////////$ ~8 Z2 W% u$ U: B: r+ F" V! N; s
//////////////////////////////////////////////////////////////////////// x- M" c# @  t* Y& h
//         CSR
) n  L; x; l8 ?- Q& t. x//: g1 v0 v9 F) K# L  T  j
///////////////////////////////////////////////////////////////////////& T/ S8 p+ V8 j0 ^; N% z
///////////////////////////////////////////////////////////////////////
4 q3 K" w, s- Y; h+ o1 I' E% }' I% s; z) |. o
class LANE_SPEECH_DLL   CSR
( b/ V3 G8 @  n# h$ t- B{( e8 J% I3 S/ u1 |

4 R3 X. F( y" ?% {0 uprotected:
' W2 {& V) |! e2 ]. y( {4 \HWND m_hWnd;) R5 J+ N% _5 T2 d9 n5 m: a6 |

2 X9 c, Z  E5 S! w: Y) r. z: [public:
$ ]8 G8 h0 ]* Z; x+ g  zCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
2 r( D( U8 A# }( h' [' FCComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。6 R# l, g* w8 z
CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。1 w& i5 ^# _! J9 q
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。
, h8 }) c: Z) V% LCComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。
( R% v9 X: g: d1 |CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
: c7 z+ a; Q9 i3 _( r, X5 [( i  F5 wpublic:
7 U/ w" y, |- r5 _static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。# P) l& ?% c! c' ~/ B

- U) [* Q' p; |  B
, j) H5 T4 q& @4 ?: C6 |protected:/ H3 v: b: \, @! j
//***************************辅助功能部分****************************************, q. z/ ?5 Y: t) e  O
4 T% |2 h% }4 ?" d6 J: A0 |
////////////////////////////////////////////////////////////////////$ U1 {( b( u5 Y  z
//GrammarID加一,每个GrammerID必须不同。. z3 o! @% ~0 S7 j# k& J6 u
////////////////////////////////////////////////////////////////////
8 }$ l; G4 B, v& gstatic void UpdateGrammerID ( );
# `0 L3 U5 `8 G3 ^7 }" ^1 `( A! b, P; ?3 B) M* I7 u" o, G
/ k# T6 U  k9 _6 N$ h3 V3 v
public:
. x& {6 L4 [) _1 J3 J////////////////////////////////////////////////////////////////////
! j! }: Q5 l1 Q9 g* H//功能: 友员。TTS中的从SR引擎中建立voice对象。
+ X% n* a. k: ]5 M) h8 p: M//参数: pSRContext:SR上下文对象的指针。
/ c; M, ^( X5 ], h//返回值: HRESULT类型。
+ Z; K0 D. H. K6 o$ Q8 O" W+ B////////////////////////////////////////////////////////////////////2 g/ _3 D/ {' b3 L* l; O
friend HRESULT CTTS::Create ( const CSR * pSR,. v8 p. F/ E3 D- n# y& B
          const DWORD dwLanguage );
: d/ m, n5 q; ?3 N3 P1 F8 }  c5 u- ]7 ^5 U
- O& o/ X3 z9 m
//****************************初始化部分*****************************************
& P( [0 k* Z, P, P6 T" v+ r5 y% {+ i4 D3 {/ m( v8 U( f
////////////////////////////////////////////////////////////////////
; I$ k8 a+ |: _/ m0 g6 e/ a0 j//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。. c8 b+ V  _: p$ Y( Q, z" S# n. R$ C
//参数: hWnd:要关联的窗口句柄。: x: }4 _; u4 n- \) C% J
//返回值: 无。
# Q2 K& b+ @0 f////////////////////////////////////////////////////////////////////6 \) G3 P7 N* q" j0 `2 s5 S' S
CSR ( HWND hWnd );, c/ k/ U, Z1 X. Q$ ~  O

" b9 W  S) @: w' O. Q////////////////////////////////////////////////////////////////////
/ Q6 k, e; J' f4 f//功能: 释放所有的对象。
  G9 P* p' C4 g7 @, ~//参数: 无。. Z  u  W) R# |3 F. L* C
//返回值: 无。
7 u7 }. X" v5 z* Y3 p+ h1 w////////////////////////////////////////////////////////////////////
) D8 b  f2 _3 ]& @0 Q~CSR ( );
/ `. Z; z# _3 G& H* u+ ]6 Y8 V  o* U- a
////////////////////////////////////////////////////////////////////
  }. p. l) ^/ i* w0 L' B0 i//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,8 D$ s) V. b- P  b
//    加载文法文件。
" S# a' i. [2 Q/ H//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
- R2 c; z: u( e1 \( _, W3 j' i! k//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
* E3 o2 e5 v) N: f6 j$ V//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。
" h+ f6 |$ c, {  w% h0 p//返回值: HRESULT类型。7 y# D  U6 k7 ]- K/ J, o- T
////////////////////////////////////////////////////////////////////
* _1 C( M' o4 D* n8 S1 bHRESULT Create (const DWORD   SRType,. v/ n: O9 ]# {
      const WCHAR   *pwcGramFileName = L"grammar.xml",8 ?* {& H+ H; F6 Q$ s/ A1 X
      const DWORD   dwLanguage = SP_CHINESE );* h+ m9 @0 b  f+ @% |$ H

5 V- `) Z( E. e. n5 @; ?; I/ k4 B
//**********************************设置部分*************************************
; \# y2 e3 ^: o; o- K7 Y8 c+ l5 V; a0 s! `2 e
////////////////////////////////////////////////////////////////////
) A+ V! \; w: @, k) ~( i//功能: 设置要处理的上下文接受的事件。
4 s/ J- d6 J. O9 T5 G//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
/ q6 i) [% t6 _& K( a/ A//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事4 v, ?) [6 h) i8 k
//    件都会收到通知。0 A, h+ t, S' V, m! W
//返回值: HRESULT。. s) w0 y5 ~. Y1 s2 S6 f
////////////////////////////////////////////////////////////////////
. V5 T' _, N$ J! F! j+ C. sHRESULT SetInterest ( const ULONGLONG   ullInterest );
/ S3 d( b5 g  v4 v) e) Z
; o4 o' ?. K6 x/ z. O0 K////////////////////////////////////////////////////////////////////
; e  A" e* C0 g8 Q" X//功能: 设置某个规则的状态(激活或者取消激活)。2 n; j$ V' O5 i7 D
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,: O; Z& g8 o1 w0 A, A2 U1 L  V
//    FALSE表示取消激活。
' ^' {3 B  b% m( T//返回值: HRESULT。1 Q* ?  B2 B# J6 h& k  ]" G
////////////////////////////////////////////////////////////////////+ H- `" d2 m) O9 z; t% @
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );) B9 R7 h) m) |& I: ]) G& m

) p2 f, s1 }. Z$ Y
0 ^4 I" `4 p# s7 U////////////////////////////////////////////////////////////////////
4 f8 j/ W+ ~5 r, S" ^( t//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克- B: I! p  w9 ?6 W% _6 w
//    风输入。# G; S* H1 @' T+ D9 L, l
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。4 G/ [& M  C; k* x
//返回值: HRESULT。
& r9 m- i3 M) |  ^1 j////////////////////////////////////////////////////////////////////& Y9 V* ~/ T! N9 O! h" c. {+ a
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );. {% n/ M" v. z8 L2 s1 G& h7 _

7 J  ^( O! ]8 r* k3 T3 l* X////////////////////////////////////////////////////////////////////
! S  @" ?& y  X//功能: 取消从.wav文件识别。恢复从麦克风识别。
" t. n) n/ q: |! `  `//参数: 无。% n7 C. u" |* n3 i1 ^
//返回值: HRESULT。
1 T( A8 U1 ?/ ~7 B$ O6 a////////////////////////////////////////////////////////////////////# r( a3 |. a5 b5 r
HRESULT UnSetInputWithWav ( );& A( V9 x+ ~, x1 z! M3 ]

7 t3 K, i. X: B//***********************识别开始,结束,识别结果的处理**************************
% M6 G- C+ d) y
* B, d9 Y: S  k1 ]  P: N. o////////////////////////////////////////////////////////////////////4 R  U# y0 O6 V0 o' {8 I
//功能: 识别开始(将所有规则激活)。
& F( v5 e4 h! J//参数: 无# Y" C6 o0 |* h# B, I: k# I# @
//返回值: 无。7 {! d. `7 y3 x( s/ D3 b8 k" W
////////////////////////////////////////////////////////////////////
8 f; o: L+ y) dvoid StartRecognize ( );
' r1 o* q) d- i; R
% |4 [# y7 z. o( _) l////////////////////////////////////////////////////////////////////
, C( A, m3 v0 Q1 s8 S//功能: 识别结束(将所有规则取消激活)。
6 _5 L" K! E* t: P) j! k" o//参数: 无。6 q8 d1 x8 a; c0 T( e/ L
//返回值: 无。/ ^( C2 [6 _8 ^/ g; a
////////////////////////////////////////////////////////////////////
' z5 s( H* s# a% [0 bvoid EndRecognize ( );5 X& b2 F% x6 x3 `& L
! |2 o; }" N, U$ L# Q
public:4 R8 o% C. V) @& l6 |
////////////////////////////////////////////////////////////////////
2 \7 v& T  R6 F0 o1 V//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。. E) C# L' {& T
//参数: 无。2 W. v9 ?2 R0 E- {/ H$ V* M
//返回值: 无。
4 t9 u3 b# s, G) R. `////////////////////////////////////////////////////////////////////: {' M. \  a# K7 G1 ?6 I
void ProcessRecoEvent ( );
  g/ k0 Y' _4 S9 @+ G7 `2 a' `' I
6 [! q# a& p  e  bprotected:! c5 j" n5 V+ `- _7 ~4 L8 n  z' @8 f
////////////////////////////////////////////////////////////////////
( Q7 I* [; t! Z6 z% N4 X//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。
3 B- ?/ Y# k! L% @- P6 U; C//参数: pPhrase:ISpPhrase类型。) q# J% O6 G) |6 B) z
//返回值: 无。3 W5 z' z8 d! g) Q
////////////////////////////////////////////////////////////////////
1 G6 I3 I2 V- Nvoid OnRecoSuccess ( ISpPhrase *pPhrase );
2 G6 P% v2 V5 q+ i0 i: A; ^4 B
" w% A5 p" ?8 J  T, }: E! zpublic:6 q# S6 h) J# c9 U' Q# q" m
////////////////////////////////////////////////////////////////////. n: b8 E' K" w  v! i9 A
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,8 f9 y0 C" K# a
//    需要在派生类重载。规则ID必须以常量形式预先定义。
- z$ I/ y$ O: M9 Q//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
! r0 F" X7 _# p/ c& M9 u( T//返回值: 无。
' l3 O0 B9 R7 t$ }5 }" Q% ?////////////////////////////////////////////////////////////////////
) g7 Q8 ^8 [# Tvirtual void ExecuteCommand ( const ULONG ulRuleID,
$ v* A1 q! {4 B( t! N: B, |          const ULONG ulVal );, C, v, U3 y- L  o* r. W+ X% o5 }
/ W8 S3 m. `4 E" x- E: l
////////////////////////////////////////////////////////////////////! X* Q: u; j! }1 B1 G/ q/ a3 C
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
6 y7 |0 e6 Z1 Y& Q; h" A//参数: 无。
/ C% O$ N/ `1 j3 ]8 V* w% _; ^//返回值: 无。, d9 E* j7 r; `; F
////////////////////////////////////////////////////////////////////
+ k0 z& a! J1 Q6 j$ d5 {0 D: Ovirtual void OnRecoFail ();
' d! p& T+ N( h8 }5 q. X
5 [# r9 G/ x& O: V$ J, C! ]////////////////////////////////////////////////////////////////////
4 h' y  n' L  i7 |; Z- U//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。3 y" B0 q1 z: o% @
//参数: 无。. K4 ?/ O; v7 B- [+ H* P5 i
//返回值: 无。
! N6 F* E9 q7 n& Q( ]# Y3 C7 n////////////////////////////////////////////////////////////////////
- w: L9 J+ u5 {* B$ T2 c& l6 Svirtual void OnStreamStart ();
# O6 @3 l  b! @" U+ X' ?
5 h% A6 B) `$ S////////////////////////////////////////////////////////////////////5 V8 r; L& h' V; v& F
//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
/ r7 d5 q  _( N- Z8 q; c//参数: 无。
# ?* j! V% O) d" L; d//返回值: 无。8 V  e" ~, K. }( Q  z$ _3 A. \
////////////////////////////////////////////////////////////////////' `( d9 w/ N( a) S: D+ j
virtual void OnStreamEnd ();: p% ~: s6 J" L+ ~5 V. R
' G( J; L/ b' ?7 m- \' k
};
% }% ^' @0 ~" N1 O
: k, K8 Y+ p, D$ K  W5 t4 b. M# s& q) \( U# E  A

$ Y" D# \! o+ i#endif    //LANE_SPEECH_DLL_H
5 d" ]" o& l, `% G
) @9 l0 w$ u' ]9 M# D6 I$ z///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/ c2 k2 _# K3 m
' t5 r! r/ [- P) L+ J" N////////////////////////////////////////////////////////' o/ P- \/ N+ z2 h3 e
//
7 Z+ M1 f3 n# C0 s5 g7 C! p// 文件:LaneSpeech.cpp
1 a1 N. M  `0 k// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能' ?5 ]1 J) }7 @" Q
//    语音识别只支持命令模式,不支持连续模式
: Z0 i- c. J# g, x2 }( E// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
6 H9 i/ |: S2 s" b) B, x5 P; @// 日期: 2004.10
+ a/ u: L- r+ w4 i+ [// 版本:1.2
. T/ k) g' S$ A5 e6 W4 R0 c) b//
; u0 z- w0 ?- A" f+ ^) r//4 J, p+ ?, R& r  Q* ~# _1 p
////////////////////////////////////////////////////////
: G. ?# f/ n4 a' a* y1 _
2 J/ x3 q- E$ P& K
/ B/ ^: D  {) }6 z' G! {; A: @! V4 c3 l3 e: o
#include "LaneSpeech.h"' d1 x4 U  p! M8 D! C

, P8 X9 H  p, t  z+ E- J3 r//-----生成动态连接库和静态库的处理----------------1 l0 W& C  b" E3 l+ |; ~4 ^
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
* Z- |* O. N  w; T, _
9 Q5 D6 z0 ^- n2 S  ^8 r5 e; r, RBOOL APIENTRY DllMain( HANDLE hModule, 3 k- R6 V% p8 V, Y% t$ l
                       DWORD ul_reason_for_call, * F( @5 S) M& f* }3 S6 [, e2 Z  p
                       LPVOID lpReserved* ?1 l8 j+ c. r/ B
      )  S4 P3 {$ ]+ q$ U3 i, ?4 P& e
{
' g7 g( {- {( Q& f& v    switch (ul_reason_for_call)* g5 w* g9 x: [6 E9 e( d3 X
{* P, l1 I7 }, `$ {& |' O- x
   case DLL_PROCESS_ATTACH:3 F- h2 `3 s. D
    CoInitialize(NULL);
5 @$ H4 d$ ^3 R    break;" H4 U2 ~% Q4 h* y& w7 B
  
! ?" o  `. x1 u   case DLL_THREAD_ATTACH:
& k0 O' |- L$ {+ }5 a6 e    break;" _) R7 T1 E' f5 i" s$ t3 d6 o
  
' e; a( U" e. q& a9 @! Y   case DLL_THREAD_DETACH:4 ^3 ?, L& ?2 X% [, O5 P( K: N
    break;
  Y4 a2 \3 k3 {6 n8 S  
9 R- l# p: y( i7 }  l0 u   case DLL_PROCESS_DETACH:7 K4 p8 P7 d& m+ N5 J" _& j9 J
    CoUninitialize();0 q% l2 z8 s+ E( ~6 w/ M0 {0 o6 _- U
    break;
0 T" B9 j' H+ i$ E- i    }, v& j. M& r( `7 ~$ Z
    return TRUE;
7 V; w- a, K) U0 Y/ F}
2 O2 d% y* U" B& g- ~5 a/ r% u! w0 ]2 D- l
#endif //USE_SPEECH_DLL
$ n0 a0 {9 q, G# ]! H! Q, m- l6 N
; z% K7 W0 h4 Q+ B2 L9 _: Q" e, F# L3 B, I8 e+ R

- t3 z4 H. {- h' Z- z//////////////////////////////////////////////////////////////// E2 S* i& f; ~3 f, S% k, `9 I- K
3 g; l8 |: [( P& H  \7 I! Q; f' B! |
////////////////////////////////////////////////////////////////////
& T0 {! r* ~( J% S& T# ~//功能: 弹出一个信息框。
3 x& s. j) E1 v) D$ ?$ P8 ^, _//参数: lpText:是对话框信息。lpCaption:对话框标题。
! N, a  C; X& S//返回值: 无。1 n3 |- {) ]$ f* `8 B. s1 ^
////////////////////////////////////////////////////////////////////
9 z0 d5 S6 U/ minline void ShowError ( const LPCTSTR lpText = "ERROR",9 @' q& ~( p% I8 Q
        const LPCTSTR lpCaption = "ERROR" )4 W% `: A7 H1 t7 H* {' {% f% B
{! }. ~4 V# c! I3 ~
   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );7 p0 j2 j: I8 V
}. X  n4 ?' N. [4 R- X0 B2 ~! W" L: V
9 k  o/ d8 ^( x4 m; H
////////////////////////////////////////////////////////////////////3 i  J8 Y: w; `7 S5 ?$ }
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。3 o& Y7 c$ y7 t  q3 K& ?+ M8 _
//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。& e% L6 s/ f" Y) @: Q/ |
//    lpCaption:对话框标题。% b8 c- H$ `7 h$ U9 J1 D
//返回值: 有错则为FALSE,没错则返回TRUE。9 y/ ?" q; ^6 o) {+ A8 W
////////////////////////////////////////////////////////////////////5 o/ ]  N( V( W
inline BOOL CheckHr ( const HRESULT &hr,
# H: X; f; _- G* k7 n8 z        const LPCTSTR lpText = "ERROR",1 V+ b+ k6 }/ y$ V. M
        const LPCTSTR   lpCaption = "ERROR" )) u+ Z+ I! E! f2 y/ S3 J1 L& D
{
( x  M. `" c- \; c" R3 ]$ Q   if ( FAILED( hr ) ) {' M6 P" c* q5 K8 j
    ShowError ( lpText, lpCaption );
; L+ o* s0 |  Q' i    return FALSE;
6 V* Z5 C4 i6 _* Q' |   }
/ l# T9 ?' |; f' P, \   return TRUE;
. u5 d( w5 `1 G" u}
6 o9 U/ e- e. J( p0 I* L5 E- Q8 y8 f* X- }: ~3 J1 u7 n( ]

+ @- h/ }. C* F9 {, r3 v# d; c///////////////////////////////////////////////////////////////////////6 \3 F0 w, `5 Y6 M* x/ @" W
///////////////////////////////////////////////////////////////////////
. U" m9 r7 l' z, u- F% }5 x8 U& P0 K5 n//
4 U3 U1 ]6 K1 g; m6 J//         CTTS
( n2 X3 L; a- o$ N//
3 h' x. \- U) ^# z* ~" S4 K7 U///////////////////////////////////////////////////////////////////////
. Q+ `0 }+ |  f- W8 v///////////////////////////////////////////////////////////////////////
7 o; u& @& H0 @* D0 `  k
6 y7 V# @0 v& C6 @2 ~% B& ~2 V4 I////////////////////////////////////////////////////////////////////
) Z7 @3 p5 r, |//保存关联窗口句柄。初始化COM。
$ a% ^+ @1 v$ m////////////////////////////////////////////////////////////////////
5 g! A3 U3 ^; ]) t' |CTTS::CTTS ( const HWND hWnd )% ~9 f4 J6 [8 r
{
# N* q8 e8 J, Y2 S  em_hWnd    = hWnd;
( }9 w- X" d9 V3 O" E0 J; Em_pVoice   = NULL;
- o1 y9 N+ I9 k  l6 I: _# ?m_pToken   = NULL;" g5 ]3 [! k+ }; p0 _
m_pOutputStream = NULL;, l& q# q6 _$ }- P. B  q; d  N4 h
m_pAudio   = NULL;( x! B# }2 @. x, k3 ~: ~
}
4 B0 w( v% z% c+ G4 p4 t' F# ~
8 k# j" g; @& W, V1 I1 i////////////////////////////////////////////////////////////////////1 D4 B+ l5 [- i- m' L) T
//释放所有对象。
  R1 B' E5 ~, }# [  b# M; [! `+ ~////////////////////////////////////////////////////////////////////
1 ]* o+ k, H* q9 pCTTS::~CTTS ()
  {, j+ H3 F7 p. M3 K4 M( G# w+ {{
3 U# a* e4 Y" S! Z  {( Wif( m_pToken) {
, K1 c: x) v4 @/ i3 t9 f   m_pToken.Release();3 o2 n2 I& X4 @' K1 o8 M* L# `
   m_pToken = NULL;
/ m5 \% }, @' }0 Z; {" X! s% X}( S/ e! ^! G* l4 U3 Y" [
if( m_pAudio ) {
  i* m; K4 G3 u7 `! e   m_pAudio.Release();) Y$ m6 ^: _& m  u9 t! i- O
   m_pAudio = NULL;
+ {2 p: ~8 I9 n" W9 q# M}4 Y1 m; P) Z# n' j- P' c1 X% y: x
if ( m_pOutputStream ) {8 Z1 u# m6 r0 _
   m_pOutputStream.Release();) q5 k/ V; U4 F+ J* _
   m_pOutputStream = NULL;
. X1 u0 r, J6 b9 Z}9 I2 I% r. y. d+ M
if( m_pVoice ) {
$ I* j4 j+ O2 h; K* ^   m_pVoice.Release();
0 X  x5 e! [% y   m_pVoice = NULL;4 o: g- ~5 y) ]
}$ u/ W/ A' v5 }/ P# |8 D' f5 @% n* B
}
9 o' s' h  U$ d6 j: X
. ^& \* u  n$ L  Y7 k' Y0 s////////////////////////////////////////////////////////////////////2 p; d9 g7 n6 }
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。/ {( j2 ~: ~! A; q' V5 h9 h
////////////////////////////////////////////////////////////////////
2 V9 G0 N# W& N, cHRESULT CTTS::Create( const CSR * pSR,1 K% n  ?# l- r! v% j! l
       const DWORD dwLanguage )
' Z8 o) S! i9 X5 H5 Y, B' L7 W{
- i1 J8 p  z: Q; X1 E* @HRESULT hr;
  f* {/ K/ o$ |% [8 ahr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
; c. v1 e* {; W. N% b& Bif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
7 Y3 z% P" T3 R* C) h( h   return hr;
8 c* {) Z# U1 D8 _9 k4 R% A) e}- n! Q1 l* g( T* v" l' L$ |

" _, Y9 q) E. B: eSetLanguage ( dwLanguage );
8 Z9 |; D7 w6 _9 a7 B: x' g: N0 b4 f% C% ~$ I7 w: e( D* g" L7 r8 z
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流0 H; g+ i& E, U3 [" F5 v
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {# i1 Z8 @6 X- p8 [5 E" e2 H1 G
    return hr;
9 S/ f$ n$ e/ r}3 d) f0 H0 X0 a; l& Y
/ h% w6 j  Y% |$ p& ?+ C) g
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
, G9 S) `: ~4 i5 Z9 x//SPEI_END_INPUT_STREAM 表示完成流输出。6 Y) l* Q2 F5 g. J0 ^* P
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
/ f! P& x. A% P         SPFEI( SPEI_END_INPUT_STREAM ),- f0 A" _# f$ w; ^  p! c
            SPFEI( SPEI_START_INPUT_STREAM ) |' c- o. N3 l8 N' t3 F
            SPFEI( SPEI_END_INPUT_STREAM ) );+ N0 B* G  J, v6 |
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {  G2 d% _1 H2 R" X0 g7 Y0 s" _
    return hr;
. K3 L* w* I" P' r& Z}, O9 A: ~+ w! [4 t+ Z; Z( ]

* y! a0 l0 M, z( L8 o//设置通知消息( b$ l* D- ?1 e+ R! k
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
  u# {  T4 E/ Q) O3 Yif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {/ G4 z) G- H, k! E- C9 c  Q8 i  G9 p
    return hr;
- j+ D# T3 l9 h}
1 b' V; ]+ q$ V6 }; z
3 o8 Z; E4 B1 T9 Mreturn hr;
' J' v6 e8 r1 V/ H}( b' C8 H5 k4 n( {
" x, `+ g8 s$ _: `, ]; Y! T
////////////////////////////////////////////////////////////////////8 y1 L  _5 I" {% L
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。. S( q) Y4 `9 U- q* y
//并设置兴趣,设置通知事件。
7 B7 E+ S& g* V3 J8 r- M////////////////////////////////////////////////////////////////////& z- M2 c) ~( H* U6 f1 E
HRESULT CTTS::Create( const DWORD dwLanguage )
/ N1 t0 e' \9 r& @- C- F{
% U1 e; {* M3 z6 r% @2 kHRESULT hr;/ O5 O6 K: e7 e0 b
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
% J6 A7 D: t: r3 I5 \4 Vif ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {( I$ k, k+ c9 W. m, [4 z; {
   return hr;3 q/ s" h: `9 d/ e% r# L
}
) U+ b/ F* w; ^' O7 ^: m6 ?6 M+ l/ M- h# l2 Z
SetLanguage ( dwLanguage );& x% p3 i2 O( W4 S. k5 _, R
9 l! `6 \' M/ J0 l3 ?; c! g
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流  ^$ S2 f: p4 u2 \% t+ }- S
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
& o+ z4 ]; E. y  j3 F    return hr;' h2 x# Y: B( u. ?$ \
}
( w" a5 u! z7 p5 \2 K
' T4 |# W) C% w9 g- P//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM, C2 A( p# P3 p' Q- c# T2 H
//SPEI_END_INPUT_STREAM 表示完成流输出。. C5 j* U  E; f1 H( s( l4 N- A
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
: N# L4 c7 r9 g         SPFEI( SPEI_END_INPUT_STREAM ),
9 U& u/ H) ^1 }( }! n            SPFEI( SPEI_START_INPUT_STREAM ) |
# o* Y, o" ^0 Z6 c4 J& n7 _* {1 T            SPFEI( SPEI_END_INPUT_STREAM ) );) k0 X+ r% w2 x/ c, w
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {4 n; F4 |8 R$ D( s$ O& g
    return hr;( e2 R5 P! q# A% a& J& p: M* E
}
7 ^5 q& f0 O' E' K& W4 I) l7 N! i8 }) M
//设置通知消息6 O+ \: v& r0 |7 n; o6 B  O
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
1 Z' ^2 C0 H9 _: r# R9 X  Cif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
( y! G4 i; _# ~$ C7 c/ ^/ K    return hr;, N2 _$ `5 s( K9 A( A) A+ s0 P
}: v. O& G4 l! A: j6 O: I( K

$ r' z) }/ `8 _return hr;
8 o8 T5 G0 i6 x0 _( V) b; {}4 d% k* U% D3 C) _% b+ X2 L/ s
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件
+ L; j8 ^. C2 g; A; B6 S& I$ [#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
4 V$ a. P$ u/ i2 {4 r7 @{
, l+ z6 r/ p+ O) D    ::CoInitialize(NULL);//初始化语音环境
$ |1 N9 S: T8 _9 X3 I; T    ISpVoice * pSpVoice = NULL;//初始化语音变量
8 @0 W8 w: L+ {: O' e* s( A1 K    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
* m9 R: O' Y9 n        cout << "Failed to create instance of ISpVoice!" << endl;
) H6 {1 G; [% p        return -1;
7 W  s, f5 g- \7 y% [    }
& W" M  s! [, w$ {1 J6 F* F% @
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
2 |9 w/ A) l! v, v7 d8 |    ::CoUninitialize();//释放语音环境
- A  ?6 K; L( {
    return 0;
$ x$ x/ ?" z* J, R  w0 g}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序
) y! _) a7 I) H# v! L+ W9 o7 g) W; S, [/ N$ I0 l
1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地" f5 E; A. C0 v" D1 r
8 _- ^& R+ @0 f6 l
http://download.microsoft.com/do ... -US/speechsdk51.exe   6 r8 t0 X6 H2 Q/ r
Speech SDK 5.1安装包 (68   MB)     
$ W; m0 c! G8 khttp://download.microsoft.com/do ... chsdk51LangPack.exe      . b& k$ }' M7 T' @& {# I+ n8 }
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
# D3 z  n/ p6 ?* q
) y* N' t% s& ~- ]3 Z% U5 x2.下载后,执行安装$ f- D; a3 j6 D1 I2 V0 z

% o/ w# N" a( z8 L下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
: q. @5 l5 P% V! }7 q" ^; p" T7 q2 `9 ?9 E- M0 c2 v7 B
3.VC的环境配置
2 K  k, U, E  q* D& r
' p  Q  K1 X' _+ \5 h" X在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:0 y! r% U/ X6 J! {
2 W2 R  l& ~9 y0 y9 Z4 v4 R( y; Y
工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
) A+ W2 `! x: k( f" n
" V# o4 y% A  u5 Z好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
* ~. e8 H3 b$ U/ R6 _3 f3 t
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-11-14 16:27 , Processed in 0.020117 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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