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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
4 E" U' w% A8 Q//1,生成动态连接库时,要#define USE_SPEECH_DLL,% f1 N0 G; D) S8 M7 y9 M. o1 A
//      并且#define LANE_SPEECH_EXPORTS( i# i) f  b0 Z$ P( p$ e
//2,使用动态连接库时,要#define USE_SPEECH_DLL; i7 C  m* n: h/ P4 Y  |) K
//3,声称和使用静态连接库时,什么都不需要
  I+ I; H5 [7 `( N2 ]2 P* L  w$ I//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),
. h5 H0 M3 p9 W3 X8 f0 i8 G//      动态连接库就不用调用了。
' ~8 F! i: g& u* e: \. W8 D////////////////////////////////////////////////////////
2 d4 b( [; ~3 P#ifndef LANE_SPEECH_H/ I+ l6 ~5 k6 M2 U& J- f; F, P
#define LANE_SPEECH_H5 J& y; J. D4 I

) G& y3 S3 F6 w. f7 y% f+ e#include <windows.h>9 @) R8 V; Z' Y0 }6 C! h
#define _ATL_APARTMENT_THREADED
; V7 f" c- x% X- O#include <atlbase.h>* X! Z: W; l/ Q( _; V7 o
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
' r( M# A4 k7 j% |# n+ ~# v#include <atlcom.h>1 S5 W! X& N) z9 o6 Q5 _7 l0 b+ l
#include <sphelper.h>   //sapi需要的头文件
1 J9 v' S: F4 _- M4 G1 t" u( K: O8 r9 \
//-----生成动态连接库和静态库的处理----------------
# D# D& [% ^" R5 b, k1 V+ _7 z#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
( ~. V9 o! L1 l/ n% h4 V7 C9 F: X  w- Y
#ifdef LANE_SPEECH_EXPORTS
" [( }! s, [& y) w% [' K$ e1 x   #define LANE_SPEECH_DLL __declspec(dllexport)+ [, e: a! E9 C5 M0 a3 o8 r8 }
#else, Q$ `' e& M2 l* h
   #define LANE_SPEECH_DLL __declspec(dllimport)
# [8 x. T7 i4 Z& v' U, x+ R#endif
0 @# @$ \  ~" [2 C0 j# a% r, b
' \5 h. ~  G" w3 S+ Q1 t//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关5 @+ x6 r% d* A6 V
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。- }9 M9 i/ j0 ?
#pragma warning( disable : 4251 )
2 R1 t$ ^; L7 P& X& G9 I9 x# [' K! U3 t
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)
  ^; I  m( o% v# o8 |3 u7 B. l#define LANE_SPEECH_DLL
$ Z) b/ r  N' a! p+ @6 [4 `( E* |, V3 y: N3 w% n8 z
#endif //USE_SPEECH_DLL
, p  ]  B/ B  A, L: R
' g- e6 f* S! W: x0 r, x+ Q3 t# {5 \7 ~# l8 M( o
//***************************常量***********************; c9 x$ X8 t9 F) H+ E

/ Z7 [/ p+ g+ f0 t9 |: z: ]/////////公共常量-----------------
5 K7 ?8 _9 Z2 _6 Wconst DWORD   SP_CHINESE = 0x0000; //简体中文.0 D8 p- v1 x& ^2 |- A! r: P
const DWORD   SP_ENGLISH = 0x0001; //英语.
7 S4 n8 `# J* y
5 X7 O& a5 b( J( @4 O/////////CTTS常量-----------------7 f8 y. G6 K3 R/ G) d
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。* J. Q2 K# V+ i0 L6 R1 v) Z
# L9 K0 C+ O6 [; y0 {2 p
/////////SR常量-------------------, I3 F4 ~) W) Y" n; j  J
const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。& j4 z. V/ T% ]5 g
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
- b8 \! p) h; W' qconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.
# q" x% v9 {( N! y& e0 j) o% |# I" S( }3 K
//以下常量仅作例子用。
' v% u% j; J0 u  B+ v# A#define VID_TopLevelRule 9000   //顶级规则ID& B$ i: N" h6 z1 p
#define VID_SubLevelRule1 9001   //子规则ID
1 O3 U/ m2 f  Z5 T#define VID_SubLevelRule2 9002   //子规则ID3 N4 s* O0 u/ j- O  p: J6 v7 ~
#define VID_SubLevelRule3 9003   //子规则ID& n/ N* H/ h1 `' r+ x
3 q# t+ v9 C9 d
) J) J* V6 Z/ j9 z/ S" x. m
//*************************类声明************************
0 l1 U+ n" d/ f" j; T# t. n( r# y4 b! z0 H7 m

