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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////. O2 E2 p2 |+ ]3 l7 o. b
//1,生成动态连接库时,要#define USE_SPEECH_DLL,4 R; R. R8 `9 ]+ B' P( B- F
//      并且#define LANE_SPEECH_EXPORTS' x! D% B" ~+ a- w3 v0 C6 N
//2,使用动态连接库时,要#define USE_SPEECH_DLL! X6 B$ O4 n6 k/ [3 S( A
//3,声称和使用静态连接库时,什么都不需要2 H. ]6 U2 j8 w9 R( d/ P
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),4 Q4 U. z# E' R' B
//      动态连接库就不用调用了。0 f( K+ C5 w& @: I1 N) d- A& ~! p) W
////////////////////////////////////////////////////////
7 u7 O+ J5 i9 p. K#ifndef LANE_SPEECH_H  ?4 p' h2 i  j& T/ B- Y! l
#define LANE_SPEECH_H$ {8 i( N) T8 _( s+ f
1 c/ W1 o- r, ^) K( t; n
#include <windows.h>
6 b) a1 P0 Z' w* V. _3 j#define _ATL_APARTMENT_THREADED1 g" Y2 K7 X! N: n, Y
#include <atlbase.h>
+ K7 J% Q2 x; ]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' k9 X4 L; u( I7 g. t
#include <atlcom.h>
5 s) w5 U  t3 X#include <sphelper.h>   //sapi需要的头文件
9 h" C8 G; S; R( N2 J4 E! ^: K4 w0 \- s7 A
//-----生成动态连接库和静态库的处理----------------. |3 L4 ^& x) t. E8 O
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类6 Z; w% u& ~6 H+ l. u- Y+ @

3 u& O" _2 K% w#ifdef LANE_SPEECH_EXPORTS- N+ h/ H. m* F+ T7 P- c
   #define LANE_SPEECH_DLL __declspec(dllexport)3 k+ b4 Z, [# z1 d# X8 a: e
#else: z  U+ z; J3 ]" V
   #define LANE_SPEECH_DLL __declspec(dllimport)
% O$ s, q- h2 U- l$ O- J#endif3 `; v8 F5 S# K0 i" ^

! p& w+ A, a( T//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关
; ]! u" p' c2 W0 E//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
6 r" }! ]7 y) v% t, U; ~#pragma warning( disable : 4251 )% d/ i; `. d5 I/ i% _# A: O" N$ b

/ ~8 m- z/ G. G8 F& s#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)# V* R, L2 l8 M0 r" G" K
#define LANE_SPEECH_DLL8 E' _& H# \  Z

