找回密码
 注册
查看: 5668|回复: 2

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
; S$ z7 ]5 N  P& r//1,生成动态连接库时,要#define USE_SPEECH_DLL,
1 H2 {! `3 `3 h! ~5 ~- S//      并且#define LANE_SPEECH_EXPORTS
* }) i7 ^* b) |" c3 i; V//2,使用动态连接库时,要#define USE_SPEECH_DLL
9 D! @8 E8 o9 K: H9 ?$ n- a//3,声称和使用静态连接库时,什么都不需要
# }" r, n4 M. P% B" T3 ?4 V//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),6 p- @2 |; k! D! n2 d
//      动态连接库就不用调用了。
+ ]% M" k' v! i& P( G////////////////////////////////////////////////////////
, i! p1 U+ t+ L4 G#ifndef LANE_SPEECH_H. N. n4 |, M. `9 N7 d
#define LANE_SPEECH_H
$ M' w) M2 @7 X( \* a2 Y  u: C2 `# n4 Y& J. t0 D$ M* ~
#include <windows.h>8 G2 F$ C( t- e" g6 Q. A4 p
#define _ATL_APARTMENT_THREADED
6 l/ ^, t# |+ x. x- W! I% e#include <atlbase.h>2 F$ e: W9 C0 G4 e
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
% r' u% r" z; u3 |#include <atlcom.h>
: Y" E/ k1 O/ Q#include <sphelper.h>   //sapi需要的头文件6 i& o9 x. j. L) d

