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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
  x$ U2 z( b/ Q1 Y* i% {//1,生成动态连接库时,要#define USE_SPEECH_DLL,
: m8 Y, R, Y$ H# Q2 F2 g//      并且#define LANE_SPEECH_EXPORTS. r: ~. U/ u$ d- G8 F$ H# \
//2,使用动态连接库时,要#define USE_SPEECH_DLL
, v$ _: C( _: b//3,声称和使用静态连接库时,什么都不需要
/ U. L; D1 z! D7 s8 P3 l//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),; |; t( n! Q% W+ L* A' F: L2 \
//      动态连接库就不用调用了。
9 H( g& Q- R* ]! r- v# ^! P' s////////////////////////////////////////////////////////4 v5 g- K0 `, Q. V3 y3 h
#ifndef LANE_SPEECH_H9 ^! O$ s/ g! a: T' `/ n2 b( T
#define LANE_SPEECH_H! _& p2 s- j7 m
4 Q! M7 M# Z  f" o) b
#include <windows.h>
* e0 L! r, K) Y/ K$ F! }#define _ATL_APARTMENT_THREADED
- c7 S7 J! N+ {  H. r5 R+ d. Z#include <atlbase.h># k; u2 f6 ~) |+ Z
extern CComModule _Module; //You may derive a class from CComModule and use it. if you want to override something,but do not change the name of _Module
$ _% @8 {2 w( F3 X$ {7 R, x3 a; E#include <atlcom.h>7 f! M1 K$ |% Z4 v5 N$ W( ?% d
#include <sphelper.h>   //sapi需要的头文件, m" D7 h$ E- l# Z0 }; t; P
: X* ^3 t& G# f( w9 W4 x
//-----生成动态连接库和静态库的处理----------------; z- m( v$ \2 r- a+ x' G# ^
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
" O/ C0 w/ x8 f3 y' `1 v% p3 j: A8 Y3 n, U7 Z- b
#ifdef LANE_SPEECH_EXPORTS& ^' X* D6 m8 G1 n3 ~
   #define LANE_SPEECH_DLL __declspec(dllexport)7 b9 F9 u# ]( |, [2 e
#else
, {; J0 x4 w6 q( [   #define LANE_SPEECH_DLL __declspec(dllimport)% t9 R4 Z1 F5 d/ f$ n* u5 P; p
#endif
5 G4 T' \, \: ~. g/ G2 Y
) U  l* l) ~2 F1 o. E; ?$ i//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关; v6 J% s- ?1 [6 B/ k7 R) w: _
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
' N' a8 Z5 C, {5 E! Y#pragma warning( disable : 4251 )1 W8 r8 P7 i5 r+ d  V! U
3 m9 \+ S; \7 d
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)1 E- g4 A; t' P% L6 l
#define LANE_SPEECH_DLL
# E% p; ]3 K0 ~, g1 `' Z2 \
. o. }7 ]: A6 q#endif //USE_SPEECH_DLL
1 u' c& i4 i( m; a
- h' L9 m5 G) ?$ s' f9 H6 E& F& [- p4 d; h8 f
//***************************常量***********************9 n" |. Y" g, K2 B+ G& s! ]

, x, M3 L5 Y' c$ g/////////公共常量-----------------) H2 i: c5 J5 F( {
const DWORD   SP_CHINESE = 0x0000; //简体中文.
/ [: F1 f4 c# `const DWORD   SP_ENGLISH = 0x0001; //英语.8 ^8 h! j( q. e" k7 a) h3 x

# [5 _" P& @& @4 G4 b- p/////////CTTS常量-----------------( U" V4 D% |+ W% X3 N& ~! k
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。% t" b6 R, m6 x9 a& U
# _9 q& O5 o7 T8 |+ W9 s" Y
/////////SR常量-------------------9 W. r- O4 a+ f
const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。- `9 B) ~8 {. j
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
) D* V8 K: K, n5 H6 l/ {" g2 W; Zconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.
( D: H. o& N1 E  `+ [$ m9 z3 a8 \1 j/ {5 ~' j9 V
//以下常量仅作例子用。+ y6 Z2 ~% p; `% \
#define VID_TopLevelRule 9000   //顶级规则ID0 j) y, v$ q: G6 o8 X
#define VID_SubLevelRule1 9001   //子规则ID. o& o6 W+ t4 p8 m  o& W
#define VID_SubLevelRule2 9002   //子规则ID
! W" q: B4 N  Q% h* C% m( ~#define VID_SubLevelRule3 9003   //子规则ID
1 Z1 @7 T2 u/ l3 x1 u  Z
: E7 ^" t6 z0 D9 _
8 o+ s, h2 z- o: K4 `8 \//*************************类声明************************4 y- m* t6 Z% w; g, K- ?% E
; g( F, F5 ~1 C( K$ Z5 R2 M  A
7 l  z3 a! u, z9 u, o
class CSR;/ G% ~9 r/ K! x
///////////////////////////////////////////////////////////////////////7 Z2 F9 f0 S9 q  ^: `9 T2 o
///////////////////////////////////////////////////////////////////////
9 q- Z) M, x6 A3 V$ q' ]- e/ I4 z/ v//
% A. x6 T6 ]) J1 ?  d5 l//         CTTS+ o8 M3 Z' f% p# t' y+ {
//- i* w5 I# }. ~& Q% L
///////////////////////////////////////////////////////////////////////
3 K* c( h2 T5 g( H. O! w% M% N! c( C///////////////////////////////////////////////////////////////////////$ L, \! m7 d( A4 w6 I8 l

) `: ]- w" J, s$ C* V& Tclass LANE_SPEECH_DLL   CTTS+ M1 R4 g( s7 A4 s3 y# e+ S# Y
{
" L$ y. g0 [! S: D+ R/ k! wprotected:
& P7 ]. ]8 x5 o: F; f5 r  `% OHWND       m_hWnd;     // 关联的窗口句柄。; B6 J# H1 u2 R5 P$ B6 K+ S5 }4 H/ B! o

4 Q' M6 V$ p/ F" X  T. ^0 oCComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。. s* _' n# M; B6 A2 S/ L6 I6 |
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
# j7 v8 `2 Q' n! O1 g" T2 y0 e+ `CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)
3 g: d0 F2 O% W, yCComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
0 h4 F& X5 Y  Y
; p" H" w! q6 u$ lpublic:
& F+ E- H& L) ~0 T+ ^7 s. Y//********************************初始化部分********************
# ?8 M& @5 }3 n% v: g: h* F; r/ F0 E. ]8 G/ Q
////////////////////////////////////////////////////////////////////
7 m5 Y! M2 \1 a8 w% N//功能: 保存与识别引擎关联的窗口句柄。
4 m4 L& U, J9 G$ W2 s" W//参数: hWnd:要关联的窗口句柄。/ W/ [$ K& k7 f5 `0 ^  D4 q
//返回值: 无。) n' n) K% z* J" m/ _# D
////////////////////////////////////////////////////////////////////
; g4 X0 d# E3 ^$ N: @CTTS ( const HWND hWnd );6 a9 h$ ^; b! H5 R' V8 L
9 a1 g/ _* r  ?- M" n. c: ^
////////////////////////////////////////////////////////////////////
5 C) d: g) G* ~. t4 ^//功能: 释放所有的对象。
. x+ s0 @  y) r. m( j1 l//参数: 无。
1 F( x& B2 u# f. O. b//返回值: 无。
5 [3 R( |7 B8 }( V: ^  A////////////////////////////////////////////////////////////////////5 [; }4 Q; o$ k2 n4 _
~CTTS ();  S3 G9 e0 q: S% x) H- h+ _
. ~! j# b# k# o8 J$ A$ ~! f
////////////////////////////////////////////////////////////////////0 Y( B: x. M3 s8 u8 g" K
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。# H5 ~3 r+ a$ C  K/ u
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
6 i6 O( `, Y+ p6 ^//    SP_ENGLISH为英文。
! Z6 f$ i! h; K9 D- d8 f  V  m  v//返回值: HRESULT类型。# K9 @9 U) Z1 u, q7 V* w9 ^
////////////////////////////////////////////////////////////////////
$ I2 ^4 ?$ z" L: n+ x9 n& [$ t* iHRESULT Create( const DWORD dwLanguage = SP_CHINESE );3 \5 |8 M& V1 m3 h" z
6 n8 s6 j; q9 m0 V: P
////////////////////////////////////////////////////////////////////8 H9 Y  r8 w; D
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
  Y4 _0 Y" H9 }//    通知事件。
3 y! l) c$ K* V9 E) z( K//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
3 N5 h  \; F! W//    SP_CHINESE为中文,SP_ENGLISH为英文。5 u6 P9 K, C/ g7 I- l# V/ M: ?
//返回值: HRESULT类型。2 D/ p1 Q+ y9 O% l) `" X6 D7 I
////////////////////////////////////////////////////////////////////
9 v% @0 z/ W  FHRESULT Create ( const CSR * pSR,6 Y/ g6 v; t- ?4 ]3 `
       const DWORD dwLanguage = SP_CHINESE );- J- o% a% L+ j- e

5 F& U1 }; L( Y, g# e; }5 V' j0 r. v3 y& }8 r4 `
//********************************设置部分***************************************
* r( k' v. k& B& w. e
$ u' {' P, D$ \& V////////////////////////////////////////////////////////////////////
2 F/ t/ e) X! ]% {. n//功能: 设置朗读声音的语言种类。
$ x( n) C. }& r# j) _//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
# H: d' S  M9 o+ A//返回值: HRESULT类型。; w8 t0 ^6 W' h/ W, Q. k
////////////////////////////////////////////////////////////////////
; Y6 \! }  e9 J- O  K- RHRESULT SetLanguage ( const DWORD dwLanguage );
' {2 Y- R9 M( g6 L4 v, {; p5 u8 k
! x3 ^" V4 k. H7 W3 Q: w////////////////////////////////////////////////////////////////////; r6 t; ]1 F1 m2 @' a1 @& U
//功能: 设置要处理的的事件。4 k0 i$ ^( I9 |( G: ]7 o4 j
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
' K& E& ]6 r# V' a/ t- A' D: S. F8 `//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事( V: V$ v4 V: W) A% s. @: M' \
//    件都会收到通知。
! L8 a0 t' t+ u5 A$ q( k//返回值: HRESULT。: J- C8 R! m4 `4 e; n' p. ~
////////////////////////////////////////////////////////////////////
* Y) f. c3 o  T0 o$ rHRESULT SetInterest ( const ULONGLONG   ullInterest );- S4 P& ~% Y6 L6 O* T
) `6 j6 h( r* @
////////////////////////////////////////////////////////////////////
) y; w" C! u5 N# _3 }# ^//功能: 设置朗读声音的音量。8 q, l$ C+ e6 _2 Y6 m" i
//参数: usVolume:音量数值应该从0到100
7 u9 n8 V, z# s) P$ p//返回值: 无。6 \2 c# N( D) m$ S8 m
////////////////////////////////////////////////////////////////////. G% ~" c9 N) q  x
void SetVolume ( USHORT usVolume );! K* m# W* Y) t! M
, y/ |( a1 Z" ]! W1 ?' q
////////////////////////////////////////////////////////////////////: W% w* I: E: M3 U
//功能: 得到朗读声音的音量。7 i$ ]: M" A  a% ~9 h
//参数: 无。
3 p* K! o+ p) S$ P% N/ U1 ~1 Q//返回值: 音量数值,应该从0到100。
) F1 o, ?- r( {2 O4 D) W7 S: z0 `- q////////////////////////////////////////////////////////////////////
8 z3 s6 @3 Q. W& _& S3 _USHORT GetVolume ( );
+ e7 M  Z# @9 R3 [  |
$ E. D$ s# Y, V$ z' c////////////////////////////////////////////////////////////////////
& s8 z6 l" q5 }5 _' Y1 m//功能: 设置朗读声音的音速。- I& u4 t. z& D0 k
//参数: RateAdjust:音速,参数范围从-10到10。
6 z' p3 I$ }6 e* K//返回值: 无。
9 q# d7 h0 j+ c8 w+ ?2 P- F' A6 K, o////////////////////////////////////////////////////////////////////- ]- m1 ]( @6 u
void SetRate ( LONG RateAdjust );5 g7 N' `8 X. p+ N) l$ T" u+ s

/ R3 K0 A% c/ M0 [+ P////////////////////////////////////////////////////////////////////  T- x6 w8 t" s+ `" p9 a# W
//功能: 得到朗读声音的音速。& G# a; L3 K* \  ?
//参数: 无。
4 b  d& g& A3 _0 Q* V8 y2 z//返回值: 音速,参数范围从-10到10。
( D9 Q; C: q# j/ T! f6 P///////////////////////////////////////////////////////////////////// M3 y# @, }3 l4 ]! A2 ?
LONG GetRate ( );
0 }2 k; q6 X3 Y7 h+ ^; Q5 |, o9 I& W4 X4 i! R
////////////////////////////////////////////////////////////////////
' U% @: @/ R8 u# B6 l  B//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。# x+ u- {3 {7 H9 q. q+ i! U6 g, o
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
! f1 V! I- b- X: e//返回值: HRESULT。- W& O) k9 S) d6 {, M
////////////////////////////////////////////////////////////////////
2 j, }7 J) x* s4 t, |HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");! h; Q3 t9 g  I: Y

  z4 G* C: r. c! U. S9 j" Y# g" k////////////////////////////////////////////////////////////////////
, g. y$ N3 s+ F+ s: R1 o//功能: 设置朗读的声音从音箱输出。
; r6 y) f, Z9 k/ K& J' c' M5 t+ F//参数: 无。. @6 ^8 s( K/ S
//返回值: HRESULT。, F1 b! n! I# x$ O# F/ n
////////////////////////////////////////////////////////////////////
; \2 `$ P  x; h0 yHRESULT UnSetOutputWithWav ();/ N' |$ C$ r1 B3 A/ Z1 f! b
2 Y; Z8 F$ V$ t  S& ]+ g
0 [7 c# X; I$ m& I; N% i# p  u
//**********************播放语音,文本到语音转换部分*****************************% n) g( v) \; l+ C  O
+ [* n( }, U$ `
////////////////////////////////////////////////////////////////////% X7 U1 Z0 T* U) z( p+ @' V0 c
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
& D9 L- n7 n  a+ i+ L% A+ h: a//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
2 h1 J7 y3 v- Q//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
8 ~4 ^% q6 [( o! c8 l//    SVSFIsXML为朗读带xml标记的文本。
7 C9 M- E+ l' T7 J; m2 T# J  c//返回值: HRESULT。2 H7 B/ Z3 r8 W
////////////////////////////////////////////////////////////////////
0 Y4 l4 Y* z  B: }* f3 A0 xHRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
* x  `# K. F) U1 c3 Q' P5 b# R9 }# `# N: C2 B- N
////////////////////////////////////////////////////////////////////% d; i7 A: V& A- }0 \
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
% ?5 T( ^0 D" i9 Z# Y& ?% |- K//参数: 无。
3 U, Z3 M" v2 M8 r# a3 ?% i: {* q0 a//返回值: 无。
. P. Y" M! Y1 X////////////////////////////////////////////////////////////////////% W* C' v" d( }, U
void Stop ( );1 f* w) W7 ~) H9 c7 Q

1 ~% Q" k4 c- Y4 y' J////////////////////////////////////////////////////////////////////
  h, X* B/ a7 ~6 W& {* u2 [//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。8 w2 c0 @& ]! C& i0 |) u4 S
//参数: 无。
$ D8 m4 z( r/ [3 E2 @//返回值: 无。1 h6 ^- j$ T2 L/ k* w6 ~! k2 `! @
////////////////////////////////////////////////////////////////////
  K! |) T/ R) }" q4 l9 u3 F: M; k6 Ovoid Pause ();/ ~, _3 N- j7 K% n2 K" K* n
0 F8 b' b% q0 [) }: T
////////////////////////////////////////////////////////////////////; F& O! x  m8 a) D1 M
//功能: 从暂停的地方继续朗读。
2 I1 y" z6 e$ @: a//参数: 无。
& g. [. G5 `. n  J" [9 F% N//返回值: 无。
8 ]9 ]  F' x8 X7 e- m# w, {////////////////////////////////////////////////////////////////////8 e* P: E* h+ x
void Resume ();
) i0 u, F5 m% D' a  }+ O4 Y* ?( t* j" s' e# k* w

( f. e! c5 q, _7 e/ E. x; A//********************************处理事件部分***********************************
+ B. d" t: p& `3 _- k0 Z
1 F+ l! t, ?* ~6 o! Ypublic:1 i+ G& J5 x0 ]( W# V6 H. f
////////////////////////////////////////////////////////////////////; [, K5 T6 s" U
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
* I7 ^& J$ m0 A* l; W! \//参数: 无。
4 o* S1 x& U8 P0 ]" U* L/ h! l/ B//返回值: 无。9 k9 W; Q4 D. R- l  o5 L
////////////////////////////////////////////////////////////////////) f7 C/ }0 V( A4 K5 B$ w
void ProcessTTSEvent ();
# z' A# b9 B6 V3 o& m
) @7 M0 A. g2 C2 \( P
& l% J5 C% X* e# X# J////////////////////////////////////////////////////////////////////, a7 o8 y# Z' s8 [9 Y; b3 ^6 d
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
, T% x0 T2 S! n( h4 i- ?  x//参数: 无。* C0 P: @, {, F# {7 c* X& F
//返回值: 无。9 {, Q+ H* ?" _1 j, y" N! {
////////////////////////////////////////////////////////////////////
0 O0 J" \) Y' U+ o. r; V7 ]virtual void OnStreamStart ();7 [! m/ w4 m. k0 c1 `2 P4 Z5 b

! X: c1 B% e5 ~* e% u0 N////////////////////////////////////////////////////////////////////
, u4 u- m" T% F& g: J4 `//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
3 H& P0 L8 Y4 D//参数: 无。
* \/ F3 H3 i( `. b0 F//返回值: 无。
/ V& @3 O8 a) x; ~/ ~' c////////////////////////////////////////////////////////////////////5 W# W: s6 r8 {7 ]# Z% O
virtual void OnStreamEnd ();( ]# {9 |( ?2 q; u1 f
};* S# k$ E5 I' ~# j
- G) E! w8 K4 g% n3 {% X

9 z3 J0 q/ ]1 h/ Z- D4 Q/ `! r8 k///////////////////////////////////////////////////////////////////////% n& y6 V% L: J. z0 f% y0 r. Q) M
///////////////////////////////////////////////////////////////////////
% e+ K2 \, x- V# n' ]//         CSR
3 L0 k/ R3 g7 Y( w9 G& E//2 v. g# O3 s6 e" [  l9 D" d, Y
///////////////////////////////////////////////////////////////////////
! }! l% T! l' b- @///////////////////////////////////////////////////////////////////////4 P1 a' a) F$ [" E8 \

. x9 ]; L; H# n. c! M, A7 m8 ~3 D. jclass LANE_SPEECH_DLL   CSR5 @' H& T' Y6 r9 y: m% L) y
{+ t5 l. g" j9 Z

4 v! r7 {4 E) k9 dprotected:
$ p. `* D* P8 w# H6 ~HWND m_hWnd;
  r9 v/ f2 u. s% K7 r: S/ Z/ ~5 q1 z9 K. z
public:
5 f0 f; C" V) e1 I4 pCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。2 ]8 e$ E2 l8 v! G1 V3 P
CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
% W" w# h! u/ ~: F1 j/ a5 K1 E0 gCComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。' u$ h1 ?/ Z' d
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。
" M$ m4 C2 F+ d6 M- e8 m; T  SCComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。9 p2 S1 Y' L  O
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)9 S1 f! S9 R  e' h1 m
public:
( l/ P1 g6 \( M+ P: @static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。# T  N6 n! T9 y2 S5 `0 |# G, {. A
. M, K4 h1 u0 \$ ^

: e4 h) f0 u- O  o# o) I2 Tprotected:9 ~+ `5 a& K2 {
//***************************辅助功能部分****************************************8 T. W" l9 P1 J. l$ m, a5 [: \9 g

5 W  _( E& T/ o" M( y9 U% v6 P2 U////////////////////////////////////////////////////////////////////+ d- `. l$ {& E$ Z" a
//GrammarID加一,每个GrammerID必须不同。
6 a+ c5 O5 B4 g' I0 b  p////////////////////////////////////////////////////////////////////% W2 ]; @5 T! j+ ^8 I
static void UpdateGrammerID ( );! @$ j1 S* M9 e& M- {
, S5 u/ t6 u5 z2 F

% ]( R/ f* A$ v* h. l- wpublic:% s4 p& ?/ _5 ~" c9 H% u
////////////////////////////////////////////////////////////////////8 _4 x" a! ^: `  a& a0 b  X
//功能: 友员。TTS中的从SR引擎中建立voice对象。3 i; B( A' S: M8 D. M
//参数: pSRContext:SR上下文对象的指针。
% D1 C/ k1 S2 V3 j% m8 H//返回值: HRESULT类型。# I$ z/ N+ X0 x0 r. s& S
////////////////////////////////////////////////////////////////////1 Q' M9 T+ C1 y0 C5 p* b: u
friend HRESULT CTTS::Create ( const CSR * pSR,
/ E; o0 z1 r. n2 {/ W6 l0 Q6 J- S          const DWORD dwLanguage );+ l* n5 Z/ o0 H
! _! ]" `! E, O5 u5 a

) [( _  q0 K8 _9 ^" a//****************************初始化部分*****************************************
" k9 u/ b: i( _3 C" @4 g6 E
+ {, T: z. P6 n0 c7 d/ `9 {////////////////////////////////////////////////////////////////////. W" R- ^: F" Y7 |% `
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。6 ]5 z7 {6 w; v2 x
//参数: hWnd:要关联的窗口句柄。
: ?- f2 d" E: U  k: V& T0 p//返回值: 无。
1 z/ c3 X4 K1 Y  R# N' t////////////////////////////////////////////////////////////////////8 }* ^& ^* [, j- P3 n7 @& [; @
CSR ( HWND hWnd );
5 ?/ V, S0 T3 Y& L; B8 O5 f" p' x9 _, M- j  \; X7 _+ q! B
////////////////////////////////////////////////////////////////////
* w8 W' b" d" T0 b" m* ^8 T, {//功能: 释放所有的对象。) W% ]7 ]& M8 X* D8 v; G
//参数: 无。
4 ~+ s; k  n8 o& @, q) I//返回值: 无。3 T/ E, i( C' U+ X/ O+ D  j1 s2 F
////////////////////////////////////////////////////////////////////
/ Y0 `7 U- T) j( ~4 n# S~CSR ( );  X/ s$ ]. B2 \( w. |3 C
$ m1 q/ K. V* H4 J8 e0 F! G) s" [
////////////////////////////////////////////////////////////////////4 z- ?- y( o1 T5 }
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,6 z, S/ j% [: u2 V: W: d
//    加载文法文件。
" u4 U' g3 U+ P# r//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。# ?) \$ k' t9 D# I! ?3 x+ e* K
//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
; ?# A1 r* |+ s' y. z' C/ o//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。- @% p0 t2 Q6 k8 _
//返回值: HRESULT类型。
& Y" j# w# d  l) ?1 [4 z////////////////////////////////////////////////////////////////////
, e' ]2 W# t5 F$ ]HRESULT Create (const DWORD   SRType,
& x7 N" F+ p! H# E7 n; a1 T      const WCHAR   *pwcGramFileName = L"grammar.xml",8 R- D4 x. Z7 b* L
      const DWORD   dwLanguage = SP_CHINESE );
# H  a5 T6 U; g3 d* r  G: [  q1 A) g9 U% Z
4 z3 L6 _2 B! w& n; O% d
//**********************************设置部分*************************************
) l5 R4 O7 W  ^8 Z/ q/ ?# ~/ ?2 }( J
////////////////////////////////////////////////////////////////////& x) i2 ?. O# J1 r8 Z0 H
//功能: 设置要处理的上下文接受的事件。4 k' c, F+ e# D. n' O/ {7 u* D/ u
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
- }& k& Q) t+ E3 N  p' V3 A//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
. x# x: H5 I( c& i4 k1 C3 G//    件都会收到通知。" Q. O) `; P9 Y
//返回值: HRESULT。
8 B* m3 q% Y1 U5 K5 [/ K0 {////////////////////////////////////////////////////////////////////& f' V* L0 Y% J0 I
HRESULT SetInterest ( const ULONGLONG   ullInterest );8 H" F; L. o% d6 l6 n
3 Y$ J* H( q8 g9 r
////////////////////////////////////////////////////////////////////
: A- C) ~; d" O( n* W/ _$ R//功能: 设置某个规则的状态(激活或者取消激活)。6 @$ ~# z/ w  o6 j7 M/ ~
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,
$ i4 f0 V: _" X0 V" {//    FALSE表示取消激活。
' v* _( w0 j; v+ e) ^$ F$ t% V//返回值: HRESULT。. V- E4 J2 T1 |. N
////////////////////////////////////////////////////////////////////
6 e4 }" o/ A( y) d* E: |! uHRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
& R7 D! V/ [5 F  x
8 T* ~1 g0 p/ Q4 \, q3 l& R
7 B; D4 `* a9 f0 k6 d) T////////////////////////////////////////////////////////////////////
- M- u, D3 U. M7 z) L//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
6 T+ S! x) L* g" @' k9 U//    风输入。! S& Y, i# s: c+ |& p5 ~5 i
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
' s  Z8 t+ \* g: M" d//返回值: HRESULT。
* H  ^# @% r" |2 b" T7 S* ]////////////////////////////////////////////////////////////////////
4 ], o) i2 j$ P. X0 M. q7 V; IHRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );3 k1 C9 g# n) z% [$ P
. z& Z/ q' K# I
////////////////////////////////////////////////////////////////////
6 y; Q6 T$ G  c//功能: 取消从.wav文件识别。恢复从麦克风识别。) c. q( Y) I& R/ I) T( J
//参数: 无。
0 g4 Z% H# h2 d7 T% f: Q$ E//返回值: HRESULT。( W- k- H) B0 j. j
////////////////////////////////////////////////////////////////////
2 o% H6 t, G, sHRESULT UnSetInputWithWav ( );* ]1 j6 M. `( p

; ^! Z$ r3 n* m, g//***********************识别开始,结束,识别结果的处理**************************4 w( I" t4 j' W  B; }
, _& S3 S+ m- u, }$ o$ A8 m
////////////////////////////////////////////////////////////////////
. U. b& t3 |1 j& V1 F6 _0 l//功能: 识别开始(将所有规则激活)。
( O6 g; z/ m) S. ~8 X//参数: 无
3 ]6 F, i& d% }( v) U  z//返回值: 无。
$ Z: O" i7 o+ O2 C2 C////////////////////////////////////////////////////////////////////3 J$ {! J/ A8 o# A# h! e' J
void StartRecognize ( );
5 b4 h: z% C' m) h" {; L) {% V! d. l+ ]
7 S! l: T7 W8 E////////////////////////////////////////////////////////////////////+ P5 O8 Q# A+ r8 T
//功能: 识别结束(将所有规则取消激活)。2 }7 w8 o& E# X) o( U
//参数: 无。/ X. A: E& G! _$ U) s7 T
//返回值: 无。: a2 z/ j9 u# w; B" T) b: Y$ {
////////////////////////////////////////////////////////////////////9 ?- D% ^& R0 R7 v! m- b% Q0 l
void EndRecognize ( );
5 p8 \1 C; P7 m4 U3 y
3 u9 x# E, z4 R8 X- Kpublic:" i) q" y- I* a7 c" h4 t. f
////////////////////////////////////////////////////////////////////  ~( `, w/ N+ }2 N) p1 C0 d
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。; x8 }/ k" y0 h1 G( k  h( E
//参数: 无。
. j4 ]' I) p3 q' E" x; Y6 Q; r3 @: @//返回值: 无。
! ~  E# a6 {+ M4 o. [) i" X////////////////////////////////////////////////////////////////////5 ]  o% s9 @  d, w8 f# E
void ProcessRecoEvent ( );
* k) X( D0 j: S5 `7 W* r* p, }3 `5 Z) g0 C; H0 y
protected:
0 H) d- k2 e7 |, ]2 A3 l////////////////////////////////////////////////////////////////////5 F. O6 S% J5 o/ a
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。5 u5 Q8 V: W; A  S  f
//参数: pPhrase:ISpPhrase类型。
0 `% ]6 r1 n* N6 S//返回值: 无。0 g2 s$ q7 {. f" f) E
////////////////////////////////////////////////////////////////////
- ^: }4 ]& Z6 ?& d/ Zvoid OnRecoSuccess ( ISpPhrase *pPhrase );
: q' b) q, v" S; V8 g/ w" S+ u
% K' ?$ V* g+ i' P9 D: y& P5 Cpublic:" O4 ]; @  [2 q% d
////////////////////////////////////////////////////////////////////
7 S0 n! l. u) p, e. L- \//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
6 I+ a# o. B" U; O/ ~//    需要在派生类重载。规则ID必须以常量形式预先定义。
6 Q9 N8 b6 j; J//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
+ i3 {. Q' @! t, f0 ^//返回值: 无。" D1 h# C& X. T" x+ k* h4 y
////////////////////////////////////////////////////////////////////
6 s5 T' B# h( k- j9 yvirtual void ExecuteCommand ( const ULONG ulRuleID,
4 g+ B* b' v% t; t; G          const ULONG ulVal );
* F' ?# q5 N3 b
7 U  q$ W9 h) Q6 M" z////////////////////////////////////////////////////////////////////" S8 N9 G  k" h( h; H7 x! s
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
: i2 e$ b, A: u# L//参数: 无。
" C  @5 R; A- g; i1 O; Y4 u$ F//返回值: 无。
% Y7 d- R5 w: q: |' Q8 N////////////////////////////////////////////////////////////////////
* v& k+ S# G, u/ M4 Ovirtual void OnRecoFail ();
- N8 W8 D, o6 w2 m" D7 A5 g$ W# `7 _
( W8 q6 M- l, W////////////////////////////////////////////////////////////////////( S' J4 Z( ]! C
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。) d; Y: V. T: Q. N) s4 s
//参数: 无。# A& m4 Q! |5 {+ l
//返回值: 无。" ~' A6 {0 h0 d# \$ M
////////////////////////////////////////////////////////////////////
7 {% @! v* R7 a3 e) h( T1 ovirtual void OnStreamStart ();
2 `- ~8 e! e0 u, H- B& x1 ~/ n1 y! A7 W) z
////////////////////////////////////////////////////////////////////
# A' ?  D+ b) i" m' R//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。$ A* J9 ^% }" d$ ~/ ]% c
//参数: 无。
- K" n7 D' B- {" s4 ]: R1 I//返回值: 无。
! _; A# t0 |- g' g& g' U2 u: u9 r////////////////////////////////////////////////////////////////////8 C) i+ p3 W3 Y! f( X) ]
virtual void OnStreamEnd ();
  z$ i% l" e5 f* _! y3 s# r7 e
4 f5 S5 f; f' F% L) S$ d5 V};
; C& h# ^: U1 l$ j. i* J. r, h* [/ Z
) K- [1 h" W% \5 M" F
& F' b$ E; V  F+ N; t* m1 K
: @, {5 [  |( n* u% L#endif    //LANE_SPEECH_DLL_H; y# e0 L! m, \0 g% v5 F0 X
4 @' M5 ~' A/ j: J& f
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" ]: w8 C( w) q2 o9 ?9 K

4 o- k* y( I. O" D0 Y////////////////////////////////////////////////////////
6 ~- G5 O: f# D% t0 N//
( ^  f+ m; u2 \// 文件:LaneSpeech.cpp
# L. m( f+ i5 N3 H) ]: K// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
  z' f3 ~3 S6 C' @& o) y4 |# x) B//    语音识别只支持命令模式,不支持连续模式9 A9 w# N/ u9 H) I6 U/ m( y$ B
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 36199084 a, ~- F/ ^; v) `8 q; k
// 日期: 2004.10
4 |1 K% {" t" F4 k// 版本:1.2; d9 c6 F1 k" {. }! d2 F6 N
// 2 Q  D* y, C+ ]6 M0 @# @
//
# E0 S  |+ W) R5 q+ U+ z6 ^* j////////////////////////////////////////////////////////; g5 G( C# p* Q3 w7 X+ n$ g
5 y3 P  B! }6 d+ M5 z$ n
, S( g- t$ N  ]2 R, S, A" \! j# ]1 E

- }+ h" }9 R$ Q+ o#include "LaneSpeech.h"" l/ E2 {( r7 g- Y3 m- _

, l& g- ?5 {. \' o$ p( g0 P//-----生成动态连接库和静态库的处理----------------
  n1 p, k2 B9 N  @" X#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类' o8 }% ~# L  m: w

( Z3 [/ G  A1 ]* D% \2 IBOOL APIENTRY DllMain( HANDLE hModule,
! O. M+ ~) ?2 ~: `( x. i/ i+ s8 Z                       DWORD ul_reason_for_call, ! S& {( I6 ^$ n' Y
                       LPVOID lpReserved
8 a9 {/ [; E- w% [6 ]1 }+ b0 i: d8 u      )! S5 W3 V: Y0 h" w/ R
{) ?$ X7 o0 j* i& x
    switch (ul_reason_for_call)- F( J* L8 n) Y1 }# S1 h
{
7 i: s) M; r: v( b+ j   case DLL_PROCESS_ATTACH:/ q' \& g; l( Z7 o) K' r$ ]2 \
    CoInitialize(NULL);& p2 z# \+ h1 z3 w4 W+ S: R
    break;
/ ^& M- W- z, Q8 M  % R( j, A$ _. z8 o0 r0 |' o5 j( a
   case DLL_THREAD_ATTACH:: |7 W1 q3 E. B$ B! o/ U( U
    break;
9 {7 v/ D' m% k  X( A) K) G* ]4 e  + H4 U0 t$ `) r3 p. ?+ Z. k
   case DLL_THREAD_DETACH:
3 ^9 q$ a2 N: [: l6 R2 S7 F: B; B    break;
8 E6 S2 P  n5 Y1 ]; }# @* z  
9 Z! M! X# W$ M; T( R   case DLL_PROCESS_DETACH:
) W/ F5 Y1 l  R& p    CoUninitialize();
4 p; w$ ?: I, z2 O3 L0 F( t    break;
' ?+ {: z9 L9 f* v* z6 W* ]    }- |3 Y, B  b7 w0 }5 L5 _, g
    return TRUE;) ^6 V$ m) z$ L/ i4 K" H1 a# a
}
1 v% F! n* r/ @/ x- U5 \* N6 {- ?* t3 E/ b( \
#endif //USE_SPEECH_DLL
* n+ D. |; R  O# _4 N) T
0 C% w8 Q% Y$ \: @" r9 K& ?
- x$ o7 E' J2 a) ?  W: |/ r/ M4 Z6 V; }3 D: S% b
///////////////////////////////////////////////////////////////$ [  h. w9 i& |" H

- O: k0 F* O- M. c$ q& J* d. Y8 t: o/ R////////////////////////////////////////////////////////////////////
8 `2 M8 @9 b, c7 T, ]# ^# ~//功能: 弹出一个信息框。2 s# ~# H4 u' I, O+ ~
//参数: lpText:是对话框信息。lpCaption:对话框标题。' p* x  _) t- H, A( H+ V+ b0 b
//返回值: 无。
# Y/ i# a4 ~; o$ f////////////////////////////////////////////////////////////////////  {2 O6 Q- H/ b0 N- @( R# D, Z
inline void ShowError ( const LPCTSTR lpText = "ERROR",
, S9 x9 l- C8 F, g8 t# j        const LPCTSTR lpCaption = "ERROR" )3 J8 q/ R( I! k9 k! c6 Q
{6 f3 W9 S0 p) ?( b. o3 v  H) G5 M
   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
' ]4 b0 P+ t  S/ O( `}! o3 @& p! Q% p* m5 I; T

% f% `1 |4 z8 I! M6 L////////////////////////////////////////////////////////////////////
; m1 Z3 ~9 A$ X# D/ ]. _: z//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。% X( P6 `8 r3 ?% x
//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
( d5 [$ {! Y7 I0 n8 o9 c//    lpCaption:对话框标题。& |: k2 T# |6 R7 v1 j. j2 l
//返回值: 有错则为FALSE,没错则返回TRUE。
2 R2 K9 P& j' d  m1 I' |////////////////////////////////////////////////////////////////////) d/ @7 E% B# j+ I/ L5 e8 A' r
inline BOOL CheckHr ( const HRESULT &hr,% ^- R' T* O+ l" }* f/ z1 [
        const LPCTSTR lpText = "ERROR",4 {0 m, j; i0 `( m
        const LPCTSTR   lpCaption = "ERROR" )
" x8 H; n" h. X: N8 G6 D{% Y  T5 U: `2 I2 B
   if ( FAILED( hr ) ) {
3 B- k+ @0 i& c# h  y2 B* S    ShowError ( lpText, lpCaption );4 a0 d/ g8 w' n) J
    return FALSE;/ a0 D" T  G, R
   }
( F+ W# a7 m: s7 v& U   return TRUE;
: Z' u7 c& ~( j8 F- G1 o# v* O}! d  T) f, h7 z5 Y& ~

2 q- j# q3 d% p: z$ [' `% w. g) B5 R
///////////////////////////////////////////////////////////////////////
) K  C2 k- e" h- X/ E///////////////////////////////////////////////////////////////////////3 X9 x9 d0 E5 o* V: g) U6 ^
//. K( H; `. P$ S% s. U
//         CTTS3 n/ E4 Z* d8 [: Z
//* S, _5 w3 G8 l+ i+ g
///////////////////////////////////////////////////////////////////////+ H8 X4 Q5 [+ Q8 g( H
///////////////////////////////////////////////////////////////////////
- x; i* v8 _: g2 l; q/ r, ?, C' ?& {) j. q/ v2 M* b% r% h
////////////////////////////////////////////////////////////////////
: q) b# R/ y6 ^3 k2 d$ J0 g//保存关联窗口句柄。初始化COM。- w) u  m# p) x; A4 Y
////////////////////////////////////////////////////////////////////* {! H; P) Q1 j. e* @
CTTS::CTTS ( const HWND hWnd )% J! V4 R/ m* G" i1 D
{
2 f  M' n1 M1 U  a# z! R& d7 C7 Jm_hWnd    = hWnd;. ^* }' |: l' Q: h8 O
m_pVoice   = NULL;  O/ W) U0 z9 o' [+ |5 [# J7 ~
m_pToken   = NULL;7 ^  ], S/ ~- M+ y$ u& }
m_pOutputStream = NULL;
; d# `1 N5 @4 D5 b9 h) Z: bm_pAudio   = NULL;
, X# U+ N& R  H7 D4 M. Z. g}6 ?7 Y4 S5 y4 v3 q

9 z0 _8 c0 f  o0 o8 p" e- J////////////////////////////////////////////////////////////////////
! u9 C5 I" n) d//释放所有对象。9 |% i0 g3 H% }9 q
////////////////////////////////////////////////////////////////////$ H3 o* ~8 N& b0 e
CTTS::~CTTS ()
. `6 w5 D9 P+ \, x+ r9 T* `{' M) }# k8 E( |/ v0 A6 l$ }
if( m_pToken) {
7 N1 e# m% `! l1 S: L   m_pToken.Release();) x/ i; Y- O& E. ?
   m_pToken = NULL;1 @; v0 Q' {/ R( r' z- X
}
  R- `) h. ^+ r8 I- l+ N0 Oif( m_pAudio ) {
6 X" V- A( C* @' w   m_pAudio.Release();; |; `4 i8 {, t
   m_pAudio = NULL;/ ~) @8 c1 p; B2 C) R0 q7 ]
}- S4 K/ g( H9 j
if ( m_pOutputStream ) {# I' T9 h# H2 x0 I
   m_pOutputStream.Release();
$ r; [. Q" |" G$ T7 G/ |: x: E   m_pOutputStream = NULL;6 D& Y  s4 c$ p1 P" }4 m
}
2 D" F8 u  j% k+ w" E8 u0 _if( m_pVoice ) {
: [. ~3 t3 l) ^) f  e. H$ B( o   m_pVoice.Release();8 u1 b1 q" y- f3 b9 ~
   m_pVoice = NULL;4 K) T  X. h' h1 [, K
}/ B, k) `0 l( F# ?4 ^( C3 Y
}: a5 z! i6 v! k$ Z" I

5 c5 x/ W* h) c$ {////////////////////////////////////////////////////////////////////& S3 [+ J$ p6 M1 V
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。' d% z+ R' \5 U1 j3 ~+ B
////////////////////////////////////////////////////////////////////4 @7 H5 U. D$ C
HRESULT CTTS::Create( const CSR * pSR,0 M  |- l: `* C7 X/ P, ]: r
       const DWORD dwLanguage )( |5 j" X! e! }
{
, U( j9 l6 S. w+ s4 i0 GHRESULT hr;
' w) o2 e* K! |hr = pSR->m_pSRContext->GetVoice ( &m_pVoice );* |, A# d+ t; c
if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
. d& b( H1 K7 n7 h7 n3 |   return hr;) h3 U9 m; ]: P$ m# c3 q
}6 s# B! T3 J7 Y: c& A' W

  u9 g  q4 |! l; ySetLanguage ( dwLanguage );
8 P1 P$ V( K" ]2 g2 H
& g2 F$ C! ]* ^hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
- b: w  P( }5 K2 [( d7 Mif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
' j/ s3 W8 [. g: ]' b- C4 n    return hr;
' ~6 h: P& o, i: T- N}% B) p0 Y& b8 F# Y5 |& N
" B( [9 A5 _3 b6 r" R$ R
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
! v# c; I" O4 ]& B& B//SPEI_END_INPUT_STREAM 表示完成流输出。
( C  }1 U- F- u& Nhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
. G% H% w, Q. i  u         SPFEI( SPEI_END_INPUT_STREAM ),
1 u+ D% r3 e/ ~) k            SPFEI( SPEI_START_INPUT_STREAM ) |! Q1 T; b0 f, K" I1 g& v: x
            SPFEI( SPEI_END_INPUT_STREAM ) );
" X& C3 M, f1 E6 _& c4 P+ L# Y4 |if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {6 I$ \+ o2 d" O  u8 S  y
    return hr;
8 H% u$ K! C) `- n; p5 ?}: |# c, `4 \& R# r5 v9 l