! ^+ v- ^  R7 ^" k5 e! @: t5 X+ t#endif //USE_SPEECH_DLL
+ f* R, ]0 G0 a) ~; I' K7 M
& j9 r+ u9 {" o. e9 T) W
  o0 Q" h' ?7 N( T* d. K7 L# D' z//***************************常量***********************
2 H, [6 s; Z- l) ~6 q  M. G0 y: s; l& g
/////////公共常量-----------------
4 u6 \; e/ N# u. [. Y5 O. z# gconst DWORD   SP_CHINESE = 0x0000; //简体中文.
7 \/ K# z: }; a  q# [5 Q" B4 }const DWORD   SP_ENGLISH = 0x0001; //英语.& y2 m% A) c4 D4 B) F  z

3 ?7 ]2 I6 t9 ]9 ]  \/////////CTTS常量-----------------
/ _4 a0 B2 ~- R' nconst UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
9 T$ ]5 p9 y4 n6 |+ C7 q: J7 u+ y: R- Q( v( M! [
/////////SR常量-------------------
$ y& ?' O/ V+ a$ m" r0 {const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。
  c9 X' ?1 E1 B& hconst DWORD   SR_INPROC = 0x0000; //独享类型的SR.
! s- K% P- \% s& J7 Tconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.( \, B  U" m$ S4 \" h
! E" |: O9 p- Z# j4 I% }& L# R
//以下常量仅作例子用。- S5 I8 P2 N2 _/ A1 b# ]6 R5 p% z3 `
#define VID_TopLevelRule 9000   //顶级规则ID
& v5 }% O# N, T, ]: v8 r#define VID_SubLevelRule1 9001   //子规则ID
' }( T4 g6 `* i" O: A#define VID_SubLevelRule2 9002   //子规则ID( u  v3 q+ C7 I: }/ Y3 C- P' |  D
#define VID_SubLevelRule3 9003   //子规则ID3 \# l- ]3 W4 _% O0 X9 I5 l. y5 ?
1 w9 [2 }$ t/ r

6 A2 n! J9 Z% J+ ^8 L) u- e2 u' h//*************************类声明************************  r0 D' L/ ?8 [4 J
" T0 d8 C- E8 o) }
8 f% r" d3 t2 m" i+ f/ P  P  F
class CSR;+ `( ~& f  u# ~8 c. J0 L
///////////////////////////////////////////////////////////////////////
; K( |) g( @. T* @8 Y- ]///////////////////////////////////////////////////////////////////////
8 L  X9 G' _& b  ^$ \//
& [  C, E" M/ t+ g- B//         CTTS. M# o5 b) H. y" k# [
//+ l2 U$ ]: f. F7 X) Z
///////////////////////////////////////////////////////////////////////
7 R: k; W2 u; }7 ]) l$ H///////////////////////////////////////////////////////////////////////
( W+ S+ M: k4 s' I) ^9 m8 o  z) i; ~( y8 V" y: ~0 j, o' {! H! ~+ I
class LANE_SPEECH_DLL   CTTS4 h( Q) K1 l( n( Z& |/ N
{  b0 y& q; T7 V* K' A
protected:
9 e7 D- @/ @# U# E" JHWND       m_hWnd;     // 关联的窗口句柄。4 B7 p7 x6 B2 _0 A
6 v% L4 W+ ^# z; l" @4 h3 w
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。
7 F# v- j. |* u4 \" VCComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
1 m* l' [* X5 ^0 S4 @, f0 A) uCComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)
8 o1 t( V2 y, H& s- s6 _CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
. W" y* v! B; Z6 t' I% [
& H; m, j+ m/ L6 c5 Hpublic:8 O5 n! }2 i' z/ C5 {6 |
//********************************初始化部分********************
( V; T6 z. L% w: C: P, i- R' D. E5 W' R
////////////////////////////////////////////////////////////////////
) w8 D! x( l1 b2 s//功能: 保存与识别引擎关联的窗口句柄。" k5 H6 \: O8 s  ^
//参数: hWnd:要关联的窗口句柄。4 a2 Z4 }0 S( z7 k6 {
//返回值: 无。
- Z& n1 t& Z$ W7 b0 P////////////////////////////////////////////////////////////////////
4 e2 `1 b: J) Y7 g$ hCTTS ( const HWND hWnd );# j" |  Y0 W) c$ B/ A) T. [  V. P

% ?- @0 B7 b6 r$ S0 ^- s$ y////////////////////////////////////////////////////////////////////
9 B& J) h5 H/ D0 F, b2 R/ D//功能: 释放所有的对象。: ^. F$ e0 k. ~' i# f: C+ b# B) E6 X
//参数: 无。
0 s- R2 ]8 U1 i* Z; X. I8 Q: x//返回值: 无。
0 H! `# b( f6 N////////////////////////////////////////////////////////////////////& P" y/ w. K+ i) Y1 o
~CTTS ();
* M9 K# C+ F$ N% M. |: N
0 i1 d) H. i/ w& x" y* |7 c////////////////////////////////////////////////////////////////////
# g# o% B1 f3 \5 f/ K& D2 G//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。
6 B" \1 W( V: A" j$ s" Q* l//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
, e  v* W& n0 Z2 n) T//    SP_ENGLISH为英文。6 g1 l* _/ X' |9 o
//返回值: HRESULT类型。
6 W# {: N+ k8 S" s////////////////////////////////////////////////////////////////////
; n+ j( o6 N. F* x* E# Y' ]HRESULT Create( const DWORD dwLanguage = SP_CHINESE );7 K& ?7 h% B4 L- l- K6 x5 ?

% G2 ]3 A6 `$ w' r+ u9 I1 T////////////////////////////////////////////////////////////////////) x  A% ?  v3 g& F, V9 I& W
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,% N3 {- \" g$ g9 X: s& U: l& x
//    通知事件。
+ f% c1 T: Q; s5 i6 i9 H) R; f//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,) u5 b; p3 W$ _- J( M
//    SP_CHINESE为中文,SP_ENGLISH为英文。1 Z2 ^% y; W- y' |. I5 K/ h& c
//返回值: HRESULT类型。
8 q& s) ?3 `" c2 Q/ @, S////////////////////////////////////////////////////////////////////) Z; W  @; O( F- `# H+ Q1 R
HRESULT Create ( const CSR * pSR,
5 ~; x. `/ \, T( A8 _5 V" _       const DWORD dwLanguage = SP_CHINESE );
' d8 M4 ]  l8 @5 b' K! s0 ]2 k0 j( s' q9 z9 l
( s* M5 X, @2 v4 M) ]4 J. E# B% _
//********************************设置部分***************************************" h4 M, I5 d( I7 c

- Y) e' o7 T& L8 x% L////////////////////////////////////////////////////////////////////7 h- _( t' x. p" O7 R/ ~, @
//功能: 设置朗读声音的语言种类。% ?6 Z  C0 o3 m+ _, s4 U7 p" {) @
//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
  T- `* V0 I$ [, h1 ?3 M6 `//返回值: HRESULT类型。  ^& K& q5 o+ T/ W- q
////////////////////////////////////////////////////////////////////& ~# u8 W& t* M4 {! l& w
HRESULT SetLanguage ( const DWORD dwLanguage );6 y# m$ N5 B) n0 U, ]+ Z. ?
2 k9 t/ w$ f& q: A! a- z. C/ x
////////////////////////////////////////////////////////////////////: e0 O0 g7 T# }
//功能: 设置要处理的的事件。
( W9 b& X+ B$ r+ x' f' g3 k  P//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,/ p0 U% P- {, f8 A
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事3 Z6 V/ v0 a7 C! M
//    件都会收到通知。
" u: w; _  _1 D5 \" c% {//返回值: HRESULT。) P) k' c8 O/ A% E* \6 u$ [. u
////////////////////////////////////////////////////////////////////
7 I7 M) D1 N6 n: m$ n, zHRESULT SetInterest ( const ULONGLONG   ullInterest );
9 D8 X8 A' O+ M6 Z8 Y- @/ y- v( e0 |' _4 B& U
////////////////////////////////////////////////////////////////////) _; B# g% A& D
//功能: 设置朗读声音的音量。
& w: g, N% N, U/ G//参数: usVolume:音量数值应该从0到100
/ \) v) V9 x8 k3 N; z//返回值: 无。
: l5 X" W6 Y& y' y////////////////////////////////////////////////////////////////////
" |: s% `! Z1 ?: n3 Y4 t( {% Y8 vvoid SetVolume ( USHORT usVolume );
- B) e# T+ G4 i# g* B, P
+ Z0 e9 c& `) z! g2 Z6 g////////////////////////////////////////////////////////////////////4 ?' T, ^* h: V! X1 c
//功能: 得到朗读声音的音量。2 q. x. M$ M) B) ~# d+ }
//参数: 无。% \5 N' u! l8 y; L: a- n
//返回值: 音量数值,应该从0到100。
1 F' e* _, E" m0 m, h////////////////////////////////////////////////////////////////////
& E/ Y" I& D# y/ E' ~USHORT GetVolume ( );1 L/ x, o, Y; H; k9 G

& y! C3 V: ?! f7 I7 R% r////////////////////////////////////////////////////////////////////& o* ?7 h* c/ g+ E
//功能: 设置朗读声音的音速。
2 |% {$ S' ^! p  `//参数: RateAdjust:音速,参数范围从-10到10。( T$ U3 u$ x) y# K/ f
//返回值: 无。- e# M2 N* U% A" x: m& i) f& z
////////////////////////////////////////////////////////////////////
: X, Y3 Z5 e* O6 Q* Bvoid SetRate ( LONG RateAdjust );4 R3 ^% i: V' N3 U
; w. ?. v, Y6 V* E& ?
////////////////////////////////////////////////////////////////////
! [/ n1 E, p1 E' M4 ?$ G+ e% G//功能: 得到朗读声音的音速。1 ]4 H7 v( C9 q5 H: F0 d3 U
//参数: 无。6 W( I' ]+ b$ J  o) k+ j$ p) j
//返回值: 音速,参数范围从-10到10。% U+ u  z3 L2 Y, |$ g
////////////////////////////////////////////////////////////////////$ |3 N! d9 P8 B3 |8 `7 m
LONG GetRate ( );
# @+ S. @3 `9 }: N# W; n
7 |- d5 h) W- D; X) v/ S) D////////////////////////////////////////////////////////////////////
  b8 ?0 Q/ P8 ~2 {/ R& ^//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。4 T/ `1 _4 @1 u+ J- R) Y1 f4 G
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。5 T* _3 \) B; X6 h: E$ G% p
//返回值: HRESULT。7 h3 ^/ s) [3 q& G9 w9 O
////////////////////////////////////////////////////////////////////
: G* y) a. J( Q* }, UHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");: Q) h* l! n- v, j- d! W6 Q9 `

