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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////  m' V. ^: L0 _
//1,生成动态连接库时,要#define USE_SPEECH_DLL,
( G9 v9 F4 K( S//      并且#define LANE_SPEECH_EXPORTS
' Y. r# p! S( b+ g" F; V$ ?//2,使用动态连接库时,要#define USE_SPEECH_DLL" c$ D, @5 `0 a: U0 s) t1 |; N
//3,声称和使用静态连接库时,什么都不需要4 f$ _4 Q( g$ Y! K6 y
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),& K; S! k+ Y2 O9 u
//      动态连接库就不用调用了。
% y5 @9 e' _1 @4 A' c, \6 d9 n////////////////////////////////////////////////////////* E" U" u( b- R0 T9 |2 H
#ifndef LANE_SPEECH_H
4 b" |1 ]# ^" e: f#define LANE_SPEECH_H" L& g" [* ?1 z2 |
4 {) B* \9 x1 l( h- f0 T+ P4 o
#include <windows.h>
% t/ p  w" {$ x( O$ b+ q#define _ATL_APARTMENT_THREADED# Y' a6 K5 d% N& n4 i
#include <atlbase.h>
4 q7 y. X: L; j% {/ hextern 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
$ v5 C/ ]# n0 K/ ?6 P0 ?#include <atlcom.h>9 b" G# {: a# h: Z" x1 H: d
#include <sphelper.h>   //sapi需要的头文件/ k: U% D/ ]8 {- e- _

$ V' F% ^3 B  G7 @, I/ ~//-----生成动态连接库和静态库的处理----------------
- n2 }6 f( ~/ C1 b4 i5 N5 o#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类6 h$ ?/ u: u- C% m4 @: K5 B

$ m7 |& p$ c4 B/ ?: R( _" e5 q0 O0 Z#ifdef LANE_SPEECH_EXPORTS* r# B* @! S- E/ v4 v- Y! S2 [- H
   #define LANE_SPEECH_DLL __declspec(dllexport)/ `# f$ b& Q! D7 Z
#else9 J) b% N* ~+ c& r! L) V
   #define LANE_SPEECH_DLL __declspec(dllimport)+ Y& s6 `% G" J! _9 S# g
#endif
: b! s0 z9 q0 n; h) E
3 W! q) H% A" y# ?//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关
8 i: r0 l$ C8 `+ A3 l//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。) X% M" Y, M! L
#pragma warning( disable : 4251 )# ]: j8 B- V0 a& @, c6 [# j3 O7 W  ~

; i2 ?. U  u2 x- R0 N" }#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)8 \# u! L, T% M; k
#define LANE_SPEECH_DLL! s! t3 p1 ?/ V( \- W. l

: Z- p# E0 q8 E4 ?) B  w9 H( v#endif //USE_SPEECH_DLL. R1 Z8 a$ _5 o. H5 p, p* `
  K# {4 O' R  A: o0 v, A9 u

$ Q8 ?1 ]6 h' C- |- ]' f//***************************常量***********************: O! A2 E- J% ], o* P/ V
( ]( W5 @" f2 g! {: T$ I
/////////公共常量-----------------
- C* ~5 `( _* a1 ^( Oconst DWORD   SP_CHINESE = 0x0000; //简体中文.5 ?8 k% _) B4 s: B% S% e+ f4 D5 u
const DWORD   SP_ENGLISH = 0x0001; //英语.
6 A+ Y( e. s' V) d% v- [/ r
6 J9 O/ w9 h; {# K/////////CTTS常量-----------------
- Z. K1 B$ a% J* M  G; t8 ^const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。1 A- y) i# X2 q4 l

+ {% b6 G3 a" B+ n# J/////////SR常量-------------------# v( q% m8 n$ q2 u/ ?; n% y& T
const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。) z2 ?7 K7 t" R
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
7 b0 E3 [! `6 Tconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.
8 p; c9 F  W) c( q. l- u- `6 ~4 Y. T, t1 q0 {9 N
//以下常量仅作例子用。
% k8 x9 k$ z$ @4 V) U/ |  x, y( h#define VID_TopLevelRule 9000   //顶级规则ID- i& R, Q" Q$ K$ l( ?4 \7 B/ {
#define VID_SubLevelRule1 9001   //子规则ID7 ]1 n" \/ p- b! p% O
#define VID_SubLevelRule2 9002   //子规则ID* c6 Q. q  D# F
#define VID_SubLevelRule3 9003   //子规则ID2 z4 _% @1 a/ ?, ]  W% h& N
8 o  M) Y: B2 l1 z5 A, v; F

+ N8 j- A+ s& k4 K9 T//*************************类声明************************: d8 ]+ N# g% ^- }
! g0 f: y* q% K: O- |) k: v+ f
6 `- w. K5 l8 Y. H. Z
class CSR;3 C3 c( {1 B0 O9 h0 n  d
///////////////////////////////////////////////////////////////////////7 ~. o9 Y; Y3 f% @, C, ~
///////////////////////////////////////////////////////////////////////
% A( V' y3 @' X' K/ S0 J//9 D- r/ u. F- R* a: w
//         CTTS
: U7 F! J' D$ M6 X  ]; q9 b7 q) L0 m//
# j$ [6 {- u% w0 z///////////////////////////////////////////////////////////////////////) I% E1 O' I9 j, ^1 ^; W" ^, J
///////////////////////////////////////////////////////////////////////
  l/ g! n' i# O+ [  K' L1 v# C# u) ]$ V: M+ }  W3 s+ a) u5 f
class LANE_SPEECH_DLL   CTTS" j- C) Q, a* I2 a" C
{
, W, ]" ^& I8 M* O! P2 E7 tprotected:. B; G7 P+ Q1 f1 ^
HWND       m_hWnd;     // 关联的窗口句柄。
# U3 `7 B3 \: Z) v4 p9 t. b
" K' r$ Z' P3 P% n( I8 }; m) e& c! nCComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。2 N2 q1 b- e% {; C+ J, P4 f
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。! u. U; x' l) h$ f9 \
CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)9 l0 K) o8 o8 ^- G0 g# O
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。0 \& u: H# s/ Q; R) v& q
. O' Z  w0 h) b! E
public:
  U3 M4 {) z0 c//********************************初始化部分********************
+ ?* j: h6 W$ G0 U& |5 R3 H# U0 S$ t& o8 y# E  f* h$ ^4 D
////////////////////////////////////////////////////////////////////8 G" {( G& Q; u) l- a" q
//功能: 保存与识别引擎关联的窗口句柄。' |1 Y5 P9 Q# N
//参数: hWnd:要关联的窗口句柄。% I& X2 a( i, `9 X
//返回值: 无。
# e, m+ C2 X5 k////////////////////////////////////////////////////////////////////6 j# W. |. J5 z% @
CTTS ( const HWND hWnd );$ X6 ]3 h2 {9 P8 E

/ Y) D( N8 g- ]' U  }# f////////////////////////////////////////////////////////////////////
* w6 i/ q+ U, ^//功能: 释放所有的对象。
" f$ n; f5 c  I' |5 u: W8 T) P//参数: 无。
. y; B1 ?( G9 L* P( U% b//返回值: 无。
' {6 z. O# E1 V  ~) |. H/ W////////////////////////////////////////////////////////////////////
& v9 t: u: Y# k; P" @. ~~CTTS ();
, F- \) ?$ |9 y! ]/ w/ r, p2 F
$ a( A3 b! ]. ]$ [; f% @////////////////////////////////////////////////////////////////////# G) {2 T" `( v7 e
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。% [, c1 E* a: S8 c# C+ g* I
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
: t. E# [" w) e& Q5 z: h2 _/ r//    SP_ENGLISH为英文。
* b" Q. G% X+ c! F9 r9 Z//返回值: HRESULT类型。
- N% `5 _7 j( E7 l/ p////////////////////////////////////////////////////////////////////7 K5 {# I8 p/ h5 |3 n8 ?% C
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );9 `9 G& R# v7 i( }1 g! n9 V3 J

; V% O. K$ n$ c0 U' s! C1 S////////////////////////////////////////////////////////////////////
/ I  r) Y/ w% x" U) J$ [  p//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
0 D1 [4 I4 r0 M& G& r" @& {//    通知事件。
! n& C, Z% z) }2 ]& }4 w$ O//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
# E; ?1 T) `5 q' ~  Q- g9 K& S. C: t0 i//    SP_CHINESE为中文,SP_ENGLISH为英文。
, p+ |; }7 [2 v: n4 J: C8 c9 f//返回值: HRESULT类型。
5 w, {8 i/ ~# M  T. s  m( c8 x////////////////////////////////////////////////////////////////////' ]2 q; P5 l  d+ G  [1 f2 j( G
HRESULT Create ( const CSR * pSR," ~# o! O& a0 N+ F6 U
       const DWORD dwLanguage = SP_CHINESE );
* L2 g2 ]! K  o1 ]8 ?: L& c
! u" O3 g- @6 a( _* T% H" }; F: Z/ E( U% N: H+ \6 Y7 ~5 v2 S( K9 B
//********************************设置部分***************************************
5 u! B" ~+ ^+ z: S; Q) i( R
8 Y( r9 M% K) @# Y////////////////////////////////////////////////////////////////////
! t0 R3 e9 U. P2 Z//功能: 设置朗读声音的语言种类。8 q$ Q' _& _4 e# K: e8 T) R
//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。& |! ?  |: g' g( L3 u2 V! O% ~+ B5 H
//返回值: HRESULT类型。
/ X8 f/ V* z1 c////////////////////////////////////////////////////////////////////9 o( g9 L) {" r) q6 A
HRESULT SetLanguage ( const DWORD dwLanguage );
' @0 b) r( x! `5 L1 h- Q9 H0 b. C1 P$ H3 H3 }& Y5 c
////////////////////////////////////////////////////////////////////0 e/ t( }8 Z5 I1 {# ^1 y( E; g1 U
//功能: 设置要处理的的事件。, V8 \) o* Y- \+ R- U" [" j7 D, T
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
1 z9 t* E# @: z, v' f! o8 N) {//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事+ e. L4 Q5 G, Z! w9 M
//    件都会收到通知。0 P3 E; ^7 q2 C  T8 z) u
//返回值: HRESULT。
. H/ u  c# \$ E3 S* w. N) w5 T  F  p////////////////////////////////////////////////////////////////////3 z. ~1 ]: \% D$ F3 T
HRESULT SetInterest ( const ULONGLONG   ullInterest );
# b* j, X# V7 ^6 n/ |0 `9 @( H
8 A( x+ t) o0 d4 n  i0 e) w////////////////////////////////////////////////////////////////////- V9 |5 B. g; D" ]+ b
//功能: 设置朗读声音的音量。1 d6 Y) J) G$ N% S& H
//参数: usVolume:音量数值应该从0到100
8 R8 p. i  ?- w! ?! Z//返回值: 无。, O0 l2 g# C! |
////////////////////////////////////////////////////////////////////
6 d2 b8 {3 `  e: T& V( uvoid SetVolume ( USHORT usVolume );
( C( y0 {' ^. |5 k2 a& Q
9 L# I* F' I  K7 G/ F////////////////////////////////////////////////////////////////////
( `  S! q1 U4 c, i% V! A//功能: 得到朗读声音的音量。  ?  @( i, q+ j
//参数: 无。
% b$ P7 ?* @, J  p//返回值: 音量数值,应该从0到100。# Q2 y" Q/ U; O# B! `7 ~
////////////////////////////////////////////////////////////////////
0 K2 z) Y2 {0 p6 [+ {USHORT GetVolume ( );4 M& \1 f4 I* w; A; x6 }
! g! o  _" p: ^3 |+ y; v
////////////////////////////////////////////////////////////////////
' I( T! I! l' Y8 A( H//功能: 设置朗读声音的音速。6 a4 h/ d$ C+ u
//参数: RateAdjust:音速,参数范围从-10到10。9 R2 @" H; }: J4 P  q. B
//返回值: 无。
9 S: j! w' x; R: F////////////////////////////////////////////////////////////////////: A4 C' p& C6 f( d% \
void SetRate ( LONG RateAdjust );
$ [2 \- R4 x! Z7 I* n" W8 d- C9 e2 I! [5 {9 q# Y7 I
////////////////////////////////////////////////////////////////////
1 L' R4 G) K, w+ e( N  m5 g//功能: 得到朗读声音的音速。" h* ^* ~! d, V/ c+ |9 G" g
//参数: 无。
4 X4 i) R# o6 d//返回值: 音速,参数范围从-10到10。% m8 C8 e9 r3 A
////////////////////////////////////////////////////////////////////4 l& z& H- q( ~! h. |7 O
LONG GetRate ( );/ l( e, \6 \# r- z: q

; `- x8 p0 R! o5 X' c# n! {////////////////////////////////////////////////////////////////////2 M! S0 ^9 q! b6 h# W
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
2 C; c4 P3 f! n. J' h; ?//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
$ `' V/ U8 |: F  f( D//返回值: HRESULT。
/ I$ A+ C# T5 O" V% X////////////////////////////////////////////////////////////////////7 @" }8 n* d; a& O- L
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");
( i! a' {5 [  i5 d4 D( v
1 v! j; |6 t# h; c* p2 n3 ]////////////////////////////////////////////////////////////////////# J7 u. i: B' Z
//功能: 设置朗读的声音从音箱输出。  }. X% f, o* Z/ v1 N  o& B( m- u
//参数: 无。
# S- L* x) C& h4 z6 e. h' |//返回值: HRESULT。3 D1 i1 l; M" ?6 g7 a* Y
////////////////////////////////////////////////////////////////////6 g# F, V0 l* o# z. r  r9 U2 H- g. m
HRESULT UnSetOutputWithWav ();
, c+ ^6 y; P# B0 ~2 J( k) Y, j4 {; q9 T) F  D* P  M* E
/ z9 e2 E' x6 a% O3 L+ y
//**********************播放语音,文本到语音转换部分*****************************8 ?6 x0 Z; s$ B& v* h' ?+ V
$ ^; ~- b6 u% S2 D
////////////////////////////////////////////////////////////////////2 e) n7 [! ^* v: a8 ]3 g2 U4 m
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
  k. C0 [, D3 M! x2 Q//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
2 w$ T9 r1 `% y7 j; x" E//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
9 V) _0 q) }( A/ d9 z* r7 e//    SVSFIsXML为朗读带xml标记的文本。
) \0 |$ W3 {+ b2 k; e7 W/ U7 u//返回值: HRESULT。; G. _  e2 A5 ~% k
////////////////////////////////////////////////////////////////////
0 G0 S  W3 b* S7 T6 Y: _HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );4 N  W3 O, k% C- S$ @
1 F" d! e, A# |1 F
////////////////////////////////////////////////////////////////////3 `3 R- H! \8 u) b
//功能: 停止朗读。如果朗读为同步方式,则不能停止。1 R7 W  R3 g2 r$ g
//参数: 无。7 q1 R2 Y& e/ e
//返回值: 无。
6 u: t4 ?1 d; p0 E////////////////////////////////////////////////////////////////////
) A8 q) y; H7 [& ?void Stop ( );5 I1 f6 u" L' X" X
0 a5 e4 R- ^9 Q2 ]& {" g  A
////////////////////////////////////////////////////////////////////
: H: }1 G4 e& c9 e% S//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
7 w1 j) G9 ?+ [+ \; e//参数: 无。
+ T6 d5 ^. r7 A+ p# I. h$ h1 y/ e//返回值: 无。
# N" D0 i7 F* c: O////////////////////////////////////////////////////////////////////9 q- H. h& ^1 A6 }
void Pause ();
% n' ~1 I/ K2 U7 Q3 Y8 X" c  A+ |# _- F% E# f+ D( f
////////////////////////////////////////////////////////////////////$ U; x+ k! P( Z' r3 k( M& t& D% |: j
//功能: 从暂停的地方继续朗读。
0 E+ R6 |% P8 ]" h) a( \4 {+ H//参数: 无。
" H0 m0 w+ ?9 p  _" T//返回值: 无。
) F' ^" [  Q2 X* U////////////////////////////////////////////////////////////////////
3 v+ t- E6 c- [; F5 M8 |8 Kvoid Resume ();
7 a* e& X1 R, l5 i& u# d. }5 }# }/ n5 ^! y/ H
: X  W: |6 ~$ s6 d8 r6 T- H% D
//********************************处理事件部分***********************************
9 f# `- y9 F1 b& U; N1 |
" d. P# e0 B( ]/ j  `4 tpublic:
0 }4 p1 R) z% e$ q) K////////////////////////////////////////////////////////////////////
! f& G: c- v" J& \0 v! f0 e//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
* _/ ~! o7 Z, Z3 n+ Y//参数: 无。
; G$ k1 Q( O3 d8 X. S; l//返回值: 无。
3 D- C1 N1 G; r5 {  P% G////////////////////////////////////////////////////////////////////- ~/ _; T, U2 a. o( @: u/ ~
void ProcessTTSEvent ();& }9 Q4 N: ^3 H$ j' P
8 l& k( p: a. W+ w" O1 P" Z' P; l
8 V+ G3 ^5 O8 {$ ^1 h4 Q% x) u& u
////////////////////////////////////////////////////////////////////
- @- s* L6 ]0 ]! E! B( l3 M; q6 D//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
) s! i3 ~3 R* \! X//参数: 无。
8 }0 F/ d4 O5 Q9 U//返回值: 无。
4 u& b/ Y9 b% M6 `5 J////////////////////////////////////////////////////////////////////  I4 g8 o6 R# `+ ?9 E& T4 y3 e
virtual void OnStreamStart ();. @' y& m4 C3 n( R: q: V* D4 v
- v6 p' [0 C( J
////////////////////////////////////////////////////////////////////$ i6 u& P& J! j
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。3 o5 k3 X: Y& b; M# `$ i
//参数: 无。7 b4 G" I/ C/ G( C5 u
//返回值: 无。, A+ z- b8 @, y
////////////////////////////////////////////////////////////////////
, X5 F- u, s) W& f- o4 bvirtual void OnStreamEnd ();' s& \1 Y7 M" Z9 ^5 ]
};
1 u8 p- v0 \) Z4 D6 u4 l4 L# n1 ^& _/ z. F% I( B