& _4 S. ^- y2 gclass CSR;
4 I- m/ I8 }8 B% ]8 I  @( \///////////////////////////////////////////////////////////////////////
4 y$ g8 ]; S. |* i- ?///////////////////////////////////////////////////////////////////////
0 @4 J% f9 \7 w2 @: r//
% j6 A, z, t9 i/ n" p0 L9 |+ I9 Z//         CTTS
( ~" t0 o2 u2 z; l! A8 p5 R//: [. T* h5 D" Z! Q5 F
///////////////////////////////////////////////////////////////////////
2 s: N: j8 B5 n4 S- D0 N///////////////////////////////////////////////////////////////////////
1 ^" d  W5 e/ t8 Z9 q2 U8 w
& Q9 X* [8 ~0 j4 Q/ |/ d( O! k( ^class LANE_SPEECH_DLL   CTTS* T& k- x# _9 b5 l0 @* _" }6 ~
{
2 z0 S7 H+ _/ e. ^% Q/ D+ bprotected:
( l9 Y! x& z4 M" e$ b7 |# jHWND       m_hWnd;     // 关联的窗口句柄。
) Z5 L8 b+ I* J+ D& W- L3 S! c) ~# h( |# g+ I
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。1 i8 {) q+ Q  O/ v$ j& X( O9 i: w
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。* Q  c8 _5 L( n* J" ]
CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)1 i8 Y# U# u' ^4 l4 U( ]' H9 H
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
4 ]; O# f3 O1 p! l: b8 `; f% l* n
public:
; E1 r; H% W; a- B+ {//********************************初始化部分********************, W4 k. \; H( C
+ O3 P7 o6 w/ M* G, N( m" e9 ~
////////////////////////////////////////////////////////////////////0 j, U% r3 ~3 ]5 k: j( a
//功能: 保存与识别引擎关联的窗口句柄。7 ]; f) f. v& \: S, _+ M, Y0 k, ^
//参数: hWnd:要关联的窗口句柄。
/ P/ W- F7 P0 }- G2 X0 x: U//返回值: 无。
5 A+ J0 k: ?* Q& [( X8 h////////////////////////////////////////////////////////////////////# x2 E" W  S* z& p- ^2 I1 y0 j
CTTS ( const HWND hWnd );7 M) F% G8 f5 D: r

1 Q7 M- \: ?; I7 h8 r1 ?////////////////////////////////////////////////////////////////////
7 s" s' h" U% w- r//功能: 释放所有的对象。
. T  j5 c3 f0 I7 b4 G7 o' G//参数: 无。6 K  g3 m$ Y- E/ S/ a# v9 C+ @
//返回值: 无。% U! I, I0 L9 x9 k; b/ Z! s
////////////////////////////////////////////////////////////////////
* G, M) F; ~+ k5 Y~CTTS ();
' m% X6 ?- S/ @3 _* S- j
+ ]& ~5 a' ]& s6 r6 g////////////////////////////////////////////////////////////////////. Q; |; f; H9 t' T& R4 N/ c
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。
3 r2 ~) G9 z* D0 \5 t+ D//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
4 J. p- w# Z% |: A$ V* w//    SP_ENGLISH为英文。! x* Q, y2 _! b
//返回值: HRESULT类型。
0 H. V& [5 s6 K+ P/ V6 \////////////////////////////////////////////////////////////////////" b& p) w6 v3 U, ~; M( P
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );
* a; h( [' g; O" m2 K9 n% i
4 A' g8 V6 [# o" b5 ]; p  u2 D////////////////////////////////////////////////////////////////////" p- q: i5 d/ c
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
6 C5 W3 q- x5 L, C) P//    通知事件。# o4 j# u! B$ G9 [* R
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,: I. x3 j8 W) Y: C7 r
//    SP_CHINESE为中文,SP_ENGLISH为英文。
6 P2 B$ T2 |4 H+ L6 m0 g+ _//返回值: HRESULT类型。# s& t5 i: u9 y8 W& o% p
////////////////////////////////////////////////////////////////////: e3 a# c, C# F- x
HRESULT Create ( const CSR * pSR,( d+ p2 ~. ]! k' ~3 w9 {0 ]/ m
       const DWORD dwLanguage = SP_CHINESE );1 c! r, i/ y# m! L- r

! W% F7 S0 n  E' A1 M- A" {- S' _% y! m" u8 W+ m! E3 g
//********************************设置部分***************************************
2 }' `6 ?- @, q7 E# t% {1 f8 ~8 k% h2 m3 L
////////////////////////////////////////////////////////////////////
$ n0 M3 ~* ]; p) {9 F+ O' E/ `//功能: 设置朗读声音的语言种类。( w1 F, s: V, K$ p2 E8 F) M
//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。% f* v5 B6 v+ U0 U
//返回值: HRESULT类型。/ l! N! Q% Q+ E# b7 X. L8 G
////////////////////////////////////////////////////////////////////
6 {+ ]9 v1 E- t: K5 E! E7 tHRESULT SetLanguage ( const DWORD dwLanguage );
/ Q  c# x5 n4 s5 {" F: G: I( ]; ?- V+ V. i% V' }; B2 B0 w
////////////////////////////////////////////////////////////////////
7 s7 D4 C5 q- \0 _: }0 y/ n//功能: 设置要处理的的事件。4 D8 N6 c4 i! I; v4 f/ S  F
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
  f$ b& \0 b* D5 ?$ Q0 Q//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事/ c  \" W/ I5 _/ S4 O" j% |: l
//    件都会收到通知。
7 {4 K# E; B+ V! c//返回值: HRESULT。8 U  }  |# a0 L( |* c. ^' \* v
////////////////////////////////////////////////////////////////////
# X* n4 u# k, pHRESULT SetInterest ( const ULONGLONG   ullInterest );2 z, Q: U: p" {8 ~4 b. r

5 h3 Q& m5 C8 J+ M////////////////////////////////////////////////////////////////////
7 ]: Y0 I% z/ i" x//功能: 设置朗读声音的音量。
  F# R# f+ A  M1 u, k3 C2 E//参数: usVolume:音量数值应该从0到100& l+ I% i" g' A- r3 ?- A
//返回值: 无。6 N7 a4 M7 e, V$ G/ P1 f5 J6 z
////////////////////////////////////////////////////////////////////
. L' k; {; Z2 }3 Y8 K3 n- X8 }+ R% Cvoid SetVolume ( USHORT usVolume );
+ z/ G' R! R+ ^" |  ]
' g3 W& l7 A) [9 Y9 @* }$ Q////////////////////////////////////////////////////////////////////. x: D. ~  f7 a2 n, U
//功能: 得到朗读声音的音量。3 ?$ l  B+ ~3 D: n* y, ?9 R* Z
//参数: 无。' ]4 E) z# W3 H8 J0 z0 r6 b
//返回值: 音量数值,应该从0到100。
" q5 ?; L8 q' m& j4 s( H////////////////////////////////////////////////////////////////////8 I9 Q5 Z' k- o: d! r' b' z
USHORT GetVolume ( );
4 x/ H, l% X: f4 Y! W
  @+ \( T* V; q) B- ~////////////////////////////////////////////////////////////////////