( W7 a9 q) E: X7 V' e////////////////////////////////////////////////////////////////////+ I8 _8 H' |! M' ~* y
//功能: 设置朗读的声音从音箱输出。
) J: g6 P7 u- w$ B9 o5 m# p//参数: 无。
8 w& X4 V% I/ l+ ~7 u//返回值: HRESULT。
: ~0 V, @5 ]3 B1 f* n////////////////////////////////////////////////////////////////////! Z+ x: K0 ^5 r$ A) c
HRESULT UnSetOutputWithWav ();
5 E' A' n4 Z9 ~& E; {# D6 w
* Z9 T  r7 k) y; D% ]8 o1 M2 I0 q& @# o9 w
//**********************播放语音,文本到语音转换部分*****************************
* |, j1 P* N, a: x  p; w3 d# y% m  d
////////////////////////////////////////////////////////////////////
5 W( f5 d# u- z- Z3 r. v//功能: 停止朗读。如果朗读为同步方式,则不能停止。
8 s% u2 i+ H+ q& d$ K0 [+ S//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
. x7 j2 e) i. ?( f9 H. S//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
5 [/ k7 ?2 U3 ]0 |1 Q  c1 o0 D  p//    SVSFIsXML为朗读带xml标记的文本。! ~( \7 X# p/ I+ m. W, Q, _% W
//返回值: HRESULT。
) U! R% Y( x5 n; i2 d////////////////////////////////////////////////////////////////////9 q: @3 X3 u. V
HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
& l9 |) X, N+ x& J* v$ D4 y9 l# k, l: Z  B" p0 m; \" k
////////////////////////////////////////////////////////////////////
% _4 a7 P# q8 p, C& X  e//功能: 停止朗读。如果朗读为同步方式,则不能停止。
3 @! k* @9 b* j1 B3 y//参数: 无。- ]5 i# h/ w1 L, N! X3 F2 o
//返回值: 无。
, a6 |2 c& T1 j  c. p////////////////////////////////////////////////////////////////////% h. z% a$ Y, E) F/ d$ s. u7 d
void Stop ( );8 M, c: `: Z+ q$ [( D7 R

( [' ]' k3 e1 L7 D////////////////////////////////////////////////////////////////////
% M# ~  B7 ^& \  J//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
2 x( ~! }: L) x0 U3 R( `3 t. Q9 d//参数: 无。
, W' n3 p. I! v; Q; `5 o//返回值: 无。
' D7 K3 B7 ]1 t' K////////////////////////////////////////////////////////////////////
' v- k* c9 ~. O/ E3 svoid Pause ();8 K8 A: C0 H( v% ^
. G, Y  E4 M' h8 R
///////////////////////////////////////////////////////////////////// {5 U2 i8 k6 P, q4 k' A% d+ p8 w
//功能: 从暂停的地方继续朗读。
2 N$ q! s; z! t* Y//参数: 无。
4 L5 M/ `9 |7 O* H- p//返回值: 无。0 c; v5 y$ {' }3 J* O2 _' X* z# w1 @0 n8 n
////////////////////////////////////////////////////////////////////, a, k0 ^5 l  T$ c5 [6 `" D
void Resume ();+ f+ t& |3 j) Q0 z) _

