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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////* B6 K6 d! P; \, x& J) F
//1,生成动态连接库时,要#define USE_SPEECH_DLL,* ]2 }$ H5 W! }
//      并且#define LANE_SPEECH_EXPORTS
, M! H6 Y9 G6 f9 A6 [' u1 W//2,使用动态连接库时,要#define USE_SPEECH_DLL3 z8 B) A9 C( ^$ @( _! ?8 H% L6 r
//3,声称和使用静态连接库时,什么都不需要
; ?) {1 }3 M, z# F7 n//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),& ]9 v+ B- i3 _$ `9 x0 b
//      动态连接库就不用调用了。
7 H3 u, A; y. t: s( z; R////////////////////////////////////////////////////////
' a9 V. h4 q7 o! s/ T#ifndef LANE_SPEECH_H2 p8 a9 z+ V* o  u. Z2 |; }, j
#define LANE_SPEECH_H6 I. i- I: ^1 W4 L2 |# @

6 g5 |- b; v5 n2 g* ~4 K' e2 ?#include <windows.h>
5 u0 E1 Y# }  I7 ?9 S& S% _1 E) ^" T#define _ATL_APARTMENT_THREADED
3 W4 W- r% v  l7 A- `  J9 e+ Y#include <atlbase.h>" D% g) Z  `+ [# o0 z  }& i
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
; w2 `) p+ y9 n#include <atlcom.h>5 T6 ^6 w  _8 T3 u6 T  [: Q: I
#include <sphelper.h>   //sapi需要的头文件& X8 f# V6 w5 H& i4 G

. e! K3 V# f1 }2 I: R7 u4 l//-----生成动态连接库和静态库的处理----------------
  u& C- h3 j6 [5 f#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类. W: U' ^: r8 C+ |0 [$ F* Z
( [$ K) U4 v3 p% }
#ifdef LANE_SPEECH_EXPORTS6 D: d* D% A4 F# B4 S
   #define LANE_SPEECH_DLL __declspec(dllexport)( f8 u# Q# H* O: L$ ?% c# n, u
#else) C4 }$ t2 V; D
   #define LANE_SPEECH_DLL __declspec(dllimport)+ k0 Z9 }, D- C9 ^& ~, U
#endif
: |. }  O' T9 d' N0 ~* A+ u
. B+ I7 v. N5 O" [6 U, s% g7 [( `//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关$ m+ \# _) R1 i( Z1 S
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。, l2 ]; L. ], u$ B2 [8 L
#pragma warning( disable : 4251 )& p) v# ?+ ~2 W6 _  b

7 ~# v8 k7 l7 h- ~. K#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)
2 K$ Y" F) x+ X( H0 E: z4 m, b#define LANE_SPEECH_DLL
4 |" Q5 v- V1 w4 r$ i5 [" r8 x# x5 q+ t$ D
#endif //USE_SPEECH_DLL
  |5 }4 n) @3 s; x6 k3 W
$ H* Z" y  P4 \0 q
  M0 f4 Z7 J: ~//***************************常量***********************0 u6 P$ e( e4 ^3 [8 W

; H( J  F; O. N/////////公共常量-----------------
% t) L  e: N8 o7 B. ^" r6 Rconst DWORD   SP_CHINESE = 0x0000; //简体中文.: d) v$ Z0 Q' v. ]2 c- |0 Q
const DWORD   SP_ENGLISH = 0x0001; //英语.8 Z; ^+ r+ d% B) C. C. z" b* T
# I* d2 i0 k# B- j. X/ y
/////////CTTS常量-----------------. h3 i% ?% P' a# A. |
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
( B% G0 Q6 m" G- F: F/ ~( @. m6 [
- `& Y+ j8 ?3 U  ^2 Z/////////SR常量-------------------
, c% B" G- w6 e2 B  z" _const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。
+ N, r9 S0 |$ kconst DWORD   SR_INPROC = 0x0000; //独享类型的SR.
/ i3 [! n2 Z( dconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.
5 P' i6 q7 w& ~
, U! M. _5 t  A( E" n8 S//以下常量仅作例子用。
. a$ j1 R( |7 ?: n# {/ o5 n, `#define VID_TopLevelRule 9000   //顶级规则ID
' Y( Y2 m) S% K#define VID_SubLevelRule1 9001   //子规则ID
3 b0 }! ?/ o7 p# S#define VID_SubLevelRule2 9002   //子规则ID
7 k# a$ q, [9 ]( L#define VID_SubLevelRule3 9003   //子规则ID
: z8 A& O1 M2 Q) H5 |
$ X4 O0 N% Z% R: e  J, t; F$ Z' H, `6 b. i( i' @
//*************************类声明************************
2 H. h+ S3 ]; r: X5 c5 L  x# x
5 Y! L+ d6 ?$ |$ R: t' S+ q5 |8 e1 T4 B. ?! `  b! W2 l$ I
class CSR;1 S  l. [% G) U' t7 i* m$ f
///////////////////////////////////////////////////////////////////////
" \8 H) g( f/ L, I9 J. e- x& P8 x///////////////////////////////////////////////////////////////////////
' `- t0 C& Q* i$ a//( J+ s+ N6 Q/ N+ `- H
//         CTTS# ~" K4 n8 B; I/ g5 T3 v! A6 h
//
+ f) y9 `0 T+ H+ k$ \7 j8 v8 [///////////////////////////////////////////////////////////////////////0 H$ v4 u/ a7 T
///////////////////////////////////////////////////////////////////////# B7 k" v& a; E  W, m1 M5 n

9 H: h  q' @% I- nclass LANE_SPEECH_DLL   CTTS
0 Y8 x- b+ H$ h: V4 a/ r! T& k{
5 i) F+ ]6 h% ~* d7 c- p( vprotected:
( p8 @' G; z+ {" ^: I. D  ^HWND       m_hWnd;     // 关联的窗口句柄。
9 C9 e/ v8 I8 Y5 G6 i' J
' I4 i- ^% w; w) }! o5 L2 w6 dCComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。
$ ?9 p5 {, r' ]; j1 wCComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
! f6 Z! l+ X# J/ h: o7 ACComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)
8 l/ F5 K9 d' iCComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。1 ~* L" u2 f7 L) A0 L) H

' Y" S& r. v9 A$ e, [* gpublic:( {; M1 V$ i) H" N" F! _
//********************************初始化部分********************
' a. H; I" u$ X5 w4 ]: `% h
" V2 z! N5 S2 n# W////////////////////////////////////////////////////////////////////& m3 d# @9 U. g2 k6 q* J
//功能: 保存与识别引擎关联的窗口句柄。( d" q  o4 q5 A' Q* O. A9 \1 r4 E
//参数: hWnd:要关联的窗口句柄。" z  h5 C, d) R- o8 {( e
//返回值: 无。
9 p) m% T9 Q6 [# a////////////////////////////////////////////////////////////////////
" K' R/ Q' _! D% ICTTS ( const HWND hWnd );! m; ^+ W9 m! ~7 ?: d

3 v+ x  b$ ]/ L& v# S9 ~////////////////////////////////////////////////////////////////////0 i4 G6 Z# {6 V
//功能: 释放所有的对象。/ ?1 L8 |8 J  e+ A6 l
//参数: 无。
+ B( d' w- H* X6 }//返回值: 无。
, W) m3 i$ Y, _////////////////////////////////////////////////////////////////////
3 m; a0 Q) o/ b! q~CTTS ();
' p% B8 U. k, n. `$ M% E/ T& q
////////////////////////////////////////////////////////////////////8 _3 Q" e9 j4 [
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。- |% z, F0 }3 L7 [$ \5 s5 U0 [
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
& x9 W5 W1 k/ a0 W, x' r//    SP_ENGLISH为英文。
3 v5 L8 e% R$ ^8 ]4 n//返回值: HRESULT类型。4 ?) R  m' }0 r" v  h& F
////////////////////////////////////////////////////////////////////( }& R) C+ y7 e! r9 W' C' E3 n
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );
  g) W/ j2 l3 K3 o4 l1 ?' n
) \6 ~5 y7 U6 N9 z' ^! r) J////////////////////////////////////////////////////////////////////) I$ ~( {6 z$ T5 b$ C: E* J7 s: j4 O6 r
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
+ y9 \" Q$ ?( ?/ i8 B8 O//    通知事件。! q! p0 j$ B" k8 ]  g# I
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
0 v0 [4 p) Y& ^% O: v//    SP_CHINESE为中文,SP_ENGLISH为英文。
4 ~1 [: p6 ]4 }+ s# m  ^5 n//返回值: HRESULT类型。
: d: }: ^# L5 T2 Y, g////////////////////////////////////////////////////////////////////
8 T2 x2 Q, c8 W! a3 x& lHRESULT Create ( const CSR * pSR,& _: J. V  D) E
       const DWORD dwLanguage = SP_CHINESE );
