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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////: j3 t) m$ B' ?+ I" {# w" B
//1,生成动态连接库时,要#define USE_SPEECH_DLL,0 s& X. O: d5 D8 R; B: k* E
//      并且#define LANE_SPEECH_EXPORTS. y, n1 N9 B5 `. a! T, J, }% l
//2,使用动态连接库时,要#define USE_SPEECH_DLL7 W1 U8 ?8 \) \+ N# r: Y# K
//3,声称和使用静态连接库时,什么都不需要
1 d2 e8 `: _, H) y, ~! K4 P6 R6 T//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),
9 R( }: \. p( F% ^, F% P# N* `! }//      动态连接库就不用调用了。
5 K5 A$ i9 p' u1 F. w////////////////////////////////////////////////////////
/ ^. O  @) y: s#ifndef LANE_SPEECH_H: }. u4 ^8 ~& @; A* m8 m! l
#define LANE_SPEECH_H
' F& I( Z# k$ P
2 e! W  y" j, M+ \- W% i' x7 Y5 e2 m#include <windows.h>
. y/ R4 ^3 j0 [, H+ k, |#define _ATL_APARTMENT_THREADED# e6 J! k9 r# Z& ~) F
#include <atlbase.h>
: l+ c0 q& U1 C2 R- t$ V' pextern 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; D. M5 v1 K6 I. _% `( ?
#include <atlcom.h>
" d" J9 |3 t! W0 x  }9 X, \#include <sphelper.h>   //sapi需要的头文件
; \3 A1 W6 x* ^0 ]( U: ]. i: }
7 c3 |9 s+ y% z/ B* @3 ]//-----生成动态连接库和静态库的处理----------------
( ~9 `4 K9 j  o5 x( s; R9 y. b$ O#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
! N: Z  C1 W" [! ]- t$ m* N% A6 l3 c% G5 p9 i+ T
#ifdef LANE_SPEECH_EXPORTS
$ F9 u4 _5 E+ ?" D% u   #define LANE_SPEECH_DLL __declspec(dllexport)
2 ^7 g; u5 [) o+ C#else
5 w) ?0 F8 W+ k6 c1 c   #define LANE_SPEECH_DLL __declspec(dllimport)& B) {. r4 X6 \: A+ @3 ?3 D
#endif+ ]' u# Y$ a0 R7 H

  _! ?# I% z8 a6 T//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关  y# ]- k: Z( E% i6 ]" ?) T
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
2 L" L( f4 d2 P5 ~" g! z4 ~0 y#pragma warning( disable : 4251 )
. |4 q4 z5 Z# [% f- }' o
0 ?6 c3 l) t& d8 n1 k2 b4 ^+ q#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)1 o6 K+ U% f( D& ~8 x
#define LANE_SPEECH_DLL8 W5 @* j: ]9 z0 L' U8 [

) ]! @7 X$ F& c5 E4 u+ o#endif //USE_SPEECH_DLL
, k1 H+ B+ b! t# ^4 Z! u5 _6 P$ c1 z" Y, |$ V

; E% }1 S! Z' s! e) u6 p0 X//***************************常量***********************8 V! _" |) }# _( v3 L3 L5 S: N

  k+ S% u) E9 ]) p5 ^# X/////////公共常量-----------------
; W0 R, Y: I( a4 A+ C( C6 Yconst DWORD   SP_CHINESE = 0x0000; //简体中文.+ i3 C$ ~, C% L6 e: d, N$ K
const DWORD   SP_ENGLISH = 0x0001; //英语.
1 T! Z7 ~4 L1 z& Z3 e
6 g$ d% M* ?7 f8 {& L/////////CTTS常量-----------------, v/ n8 J; D) f/ q/ e
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
/ O1 m* x4 b- r) w
8 T# V3 G9 p! ^9 c/////////SR常量-------------------
" |% {* C" g" A3 o0 @6 |& Hconst UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。
; f4 x. n% f, P2 Z5 o1 ]const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
8 ]8 m) ^* O7 `5 j; o- L2 m5 B, tconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.; t" z+ S" c3 J- z4 i& _

" q9 \* m7 X: O# t6 ~//以下常量仅作例子用。
! V6 X" P0 R- A( ^#define VID_TopLevelRule 9000   //顶级规则ID3 Y' B2 s- ~* \: u* X& b$ I* l- h" w
#define VID_SubLevelRule1 9001   //子规则ID
9 s/ h$ O6 V/ j1 P, r! p( q#define VID_SubLevelRule2 9002   //子规则ID/ ?/ u/ [4 _8 g' H2 z
#define VID_SubLevelRule3 9003   //子规则ID
7 B4 {1 u8 q: y* s. Q( h. b2 g# K1 O: V& d5 j5 z$ V3 l

% M& Q4 O$ L: w/ [4 [5 n* {//*************************类声明************************
) M; [; d3 b) m* E
5 ^% Y7 l/ l6 h+ ?( S+ F/ p
' Y! v3 b0 }* [: ^class CSR;# j, L! r* Y9 l: f" n" B
///////////////////////////////////////////////////////////////////////% v5 }* J  C1 T3 S2 u
///////////////////////////////////////////////////////////////////////
  s" f) G2 }2 g! v5 Y7 a) R//% U8 h. \/ I0 i- A- Z8 W7 \3 `
//         CTTS
" P! J2 y3 s" \  {" t" A/ E//
! P6 S. d& T( ~- j///////////////////////////////////////////////////////////////////////  |% I( D+ v# f, H; |6 u/ I/ F
///////////////////////////////////////////////////////////////////////
8 a8 q3 X8 [/ k5 n4 [" F+ i$ \/ t7 X
class LANE_SPEECH_DLL   CTTS% U" f1 e1 C8 v: B( ?
{
( q+ E4 h; u! pprotected:2 v' Z/ J" U  @1 E
HWND       m_hWnd;     // 关联的窗口句柄。) Z) A3 G/ w5 f3 o' v* l  _
$ m* n# I1 w0 K
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。5 _, Q& H+ H& {% l* n& V
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
9 {' `% y- T6 p* ]. |CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)
6 F; I! w( W4 h" U7 sCComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
$ L; _3 D$ @6 J7 h' p3 q
4 i( @# N3 U/ J: A6 U0 xpublic:, `' E+ t, X8 j
//********************************初始化部分********************
6 [0 l2 t2 c0 l( w7 S% `; o5 _; W% p" h" \2 V  T
////////////////////////////////////////////////////////////////////( N* B' h/ ~* z3 V- Y
//功能: 保存与识别引擎关联的窗口句柄。4 M1 j* C  b) H# K( l
//参数: hWnd:要关联的窗口句柄。7 d/ M+ l4 @0 W* P$ ?8 s- t) @( F, w
//返回值: 无。
) U/ {7 I( O5 _////////////////////////////////////////////////////////////////////! @2 O7 X2 l" M# K6 Z  A3 H7 P
CTTS ( const HWND hWnd );6 _; ^- f7 _# K) @

5 ?& ^- C& w9 {7 G5 a8 K' f////////////////////////////////////////////////////////////////////( I3 y& N0 t. _9 l& Q6 I* b
//功能: 释放所有的对象。- H/ e. Z8 K6 s5 h2 `
//参数: 无。! a/ u# Q/ B3 J  \
//返回值: 无。
5 Q% ?0 Z5 L1 C" u  t3 b////////////////////////////////////////////////////////////////////
: _# D8 Z1 S- s# W9 O4 k/ H' H! |~CTTS ();
6 r2 I6 e( ^$ l0 ^/ U, C8 t2 S( i: T4 d1 B, h$ ]
////////////////////////////////////////////////////////////////////
: v0 s; h4 ~6 N$ X% ?+ t//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。
* R/ H) o( C6 {//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
/ w5 S. N2 C  U4 R5 J9 w+ C9 @//    SP_ENGLISH为英文。: ?. ?+ y7 H. R
//返回值: HRESULT类型。. Q7 i5 g$ J9 L( d( Y* r# J0 {
////////////////////////////////////////////////////////////////////
6 u4 i  D! ?$ n0 Y: t. p9 j7 gHRESULT Create( const DWORD dwLanguage = SP_CHINESE );/ X" F/ P" S, z% O: [

% v5 x( d4 z$ J////////////////////////////////////////////////////////////////////
; c; P; v3 S2 M# S; Y$ j//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,/ M7 E/ p/ {7 W4 X, O
//    通知事件。* I: @$ m! J. g* Q
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
7 J, L, q" H% p, J2 N. F//    SP_CHINESE为中文,SP_ENGLISH为英文。
! F7 \9 y* D3 @/ T//返回值: HRESULT类型。
3 Z/ z; i/ W& ?6 Q7 {& h* P////////////////////////////////////////////////////////////////////) @7 K5 u& q* r. b. C. L
HRESULT Create ( const CSR * pSR,
2 `; m$ i, ]. V       const DWORD dwLanguage = SP_CHINESE );
, Z$ S8 l5 c: ]+ B! ^# v4 `( |4 x) Y6 c% _
* \3 f  I' U# F6 E# V+ Q4 M
//********************************设置部分***************************************
/ f; x; {/ E/ t9 q) s! i, `
2 Z: t8 E. h* c3 ~8 |///////////////////////////////////////////////////////////////////// C- P! m$ ?: {
//功能: 设置朗读声音的语言种类。  D$ _$ _4 H2 m9 P% a' b9 ~
//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
3 t" P4 G: r& G//返回值: HRESULT类型。9 U; n* ?7 U! N4 A1 [' Y
////////////////////////////////////////////////////////////////////
7 ^8 [& ]( T" ~0 J$ _! \2 f$ RHRESULT SetLanguage ( const DWORD dwLanguage );
7 _" U+ R8 T# n. h) z2 p% i/ B/ A# v6 M$ Y3 I: t$ r& M
////////////////////////////////////////////////////////////////////
& c8 u+ b; U" i; C. T, W//功能: 设置要处理的的事件。
, V# @% L7 y' w( R6 t, a8 \* D; o+ s//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,- a9 `2 |: @) u9 E
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
. u( _, p; r" F9 p2 d1 E//    件都会收到通知。
! O! G; n6 L0 g) L3 Z, B; y5 m; b  r//返回值: HRESULT。2 S4 b8 o! I; C7 f% a' ~
////////////////////////////////////////////////////////////////////
0 g5 Q4 o* k, d6 f- wHRESULT SetInterest ( const ULONGLONG   ullInterest );
( X: c7 {% `. }. e% s+ _7 C, M* p
////////////////////////////////////////////////////////////////////
" D5 n6 R: F8 L0 D$ u5 i" d- h//功能: 设置朗读声音的音量。& C0 g; a3 \0 I* P( @7 _2 B
//参数: usVolume:音量数值应该从0到100
8 l* s2 j, |4 S9 `8 N- z0 r6 }1 b//返回值: 无。" D' y6 l) z5 H7 s* G" U! f, H( D
////////////////////////////////////////////////////////////////////- v. Y0 T) m4 l' U
void SetVolume ( USHORT usVolume );- m' \" c% g6 u

6 g! `3 e7 G8 n& v% ~% s////////////////////////////////////////////////////////////////////
2 ^0 ~- s  W7 d" r- `, @//功能: 得到朗读声音的音量。  @1 K- F7 f' ^! {
//参数: 无。
0 A5 B. U' Z( B! P- n) z: T//返回值: 音量数值,应该从0到100。+ p* S( U# j7 Y& o
////////////////////////////////////////////////////////////////////# x8 p, d$ s) X4 U  t  `
USHORT GetVolume ( );
. K4 m0 N- j" L5 h) z  A; v
+ k! X: B8 f* Y( W/ \4 |5 y' O////////////////////////////////////////////////////////////////////8 E8 H7 _2 x+ F0 h6 O. }
//功能: 设置朗读声音的音速。* [4 D' x! F  B9 `6 Y
//参数: RateAdjust:音速,参数范围从-10到10。
0 X$ l5 d( z& ~% u1 w" Q//返回值: 无。+ G9 `. m0 U& W* G  o/ ^
////////////////////////////////////////////////////////////////////
. D' E5 m* O6 |) ?, R% @) n9 K, cvoid SetRate ( LONG RateAdjust );
2 t8 ^7 A/ G, m
4 G  X, J* I. r0 s////////////////////////////////////////////////////////////////////
5 Z# i1 ]+ D. O, B& f3 \% U# ?//功能: 得到朗读声音的音速。
: e, n. o3 a3 d//参数: 无。3 K7 @3 ?. ]% G0 G: ?$ t
//返回值: 音速,参数范围从-10到10。
; ?: i; `) ?( \, t: j4 P) Q! b////////////////////////////////////////////////////////////////////0 d- q) c0 v+ T) z3 c) m5 M, a% {
LONG GetRate ( );
9 T! [2 _6 f3 A6 }% V- _: s+ M, u1 U4 u
////////////////////////////////////////////////////////////////////
* w5 W* U# F! L0 w" Z4 s//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
' k- b; u- S! Q* i; @8 J//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。% W! E( ?/ F7 p9 I. |4 `4 W% ~
//返回值: HRESULT。# w6 x& f1 C! j- f8 `% ~" O# ?
////////////////////////////////////////////////////////////////////
% J6 p& u. I! A0 d1 Q' L8 jHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");( h) g, k% c; a% {

  a6 P1 a; R0 p# Z, E////////////////////////////////////////////////////////////////////
2 A' T; e( X& }//功能: 设置朗读的声音从音箱输出。
; G4 y- N; N. }5 E; \5 o//参数: 无。
; U& w3 D6 d. A5 ^* ~  g//返回值: HRESULT。
& S% k2 f# M4 g1 f////////////////////////////////////////////////////////////////////% G0 L; ^$ ~/ k) i, a" [
HRESULT UnSetOutputWithWav ();
: x: S$ L- ~9 q4 q& }1 w8 ^# s' B% ]# v. A) Z! o3 \

, M+ H+ R0 J" v, C+ f//**********************播放语音,文本到语音转换部分*****************************
' ], E2 ?- I8 {# |) Z. L. y0 V
, u3 w7 V5 A/ t# i////////////////////////////////////////////////////////////////////3 u, D2 p! W0 M# S3 v
//功能: 停止朗读。如果朗读为同步方式,则不能停止。2 ]8 ~& ~# n7 p2 N: n+ `+ H: N
//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记6 {3 b, I* X3 A
//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
2 W5 L3 e! W% v//    SVSFIsXML为朗读带xml标记的文本。
1 @2 a0 N& n! M* m3 R6 b//返回值: HRESULT。
2 g0 e* z8 [8 _  p5 R* k- c# W////////////////////////////////////////////////////////////////////
+ G/ T/ Q  h# X+ z, g( T% xHRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
. {5 ]+ P1 F5 y3 `
# Q* A- o3 N# X" N4 [5 \6 o///////////////////////////////////////////////////////////////////// ?4 D: P' B2 J9 p* |) Z" v
//功能: 停止朗读。如果朗读为同步方式,则不能停止。& W* q0 S, P! i  H; }4 Y! ?7 d2 t7 a
//参数: 无。
5 i# Q. `" |' r1 D, y4 a//返回值: 无。  n4 c/ h6 h4 z6 s
////////////////////////////////////////////////////////////////////
/ J" ^: z- h+ h- bvoid Stop ( );
8 [6 p+ Y3 @( U4 f1 S; v1 a) ?: Z' l4 k6 i) z  k2 v4 c& ]
////////////////////////////////////////////////////////////////////% W7 `; P& m; k2 e9 o6 n1 v
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
. _9 ?# x& l" e//参数: 无。
* q) n- a6 |8 r! T//返回值: 无。
" `# [/ ^0 E/ W. ^- W+ c////////////////////////////////////////////////////////////////////4 N4 V5 ]5 R2 F; b
void Pause ();, g7 m7 p$ ~+ }* j# k7 u3 Y  z

( ]! x3 m, a. w7 E& d/ ]////////////////////////////////////////////////////////////////////7 ?1 n% v% s/ I0 c( F8 ^- m! V
//功能: 从暂停的地方继续朗读。8 k& s. T9 {/ ^7 S7 ^
//参数: 无。5 M- o/ |0 O7 a2 }, w
//返回值: 无。' `$ B( S+ x, w) F
////////////////////////////////////////////////////////////////////5 P* f1 J: o5 @, t" q) b; B' X( D
void Resume ();7 g. P6 u9 C2 k) G

; Y1 L% x: `1 c2 q8 t
) o  g' q% `0 g//********************************处理事件部分***********************************9 _8 }) b9 E, b) Z/ E

( e. A4 r; j; npublic:# S( s6 n" J& s: {+ a
////////////////////////////////////////////////////////////////////
  W0 B" `+ L# d7 I//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
6 [' I! b' o; _# W3 a$ [: {+ @//参数: 无。
! d( D4 ~! r- a- p# m1 m//返回值: 无。
% e4 l. l  C) H, X4 w2 E. w////////////////////////////////////////////////////////////////////
) w* b% m( g- V% S) Y, ?void ProcessTTSEvent ();5 S; ]7 k1 h) e9 P

. j! F; Y7 u0 {& t; C, I/ j* ^$ u" l5 f3 T
////////////////////////////////////////////////////////////////////9 Q: G& G% Y. W) \" b
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
4 ~2 A+ n- P3 }9 ^! I0 P//参数: 无。- g& V) K# ^5 z6 V
//返回值: 无。
* ~# w' W% M+ Z9 S////////////////////////////////////////////////////////////////////1 U4 q- c. |# X/ U% |
virtual void OnStreamStart ();
2 u! x: u( u' B5 A- q* |3 O8 H
/ i) }6 b: P: W+ |5 `( I' b. b& i////////////////////////////////////////////////////////////////////7 j0 P& O2 K2 r
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
- P( h& }2 k5 C6 O5 _8 b2 o% y//参数: 无。8 E+ B# ?- N7 s$ D' h4 _
//返回值: 无。
( \, K. C/ W/ B# d2 D. A////////////////////////////////////////////////////////////////////
! f9 m: L8 B  w# |$ Z& A- pvirtual void OnStreamEnd ();
& P, w& i9 E& i# r. t};
9 m8 H1 [$ I3 k2 W
" ^8 a+ P, k4 D! r
) R, b! E% a5 {% I+ C) [///////////////////////////////////////////////////////////////////////' _' L5 H# Y2 Z
///////////////////////////////////////////////////////////////////////
+ o9 ~3 X4 z! ?( |8 T//         CSR1 i& f5 k# Q- g6 j3 n( n; O* A: b6 ~
//  U8 @8 ], v. Z1 ~% f* F
///////////////////////////////////////////////////////////////////////
4 K9 e. g8 X  a" k7 r  e///////////////////////////////////////////////////////////////////////7 K6 _, P8 |9 u7 j% g

( D) v2 b- m  p; iclass LANE_SPEECH_DLL   CSR
" p) W8 q8 u( H{
# N% P5 ^* U  M, u  y" p* v& x2 k% t6 |  `; @& V2 S# o
protected:8 u* E* m, D+ v& ^& H
HWND m_hWnd;- S1 c* Q/ o$ P5 ?
1 ]$ ^" N; j% t1 ?  o( g; E# Z/ o8 s6 I
public:
6 t- S7 q( @" m7 l2 ACComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
% a% x: W" o# b4 U3 [. sCComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
1 N8 |- B! \, I! qCComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。6 x% M5 Z$ F* I( ^: l: g
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。
/ T. a7 j, ~: Y. M; y6 vCComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。
8 L% `; m" r# F; b6 q5 ?' }' hCComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)( ]9 Z5 M3 b9 @  I3 {. v! Q" Z
public:
/ R) X9 T8 B6 y6 c9 Fstatic ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。7 z; p1 g* v' [2 G" N
9 E* L8 I# j* C9 S
3 _& T5 U( B+ d: T0 t; ~/ \" U
protected:  ^7 M: s" y* F7 A( B- Q
//***************************辅助功能部分****************************************
3 p( Y) a- E) g* y/ h$ k( _$ |7 Q1 j3 r8 z+ ]. M% p! c3 o; W+ x
////////////////////////////////////////////////////////////////////
9 ?* c0 s9 l* [) q: a- G//GrammarID加一,每个GrammerID必须不同。" U5 I; P$ z# x5 r. b, T
////////////////////////////////////////////////////////////////////( I3 n. }* S) o8 U, j
static void UpdateGrammerID ( );& I" o! L. A" Z/ o

6 J( I, Q8 z, \" s& Q' b6 R5 W" Q8 B- d1 A1 g2 \9 R. @
public:
* Q! h; d% h& l$ w////////////////////////////////////////////////////////////////////& ?$ ~, ?% u6 |" ?
//功能: 友员。TTS中的从SR引擎中建立voice对象。8 T3 H5 \9 c$ v! E( V
//参数: pSRContext:SR上下文对象的指针。. j2 [6 Q) S4 Q( O2 i9 l* [$ J
//返回值: HRESULT类型。1 j7 L2 O6 x# I8 W6 I1 x
////////////////////////////////////////////////////////////////////
( c: t5 U4 Y/ F$ U7 ]4 ^friend HRESULT CTTS::Create ( const CSR * pSR,
& G! d( ?; e* |/ I          const DWORD dwLanguage );
. i5 o- X  u2 C5 r: v1 n1 t2 z( Q$ C; h* b. w

/ |) I0 ]8 i2 X2 g' k& g' T//****************************初始化部分*****************************************) f! d" u7 z3 d# _- y2 i$ h) ~' f, R

8 D- a# s/ C. ^- v+ s2 L////////////////////////////////////////////////////////////////////1 v6 C5 i' c: K. V/ b% @  p7 q- Z9 A
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。
/ ~# u5 |2 a8 L" ~' \& A  k" ~//参数: hWnd:要关联的窗口句柄。2 o* o( a9 ]* D* l( L" i0 {# ~
//返回值: 无。
; {# C! n9 O5 T////////////////////////////////////////////////////////////////////
! k  u( M" g1 J; s2 ]CSR ( HWND hWnd );
, `8 R( j' a0 B9 J4 M' m9 z% L; O" m0 ], {. v. y6 W
////////////////////////////////////////////////////////////////////+ s8 D' }9 p  I3 y/ I
//功能: 释放所有的对象。
0 e$ `4 `# O: _. I% t//参数: 无。  p, k4 H6 D) k
//返回值: 无。* }0 R) X, c) j8 Z4 B
////////////////////////////////////////////////////////////////////
0 f6 H) b& k: o8 x' O/ @~CSR ( );
% |' |) d; w1 a  m+ \
- m  k9 N! g# o' ?+ W" b////////////////////////////////////////////////////////////////////
: l0 ^  a5 n' @6 D! G& g6 O//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,# G9 h5 G' ]* K0 z5 ^
//    加载文法文件。( U) d7 _. N& F& V4 W' a/ }
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
7 u% U0 G/ B, a+ w: u2 K4 i; ~- i' |//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。. `$ J; F8 u; G1 {+ Q+ Z
//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。$ Q$ K8 a/ w! e" k; u
//返回值: HRESULT类型。  k+ z5 o. [# @' H( o
////////////////////////////////////////////////////////////////////
. [( O& e- N1 D+ jHRESULT Create (const DWORD   SRType,; e+ x/ N+ c- r4 B5 v( Y
      const WCHAR   *pwcGramFileName = L"grammar.xml",( c# Y8 N5 D* i2 T' {7 H0 e
      const DWORD   dwLanguage = SP_CHINESE );
3 `" K4 ]: N* |! d6 \0 M: a' S: s- o1 F" b: s( g1 z

0 h3 z! H4 s/ \$ T; X//**********************************设置部分*************************************; u3 R) h) ?$ l) R, J) \
/ W8 I0 u5 [8 _: S8 Q" ~7 x
////////////////////////////////////////////////////////////////////
: h  Y  V+ d1 @) S//功能: 设置要处理的上下文接受的事件。: M% k, e' B8 Y- h
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,$ q! I  K9 \# o0 Y% w+ Q' b
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
1 S/ l" C  y% G2 `& {//    件都会收到通知。
5 a+ h; F9 R; t6 O//返回值: HRESULT。
3 m1 D4 M, t0 T- e1 o9 ]////////////////////////////////////////////////////////////////////
) H/ L% R% G' i7 _HRESULT SetInterest ( const ULONGLONG   ullInterest );5 r8 ]4 F9 f3 D# ~

3 P( E  S& A$ d5 ]////////////////////////////////////////////////////////////////////
8 j& v5 f1 d4 e4 v//功能: 设置某个规则的状态(激活或者取消激活)。
. Y! n* F! W0 L* |//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,: l$ ?6 Z# ~6 G7 a* I5 u: i
//    FALSE表示取消激活。
5 M/ f# W$ z" Y  y( d- E* N& G0 F//返回值: HRESULT。
: K5 V6 _' P  y. ~" }+ K////////////////////////////////////////////////////////////////////
  |0 o% f8 {; f: K; c+ T& H! XHRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );" w5 F& w; s1 w4 g* _, W

5 @6 m+ J3 e. K6 q6 y% V8 O) Q+ }+ z3 [# }9 D& K: e: I) B
////////////////////////////////////////////////////////////////////7 ]( u% X8 ^) l% m7 A" \8 t
//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
! ?* H2 e+ z6 j0 ^+ s//    风输入。
. T$ Q, E7 {8 }//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。( ^/ B6 C+ ]$ j( g/ K# ^0 q
//返回值: HRESULT。- Q6 t4 y) |; h. }. W: C7 ~
////////////////////////////////////////////////////////////////////2 U2 |8 h1 e* I
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
5 h* K  b# D- y2 Y; h' H/ r& t4 V# U& C# L+ C+ _( c( p
////////////////////////////////////////////////////////////////////
+ v+ e; [* w0 ?! @& W* C" K1 V//功能: 取消从.wav文件识别。恢复从麦克风识别。
1 ?3 ]& M, X# t2 f- s! n. p; }//参数: 无。
( J  ~5 c, g3 Z9 @* K//返回值: HRESULT。
( P( ~0 }3 q; z" j( d, M* r////////////////////////////////////////////////////////////////////& ~1 x! X# p# \. S) _
HRESULT UnSetInputWithWav ( );
+ r! S, @( w/ |& t: r8 V" `3 H; |- v: R0 M6 o3 Q
//***********************识别开始,结束,识别结果的处理**************************: Y/ k) ~* ^( z

0 C+ s" G0 a' ], g- j# x////////////////////////////////////////////////////////////////////
7 t/ ?- b! _- M$ C: Z/ ]//功能: 识别开始(将所有规则激活)。
9 _$ s4 k% f) Z7 A8 o" {0 Q9 q//参数: 无
! e  M* N/ u1 d' H; X  `2 A, X8 {//返回值: 无。
1 {2 h9 Q% A; l; I////////////////////////////////////////////////////////////////////
) L/ ^7 _& `9 z+ L' Wvoid StartRecognize ( );. M) m' s0 ]9 R$ Q) a; Q  r) ?) W" e
0 v( l5 }; `2 s6 b* T" P& ^
///////////////////////////////////////////////////////////////////// P) O$ j/ c3 L7 k; p# ^" y
//功能: 识别结束(将所有规则取消激活)。" c- s. t- x8 P1 z2 k/ C6 P" u# U
//参数: 无。
  }4 E/ X1 F8 W) t//返回值: 无。. _- O4 G- K+ e3 |
////////////////////////////////////////////////////////////////////8 p% F0 ?' F, S" B3 ?% C
void EndRecognize ( );8 p$ N9 r8 x$ l# J! l

2 F: b. _8 Z8 M0 w) o% p7 epublic:: c: x; r3 W( R* t5 ^! k( t" ]
////////////////////////////////////////////////////////////////////
7 P7 @2 _1 O; l//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
% ?* j4 Y4 f3 m7 G/ ~8 U//参数: 无。
* c* Q* L2 s- ?. Y% K//返回值: 无。4 Z+ E" J/ y/ Y/ I2 |- C4 O
////////////////////////////////////////////////////////////////////# D" `% c" l# u* Y" P# @
void ProcessRecoEvent ( );
8 n0 Y9 L8 i% e7 T3 _1 C) z  Y5 d5 I' w9 Z* T9 K: d8 ~
protected:
: B) z+ J! {5 Y: V; _////////////////////////////////////////////////////////////////////% E6 J' T( M/ a, a. O! B
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。$ V$ w0 f8 Z$ Q. ^6 e# ~
//参数: pPhrase:ISpPhrase类型。
: T& {! X& E5 k/ L$ G7 L$ `//返回值: 无。
5 z0 s+ a  L: S3 c////////////////////////////////////////////////////////////////////# x5 v( n* w; p6 R5 D# H, A
void OnRecoSuccess ( ISpPhrase *pPhrase );
2 v! H! V6 X0 k) f0 Q7 a, [0 s! X% Q) l0 }5 O+ c
public:8 U) x( ~5 t! J  c' S: B+ e
////////////////////////////////////////////////////////////////////
* J. N6 a" e( }5 Z3 `//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
* X( E) M" X* \# E: V//    需要在派生类重载。规则ID必须以常量形式预先定义。
8 s+ l/ v8 j% }2 c  q8 {//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
4 U+ {6 X- _- s; r) u//返回值: 无。, R! `9 _& L  `6 n9 F
////////////////////////////////////////////////////////////////////. n  P1 m3 g% G* @. W: E
virtual void ExecuteCommand ( const ULONG ulRuleID,: t! g- T4 w) z! o, R  L
          const ULONG ulVal );
% N: s- w2 s' f7 X; t, z! y  R# `) j
////////////////////////////////////////////////////////////////////# V! ~! }' {, `, j% b+ v; h4 J$ N5 p
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。1 D9 |' h6 \; y$ b
//参数: 无。
4 Q8 |, s0 ~+ p//返回值: 无。
  H* w" \/ _- I; O. r////////////////////////////////////////////////////////////////////
1 O1 G. y' H( v9 ?4 g" `# `9 Zvirtual void OnRecoFail ();
& h4 Q  z) b- j8 H
0 `4 N* U4 j+ h( B% H2 A////////////////////////////////////////////////////////////////////3 @4 G, Z0 u' D& I- g; n' P5 l! }
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。- H  ]1 e- ^" C, a
//参数: 无。4 Z8 {: z9 B8 ?) W7 x
//返回值: 无。- Y4 \" E4 S- T0 m; `4 ^9 z
////////////////////////////////////////////////////////////////////
: a3 V3 {2 `5 e: h# S0 N7 C% yvirtual void OnStreamStart ();9 r! _4 [: U3 L5 N, b
2 [; Z7 D1 J7 h* I  ]/ a
////////////////////////////////////////////////////////////////////% K+ ]) Z) Z& i# }! M
//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。& V) g5 ?& V$ |! f
//参数: 无。
2 W$ O! F' g9 \, K- ]* `3 X0 n5 O//返回值: 无。6 s; Y- J8 P" \; V& ~! \/ O" }1 c
////////////////////////////////////////////////////////////////////. n! V2 ?7 D! C
virtual void OnStreamEnd ();* @8 B5 M3 R2 T3 \2 V
' a9 |* a) l) Q2 m  R% d
};# o4 f) S; o! ?) a2 P/ `9 s
; Q4 m' \1 N4 |% w/ [

# u/ G! K# z7 x+ P9 O1 u( A/ b; A5 O+ [3 c/ y" X! b2 d
#endif    //LANE_SPEECH_DLL_H5 h# A$ _" V2 Z3 [  V0 C

* B, O8 K7 ]. ]8 ?3 a///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
. [. z. l2 D% L1 I- `" O$ @, P2 J# o
////////////////////////////////////////////////////////9 w5 G' L! Z6 t3 r6 g; D" P7 x; [4 F
//
' X2 ~" J1 E) |1 w+ b9 Y// 文件:LaneSpeech.cpp
9 y* |5 E/ W6 P, q/ f// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
% N# [9 K( f% a# B//    语音识别只支持命令模式,不支持连续模式
- G$ W3 y" `, T// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
3 g6 l6 n) D* o4 S& g5 e// 日期: 2004.10% U- P, H- R2 ^8 s- r" K: F
// 版本:1.25 E- y; W8 X7 a4 U; }$ C
// 9 E/ D3 u; K, \" g8 d! A
//( Q4 b3 R* |3 O; t
////////////////////////////////////////////////////////
5 i/ A' B! t& u: Q8 k* z
+ h/ R: I8 n- w" V7 {+ r! m9 @, B$ ?  f/ S% ?
' C& m& s; V' Q9 M4 r6 |- e
#include "LaneSpeech.h"
9 X& d4 f+ `0 P6 s0 }" D2 ~: Z
5 L0 m: R8 `6 ?( p. ]9 ^//-----生成动态连接库和静态库的处理----------------
4 |6 f+ ?8 \  l: [#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类  F( ^+ o1 [5 n1 W) E( Z0 X( |
  X3 d7 O2 T0 K
BOOL APIENTRY DllMain( HANDLE hModule, 9 [- A* b( \2 \  O  i$ q
                       DWORD ul_reason_for_call,
" P" p  _' K  P  `8 w' g% N- ^                       LPVOID lpReserved7 k# P% s% K/ C/ x) a& ^
      )
7 Q# P* I/ m4 `" M) n{: E; J1 q- W3 P& D: C7 t$ V0 E: O
    switch (ul_reason_for_call)8 `  a$ t/ i$ C, C2 }# W
{
/ g* w1 _) R* T  ~- P   case DLL_PROCESS_ATTACH:
5 ^5 m4 r4 s' \/ v: v) s0 u$ k    CoInitialize(NULL);
  B! H/ i( q7 W; M- j5 a5 p6 V; M* r    break;2 `, r$ d2 `+ o* G, N! d. ]
  
9 E7 F9 c, ]3 A; x4 r7 Z5 }   case DLL_THREAD_ATTACH:
+ n9 m6 N; B1 x, ~    break;0 {( U4 p: v" T, t3 l
  % U& K  }$ h. \" i
   case DLL_THREAD_DETACH:
7 e1 R- K3 A- q7 ?( f- g( L0 N    break;; D! ^+ e" O  L7 Q# f  k" }
  ) T% c6 H, F) D
   case DLL_PROCESS_DETACH:6 A7 D- ^4 L' K
    CoUninitialize();
7 e& w, [/ t3 I: P6 T) Q    break;
; B4 [# _1 M; l, Z- X0 n! ]    }
+ v# S% `" J% I- y    return TRUE;
  d2 O- ~7 o/ J! ~' c3 P, T. k}, D2 b; |5 e# A

: K. U9 [! W, G4 t7 _#endif //USE_SPEECH_DLL. E: F7 m- J, G$ l# }

$ s2 p5 M  U/ u& o6 J! q6 k: K4 _! v, \$ O) Z
. [. G  p6 F+ o7 c
///////////////////////////////////////////////////////////////
9 i* A; `/ \& F. i/ e  u: [/ W/ w2 @4 t% i& Y* F2 i* Q  T3 v
////////////////////////////////////////////////////////////////////- [7 G! ?# `  C8 R1 n; L
//功能: 弹出一个信息框。" _  L8 [; a1 A2 \( Y
//参数: lpText:是对话框信息。lpCaption:对话框标题。6 b; \) ~, y: ?! {" g, N) Y
//返回值: 无。$ g# E1 ^7 o  n: C+ W
////////////////////////////////////////////////////////////////////
, ]0 t. M6 v6 r7 K" P. a& q; ~inline void ShowError ( const LPCTSTR lpText = "ERROR",
! l# G- ~9 Y; S; q% }7 K        const LPCTSTR lpCaption = "ERROR" )
, w, R# P+ x0 q0 H" s$ D{+ m: A1 M+ H) a, o4 b' Y/ r6 X
   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );, D) a  W2 V6 Q; `6 c% j
}
. S' j: e( ~& D$ m! I2 S0 y
& D, m- e! G0 P( K8 Y. \////////////////////////////////////////////////////////////////////
) X, N$ n8 b9 Q+ Y$ `//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。1 S- G& }7 J4 k3 [9 E
//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。" N* I2 }3 _; q5 a; \2 \
//    lpCaption:对话框标题。- X- }+ S: e( y, K. z
//返回值: 有错则为FALSE,没错则返回TRUE。8 n- i  v/ G$ y9 O+ [5 D8 y
////////////////////////////////////////////////////////////////////. H. B, m  w$ X  ~: P  P. p* T
inline BOOL CheckHr ( const HRESULT &hr,2 v( P/ P) c5 H7 L' ]% t
        const LPCTSTR lpText = "ERROR",. C5 y6 N' l% E" I1 b; _% Z& B# j  M
        const LPCTSTR   lpCaption = "ERROR" )
/ Q: {) f6 v, D( m, h' B{6 Z1 u8 e) t4 S. L
   if ( FAILED( hr ) ) {( ]( O3 R% V2 l. e* b+ W5 m
    ShowError ( lpText, lpCaption );4 {5 ]: k8 F8 O! h, F0 E  `
    return FALSE;( q& N6 E, p) y2 c: F3 H! E
   }
* F9 W: J, q/ t# p7 a   return TRUE;- ^8 @1 [3 n2 d( s
}; }+ i$ l6 G8 {! D/ `! L

: z" `: k* F4 `: Q. o
; p7 ~& f% p" Z8 ~# e///////////////////////////////////////////////////////////////////////
6 [, ~' w. U/ P; s///////////////////////////////////////////////////////////////////////
- C7 d3 y/ M* g- B6 X! E# d; f9 Q//5 u* m5 r. p9 }
//         CTTS. B% A) F0 N) b1 m# L0 n( k
//
3 ^  ]/ v% g5 G* I- B: {///////////////////////////////////////////////////////////////////////
. t4 A6 [$ [. C$ J# d///////////////////////////////////////////////////////////////////////
  U3 S2 H' _3 J+ O  y. O1 M
1 D) E4 V" ^  a1 d, j* A* A////////////////////////////////////////////////////////////////////  Q9 l  K) m: i1 k
//保存关联窗口句柄。初始化COM。) s. h- L* X2 ^- S1 k
////////////////////////////////////////////////////////////////////
- F2 v1 f- O0 O7 h1 l' mCTTS::CTTS ( const HWND hWnd ); M1 v. c9 x! e
{; `0 N9 [  f) e% S- g3 O" f; w3 l
m_hWnd    = hWnd;
/ |- c2 V, p+ Z$ G& E3 N. B: i. r+ f/ fm_pVoice   = NULL;
( z9 R- F: X) T- ~, f# Y; Om_pToken   = NULL;
) G4 K4 u& C" ~m_pOutputStream = NULL;
, y7 A" u$ F$ qm_pAudio   = NULL;- K' B5 w! U! c3 z5 S
}/ m; n' y7 X1 a' \2 b+ p, K, ]
7 q" R* Q3 V8 M% V: Y, O7 ]) x
////////////////////////////////////////////////////////////////////& ^6 h% |/ b' t0 B/ `" p
//释放所有对象。" W9 K8 D7 I* @* T, X
////////////////////////////////////////////////////////////////////
7 n: I$ E9 Q5 @: ^- w$ W# LCTTS::~CTTS ()
( p  ?! e# x$ b8 L* c. `{# t( z+ w, h* M7 r% d% B
if( m_pToken) {% E4 _3 l4 H% L# P6 T" p
   m_pToken.Release();
7 ]4 B) p+ _" E9 w6 f4 _8 G   m_pToken = NULL;
/ u4 \9 J. X% r1 a7 y  ?, D}5 x9 w  O# K* [: T* b* V
if( m_pAudio ) {
& c9 O6 j; w. u& {   m_pAudio.Release();
! {& ^  `" D6 x: m! v   m_pAudio = NULL;% @" l- `7 Q9 i+ _) v
}' N( s) V1 [, g& J
if ( m_pOutputStream ) {0 x6 c, ]+ r* S
   m_pOutputStream.Release();1 K  y) j- M! z6 Z2 u
   m_pOutputStream = NULL;
5 W1 R9 `# I0 z6 p}; Z9 m, J' T4 @9 j( m3 t2 B% t$ n* `
if( m_pVoice ) {
( \* W$ C" e4 b  w2 \% P1 K+ r" N8 Q   m_pVoice.Release();0 ]. R$ j- j7 H0 l! g* n, ?
   m_pVoice = NULL;7 [+ I: q+ I) {6 V9 @
}; {! y- y8 v3 c1 ?8 {9 C* J3 `/ Q
}
9 X5 _8 Z* P/ s$ \4 Q$ @, n7 o
& n# _( Q* H; ^2 Q, P3 f////////////////////////////////////////////////////////////////////. \$ N2 K% g9 u8 g8 _9 F0 q
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。& q) U+ _3 H. I- T$ ]. Q
////////////////////////////////////////////////////////////////////
% a5 _3 V2 [+ W! m3 }HRESULT CTTS::Create( const CSR * pSR,9 ?1 [+ ?2 o6 m* V* o8 [
       const DWORD dwLanguage )3 k0 y( s+ ]2 t2 e4 U6 M% j% v
{4 M( @$ o( V/ a4 [$ l6 ]
HRESULT hr;, [+ U1 D( X) y% ^  H
hr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
: P8 n0 x: l0 A( sif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
" V+ D; N9 m3 l/ u. ^0 n! k- l   return hr;
9 a2 H. x6 P% S9 I: q/ t}) p1 l4 n; i0 j! W' [: C; W( M

+ l. d6 M6 B; k9 }# }7 v. U* L' }SetLanguage ( dwLanguage );
* n: f+ E* ]; l* e9 e* T+ z. w/ Z& V
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
5 o0 j3 r' M3 qif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {) o3 M# Y0 X+ o, ]3 U
    return hr;5 h7 h4 l. K2 Q6 e
}
0 M9 ?+ X) F! A( |8 ]
, A& u7 V- X7 t/ {//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM! x3 J- r, P$ Z& m: G# A3 Y8 ]
//SPEI_END_INPUT_STREAM 表示完成流输出。
" L, ~3 ]% [3 p4 p; ^hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |( [8 W7 E3 X) M7 N6 F* u
         SPFEI( SPEI_END_INPUT_STREAM ),
$ C+ c) r& F; M2 l" c* r8 B            SPFEI( SPEI_START_INPUT_STREAM ) |0 X# s8 h% m; A$ e- ?% E, A7 w$ O
            SPFEI( SPEI_END_INPUT_STREAM ) );- S: r; R+ d, x
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
; o# l" D) H3 r$ x3 }2 ]4 x. p% i    return hr;, v* N' n* _2 E! c0 A3 b
}* d: N. V7 U2 E- W( p: m, n

1 u5 ]. F( \* Q+ T3 E//设置通知消息
2 ^3 p& n& v  W0 [5 f6 Bhr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );6 a. F6 D1 ~& w2 _# [7 q  e5 g5 ~+ v
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
' F1 m+ b) w1 D! b6 z5 g) W/ ]* j) ~    return hr;
/ o( P. K0 b: m; G4 M: t}& V+ \6 N/ t" V) d8 z0 e6 v1 O

7 P" D) f! s9 e/ O. e* Y+ F, k% Ireturn hr;; N; v- p2 p$ D
}- B. N" [1 u& p' n5 i3 f
/ P8 A  ~9 S( t% q; h
////////////////////////////////////////////////////////////////////' a3 y. C' D$ k
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
* U' o7 e9 s; ?0 E! e& Q1 M//并设置兴趣,设置通知事件。7 u8 M2 W! _3 A* w+ X; }
////////////////////////////////////////////////////////////////////) t) g+ O7 S: k) F% W+ x5 ^% Q0 I2 e
HRESULT CTTS::Create( const DWORD dwLanguage )6 d6 f! e* a5 b8 G; }8 S
{
+ H- G- V. }  `5 u7 S0 r7 \9 qHRESULT hr;
  J* S% o# a, \9 a. @  T3 k, Jhr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
* l" k# c% m: }# v; V( Gif ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {
' i5 `  D" ]$ K8 R: q! Z+ N( n   return hr;8 X8 r2 k: H( s% a
}
1 Y' |8 x5 B9 ~& Q8 y" r9 y
( r" h5 _# y/ A5 J8 Q4 oSetLanguage ( dwLanguage );
- R6 K$ s, e; ~4 V7 [5 Q
2 b. ^) G* v9 J) F4 @' E( G: @hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
4 b6 C% q9 l4 j) b: Gif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
! @. \0 t3 z. R1 N4 n" n7 t    return hr;7 D; @9 W9 G% ~2 f' I
}
( B/ p4 l0 q& U& q  f' D! J( O) \: [% n
2 L4 F& C" ^3 x//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM- m- H( _0 c0 V: b8 `$ w
//SPEI_END_INPUT_STREAM 表示完成流输出。
1 a: d0 m& z" j6 v- Z. p, nhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |3 h( p9 W  {2 W* Z
         SPFEI( SPEI_END_INPUT_STREAM ),
! i) w- N( v! J' Z# Y5 D* P            SPFEI( SPEI_START_INPUT_STREAM ) |# k- h7 g% ?) O: p- D/ N
            SPFEI( SPEI_END_INPUT_STREAM ) );
7 E2 e- h; R" D7 C5 Kif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {# j5 ]$ F; l! g$ g+ ?4 j
    return hr;
4 Y0 H: M" I8 g( [}. A' S! b/ r2 |6 {5 q4 u8 Y) L( g
4 S6 S5 D1 h0 W$ r
//设置通知消息9 m( o+ \# X9 u8 [- K& h9 Y. M
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );" Z' l4 O$ S4 H; w6 C" Q
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
6 ]8 L" h8 ]. v5 c& \. ?( G, c5 m    return hr;* c% L! c/ g  S
}, |: H5 N/ J) i
' X$ s3 O3 v/ D2 }
return hr;. ~3 t6 e3 P7 u# I. ^0 `3 W4 c
}; N. N7 U/ ~. g1 [: j1 X# {
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件
/ N, G" |( f8 T" K$ s& D% N9 o- V5 b#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()5 @/ ~% ^9 L+ \3 X9 h# L
{
4 {/ D3 M( e0 }8 D* o    ::CoInitialize(NULL);//初始化语音环境
: i' y2 E. q* [3 D) K; K  o# h% {    ISpVoice * pSpVoice = NULL;//初始化语音变量
/ i* R- W9 b, F    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { 0 b4 N, v% F* J
        cout << "Failed to create instance of ISpVoice!" << endl; ! y4 H1 ]. u/ F. ?/ u
        return -1;
* u* a9 ^, `/ Q+ P8 A    }

( T, y) T0 O: g8 v" b5 _! Y* C1 J    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
' ]6 b" D. T# ?/ p    ::CoUninitialize();//释放语音环境

% G2 K% J6 t  q" Q    return 0;
$ e8 O3 {5 X) T$ _: l+ Y' }7 a5 P}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序+ M  [8 n8 n1 X) p# {

' B8 W/ X8 U/ P1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地, Y: ]3 _. x) @0 r5 U$ _
" F! u- R/ j9 z5 _6 u  K
http://download.microsoft.com/do ... -US/speechsdk51.exe   
# }; W4 t) [4 g6 c/ Z% r. hSpeech SDK 5.1安装包 (68   MB)     8 n. A, J# @" \, S* \( `$ A) `0 Q
http://download.microsoft.com/do ... chsdk51LangPack.exe      
, F- }" q$ h$ ]& M* U中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
. D4 D0 E! p+ P# G4 b& [
. O& C5 \1 K1 b' N2.下载后,执行安装; c$ \& E/ T0 a* t9 O7 f- }0 t
4 Q: l8 Z0 Z  ]) M7 v
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
6 Q9 p7 O3 k! F# m7 w. U" [- \" B* l4 s
3.VC的环境配置2 P( @; e$ R4 u" l
  k7 i0 m; Y, |( r$ E7 Z/ Z( J# I3 o; U, }
在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:( G( C; Q- L5 U

. X- t4 F9 U( L$ V5 K# @9 _* d工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
! m$ _' @3 t# P4 \- V- [3 l& A: l3 l: ]. a+ {
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~- p8 F9 I' }/ l2 B6 Q, k& T
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-8-14 02:14 , Processed in 0.024990 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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