! Z/ k% r, F! e1 l; E  x3 z( ~: b$ e( X$ F
//********************************处理事件部分***********************************
8 |* D8 v8 B. r, F3 K4 k- _& L% i% h9 r+ ]- e9 E. `1 n
public:
( h+ z" l- P. e4 e# f////////////////////////////////////////////////////////////////////
" p1 g# k; L. ?; p# G//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。& l; y' @- ~* S- Z& G
//参数: 无。0 z9 Q# u4 t% e  X9 Z
//返回值: 无。
. y- |7 x. e* S0 g/ v3 Q% n////////////////////////////////////////////////////////////////////+ ]4 P# U! W! W( b) ]* q- P
void ProcessTTSEvent ();9 @  d; `2 a' b& q

0 Z* S  V, x3 N$ @4 D; @
% u  r2 m6 ^! x- p////////////////////////////////////////////////////////////////////
5 A7 j- c5 {7 D( |' E' F( L//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。: y' O" a2 j5 `/ O1 K/ }1 k
//参数: 无。
' [. b% Z3 ?3 `% J% R4 G//返回值: 无。) k. w! `0 x, P; j9 x
////////////////////////////////////////////////////////////////////
& E9 d8 P4 n0 h. [# Nvirtual void OnStreamStart ();* t* T3 S9 v- E, z0 S% [7 A) M
1 }3 k1 L6 o; R
////////////////////////////////////////////////////////////////////0 q9 ~- W0 @% c; ^
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。, u% t+ C$ e0 W, v
//参数: 无。" n' H- |$ X6 F2 G1 D) l2 o4 {
//返回值: 无。
  F) ?5 k+ Z9 w5 i' E////////////////////////////////////////////////////////////////////
9 g; ]5 @0 r4 @' _+ u2 yvirtual void OnStreamEnd ();) p* G2 A0 F3 j$ J8 N
};
0 t# |2 `$ C) L$ B# N* \9 y* @) F& m( y. y7 A; v

- u+ f" b/ X; W8 O- H///////////////////////////////////////////////////////////////////////$ C: h* y) O, K' J: [. Y
///////////////////////////////////////////////////////////////////////+ f' k4 S- T+ H7 F; ^8 Z' l
//         CSR
( X, i( p3 x. ?6 n9 }. Y//2 o  I2 z7 Y3 j- j4 O
///////////////////////////////////////////////////////////////////////( q, f! d8 q: b" M  p% a4 k* d
///////////////////////////////////////////////////////////////////////! X4 \8 u9 I/ S' Z
  a2 C+ }% k8 H- p& ^8 c
class LANE_SPEECH_DLL   CSR6 }( i0 B) _$ `7 @/ e0 b
{
5 \# \# k! q" T: V- t5 q4 Y0 U) I' T/ A7 \2 q
protected:
6 B+ r7 a( b, m5 U1 s& pHWND m_hWnd;* V1 @7 f1 ^- S5 O
% Z6 I, F1 S9 A# f5 j4 u
public:* p) o9 C  {$ M. U$ l. d& h
CComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。) d* A5 e" J2 B% q& n' @+ D6 _
CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
1 U4 Y7 Y. {) uCComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。
6 y" d& M6 M. `CComPtr<ISpStream>    m_pInputStream; // 流()的接口。
9 O! u9 |; w) o, E/ ACComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。! C2 o0 R4 ~, b2 I: B
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)' t1 ]1 R: x( b( x  O) t
public:
0 J/ g, z. P, |/ E3 F) U/ S$ Xstatic ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
- f# Q% c2 E# k* ^* O9 c: Z  U0 x% G$ R
( w& x, W9 f' p) D5 P9 z9 H
protected:
' Z1 F" M* I; [5 ~1 e0 C//***************************辅助功能部分****************************************
0 O$ W- n3 R$ H: v$ j3 J2 X$ U# s( ^. m6 Y
////////////////////////////////////////////////////////////////////
) R0 u9 X) m. W) C//GrammarID加一,每个GrammerID必须不同。
3 M3 m4 Y* k8 N////////////////////////////////////////////////////////////////////
7 |- O" y! y& U6 G" n9 {static void UpdateGrammerID ( );4 m* x( Y2 X+ `, t: M
! n6 e5 i! Z4 _: j) W6 X1 U
, ]  D) t9 O7 s6 A" Q$ }: E9 J  S. I
public:
0 m+ J! u. W3 U, m" b////////////////////////////////////////////////////////////////////
9 o; R& m+ ^: v/ F8 D: _//功能: 友员。TTS中的从SR引擎中建立voice对象。! {- P$ w9 ?( ]5 h( c
//参数: pSRContext:SR上下文对象的指针。2 j9 D1 e2 ~5 a' R* g( W
//返回值: HRESULT类型。% u! [; N: S& @3 \' q- _+ v) h
////////////////////////////////////////////////////////////////////5 h4 f  o  Z; _2 ?2 b& ]
friend HRESULT CTTS::Create ( const CSR * pSR,, Q+ g& N% w: y% I& Q6 E! P
          const DWORD dwLanguage );9 J8 E. o* ]9 g: V. [4 N
2 m, u% v9 f% ?6 P& o! o6 [3 r8 ]% B

* |) J8 k3 P5 E" c4 V$ i3 t//****************************初始化部分*****************************************$ y8 Q; |7 v3 Z

6 [5 B8 o9 v) v////////////////////////////////////////////////////////////////////
+ ~6 G2 \. P0 _" ]% w. z//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。
& c& l4 Y# x' H1 b//参数: hWnd:要关联的窗口句柄。
' F& k8 ]8 B0 t# |! T, _//返回值: 无。
$ c+ o- |5 p1 Y* \. K; K! k6 m////////////////////////////////////////////////////////////////////
. I1 J8 N" D/ f" }6 F4 o9 b# HCSR ( HWND hWnd );
7 `; C- z4 X. G+ S3 m. t5 P0 T+ V  q  ]. ~
////////////////////////////////////////////////////////////////////
8 P4 @5 f# F! {2 k0 f//功能: 释放所有的对象。/ B; s) I( F, z# x; S0 C
//参数: 无。' e8 j/ E; ?  M: q, h
//返回值: 无。: K  m% k  v# b! \
////////////////////////////////////////////////////////////////////7 \  G# f* y) J3 |, L
~CSR ( );, o% _1 V6 F8 e& }! k0 G: b2 V8 c% j
  V9 i5 g0 G' i+ M2 T# y. ^5 `& L
////////////////////////////////////////////////////////////////////  T1 A  p, M1 D/ w$ C2 S
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,. H  x# j1 ^- N( J1 u8 e
//    加载文法文件。
! C$ D+ h2 Q1 Q3 w//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。( o* e% h7 J& {6 |) }
//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
/ x' I: R$ D! ?) J8 v//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。* I! {, M2 R3 d% c
//返回值: HRESULT类型。
" O2 n; L; C+ Q' t/ U. \1 s' r///////////////////////////////////////////////////////////////////// N1 O) [6 L* }; k9 a
HRESULT Create (const DWORD   SRType,
% \. r, _5 z2 S- \      const WCHAR   *pwcGramFileName = L"grammar.xml",* D$ a  u* g1 x, d
      const DWORD   dwLanguage = SP_CHINESE );* E8 K/ ^2 S. Q4 c6 Q