; _/ \9 P3 M+ r" J: r//-----生成动态连接库和静态库的处理----------------! ^0 R$ I8 k" L: }: v
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类! ]% S/ _# T& r2 u4 c& n
, M4 A% _( t  [0 {7 m6 q/ ^" l0 M- O
#ifdef LANE_SPEECH_EXPORTS
& v/ Z( X, {# U* ^$ J   #define LANE_SPEECH_DLL __declspec(dllexport)- p; A9 w" V- T. V7 X* A) U% j
#else' x$ H3 c- P9 f, f) X- {
   #define LANE_SPEECH_DLL __declspec(dllimport)
* G: w* k$ I( U* z2 n#endif0 R* a3 _# L3 D/ s0 ~
8 @: E( Z0 N; `5 i
//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关( d8 \+ W; T0 O* c  L3 X
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
' N# z+ d7 r# i% U#pragma warning( disable : 4251 )4 i6 G+ L$ r' |6 a5 a4 ]! {  @

. w  p+ g; ?: U. U& H#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)
6 M( A. C/ @& H7 t6 @& v+ k#define LANE_SPEECH_DLL$ R: h. w$ C# i8 [8 X( K+ L4 ^8 S

, l% `7 E1 {# w& l' @! D/ M#endif //USE_SPEECH_DLL: H% \% R9 j3 O! l9 X6 A& ~- Q

/ x0 ^  h1 |+ |) s8 c  t* G
8 i4 e- N! {7 v6 h2 @//***************************常量***********************- L! R0 y# h- _7 E& O4 S- A7 H* D  d

3 [$ v' X! O' F9 U- }! \% A, Y/////////公共常量-----------------
' H! O! I9 n; _0 @5 }" @const DWORD   SP_CHINESE = 0x0000; //简体中文.0 x& d7 w* ^! ], T* y  s
const DWORD   SP_ENGLISH = 0x0001; //英语.
4 U/ c4 f# c) @
* y, L9 M2 {* w! p/////////CTTS常量-----------------
6 j# z+ t- @! {% ], Sconst UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。) O: n9 e9 q0 c9 x) q: M+ Z

! j# C* a1 W( F  O! j# r' ~9 S/////////SR常量-------------------  E* _2 Z; o9 {- Q
const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。* N  i; P% [/ ]: }! J+ q
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
. Q* l6 d. y' Y; s8 R( yconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.
( J6 a$ }4 _) `# z2 [& N! U9 L7 a; t0 `% i
//以下常量仅作例子用。
- l6 _. w6 B& H6 ~3 }#define VID_TopLevelRule 9000   //顶级规则ID. P+ N9 i- O% n
#define VID_SubLevelRule1 9001   //子规则ID! R. p# p5 o6 F' O; L
#define VID_SubLevelRule2 9002   //子规则ID
* \4 I# V! ^6 T# V6 V- I#define VID_SubLevelRule3 9003   //子规则ID
5 m2 [, b, L4 O: b8 w9 b( V8 t/ w, u: l% @

. d" V5 {. ], z//*************************类声明************************
: f: w4 [7 S8 d$ y7 q+ s3 ^4 S4 i3 r2 P3 o/ N% G
6 j$ ^0 f7 @; g& _: B2 S
class CSR;
7 J, y  p  O! @/ n; p, Q4 e///////////////////////////////////////////////////////////////////////5 r3 I( }. o& P$ N9 ^, t) i, a
///////////////////////////////////////////////////////////////////////( ?% [; o  M* p( i
//
0 B7 `4 E' y7 x8 X//         CTTS2 c: m3 c! |, }* J9 e3 r9 h# {( O+ M
//: }$ i7 G  b1 M& _' P9 W
///////////////////////////////////////////////////////////////////////
  N" A0 R( o4 p+ Y. L, k" S+ h///////////////////////////////////////////////////////////////////////+ r- t8 a$ Y% F% Y8 K' s  [
6 {" N1 b: H0 S4 @( n7 R
class LANE_SPEECH_DLL   CTTS
' w' y( O4 [/ `" v8 e  Z2 f4 d) q+ {{1 P. C% _1 S3 _7 z) j3 W# z* ?
protected:" ?, V  m9 f( z9 L5 m
HWND       m_hWnd;     // 关联的窗口句柄。  t. C+ [3 T7 U4 G. H+ j: g
7 w; o" e5 R8 B# B) n0 V
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。
* F. X1 {4 S; ~: e0 ?4 q4 Z" wCComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
% D( T# V2 w) GCComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)6 c7 {# @1 F; P
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
6 j2 A! N: t' D4 f( l2 L9 o  c8 i' @7 l' }* P
public:. y' W( P6 k: [2 G) ]0 ?
//********************************初始化部分********************9 G7 k5 c6 w( x
; N, o4 ^0 T. J7 d& Z' s
////////////////////////////////////////////////////////////////////- o9 ^5 t( J3 T$ ^
//功能: 保存与识别引擎关联的窗口句柄。
6 E1 a7 G* |1 ?/ `% P//参数: hWnd:要关联的窗口句柄。7 M4 g6 a) `) s3 k5 R; x0 b" U
//返回值: 无。
+ ]0 p0 J( t7 A8 ~1 H5 B- _5 @////////////////////////////////////////////////////////////////////
0 S% \& F1 P/ o, ICTTS ( const HWND hWnd );9 I- b9 p% R0 }! X" k( [
4 N. j. m$ M0 x, e( y! o/ N
////////////////////////////////////////////////////////////////////, X- K) `' p" E" f7 }; ~
//功能: 释放所有的对象。
6 J8 `: I5 g3 Z& n- l//参数: 无。$ k# Y0 a2 p# j0 Q
//返回值: 无。
) u: K+ @5 F/ \# ~) e, K: s' l////////////////////////////////////////////////////////////////////
# H  H3 l" {2 H5 v- Y~CTTS ();/ A! y) P1 V5 R! p

3 n$ F4 Q3 h: M5 z3 o: q////////////////////////////////////////////////////////////////////) w$ F' i+ X8 i7 R; h5 G2 `
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。
# Q2 Z+ m6 q% M. p( }2 z8 g//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,: T5 B% F/ \, o, }2 V& K& E  w
//    SP_ENGLISH为英文。
! P# _& k0 P. Y0 ?7 v$ p//返回值: HRESULT类型。
$ ^3 V, [! m- Q( T2 v////////////////////////////////////////////////////////////////////
. t9 L0 ?) s( ^6 V0 m3 m3 u$ wHRESULT Create( const DWORD dwLanguage = SP_CHINESE );
# h( m8 \& e1 y. z% y" y2 {! N, g0 ]$ F0 L% R# }, g$ I0 [1 V
////////////////////////////////////////////////////////////////////2 B/ ?  i$ b7 S- M- D" f
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
* Q- y. B0 ^9 @/ {//    通知事件。
/ r5 C% S2 r6 q8 I//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,/ a: Y  g5 K- `8 e
//    SP_CHINESE为中文,SP_ENGLISH为英文。
# V) g9 }/ a! S- F2 ^2 h//返回值: HRESULT类型。9 i, i3 L" g' S( t, B' @$ W
////////////////////////////////////////////////////////////////////
( j2 N. y* Z" z& fHRESULT Create ( const CSR * pSR,
0 Z" @1 A3 P, j2 c4 T2 K       const DWORD dwLanguage = SP_CHINESE );6 L7 w* j% `) ^+ @" O- U

) u5 t9 H% \6 g% a5 q; U8 i/ y) p4 M( _' i5 U5 z: y+ A
//********************************设置部分***************************************
- @5 q4 E1 E+ G/ l# L7 C+ K+ E% a. A0 e% h- W8 X+ k
////////////////////////////////////////////////////////////////////8 U+ j$ t% y; G7 t# i
//功能: 设置朗读声音的语言种类。) g; B6 S- `2 @9 a  G! Z
//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
/ V$ S" W/ b. a: C//返回值: HRESULT类型。
4 X' b! g, p7 ^6 }" L0 l2 v- i////////////////////////////////////////////////////////////////////
7 j( L; Y2 Y+ s* D; Y1 yHRESULT SetLanguage ( const DWORD dwLanguage );
- T) t; e, z# U2 F( e* \6 A! j+ I- j) ]' M
////////////////////////////////////////////////////////////////////8 v6 K. r% v- ^1 z" e0 P4 n, `8 q
//功能: 设置要处理的的事件。
4 u, p* T) R8 L  n1 x- ?//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
, k; f) y: g% p7 x, n! d//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事: a+ ]$ @. d+ T& K1 J, ?. G
//    件都会收到通知。5 K3 e( B" e3 P: T# `
//返回值: HRESULT。  |4 @7 [& i* w+ v; _
////////////////////////////////////////////////////////////////////: _; A2 t$ z4 C! [% C3 G- A" D
HRESULT SetInterest ( const ULONGLONG   ullInterest );
' o# z$ v& `, e* f, F$ u
3 R! V" ~/ G$ t7 I6 t$ y- {////////////////////////////////////////////////////////////////////5 k4 U  Y  J( F! W5 H% L
//功能: 设置朗读声音的音量。) }$ I4 d# X2 A8 a( ]
//参数: usVolume:音量数值应该从0到100
7 i5 L* Z( O* u+ ?9 v8 `1 t//返回值: 无。
! K: H5 |# K$ Z, c7 x- f. f////////////////////////////////////////////////////////////////////% v8 l0 g  A% z5 r1 Z2 h( v0 c. F5 g
void SetVolume ( USHORT usVolume );
, V, i; W4 S$ d8 t( q% M
8 d! t+ Y+ P" b/ L( _////////////////////////////////////////////////////////////////////
) g  U1 K' L6 `4 G7 H0 j//功能: 得到朗读声音的音量。
; v5 l9 H- m' M9 I4 j6 S//参数: 无。
3 J1 m; s, w! i' R# L//返回值: 音量数值,应该从0到100。
1 y0 {, ], G) S. [/ `$ v+ a////////////////////////////////////////////////////////////////////
8 H7 Z/ K# X# YUSHORT GetVolume ( );8 C# x: F0 {2 ]  D; y$ X& e6 U  _  R! X

) f; U* `: i; d: }% g. g) \////////////////////////////////////////////////////////////////////; Z$ O3 a) Z( L% @2 [
//功能: 设置朗读声音的音速。; J# n. n6 j; h* [3 g. o
//参数: RateAdjust:音速,参数范围从-10到10。7 S9 i5 x. q3 z# M7 ^
//返回值: 无。  A2 u9 }: I+ L, P& H7 H$ }
////////////////////////////////////////////////////////////////////
/ ~5 D7 X( _4 p. \void SetRate ( LONG RateAdjust );
8 s& f; x/ d) R7 {+ w* ?
3 M: W# s( }0 u( a////////////////////////////////////////////////////////////////////6 m% _- i% u" P3 z6 D
//功能: 得到朗读声音的音速。  }5 T) ~: d0 p
//参数: 无。% n! Z  v8 w5 Z1 r$ I% A1 A, ~0 o
//返回值: 音速,参数范围从-10到10。
5 H) \" Y4 j* Z$ g6 O////////////////////////////////////////////////////////////////////
! s( u: i  C1 Q8 Q; ~- E" cLONG GetRate ( );: e3 ]7 B* Z) `% `; g# P; \1 l+ n
/ b* `8 q* o6 A, Y
////////////////////////////////////////////////////////////////////
2 k/ p  B, C5 Z$ I7 ^( R# w//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。# W: j( G# f# l, a
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
( E$ a# [& I& z$ {' p, M4 F//返回值: HRESULT。
8 h, y2 X& Z" i" O6 Q3 I////////////////////////////////////////////////////////////////////+ a" X& W2 m% E$ G$ Z
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");( J. x7 y' A( V4 I& l! C

: {; f6 A# X. O, r" W8 J: I! T, R////////////////////////////////////////////////////////////////////
- G& L. J  _1 H# {//功能: 设置朗读的声音从音箱输出。8 O8 m) c; k5 e
//参数: 无。; r1 ~/ E6 [" K, n' v
//返回值: HRESULT。
3 g1 v9 q2 Q$ A% g  Q////////////////////////////////////////////////////////////////////
" {% E, Z. z5 d$ A, xHRESULT UnSetOutputWithWav ();4 q  u+ [* N7 {( F5 K' ~

# T) J  u- U& T- K
6 _& b( |/ R! y//**********************播放语音,文本到语音转换部分*****************************
& t# \) @; o4 h) m7 J; B6 x
& J3 ~5 H  M. d: e5 E7 L/ Q  Z$ n////////////////////////////////////////////////////////////////////2 S/ F- E! p1 \7 f
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
2 H5 N' i' Z8 Y* {/ F//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
# `, J, n& b4 b& D9 K3 C//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,0 D9 l5 O6 r4 L6 ^: X# P. @
//    SVSFIsXML为朗读带xml标记的文本。* f! X3 Q( B; T1 r  ?
//返回值: HRESULT。
, c6 A2 |' g8 B3 L& X, H, C. d9 ?////////////////////////////////////////////////////////////////////
4 k' p/ ~/ Z0 C7 s8 A6 W4 B5 \HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
  D+ L# e$ x" `) z) |+ R0 X8 E8 G3 {& N4 x$ W3 F
////////////////////////////////////////////////////////////////////, R8 v: G) v5 V3 h! D  \+ |: L) ~
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
, a! ?; k# Q1 w4 G, E5 f! e//参数: 无。
( ]) l) i9 d7 c0 r) i) V4 E# S//返回值: 无。
) n9 K' j7 w: k% E: ~8 @0 j# y: }4 y////////////////////////////////////////////////////////////////////
- M" [1 m( n; ?: h( w" W7 n! Rvoid Stop ( );8 t+ o) C2 T$ q$ k0 a& D8 l# J' E1 ?0 }
  @$ e; j/ k% V6 W! z  |1 ~" N1 U
////////////////////////////////////////////////////////////////////& y# w- i& v, C6 n) A9 |7 z/ H
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。8 t! ]/ z" k2 t
//参数: 无。
( F; k' n. A' E! |* ]. |- O6 ~$ [; X//返回值: 无。
4 z" q0 \7 u: @! G////////////////////////////////////////////////////////////////////6 {; N5 o! y6 |/ w
void Pause ();
) M7 {2 }5 A: P- }' ]# R4 \2 h5 h# X! V" e0 b
////////////////////////////////////////////////////////////////////5 j4 F. E( o7 I
//功能: 从暂停的地方继续朗读。
* y* }3 S; e8 k' R  B  S//参数: 无。
# z, V" Q, X9 t: [, o  v//返回值: 无。; Q9 h2 u7 g$ L/ s# _% V
////////////////////////////////////////////////////////////////////
8 Z0 T# H8 _$ H7 H0 d( D8 d' B  qvoid Resume ();, |- F/ W/ [$ ~' r
! d4 _1 w1 H8 Y1 u

* [. p) ?4 o% p) I& D//********************************处理事件部分***********************************
0 @1 L3 x. O+ a. K
# Q9 S, i* i/ Y/ s! Qpublic:, U6 {$ T* R* K
////////////////////////////////////////////////////////////////////
$ V0 S) ?2 e' E; j//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。) [" ?0 P7 ^" @0 h
//参数: 无。
% K" u8 F4 U2 p3 r% y% A  P5 C+ J//返回值: 无。4 y+ Y& y. r0 W) b+ f+ `; Z2 j
////////////////////////////////////////////////////////////////////
' V: L1 K# `; u! S5 Xvoid ProcessTTSEvent ();: I# m  h0 N, V# ~* y+ Z