1 t" P7 [" N' b/ J  V- P9 d- i4 Q. Z
& A! _1 |$ L- w4 v  Z
//********************************设置部分***************************************
4 P# p" Q- X2 d% y  }. |# D) A# c7 V' M( v7 w& `1 U
////////////////////////////////////////////////////////////////////4 \; K$ _& C# v5 \1 S& I
//功能: 设置朗读声音的语言种类。
6 ~; s; v! n/ L$ ~//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
( ?$ C! K4 {, n! ^- M7 r& N//返回值: HRESULT类型。
7 o5 p9 t. e4 B- M6 r7 C9 Z: H////////////////////////////////////////////////////////////////////
- w+ `2 e/ Y( qHRESULT SetLanguage ( const DWORD dwLanguage );
  q" r" P& J, s1 y( e
# Q5 s1 D( X% C5 N////////////////////////////////////////////////////////////////////
7 @2 n, z/ T7 _% M8 v8 e% ?//功能: 设置要处理的的事件。2 u. W9 T) ~+ h9 d7 p' T: \
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
- V& a8 q( `, F( n0 M( n9 E: R//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
" R% r, N( I& d0 J3 @! t. j* _8 z//    件都会收到通知。4 Y* ]% l- p+ P, _7 Y
//返回值: HRESULT。( K+ h" L7 f9 r# v3 _, d+ O
////////////////////////////////////////////////////////////////////( L0 K2 W  i! m. k
HRESULT SetInterest ( const ULONGLONG   ullInterest );' j7 k" m, `: g( V, z2 e9 g$ H' `8 s% E
2 _. o2 b+ @  `, f9 Q+ m
////////////////////////////////////////////////////////////////////* Z: j0 u1 Z* z- Q! J
//功能: 设置朗读声音的音量。+ r% S% D* C$ |" i8 Q' `: E
//参数: usVolume:音量数值应该从0到100* v! {$ F, w6 P, ^$ R2 L
//返回值: 无。
% }- v; V- h+ V% `1 }2 G4 K////////////////////////////////////////////////////////////////////
% h- B& W! C% Y0 N: avoid SetVolume ( USHORT usVolume );8 h, B$ s4 r( m, _$ o; @

& b* f$ [8 M$ ]1 X$ r5 R////////////////////////////////////////////////////////////////////
8 G, \" k3 X$ v! P3 w0 }//功能: 得到朗读声音的音量。
. V1 Q/ L$ S3 Z( d//参数: 无。
0 ^# j# ~# R0 Q7 Y3 D0 s//返回值: 音量数值,应该从0到100。7 j' M1 f6 Z3 w$ q
////////////////////////////////////////////////////////////////////
. l! Q! {6 O; [2 C: P; X& A: R2 }7 iUSHORT GetVolume ( );
5 f- w/ o. a( C: X
: \3 d$ _8 n9 M- L. S$ f) q. q: U////////////////////////////////////////////////////////////////////: K% d3 U4 g% i/ n6 i) _) c
//功能: 设置朗读声音的音速。! d: d7 B7 k8 [: S' S
//参数: RateAdjust:音速,参数范围从-10到10。
' J. _8 z4 b8 W- r//返回值: 无。% a% t) {6 L) P( y! l! G' W
////////////////////////////////////////////////////////////////////9 r+ K' j7 d& V1 i1 H& q4 A
void SetRate ( LONG RateAdjust );/ ]+ Q+ _5 ~& S& Q* L9 E* g. a" V
6 b- r) R7 j6 i* H) j$ B
////////////////////////////////////////////////////////////////////+ K+ t7 E3 P/ Y/ N6 s
//功能: 得到朗读声音的音速。% }; s% ?5 o3 O5 A. Y- |0 D. B7 y
//参数: 无。8 f9 b1 W" R2 I0 Y/ S1 S
//返回值: 音速,参数范围从-10到10。6 n0 E5 i& N5 V% [6 X6 J" |0 M8 M3 P) D
////////////////////////////////////////////////////////////////////
. P3 l* ]" ~% E- N9 \LONG GetRate ( );
' n) }. g9 F, a1 K5 {# w" _
' s8 J5 i4 @7 J! c" i. w////////////////////////////////////////////////////////////////////, M, @7 V* u: V! c' ~
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。/ S7 E9 _# V4 E+ Z# X( q! R! S
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。! t. O& u& n, D9 c% L5 [# U& e
//返回值: HRESULT。
  l/ h6 Q' v0 |+ j' D2 U! z////////////////////////////////////////////////////////////////////# L* @; K  s( a# y, ?$ X" J' @
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");) }8 A2 g; R# ?7 r* u
# U' {* F# ^, Y* @3 ^3 |; T
////////////////////////////////////////////////////////////////////6 _) |8 z1 u, ^
//功能: 设置朗读的声音从音箱输出。
- M" R- v9 p5 `& [6 j//参数: 无。1 Z$ h- R6 P" H& M
//返回值: HRESULT。% w# W5 L8 O- G, {9 O  t) M9 j
////////////////////////////////////////////////////////////////////. x3 k$ n3 E' o' c4 N7 {; j
HRESULT UnSetOutputWithWav ();
% S8 b5 w8 O$ @) t$ _  u
% R! q( X0 i* @) m7 O# V( m2 n6 X. `7 `
//**********************播放语音,文本到语音转换部分*****************************
. [" J% N1 _) Q$ v; \$ O% _! _- E
3 J/ R, S8 J, S1 W' p9 A////////////////////////////////////////////////////////////////////( H% g/ M& l, }9 N
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
4 v8 o/ t8 K9 O( B5 e//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
% a# O) A7 A( p; L) ^$ x//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,# g+ X/ @2 w+ g8 x
//    SVSFIsXML为朗读带xml标记的文本。
1 |7 n$ U1 B  C' ]1 T. w4 n2 s//返回值: HRESULT。, D  o/ x+ s: F9 m5 p* @) k
////////////////////////////////////////////////////////////////////: s# O3 @' b; h6 j. ~  t3 h
HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
' {5 C% F8 j+ ~# f9 B8 P$ F: R) l- q/ y& n5 K2 s8 R4 n
////////////////////////////////////////////////////////////////////# |3 D, g; Q3 x; @! f2 n5 n
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
+ y6 ?& }, y6 n//参数: 无。
& `) `) i- s3 ?! @1 I4 h6 K9 W//返回值: 无。/ Q& K; y" L2 u0 B8 z" X; A
////////////////////////////////////////////////////////////////////
7 o2 L' F% Z; x) I4 ]void Stop ( );3 w4 J7 Q) \: s; V  w9 ]& X1 h3 Q; o

5 x( T0 G/ s( w1 }% V9 B. k////////////////////////////////////////////////////////////////////
1 d% B/ J" [" C4 \# O. m//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。* d, X! a) V% p4 X& B
//参数: 无。3 D1 L$ s$ G3 U9 ~1 e3 o
//返回值: 无。! c/ O5 ^" \; e/ ?
////////////////////////////////////////////////////////////////////
4 S8 X0 l+ s: Kvoid Pause ();
" m: O: ?( j9 `0 j% x
' T) _2 |2 `& r////////////////////////////////////////////////////////////////////7 B. J/ @# `: u+ P' s' R/ p6 f3 A
//功能: 从暂停的地方继续朗读。
' u. I3 N/ ]6 h+ B# L" E: y//参数: 无。
& U" U9 T; k+ E" x( b; O//返回值: 无。- W3 E* e1 \/ X" f6 x# ^  ^$ @1 h
////////////////////////////////////////////////////////////////////6 _) _0 v" L) _$ |8 Q/ c
void Resume ();' m- L" j2 A4 h5 H3 f' Y
4 Q* A1 L$ J4 k& j0 ~
, U9 U5 R1 y% R, ]8 b7 l
//********************************处理事件部分***********************************. }+ D8 d8 b4 ?; O- r

  {5 H6 \1 m" E/ X0 Opublic:
9 E- A4 |- g  j////////////////////////////////////////////////////////////////////
2 S5 S  s. M8 G; _; g" O6 ~//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
. }& |; \, ~; z' V, M//参数: 无。+ D5 |" ?2 {4 @0 F
//返回值: 无。
/ W) D* {. j% I' X0 A: a7 E////////////////////////////////////////////////////////////////////
7 ^  S5 Q% `! hvoid ProcessTTSEvent ();: q! U. s3 o$ x- Z: a! b

# d, e1 [, G  \3 F1 `$ C# F* Q5 D
0 Z( q; Y( F4 ?- T; X////////////////////////////////////////////////////////////////////
/ W; x9 E% d/ a/ _2 Q. Z//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。; N9 @6 H1 o) X9 j
//参数: 无。4 q& H, J1 ]3 Y5 W, b
//返回值: 无。
) M  I9 g2 ^) T  E$ S8 L0 m5 m" x1 Y////////////////////////////////////////////////////////////////////$ l* a- N4 y. i( Z
virtual void OnStreamStart ();3 H, l* q) Q( w  i

- i  i& I5 @! K9 h' F6 \4 }* ]////////////////////////////////////////////////////////////////////; S/ B3 g  L; [/ R3 K5 t
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
7 [5 w( C) Q4 j. |  P//参数: 无。
7 q; x6 S3 x# M6 C//返回值: 无。
* N' V5 \  F0 b# n- k////////////////////////////////////////////////////////////////////" V, u& s4 q4 [& C4 ~
virtual void OnStreamEnd ();, ?( X+ \& ?  {2 c
};
: Z- K7 ^0 i& K% {4 |4 t, m, ~
4 Z$ L: s, B# u2 s% C% u1 O% u; {8 j+ g7 F5 {
///////////////////////////////////////////////////////////////////////0 z/ m5 ?& M5 X% Y! U, w$ p2 b
///////////////////////////////////////////////////////////////////////
- P8 v( e8 L% ^, E( C9 [, i6 M8 E1 E# W//         CSR- Q/ {3 i* P% Y
//
! q, l2 y, Y* |7 ]" o3 Z3 P2 k8 U///////////////////////////////////////////////////////////////////////5 g* M+ c: Q' }9 I
///////////////////////////////////////////////////////////////////////3 k; H* G" k1 Y8 G6 B6 k
5 z3 o* z, I; ^4 w
class LANE_SPEECH_DLL   CSR3 g$ ]% v. e% ?: S$ E
{
' a' z2 b, N" G; f, k" |, g2 t- I  x) h. z( g9 Q& R& A
protected:
7 d( w- x$ N; m& h& bHWND m_hWnd;2 G  g; P5 c( }; S+ @0 j! j. c4 B
! p* _. }7 i" `" E
public:
& k0 z( G9 h' BCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
$ b" s5 `; b0 @% l7 v: ECComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
5 F+ V  e4 Q" t8 _1 R$ y, Y( `CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。
$ D8 M8 R* c. ?+ O4 S% l' U! PCComPtr<ISpStream>    m_pInputStream; // 流()的接口。& P5 ^1 @' n6 `5 x% L
CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。
* v4 ^) B. K( y$ Z& z% n& J. BCComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)' Y. \5 Z9 F1 j; F
public:; A0 h( j0 w* C( m, u
static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
5 ~. e% t7 \# }8 Q- f# Y" l- l6 _% G: J& `9 @1 P9 w

' c/ e, p5 E* z4 Z5 kprotected:6 R2 c% \1 G! j3 f$ E
//***************************辅助功能部分****************************************
( j! Q& K2 D; q; O! }% |- e2 C+ [! u8 l* U
////////////////////////////////////////////////////////////////////
3 P( ^0 A( y+ D//GrammarID加一,每个GrammerID必须不同。
1 e% |# V% N+ B. H, y; f# f////////////////////////////////////////////////////////////////////- f& L8 X- w% ]( U1 {1 a
static void UpdateGrammerID ( );
5 w, r4 C9 H2 z0 z0 O9 n% M2 X; C) q5 Y% T$ c( v' X5 M

$ M) J- b0 o5 s: Ipublic:, d+ h6 M8 p" U
///////////////////////////////////////////////////////////////////// b$ J+ F" n; I* p
//功能: 友员。TTS中的从SR引擎中建立voice对象。9 g( ?+ f# Q9 b/ q& {) a" z
//参数: pSRContext:SR上下文对象的指针。
' H# b/ o: q; l# I//返回值: HRESULT类型。
0 h9 ?$ Y, c, e) p6 w////////////////////////////////////////////////////////////////////
  a6 v; Q7 j7 Z2 v) i# V% ifriend HRESULT CTTS::Create ( const CSR * pSR,' z9 d* q( W* V- L# ^
          const DWORD dwLanguage );7 m0 P+ h- F1 [% f8 q% D; t- Z

3 A  A) Y% w7 \& l7 t
( R! s8 y% w3 z; `. `3 y//****************************初始化部分*****************************************
$ }( B0 u1 ^0 Z4 \! y
, X6 H) i8 X4 p////////////////////////////////////////////////////////////////////- O5 c/ h' ]8 d0 T, H
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。
; p/ d  L3 x. L//参数: hWnd:要关联的窗口句柄。* z6 H* ?8 l' q" a4 p
//返回值: 无。2 ]4 p* e2 k+ D# d5 R( N
////////////////////////////////////////////////////////////////////
& I: h. l) d2 p$ QCSR ( HWND hWnd );
) X0 w2 y  F4 y
5 V5 n1 k% y- c, R" t////////////////////////////////////////////////////////////////////
- B3 {3 |4 |& F; t3 `6 ^2 ~' x//功能: 释放所有的对象。! h/ P8 k2 j( V/ `
//参数: 无。
- J# d3 V; C7 d3 Q! M) I; x//返回值: 无。
7 x/ ?/ S+ Q/ x2 m! j0 S$ F4 }1 D1 z////////////////////////////////////////////////////////////////////- u1 O+ ]! `- r, f4 O1 H! h# a/ V
~CSR ( );7 {/ W2 O" {& m- R# s$ k" L
. t% O3 y. Z3 y4 q
////////////////////////////////////////////////////////////////////
. E9 x* D5 I4 X* K//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,8 c8 o3 w. Y$ n3 p3 D
//    加载文法文件。
* |$ ^5 g; A4 A//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
9 T8 F8 Y  u3 Z+ u1 l3 l# r+ O: q, G6 e//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。/ @3 |" w- d& c
//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。6 S; ]9 A5 k) C/ u
//返回值: HRESULT类型。
) O+ v% r' G, T& Q& }////////////////////////////////////////////////////////////////////0 e* x2 S4 l# w% D4 W. ?
HRESULT Create (const DWORD   SRType,
. E% l, p- o1 k( m2 W) [% [      const WCHAR   *pwcGramFileName = L"grammar.xml",2 ^0 g" c2 }0 \0 a' t6 E' g
      const DWORD   dwLanguage = SP_CHINESE );
) b% Q5 K2 R0 r6 d% q* w) T) d
9 L1 H5 `$ `2 N( F% @2 A2 i8 l
. |6 Q- B; ]- n- i% v& `//**********************************设置部分*************************************
5 q7 D5 W: N: Y7 n0 a3 @$ ]
' ?0 H5 E( \" W* l- T////////////////////////////////////////////////////////////////////- t$ B' Y+ V7 D3 d
//功能: 设置要处理的上下文接受的事件。
& ]( m% `; n( l! e/ c//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,! F! Y7 l: _! o& w
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事" K+ \0 b! X7 V
//    件都会收到通知。0 x- K; N/ _, d7 g& M; d8 Z5 I
//返回值: HRESULT。
2 e9 w! R- x4 H6 o* X& s/ p0 [////////////////////////////////////////////////////////////////////  @0 X2 H2 g; x
HRESULT SetInterest ( const ULONGLONG   ullInterest );+ E, a8 k9 j& O6 o
% v; A, H- g3 g2 R
///////////////////////////////////////////////////////////////////// Y) e6 w$ s4 |6 ?/ z
//功能: 设置某个规则的状态(激活或者取消激活)。
0 f2 {, i- I- o) K; ^. X//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,0 b/ r( e; C1 g, E) t3 h) }
//    FALSE表示取消激活。
1 U9 h& K+ b* s) _//返回值: HRESULT。
2 w+ C7 h, a9 h& H////////////////////////////////////////////////////////////////////0 \' }1 a4 S& i
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
3 |" A* O$ c$ H. P: U
0 g# z: h' f4 K: h5 I' d" I- c3 A1 x1 w9 E, G! w& m) p
////////////////////////////////////////////////////////////////////
+ y% j. P# M: K! g: A//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
9 G& c- M  S4 N% d//    风输入。
2 P: {$ w. Z: g) C//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。" W& h  V. W3 L+ k
//返回值: HRESULT。
( L7 T3 _6 u0 a; m* {  A. C6 a////////////////////////////////////////////////////////////////////
" W1 B' K! V5 Q4 u0 e3 E7 jHRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
9 H/ |7 I" q# j2 _5 I5 L4 {7 t3 O& C! q5 N" ?% Z
////////////////////////////////////////////////////////////////////
5 {# s% I) p! B9 x//功能: 取消从.wav文件识别。恢复从麦克风识别。
/ }: P' e& k: o//参数: 无。
/ A9 Y( C  q6 O1 {* S$ k+ \, Q//返回值: HRESULT。8 b0 G2 b" f3 M& f# l; A& \
////////////////////////////////////////////////////////////////////# \5 _5 P1 p- e0 l7 _  ]3 M
HRESULT UnSetInputWithWav ( );# Q$ t; h3 t8 Y9 M6 Q
% h  U1 z4 _- S/ F1 [
//***********************识别开始,结束,识别结果的处理**************************( p* q: u% A0 Y1 N2 D
. s0 Z8 w7 Z0 S5 T" L% v
////////////////////////////////////////////////////////////////////
4 h8 g% K! o3 G. e//功能: 识别开始(将所有规则激活)。
% V, L. ]8 J$ N$ q. L//参数: 无
' `/ z& ^; n5 t//返回值: 无。7 B. j% o$ L& ~
////////////////////////////////////////////////////////////////////
% U  ?' e8 ]2 q3 Yvoid StartRecognize ( );# Z7 b5 t0 |2 K$ A7 l

: L* H& h  U( q: F+ Q: q////////////////////////////////////////////////////////////////////
; E# b( D" ]$ W$ T4 V$ [( c# D//功能: 识别结束(将所有规则取消激活)。" D, H) s  g. c+ s) [  M* Q1 U8 y
//参数: 无。! k7 b; Z3 X3 k4 Z
//返回值: 无。
, x. e# u' |8 K% U  Q" T/ ~; ]////////////////////////////////////////////////////////////////////" b2 S* h% Z& o4 d% z6 k
void EndRecognize ( );  x# I5 Q" D& Y) j

; Z8 o! A' P' Xpublic:
: @: ]. G$ B$ Z  _6 [8 M6 l. n////////////////////////////////////////////////////////////////////9 S: x& d" g1 `8 Z5 R5 _# k( j/ d3 N) J
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
; i- K, ~, b$ c$ |7 ?//参数: 无。
/ r3 K' o% Z, j4 G9 I//返回值: 无。& ]1 ^5 h, _  Q; q0 T
////////////////////////////////////////////////////////////////////
  \& j5 n2 x2 k" X0 dvoid ProcessRecoEvent ( );
8 F/ p4 Y" T) p. @$ ~. |7 Q4 s( J$ G7 N" |3 d! ~2 a
protected:
" i4 ^& G& J0 M. D3 g5 p: P) v9 I" {////////////////////////////////////////////////////////////////////6 g2 C6 U6 {2 \( }/ E  T
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。* P$ u7 ]' V# C1 d, t( V! ~
//参数: pPhrase:ISpPhrase类型。
: J( {( c  i$ l% Y, q! b//返回值: 无。; T- U" d/ [' }4 i# V( v) D; W- `* g
////////////////////////////////////////////////////////////////////% ~6 ]* Y2 B2 V: p' H( t: N; y
void OnRecoSuccess ( ISpPhrase *pPhrase );  a2 @% l* @2 c! s3 f3 C) }% `
$ F% V0 b9 [8 B5 n# a7 _; l% m" Y
public:
/ m1 f- ~/ c0 H4 H, _' C5 g- d////////////////////////////////////////////////////////////////////) F: {" ]* K2 Y
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
; L/ w4 F6 f: j) S1 d//    需要在派生类重载。规则ID必须以常量形式预先定义。7 P7 w  r" P9 e9 ~& f; S
//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。3 k" L) H( i! v) D9 X
//返回值: 无。/ E7 a# }! M1 y2 w. R
////////////////////////////////////////////////////////////////////6 m+ j( S! |' O; J  C4 u+ G# J+ G
virtual void ExecuteCommand ( const ULONG ulRuleID,; _* s8 K6 H. b
          const ULONG ulVal );$ I) a: F" g# a' k3 d. A
3 ]/ f  S  f  ^8 o' v0 y
////////////////////////////////////////////////////////////////////
4 s+ H" ^4 K1 I; g5 E1 r4 w0 L- H//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。; d4 r6 t) a3 _6 D
//参数: 无。
. ?( r; m0 j* B5 v( l& ?" ?8 U//返回值: 无。
/ v& d4 z# x( P6 o5 L( Q4 Q////////////////////////////////////////////////////////////////////; @7 v9 _3 j- }
virtual void OnRecoFail ();
5 F/ C) W2 b; ~# E3 C" ?& f/ c; c) p! [) _7 J) V
////////////////////////////////////////////////////////////////////
( U# N" M. p) f/ B/ c1 D8 c//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。( d7 z: I6 W( m- X: d  n
//参数: 无。% W4 b9 @* o) P* c6 ~
//返回值: 无。
* A' R0 {. [% ?9 J- {1 d) e9 H////////////////////////////////////////////////////////////////////# {" I$ Q1 |  P- I
virtual void OnStreamStart ();3 T: q# N1 @+ ^9 u0 G7 n
6 h4 [8 z# S6 |, ]( X" h# m4 J
////////////////////////////////////////////////////////////////////
3 `0 g0 {, l5 @2 D- I//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
* [" x1 ]6 g% G/ E# m4 k: j//参数: 无。* v3 v6 s' G4 H; ?" d; X/ V
//返回值: 无。: i' \# q0 j* Q  E% f
////////////////////////////////////////////////////////////////////' K$ o9 j( E3 n
virtual void OnStreamEnd ();
# U3 `2 N% P% C
2 q3 z& {$ e9 O2 Z};
- S9 v, Q* ^- I$ \% [) y0 u" I! q" u) Y  O% D& o9 ^8 [

8 ]: A4 S' `/ c. h9 T, Y, M( x" S
3 m  Z  a/ I0 i! G#endif    //LANE_SPEECH_DLL_H
  h8 E- B; p) E( H; Z: R( ]8 O; I3 F0 S& U) s
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////0 ^% C- I4 O5 v6 Y
' W* h4 t* O- S; U3 K9 N
////////////////////////////////////////////////////////; A7 b# Z7 H& j6 ^
//0 s* F' ^* g0 Y3 y4 W- h/ i
// 文件:LaneSpeech.cpp" T3 w  p/ N* l
// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
# D$ U6 i! v( A/ u3 m//    语音识别只支持命令模式,不支持连续模式9 T5 T& R6 K5 A
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 36199082 S9 W$ j9 r# P
// 日期: 2004.10
2 p7 j& D; G2 q// 版本:1.2
; @, f. m5 E, K5 u* G4 d// 5 S; [' K2 K! Q' T
//
5 p( W6 y6 o8 b* D! K7 b& u////////////////////////////////////////////////////////9 q6 G$ ]  M' t1 [: k+ H9 ^
# r, d. Z$ S3 H; \8 X/ b

. a; D4 o2 f. `- r* w$ R* P8 p: l, r& {& {+ R
#include "LaneSpeech.h"
9 P: `- Y! z* ]/ f
" C$ K' D# g% Z//-----生成动态连接库和静态库的处理----------------3 W5 h: |, m0 Q* l, g
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类% c4 f! _  \! h( ^' f5 L
7 Z) W# [3 Z$ f5 U; }0 z: m3 G
BOOL APIENTRY DllMain( HANDLE hModule,
- B% y$ Q% m2 R3 |4 [& Q( h                       DWORD ul_reason_for_call,
' c( u  v" Z) t& V2 Q. S' e                       LPVOID lpReserved. t2 E, W  j* P" j2 U: g
      )
& f1 A7 N# o( n6 A0 m4 r{
9 @5 @2 E! G* B& Y' m- T    switch (ul_reason_for_call)
' i; E4 r- |4 T7 W6 j+ Y: P5 V{* I) s/ q  \* I0 D
   case DLL_PROCESS_ATTACH:
: G0 T2 c# }. G( O+ |" w0 v    CoInitialize(NULL);  A0 l) }- e4 O" ?9 E
    break;6 T6 H* T) O0 z" s$ Z! A4 w# Y  t
  9 r& n1 O* c8 h5 x& F
   case DLL_THREAD_ATTACH:$ E! f# P, G/ L) _0 {
    break;0 C$ q8 m& l7 R( e
  7 }9 u. W$ M7 }/ R1 h9 _; W
   case DLL_THREAD_DETACH:% g" k( M. {+ E; [% ^
    break;
1 l: b% E! Q1 }  
$ x# K  \( {8 B. _( @   case DLL_PROCESS_DETACH:
3 @' A! [1 ]2 }' R+ ~, `5 q    CoUninitialize();4 E% G! @0 z1 F/ ]& n8 l2 x
    break;
2 g9 s% C" v' U. ~    }
8 n$ b4 Y" D" z& r8 _7 @- |. Z    return TRUE;
3 Z- ?3 t: J( W: u* }, Y0 Q% z}) C  r1 L& e; A: |/ B6 T5 Q
6 z8 i% o: F; v$ r, O
#endif //USE_SPEECH_DLL1 `- `/ k) M& r$ c
8 w1 g& h$ E* i' I1 Q

+ p! E8 H7 f- b6 f: Y. ]1 t1 |/ }8 M, M' N. H0 X
///////////////////////////////////////////////////////////////5 |* ~& F; a; q+ Z- X# f

8 ?4 Q. b0 D6 e' W# O1 t1 e3 s////////////////////////////////////////////////////////////////////0 P& E0 _' |. e' |9 q) u
//功能: 弹出一个信息框。
2 _4 e9 ~+ b! U4 x2 _4 v' J' Q& v//参数: lpText:是对话框信息。lpCaption:对话框标题。$ X' m/ O( V) b2 T# a; K
//返回值: 无。
# Z- R. [; F7 z. _  `2 L: R/ o////////////////////////////////////////////////////////////////////
3 o1 J0 p- I: }5 J) y  ~4 J9 ^inline void ShowError ( const LPCTSTR lpText = "ERROR",
0 x; X( O. \. o5 e, u0 {        const LPCTSTR lpCaption = "ERROR" )
6 N  V' `9 L; t{) \7 ?6 U5 \1 G6 \% n
   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );' U* ]& g) g; z4 p9 g8 B% P- u
}0 u8 B+ F9 |! m/ v/ A  Q! c. ~
$ m# b4 ?7 W1 ?/ [
////////////////////////////////////////////////////////////////////
7 O7 b  A, g' C//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
3 e- w9 S& i8 K% {//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
' u3 e) J& F2 }//    lpCaption:对话框标题。
; h( D* o+ |/ A/ I# v//返回值: 有错则为FALSE,没错则返回TRUE。9 x2 Y" r4 K7 \/ d; v' _* _
////////////////////////////////////////////////////////////////////
: b! H' Q0 ?# s. }$ K( Z' I' B# ninline BOOL CheckHr ( const HRESULT &hr,1 z8 z; ]1 i% T  A! a
        const LPCTSTR lpText = "ERROR",( v8 j4 Q! Z& b7 F" _* w7 @# ?
        const LPCTSTR   lpCaption = "ERROR" ): g* A6 f- x7 _0 X! e4 o$ ^' |
{
+ r& b1 J' q) S$ f" v: a6 ?' G   if ( FAILED( hr ) ) {: Q- V4 q7 [; n/ z
    ShowError ( lpText, lpCaption );
9 f% j% u1 i9 v3 g+ v( h4 S    return FALSE;
& ^; v2 L- P- F* v" i   }8 e/ h9 o4 g5 C, p3 d1 O# r
   return TRUE;* U) E: ]8 D# `( ~6 {5 d
}4 I: f- a' o, M1 K/ f% D; V
* L. {3 i/ L; j

1 p9 C& H, g( U' r1 r3 j" ]///////////////////////////////////////////////////////////////////////
$ ^3 \  ^7 u/ m; J- W///////////////////////////////////////////////////////////////////////# j2 y: M$ R( f* f+ r, _8 `  c
//
4 \" r3 `. t4 i7 S  d  j: ?//         CTTS2 T: ~$ ~  ~6 A
//
9 \2 k+ k6 j5 `# [* y: l- j# U+ q///////////////////////////////////////////////////////////////////////2 {! y2 g4 E* J# x5 |2 S1 K
///////////////////////////////////////////////////////////////////////
+ ]+ h. T( G7 u1 C& K! V
- u0 U) k  o+ Y$ Q: o////////////////////////////////////////////////////////////////////
9 O' b( M8 o+ Z1 q//保存关联窗口句柄。初始化COM。% D2 k1 l% s# \
////////////////////////////////////////////////////////////////////
: a- M/ Q3 L2 G4 @% ]% W6 O. XCTTS::CTTS ( const HWND hWnd )  m- M$ \4 ?$ h7 F5 y2 x) x
{. T; `9 W5 k7 ~; }8 f
m_hWnd    = hWnd;2 ]4 w1 e* c8 @
m_pVoice   = NULL;6 Q: p/ B/ ]% d3 _. Y9 \& y
m_pToken   = NULL;! H) o  u9 O, O8 ]8 o  |7 V
m_pOutputStream = NULL;$ y- {8 d- Y0 Z, m; o
m_pAudio   = NULL;
1 @5 |  g# Y+ b6 O8 g}% j7 ?+ r0 C* b  ?

( J* L1 w1 e6 w/ b( P9 H% ]$ n////////////////////////////////////////////////////////////////////; w0 ]  N- x' W. t& [
//释放所有对象。, R( V4 `2 H4 K$ l# i" f5 Y
////////////////////////////////////////////////////////////////////
" U6 ?+ ~  A5 K$ g6 {3 nCTTS::~CTTS ()
' X0 h# R) \& ^  J: L# Z) }4 i{
! E! Y6 p$ G+ [$ H2 s$ Z% Uif( m_pToken) {  ~# _4 g( I0 ~& z; _/ ^( A  E
   m_pToken.Release();
' d) c) g: j; e; t   m_pToken = NULL;
9 v; c! v2 V7 Q7 A}, F  J& l0 Z; j: ?7 I9 K
if( m_pAudio ) {! g$ K% E3 ?/ Y& _
   m_pAudio.Release();* O7 O( [) }, z$ B* q6 `+ z( l
   m_pAudio = NULL;6 Z' L+ b4 C& x% }" J) V  a" S
}
1 P. G; |0 E! n# n+ Uif ( m_pOutputStream ) {
! D* [- h: W0 G5 ~   m_pOutputStream.Release();! {6 H* u8 \1 `
   m_pOutputStream = NULL;
& Q6 c1 p7 Z9 n. [5 E}8 Y) O! [: K; V5 N+ ^( H
if( m_pVoice ) {& C! c/ A: ^" v- i! _1 b4 e
   m_pVoice.Release();* \7 P# X, V8 O" Y5 ?
   m_pVoice = NULL;* X5 h  ], n0 z4 g& n9 L6 A7 U2 p
}
, h+ v  ]# [" u" {}
& g. w$ h" w5 J# S2 ]! T/ X* u% U
: B2 O1 M' P2 y- ^+ N8 m% L////////////////////////////////////////////////////////////////////3 u6 e) T% E; r$ K3 o
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。( n& P/ x6 U6 z+ @% r* f& K
////////////////////////////////////////////////////////////////////3 e! b9 ?9 {/ i6 \* C  ~5 y
HRESULT CTTS::Create( const CSR * pSR,' @  q! _6 e! g: E% _) ?& g
       const DWORD dwLanguage )# P/ q8 v1 U0 E5 D
{# G( G3 C! \7 p& r7 ^. Q
HRESULT hr;
) Y3 g0 {  ^, |0 w+ x- ]  e2 Z) |hr = pSR->m_pSRContext->GetVoice ( &m_pVoice );, L/ j( i  g4 T# ?2 i
if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
/ k+ e9 G# K' R. V% B9 K/ E$ u2 a   return hr;' g9 y' g7 e2 Q. h/ e7 E( ?
}
4 w2 g# O2 s+ x0 A. T3 E6 C# B# u: I4 ]* ?) X' O. j& \' n' Y
SetLanguage ( dwLanguage );2 K6 H% {3 i: R1 z2 ?

5 V+ g* y  w6 U& \! Shr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
8 y* d/ ^& O1 ^5 _. `- o9 Sif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
8 T( S6 [- V$ a  N# u; M( E    return hr;% b1 X# ]. Y0 a8 f' I+ O
}7 k0 h: @% ?4 o0 D8 ^( H/ L7 `$ A
  Z0 J0 M6 J. N9 w
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
0 S# l% Q# z: C2 c2 `; f5 t& v  E//SPEI_END_INPUT_STREAM 表示完成流输出。
0 w* U: E7 p1 x* W0 T8 vhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
* t" c: |+ b% {+ C, A         SPFEI( SPEI_END_INPUT_STREAM ),
, W' U0 b8 c" J- K, B            SPFEI( SPEI_START_INPUT_STREAM ) |. @, [% W( {) A3 g3 {
            SPFEI( SPEI_END_INPUT_STREAM ) );
8 h! W( ^: A. Z& P! x, v+ N' ?- @) }( mif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {) a4 M1 y# p/ `3 z4 _
    return hr;
" w2 D* _  z  T4 F. s}
4 T6 @$ v5 O7 j$ U2 J" u0 I
2 ~; g% \# ~* w" ?: [. u//设置通知消息& Y1 _6 E* N5 F) D* n
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );1 j! e. v( J9 p- ]
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
( f" _9 w5 _4 l% w; m" A    return hr;: S% w3 c7 h+ k. D8 F# O
}
9 |8 m2 p4 M& O/ I/ P
6 X+ D& x5 k9 R- Y' o( ^/ \return hr;& f0 R7 t, @3 w) {' ~! y$ R
}/ L2 e' E1 l. R' B& ]8 x% q
- ^8 e' b9 U+ g& S) R) I/ \
////////////////////////////////////////////////////////////////////
+ z8 ], K# v6 E$ g//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。: K; W% h7 f' Q: u3 ]2 i/ }7 Z
//并设置兴趣,设置通知事件。
9 M0 i. j6 v% ?% ]////////////////////////////////////////////////////////////////////3 `4 J0 |. z1 f* @
HRESULT CTTS::Create( const DWORD dwLanguage )
5 t1 T& \, B! l6 P( J: S- G{
1 b- ?. F1 [7 b) y& x, U. GHRESULT hr;! Q9 V1 w% j9 K. ^. ^; z
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );. [( ?) W% Z5 E; Y. B4 X
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {' T- T) z% f9 Y$ J, Y* F
   return hr;% q) V/ ~7 \: {# }: q
}
  E# ]3 k0 }2 {# n5 L
; ?, k* D  v$ N" ]0 a4 P/ oSetLanguage ( dwLanguage );
( T' n( N+ A" O- |! K( ]3 {; V6 C+ C1 ^/ a# v2 ?0 @* s" O
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流* ?0 D: |- p  L5 }
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
: K1 o9 z  \! {  @3 j    return hr;4 w/ I  r* z. l1 Y
}& y: E3 r0 j& Z3 J
8 Y% I, D6 J& e7 b6 L
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
( S; z1 u) Z% T4 H0 [  e//SPEI_END_INPUT_STREAM 表示完成流输出。8 U4 E) S! N+ u# _; h, F4 k
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |- ~8 W  P5 K0 O: t) T
         SPFEI( SPEI_END_INPUT_STREAM ),( L0 T5 g9 d6 f( k+ d" R
            SPFEI( SPEI_START_INPUT_STREAM ) |4 W) c9 f8 a5 ~* w; j+ ]6 x
            SPFEI( SPEI_END_INPUT_STREAM ) );& l! _2 F& r! R0 u8 J
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {. O4 D6 Z' k4 T( w3 ~/ N) z0 m
    return hr;
8 y( r% n# n* x7 [  ?! }}
& v, _1 v# z8 K  z. B
! W; q8 M& X5 Y) W$ |" s//设置通知消息& q, _. d4 L# z) A
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );1 H# u8 C: {5 R3 D" Q
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
* ?0 J( a% U/ r' ?9 R    return hr;
% x  N% p8 Y: q; p, y) t}
7 r# F- U0 s3 L' D7 ]
- V1 C7 O4 K: }% {2 k5 E0 L$ Q( Areturn hr;7 O$ ^- H1 O: W! g1 L
}% ^1 L& o5 N, L4 x7 F
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件
3 L! ]. Z4 r" H  q, {- F8 v#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()+ u$ J0 k1 ?4 P- |+ b
{& h! n0 Z+ i( W, \
    ::CoInitialize(NULL);//初始化语音环境1 F  o) d5 B- B9 p! _
    ISpVoice * pSpVoice = NULL;//初始化语音变量$ d+ D/ c9 u6 V& w1 x
    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { ! v8 @. Y' I. J3 v, k* F3 Z
        cout << "Failed to create instance of ISpVoice!" << endl;
: H# S+ F: y- w1 j/ [        return -1; 8 {1 M) t' Q* e. c% o6 a3 `
    }

" ]/ D- R2 {% ^7 g    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
+ N4 G+ T% u, ]$ v    ::CoUninitialize();//释放语音环境
, o9 U0 K2 Z( n6 C6 q
    return 0;
0 i( r' T, R. K}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序4 A! G" {* `) b& c1 U! b) O) U
9 N- D9 @6 C; b. i; i
1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
) N$ e3 I+ X# i# d* _2 ]2 J* t3 i  Q, }7 _9 c2 ^; a1 a/ O
http://download.microsoft.com/do ... -US/speechsdk51.exe   : }, W4 \) j* _, w0 f$ n
Speech SDK 5.1安装包 (68   MB)     
# D; i$ v" w; dhttp://download.microsoft.com/do ... chsdk51LangPack.exe      ! P3 L7 `& E  }' T8 n9 ~! s5 F
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  : W( y+ E8 d8 Z
9 I* n5 M- [  y4 ]% D  b% P
2.下载后,执行安装
3 j: I( j" d9 ^6 t* N& g
5 e3 N8 Y' g& ~' V2 r" Y下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
1 l, f4 J4 e! S7 ?: s! O
- c# b" V( ~, M1 d& e1 [  Y+ ^3.VC的环境配置
  C5 N( f! p% G% C
% A/ |" V$ Z  n1 C% s3 m! h: m! B在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:7 @; N2 c7 \" B* z+ C( k! B
2 Z0 t% g& n0 w, F8 D
工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.- }# T. ]/ j( n6 Q5 m" b0 }% @
4 M' c5 Q$ x3 h2 S( J: h5 Q
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~" M! j9 p" e9 |$ {5 [
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-9 06:31 , Processed in 0.036090 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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