! m: i9 K2 s' J+ Z' Z+ c& `* ?6 N  |/ s. i- E3 _- \; [" p
//**********************************设置部分*************************************
3 d2 ?8 u* ]* J; }6 N& }0 w
, _0 X6 ~$ F" I; V# l. Q////////////////////////////////////////////////////////////////////
2 z6 ^3 f' W( C8 V- C9 }( x//功能: 设置要处理的上下文接受的事件。' Y1 r1 ^4 m, L% K3 D# s. w
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,  b2 f$ [% n1 j. ?
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
; W3 _% {1 |4 X" K* h//    件都会收到通知。( m  ]. z' C: a' h# k( `/ S2 r
//返回值: HRESULT。, Q  t" G* A. q; `9 b; _
////////////////////////////////////////////////////////////////////
8 v. B; P5 J3 gHRESULT SetInterest ( const ULONGLONG   ullInterest );
7 [) D  L* e5 ?$ H0 ?- P- g
. p7 o+ s. u8 }- ?4 y9 \+ i////////////////////////////////////////////////////////////////////
2 F: m; M# y6 X//功能: 设置某个规则的状态(激活或者取消激活)。1 s: k( u4 U% N, R
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,& b$ e# C8 c/ v- h1 L: w
//    FALSE表示取消激活。1 J: r- s$ `1 a# [4 A
//返回值: HRESULT。
4 a; n6 W7 z# `9 J" J* m! f" C. {////////////////////////////////////////////////////////////////////
6 |" `. I" C0 N5 y1 ~# j% `6 v, PHRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
1 r3 L2 a) Z3 r9 L+ [# ]0 ^" }" j5 v0 e/ M

  p# b. ?4 H) n0 U9 c////////////////////////////////////////////////////////////////////6 Z5 X: n3 F, d+ I
//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
" S$ H6 b; Y6 C/ \# P% N. r9 Q% |//    风输入。
% o3 I0 X1 g1 }6 i; S4 m//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
. K# P6 b, J  K9 u//返回值: HRESULT。
; j" e. w+ @( y5 b, n7 x/ g; j* `///////////////////////////////////////////////////////////////////// ~: u4 a7 u' n" |
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
$ ]& A4 d& j# G. {7 {$ j- X# E/ ^# O) y2 C
////////////////////////////////////////////////////////////////////
: E! e0 q* V& k7 ]' s  }& M//功能: 取消从.wav文件识别。恢复从麦克风识别。
7 g, B  V; U8 d  i5 E//参数: 无。7 N0 g% d* }6 P
//返回值: HRESULT。! C: K% [( C  O% D& Q% h7 a! Z/ B
////////////////////////////////////////////////////////////////////2 c/ p+ \! Z' I- n
HRESULT UnSetInputWithWav ( );
" q7 Q* F1 A' j% \/ R, J+ \4 t' i5 W* _! p" G1 S* z0 G
//***********************识别开始,结束,识别结果的处理**************************
( ~- x0 G; }/ N1 R* r- U: I
$ Q, G  h$ U7 d6 g* |9 l; [7 O////////////////////////////////////////////////////////////////////
1 P: S6 n* `& y- k2 ~//功能: 识别开始(将所有规则激活)。
* A; I0 f1 s5 O2 ?//参数: 无( @+ h3 n  ]/ y4 Y$ Q8 c. J1 K
//返回值: 无。
( W* ]4 y; \. i- l- n) P" u////////////////////////////////////////////////////////////////////+ M) ?! A, w, z" F2 t- m
void StartRecognize ( );
- p4 }! u- {9 ]: r" I3 U% l8 \" d, K/ K( O. D; R
////////////////////////////////////////////////////////////////////
# b3 @7 i/ z( m# Z& M//功能: 识别结束(将所有规则取消激活)。
, `' U0 o3 Z4 Y9 L7 \- v//参数: 无。
9 s$ U6 X7 l. B! L//返回值: 无。
" V- A3 {# r' w////////////////////////////////////////////////////////////////////* ^( @- j: _, h, Y$ j/ V+ P- _
void EndRecognize ( );
& k" i6 P* s* S5 g) p) [7 w5 Y* X# q  D+ M: P8 z
public:
7 b4 f6 R9 l; W////////////////////////////////////////////////////////////////////
, o8 K1 Q! X0 _; D) ^7 B//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
  O% c. C7 h) H" n8 [7 ~9 y/ o% W//参数: 无。