* m. z% O( ]2 V; B/ p* a0 C. Z4 i9 y+ u0 Z  [' h) a( h6 K- v
////////////////////////////////////////////////////////////////////
4 q' x+ ]7 c3 G//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
- B( v- y! I- Q/ v- i//参数: 无。8 V& {& \1 N, `2 o
//返回值: 无。
, S- E: w. {# d" |////////////////////////////////////////////////////////////////////: w& l5 [4 |& e3 p$ R: \6 A
virtual void OnStreamStart ();
' r. K  z, a- |; I5 ~+ n" u2 t+ I# ]- J4 ^
////////////////////////////////////////////////////////////////////
; r# E5 w& ~7 a7 y//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
1 {  Y' @. H6 @9 n//参数: 无。
4 d4 Q0 o0 B4 N9 }6 F, z- F//返回值: 无。; k! Q  Y$ }  k6 ^0 _
////////////////////////////////////////////////////////////////////& S: Y* A& v9 m. n$ j
virtual void OnStreamEnd ();
7 z2 o  {6 l% f9 Y/ Q3 j: e};
- L7 v; u) n- G
8 p( k- b) w4 E' W: H
8 z0 w3 R& A6 y6 d///////////////////////////////////////////////////////////////////////
9 e4 G1 G/ t- x) c5 H& h///////////////////////////////////////////////////////////////////////
$ y- y! e. n' P/ B2 C/ f//         CSR
2 m, w+ _0 k0 A' o. m* u& ^  M//
" K  ^9 k9 h& Y/ n2 h4 e" X///////////////////////////////////////////////////////////////////////7 I, B% h- c: p7 y
///////////////////////////////////////////////////////////////////////
  r& t+ o' a  `% Z& L# d9 k/ \
5 \. o. n& a* D' B3 x7 iclass LANE_SPEECH_DLL   CSR
4 M% T% u$ j. ^/ H* T0 I, \% u{+ h' d- ^) N: }5 f
2 F* T: j! D  T1 C
protected:
5 O7 J* g; K" @3 bHWND m_hWnd;* B5 f8 X" h3 ]* q' N& @" u

7 |( H* _5 I6 A* Spublic:5 @4 `4 m& D. T& R. @* a2 A
CComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
6 X) ^( j  i: C4 V+ SCComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
9 _% d' c9 M# l( PCComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。& Q' X' R5 A! ^+ c
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。6 r6 `* i2 u1 ~  t& K7 F; S
CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。$ ]& B; A, B5 k" G1 A
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)7 g  a6 f, i/ n) q9 I+ H' D
public:$ p) v2 J- U, Z8 g! V% S3 g# n
static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
! M+ e, M9 R# P8 U  K; }8 c" H9 A
8 z0 e* ^, Z9 u3 t  F
protected:
7 k& v" J; G! X6 A  H! Z2 Y//***************************辅助功能部分****************************************7 u! `+ X1 ?0 s( l& o1 F4 B