3 C, t, e/ f* L7 \0 Z% L; s( r///////////////////////////////////////////////////////////////////////& Y$ D+ b/ `; @" m
///////////////////////////////////////////////////////////////////////2 u' n. r2 R  K: _6 @  ~% R% e% T5 h
//         CSR% x4 K7 A; J/ r5 @. |* `$ l- }
/// ?& P: \% C; G1 }4 e8 G( F
///////////////////////////////////////////////////////////////////////& O6 F' J, w2 w! Q. H# r4 H& ?
///////////////////////////////////////////////////////////////////////8 K" Y) H( S  F+ ?

, |; v7 T( B' `2 f  q! d* Dclass LANE_SPEECH_DLL   CSR) @( U$ x- U+ B7 x1 P7 z
{
8 Y6 c- {" ^7 U; N1 ?# `2 i  K% W% U% i; i& \3 N
protected:6 o. `. A( u1 e+ u* v  D) Q9 n6 I
HWND m_hWnd;
" l! r, J1 y+ C! @* `  p' D. N3 K+ g; T2 x; r0 N
public:3 O. |7 s$ J2 W4 n( q
CComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
9 Q- k8 R; b$ `; S6 Y5 q& WCComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
$ f) c. r% H6 A* X! TCComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。
6 w  e" u: q+ H! cCComPtr<ISpStream>    m_pInputStream; // 流()的接口。
; i: B1 u1 ]: V- H1 }CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。
  _/ U8 w6 W( c1 zCComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
) n1 q4 U5 ?* B. k5 H, ~public:
8 d1 d# _0 l% t; @: p8 ]. I. _static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。* ~7 d) z) u- \/ K

1 [( K+ Y# S6 h' T! m& p1 T3 {# x& q, f+ D4 U7 e' L
protected:
- k& r+ Y* \# X( N! \2 W/ ^8 K! ]  b//***************************辅助功能部分****************************************
" p) m/ w5 i9 {
& V! v, |& K3 x5 n8 ^////////////////////////////////////////////////////////////////////7 E% s+ ~& M; D
//GrammarID加一,每个GrammerID必须不同。
% {+ t. i# o+ i& R////////////////////////////////////////////////////////////////////
5 [6 v- P7 ]: R& f1 R+ |8 }5 ~3 `static void UpdateGrammerID ( );
9 [7 j) ?3 w& ~5 l9 r* @6 I6 d# l# w) s1 ?" ?) R2 k# c

; |- Z# i9 |: K; opublic:
/ t. g4 Z9 q4 |* }////////////////////////////////////////////////////////////////////
, R; M* H: ~2 Z% M) {' r! _  X* o. N//功能: 友员。TTS中的从SR引擎中建立voice对象。3 c/ C+ w' {9 y  X0 R. C
//参数: pSRContext:SR上下文对象的指针。" w* k% f6 [# V8 F
//返回值: HRESULT类型。
  d- p/ w5 g) U$ [# Q////////////////////////////////////////////////////////////////////3 `4 n, R% ~. J, h4 I0 n
friend HRESULT CTTS::Create ( const CSR * pSR,
# i* f, y7 q* f6 R          const DWORD dwLanguage );
$ ^7 D: Z2 ~7 n' S' B- A! K# I8 O9 n9 R+ ^/ k- B
; e2 Y$ _) I7 f  ^* g$ D  E
//****************************初始化部分*****************************************
- B: }. I8 ^, f$ A0 }3 ^' i' R6 ]! w5 r/ P
////////////////////////////////////////////////////////////////////3 C8 {4 a. a5 r* `! V
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。6 g/ }8 R1 t/ o# Z4 T# V( W
//参数: hWnd:要关联的窗口句柄。
* o9 k- F, R: \' f- W//返回值: 无。
$ }0 l# R1 f: ^2 \! l////////////////////////////////////////////////////////////////////6 @# X- L: n' E, ]
CSR ( HWND hWnd );
& N3 O5 H& k4 O$ S- q2 s) l$ @4 M3 R) C) x# Z  p) e# v; \
////////////////////////////////////////////////////////////////////) k: {* Z4 i; E$ e
//功能: 释放所有的对象。; e6 _/ W. H* a: I, z$ ^
//参数: 无。
* [" I/ D, T% |; b) y//返回值: 无。4 O, e/ U% ^, q& ?( ]8 [: A3 R
////////////////////////////////////////////////////////////////////1 i( a) H0 `/ P
~CSR ( );
; P3 _  G3 T  E+ _3 ]4 x# i- ]! B/ j* D  H: D6 u% l" w
////////////////////////////////////////////////////////////////////- X4 d1 f) n! ?7 D
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,4 v8 w; d8 @5 ^/ \2 s" D
//    加载文法文件。
% y* }  _! r1 @) R//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
7 V/ R* K, f: J. D8 }, I8 L" E//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。. t& s, p: N; t- x
//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。
% q" F1 S- T7 f( D3 R//返回值: HRESULT类型。
$ s: D+ P# [" P1 B5 k( K* u* T4 U////////////////////////////////////////////////////////////////////; t3 \0 n% n. k+ y
HRESULT Create (const DWORD   SRType,& j. X0 I6 e5 M+ {9 G
      const WCHAR   *pwcGramFileName = L"grammar.xml",
1 E* w& ~+ S' ]4 Y( f      const DWORD   dwLanguage = SP_CHINESE );
/ S- M5 Y! Q8 |' w/ Q4 M. k% Q3 q, {' o- p7 K: }8 e+ Y; t, S6 s

/ J2 {7 E6 _# R0 L4 T; \. v+ E//**********************************设置部分*************************************$ D7 |$ W9 s( q. P9 X2 i7 b! f

8 X- Q- l# j: ]9 F6 i////////////////////////////////////////////////////////////////////; @4 k1 P( B  @+ P
//功能: 设置要处理的上下文接受的事件。
5 {0 D  b5 P7 B  r- R//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,2 e6 p; v& P+ g9 Q! t% J) P
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事' s" V7 d4 U" r8 R* S
//    件都会收到通知。; L- I( B8 R5 \  A! U( t- k1 F5 ^
//返回值: HRESULT。4 K% ^$ m+ ], x0 O: ?5 c( ~% z
////////////////////////////////////////////////////////////////////
! [5 o1 M7 C# X1 U0 h4 ?5 Q! ?HRESULT SetInterest ( const ULONGLONG   ullInterest );/ m* p) o* B: \; K3 J" c. S8 J( `
! q: r  m( H2 ^1 @4 Z% J0 j1 z
////////////////////////////////////////////////////////////////////, P. q# w1 S" x$ e5 o$ b
//功能: 设置某个规则的状态(激活或者取消激活)。4 l( q, {7 o; F" G, g( Z4 s: C( z
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,
# d* `6 J( h0 z5 n* V( q7 n2 p//    FALSE表示取消激活。
( R$ S2 O# E0 h4 @2 B//返回值: HRESULT。/ L. b; _' A1 T8 {
////////////////////////////////////////////////////////////////////
1 h. J" e' d' q( N% @0 C5 ?HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );" {, M7 W# ?# A& E" u
% Z* o7 |' z3 e; N1 I

; \; o* K) ~! y: Y+ M5 R: i////////////////////////////////////////////////////////////////////4 A/ Q8 d( l2 Z1 V' j! T
//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
; i7 R  y: Q0 n3 i  r0 }//    风输入。
  v/ ?- G, ~5 O% z" Q//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
$ A% H: \" s  P+ ]//返回值: HRESULT。' [( E5 i& }* I$ n- c. S
////////////////////////////////////////////////////////////////////
# F$ ^& W% Z. q+ b5 mHRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );2 |2 p" e. k1 i7 }

) F+ n& @; m' o9 H  j% v////////////////////////////////////////////////////////////////////# o/ \0 V3 ?- g3 e% e2 _, B* |
//功能: 取消从.wav文件识别。恢复从麦克风识别。
0 `# ?6 L  j" [$ L//参数: 无。; x: J5 J( ]) {$ A
//返回值: HRESULT。
2 d" l" ~; g* Z( q( ]- |& I2 ]////////////////////////////////////////////////////////////////////
( `1 ~( t6 l0 w; k7 e; lHRESULT UnSetInputWithWav ( );1 K% M+ i- n: s5 }4 O
1 l% p* N& S6 q! u/ |
//***********************识别开始,结束,识别结果的处理**************************
: c$ |# g6 Z3 n/ t
* S5 W( A7 C& ?. r4 f+ J$ w////////////////////////////////////////////////////////////////////9 t$ v0 P3 r6 R0 a$ D0 m! |0 ]
//功能: 识别开始(将所有规则激活)。" Q" F5 j+ V" N: c; _& \& h5 I& _, b8 S
//参数: 无( W; `$ F. S# K. R' I
//返回值: 无。
+ P/ d6 h1 X9 D$ Q0 _: P9 x////////////////////////////////////////////////////////////////////3 X6 k+ S- d  f; `" n' V" P
void StartRecognize ( );- v( K) i. [" Z# K
- f, F- r& ^. f3 r) M
////////////////////////////////////////////////////////////////////
2 w- `  s( m0 {: f; n, }//功能: 识别结束(将所有规则取消激活)。
: c$ m# ~3 b5 F0 ]% U* V* V: ~& U9 M. y//参数: 无。7 _& S3 V* [) d, _3 S% D! a
//返回值: 无。1 [) Y* b3 z8 e" {! b
////////////////////////////////////////////////////////////////////
; h9 d  ]2 l* `void EndRecognize ( );
$ f: ?+ u) c! c' r, g, a7 r: H3 G$ e. B3 ]) L% X
public:
3 W0 q. m6 Y, X; V- u7 x6 \////////////////////////////////////////////////////////////////////! w8 }: Q  T, U1 ~- \- V% O7 F
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。+ C7 P1 T* X5 ^' D+ i
//参数: 无。
. A, Q  f3 E/ i//返回值: 无。
+ S/ q' W5 a3 V' E; Q////////////////////////////////////////////////////////////////////( A7 x( |9 i& D8 O5 I5 v) U
void ProcessRecoEvent ( );
$ q1 @& T$ u: _, K6 I+ v7 h
  K) D; o1 B  F( Qprotected:2 `& b% C& ]8 y: u
////////////////////////////////////////////////////////////////////5 N: A% h4 A2 T3 ]
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。" n. s! D* S4 W8 l
//参数: pPhrase:ISpPhrase类型。. \0 {$ m7 g0 h- ?
//返回值: 无。
# R: g5 K, P5 g7 j! t////////////////////////////////////////////////////////////////////
6 p' N. h' M; p! E. @0 ~void OnRecoSuccess ( ISpPhrase *pPhrase );
( e$ }' P/ W# x3 l2 @+ w2 O$ Y' x6 m" \0 t$ E8 P+ V, y/ _7 ]1 r
public:' }* S# k: Y, v# w9 h
////////////////////////////////////////////////////////////////////
+ S; \% E! I+ H' M* |5 W/ b4 B//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
& D- {6 M3 X% T0 u( x1 ?1 o9 d//    需要在派生类重载。规则ID必须以常量形式预先定义。
* R- q, M' x9 C* Y, l//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
0 E9 X. L5 C; S3 Q  x! L; c0 b//返回值: 无。
& |/ r8 k: T7 `( I3 t8 }) i////////////////////////////////////////////////////////////////////
- `7 q5 y3 K, Y. p% hvirtual void ExecuteCommand ( const ULONG ulRuleID,
0 E* s% ~5 Q9 V, d4 L$ t          const ULONG ulVal );
. s& z5 j' z9 R' @1 }8 b' i% y2 g' E; Y; }. u9 w) b
////////////////////////////////////////////////////////////////////& B4 A! y; N" r; |
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
% y7 I! {( W/ g6 H" w& \//参数: 无。
/ l/ Q8 \! a/ F$ T% \% h//返回值: 无。2 u* b7 b0 {: C
////////////////////////////////////////////////////////////////////; f) L( A# i2 O6 V$ A0 S
virtual void OnRecoFail ();$ d$ n4 o) ]: O& a2 k  y* m

& S( ^8 y% e3 J////////////////////////////////////////////////////////////////////
: B1 x- U& @( E' Y7 L  A& G//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
+ x* K9 F3 o2 B//参数: 无。
9 h) P( T9 ], a0 k( T1 A" G//返回值: 无。7 T& d! I2 m4 G) j1 l3 _8 r
////////////////////////////////////////////////////////////////////
* W# B' f* u6 \0 J( Pvirtual void OnStreamStart ();
. k+ ]# e! W. c9 J* y/ D* O% o: ?" G% M5 `9 e
////////////////////////////////////////////////////////////////////- R3 X/ }7 S2 I& r' K- L
//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。( o( i: O. {) J( U7 t4 `
//参数: 无。
& I! d+ w4 V. }" \9 s; \* d//返回值: 无。
5 O& X$ T& l$ L+ S1 s( X////////////////////////////////////////////////////////////////////) w- u+ R5 ~5 e  \
virtual void OnStreamEnd ();5 I- U6 t# \1 Z  G4 I
4 k4 S. e5 H' o0 |
};
3 |6 P  n1 c' h7 o0 t2 `. x, D$ K" n6 Y/ {! b6 T; o* m

! q# T2 }% W% }% n, c( u+ V
+ ?! A. L4 y% {! I4 U) v6 H3 N#endif    //LANE_SPEECH_DLL_H
7 l. c6 d* \8 U" R
+ ^$ i2 X( @9 i1 W3 q1 O///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////$ ]$ B7 M, t. B
" h0 `8 J0 l% e4 n. k
////////////////////////////////////////////////////////; v9 _! L5 D$ w
//2 }2 f6 ]- ?& ~# h& }
// 文件:LaneSpeech.cpp
9 Q* m+ \( b* z8 U+ \2 B// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
& M4 D. s; T, g- o//    语音识别只支持命令模式,不支持连续模式
8 R& m5 Q. f7 K8 _; `, `( v% P// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
% D2 [: X2 J" A# \3 B: l// 日期: 2004.10
8 }5 x  }. M, |( u// 版本:1.2% z' p! t5 \  N
//
, N$ _6 S* g, ~( p9 r: @" t9 k//
+ J9 {" E9 x8 y. @////////////////////////////////////////////////////////
" i" }8 n/ b' u8 f% h" @2 N# u" Z6 }2 J; ?' F3 x! p$ g8 Y

6 b2 E4 [# p+ t5 L2 z; n: T$ r
+ s1 }" }5 x( T6 `  |! M#include "LaneSpeech.h"" \" s* }1 |! U+ N5 l

& l/ h8 z0 O# Q$ t) `//-----生成动态连接库和静态库的处理----------------
) N" j" ^5 v( m+ Q/ x1 P4 i#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类7 v$ M! d) Z- {0 g# U6 L8 p# b
  t' E' k% k. \+ _8 N2 L; _
BOOL APIENTRY DllMain( HANDLE hModule,
1 i. N$ ^! l* K/ g                       DWORD ul_reason_for_call,
" f- Z' U' _3 I! N, q1 e) `3 h                       LPVOID lpReserved& T3 U! O' \' ]9 ^' l
      )+ G. V, h& [* |, u0 G" a
{
- `1 o3 @% [. b$ I4 b* V8 ?  B    switch (ul_reason_for_call)
: t8 V. p3 I- u0 o{
* K% H+ K6 x8 R3 s& X( p   case DLL_PROCESS_ATTACH:
# o% H5 v; k& y( h  d$ f    CoInitialize(NULL);4 x: k/ r" z5 G) Z
    break;! \# d# Q& I8 A( F& b
  
, \0 B; f% b4 D   case DLL_THREAD_ATTACH:
' r8 d9 S! B" @. n0 o    break;
$ u' c: m9 S. l9 W$ p  
& i( _( s2 c; I5 W- E   case DLL_THREAD_DETACH:+ H- E! n  o, G8 u
    break;) j. u2 W  v- P, Y
  ! c$ h4 l: V: B! V3 s
   case DLL_PROCESS_DETACH:
" q; ?+ a; b( d+ v) _5 P% J5 i    CoUninitialize();
6 r$ d6 i( D" {% E5 J    break;% d0 ]! ~' p2 x( T- D+ l  v7 X% H
    }
2 R7 U- D9 _6 J7 c5 P    return TRUE;' k* }1 ^2 l, Z9 c% t* ~
}0 b$ Y, @: q! Z

* ?% `0 N: `; j+ r( r#endif //USE_SPEECH_DLL: U9 \7 A9 t+ X1 W) G  F

' D# Y+ k' O- b4 T# m' k* Y
1 j1 K- b7 y2 R6 c
+ p% j5 j6 I  j4 H0 v' Z6 ^) C7 }///////////////////////////////////////////////////////////////
! p5 t) D% e; u* S
& z) @5 ?$ g+ j////////////////////////////////////////////////////////////////////1 Y% |1 A! ?5 c# j& \  I8 M
//功能: 弹出一个信息框。2 R( V: V/ c0 `8 A
//参数: lpText:是对话框信息。lpCaption:对话框标题。5 e8 v+ X4 Q2 P, s. \
//返回值: 无。% b) A& R/ D. L
////////////////////////////////////////////////////////////////////
3 ]0 H! e+ ?8 xinline void ShowError ( const LPCTSTR lpText = "ERROR",
3 ~3 [. Z; O- k6 d& x$ q        const LPCTSTR lpCaption = "ERROR" )
7 D9 S, W1 q# O2 h! q- k/ I{
  {" e; M6 i' Q9 [; O; E4 A   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );- _! [: {2 d$ X) b$ c' w
}
9 s, ~# Y( J: h- O9 \" F1 m
' R0 T2 Z4 R* l+ _0 B1 Q////////////////////////////////////////////////////////////////////
5 ~" _- y6 X1 U//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
$ }& i1 e' H  J//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
, N* E  m5 g) a- \//    lpCaption:对话框标题。7 E9 u( _" n! ^( s+ h
//返回值: 有错则为FALSE,没错则返回TRUE。. {$ o* ^, k! X) u8 z
////////////////////////////////////////////////////////////////////
5 B2 X1 f& |( @" pinline BOOL CheckHr ( const HRESULT &hr,
# j% w0 K6 a1 Z2 @        const LPCTSTR lpText = "ERROR",* u, M; \! h( _0 m- [2 |
        const LPCTSTR   lpCaption = "ERROR" )5 I" _# B. m0 [- o+ p$ i
{- f5 u' U/ B8 R4 y  P9 W
   if ( FAILED( hr ) ) {
' v( U4 s3 v% H+ `; v    ShowError ( lpText, lpCaption );2 A' ], S: e+ P  `" m
    return FALSE;; z9 x* Z/ A; e) ^; s
   }
9 C; T4 j- A* Z* M# x7 Q6 o   return TRUE;
6 R! \# t, U6 t}
( a# F# k9 b; t/ h$ n4 p" a1 {4 h6 a
% ^' w) m% p- ?) _8 g0 Z
///////////////////////////////////////////////////////////////////////2 |$ [/ A+ o) T/ P  `3 S
///////////////////////////////////////////////////////////////////////
$ R8 g3 z  Y% ]- L//' J4 W; Z$ b9 H. k3 E  T
//         CTTS( o" q* D# v) t* e) \& D, u
//
/ `7 A& i# w' @  _/ z0 G2 x///////////////////////////////////////////////////////////////////////
; C, Q& P$ k+ L* R2 }, [///////////////////////////////////////////////////////////////////////( s; Z3 L+ N! b: R

/ A. _- V: v  j0 u. ~( X////////////////////////////////////////////////////////////////////
' _7 d* c7 U9 V# N/ U4 h- s//保存关联窗口句柄。初始化COM。
7 F: r0 S4 v4 A" X9 n5 w% z0 V! [////////////////////////////////////////////////////////////////////6 S- G7 E. I4 R" E& g% G
CTTS::CTTS ( const HWND hWnd )
: `( `  O7 B  t1 z+ a+ K1 v{
/ O* x( t0 `  ~# [" o1 X+ Vm_hWnd    = hWnd;
) r2 k0 _- ~$ v: bm_pVoice   = NULL;! l7 \1 m& F; n+ b8 x
m_pToken   = NULL;
; E% Z; f& M; T. f4 x* H* R6 ]& Vm_pOutputStream = NULL;; ^. z: M9 u4 }" }$ `4 f
m_pAudio   = NULL;
0 |! a7 y  ^7 y! l}6 k# a( ?9 L7 i; [1 h5 T2 @
& U+ K* n$ O' |0 m- i+ ^0 j. }
////////////////////////////////////////////////////////////////////- x8 ?- Q" m. ?$ X2 |
//释放所有对象。
$ b7 L7 N: c9 ]7 `3 o3 L////////////////////////////////////////////////////////////////////8 a6 B% `/ Z$ z7 f* Y
CTTS::~CTTS ()
. }1 N$ w2 y% n# R: u{% X# F& W: k7 _1 R% `6 M
if( m_pToken) {) h' i! P" ~/ P4 E3 w; g4 n/ R, W& ?
   m_pToken.Release();3 ~# O+ r; Q( V  d
   m_pToken = NULL;
0 D" {1 {5 R0 _, j1 R& s}2 I0 s* C9 ~. T
if( m_pAudio ) {
3 Z% O1 w7 f4 _' M* g   m_pAudio.Release();0 ]# T3 {, s4 T0 ?
   m_pAudio = NULL;% q5 ?8 h* m! x- \  ^
}1 i3 \) O+ q' E% O
if ( m_pOutputStream ) {
$ M+ d  Z5 [3 E7 w* f   m_pOutputStream.Release();6 }1 k9 m- ~1 k4 o0 K; f/ z0 G
   m_pOutputStream = NULL;
5 x( v3 E. H7 e- F: T' S2 ?9 ]}. Q3 i" z' v9 L# {9 ~4 J) c
if( m_pVoice ) {2 f; m: \5 g6 c/ {# V- M; {5 k
   m_pVoice.Release();
5 j7 X% Y% {* e+ ^9 u+ K* V: U   m_pVoice = NULL;
7 \7 ~; r3 I4 l& j}
2 H# j1 A7 ?8 \5 J( @7 J0 y8 u}
  o- F( y' W0 W1 I4 @
1 O1 i% q0 O$ }1 S////////////////////////////////////////////////////////////////////* S6 V1 F+ {2 F+ ~% T
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。/ f1 B% {0 _) O7 V# @
////////////////////////////////////////////////////////////////////
2 o1 `( s! i! `8 L& |' q! u9 vHRESULT CTTS::Create( const CSR * pSR,- t& m# \) m5 Q0 s) j% h
       const DWORD dwLanguage )5 a3 t; k$ u6 {) H6 Y7 a5 U: ]
{; l$ k2 G$ A5 v- {/ f: l7 w+ ]
HRESULT hr;2 K: O7 a& Z  ]+ u
hr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
$ v! b: E) {$ ]# Rif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {- x# z: [6 n" p% z  h
   return hr;: L' K& k1 |8 t0 {* m! p+ w
}
- _2 L4 a: |7 @! R+ T
0 K$ T! r+ D3 c- w1 o8 ?( O7 _1 NSetLanguage ( dwLanguage );
9 K6 R( {  J% X' f% [  J" t. }
) W" u3 }* b& U' |' d1 Dhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
' E" {0 ]2 ~+ o5 E: z9 u: [& uif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {, E6 G* V$ A8 c9 y1 X( V) p
    return hr;; {4 A8 h/ N0 Z! e
}. m1 v8 \1 d2 r$ X. `* |! K
$ ?4 i7 p5 R& C4 B
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
! A! J1 i3 D! f  }, c//SPEI_END_INPUT_STREAM 表示完成流输出。
% B* I" O4 q; |1 Chr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
/ ]7 M! x$ b7 n% b: n) c         SPFEI( SPEI_END_INPUT_STREAM ),
2 q) s# y' J3 q) H4 f9 o9 g/ F: \6 o            SPFEI( SPEI_START_INPUT_STREAM ) |
+ _& n& m( p2 s: o& |            SPFEI( SPEI_END_INPUT_STREAM ) );, R8 q- f4 w$ h( |2 E; }2 K
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
1 e" \  K# x7 v2 o5 C    return hr;% F; y$ e5 Q/ A5 I: k# t
}. @0 C, @; G- ^+ _$ x! \6 D
8 q+ c6 E) p8 s
//设置通知消息
/ |& E# o# R9 @# t6 N" h+ \' yhr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );5 X. U! p# h, C3 a4 B6 h8 U; ]
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {1 y% d" i& C- |0 q
    return hr;
* D, n$ F4 L9 O' l1 n2 z' B}
* l' i' c' m' V# ?4 i0 T$ u2 c
return hr;
8 |3 z8 S" d/ H  j- e' y4 d9 N' V}8 d5 k; b  N- ]& S  F1 g

$ Z6 Z  {: p6 d- [  }) x////////////////////////////////////////////////////////////////////" e  F. o$ k$ N. y: H
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。8 Z, q. V) t3 b; f6 h1 o3 K
//并设置兴趣,设置通知事件。0 }' p7 T( t! A+ w
////////////////////////////////////////////////////////////////////6 V3 n' K+ Q6 e) Y
HRESULT CTTS::Create( const DWORD dwLanguage )
+ j0 s# `- a9 u' O9 g: A{$ g) H2 C4 U$ Z2 R7 f* [. f
HRESULT hr;
- s: O3 F. y) k# M! e0 E: vhr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );" t# }8 u9 a9 f$ x, u  e
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {
" _* H, {0 f% A9 M   return hr;
0 ~# B, F& L2 N6 b" u5 z: H}
# b' _) _, @1 |( D; O$ o
! ?2 l, E6 ^! m$ h! C; ?SetLanguage ( dwLanguage );
+ X, a5 d9 |8 S4 p
4 C  r; ]3 P* `, ]8 @hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
: x# t1 z) P. J0 _if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
- z- Y8 |& z$ h! `& j$ L    return hr;* ~  `0 ?* k' R4 ?: C7 _
}
* y! z1 S8 |' w% F
8 c- y  v! f1 G, g5 p5 G' o//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
) ?; b$ |1 ^8 R" y//SPEI_END_INPUT_STREAM 表示完成流输出。
7 ?0 N( I! n8 Z( m2 e, c) thr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |, ?& H. o# ~: B- S" K
         SPFEI( SPEI_END_INPUT_STREAM ),  P. a1 O; t, g5 q1 I) d
            SPFEI( SPEI_START_INPUT_STREAM ) |
4 \4 v( ?; H  h& x7 ]% |            SPFEI( SPEI_END_INPUT_STREAM ) );) ~# C4 o' v5 ]+ A7 c2 X. L4 T
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
. q' }1 o$ Y% l3 J* |    return hr;: N$ z  W1 `8 `7 H" E: f' i
}
$ S, z  \$ T- e# G
1 W+ N& K1 X* h8 @  R! o& Z//设置通知消息0 Y1 k2 ]$ D7 P3 {' T
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
$ V/ f/ R  v, m% _3 Dif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
8 Z( ]7 k+ x! O" r/ r7 _; R    return hr;3 d, w' K" Z. r, Z5 P
}/ v- @9 D! _$ ^( Q

/ k2 \2 l" W# Sreturn hr;, y/ h7 z* q1 A4 i2 J2 w; `- `+ `
}
2 C% f7 l1 _, f  P0 F: V* X' |8 z
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件# }& L: j0 E9 L, L* i7 c
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
/ K  V. P! ?. G) E% V( s7 H( O{5 [% ?0 u: e5 B5 `$ T/ ]/ c* c8 C$ Y
    ::CoInitialize(NULL);//初始化语音环境
* J4 h/ X  a: Q" t6 i% K    ISpVoice * pSpVoice = NULL;//初始化语音变量
6 Y0 W* G* i+ a- v* o( o( N    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { 4 @6 m( s8 m( z$ Q
        cout << "Failed to create instance of ISpVoice!" << endl; 2 h& ^3 D9 x2 ~' j. p( L" R
        return -1; : [8 {% G6 ?9 U
    }
7 C5 W1 B5 f% _( ~% U' A
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量9 g) B. W- C9 J2 g  d; i- ?
    ::CoUninitialize();//释放语音环境

4 S6 b3 s0 n* F$ \    return 0;
, v$ Y5 S1 X% U: P3 q* X}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序! R. G8 O1 ?& d: S
" D9 ^) ^3 e  {, X9 w! P
1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
1 Y! ^0 ~+ {9 x! U; {8 R
' ]; G9 T) I# V1 Z, n% Shttp://download.microsoft.com/do ... -US/speechsdk51.exe   " z/ e; [7 z- S
Speech SDK 5.1安装包 (68   MB)     
: i* r; ^) o9 \7 t0 Phttp://download.microsoft.com/do ... chsdk51LangPack.exe      2 t( W$ h: {- w# E
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
" d2 W' u( i6 J3 y% F0 F/ a* {/ x. y0 Y( }$ t- M5 T  g9 Z
2.下载后,执行安装
% @, q4 R8 H  T1 y5 `) c# r! B3 ~+ u$ W; J3 z
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。/ P5 U' j1 Q1 Y; q

0 k7 z! E  O1 F' p1 I3.VC的环境配置
' h2 k2 ?* {+ D# H/ l( S9 U% d
. A3 v" @3 @5 z& h  v9 b# i在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
' h: \$ T+ D1 D& l$ F( W& V3 o1 J/ p: s
工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去., F3 P9 w( ^) F7 j
2 X4 _# [. _' ^7 i
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
) k' \" X  r7 t4 M5 K) {, \- F
回复

使用道具 举报

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

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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