9 Z/ T8 b1 a4 X1 J& m//返回值: 无。
! X+ i$ O4 K! E$ J: e( O////////////////////////////////////////////////////////////////////
' n+ T" J4 t2 I  N& F, n$ ~. X& Yvoid ProcessRecoEvent ( );( M% s$ t, o/ U3 R. }
2 l& M" j2 y/ @7 F: d
protected:
1 _) R3 d& C- H////////////////////////////////////////////////////////////////////
% d( i+ F, [& w% h. A9 F//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。$ a# W# Q" v$ ?
//参数: pPhrase:ISpPhrase类型。
6 _! C7 G" I$ W9 J4 k: K/ m//返回值: 无。
3 @" r) W3 V% {# }; N; O////////////////////////////////////////////////////////////////////! c- U" Z7 Q: y) H3 T7 e% K6 k
void OnRecoSuccess ( ISpPhrase *pPhrase );
! a; y7 l6 V) G8 W( \: E4 c) a1 g; O
public:
# G$ ~1 e7 t( }/ p5 Z# P% h////////////////////////////////////////////////////////////////////1 \. ]4 x- w* {4 U( R3 [
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
6 ^5 C5 d8 B1 g3 {: Q* T1 }//    需要在派生类重载。规则ID必须以常量形式预先定义。
6 h6 g2 p2 k3 K9 M' H0 V//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。1 g7 u) j% m$ v* A: V
//返回值: 无。
4 D1 T5 V7 a3 _( g////////////////////////////////////////////////////////////////////& b6 K3 c" \( \8 p  W; p
virtual void ExecuteCommand ( const ULONG ulRuleID,
2 H4 d9 [; |2 B% J6 q          const ULONG ulVal );! s; y" A$ x, h( c+ m& N
& E# i6 f  F' h; G
////////////////////////////////////////////////////////////////////2 C! a2 Z) i, F* r% E
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。$ l2 F* L7 o2 Q: I$ w
//参数: 无。
1 [; V( r$ u* T//返回值: 无。2 G+ s& n6 H! V9 l
////////////////////////////////////////////////////////////////////
" v0 j6 L$ S3 S4 F0 }9 @virtual void OnRecoFail ();
- ~. X* q" ]( t/ g+ {
4 A7 j$ B) G+ I$ s////////////////////////////////////////////////////////////////////
& e2 l3 P. D4 j2 i1 a# h8 R//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。# k7 i0 `. ^" N' _* u7 G, w5 E8 |
//参数: 无。
; ]+ F* f5 R' P4 r; A  O/ U//返回值: 无。
' w: L% R" ^, n5 n9 [$ G- ^////////////////////////////////////////////////////////////////////
# b6 V& V. S" {9 i1 `4 a; u3 evirtual void OnStreamStart ();1 P, L2 f8 _' s" t0 o

4 C/ p, b6 g; X////////////////////////////////////////////////////////////////////, J/ s5 ?" Y8 T+ @
//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。: C' v- I7 E! _/ r! c
//参数: 无。
/ A  D1 {! M3 x$ K- v# M//返回值: 无。
: V% y# \  ^3 s! U+ c8 W////////////////////////////////////////////////////////////////////
& c, ?  H/ a" x( p" q$ x1 uvirtual void OnStreamEnd ();' K6 m1 N' y  p3 n7 K7 I; K  `! l

$ {) q$ [& j  E7 Q* X: J};
( g. ~' G7 h/ h" I  R5 o% t  }! i; ~9 ^* ?

  J# H' \: L( X3 |6 a/ B7 G  H; V
+ q- E8 T  r- s5 d8 l6 O; J5 B#endif    //LANE_SPEECH_DLL_H
/ _* f' E5 Q, {8 R: @8 }
0 H1 K. e2 \* f: C8 w( g; |///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 Q5 S# s+ S! {3 _0 k; q
4 p: G( n8 Y" z& c0 D1 {////////////////////////////////////////////////////////; S% D. t! X) |" n' Y( |( I5 }
//1 g' z, E. h' j" N( b; R
// 文件:LaneSpeech.cpp
' D7 r% E& e4 d! ]7 R  T// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
# f; Q1 U6 t  [) M& P: H//    语音识别只支持命令模式,不支持连续模式- ?! e/ a% _2 v5 A1 P+ S
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
0 z; T/ ^  h! [8 q0 D( T( v% e// 日期: 2004.10
) t: y6 s2 x7 Y6 P( O  }5 c' [// 版本:1.2
& y( p$ H# A7 L) z- o9 T// * r/ h: v9 Z6 m: ]4 P# l
//
1 M% j; w- D6 u4 v) |////////////////////////////////////////////////////////
3 U+ z% Z# @2 o  M/ w4 r1 s8 B" t% B- D2 s$ A
0 p0 F3 r5 M8 h0 ^

4 h4 [3 i/ |9 z! Y1 E. U7 J" a* U$ X8 F#include "LaneSpeech.h"
8 [- ~( [! y8 _( U& ^. K: U
0 }8 V& C* @3 q# e8 q' U" k" b+ |//-----生成动态连接库和静态库的处理----------------/ @" E" H8 c: {( M% J5 h' l3 W
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
" W. @9 J8 u9 M8 K9 u0 ~( h' i' z+ l- d' u
BOOL APIENTRY DllMain( HANDLE hModule,
( I! @+ e5 x; g$ c                       DWORD ul_reason_for_call, ! r- s7 @! K$ }' h( E+ o
                       LPVOID lpReserved7 }2 Q' }% D; b) R& O; L7 M- `, x
      )# L( I. ^0 k- \" ~. x% r
{0 v. H3 e( h& y  e: J" a8 d1 X
    switch (ul_reason_for_call)
# Z& y3 o* _: X+ q: G{
; b* S) y! E7 P9 J! n   case DLL_PROCESS_ATTACH:
7 b3 B- w: Z9 }. W$ t1 Q# `, a    CoInitialize(NULL);
+ W) _  q5 _; u    break;; k6 C: h& d: n
  
; I+ f. L% E8 B) Y   case DLL_THREAD_ATTACH:3 O! N* D3 z  [6 |* w& P# V7 M2 J: {
    break;
4 k" C! o1 F+ o/ M! V8 [2 J  : C. L1 d6 e2 j2 H( C: P
   case DLL_THREAD_DETACH:
4 k$ ~2 H6 L6 |% ]( f9 f$ j    break;
  f4 I  ]4 m) }    s' J% M; U& j# }
   case DLL_PROCESS_DETACH:. b3 r" Y% M3 d6 d7 s1 U
    CoUninitialize();7 b! A( t1 h: K2 c7 K- s' m
    break;* _2 [7 r' h; Y% [/ s
    }, I" u3 _( U4 P2 Q  S4 M# P
    return TRUE;
5 _# E7 _' M" K) C  Y# z5 [% u% y}
! @; s0 {7 b8 ^) Y2 K* y' o& d* }5 F
  ]- `  y7 d, h2 g#endif //USE_SPEECH_DLL% |6 z' ^: d- n4 F
  L& c5 ~; t7 K8 z) @, @
4 a- \6 L+ K- I: e

5 c% M& Q4 @, o* w///////////////////////////////////////////////////////////////
0 s$ x  r) g( G+ p+ G  e; S  F! l9 u  g, p
////////////////////////////////////////////////////////////////////0 c8 O3 A0 i& S% y$ s. ^; Q3 Z4 U$ x
//功能: 弹出一个信息框。/ q5 i7 p1 Q1 L( X$ K! [8 T7 _; }* R
//参数: lpText:是对话框信息。lpCaption:对话框标题。% m& J/ r, @7 g; W2 d# F) y
//返回值: 无。$ T2 p! j( a6 k* a! i
////////////////////////////////////////////////////////////////////
2 T8 }: }  M" f, g6 oinline void ShowError ( const LPCTSTR lpText = "ERROR",9 V. p; q- Z/ e& d* x
        const LPCTSTR lpCaption = "ERROR" )3 {3 s: J. ?9 A# M
{9 _/ B% Y2 y' }" t' p* v+ T. K
   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
7 @3 y# d- Y' t" c' j8 ]- b. Z+ E7 w}
( ?+ n, z' R( R; {6 t. B1 f7 T% Y( _9 t/ {5 s
////////////////////////////////////////////////////////////////////. T  N5 k, G% P/ P6 m6 K
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
" a8 w, M8 {* x2 ?6 x* A$ C% W( `9 x//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。; t3 \: E4 t# o. v+ ^
//    lpCaption:对话框标题。
* l& [- l: d) X/ i: c2 s//返回值: 有错则为FALSE,没错则返回TRUE。
" i/ e, h. h" F8 c////////////////////////////////////////////////////////////////////4 r; f  H% |) }) w, f' \/ l4 a
inline BOOL CheckHr ( const HRESULT &hr,
% y- Y7 V: U4 b5 I3 \        const LPCTSTR lpText = "ERROR",  ~8 F$ Z. v& h) p* i9 Q  \, A
        const LPCTSTR   lpCaption = "ERROR" )