7 @% [" s  ~) q  N& r% J1 }* ~  ^////////////////////////////////////////////////////////////////////" m. i, {# F: Q% j* y. k& K
//GrammarID加一,每个GrammerID必须不同。
7 u0 K4 G3 A) R8 `# Z////////////////////////////////////////////////////////////////////
) Y2 c1 c, R. I) @static void UpdateGrammerID ( );
4 s7 S2 }8 A1 Q0 r# i% X- z' `
2 ?) E) T/ g  t6 |) v2 j& Y6 N. m; X) o' ^& b( [) o( l
public:
5 c' T2 T& ~; o4 t- [" @; T////////////////////////////////////////////////////////////////////  E2 f4 c) {  m% j. r$ T
//功能: 友员。TTS中的从SR引擎中建立voice对象。
( {( Q& T* |6 @  Q( S1 M//参数: pSRContext:SR上下文对象的指针。
7 J' ?: z/ q$ n4 @2 Y//返回值: HRESULT类型。5 Q0 w/ N. s$ v* j& i
////////////////////////////////////////////////////////////////////
: ?& i* G& ~8 s* l( L+ E4 o7 }. }friend HRESULT CTTS::Create ( const CSR * pSR,; W( m0 ^* P  d: d0 A" N) i. o( L& ^2 S& f" z
          const DWORD dwLanguage );! q/ F5 {4 J% i' i

8 R% O2 X% |  j# u% A4 j, M& l5 U8 ]' `8 M# r/ l- G1 J
//****************************初始化部分*****************************************
( S/ b# `6 [8 Z+ N/ S3 J# D3 F  x1 v, q2 X/ R7 |8 X
////////////////////////////////////////////////////////////////////! f+ E9 A' B/ c4 e# P& F1 V
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。- n2 Y* U& g4 C6 L+ d( y6 c' [
//参数: hWnd:要关联的窗口句柄。
) A# V. [& W3 w0 Q//返回值: 无。
  Z/ |, k  u1 L////////////////////////////////////////////////////////////////////" |& u4 ?2 F$ {. l- [
CSR ( HWND hWnd );! A8 G+ l7 j& {$ d& R$ n/ q" P+ [# H
! c: B1 E& r' b7 Y3 D2 g' a. e
////////////////////////////////////////////////////////////////////5 S/ c9 m3 x" {7 Z
//功能: 释放所有的对象。
* ~' J- [; a1 T//参数: 无。! A# N! ^5 Z" ~' e
//返回值: 无。
) U- v# c4 v" w0 m0 H7 I////////////////////////////////////////////////////////////////////
: V4 M" o. {! w0 S~CSR ( );
) ?. I1 v4 v5 t9 a8 R' X  o& a8 K) A. E3 C% n3 N; a% {
////////////////////////////////////////////////////////////////////! {8 d* F# g3 O- Q  \$ C; ?! X
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,! c1 o8 \  r% H+ u8 f
//    加载文法文件。
- D$ n- {6 @: n/ F% v//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。. @& B" W0 g3 v& t" W( j) d7 ^
//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
; d: Y8 @6 F) n  t) R+ _//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。
2 y9 |; L: d- C) A9 B* K' s//返回值: HRESULT类型。! f# }# k- B/ u% j& X
////////////////////////////////////////////////////////////////////
. O7 O3 u+ {/ X' K) {' sHRESULT Create (const DWORD   SRType,7 g" t; W; p; O1 N. K4 ^4 n5 _" G
      const WCHAR   *pwcGramFileName = L"grammar.xml",) |( ~2 K% e. y  k, a" `
      const DWORD   dwLanguage = SP_CHINESE );
; V; Q  i: d# Y, F/ Z; g$ }% N$ ^, g( @
* O  }% k& j1 z$ d
//**********************************设置部分*************************************( x2 K3 ?0 q) `7 a4 j1 R, q) y' t8 t

9 Q5 H; R- p: e8 a, c////////////////////////////////////////////////////////////////////
+ f  v6 c6 c4 [//功能: 设置要处理的上下文接受的事件。
; g5 X- f8 q9 C, C2 _//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
- Z, X- \8 G5 K+ {; o//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
+ f/ G' Y" F  ?( |0 s//    件都会收到通知。1 B( `% C/ _. f' J1 L3 r" P9 x3 c2 O0 |
//返回值: HRESULT。
- j% `5 h2 ^9 Q8 L! o////////////////////////////////////////////////////////////////////
# u7 h* s- X- `# m8 Y) t9 HHRESULT SetInterest ( const ULONGLONG   ullInterest );3 M- H% z1 Z8 l4 E
+ W/ ~3 @5 `" ]2 f  o0 i
////////////////////////////////////////////////////////////////////9 m+ y) t5 d7 f7 O" t# @/ R9 n6 [
//功能: 设置某个规则的状态(激活或者取消激活)。. I& K( F5 Z: w
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,
  G" ]& z+ R6 O# n//    FALSE表示取消激活。$ U& x& N, d  w; ~+ t' b5 X
//返回值: HRESULT。" G. L# R7 x/ i9 P5 \3 T) P
////////////////////////////////////////////////////////////////////
2 X8 N% Q& r9 ?7 `HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );+ O, m5 w, ?% X. @2 b
, W, k, T. ~; ?

- n) `. t0 ?/ j4 X7 Z/ z////////////////////////////////////////////////////////////////////
6 ]8 L$ X1 i3 S1 `, l//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
! x! T( k' r9 @: [9 I//    风输入。
, k8 T! a# }' ?7 Y/ Z//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。- W+ e  r( o! i- @) D
//返回值: HRESULT。
* t7 M$ M# _* O; }////////////////////////////////////////////////////////////////////
4 k  @4 @9 v8 l3 lHRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );7 c9 Z  L; h* ^8 F

7 \' H1 z  {* P0 n////////////////////////////////////////////////////////////////////0 R. y9 }# g) G
//功能: 取消从.wav文件识别。恢复从麦克风识别。2 A: `; ^+ g& c/ w! d4 Q
//参数: 无。
. S2 f; Q! h/ H" e, @; e//返回值: HRESULT。0 Z$ c! y4 V$ H/ i
////////////////////////////////////////////////////////////////////  c% M3 E: ~. u9 q9 r
HRESULT UnSetInputWithWav ( );) j' Q9 u; R3 G& i6 B
" f* S/ D- T/ M7 L+ r5 M
//***********************识别开始,结束,识别结果的处理**************************
" w6 u; p! W, M4 {2 D9 c
2 ?/ q$ }0 |/ f) l/ _7 I4 R/ s" [////////////////////////////////////////////////////////////////////
, U& B, |0 g1 `$ ]//功能: 识别开始(将所有规则激活)。6 b8 r' j$ K2 Y1 \
//参数: 无
5 C, w% V9 \+ v//返回值: 无。
1 Y( ?& M" m+ U( I8 a////////////////////////////////////////////////////////////////////' H  c& H) x6 Q& ^
void StartRecognize ( );2 ^5 q9 w' |+ H' n6 j
6 W  k) ]9 y8 }. U
////////////////////////////////////////////////////////////////////+ M& ^2 [% c; U) G4 `2 }
//功能: 识别结束(将所有规则取消激活)。
* i. Q6 n( s7 ?* Y# {7 A. W//参数: 无。
+ o" z+ D+ @& }+ l//返回值: 无。
1 L% I" O4 c) s5 s; A4 {" G. W////////////////////////////////////////////////////////////////////
' ]6 ^% X5 H; Y6 e% D3 Bvoid EndRecognize ( );8 w3 M7 ~  O; ?+ W
6 i* R% m- `7 X' u6 t" s! d' R( A
public:
8 @$ d( D% a5 M5 J% f" b/ P, P////////////////////////////////////////////////////////////////////
1 B% I, v: F; K" _. J//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
9 m+ i/ p8 n0 _4 s//参数: 无。- h# b* d8 f% d
//返回值: 无。
6 V2 `7 A0 ~2 {% a- M( u4 l1 {4 z////////////////////////////////////////////////////////////////////; t1 @3 B" Q" j
void ProcessRecoEvent ( );
" S% P+ t% U8 S& b- v# r6 j; a/ C0 B4 G/ F
protected:  ]8 E5 M! k& n. Q7 R
////////////////////////////////////////////////////////////////////% @5 U" B+ ^  N6 O  X2 ^
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。
+ l0 Q4 p5 d' ^7 y( f//参数: pPhrase:ISpPhrase类型。' {  w  S- o+ {# z
//返回值: 无。
: T5 q3 W/ |  \9 q/ y9 x5 p////////////////////////////////////////////////////////////////////
. d  o$ ]) y% V  R8 `! xvoid OnRecoSuccess ( ISpPhrase *pPhrase );: a3 i( V8 |  Q: P

% F2 i$ {- b( D9 lpublic:7 ]. d9 O( L7 X# m# G" X0 o
////////////////////////////////////////////////////////////////////# ]4 A! v% M7 R& l6 F
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
" k5 C8 w: ^# v$ p5 U. f8 Y//    需要在派生类重载。规则ID必须以常量形式预先定义。, n, o% t0 J7 r
//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
% z2 [! a- E6 T/ ?0 a& @//返回值: 无。7 [8 B6 O, b( ?% \$ `: N
////////////////////////////////////////////////////////////////////2 T6 j5 I! P; u2 y  V/ T
virtual void ExecuteCommand ( const ULONG ulRuleID,% H2 K  g, k! K; q: B% X
          const ULONG ulVal );0 l6 A. F8 p8 Y+ k) k: f1 n  H
" T1 `5 F$ k. \& i. @- ]
////////////////////////////////////////////////////////////////////2 y9 w  Z& n+ r! v9 P7 m9 R+ K0 P( E
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。3 Z: B4 i; X' k8 r- R" K+ K- U
//参数: 无。/ w$ p! w3 b/ {4 \7 p7 a* p! m
//返回值: 无。/ M( u7 U4 v0 \4 Q
////////////////////////////////////////////////////////////////////
" h/ I! A6 `5 q$ Pvirtual void OnRecoFail ();5 D! \, l5 i5 E; @" |
, f% Y9 v( \: U4 X
////////////////////////////////////////////////////////////////////
& E. x4 A2 l: E8 v1 M2 l: i# m//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
: h( A5 g; |1 y" @0 z//参数: 无。2 j5 n  P: J% u
//返回值: 无。
0 L1 D$ z; J( R% Q4 a////////////////////////////////////////////////////////////////////: w0 u1 p  X* y$ a/ z. A+ q
virtual void OnStreamStart ();4 Y* @. I: d& Z4 W9 w

" L* u8 a4 P; L- ~////////////////////////////////////////////////////////////////////
; }# ?$ p% K# t3 B9 y; p9 y//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
4 z; q; _$ V2 o7 V2 g3 Y( F//参数: 无。$ r) h, K- L( o. I9 X9 N+ T: ?  H
//返回值: 无。/ ~4 P" G, B# T
////////////////////////////////////////////////////////////////////" _0 f! Q  G# W# O# \8 @# U9 b/ A
virtual void OnStreamEnd ();. H$ o& v' l& h5 z

: n8 G) t( C, k" K; M0 a% B/ G# V};9 e( V. O5 E! p- V! l6 l
7 S- W; V1 e4 N6 ]( c; X
( g, c2 D, C) x+ _& f

' H2 W1 C( m! `6 y: p5 R3 |#endif    //LANE_SPEECH_DLL_H5 B  s( G5 R0 M. a
! m. u1 q! z+ \: k) O& U
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" `" K! R" G" Z: Y: f
6 x/ }' d  |# Y  T
////////////////////////////////////////////////////////
8 J% W" n2 W/ u. P7 a//- f) O7 V/ c4 ~
// 文件:LaneSpeech.cpp- ?6 c8 ]7 b. E* N6 ]) W- g
// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
4 a9 t& B% ]/ U$ F5 J3 h3 b9 H//    语音识别只支持命令模式,不支持连续模式
% b$ W5 h3 C) \. T// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
& f% I7 }3 V* N// 日期: 2004.10
* s& x; Z% A( U2 V- G// 版本:1.28 O7 w) [7 y2 E) N2 Y; ?' i/ P
//
0 R- k! m% x( F//
! h8 V6 E  a. B7 v' u3 U////////////////////////////////////////////////////////% S" ^6 B  d9 F4 d' l

' `6 H$ P: W. m! p' m3 q$ v  `% ?4 l) [

. z) z: ~2 |4 _#include "LaneSpeech.h"
/ a! {: T6 o! l1 p
) {) f  [1 S1 f% u9 M//-----生成动态连接库和静态库的处理----------------
" `, T' K. b( u# r#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
" z% }9 |: }  m  _0 L% M' |8 B; C/ j- g0 z4 ]( i) p$ W8 D' a. [/ I& \
BOOL APIENTRY DllMain( HANDLE hModule,
* T9 t# e6 l. E" s8 [) F* p: M                       DWORD ul_reason_for_call, & Z& P4 [5 o6 ^- Z
                       LPVOID lpReserved5 K2 k( b! O. @+ v0 d; q
      ): B. |9 D  \2 J4 v) z" {0 K" j
{
0 \6 F: h- i% Z2 _0 G: k    switch (ul_reason_for_call)/ _; c2 t# U2 d  S& Q2 q; O
{/ b% ]: g  o1 J" n
   case DLL_PROCESS_ATTACH:
$ v" Q9 d4 i/ c8 T    CoInitialize(NULL);
# _# {( N( m8 h' J: P3 y    break;. _2 p8 a" y2 S. }  \
  / @% m# b7 `8 d5 b1 L$ Q6 @/ b, @4 H
   case DLL_THREAD_ATTACH:& [/ N7 B4 k! r% r7 A, A
    break;
' g+ ^2 l* V) K6 }* O: {: ]    Y5 f+ S; b2 c" c+ D6 \4 F
   case DLL_THREAD_DETACH:! I6 ^' l/ N7 M# p6 ]5 b  b" O1 A
    break;2 B2 Y& y6 \; _6 l
  
0 Z0 q2 B+ \& W! t5 S  W   case DLL_PROCESS_DETACH:
1 P1 @9 Z& c+ ?# A    CoUninitialize();' H  r* p- ~; q/ v9 z3 s# h) Z  s
    break;
* E5 k# o+ N; I& o# b* r; f& @    }
, P8 F4 z  E8 r. c7 I: [2 D  |  `    return TRUE;" f0 q) S, l9 b7 V9 |0 c
}; {& p: g; i  M  @5 L$ ?
: C9 H$ n7 r+ ^; i3 r4 e
#endif //USE_SPEECH_DLL! f$ ^8 i# j( ?7 M4 e
- N# J  e2 x! A) h2 N
' ?6 [: h9 @4 O
6 T: l8 @. n( H- J; }) l
///////////////////////////////////////////////////////////////" L/ `3 Q3 C) a& }3 {1 o! Y( r4 b
6 ]1 ?! \3 \# f, l% Z
////////////////////////////////////////////////////////////////////
# k& F, O1 g. l5 {5 _//功能: 弹出一个信息框。
1 B: K/ {7 i, ^//参数: lpText:是对话框信息。lpCaption:对话框标题。
  Y4 H6 e( A. R. ~//返回值: 无。
. x9 v; ^$ W/ v5 z' ]5 a3 w, a////////////////////////////////////////////////////////////////////
1 j* T9 [# j9 m8 J8 x% ^2 f: Hinline void ShowError ( const LPCTSTR lpText = "ERROR",
9 p& a& [3 r6 h0 p: }* \7 N        const LPCTSTR lpCaption = "ERROR" )% e% |% O  t1 J) J, s  z
{
& @4 J) p7 z) E7 y0 ]   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );* r& `) x  V7 R
}/ v4 v/ f1 R) c$ P" c5 a6 v
$ v; Y, {1 C) l; l2 L
////////////////////////////////////////////////////////////////////
  n# Q2 Q. Q3 ~1 D5 G0 U//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
! P; I( v% n# l  X1 G//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
' i& B& |+ r2 i, z. O//    lpCaption:对话框标题。  x1 I. [: E% E0 D# x* ]
//返回值: 有错则为FALSE,没错则返回TRUE。9 l% b* W, }0 U' |- m
////////////////////////////////////////////////////////////////////$ W$ s" E" K& ~0 A
inline BOOL CheckHr ( const HRESULT &hr,4 |  M, i& X; s
        const LPCTSTR lpText = "ERROR",
5 T% ^3 [2 f% Q3 c        const LPCTSTR   lpCaption = "ERROR" )
7 C3 c( x. O- @! m( j2 h{
% m' v$ j2 [& ]6 [   if ( FAILED( hr ) ) {
/ J4 D4 Y$ H. N1 I% }6 k1 _    ShowError ( lpText, lpCaption );+ k* z3 Z' ~9 m7 g+ W# _% w
    return FALSE;
4 V! ]% f5 _9 W: G4 B( e   }
9 k1 ]. }% v* k" F# k   return TRUE;6 U/ V' g, u1 D6 {: |1 h& |6 d
}
* n* V- ]2 B. K* N# {
1 c5 [$ f: p- y. a" ?8 h0 f! H
3 A& [& b8 E5 t& r$ g1 @9 [///////////////////////////////////////////////////////////////////////- J! m" S: m  p: Z# D$ c
///////////////////////////////////////////////////////////////////////
0 \& W" Q" H6 i8 `- X//, Y3 D3 Q% ^6 U& H- v/ m
//         CTTS& q) n- t$ d+ Z* k; l: c
//9 X% Z' R' P+ ~
///////////////////////////////////////////////////////////////////////; D& W9 Z6 F7 |+ M5 c
///////////////////////////////////////////////////////////////////////6 t% {  E8 ^; q9 t# X2 @

1 @: k. Z: n4 P////////////////////////////////////////////////////////////////////# `" \- M  L+ I7 ]
//保存关联窗口句柄。初始化COM。5 n1 v1 U, r/ |7 Z
////////////////////////////////////////////////////////////////////9 g& x* l# t4 g& o) U; Q
CTTS::CTTS ( const HWND hWnd )
$ D# ], c# I, b" \  O; K{
. b/ M. K' s  y3 r7 `m_hWnd    = hWnd;  y  A; J3 l( F& G, ^9 C
m_pVoice   = NULL;) c7 U8 ^/ I. p: r: l8 u) ]- D
m_pToken   = NULL;4 |- G/ Z7 ?4 ?' `: G3 c
m_pOutputStream = NULL;9 O# {) m. @, @- {
m_pAudio   = NULL;$ K0 s/ R  X$ y& o9 a3 W5 D
}
$ v0 {/ ^, O0 k
* T# ~* D" N, Y9 v////////////////////////////////////////////////////////////////////
/ P- x- C# `0 ]( i/ m" b; H3 I//释放所有对象。
0 J8 W4 T* x2 `- r////////////////////////////////////////////////////////////////////
( P7 n8 N+ d. h4 }0 tCTTS::~CTTS (). ~+ U2 S, G/ m, Y, S7 r# X
{% G- H4 `" @$ O. O0 L% e
if( m_pToken) {  x8 t$ d: E6 ?  W3 X
   m_pToken.Release();
$ c+ m( ]! `  u% v   m_pToken = NULL;7 g* V$ U; M9 z6 X) j
}& O) U8 O, ?, ?8 v* J* R
if( m_pAudio ) {
( R$ B5 |9 z1 P! m   m_pAudio.Release();: V& j" I% H- c( `; S& a
   m_pAudio = NULL;; y, b& D6 P2 F- b- W
}
& {" W  n) ?4 R; ^if ( m_pOutputStream ) {
  h7 N: a+ q# S, ?0 L7 H1 n2 y   m_pOutputStream.Release();, I+ f+ b! `- h
   m_pOutputStream = NULL;
+ J1 }9 E! I4 V0 R# V8 @}
& ~7 p2 x* N- z& B; ~0 wif( m_pVoice ) {
; a5 C- F9 o: n; j. u3 d1 G) s1 v9 [   m_pVoice.Release();
9 ^( d: \7 v/ i" y- f; H! @   m_pVoice = NULL;
% l& o' ]9 M7 o$ m8 c9 O4 N}
3 d: ]+ u7 K5 J( Z; b1 m}' o2 k3 u: ?" k2 p1 }
( x) D5 Y7 ?! Q& _5 H. t
////////////////////////////////////////////////////////////////////: t/ M7 ?' K% Y) M
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。
8 g& F" I( C) V1 i///////////////////////////////////////////////////////////////////// G+ ?8 X' o# `+ @8 d# [7 Q
HRESULT CTTS::Create( const CSR * pSR,
5 n# g- C9 S% g1 w! p       const DWORD dwLanguage )
* |6 N+ F% d! R8 ]8 z{
4 j* ?3 H0 U' R0 \" h; nHRESULT hr;) A! n+ [/ `3 R6 h# {- h
hr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
+ J0 d$ ~5 X8 ?if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
3 m5 F+ {1 ]+ r% U   return hr;
+ S0 v) z4 E0 G# |$ ^}+ z+ l- e( e7 y( K% D
2 C8 R( v, a8 L& S2 F! c/ y
SetLanguage ( dwLanguage );
4 p: X! {; p7 K6 D: }& V8 `+ Q1 J% f  V  q. t3 s
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流/ i' C1 Q% \' X" i# l  x
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {! J" D- i, Z" W+ f. [0 }
    return hr;7 O" e0 b5 H! a7 l& z4 [8 H2 N
}8 q# J9 p+ e: i4 p8 m- N; U+ Q; {
2 S% r" Z# X: X! @" ?* O2 n- ^$ L' f5 ~
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM( S3 M7 r2 N) l* ^6 ?$ F. ~
//SPEI_END_INPUT_STREAM 表示完成流输出。4 c$ [) ?/ [, ]/ }* L2 i8 O: w( `
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |. e! D0 V& F  f# e
         SPFEI( SPEI_END_INPUT_STREAM ),2 M( Q: S6 g2 n$ |5 Y
            SPFEI( SPEI_START_INPUT_STREAM ) |
( @! ]( s2 t* t2 U: M            SPFEI( SPEI_END_INPUT_STREAM ) );
2 {2 @% H8 M* M* g# ?* M5 ^if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {* D& k: \: ?3 A  s
    return hr;: S* ]2 \2 @/ A1 g0 \
}
0 a, `! j/ t% l+ q3 o& L+ {
2 ^" l& C0 s6 c  G//设置通知消息* v+ u3 s, ]  |% S. e  r
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );/ @" H" A4 j( x0 e- D
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {! C: c3 h5 q) A! c5 O; [1 g
    return hr;
) r) M( Z- b" T}/ S2 U7 }; |: G" X; }5 S7 E: F+ h
7 z' r% z! k8 j/ J+ M$ |; ^
return hr;
  ~8 S7 C7 h+ E% M& t8 g}8 X3 w1 r& I+ W% L7 ~6 C

% L8 u9 g* }! C1 `$ M# v, }7 t////////////////////////////////////////////////////////////////////
" U5 D$ m' m3 j: O- q  {1 J. u) K//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。$ L" L+ @6 x! x! }
//并设置兴趣,设置通知事件。& y1 ~1 ~2 Y! b' |
////////////////////////////////////////////////////////////////////% p, _# G" s' J; O
HRESULT CTTS::Create( const DWORD dwLanguage )( c9 F! |6 ?; v/ q
{( V0 {& f. t2 {& G/ x! @: M
HRESULT hr;
' _7 |: c4 Y% V0 Zhr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );& S5 x6 s) d% k
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {
/ p% [5 L2 U; U) c7 U8 L   return hr;5 ?- G) S3 f9 j$ s( @
}
/ L8 {0 g; ]' |& U0 b1 Z1 C3 a
1 K* D. N, B( B4 m" d) ?& Y, ISetLanguage ( dwLanguage );
1 A6 K. `+ f/ G  ?+ E6 o0 \
) H8 A' W; Z/ yhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
- ~0 @: z: v5 O4 _1 n* b! cif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
, c$ ?/ C6 c- ~0 t" g    return hr;
8 ?, {* n0 W- v. E% m+ @( j( j}3 |& k/ [5 Z, A& p
. ], L) h. ]# d
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM: v4 f  c7 K8 u, n4 U
//SPEI_END_INPUT_STREAM 表示完成流输出。
0 [- V9 f# S2 _! n' K; ?6 W4 s1 xhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
' ~0 ~. G# _; Q3 q% ?         SPFEI( SPEI_END_INPUT_STREAM ),9 Z% j6 r7 }; i7 y6 K# Y
            SPFEI( SPEI_START_INPUT_STREAM ) |1 o! a: v/ O# Z1 _  l+ X
            SPFEI( SPEI_END_INPUT_STREAM ) );5 q, @" h3 N8 X8 ~
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
3 p& `; n  A7 U6 `+ y! ~  C    return hr;0 ?) k" D1 S! l9 ~
}' A5 R9 B; m9 i- W+ J; r/ |
* e& [: Q% t. `
//设置通知消息
" @  ^* ^! D3 _3 y7 f! }8 jhr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );, k3 r8 |9 O8 f" K6 `! s0 |/ U
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
3 Y, R" ^) E# s& L( s+ b    return hr;
9 P) o  D3 O* k2 d4 i}
' b. G: l8 w! F+ `! Z- g" a7 K# e) r8 T0 W1 r5 g! b
return hr;
. m* _4 l: n8 R) ~' s+ h}
5 M! @, e1 F, h% s7 X& l: G8 E
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件/ R5 i6 {% b8 K0 y  E
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
: E, H0 ?9 J8 w2 z2 F{
9 E) \' ^# Z$ N1 i    ::CoInitialize(NULL);//初始化语音环境
/ G2 J* W0 S: M3 h- O5 }6 F# e& f# ^; r    ISpVoice * pSpVoice = NULL;//初始化语音变量) f' d2 ]9 N# \9 c
    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { ; T/ |# F/ |* V/ m
        cout << "Failed to create instance of ISpVoice!" << endl; + x6 T% v% k$ U/ o" a
        return -1; 2 s8 q' w' _, v* P0 C
    }
/ l3 A" I! O  W' J& B% l' q9 c& Z
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量# [9 o9 y3 r% w; n6 i
    ::CoUninitialize();//释放语音环境

5 {+ T, d/ C+ M3 c  Z0 R    return 0;: @" D3 s6 f) V6 q6 ~
}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序, l0 r9 \! X8 p* ?

0 m- \2 i" G* k! t/ J% o1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地* n! L5 h/ y# a8 c

! _8 n0 S  h2 ehttp://download.microsoft.com/do ... -US/speechsdk51.exe   & [' A& b) b  e% n& @6 s* b1 i% w
Speech SDK 5.1安装包 (68   MB)     ' y7 R& y+ t: L/ P
http://download.microsoft.com/do ... chsdk51LangPack.exe      
' Q6 \+ O" }" b中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  - `- Q8 N, q$ z& R
/ m6 O% c3 Q0 s% ]  E5 l6 ]9 f
2.下载后,执行安装
. H/ X+ D  d4 |4 N) C) w( n" w( M7 ?  R% x5 K
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。- M8 K7 e* I" Y  R
6 ~+ N+ F7 E. _* {+ R' Y' j" z! h+ E
3.VC的环境配置, y& m! r! e/ r* Y2 n) y; T
3 I& ?* V' I$ Q
在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:# y9 I' a. @% x6 J& L  ]! a# C$ l7 x

& ]  u& g; H8 t& ]2 K工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
) Y: \' }) J# E  r, |- d% ?. v# E( U( A( Y- O' A# ^, q/ W0 D
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~( y( Q/ a& M' ^! s& K1 ?) Y% i
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-10-2 05:28 , Processed in 0.021149 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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