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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
: j; Y, h5 x; `8 _" [//1,生成动态连接库时,要#define USE_SPEECH_DLL,
; l7 B, o/ }3 H! J//      并且#define LANE_SPEECH_EXPORTS
4 t, z# x& l5 I, n/ Q//2,使用动态连接库时,要#define USE_SPEECH_DLL# E1 ]$ A  q: g* z: U1 J
//3,声称和使用静态连接库时,什么都不需要( W; b- g+ _0 [& ?) _6 `
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),
7 l$ l, h6 L6 W* T& A//      动态连接库就不用调用了。
0 x6 p# r. p( P////////////////////////////////////////////////////////
3 ~( \6 N' E/ i4 H; x# m. z/ B) J#ifndef LANE_SPEECH_H
! [- b3 G& G# S0 [$ c& I$ I% g% h#define LANE_SPEECH_H3 c# R: @" B2 i7 W+ w* m: U

6 {* A0 E: ], ?$ n+ O3 t0 L#include <windows.h>) s5 O6 r* O! [5 n8 R
#define _ATL_APARTMENT_THREADED
; Z2 O- `9 D) i% z7 ?  y) I3 ]#include <atlbase.h>
0 t: D5 g: ?+ ?+ qextern 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/ S, ~+ X$ f) n6 S4 J8 u
#include <atlcom.h>6 N7 ?6 u4 j! C: r
#include <sphelper.h>   //sapi需要的头文件; Y* C8 p  J: R5 B7 N

; ~( H" O0 O: h//-----生成动态连接库和静态库的处理----------------
6 ~% M8 B6 \8 T# b2 I# c0 e! e8 }- H2 L#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
' c& @0 Q8 j+ U! N9 Z" f. M+ x
6 ^' H5 L' B1 a: z/ `$ _#ifdef LANE_SPEECH_EXPORTS
- G# e* M! {4 A2 {$ a   #define LANE_SPEECH_DLL __declspec(dllexport)* j4 @- p. a. x. \2 w5 n
#else1 a1 t& g% I# x2 Z9 u" |- D
   #define LANE_SPEECH_DLL __declspec(dllimport)
0 K# F  \# S. W& I' O/ @& M#endif
8 {* y% \1 w* `9 y; N2 l) ?* c4 M6 [7 C* M! b7 h6 l
//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关
2 Q2 v. h( P% l3 G% K) x9 ^. X//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。: g% O9 |9 `. e5 F; O, A3 w
#pragma warning( disable : 4251 )' N# b5 G3 f% X3 I% B& q6 D+ u: X
( u* _8 v% P* d' V. w, K
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)
7 m: k, J# k+ c2 e- r( \. \' k. y#define LANE_SPEECH_DLL
% j& j' p* k) M8 V  [, }7 J5 P) ^4 M
#endif //USE_SPEECH_DLL
  K2 J+ K" F9 s2 P) M( o: R3 I% p6 X9 `4 H
0 r8 G9 U; C4 ~
//***************************常量***********************7 `* P, E0 W9 b% Y+ O5 H

- S+ Y6 g  }% X% M. X, b1 r/////////公共常量-----------------
5 p& F0 ~6 Q% W6 H' d$ rconst DWORD   SP_CHINESE = 0x0000; //简体中文.
+ G: j( Y4 H) V& h; c7 Fconst DWORD   SP_ENGLISH = 0x0001; //英语.: A' F" J3 L# ?/ z

! r1 d6 V; {& [7 p1 ?2 K/////////CTTS常量-----------------
: I9 H% Z2 P& {+ ~const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
# x) l6 ]' Z$ ~$ f' q/ T- _5 y( z% T2 L3 f% f; x7 a
/////////SR常量-------------------3 U4 [5 F: ?2 Y) m% F* v
const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。" u0 k% G, |3 V; g/ G; s
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
- A2 z4 e- z1 {$ x8 e& Hconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.
+ [. F5 E( f5 g; q- [5 N$ z6 o" M7 ]8 F8 o$ W6 {
//以下常量仅作例子用。* \& ^( \: E; m: e0 r
#define VID_TopLevelRule 9000   //顶级规则ID
: r, G; _7 Y. Z( S1 X#define VID_SubLevelRule1 9001   //子规则ID% K  b& ]- t9 n  ?4 o, D0 y& L
#define VID_SubLevelRule2 9002   //子规则ID
+ F1 Z* [+ u+ F3 Y( Y4 b9 l+ i#define VID_SubLevelRule3 9003   //子规则ID
) G& t; E* L( X2 j, k5 a9 j
+ y; j2 W- Y- r8 M% m! S8 \8 _; y: Z1 {7 H  e2 ^
//*************************类声明************************
9 U; d6 d+ `6 s) \/ r9 {! F
6 l& o9 H# u) H, Q' V2 k+ V, `: G
class CSR;2 J+ L6 h; a: n
///////////////////////////////////////////////////////////////////////
# P' R2 w; h; Z///////////////////////////////////////////////////////////////////////; }1 u/ W5 p6 }1 l, h
//
9 K/ [0 k. m* g4 R8 y1 ]6 l4 v//         CTTS- ~2 U, v7 G" r
//
. X+ k0 K- D* Y$ g! N/ v///////////////////////////////////////////////////////////////////////$ Z) `" P  F; J0 |1 }% U
///////////////////////////////////////////////////////////////////////
0 @/ W; }% J' G  [3 p/ E& u$ q% V4 n% F3 _
class LANE_SPEECH_DLL   CTTS
  m6 G! E( l  P  e  L{
/ H. \8 @  J! R) c0 p) @protected:: t0 E7 [2 o6 T2 s' L
HWND       m_hWnd;     // 关联的窗口句柄。3 B# x/ x, A6 g- q
6 Z; [6 m4 Y/ ]$ Z, b9 ?$ B
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。
6 ~9 I% i' f- b+ A4 O' I3 kCComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。1 a5 z  ~; U( S9 _5 p# }- I
CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)3 O- a2 e' c, @: f
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。) ~2 [$ b1 Q4 \: z- G) t+ C% \2 d
2 `/ x; f& E2 T( [# F4 ^8 c
public:- I. r& L& ]4 l( \
//********************************初始化部分********************1 J% r0 S5 S2 ^: s/ k& G" R
; Y  U3 p3 K, i% `
////////////////////////////////////////////////////////////////////; {, v# z( k% R
//功能: 保存与识别引擎关联的窗口句柄。( f( s$ l# G7 `; x
//参数: hWnd:要关联的窗口句柄。
: _# O  _; e0 {6 F' F3 Q' w4 M//返回值: 无。
4 ?) z- e' N& j1 [////////////////////////////////////////////////////////////////////# |2 Y3 |! F  Y) B' ]' {
CTTS ( const HWND hWnd );8 {+ }0 F; r( X+ j' o
* i5 ~7 Z  o* }1 x
////////////////////////////////////////////////////////////////////  G: p, S1 m8 Q5 g5 z" [" Z# l0 _
//功能: 释放所有的对象。
- k, j  ~0 c+ z  |//参数: 无。: P  x3 _, A' j
//返回值: 无。( j% o) x2 `1 t! q
////////////////////////////////////////////////////////////////////
( Y2 H& W% v& Z% d6 g~CTTS ();" r2 Y, Q0 p9 C' K3 @1 ?( t$ t

+ ^" k! [* ^. r( Q////////////////////////////////////////////////////////////////////
/ u% L6 p. L" X2 R  g# u+ ]- L//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。# C/ A+ R9 q, ^$ ]9 L/ J) ?
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,1 ]: M9 G3 |# p
//    SP_ENGLISH为英文。6 y' `) H9 n) m; U/ @* u( N
//返回值: HRESULT类型。
# E# V: |9 K  x& ]: D////////////////////////////////////////////////////////////////////2 j+ K4 A7 x( `$ V, l& y8 H( i
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );
: r' p: a- N+ i- G" _# s. `  C& m+ ?! K  h. m
////////////////////////////////////////////////////////////////////
9 o- r. `5 j% ^% B+ a0 h- B//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
7 X0 j4 S/ B# I( Y5 G/ z% r//    通知事件。0 k  o; T: @4 t, Q' X
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,2 V9 v8 m; e  g: k( G
//    SP_CHINESE为中文,SP_ENGLISH为英文。
  x! f8 o+ K$ j8 H  S//返回值: HRESULT类型。
; U* p, e( C+ g; R////////////////////////////////////////////////////////////////////
, i" d* `: D6 u4 @2 p, y3 CHRESULT Create ( const CSR * pSR,
% h# p& d4 U$ ?9 C       const DWORD dwLanguage = SP_CHINESE );
2 U* _/ a$ ]& t0 Y' }
: L# ]. H( A! J$ B
2 h" }* M. B+ x+ b2 F//********************************设置部分***************************************1 N% B: G6 e1 S# |
" b$ c# C# Q7 `! a* X3 C
////////////////////////////////////////////////////////////////////! R4 r+ [! F8 i* Q- Y
//功能: 设置朗读声音的语言种类。
2 R; D$ n9 q6 `* K, f$ i2 S* T//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
1 i( l$ N* s" R+ a: \& ?& c//返回值: HRESULT类型。
  K7 N( V& W: t* ^* ~////////////////////////////////////////////////////////////////////
8 }4 o7 n9 j6 bHRESULT SetLanguage ( const DWORD dwLanguage );
5 C# U  H0 F7 e2 Q! N  g
/ [! w1 |4 h! d* J2 ~% m////////////////////////////////////////////////////////////////////
! S, `3 K) I, r6 P, x//功能: 设置要处理的的事件。
  j& J5 J4 g: I; M' k0 n) U6 L- ~//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,8 U% Y4 \$ [/ k* L
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事4 O# r* e+ p& r; ]
//    件都会收到通知。
4 l8 |2 }) }8 Q# j9 o//返回值: HRESULT。
; @, o3 p: c" b7 F" X% W" v////////////////////////////////////////////////////////////////////
$ O+ E" x  R( E- OHRESULT SetInterest ( const ULONGLONG   ullInterest );
& C1 ^1 G' @" Q8 j' o" c$ Q/ W% Y& K* v. T6 S6 W
////////////////////////////////////////////////////////////////////0 V; ~7 z# s# l7 l# x* p: ?' F5 ^
//功能: 设置朗读声音的音量。6 C$ x; M3 b: h8 V" H
//参数: usVolume:音量数值应该从0到100
8 Z+ [, O' W" ^4 o, l/ C$ j& ~//返回值: 无。% _5 B: L; B( n2 X( i" r
////////////////////////////////////////////////////////////////////
# B* [% E0 D6 W, i" A. B) \void SetVolume ( USHORT usVolume );% v+ d& O7 [, a9 W

+ y0 m+ ~5 _: e& ?( a+ ^5 T////////////////////////////////////////////////////////////////////
1 }; i9 V* G: G, b# g//功能: 得到朗读声音的音量。5 a/ h4 W, E$ k5 Y4 X& A6 }
//参数: 无。5 s5 S. P2 u' s% d( k% I% C
//返回值: 音量数值,应该从0到100。
% A2 @- ~# c+ g. T/ y# H////////////////////////////////////////////////////////////////////( o$ r& q& f4 C+ O
USHORT GetVolume ( );( [* s/ i0 r. E; j2 H* y
7 W% h. A  o) y  D$ f; y
////////////////////////////////////////////////////////////////////8 m9 m- L! P6 G! s4 ~8 x2 o! r3 ]
//功能: 设置朗读声音的音速。0 {) {+ E0 [; I+ i4 ?* @+ M0 r
//参数: RateAdjust:音速,参数范围从-10到10。, C5 r: @1 U+ i+ }
//返回值: 无。6 S8 v/ i$ ~# b1 D0 e0 m
////////////////////////////////////////////////////////////////////+ e4 n0 e$ T- x$ E6 ]* O
void SetRate ( LONG RateAdjust );
; I0 R0 e# Z& U% u6 u+ R3 P5 t  W& l/ d8 L1 u# x" f
////////////////////////////////////////////////////////////////////
/ r! B( L- R  U1 Q- q" }//功能: 得到朗读声音的音速。
; c) x+ p; h! o0 D//参数: 无。3 D% @* v* k' q/ [
//返回值: 音速,参数范围从-10到10。7 I; [9 p2 F0 }
////////////////////////////////////////////////////////////////////1 n6 V4 q9 Q/ u4 p2 [
LONG GetRate ( );0 n; A1 `+ }- z& _8 S; O% V
9 |% v% |( o2 S+ ?( X6 K
////////////////////////////////////////////////////////////////////1 u7 [# u. N0 H7 R
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
! V: }' y' @$ u, z5 C4 r4 C* \1 y//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
9 K. U7 C. d0 y2 P//返回值: HRESULT。3 x. \9 ?: ]# A0 j
////////////////////////////////////////////////////////////////////2 J( s- _/ k* E1 X
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");
0 T, y: f  g" c7 B4 r
" O: L' `6 r# G* j+ l////////////////////////////////////////////////////////////////////
- O0 t; c0 o" v. O  E% f4 i1 ?//功能: 设置朗读的声音从音箱输出。
2 G& g$ A; M( O/ [& y7 V# x* `//参数: 无。
# a5 h, |3 G! P1 o! ?//返回值: HRESULT。" Q& N) [8 T' a
////////////////////////////////////////////////////////////////////
5 e% }4 R' N, Y5 F. }HRESULT UnSetOutputWithWav ();* T5 N1 E% x9 B1 A% \7 F
; R; Z5 }' f. E( M: Y+ l  g

, z4 j3 X) s/ x2 O//**********************播放语音,文本到语音转换部分*****************************- a' B: b. _" u, n5 \
: e6 U1 c" b& j8 q6 a' y" Q) n
////////////////////////////////////////////////////////////////////
% s! C+ S, \% {; C4 p$ R/ {//功能: 停止朗读。如果朗读为同步方式,则不能停止。
1 u3 w) _  X" J& P//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
+ S: y( l6 q/ s5 [8 q/ n3 Y//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
5 B  ]6 M1 h% l- m! e! Y" c//    SVSFIsXML为朗读带xml标记的文本。/ e$ J' T+ ]7 `" b$ b
//返回值: HRESULT。; s. M# Y' g7 X/ q
////////////////////////////////////////////////////////////////////* L# P- X& @' P7 C
HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );( x) `! q, P8 D1 v* e, B# s9 m5 m
& u- S% L, _+ ~' B7 p( S- m
////////////////////////////////////////////////////////////////////
( x/ Y- T8 G$ n: m' q; b//功能: 停止朗读。如果朗读为同步方式,则不能停止。
: N" }: l. S" [* G& h//参数: 无。
# Y2 x: I4 B1 t$ V" ]4 m" ~//返回值: 无。) }# m$ Q1 |; F- f
////////////////////////////////////////////////////////////////////
& I, x& F* g" F# cvoid Stop ( );
+ @& k1 o  @% l! ]/ ~, e! w, V9 ^0 F6 X# D
////////////////////////////////////////////////////////////////////
8 e( J8 e5 Y8 k+ R/ T//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
) l. ~) Z& U* `$ I//参数: 无。
) g% A( @9 G4 S1 Q//返回值: 无。
+ B8 d4 L/ D- S3 b) m////////////////////////////////////////////////////////////////////! l+ w# E9 k8 y" K# H) C, D
void Pause ();6 @7 R* l( m3 u8 Z0 @& r5 w: x6 e
7 }& C* y8 `0 {$ k. L7 c0 |
////////////////////////////////////////////////////////////////////
- e5 u" [# W! ^1 R% E- D//功能: 从暂停的地方继续朗读。8 X3 v4 I# S2 B6 C5 C+ _- c
//参数: 无。
* J& P# r0 d3 m, N+ I& i# y//返回值: 无。% e5 R3 N0 o  d" V, S! S
////////////////////////////////////////////////////////////////////
& a. C$ E0 K4 m% v+ Xvoid Resume ();( Y) Y* U+ Z( Q$ A
, k8 e( @2 q' y' p8 \; B: U
& b* q, z8 r# m/ _1 W
//********************************处理事件部分***********************************
  O: T1 m. S& r6 J5 @" Z8 T& d
' U* C: A( G7 p# Epublic:
! N, o  K$ b% F" W////////////////////////////////////////////////////////////////////- Y+ E9 M* z) r# X" U9 }8 {
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
: i6 d0 T- s; U# S  [//参数: 无。
" ^1 f5 S% Q: C: R# D- Y//返回值: 无。) o3 \; ~1 \4 `+ b+ o7 O
////////////////////////////////////////////////////////////////////: R% {) y/ V# h1 X5 E( E
void ProcessTTSEvent ();1 w9 [  C* y* R( W) c' T

6 m, k0 R0 M  a" N& z- ?
8 b2 Q) B! n9 B" e: C: [# B////////////////////////////////////////////////////////////////////
& \, a# c# Z7 L: `5 `//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。0 z! j5 Y0 p9 I  k+ z2 }: `
//参数: 无。* F4 [4 X1 _: y* |' ]+ Y$ H
//返回值: 无。
: }1 \; f* k3 n$ W2 d6 P////////////////////////////////////////////////////////////////////
. _% h6 m4 y4 X( C# ]5 a5 C9 C- Xvirtual void OnStreamStart ();
- V9 |( y6 t. |
9 V- W& Z7 K! x0 M0 E9 O7 _////////////////////////////////////////////////////////////////////. p% k6 j( [% V
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
8 Z( o' V& v6 v5 v$ ~! M//参数: 无。
$ Z3 J( B1 H+ c7 x$ Z6 `1 h//返回值: 无。
/ [; ~0 g8 ^! g% S. G////////////////////////////////////////////////////////////////////, O, S1 r3 S, Z' u
virtual void OnStreamEnd ();, z: U6 d, `7 {/ Q0 y9 F
};
3 W! G8 m% b  w# n2 c; t! _3 ?, o. ?. |/ H: L

( L- o$ A* ~8 b+ U. k/ b///////////////////////////////////////////////////////////////////////
6 m: n. p* A" M( t///////////////////////////////////////////////////////////////////////
" a. z: q* e8 k//         CSR
3 F1 U2 g& W& t//
0 C3 Y7 L1 z% u1 S' H2 F///////////////////////////////////////////////////////////////////////; O1 H2 s1 r. o/ q+ L9 _
///////////////////////////////////////////////////////////////////////
- K! G; L/ Q* F% P& O- p- M) h7 m5 A! S: W& O2 R
class LANE_SPEECH_DLL   CSR
& _1 x9 h; W( A9 s' a9 c/ g{
; X5 \' T3 v: O4 S" \: O. Q! c% z
5 Y0 T5 O0 G/ Z" J- ?protected:; R& i" T" @+ S
HWND m_hWnd;
8 @5 v6 n8 a  @. E( s5 H! r0 o5 m/ n! A% q0 V: k  S
public:
" _! f  }' L5 B! N' aCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
  W) r& ]+ t) f9 C& q1 PCComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。0 |% v" `1 X* ?6 m+ D! `7 S
CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。7 j6 I0 K8 |0 U3 X/ f
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。
& ~. c; g, v2 K7 ICComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。9 {) y; l3 z+ G) a5 H; o/ t
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
" D- a3 U# D2 p* ?' Ypublic:$ Y8 ?& q% d; L- d4 N
static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。8 q6 w' y, g5 {/ T( l+ Z$ Q
1 `# `: X$ W9 L2 G: b

* f, C9 G5 y4 O/ j7 f6 v( ?/ v& Lprotected:, _1 k6 Q  `8 [' n9 j3 K
//***************************辅助功能部分****************************************
( n6 N( r( }# ?+ `; O6 e+ W) A( }3 ^+ F/ S# `3 @6 \& q0 C5 C
////////////////////////////////////////////////////////////////////, b2 k3 j: a0 E& z( u" d
//GrammarID加一,每个GrammerID必须不同。' ~, o8 L$ d, ?8 k/ s
////////////////////////////////////////////////////////////////////
& s" e( Y8 D! W( Y5 R4 z; [static void UpdateGrammerID ( );
0 Z- P* i3 [: {# a. H
# l2 q1 _% ^: y. w( l5 v' P& R8 F" }2 |+ U4 r/ w6 I! S% C
public:0 V6 K: Y; k! E+ v  r2 Z
////////////////////////////////////////////////////////////////////% n0 \9 j) P- G  p$ m
//功能: 友员。TTS中的从SR引擎中建立voice对象。/ c- e1 M3 _. p7 U+ Q
//参数: pSRContext:SR上下文对象的指针。
9 t) d7 s' K* m* x% |* d0 ~//返回值: HRESULT类型。4 f) _6 K2 {0 q7 i
////////////////////////////////////////////////////////////////////
% K* F# r: x. p: U) ?4 g6 Mfriend HRESULT CTTS::Create ( const CSR * pSR,% ~0 L; s9 K$ j) t. t; L
          const DWORD dwLanguage );
: V5 ^5 ^- D9 W5 b! B: y" \" E( k. [: V
8 d2 T9 ?/ J: v3 ^! K8 r2 h
//****************************初始化部分*****************************************6 {3 m: L1 ]: v6 Z

" m5 X6 h$ c7 W5 |+ H: C" p7 K////////////////////////////////////////////////////////////////////
" P  {- C  `0 K8 }! V' p5 O//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。& b/ L$ p0 {; L  T% Y
//参数: hWnd:要关联的窗口句柄。% W9 _: d  g4 ^8 s7 z' H" s
//返回值: 无。
+ j+ I  u4 K8 C/ U% U) f' ~////////////////////////////////////////////////////////////////////" O' ?! \/ F, z+ W' {6 v. K
CSR ( HWND hWnd );+ `: D  A" o* x, O+ B
  _0 f2 P  O, A9 w# W
////////////////////////////////////////////////////////////////////9 r1 C8 A  F* w+ J* q) p& D
//功能: 释放所有的对象。
/ P* L' j$ @) l6 @//参数: 无。. L( R; [1 I5 Z" m4 n- H
//返回值: 无。
. A8 [+ F, z3 ~* o$ Q, d( m6 n////////////////////////////////////////////////////////////////////
, S- \/ f# v* Y5 j, A3 l. z6 _/ x~CSR ( );
/ s! w7 }/ A( c
9 b# P+ B2 d/ E( s////////////////////////////////////////////////////////////////////
( t0 T$ Q" v! K; \3 s4 A//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,: S1 J, q. f" X, h+ E
//    加载文法文件。% H" H3 A4 U$ D) y
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。7 D, }0 C: T" c+ r+ o( e% y- K
//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
: S' W6 }! g9 l; m! j, @; ~//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。
0 ^1 _" J- z; E2 i//返回值: HRESULT类型。5 j- r9 h& y# H/ @
////////////////////////////////////////////////////////////////////
2 ^5 B" K' w: `4 e& V# V6 \HRESULT Create (const DWORD   SRType,
# T4 }0 ^7 Z6 j0 k! }2 ]8 N      const WCHAR   *pwcGramFileName = L"grammar.xml",
; P& R2 M( P2 d; O3 y  G; n: ^( [      const DWORD   dwLanguage = SP_CHINESE );
. B1 B3 i% L7 k7 K" Q0 k
2 `: o7 Z" i1 @  S* y- U
  I$ N! i) {# _5 l  K" {( P//**********************************设置部分*************************************' V0 I6 e2 t7 \3 v+ |# v

$ d7 M" q, _' B- r  l, a' {////////////////////////////////////////////////////////////////////8 h1 I7 A  K* m) a1 i
//功能: 设置要处理的上下文接受的事件。
* a- w* ~& _* i7 W* k//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,& V4 U& L& Z+ m7 a+ D( ~5 Y( s
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
, L4 U0 B6 O# D9 N" @//    件都会收到通知。$ x1 F" \( f" X- X6 m! ^9 y
//返回值: HRESULT。
; z& ~$ }4 B9 ]  O) Q8 K, d////////////////////////////////////////////////////////////////////! i2 T* x/ `. l7 t2 h- x5 G
HRESULT SetInterest ( const ULONGLONG   ullInterest );
( i; z% P: @5 l9 F& o
) E: J! e2 a( a+ K% ~% l////////////////////////////////////////////////////////////////////: X5 i' z7 S+ J
//功能: 设置某个规则的状态(激活或者取消激活)。# T. `* ?; A4 X$ |, |& T- [
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,* @# w# T: c( T8 e! a. x) O
//    FALSE表示取消激活。
$ V8 {/ O4 }9 q0 K//返回值: HRESULT。
+ E1 ?5 l3 S% u) h: z5 Y& Y  o( W5 H- T3 D////////////////////////////////////////////////////////////////////% s* b7 l+ h9 m5 I& ]7 e
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
8 v1 l+ }: b3 M5 c
$ i+ G, T( p( D0 P. y4 b6 `7 D3 d
8 c- e( I  X" L! P) d9 P/ j  F////////////////////////////////////////////////////////////////////
% \+ z& U! V& A( {//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克3 ]4 R' Z4 Y+ D# v  d. N* }" W
//    风输入。2 Q  l  S+ }' [1 t  f0 a
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
$ p' i' W' u' r* l# h7 A- s7 w; r//返回值: HRESULT。
* l4 n$ Z6 E- O4 z////////////////////////////////////////////////////////////////////) |4 l  `+ O& A! P& Y, i: ~7 L
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );6 |7 R2 y1 @: @

! J5 X8 D$ [) a& p; _////////////////////////////////////////////////////////////////////
0 \7 D! h/ ]$ T( S//功能: 取消从.wav文件识别。恢复从麦克风识别。
8 Y' d/ Y% v! U( H8 s9 r//参数: 无。) a+ w2 X. a3 G% S" b/ D
//返回值: HRESULT。
- ?: l5 _# t8 j$ T. e+ s! Z////////////////////////////////////////////////////////////////////
* d8 C( {8 S) g- L5 LHRESULT UnSetInputWithWav ( );. P+ b- U, D4 I# q) d' V
( N" ?9 E: G2 L( [" D7 w' w$ B
//***********************识别开始,结束,识别结果的处理**************************+ a( q9 X' w% K% }2 _

2 ]' ?, l" C! v# s8 s////////////////////////////////////////////////////////////////////8 {: d. ?+ d' @+ U% @) K) K* [
//功能: 识别开始(将所有规则激活)。6 C1 w  x  @% X1 y: G7 Q
//参数: 无
5 L/ d+ B0 S6 q8 @% @% F//返回值: 无。
6 D+ v: e0 R6 C+ ?////////////////////////////////////////////////////////////////////  x% K; l% w! @; C! z
void StartRecognize ( );
% ^+ G+ K. f, ]
) u& [# z+ q! \1 V////////////////////////////////////////////////////////////////////, y$ Q- _& D# `- P* X% L0 G( l/ Y
//功能: 识别结束(将所有规则取消激活)。
$ Z# {1 g9 X, L, U//参数: 无。2 `- E# _; z/ w0 o/ }
//返回值: 无。+ D9 C( D1 F. K6 U
////////////////////////////////////////////////////////////////////
/ R7 v) U0 C# C/ X/ Tvoid EndRecognize ( );0 D3 ~, Y8 }2 |6 v- f, C

/ x8 D8 C/ j( W: c1 Opublic:) E$ K* C! y8 s/ Z4 i4 H# y- Y
////////////////////////////////////////////////////////////////////* }: g. A5 E+ |$ e3 a) m% W6 {
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
$ s, i7 U0 g; k7 o: i7 U8 L//参数: 无。
0 k  Z% ?& X2 [% O//返回值: 无。3 E+ S$ u1 o5 _4 v! J5 D
////////////////////////////////////////////////////////////////////
( U7 ?8 f, [0 `. D! T) a$ [void ProcessRecoEvent ( );
8 h9 D' u/ _" l& y% \( Y7 K8 S: x$ @$ J, T& m2 K9 @8 ?' t/ t! d
protected:. _3 T' Z: G$ [7 s0 r$ ~; m
///////////////////////////////////////////////////////////////////// l% V, C' g& ~9 N* o4 ~" g5 N; A
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。! i! t! D( t/ r2 i! J9 z
//参数: pPhrase:ISpPhrase类型。3 d9 S4 i8 k4 ]4 ^6 e' a5 z4 K
//返回值: 无。2 D2 v) ]+ ]7 ^* T  o: p6 y
////////////////////////////////////////////////////////////////////+ W6 }- e3 ?+ K/ v3 E# d
void OnRecoSuccess ( ISpPhrase *pPhrase );+ C6 w; X/ _$ h$ o5 G: m

4 T$ _& ]! A! @7 J; L$ i/ _; ~public:# e1 X% Y! _, H" z6 S
////////////////////////////////////////////////////////////////////) ~$ `5 ]3 i$ y
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
! B, H# H7 ]2 S4 k//    需要在派生类重载。规则ID必须以常量形式预先定义。  }! `7 t; f: e  i- F
//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
* t. z3 r6 @% \, v- }) B4 k. D/ m* i//返回值: 无。
+ S0 A' O+ }* Y6 `////////////////////////////////////////////////////////////////////
( h" S9 A1 l1 ?) ]( C8 }virtual void ExecuteCommand ( const ULONG ulRuleID,7 G7 y" g$ @6 v
          const ULONG ulVal );# l( [) U  J$ m8 e8 P4 i% i" v: C

( V2 `6 x; P* p& F6 d& E8 _8 Z////////////////////////////////////////////////////////////////////" h4 H: B4 k8 Y; K  o6 v, j1 ?. r
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
$ @8 }( v$ b+ J: ?. K9 [//参数: 无。9 w, ~$ V% E1 ]
//返回值: 无。' u1 \0 K& c% Z' w: h* h7 I& @8 G, x
////////////////////////////////////////////////////////////////////1 ?  Z' N( R1 b" j6 a# J5 `
virtual void OnRecoFail ();2 N. ~' ^; L7 O; e2 Z  z. t& z
/ U6 V+ E! p5 ^! }
////////////////////////////////////////////////////////////////////$ D- r  q2 H5 b9 {- L: w  g
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
* C! _' _& B& F- k9 ~, _//参数: 无。
. ^2 }! E; w# `8 y+ B' |' `//返回值: 无。
2 B& @& L; \" d+ p3 V8 H////////////////////////////////////////////////////////////////////# z3 w! m; }' W% c8 _3 B
virtual void OnStreamStart ();1 [. V+ t/ b& h/ X* w  B
; ~! {: e' i9 o. f
////////////////////////////////////////////////////////////////////
$ S/ c2 V' u" x# v" r# M//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
. \) x) I% g$ k4 M4 c( o( n//参数: 无。5 r6 L+ d) p3 Q2 S
//返回值: 无。
, D. i" N. z+ J- U9 U; Q  E. V////////////////////////////////////////////////////////////////////, E: g) v( ]2 X, ]2 k1 i# E7 y
virtual void OnStreamEnd ();8 b8 y, c2 r- K; Q% k

0 A8 `9 B  A& u( S7 U8 Z6 P4 j+ q};
7 U# m2 W; k& i; f3 x) |
; y# o1 @3 o5 F8 ~, J4 F4 g1 n, I& c% H6 y; m7 v) |

& h4 ?# O: O1 ~. N#endif    //LANE_SPEECH_DLL_H& d. ?$ i5 J) A! n

* k6 \6 `# D1 b///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1 z! x: T4 k3 T1 G+ N3 R5 f2 J7 X0 `& q, P* z& D
////////////////////////////////////////////////////////
+ i6 t/ J6 F; ~5 F/ U6 x8 Z, L& U//  l  p: Q& X$ E; }4 N
// 文件:LaneSpeech.cpp
; U- E9 S2 l1 [4 s6 |4 [// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
. ?- @0 x) h7 y+ a; \; w: x//    语音识别只支持命令模式,不支持连续模式  C6 e# Q" A3 q# l5 m; a$ u
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
0 C5 |- r2 i) H0 Q- j+ \// 日期: 2004.101 e2 e. e3 l% m" Q# l  d* a
// 版本:1.2
( {/ n1 n/ U# m  w) R* @//
3 ^. ]! J. a  `3 ~5 C' y. T//7 u6 q% B5 s3 N( ]- C
////////////////////////////////////////////////////////
, j$ J1 n/ `3 A( _2 \4 U5 V
  [4 s. I, f* U5 x$ R5 v9 u
5 e  N4 w# M( d6 c7 S1 L0 x7 V
! X1 t4 y1 H& [( {: t! `: g& V#include "LaneSpeech.h"
* i% U2 ~' V& p2 r3 M
9 F3 g( @' W! s! l# X* G//-----生成动态连接库和静态库的处理----------------
, c; Z5 s* ~! N- I#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
% }% O  g0 G6 N. r$ N. A! p0 [3 u
$ }$ i3 V+ o& m. n8 t. zBOOL APIENTRY DllMain( HANDLE hModule, , K! g4 a8 b9 x  ^. }! X
                       DWORD ul_reason_for_call,
$ h) X9 ~# r5 v' T6 P* i                       LPVOID lpReserved+ e0 g: g+ ?" Y( N. q: U) v5 R
      )
* ?, \* N* e4 B& u5 V- u+ S/ {{
, ?  M; N1 k. }9 I    switch (ul_reason_for_call)
/ F! F& o8 {/ I+ |/ Q5 ]{
. _; J- ~0 _) \7 h3 ~) j4 a2 Q3 O# u   case DLL_PROCESS_ATTACH:
2 u8 E/ s. e! h; L5 a+ G    CoInitialize(NULL);
% r/ m+ D+ r* L, G8 l' f    break;
" e& W. w) ~* R  [: P1 {  5 R9 r3 c) L# \' E
   case DLL_THREAD_ATTACH:
0 a! I9 A, O1 E# d1 T* Q) Q  ?    break;
) A5 v1 m9 S5 t! c( I* y1 h  
. y- h$ Z5 Q7 o, |5 |! {   case DLL_THREAD_DETACH:
' R0 |, t4 X. }8 j    break;
' f9 J/ Y. k, V  + P, c* J$ K3 l! L1 @
   case DLL_PROCESS_DETACH:' `' |" P- P6 d0 S9 m
    CoUninitialize();
: I/ |3 Z9 ]6 k- O    break;& P6 W: H1 S! d( r7 m
    }( b2 G; `7 d( r% N5 M3 J
    return TRUE;0 i# F% q# K3 G
}. Y% m6 o: K! G  ~* [8 Q' r
6 f1 |- g2 ^: `2 Q3 G4 j8 ]2 I+ m( r
#endif //USE_SPEECH_DLL
" j& G* i9 y6 h' J# p- Z  ?
: w6 M6 D+ m6 M9 u8 O/ s
5 G1 e+ ^- `) M  j  c& n% |7 z; ?4 n
+ [1 ]$ z& a/ Y: P, l& S///////////////////////////////////////////////////////////////6 p8 \7 c+ ^3 V. x

/ r& H4 I  q& O////////////////////////////////////////////////////////////////////3 N# Z; _5 h, E; A1 O7 |' Q
//功能: 弹出一个信息框。
( ]; {: a& N& K/ a  y3 C5 [//参数: lpText:是对话框信息。lpCaption:对话框标题。
% D7 }9 L7 H0 B0 s//返回值: 无。
3 r; E9 }" X% Z0 X( f+ w////////////////////////////////////////////////////////////////////+ l+ Y* |5 Q1 Y" j+ T* e# p1 P1 @1 ~2 C
inline void ShowError ( const LPCTSTR lpText = "ERROR",
  M! M$ Y7 k9 Z! P6 {! [        const LPCTSTR lpCaption = "ERROR" )" P  }& m5 B& {: y! G2 V
{+ K  r  o; A2 G$ M  _
   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
' S9 r5 N# v' _, z* w  \/ B}8 v  `2 @2 r- \& V

; B# ]# ?* R) G& W9 B% v////////////////////////////////////////////////////////////////////8 ?6 X, h4 C8 q
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
! y+ N. H' ^6 p6 A& ?) F//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
# w& k0 K9 }. {- Y//    lpCaption:对话框标题。; [; C9 \! j2 c' }/ r
//返回值: 有错则为FALSE,没错则返回TRUE。
# a/ {) C5 m: r1 a8 r, {////////////////////////////////////////////////////////////////////+ O/ Y2 _4 J- K: S/ \5 q7 b
inline BOOL CheckHr ( const HRESULT &hr,
  R$ @3 g! g6 C' w% Q5 ^        const LPCTSTR lpText = "ERROR",: \% ^4 h: B4 _' M
        const LPCTSTR   lpCaption = "ERROR" )
$ B( n& H) `7 m  c0 V{
, I( l8 |  l5 n2 o% Y8 G% g, Y   if ( FAILED( hr ) ) {
0 S0 R) N# C: }' X( @3 \- _2 |    ShowError ( lpText, lpCaption );1 F% z# A' y4 B3 _6 [: M- S9 d
    return FALSE;0 _2 ?. b% S0 Y% M0 I+ p
   }
# f/ Q- d& y/ ?4 [6 p7 X. ~   return TRUE;
4 q6 i+ m$ P" _3 c- i2 A1 f; Y3 {}. ?) r4 `$ O( Y9 w

9 i. e8 w; j6 T, x8 u& e7 p& L" t- M8 L6 Q: Y% y
///////////////////////////////////////////////////////////////////////) i& P* v. O1 D7 f$ t# f: @$ M
///////////////////////////////////////////////////////////////////////0 s! s: Z5 Y# X" V! }
//  `4 E% S9 Y/ w
//         CTTS6 g5 T: |6 y2 h9 u/ a) O$ I4 I
//. j6 T* K/ F! k# y! N- m8 J; ^
///////////////////////////////////////////////////////////////////////' v5 y  x. U% I, f
///////////////////////////////////////////////////////////////////////3 X, {4 \! S+ c2 W% [+ F

0 H* |0 L& b6 ^////////////////////////////////////////////////////////////////////
" t+ g5 O# O) h  @  E8 x1 }//保存关联窗口句柄。初始化COM。
2 S  c1 Z4 u/ D' b3 ~8 `" r////////////////////////////////////////////////////////////////////
; e- a5 p. K+ t+ l  vCTTS::CTTS ( const HWND hWnd )
+ R/ y. e# i0 T2 q{9 t5 j% P" a& i) k, Z* G/ n
m_hWnd    = hWnd;
" ^% ?0 C9 @7 K/ ~1 h  O4 m* Pm_pVoice   = NULL;8 B3 D# O1 ~+ [  R7 o* [
m_pToken   = NULL;. j$ O6 v! }8 K4 j2 ?+ {3 a; {
m_pOutputStream = NULL;
/ o' `! d0 \  z6 M# s% W6 S) Um_pAudio   = NULL;, ?7 A% f: r* y
}! A. D6 ?+ l& t0 j9 j

$ b1 U3 `: f; j8 ]////////////////////////////////////////////////////////////////////
  W6 p9 a5 _* C2 G0 S7 Q) U//释放所有对象。$ ^' z* W" K1 {
////////////////////////////////////////////////////////////////////) p, }" p, R- w2 Z- T% r
CTTS::~CTTS ()
% u9 M- l0 C& }+ I. d# t2 \$ M{& k' l! H, b* ^8 S+ T" t3 Z
if( m_pToken) {
: q, ^* O) X  Z7 b2 e   m_pToken.Release();
; r% L7 z! \2 e   m_pToken = NULL;: }6 L) ?" F* G5 |! j8 j
}
9 C2 ]6 D% Q1 {0 ?2 P# jif( m_pAudio ) {9 j1 H; I" _! F2 z6 y9 P! D
   m_pAudio.Release();
, I1 E; i- X. x   m_pAudio = NULL;! I1 f$ p, r3 c( T* `
}% Z& K  |+ y4 y/ R% y) c) u; V
if ( m_pOutputStream ) {
7 z" \3 L  }+ N( E  K$ L* G   m_pOutputStream.Release();
' R" V3 t; M1 _4 r   m_pOutputStream = NULL;5 q; b( v8 X$ ]% \
}2 |+ V& Y( v7 |7 W+ A
if( m_pVoice ) {
5 j2 J% P8 c1 T& t# g   m_pVoice.Release();
- X$ F  H: `; H7 E9 }& k7 T8 a% v   m_pVoice = NULL;
0 P2 B+ S( h" {$ F1 p& ]' d8 s}
6 ~4 v0 B) q/ y' Z}
) m% C6 D& K8 A2 [3 _5 J( b7 O. s; _3 C9 X! j
////////////////////////////////////////////////////////////////////( p0 A% y  l+ s2 ^9 L& [% j- T
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。
' Z6 e5 m) n& n% C- c0 F' {////////////////////////////////////////////////////////////////////. i) r5 c) K/ U- r0 k+ N! H! B; u
HRESULT CTTS::Create( const CSR * pSR,- D2 f% i2 w1 k) q  e1 h
       const DWORD dwLanguage )
2 o1 v1 {2 k8 S8 I1 ]{
1 H$ o8 S& t6 u6 o# e! THRESULT hr;
  K* \4 C* @  Khr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
0 t3 R5 T% V7 B2 g$ C5 ^if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
, K7 G+ U7 R* T5 x; Y1 Z: \   return hr;
( z+ i# Z5 K% G7 F5 a" W}
. O  r/ S; ?# b8 o  V; E
8 N5 d  Q' U, g3 N" e/ ^6 s. ySetLanguage ( dwLanguage );  n5 D! ?8 ~% y7 Y6 b1 H9 l4 J

( R9 S9 B/ u/ F9 s6 B* Z7 Khr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
" }* Z0 A% K2 \  }9 Fif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {0 a" w1 {( @! ]. |
    return hr;6 q6 c0 q$ [; \: w! e! z
}/ [; V, Z$ ]. q, j# M; P
% ?0 y% n: P% u$ Q* \+ h
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM# b4 u/ E- z; ~
//SPEI_END_INPUT_STREAM 表示完成流输出。
, w! b# p8 P% P0 Mhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |' |" ?% f$ i$ F4 _4 @
         SPFEI( SPEI_END_INPUT_STREAM ),
! G3 X6 O: F  a  K            SPFEI( SPEI_START_INPUT_STREAM ) |) F3 P4 j% X0 G% s' i& d5 Q3 ?
            SPFEI( SPEI_END_INPUT_STREAM ) );/ F! r! r3 {3 _8 k4 J
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
/ V7 k( q! }+ }3 s3 U: w    return hr;
6 q& g; q# y5 @}
; e: B4 X" h/ O" T6 R$ R
/ X$ s& F+ t; ~+ g5 }% f//设置通知消息
. |. ?  `4 q2 i3 P$ Uhr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
/ u" j& v, _5 Aif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {: x# H% ~7 A7 Y
    return hr;
9 D7 ]' R' R: h}! a3 u( f" x& Q" b! |, U3 e6 V
5 O6 U! a3 c2 }$ i
return hr;
5 S* ~/ l. N* S) |}
5 v6 r( B' @/ _/ p& L9 g
; y) i0 D  l5 Q2 g////////////////////////////////////////////////////////////////////; r$ x* R, k7 Z9 J5 L; r
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
7 U8 @2 P. U9 l5 c0 V) R//并设置兴趣,设置通知事件。
4 n/ _! q% ~. Y3 t////////////////////////////////////////////////////////////////////
7 W! ?( r8 B$ e/ b  P" M5 k. JHRESULT CTTS::Create( const DWORD dwLanguage )
; {: b7 U, |6 G# [{
% P0 U0 k: n1 h6 X5 C  D6 vHRESULT hr;
2 ~% r1 X2 W# M; u) E5 i+ _hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
) ]! f+ k$ V6 x& B9 Qif ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {( U9 u  b0 m9 F& V. P6 J1 V
   return hr;1 H+ P2 S( m! \: h6 V3 h& A+ C# |
}
; A8 R% |" b5 V" W: u
9 B  \( I$ N6 p" ^+ H/ b0 M# rSetLanguage ( dwLanguage );; W% z. Y: `, I" c: ]. H
* }& e  ^' @; D
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流% O+ a  k* |8 \3 u$ X: ~  v6 Z
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {& K( I9 r$ k4 g
    return hr;
5 q. r& H! D+ n  v0 O0 d& f}
1 }: M7 q  o7 P' ], J, [. o
! A6 a+ E- `# _. q. @//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM( P7 l# _' y  v* B" }2 J; {2 l
//SPEI_END_INPUT_STREAM 表示完成流输出。
' Y) {3 h. u. y8 g/ M) y5 a- C; C+ jhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
6 s& o- c  x2 p8 k3 M& a0 w         SPFEI( SPEI_END_INPUT_STREAM ),
3 S6 a! k! Q" n8 N( z6 m+ B            SPFEI( SPEI_START_INPUT_STREAM ) |* M/ N9 P7 V* z8 T$ ?9 U
            SPFEI( SPEI_END_INPUT_STREAM ) );
4 _# ^$ S& j% o& W( Kif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
0 c) F/ G* O5 R, r/ _' V5 C% A* j    return hr;. V7 d- C# O# S
}
: X& ]7 q9 }  N7 @+ U. b) d. |. u: ^& q% E! c. E/ v
//设置通知消息
5 a4 d3 j$ ~$ i6 m. D: q9 Yhr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );* Q9 w) E' M. R
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {0 K8 l* A/ I5 I
    return hr;" m+ g' O, W2 y# W
}  H! Q+ k* M9 X  a

; M: d0 f! s( U1 H; s$ j# Ireturn hr;
* J1 V" ^9 i6 [}% p* n! y. i2 X% h
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件0 W# s8 S2 g3 E9 y( r( {
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
3 u7 p7 b2 _5 v+ k% M; l/ @# J{
/ t2 c) j/ D( ~# ]    ::CoInitialize(NULL);//初始化语音环境" _. X9 `1 U/ R; @5 A3 _1 k, m
    ISpVoice * pSpVoice = NULL;//初始化语音变量
7 F. ^8 {$ {6 Q- c1 Q9 A    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
2 H/ o. X% A9 U" B+ \        cout << "Failed to create instance of ISpVoice!" << endl;
+ m6 H: }# {2 P3 [        return -1;
0 r' Y3 C' P& j" j    }
& ~# r! X0 }" A: |
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
+ o& y6 e; b5 H. l. Q7 I    ::CoUninitialize();//释放语音环境

2 H4 ~+ p( ^* U/ G; @    return 0;2 C1 [' U9 V4 I' [  }8 m" r4 |
}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序
, h3 u( x, C3 `( C2 h, P6 t- C
* ?6 X" `% m1 D) e( n! U1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
- N* s( Q. D. H! l% P1 i/ H* y2 z' ~
http://download.microsoft.com/do ... -US/speechsdk51.exe   / W, w% F( R$ a/ @
Speech SDK 5.1安装包 (68   MB)     ( y% u9 t/ Z( D( ~6 w5 x
http://download.microsoft.com/do ... chsdk51LangPack.exe      ) i& [5 \$ F1 [% \# P6 {
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
! F* I4 ^) ?& ^( v7 p. }
9 m4 V& \( M  u  ]  \1 q2.下载后,执行安装
" G. R7 c4 z5 `4 _: k% T% [1 r- R) Z- S. v, F8 D& @  q) c6 m
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
5 [+ u4 E4 E0 t/ g% L; x) g! H
3.VC的环境配置
5 V' k- ]4 G/ z' ?
( V) o6 `1 U) E0 l& W& Y& {在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:( k; V6 L& I* I/ C3 T  J: E, M
. }/ C; k6 u2 I$ [9 g& b
工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去./ T/ ~( F' u$ \  Y2 e- o
- K$ u" ~$ Z% @4 u9 j
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
  F& }/ [( S/ ]& B1 a; r( r
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-8-13 22:33 , Processed in 0.019237 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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