+ }. J& N/ N/ e/ z8 s{
/ ]+ M  g! {  E- Y   if ( FAILED( hr ) ) {+ J/ M: [- ^5 }4 v4 U% P
    ShowError ( lpText, lpCaption );
) L+ r! u$ W4 G, |# _/ M' S3 K    return FALSE;
( @' v; p' h1 \   }& O- G9 g+ i6 y9 S8 S4 ?  a" s
   return TRUE;
. D' q' p: C( Y% T}$ E) [) O: n4 e
3 j) g7 m, g. `3 V3 l+ k2 L
4 z) z7 p+ T( o  F" W) J5 I
///////////////////////////////////////////////////////////////////////" Y- Z' l/ T& e9 s1 |9 v2 P
///////////////////////////////////////////////////////////////////////3 G7 G1 A* x6 c% Q. I! `1 k
//1 m% U0 g0 y9 Q& x! ^
//         CTTS
( V! e. {% p3 `/ S//
. x' A- y, G9 z0 l6 M; r$ R///////////////////////////////////////////////////////////////////////
/ u1 `. d( g! c+ ]$ Y2 P///////////////////////////////////////////////////////////////////////
1 p% J3 q7 Q3 f3 K3 L6 Z* t
. v3 }, m4 |, J/ |////////////////////////////////////////////////////////////////////
) o8 F: f- H! S6 l" J//保存关联窗口句柄。初始化COM。: H" N1 u  y9 x3 W$ `
////////////////////////////////////////////////////////////////////6 }! a1 _1 n' F6 V; P4 M+ d% L4 p3 B
CTTS::CTTS ( const HWND hWnd )
  \: Y# U& ]) z  G# j7 R8 e% D- g3 r{- Y3 l6 X9 I/ e" e
m_hWnd    = hWnd;
1 ?8 U* {9 ?2 \3 _& W0 am_pVoice   = NULL;
6 g7 j% c) F- ~1 hm_pToken   = NULL;
7 r: X2 |* \% R+ j( p5 {4 om_pOutputStream = NULL;
! q9 M; u! D- j9 m" _. k9 p3 O9 Um_pAudio   = NULL;
: U# U, S6 b0 n  w5 \/ c9 u}+ ~' x* @! N6 n* A: i7 S' ^

* P% Q' M% _( Y2 |; a5 E% Y////////////////////////////////////////////////////////////////////2 d+ y% }2 c* T$ [2 _2 v! K2 L
//释放所有对象。
1 c8 [4 ?2 f( v  l; h3 [! i+ ?3 H////////////////////////////////////////////////////////////////////; T; j8 D/ t! ]% ]7 A
CTTS::~CTTS ()- {+ H6 e. Y) K2 B% p
{& v$ b2 p- l7 |: p9 w7 b
if( m_pToken) {  Z% @% c. C9 k0 M+ s! R- o# A( I1 ~9 V
   m_pToken.Release();2 B$ {! K: I6 {5 {3 f$ b
   m_pToken = NULL;/ G9 s- D; M: p: O1 {1 d* i0 E
}
: R' P. k' F. u& I, Mif( m_pAudio ) {
9 H; y: C' S0 X+ _; B# w( `7 y8 O   m_pAudio.Release();& Y1 R' l  {6 n" ?$ H
   m_pAudio = NULL;
9 j: [, V& ~  N( I- ]}) b( E7 v7 F# i1 J
if ( m_pOutputStream ) {$ b) m" r8 m8 e; W& t# ]. a; K
   m_pOutputStream.Release();* D' J) p5 S' l
   m_pOutputStream = NULL;
  m: H4 ^, o  f}