( n* V2 y8 c* g& p$ r% c//设置通知消息
2 [+ E3 J. u) C& whr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );5 a1 e) f) n2 I. Q) R
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {! v3 n& t3 e& l  Z) [
    return hr;
9 l6 l- w* k- ~' k: M}
* k: x* d. o* ~, t6 I- I9 m2 t. Y* ~6 l/ K: F  R% m
return hr;
; F: U$ o3 s' y8 z  u}. S4 O: e3 f" V+ C& p
% Y. e8 ~3 K8 w: x
////////////////////////////////////////////////////////////////////! g/ ^6 b7 _, Y6 D. d
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
) Q' X/ j0 T8 r4 p' f" o//并设置兴趣,设置通知事件。$ |6 }* M, S4 E
////////////////////////////////////////////////////////////////////
; v, q" M& u+ A1 C/ ~HRESULT CTTS::Create( const DWORD dwLanguage )7 V6 F# x* x: Z% K9 L$ h/ I4 ]" [
{  L; h! ~5 ^; \8 j
HRESULT hr;
% v% P  w& S0 q( u9 u  ~7 j9 |hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
3 |% i3 F, @# G: |if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {' {& G1 I6 W1 [  W: p, s
   return hr;
+ F0 C9 h% @1 j}
9 }  c) p. |) M9 e7 Y7 X
) N- S5 G( S, K7 T4 xSetLanguage ( dwLanguage );2 f! e8 O8 A' c1 E1 G- _

2 L( y& U6 y2 B( B, h+ K" D" Yhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流1 `' b6 n% m3 P: Q$ V
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {8 r5 v* D3 S, ?6 v
    return hr;9 D% r, C: E5 R, F
}; h' B% c" W/ C. K% x3 ]
' n- n  y. v- p
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM0 R$ R; i" l0 R: U. u4 i
//SPEI_END_INPUT_STREAM 表示完成流输出。
* \% |9 n& q$ _/ X; Khr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
: d+ H5 r# g  G5 V( s         SPFEI( SPEI_END_INPUT_STREAM ),2 h! K/ t: [* s- N/ S1 L' [# L2 j5 E
            SPFEI( SPEI_START_INPUT_STREAM ) |
1 p7 c' P2 J/ c) N7 J            SPFEI( SPEI_END_INPUT_STREAM ) );$ S/ u! m3 ]7 M
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
. Y+ n; I* k3 X) e' T8 ]' f/ `2 x0 D( _    return hr;
% d3 t2 w" {8 I3 s}
9 j1 P6 T# J! ^; ^7 ?( w4 [( S) W! C$ ]) k9 V% e
//设置通知消息8 ]! f$ {& z7 j- P3 X
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
  {- @# {  {2 Xif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {+ Y! b4 O8 @1 a' _6 c
    return hr;
6 l5 ^) H' S9 i& n: [2 T( U}# Y- }5 f( S( D3 S0 ]0 ?
; }* h. l6 z1 W/ j* i
return hr;
( @9 k& a2 O% e6 d1 \}8 U( a1 K" I: \/ C7 y+ h
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件3 r0 e2 K2 A1 \; v+ @' w/ S
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()5 n& n1 B: E- c( U( {* N8 z, G9 Y
{8 ^  |6 V3 E. ?; u) w! i
    ::CoInitialize(NULL);//初始化语音环境
4 }/ N" c' W$ A" u( ~% Q6 Y    ISpVoice * pSpVoice = NULL;//初始化语音变量
# c/ F. w; |; ~  j    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { 2 S) O7 l% L& Q8 N( b( G
        cout << "Failed to create instance of ISpVoice!" << endl;
$ q7 l9 B2 R; I        return -1;
, q- Q8 \4 t( T+ S! P1 L    }
5 T8 d! F! X1 T+ t' W4 X# v
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
( `5 A$ V; h6 [0 `1 e; W    ::CoUninitialize();//释放语音环境
1 J# [% ?% K- n  k$ g% o) {
    return 0;
$ _4 @- W' G9 o, T}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序
( ~0 L6 {( B4 p3 ^2 v$ g3 \
$ h% Y4 j' a' w8 H# d1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地' d3 @9 O7 U" k, l; k0 C* k( B0 s

+ m$ J4 T- Q/ t5 t8 c! f8 n, A$ [1 c) Xhttp://download.microsoft.com/do ... -US/speechsdk51.exe   
! ]6 \) N) n& T- ?' M2 CSpeech SDK 5.1安装包 (68   MB)     
: [9 Z- p/ T  f9 \2 bhttp://download.microsoft.com/do ... chsdk51LangPack.exe      3 Y% U( D% {( u' N
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  5 z+ J6 t; L! P4 D, R2 Y- B# E
9 v- U: W4 E" V  k" p9 E
2.下载后,执行安装% x0 ~5 R; i: D- a, Y- }  X2 A

8 f& g' y+ S. M% {7 B- d下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
$ ^' `- y, ^- A- B! ?2 i; X5 t. c
3.VC的环境配置2 W% [  q$ E/ m

3 l5 M+ k2 W- I在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:% w( C2 M1 X. M+ W/ O  }  w
( {4 `4 v) _$ p, v5 s. m6 i
工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
& B. e7 i; U+ a6 e7 K: S% i6 x
  f) Y9 E$ ?% p好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
' _  l. E; \! C! q
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-6-18 06:05 , Processed in 0.020357 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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