; x. E4 |: F8 j4 p/ I. p; p; \//功能: 设置朗读声音的音速。
( Q: M/ Z7 {: p( F//参数: RateAdjust:音速,参数范围从-10到10。
" y5 M. d, ~: @, a; p$ N5 F4 P/ d//返回值: 无。
: K# ]% T+ M5 @& g# h////////////////////////////////////////////////////////////////////
8 Y7 G# I+ v0 I% T6 I% V' D: H% Qvoid SetRate ( LONG RateAdjust );
* e& ^, u; ~/ e- g. ^( V; s5 L
$ L% K: {4 b. N$ B: l$ o) e3 ?* s////////////////////////////////////////////////////////////////////& H; _/ z6 `+ N% E6 Q
//功能: 得到朗读声音的音速。
. r, Z: [+ `9 u5 o3 V& S; N//参数: 无。# g8 n3 {" X: s/ B# B
//返回值: 音速,参数范围从-10到10。# o* r( B, n& G8 C* O
////////////////////////////////////////////////////////////////////
$ o! a2 b8 z1 `. P% K% k7 V+ {6 @LONG GetRate ( );+ l. z, \6 `5 N8 w) b+ J

* F8 `& ?+ c9 \4 ~0 A  R$ S' X) b////////////////////////////////////////////////////////////////////% Z( d7 w% y# {1 O3 w, p9 J
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。% Q" o& p- u: I1 F
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。1 N. w6 J. p4 G. B) f
//返回值: HRESULT。
# H' Q$ e( V" @0 c; h% L$ [8 v+ B1 C////////////////////////////////////////////////////////////////////
) j- a1 Y+ B; E, mHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");8 k$ s/ ^+ T+ t& l

3 G: [6 j7 u/ G+ s9 J) S9 Y////////////////////////////////////////////////////////////////////
9 G& g4 N8 N+ C9 _0 y* I' b" {' M//功能: 设置朗读的声音从音箱输出。' g+ ^% n% N0 k) T/ v" M1 ]% l
//参数: 无。/ x1 m% ^7 O( G, _. j7 @
//返回值: HRESULT。
7 ?6 w3 k8 h, C1 {3 r1 N; ~1 G////////////////////////////////////////////////////////////////////
7 ?& j$ @& {6 p7 i" O4 o6 aHRESULT UnSetOutputWithWav ();3 o$ i0 R6 m& z7 N

+ m! W! o' i& L; x  _& d: i: n: X
1 v. I7 n: z  h9 b3 b3 D6 y+ _//**********************播放语音,文本到语音转换部分****************************** h# v+ N! b2 C1 i- A0 k2 j, H% E

; A5 K( ~. [7 W9 N, ^////////////////////////////////////////////////////////////////////: ]: |# ]* r3 h6 q
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
0 ?* k! j3 p2 j, z' ?& g, A* R# f" `//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记1 H1 Z. w# T( E1 L
//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
& ]8 b' S% J. E9 ^# [% E# Q2 C) S//    SVSFIsXML为朗读带xml标记的文本。
: E, V3 Y) s" S1 l2 }+ a, w//返回值: HRESULT。( |5 q% A$ e4 l8 O8 q% S
////////////////////////////////////////////////////////////////////
: N/ H# I; `0 w6 gHRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
. r& X$ d( y8 w4 [* z, \
8 Y$ }4 M) e6 b' P////////////////////////////////////////////////////////////////////) I6 r6 W) V) K- [
//功能: 停止朗读。如果朗读为同步方式,则不能停止。, ^3 n5 u$ K# y; A2 r* F+ c, y
//参数: 无。
9 P' W* O! u; n! T0 h2 {# G//返回值: 无。/ Q/ o7 M; b; q
////////////////////////////////////////////////////////////////////( j. X3 R% f  Y. M5 A% [
void Stop ( );- G! E: L8 S9 l& ]% F6 a( g
( P. d% J# r4 k9 |% w
////////////////////////////////////////////////////////////////////# v1 A7 _, a/ I0 {0 C* {1 S
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。6 b, [7 D+ [! l5 s2 t
//参数: 无。/ n; v0 Y' B7 z; C6 e
//返回值: 无。
- m. @* m- |! Z4 b: d7 j% f////////////////////////////////////////////////////////////////////
' C% }/ f6 R% F4 n5 t% ]void Pause ();
  j, `$ ?8 D2 ~. r. O* }) Q; G( ?. ~0 P( o  a* }) M
////////////////////////////////////////////////////////////////////1 _: {1 W1 l) u: T2 n
//功能: 从暂停的地方继续朗读。
7 l# ]  C- q1 [//参数: 无。! k* i) P  y$ [4 }' O$ z( k
//返回值: 无。' W+ ~8 \; |7 V, S2 j
////////////////////////////////////////////////////////////////////) N1 V6 B' D3 c
void Resume ();$ X2 ]* h2 Y* q$ u* d9 y: @
. Q1 l  t  \2 K( G9 [) t
2 o( p" }1 K$ ^
//********************************处理事件部分***********************************
% w8 g: E2 W9 G% `; E
7 O0 G- @6 u  ^4 D1 M6 K8 apublic:
7 W( _/ y0 r) N* s/ z* C////////////////////////////////////////////////////////////////////
% L; u; [3 y; I# R- n//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
" q- d1 }& ~' l# U//参数: 无。/ d, ]/ k( V1 S3 V
//返回值: 无。- j8 _8 N* S! ?7 a) W
////////////////////////////////////////////////////////////////////# {9 k1 Q; Y1 Y  j  i- S, V8 \
void ProcessTTSEvent ();% P& [8 y- V0 e3 I: S# @

, g/ J" y  ~( ^. U$ C" `) n5 y: ]" c* R
////////////////////////////////////////////////////////////////////
( O8 E$ a7 h$ A' d//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。) A5 p- _, \  `. a3 R/ h; ]. \: U# U: I* i
//参数: 无。- k$ s/ t9 U+ ?$ Y9 C
//返回值: 无。
& I- J3 I" F9 c9 ?& Z////////////////////////////////////////////////////////////////////5 m5 m. L4 W/ z7 J+ M
virtual void OnStreamStart ();- w' U2 f* R* D' {3 f6 A9 c  R

9 x' H4 u1 \: U0 K6 ^7 E! }////////////////////////////////////////////////////////////////////0 s* ~( x$ W  m( o) e' `
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。5 @, p' }) S$ y0 o. l: s$ m: i) N
//参数: 无。. D0 C  m, L9 w- q' `0 t
//返回值: 无。+ l5 ^4 ?- R" K& S# X% k( `
////////////////////////////////////////////////////////////////////$ _( [& m8 j3 o; m
virtual void OnStreamEnd ();
- `. Q- X3 h! I9 u* J/ K/ ^};
$ w" U& u+ H& f0 s2 [% ]9 M0 h# T0 Q0 @8 D6 F6 v( e" U2 U1 o

, _( s2 O$ n0 Q/ x" F' b. N///////////////////////////////////////////////////////////////////////
0 @/ \0 G* `. u: i9 U/ F5 c///////////////////////////////////////////////////////////////////////& ]0 [( v6 A! W- a( l3 E$ @
//         CSR- b3 h/ k8 Q- [/ T3 w( B
//" ?" \' |7 X! d# H& P% L( H. L
///////////////////////////////////////////////////////////////////////
, x6 e. P8 M$ }% H; P$ O6 H* Y7 r///////////////////////////////////////////////////////////////////////3 o6 ?0 P8 l) t$ ?1 v
6 w, y0 `3 V3 H# s
class LANE_SPEECH_DLL   CSR0 g$ t- P$ R8 ?# C% I; t: K
{
% V  i3 C; i5 p9 f' i! R8 i
6 j# [- C/ ^/ _& Cprotected:/ Q. ~8 K8 p  o8 T; D8 i6 X# z; o0 ^1 l
HWND m_hWnd;. r7 I( d  L0 |
# u/ h' f' {4 S) s" b
public:- n- L8 d8 _1 x5 ^
CComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。( Z' t5 W  Y6 ~/ j" \
CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。2 H" L# C) u6 O
CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。
* E8 k) D3 O* x5 K, G  e; FCComPtr<ISpStream>    m_pInputStream; // 流()的接口。; ]# P# x3 |8 P+ D( e
CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。& ]- j4 e- Z! l4 K* j1 z
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
  t7 S& j. J7 v! F) jpublic:
9 q9 I& n4 \3 T2 e6 A0 qstatic ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
8 }" }4 s& p5 H$ H. W8 B6 O  b+ N7 ]/ D2 a( z! v
: g2 B0 @! _; O  W# h! H
protected:
1 A& S- q: O- ]" q" k2 C3 o//***************************辅助功能部分****************************************
  ^( a6 @5 W1 n
9 R$ A/ m/ Q# T% w8 W( Y////////////////////////////////////////////////////////////////////
! f8 y) e# G' ^# x7 u//GrammarID加一,每个GrammerID必须不同。! f6 e# P/ P+ c
////////////////////////////////////////////////////////////////////
) N5 L2 {6 s& c/ ]static void UpdateGrammerID ( );' c7 Z. p1 D/ F% k- x0 U

# Q3 u/ [6 U* \  ~+ F5 @* V; z8 N- H7 X- G: {, W
public:& ?2 T2 y5 u3 v; W+ [  M. g" `
////////////////////////////////////////////////////////////////////' Y6 s" L+ Z: k1 U$ z9 ]* @
//功能: 友员。TTS中的从SR引擎中建立voice对象。
# t+ W1 T# Q0 }# k( D% X9 ^//参数: pSRContext:SR上下文对象的指针。5 r) {" A; E& o2 d( I$ \  s, d" E
//返回值: HRESULT类型。) f9 \' D; k1 A" e4 X; b; C$ M3 K
////////////////////////////////////////////////////////////////////4 v# X. u: H$ m5 a3 E+ o! ^% x
friend HRESULT CTTS::Create ( const CSR * pSR,
3 b9 p- M9 ~0 E1 X/ r          const DWORD dwLanguage );: r0 A$ g8 v! K8 B8 x( Q  o6 C
2 n( @" y! E% l6 t  @) V4 c

/ z6 S3 @' L4 r6 Q3 J# A+ a//****************************初始化部分*****************************************
8 l' X) m8 a4 w. e$ S0 t  [0 r8 N9 U+ \
////////////////////////////////////////////////////////////////////. Q4 b4 K: j* H% M- H1 x& [
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。: j1 L- W" f, A- U# b, I2 L
//参数: hWnd:要关联的窗口句柄。. `( k* B9 x2 P- f& L
//返回值: 无。
+ m6 j) `; V2 Z////////////////////////////////////////////////////////////////////* q9 @8 \1 a+ F/ ~& _4 o  P$ y
CSR ( HWND hWnd );
% B8 U% ^. n1 k& Y$ T% s3 {
: n  L  }2 W! G! d////////////////////////////////////////////////////////////////////
/ X; E4 K. f1 q) k//功能: 释放所有的对象。$ K( B) _) i- @0 k9 f6 s' Z
//参数: 无。
# V) N, \, ]8 q+ v7 z/ G+ P- Q//返回值: 无。- M1 B" ~5 Z0 w( z" A
////////////////////////////////////////////////////////////////////* l3 A3 o1 Q5 C/ {8 {. n/ W
~CSR ( );- Y' h: F1 f1 C, P, w& e, d
( v" x, k$ L  e) r+ f
////////////////////////////////////////////////////////////////////. |- ]# V7 v6 Q! `% z
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,( R+ A3 x5 f3 F
//    加载文法文件。4 Q. @/ H/ B* C% U1 m
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。3 T2 ]9 g& L6 r+ \5 Z7 ?: N
//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
" E- Q0 A3 E/ @6 \4 C* ^//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。+ t+ h- f* `$ s- |. Y0 g+ t' [" N
//返回值: HRESULT类型。$ J* `! Y* _! Z) i
////////////////////////////////////////////////////////////////////( A& y; n8 U; o! \( {' M0 ]/ X
HRESULT Create (const DWORD   SRType,4 u. l1 H, B: V
      const WCHAR   *pwcGramFileName = L"grammar.xml",
% G, x" {5 y; w: r      const DWORD   dwLanguage = SP_CHINESE );' h& G9 f2 t' ], x1 e7 k
  k; `1 |4 q/ f

: L5 n2 O. n7 Z* l3 H* E% C//**********************************设置部分*************************************
' x6 `7 m7 P; p8 u) I  \8 k- ]& ]: v( B6 ^! ^4 Z1 ^
////////////////////////////////////////////////////////////////////
  q3 I7 g6 q' |8 X1 b//功能: 设置要处理的上下文接受的事件。1 g4 n& P& }% l" x- M
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的," k# U5 k0 {- }. h8 ~" ~$ ?
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
  o( T1 v: I8 y- A( H+ H1 r//    件都会收到通知。
: Y/ t* q1 f. V1 Z//返回值: HRESULT。
7 A1 A9 r( {  `////////////////////////////////////////////////////////////////////1 ]0 L$ r: v+ Z' L2 t, ^) a' X; l
HRESULT SetInterest ( const ULONGLONG   ullInterest );7 A9 L8 o" M" D- I* }

1 z# y& c  `5 b. z7 D! N' P  q////////////////////////////////////////////////////////////////////* p) H- G# s) g$ v9 t7 I; g4 ]* M
//功能: 设置某个规则的状态(激活或者取消激活)。. ]# f. p3 J- F
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,+ @6 a1 }  y9 ]& h" x/ h
//    FALSE表示取消激活。+ r/ _2 o3 w8 W9 R" l
//返回值: HRESULT。
$ ]% o% e0 |/ {, m- A////////////////////////////////////////////////////////////////////
4 z$ i2 Z; w, F+ H. NHRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );6 Z7 R# `9 z8 o4 H
* P- y$ N: i$ @
, ]9 z5 }$ O  m) o2 E" V
////////////////////////////////////////////////////////////////////+ U# Y! I9 M. _+ r5 n" a
//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克- O3 I) N' K6 C8 p% {5 y- U
//    风输入。
2 U* K9 m; D- O* H' u//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。; w% Q, b" ?5 C; D% |% R
//返回值: HRESULT。' |9 F  {- \# A& J. _
////////////////////////////////////////////////////////////////////) X) z; Q& ?% z4 Q, K
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
2 i1 v7 ~8 D; B2 e/ S9 w* j' \# Q& R8 w4 W* n* `
////////////////////////////////////////////////////////////////////2 S( d9 p, c8 F$ r6 X1 d
//功能: 取消从.wav文件识别。恢复从麦克风识别。/ K) X- V6 P4 k0 Q
//参数: 无。
, w0 V7 f; N! N' L2 {1 N//返回值: HRESULT。
, Q" |- \/ ?6 b3 ]/ r////////////////////////////////////////////////////////////////////
& g+ ~$ U( N) p8 U; B; LHRESULT UnSetInputWithWav ( );
+ v  o) V8 @8 D2 p
4 k( c3 v! i, K; G* d//***********************识别开始,结束,识别结果的处理**************************# D, [5 a$ V! I1 C1 Y- B

5 M" z) V% s7 r9 H$ h////////////////////////////////////////////////////////////////////
3 ^$ ?; L* z9 i3 Q//功能: 识别开始(将所有规则激活)。. J7 [4 a' b; V$ t8 T
//参数: 无. a0 Q) A0 j+ g6 c! M
//返回值: 无。: b% v# M( F$ y+ r' s' G, \
////////////////////////////////////////////////////////////////////" J9 G9 A5 p! Y% e
void StartRecognize ( );
% l' w; f5 _& a' }9 E2 V/ g! ]% i5 L: ?! E' h( l; x
////////////////////////////////////////////////////////////////////
* Q' P5 f9 v% G//功能: 识别结束(将所有规则取消激活)。
8 ?2 l' p+ Z7 x1 U//参数: 无。
. M0 Z& C1 ~- u+ A+ U, z//返回值: 无。! w$ f: \* Q5 s
////////////////////////////////////////////////////////////////////
9 O  E' x2 V: P. M7 N; v, l% Nvoid EndRecognize ( );
/ W8 n  a, j9 P3 }4 O( N1 H/ [- d9 k! s( q/ ^5 k
public:, R% z3 m& j6 b* L' i- ~. u
////////////////////////////////////////////////////////////////////
( @3 `7 |! E8 c' E$ S! T//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
7 Q' i; v. J9 z1 F* Z//参数: 无。
+ ]& I$ v" s. |9 @$ S( h! }% P//返回值: 无。2 z8 w' ?: ^! S
////////////////////////////////////////////////////////////////////1 [! g4 s, H: }5 F$ ^1 v: a
void ProcessRecoEvent ( );
. K$ f* C: C8 t6 `
2 _( t  f% s7 P; i! Vprotected:$ r( Y1 U+ m9 y  G; j. J" u1 m0 J
////////////////////////////////////////////////////////////////////
5 K2 J, l3 |6 T9 f2 j( w8 _! m( q//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。
9 a8 \# `6 T- b2 N3 G# \: n7 y//参数: pPhrase:ISpPhrase类型。
( o) ^- S3 R6 Q7 f5 ^//返回值: 无。
. a/ U& k& x5 A* l/ C! [8 m7 }  Z! \////////////////////////////////////////////////////////////////////+ t+ }. ?  h( d1 t8 D+ X$ O
void OnRecoSuccess ( ISpPhrase *pPhrase );
9 D7 g4 s" k% g+ u( a" k4 q
5 E' Y3 t: c, J3 F' [public:. ^0 W) X7 _8 y- ^0 H$ w
////////////////////////////////////////////////////////////////////! Z0 T# W1 e# m8 Y: t
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,5 s7 g3 X9 {5 C  R  r$ c
//    需要在派生类重载。规则ID必须以常量形式预先定义。
+ q) ]1 o0 X# R$ U5 f. }9 r//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。9 s# F. z, ~) m' C) d
//返回值: 无。
8 a1 ?! f1 U! U. I) ~8 {////////////////////////////////////////////////////////////////////& l6 j! e8 o; k: \% `& p+ K5 b
virtual void ExecuteCommand ( const ULONG ulRuleID,
- y. u6 X2 x! i$ \; d' k* J( b          const ULONG ulVal );
" p5 N/ c) [7 _- I! r3 H0 N. D$ w5 c# [( K" O# A
////////////////////////////////////////////////////////////////////
# m5 |# Z/ I, O) P( c//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
, p$ |6 w  B0 M/ ~) {% E( c//参数: 无。+ v- p1 M. z1 V& z* u, f' V9 f# u  N
//返回值: 无。
( x2 X8 j& Q% Z& L///////////////////////////////////////////////////////////////////// `# c4 t. J8 Q
virtual void OnRecoFail ();
7 |" A) B. v4 P( i& E$ M; G3 D+ Q2 k, d5 m
////////////////////////////////////////////////////////////////////- \) F7 k/ e6 B+ l4 l# M
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。7 t4 m: ^; s; t
//参数: 无。( D5 f. ~* Y* j" `
//返回值: 无。
: P! P$ o7 {+ D+ n2 C////////////////////////////////////////////////////////////////////1 |* E: V# U1 a: a4 j8 \; Y7 X
virtual void OnStreamStart ();2 _$ o* y9 y8 `' F

9 j, l7 F$ {6 e$ R////////////////////////////////////////////////////////////////////8 @$ }! B! D- @
//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
. ^. k1 u( |' w$ Y% Z! T( i//参数: 无。
: Z- I2 S: I" J+ F" V. v7 |//返回值: 无。2 D" P5 s4 ^8 s4 i' c
////////////////////////////////////////////////////////////////////0 X+ A/ x3 V/ q9 L2 R5 d
virtual void OnStreamEnd ();
* v5 o1 ?, Y7 f4 L4 J3 S( L5 Q( L. F2 M
};/ R5 k' B! W% o4 _. r% ~2 W9 X
; h' S0 h/ k! s. }* u% C

, Y( E* `7 K- G3 L9 ~/ I3 Y
. [9 j/ ]5 Z4 g" h& |& z#endif    //LANE_SPEECH_DLL_H
: F1 w! c; p( w' E4 R; n( y! D' r3 k; U) J) j
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////* t1 k+ f, F& Y" N0 i2 W5 l
7 E1 j; h0 ]5 q7 h: k
////////////////////////////////////////////////////////
& @0 H, b; b# ~, l" g0 i//
9 _% M0 R0 D! Z& \7 O, }$ _// 文件:LaneSpeech.cpp4 z: B, S" W7 B' y) V/ v: E
// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
/ d+ b, T9 \- c! A//    语音识别只支持命令模式,不支持连续模式
- F" Z1 J( Q3 O# k2 r9 b// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
9 R6 n1 k  u* y4 e# a: ?// 日期: 2004.107 T% Y9 ~% `, b3 \4 _
// 版本:1.2& {8 E, C8 Z, `! |2 `# Y3 _
//
9 w- ^& a" j  e# H4 G8 T5 b//' u2 ^8 W2 _4 m; t- n- P
////////////////////////////////////////////////////////
, K/ ], I0 N5 z: O" s" v  Y6 R0 Q2 _3 Y/ _+ Q$ C: V" w
( T) ^! M2 ]! Y* w. P9 p
! ~% x+ N( ~% O+ X; }
#include "LaneSpeech.h"
& w) |* V% @7 K# ^; I* |
9 S- n9 i% q+ I4 z# |/ Q5 A//-----生成动态连接库和静态库的处理----------------
( z( f* C) @) f, i, L$ i: y: C) J#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
8 s' G$ I' M) X0 v+ O/ H
2 F* }( ^/ [& T! s& I5 _BOOL APIENTRY DllMain( HANDLE hModule,
4 u( W% C9 A5 ^; b  x1 ^- h4 K' A                       DWORD ul_reason_for_call, $ x9 N# Y+ F0 L- S
                       LPVOID lpReserved
5 [8 g' s( D+ f, X      )4 b+ a7 g3 p: G4 g6 z4 _1 u) |% D
{+ \( }0 n  @0 y+ v
    switch (ul_reason_for_call)# c  n& P- z8 P. m' K
{
+ C3 o# W! A1 W3 T1 f8 y   case DLL_PROCESS_ATTACH:( Z# p: T. W9 G$ W5 S
    CoInitialize(NULL);  t8 l2 A9 m' ^  x7 Y* r
    break;; L) Q8 I7 s' u( I
  
- j% J$ R. p( V# K& C4 H$ h& Z   case DLL_THREAD_ATTACH:: {5 k( C' V& i2 C% T7 G
    break;+ A2 X! w9 |4 R# {& v( p
  
3 u5 b" {. n- T- k( l   case DLL_THREAD_DETACH:
, E5 K: e1 Q- i! F! Z; ~, ^+ i, p    break;
6 U+ |# ]# _/ w  8 s: B9 Q7 i( v, T, k" c
   case DLL_PROCESS_DETACH:
% O  z7 l0 H; Y& p3 ~    CoUninitialize();
+ V) h% B% G7 @. s# \( D' A0 k    break;
% c& k" C: z; o    }
3 Q1 v' m/ O7 v0 y0 W7 E& R4 y- O/ f    return TRUE;
5 K, L1 N) F! Z9 t8 L4 x3 C}
2 }: o3 w2 @5 A
4 H4 C7 p6 W- Z1 I#endif //USE_SPEECH_DLL; H$ t9 K# j% g+ H* }, i5 [

5 o  D1 i! p/ }1 q+ W+ z( z  M! O; A7 a, E

" L' {; ^6 D2 I, J///////////////////////////////////////////////////////////////$ d$ X/ G# ?; b7 k. A
+ J# y' g: W3 {. q
////////////////////////////////////////////////////////////////////: h/ B( z0 J4 {! k1 A
//功能: 弹出一个信息框。
% v1 s4 h: W' b6 ~+ r9 W2 T//参数: lpText:是对话框信息。lpCaption:对话框标题。
# w& w' h9 s- k' U+ W//返回值: 无。
6 T5 U- r* i( m////////////////////////////////////////////////////////////////////% k+ R0 n/ s; Y/ F4 [& y
inline void ShowError ( const LPCTSTR lpText = "ERROR",9 S* `; {9 ^0 k0 X/ M& I
        const LPCTSTR lpCaption = "ERROR" )- i! B: }0 p& p  ^# T( D+ m
{( @) A# o" J4 n5 q, r
   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
3 I* z" F- f% T1 B2 h9 F}
6 _) C$ w1 `) l- G7 f* J2 g$ a9 M
4 `) G8 w& K, N- J( W////////////////////////////////////////////////////////////////////
! I5 T) A5 P8 O) y//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。# q3 u) p! |2 J4 r4 g. n
//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。7 Q9 d" ^4 V5 D& K
//    lpCaption:对话框标题。2 W% W" r' I- o; H
//返回值: 有错则为FALSE,没错则返回TRUE。
; J9 s# X$ g. C////////////////////////////////////////////////////////////////////
2 {7 T) C! l! L2 H6 oinline BOOL CheckHr ( const HRESULT &hr,
5 {! H" W. H! w+ [1 M        const LPCTSTR lpText = "ERROR",
0 v1 U& |& M5 ]4 T5 V        const LPCTSTR   lpCaption = "ERROR" )
2 Y5 b& |: J! l+ W. u6 C( I{
% u# m: K  A; X- o# Z! S; Q   if ( FAILED( hr ) ) {6 u  H8 u: `" Y: R
    ShowError ( lpText, lpCaption );6 M4 l- E9 n5 ~0 T! `" M) I
    return FALSE;
/ [+ _# e3 H" S. Z   }; q, [3 S: H9 S: Q! ?
   return TRUE;( k* g5 S- g7 x- T
}/ d5 I! n+ b2 t  t7 R6 Y
' a* t" _7 a4 q9 g6 T, J6 E9 ?
3 H/ W/ B0 o( {8 ^8 E; ?6 ^
///////////////////////////////////////////////////////////////////////; a9 k1 C5 H' ^6 c) L
///////////////////////////////////////////////////////////////////////* A6 s) d* h( |3 O2 g
//& |4 X  ]& g. L, f. z: N
//         CTTS, q  B1 ~4 {) }  w1 j. O# F
//' i1 w2 A! }7 D* H. U1 K; [
///////////////////////////////////////////////////////////////////////0 R' y- D% t4 A* D
///////////////////////////////////////////////////////////////////////
+ A" v1 U2 G. j% N0 q* N& P
6 ~( d$ D) m1 K1 N! ]( `; v////////////////////////////////////////////////////////////////////
  }+ Z6 P% c6 D  d//保存关联窗口句柄。初始化COM。
" e( q" J$ o* o5 b# j0 u6 t////////////////////////////////////////////////////////////////////2 ?* z) B% O8 w$ Z) _( {$ u- l
CTTS::CTTS ( const HWND hWnd )" ]7 n. P0 \$ @+ [# h* a! w
{
; N- N8 v5 m% p: tm_hWnd    = hWnd;
) s1 S, ~! C- cm_pVoice   = NULL;
* M1 X3 @6 `4 C" am_pToken   = NULL;
7 v9 H: P- [+ Q: d2 g1 bm_pOutputStream = NULL;! {- o' }' ^1 Y8 s
m_pAudio   = NULL;
4 p" L! D8 [2 h6 i0 H) Y2 V9 a}  ?" Y4 \, e( C4 w0 N) C- O* _

) K- E4 y' a* }" H////////////////////////////////////////////////////////////////////5 i! `& ?; ]3 o8 w
//释放所有对象。
. C0 O" r, v( z9 l5 \1 A* V% ?& s////////////////////////////////////////////////////////////////////
2 e" W& ]' l  C4 E$ A0 dCTTS::~CTTS ()8 x, _) q1 w/ ]/ q  r: @( I. Z
{( D7 @  @% L) F: l6 P# D$ g
if( m_pToken) {
/ O7 L4 r* l7 ~" d% k) I   m_pToken.Release();
' W* W6 I; h7 f: k1 M   m_pToken = NULL;
8 ?( @* |9 Y5 A8 B2 F}
  O. m6 G1 d+ P" O; J5 K9 B( i7 @$ G; rif( m_pAudio ) {
& b" k$ m) u7 Z, T  [" G( B; ~   m_pAudio.Release();
& a) Q+ {! p! k( q% U* J1 s( {   m_pAudio = NULL;
0 E6 h7 x; j6 m+ \}6 u! A* U, `- r, ^$ E
if ( m_pOutputStream ) {6 R2 s" N8 k/ a' ]. }
   m_pOutputStream.Release();/ [5 v( {9 Y" G- @" l( }8 J( }
   m_pOutputStream = NULL;
/ u' B* _3 f9 v! Y}
/ p( m8 a- t* \( [( X7 V9 q# o- }+ Fif( m_pVoice ) {
1 F) R9 _# N$ v6 x: v   m_pVoice.Release();' B0 e/ f; W, l' n8 i, J& q3 v+ \
   m_pVoice = NULL;. w: w; `+ d. M- G. A
}$ s8 H/ ^' t9 g/ n
}9 J: J& ]' N# ~  c9 b3 Z
" D. p, i0 m3 F; N6 q# E0 c( O0 \
////////////////////////////////////////////////////////////////////+ P  \! E8 v: w# Z3 Q
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。
% S" ?' n, h& k( n5 k. s////////////////////////////////////////////////////////////////////6 G- {2 w. d" r+ H4 M' |6 H
HRESULT CTTS::Create( const CSR * pSR,( r3 M4 M5 X% o% P' R1 u/ F$ }9 ~% Y
       const DWORD dwLanguage )
  u" o! B* K: y( g) w{+ V9 @( E/ c" a5 a6 i! o: j
HRESULT hr;1 P2 }& c/ a) x, ~* ^) M% N
hr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
* a1 N$ t! P. Y) e$ O) [5 sif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
( }% Y+ K1 i* I) o# e3 X   return hr;  X' a/ R8 c7 Y( v
}2 G; S3 O+ A7 i. a  {

6 a2 H4 ?2 t% k6 ~" oSetLanguage ( dwLanguage );
, |5 s* I' R5 b" u/ C! Y' ?
$ G+ e$ k+ u9 h+ U1 i0 R" U  ehr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流& ~! R& e( L; N; F, v, h
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {/ V% L) P8 F4 E5 y2 {* R4 T
    return hr;
: \" K8 n4 C& t$ A3 h) L}
3 R7 u0 x( M& \
- n1 Z* b+ n5 D' \//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
6 N) M2 r3 o$ Q! q: }6 R//SPEI_END_INPUT_STREAM 表示完成流输出。/ A2 J& }. T' J& v# L
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |! h8 L) Q# c0 R. g
         SPFEI( SPEI_END_INPUT_STREAM ),, D" N0 F* R5 J
            SPFEI( SPEI_START_INPUT_STREAM ) |
+ d, a6 a( G2 N/ G            SPFEI( SPEI_END_INPUT_STREAM ) );# N& t* L! _: L/ {
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {# B8 |/ n! ^* r' v1 K
    return hr;
6 p; T- k- K4 t}
4 k/ b. j" C8 X" z5 _4 D7 ?2 T1 t* e  ~0 g+ x
//设置通知消息
) X! `5 p6 C. w  f( s6 v, M9 O  Ehr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
+ j, w& v# ?8 x0 v8 hif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {& B. j) B! T2 B: Q# `
    return hr;. }; R. r# ]2 k) b# |
}' Q# g1 h' c3 C( }
, D1 ?+ E: U6 `5 K* J; I, R
return hr;
3 Y% Q% k4 T& V$ j3 ^% c( t}
7 g9 `$ \/ k/ r- o3 |( p" s" e' b8 ~, a2 l! U2 O- {# ^% j
////////////////////////////////////////////////////////////////////& L$ t& }8 ]/ j! B' t9 U. n
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
/ |( |, [, {$ E: b% g+ M. K//并设置兴趣,设置通知事件。
6 I2 y, T2 t" ]& @0 k" Z8 E; n! B////////////////////////////////////////////////////////////////////9 D! T: }% x/ p2 m' @3 C& I- Z2 {
HRESULT CTTS::Create( const DWORD dwLanguage )% x9 C' O7 O4 d( \" v7 e& d
{
9 W; P6 h; `6 R! I# m( @% ZHRESULT hr;
. U3 r" f8 M. x! P1 h. {hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
2 R" M# P: U. F' E8 A( b& {if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {* @+ \' e3 ?! g8 ^& X
   return hr;7 z- N/ \2 \# G7 @" Y' k
}
4 j* w; P5 e, x
: d" I9 E. m$ W4 HSetLanguage ( dwLanguage );9 w4 T) x& i# J) S# F8 a: ]+ t

! d+ T9 x% ?& Khr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
7 K! M6 r% \2 X+ ~3 Cif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {5 t) A3 d' O( m8 Y
    return hr;
6 d& U" N" t( Q+ j  @}( Y4 ~$ L0 y4 s8 |) C

5 \: l. H5 o9 b2 S9 V//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
, m5 }) m# P7 v: k' f//SPEI_END_INPUT_STREAM 表示完成流输出。: y& F$ n, ~% o9 r8 _
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |8 ?) T6 J: o  N' z4 U+ y* V
         SPFEI( SPEI_END_INPUT_STREAM ),
% U7 N' f  W$ E+ G( M            SPFEI( SPEI_START_INPUT_STREAM ) |6 r2 z5 m2 }7 p( U3 p% d
            SPFEI( SPEI_END_INPUT_STREAM ) );
7 l1 \0 g3 P+ {( Q. Mif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {9 h( `# V8 `- t9 i; _
    return hr;
% M- d# O6 z. F}6 R' a/ Z% F2 o) h1 K3 f+ R, l

& R" i; w" q, d0 C) J, |% B; H//设置通知消息
: ~1 k: f% |! o5 t- L, Shr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );& i1 V8 G/ K+ E$ [
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
% M, D: h% `. [2 b1 [; g    return hr;
! D% P* J% X; ^/ X6 W. D}0 ?/ ]* c4 g8 L4 O

- Q% W4 C3 r2 L" w+ o; S2 @" C( ^. Ireturn hr;0 D: E- s( P0 g# k9 X! Y; z
}
- }* Y% @! T- x! U+ s
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件
6 J' {  ?( m  N7 v" S( N5 l7 {+ g#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()/ W+ M/ f. W7 \$ U/ Q
{
3 S& c0 U& L0 L# y1 c    ::CoInitialize(NULL);//初始化语音环境
. o; D: N  L2 Z2 x' m, y4 `" n    ISpVoice * pSpVoice = NULL;//初始化语音变量4 `( I$ h9 F5 g  `3 ?" i4 T
    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { 2 ]$ y2 J3 `+ A- c% b
        cout << "Failed to create instance of ISpVoice!" << endl; " H* b* x7 k! A
        return -1;
) T2 B# V5 I$ W! u0 P    }

( T5 X; b+ Z# e. M+ ^    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量' V1 D. |3 Z& q# n  Z6 E
    ::CoUninitialize();//释放语音环境

4 X) m4 i) A7 O- Z) c    return 0;
; ^9 M$ F, p3 i# \  `}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序
4 F9 C+ B' E  k8 E9 {
" \! |1 [; J; B* W1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地  l. P" s$ W" w/ K* ^, H6 k" \: b

' n& q1 L' a% y; Y& I# ~9 Fhttp://download.microsoft.com/do ... -US/speechsdk51.exe   5 r. T# w& E9 {% [6 i6 _
Speech SDK 5.1安装包 (68   MB)     
, ^! q) P, F/ chttp://download.microsoft.com/do ... chsdk51LangPack.exe      ' m7 w0 \) j- N' b  B
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  4 N- q/ ~$ p! P3 @/ B; L* V; S  C3 F, i
2 m  v7 G& _8 q9 g3 n
2.下载后,执行安装
$ i) k/ o  F! m1 V$ B0 @- k8 p9 v! T$ ]5 r8 G: z
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。7 Z+ `  p1 a5 z: S7 F! u

$ X! o1 N" T. q- o* q% t- @  d8 h3.VC的环境配置
! J" y8 O' O' f; ?1 k
+ w: i, R# f5 i在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
' v5 |! Q4 M. }2 j; }" z
/ A7 K3 a- z, F# q' f工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
3 G( T1 g# t2 D2 n  U! _$ Y5 G5 }
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~5 |; Z  O$ N6 e
回复

使用道具 举报

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

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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