- i  u. Y, U: Gif( m_pVoice ) {8 \" Q! |; s7 G3 b1 J
   m_pVoice.Release();5 i: f: d' A% e( e$ x
   m_pVoice = NULL;, `% z4 I) R/ T  \0 k# ]" j
}" r# Q/ H1 M5 y3 ], @5 Z
}
( ]* P  N3 N- n
+ q$ x/ @% Y! _8 M( P, a////////////////////////////////////////////////////////////////////
) s$ N8 {: i1 ^//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。
2 t- |1 B8 q# M4 g- {////////////////////////////////////////////////////////////////////3 h$ n' a. {6 z
HRESULT CTTS::Create( const CSR * pSR,
" H# ~) M1 x  E4 f3 M3 _1 x4 K       const DWORD dwLanguage )/ N6 i% H9 ~" L+ P1 k
{; U3 j6 I, |" V
HRESULT hr;' z: J" M$ M3 l. H+ G+ m. Z' Y
hr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
& L. Z9 X1 P$ ~- X+ v; b7 Vif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {# V2 `6 D4 V- _+ Y
   return hr;7 B# R% o# ?9 _* }/ u
}! M9 s9 Q$ ?$ w6 J
, u: s# l# U1 C3 k& ^
SetLanguage ( dwLanguage );
" s- e+ V) b  R. y. Q5 x0 [" l9 `% K7 L$ x3 q/ F+ Y% ?
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流  Q. C- S* s& P! B
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
$ X% @0 z4 h$ a$ ]! d    return hr;2 F1 A% J2 Y( s
}4 _3 _) O6 c. P

9 Q* y; }# |" C- ]' i) [3 U% m//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM5 X% ?. C" T6 [% D7 H" e5 @+ X
//SPEI_END_INPUT_STREAM 表示完成流输出。
- ^! [# e/ @3 `# N7 ~hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
4 \3 e6 e9 O6 ^) T, P* F: ?         SPFEI( SPEI_END_INPUT_STREAM ),/ X& p& `0 S( W* c$ E
            SPFEI( SPEI_START_INPUT_STREAM ) |
$ T) ~( j& m& S6 _" y4 Z( V  H            SPFEI( SPEI_END_INPUT_STREAM ) );( z0 S+ r9 ^% k' T) `- j1 ~
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
8 h. i/ `, J1 K' ~    return hr;( A& W) y( X. M; e! M6 w0 z) c1 [
}
9 f: _8 P) I" u) Y, y# a* q; ~: C( \7 S; @! G. y# Y# b5 D$ w
//设置通知消息1 ?! O6 D; K, o. S4 y9 Y; _) M& ]# V
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
% I& o4 F7 A1 dif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
3 g3 ]+ D# S6 f. Q3 N+ q6 Y    return hr;8 J, {  C) B; B' g4 F/ ~
}6 [- q0 y( y( M' G

- T* b9 Y3 f' I7 N+ K: [3 Freturn hr;
1 W$ n4 J( \6 L  U$ m6 h) M}2 b" A3 Y7 t8 L7 n3 L5 E1 }

: J3 V& f& x# L9 G4 t////////////////////////////////////////////////////////////////////; {$ l% M) l( [' q2 q+ a! ?
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
; w- C- ~( ^" @7 O//并设置兴趣,设置通知事件。
, T- H6 B) u7 p3 B$ _! Z; |9 K% {0 ~////////////////////////////////////////////////////////////////////) W, y) D9 i" T% {) A
HRESULT CTTS::Create( const DWORD dwLanguage )- f/ A" V4 N$ U4 Z/ s
{
' d* E: N, v: `4 ?8 F1 d8 |HRESULT hr;4 W' p# k! V- H0 A; Q; G/ j
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );8 w1 `% i2 z7 i) {. O, {
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {
4 u: p/ `6 B0 F$ q0 E* a   return hr;# P; c- z- {$ j# R' t+ J/ l2 g( c
}
2 _* w+ {* Y2 ]# k
1 p5 G% @! f! ~! X1 @, Q0 RSetLanguage ( dwLanguage );; U7 W# c" Y3 a# a: [1 J
% a- P1 ?) D6 x: N8 I
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
/ b7 i. a/ n$ N% u: v% Qif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {7 X- Y- X! x8 _3 ~, A; @2 X+ j
    return hr;7 g( N" Y& D! l4 j9 i- d0 J, w
}
# D% z  c" E9 M$ e( j/ y; S* y3 E
( a* i9 e" R1 y9 _% P//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
& b4 N" H& m+ a' `0 j# e$ @2 ]9 V//SPEI_END_INPUT_STREAM 表示完成流输出。( L" p- r! s8 z7 c, I+ ]% X, U- g7 A
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
/ I! }: [! Y# `7 F  H         SPFEI( SPEI_END_INPUT_STREAM ),
  |$ g3 R2 k' Q; P* p+ z, l            SPFEI( SPEI_START_INPUT_STREAM ) |; x; \* }' b' B
            SPFEI( SPEI_END_INPUT_STREAM ) );
/ m5 O4 P0 u' ~4 bif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
6 p3 X9 Q. Y/ e3 i/ E8 j2 }' W: }    return hr;4 X! M: ~, q6 @( U
}
0 A9 R) {. q+ S3 o% Y
: e& o# t" W- y//设置通知消息5 y9 B1 i7 a& ^4 {! W
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
  U# s0 [9 c) {5 }- {3 Eif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
8 ^6 i) ^* p: z% u7 s8 I; K    return hr;
; m* q0 w7 g5 C6 M2 L}4 N+ j2 n4 L$ U3 S
" y4 P" n2 j- w; b' m+ c5 D
return hr;4 L* p2 U5 Z+ ]' P; P" y
}( C1 A6 L- D- r; @: z9 `* B: K) g' n
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件
1 q1 g8 Q! y3 K8 A#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
5 o  s& S$ M/ \{
' x  j  Q' W  ?7 Q. _    ::CoInitialize(NULL);//初始化语音环境! }/ d3 c' `  N) ^0 c- j: Q
    ISpVoice * pSpVoice = NULL;//初始化语音变量) e' o& e" v% P0 r" G/ _6 H
    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
7 W$ z0 r. Y  m+ _/ G, f  ^+ \        cout << "Failed to create instance of ISpVoice!" << endl;
( G. W9 O7 v: P8 J: b        return -1;
' n' Y: F. F$ N2 i' Q+ f9 R    }

7 ]7 A6 Z( P) B6 ]2 @# N    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
# ]$ _2 L) C7 X) [6 ~% w/ N4 M& Y    ::CoUninitialize();//释放语音环境

* j* U# U" e4 w: l3 \" l    return 0;
; o  M: b" i3 ^2 b' H2 ?; A' G}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序0 ?4 W) X. f" T3 z, l* [6 u' C. X% D

0 J/ B; p) h$ b+ U1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地0 c7 V/ a9 ?  J
! {. d/ l7 D, N5 ]2 U
http://download.microsoft.com/do ... -US/speechsdk51.exe   
2 h) }5 b8 Y- C9 v* c- _1 e4 g% pSpeech SDK 5.1安装包 (68   MB)     % y. Q; e* s" B. X: @4 `/ F
http://download.microsoft.com/do ... chsdk51LangPack.exe      
9 T" {0 @5 k- Y4 A( v% Z& [中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
2 i, ?3 X( `  `/ ?3 H& Y
& L+ C' g) P+ V" t+ l9 D, [) |2.下载后,执行安装: g0 ^- P  n7 l( o  O5 M
# w7 `6 V, C/ N7 W
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
5 H. R+ _( p: ^: \( S' p9 R  r( \7 O9 W7 O: o6 f
3.VC的环境配置; q) ?$ B% r. s1 y

" |  k- A- j% r- Z/ ~7 `3 f在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
) Y8 R7 ^2 Z2 W2 z5 a2 u! R4 J
& q: A8 R- L% P4 o1 @工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
3 [2 Q1 y5 B8 o3 H8 e5 z/ k6 r5 V# S+ ^
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
/ X( z, s( S: l( @: y
回复

使用道具 举报

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

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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