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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
0 x% {5 A4 y6 t; N" ^4 B//1,生成动态连接库时,要#define USE_SPEECH_DLL,
- l& \" K2 t$ I$ I" }. F% N//      并且#define LANE_SPEECH_EXPORTS
# ]- e# H! f% e5 Y% d- C- g& ]) m//2,使用动态连接库时,要#define USE_SPEECH_DLL
9 J9 S4 _. @. y* _7 V! C//3,声称和使用静态连接库时,什么都不需要3 Q" q: ^" U) P6 C
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),# P( Y( B4 ]. G  p
//      动态连接库就不用调用了。  R! U/ V/ U% c. e
////////////////////////////////////////////////////////
1 s( L' S+ z) S! o2 v7 D#ifndef LANE_SPEECH_H
( w* C3 T' X7 [% m+ p/ z* a#define LANE_SPEECH_H
' U3 _2 U' b; M' n% A# x: Z- Q* Y5 l9 B1 ^* K4 Q2 \
#include <windows.h>% ?7 x  B& _5 H# P
#define _ATL_APARTMENT_THREADED1 ], ^7 L4 Q  e1 g4 d" R* J3 E
#include <atlbase.h>
  i2 K* ]/ }* r( M5 x2 {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
# c: p2 h$ v) c% N% S4 O( \1 s# A#include <atlcom.h>
# B0 ?5 k+ a  _! O& _& w+ V( N# k4 x#include <sphelper.h>   //sapi需要的头文件
+ d" I( {6 p9 t9 D
6 v4 O2 _" A: a- Q( X$ }, l//-----生成动态连接库和静态库的处理----------------8 m0 ]4 E% X$ Y/ c
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类4 J# D; }2 \1 [, T5 K
- H5 H; f7 @* X( [; X  D2 h6 D7 u
#ifdef LANE_SPEECH_EXPORTS
! p! Z# N# D& J4 z# m6 y" K$ P   #define LANE_SPEECH_DLL __declspec(dllexport)
8 s. `: X) U  i1 [, ~8 H# P  s0 D#else
- D4 M1 I4 V' E   #define LANE_SPEECH_DLL __declspec(dllimport)
( w& ?+ c( |  ^  _  h( Q& g#endif
+ l9 Q1 w; K1 T9 D; F. l, [) w4 b# _' R
//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关' K5 R9 ~6 T9 H- z$ q
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
6 h5 I/ c1 S( K- j% _#pragma warning( disable : 4251 )5 P7 J% q+ ~) f3 a+ h8 w
# b/ P8 E" o8 g8 p! d! d$ \. U' J
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)" Z2 O& R* \# g( C+ c
#define LANE_SPEECH_DLL
/ a" ^% m& a$ d
1 h: E4 A' y: w#endif //USE_SPEECH_DLL# L! ?) P+ s  y3 p0 @, ]
5 [- T, Y2 s3 i  Q$ A+ h
; M$ Q0 v6 M1 V5 z2 O
//***************************常量***********************
* \" R+ u% w( i4 Z! W' k" `: a. i0 g# |/ F  ~: c8 K* m9 \$ w
/////////公共常量-----------------2 [# l" J9 _( l! p; v& ~
const DWORD   SP_CHINESE = 0x0000; //简体中文.+ z4 y1 ?9 c! _
const DWORD   SP_ENGLISH = 0x0001; //英语.+ w! q' I  _0 p! h4 s5 J
  i# O4 e% p2 |$ v4 {5 f
/////////CTTS常量-----------------
4 |- H/ \- _2 a" g" w+ ]const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
% Q: y  k. B* K) Y( Q4 v( ~% ^& q4 n. ]
/////////SR常量-------------------
3 x- I( P9 b& B+ B; L( ]" \const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。) `0 b# e' {, k4 Z3 B0 p5 ]
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.! ?& e5 J1 s8 q
const DWORD   SR_SHARE = 0x0001; //共享类型的SR.
/ g/ g% N8 g9 k! k; O" e+ k/ V1 q: j4 u
//以下常量仅作例子用。% N& B4 N* o! W. n# _
#define VID_TopLevelRule 9000   //顶级规则ID
& \! ]2 h/ r0 O, Z* A5 k( ]4 E#define VID_SubLevelRule1 9001   //子规则ID' t' K9 d8 G4 y) P
#define VID_SubLevelRule2 9002   //子规则ID
7 K& [$ S/ C$ Q% |3 s8 n#define VID_SubLevelRule3 9003   //子规则ID
3 p* `& V5 C9 V9 r
3 Y# T0 T! \0 z3 f# P2 w! H" e
//*************************类声明************************6 ?# A- J5 G- _, z

# [/ v/ [8 E( @8 c8 k5 B; ]# X+ r+ U6 w% x' B0 d
class CSR;
, r5 A5 W, {  ~$ _6 `8 i///////////////////////////////////////////////////////////////////////; s( u: V6 ~* e6 A: z
///////////////////////////////////////////////////////////////////////
' V+ p+ N  K8 y//
# I, W  n1 p1 m: H' ], E//         CTTS
5 Y8 t! p# i& m4 S# u//
8 r' }5 i+ A) q///////////////////////////////////////////////////////////////////////# n' |# W3 L' o2 `$ j% F; F2 I
///////////////////////////////////////////////////////////////////////
/ K8 B% j6 _: G; @
1 q/ f$ e, G. a& Bclass LANE_SPEECH_DLL   CTTS" f5 q3 C# s% F+ J$ A) Z8 [
{1 v; T) X+ e  L; h8 s
protected:
" \& b. e- {0 k9 PHWND       m_hWnd;     // 关联的窗口句柄。
% ~0 h; A$ h2 {4 a. p! P. k: A) ~1 W0 ^8 b) |5 C' ^0 H! z
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。
" `* Z( U8 x3 e% V: S9 \CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
2 N  x! `* F" y% M! @' a6 ^CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流); w" T  t0 V3 ]9 B" r( `" [
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
% R3 f# D+ c: J( m! {& Q5 E0 Z: I. V& s# r5 k
public:
( k& A2 U, w/ k8 O" x  w( H//********************************初始化部分********************
3 P& M9 Q  {5 T, ^7 M' k& [& `' O* }: S2 z
////////////////////////////////////////////////////////////////////; W# t5 ~$ {: f; x# G# H
//功能: 保存与识别引擎关联的窗口句柄。3 ^: O/ A- v: B- Z2 ]: ~( P' [
//参数: hWnd:要关联的窗口句柄。9 g: e7 D4 Z) d9 d0 I
//返回值: 无。
3 O0 g- X6 j% V  t2 K4 J' ]" {////////////////////////////////////////////////////////////////////
; W' s2 F3 Z& JCTTS ( const HWND hWnd );0 t; c) ]! x8 q* M* B7 o
+ ], U+ D- b$ w
////////////////////////////////////////////////////////////////////
9 }* g* O/ [; s5 g: q//功能: 释放所有的对象。
: |9 ~+ C) S1 I; [8 E//参数: 无。
8 q5 M* x2 B3 c# n  l4 e//返回值: 无。
- U0 ]7 }: v. @- r2 o  L% D////////////////////////////////////////////////////////////////////
5 H* \  [9 c4 L. b# J~CTTS ();
7 }; K7 M7 i, h) t) _+ F2 u, q
% g" B/ T+ f% A6 u2 X////////////////////////////////////////////////////////////////////% M' S. q) F* P* Z4 h( D& ]7 A+ w
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。& p- `* a; G7 F
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
, K7 c' |* _* ~; ]0 X8 x//    SP_ENGLISH为英文。' E$ w* Z9 K- I. t1 ~% _: V; e1 @
//返回值: HRESULT类型。3 I3 y  A+ H6 a. {; S2 n6 B( _
////////////////////////////////////////////////////////////////////
* M4 S7 M8 f- ?HRESULT Create( const DWORD dwLanguage = SP_CHINESE );  s) U" R0 y: [

3 b. p( V  ?# E////////////////////////////////////////////////////////////////////
- s* c' ^6 l+ L//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,3 F5 s2 G7 d7 v* r5 l, F
//    通知事件。: H6 j8 Q! ^5 n* G( }4 a/ w: B. U! R
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
& H& G" W5 h$ N. _- x8 C* v//    SP_CHINESE为中文,SP_ENGLISH为英文。
2 O9 g; X  I/ \( y9 P//返回值: HRESULT类型。
  l! m0 r% G) j7 d% A" t////////////////////////////////////////////////////////////////////1 K3 Y- m0 P) ?% j( w1 J1 Q
HRESULT Create ( const CSR * pSR,6 W+ r; B3 e2 V9 e9 F, ]
       const DWORD dwLanguage = SP_CHINESE );' q7 w& @, ?; P$ g' Q1 E( G$ W" A! A
/ k7 m0 V; g% J& V- K7 ?% Q3 E
& g4 \$ Y9 R5 i8 o: w* E  `  w
//********************************设置部分***************************************
/ V+ P+ g0 D- Z
: e- [! A; Q, ^8 T7 c1 h" I: [////////////////////////////////////////////////////////////////////8 M1 j- [1 s; h4 I
//功能: 设置朗读声音的语言种类。
9 h( ~/ X0 G9 {, h! n7 Q1 {//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。# ?  }9 m& O  q
//返回值: HRESULT类型。
! q; @( T3 u- q4 x7 w////////////////////////////////////////////////////////////////////# M8 M# H3 C9 N- Q5 d
HRESULT SetLanguage ( const DWORD dwLanguage );
3 q, |6 v- u3 m# ?: g) R% H& M: Y3 p
. n) X  \/ b1 C/ I; ~9 Z////////////////////////////////////////////////////////////////////. J0 R; c2 C! X' b. z  K
//功能: 设置要处理的的事件。
8 f  A7 G6 o4 \% X//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,1 j% j5 u) I% e+ U9 n' t, y
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事3 Q; \% ?! k& P2 s' W
//    件都会收到通知。, C/ D3 x) u* l0 M0 M
//返回值: HRESULT。
9 ]; p2 m: [3 E1 n3 Z) F3 v////////////////////////////////////////////////////////////////////
1 v' c  u; @: |9 l; YHRESULT SetInterest ( const ULONGLONG   ullInterest );1 ~# D) U( b( z. J' L- b
& m: |1 r8 L6 d. i" S' @0 I  k
////////////////////////////////////////////////////////////////////
' @% L" O1 P3 _0 ?+ l, t//功能: 设置朗读声音的音量。
+ V% ]! _% H( C, Y; P//参数: usVolume:音量数值应该从0到100! O. s: s2 V( v
//返回值: 无。/ w* R* i9 j: D# q$ q! j. i$ c  j! `
////////////////////////////////////////////////////////////////////
, x, N/ r2 \! H( wvoid SetVolume ( USHORT usVolume );
6 G' _5 N) K# p; g9 ~1 T2 Y( a8 w9 h, h/ w
////////////////////////////////////////////////////////////////////) u5 c3 {& T! Z& `- o. w* w
//功能: 得到朗读声音的音量。
1 @- z9 U/ P7 Z6 X' W) ^* i; V//参数: 无。( f, P9 o6 s0 `3 \* R
//返回值: 音量数值,应该从0到100。
$ _3 g1 j' G& C9 b" I2 k1 ~////////////////////////////////////////////////////////////////////2 b+ L! ^& o# o- }) `$ q# {) O
USHORT GetVolume ( );8 Q3 Y' ?) H! H1 z4 E2 \  q, F8 ~: L

& a% b; e% ]6 z0 d4 A" F* Y' `9 L////////////////////////////////////////////////////////////////////
% U) W4 ~1 u, j& S//功能: 设置朗读声音的音速。
+ j: v# d8 j8 T5 @- F, q8 P//参数: RateAdjust:音速,参数范围从-10到10。3 ?* d3 G2 x2 c8 s
//返回值: 无。6 {0 P5 ~$ c( S  B; M+ f, z& F0 Q% H3 J
////////////////////////////////////////////////////////////////////( Z$ H5 F  H- O) Z) |2 r
void SetRate ( LONG RateAdjust );
# N! D& j  N9 U- D
/ \# b" `; I* s. M( L# P: c# H////////////////////////////////////////////////////////////////////
5 m6 s: F7 K7 ]: N//功能: 得到朗读声音的音速。
1 L' O+ a9 ]" X# h% P$ [//参数: 无。
: m+ k. _* e+ h8 a" v6 u//返回值: 音速,参数范围从-10到10。
- U7 ^3 A) {  t2 i! A/ y8 L////////////////////////////////////////////////////////////////////
. ]( d' P0 d" F; F" N$ rLONG GetRate ( );
9 |1 K# e& I+ U/ h- u5 x2 h
3 M/ z, Y2 b! y; {! A" M7 p( e////////////////////////////////////////////////////////////////////. r# }: ~4 u0 o
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。, H0 S# s( M& Q5 C
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
5 u: s' Y% i4 [//返回值: HRESULT。
& a, P" D% B: R8 X////////////////////////////////////////////////////////////////////1 ~: x3 o- N0 P0 S
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");3 W/ }7 ]6 |. D. f
" ?. G. J/ w" I( `5 z1 r. z
////////////////////////////////////////////////////////////////////
  r' ]* P7 y: _//功能: 设置朗读的声音从音箱输出。
0 u0 M  y, _- C0 a//参数: 无。
5 b9 U1 B! @- }0 d* s- `//返回值: HRESULT。
5 x/ h$ Y% i+ S  c////////////////////////////////////////////////////////////////////
1 v+ ]- Q$ W( c6 }9 }8 mHRESULT UnSetOutputWithWav ();
3 c' z2 W/ ~1 |- G- f8 ~1 T' S+ n% z6 Z& c. Y

! R7 K9 D1 U8 L& e* X//**********************播放语音,文本到语音转换部分*****************************( ]- O: T0 ^! }- n2 c8 r

/ V" l( T2 ~8 n& E/ n////////////////////////////////////////////////////////////////////9 F0 Y( d; I( y, `
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
& L" }0 s( C8 ]) N* `1 F" C//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记1 K  C' \5 v( h: `" G) H
//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
, M! |& _8 g9 ^) J$ F% f//    SVSFIsXML为朗读带xml标记的文本。
" K$ O- R4 Z" x- L+ K8 A2 s//返回值: HRESULT。) |& x$ t' T4 V" w, V6 m9 c/ O8 X
////////////////////////////////////////////////////////////////////
8 I( i) r1 K' w+ f5 AHRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );1 H4 E, a" J% ?; Y) o1 |
9 G3 t( Z; _  t
////////////////////////////////////////////////////////////////////
% i; v! S1 Y% F& V* N//功能: 停止朗读。如果朗读为同步方式,则不能停止。
4 N& F- G. `7 S; O//参数: 无。
2 m+ I! E* W7 `6 U* J//返回值: 无。
2 |, G, T; |/ u4 j////////////////////////////////////////////////////////////////////
5 H9 d! P: F3 b  n% J6 Cvoid Stop ( );- O* j, i( C( W$ V2 l
0 f  p# J) y8 ?; ^
////////////////////////////////////////////////////////////////////
. E: [2 k9 X3 U2 E//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
7 U: t7 b6 ?2 C5 J+ b//参数: 无。
+ q9 ]" q: i; `% R/ @9 s/ c, ]: u6 z//返回值: 无。
; [: T) t2 K% a1 w0 h7 B$ v, b////////////////////////////////////////////////////////////////////
! ~" W6 }2 {5 d" zvoid Pause ();
- q  q/ M0 k' N% y  i/ `- K* r0 @0 _" v: u& }: E
////////////////////////////////////////////////////////////////////) {* ^2 z1 m# T8 r  }
//功能: 从暂停的地方继续朗读。6 E/ R8 a1 s" J! E
//参数: 无。
2 y# k& J. Z! {9 D' A% O//返回值: 无。- ~) l* v0 Z) d, a# U9 ^/ J' B
////////////////////////////////////////////////////////////////////
* a6 X4 F5 f2 o" P* R. svoid Resume ();
' u# `& L8 S: j' D# J/ n, r" V
$ i% t( D; L3 c) U& O  y( i4 W
+ c# C; r/ s, h3 d! y4 L//********************************处理事件部分***********************************: z6 R$ x, v0 |/ P% X& s4 J. u3 l

) P1 ?& p9 K: z( ^! xpublic:
  i, o: S% x. S: B% X) \////////////////////////////////////////////////////////////////////
4 L8 u5 D; x3 I3 `8 {5 ]1 o//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。2 J" v( S& c$ ~: a" W/ _4 N1 G9 V% ]! [
//参数: 无。/ u! s$ n% D; J, B* a; e3 u
//返回值: 无。3 V! B% y/ e  e$ H# {
////////////////////////////////////////////////////////////////////7 R- T; J$ |  l, B5 i7 {3 y( b
void ProcessTTSEvent ();
3 {6 f6 B# \( J. w6 e- X! t0 S; A! q7 m4 E
/ K7 v+ _2 }8 Q( @6 ?$ K0 ^
////////////////////////////////////////////////////////////////////: t5 Q, \" q$ r
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。' V" W. x0 y* q$ q- y% U
//参数: 无。
1 E. W+ u( Y% t' ~+ [2 D# G//返回值: 无。
, z  B5 B6 J# f7 x0 U' S////////////////////////////////////////////////////////////////////! f/ ^3 U  h2 x) V" c
virtual void OnStreamStart ();
  m8 }% h" j; b/ i
- U3 `8 {+ b" Q2 G3 G$ s////////////////////////////////////////////////////////////////////1 w, C1 I* g' d5 h, D
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。0 ?  D; x, e* d* M% z
//参数: 无。
; I: _3 W- x5 j1 E4 y/ A5 M) Y& y& R//返回值: 无。  r) `1 V8 g. m' z$ x4 Z
////////////////////////////////////////////////////////////////////# O' s- ?% e, g
virtual void OnStreamEnd ();8 F# a  ^; G1 U1 f; M0 I) M& P' b
};4 U# n4 F! k& Y, D, ]& V
2 ~1 j7 t% z4 O& P. G- k" m
( O0 B- _4 {( ^$ }' N* @' p
///////////////////////////////////////////////////////////////////////
4 l3 {% X. s+ j- w* Y# N///////////////////////////////////////////////////////////////////////2 E* A1 F5 l9 H8 q4 W4 O
//         CSR" {/ W* I. i; v  J* A$ Y
//
1 S: ]" y% W% ]$ M% O///////////////////////////////////////////////////////////////////////
2 W3 [& i" g4 c2 Q5 k2 T; O///////////////////////////////////////////////////////////////////////
# \, W4 P) z7 D8 \" q% S6 x
6 N& z, t( e- G7 f9 Hclass LANE_SPEECH_DLL   CSR
% R  f7 M. J% b4 R: \5 d7 p. S{  y4 X* t* k: w* [  f5 _2 h

3 b. c0 T+ k% o0 e" G- i, Aprotected:; s$ m/ D" k$ K& s% {+ ~2 n( M
HWND m_hWnd;
; N8 J0 e( R0 l/ D. x  O
, T8 n! g, b: d+ }" u- Q9 opublic:; O$ m; `, X) S* ?- x4 R( D, _
CComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。  k- n8 I, ?9 ~; D  U
CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
4 d  K! M  H$ {' R& b! G4 w+ NCComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。/ C% Z5 S* `2 t- d8 Y0 u$ F
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。1 Y" s/ J5 O. j9 U8 H
CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。$ r; Z# L( _6 n4 Y% U: _! g" Y
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
2 z! K- @5 P. h4 j, X  O+ q8 |public:/ C; H' m) S+ ]. J
static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
" p: G  ]2 {' ?8 Y1 b* I3 z" h
9 ~" g$ n1 ^& y* O) l2 F
4 F3 M- z8 {, zprotected:
* E5 Q9 T0 ]: H2 i: x/ t% {( w  A1 x//***************************辅助功能部分****************************************
( v( N# b# K8 ?
3 E6 K' I$ X) A) Y+ r1 v! X8 T////////////////////////////////////////////////////////////////////; X! m# n% x/ u( W# k
//GrammarID加一,每个GrammerID必须不同。! P9 m. q2 Y  d2 b5 K- U, C
////////////////////////////////////////////////////////////////////
7 a0 [3 W% |1 y- B0 astatic void UpdateGrammerID ( );
- }$ a* o3 C5 n7 @; M$ ~7 l! Y4 u0 h, \7 w$ D

$ Z  k  s9 L! Z: Qpublic:
6 y6 S' P; b, i# H; ?- O////////////////////////////////////////////////////////////////////
& {1 i4 N1 T% ?1 F3 t  l' N//功能: 友员。TTS中的从SR引擎中建立voice对象。5 z6 o/ {- Y2 `5 s
//参数: pSRContext:SR上下文对象的指针。
* R& K% L5 E. S) ~$ U3 C  O7 F$ w//返回值: HRESULT类型。& r0 o2 P: @  D5 c& O& E. {0 M
////////////////////////////////////////////////////////////////////) Y: s) ^2 A' O5 ^7 ?% {6 y2 v7 j
friend HRESULT CTTS::Create ( const CSR * pSR,
& ^' U8 k8 z2 G  I- _4 |          const DWORD dwLanguage );: q* v8 i/ E& [+ X* {
( r( u. S7 T2 y/ d  \( O

7 k) O& b6 S: d  r% S3 k//****************************初始化部分*****************************************& B0 K7 E# @  T. G$ f1 i
, T! S+ n, I  j5 I
////////////////////////////////////////////////////////////////////
3 h6 T. S* }" B//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。- ~/ W! t" f+ j% \6 p2 \
//参数: hWnd:要关联的窗口句柄。
' a4 @- [6 q0 w. M5 ?//返回值: 无。' t6 y  _: ~- j9 K$ y. C8 }
////////////////////////////////////////////////////////////////////
' t) d! l  l- w+ y  O8 X! w0 hCSR ( HWND hWnd );
3 P; a5 p3 S9 l* R
4 d2 l+ D# K2 H0 x////////////////////////////////////////////////////////////////////5 W, B* }% z( l, t2 P. p
//功能: 释放所有的对象。
; [, l" {+ C. H) K2 n. s, F//参数: 无。
  D3 D; |+ v( X) e" u//返回值: 无。8 `8 N3 b! B# ]0 l( {! ^) R1 Q1 L
////////////////////////////////////////////////////////////////////* V' l* U, F' Y% f) i  J, n: [, o
~CSR ( );
4 u9 @5 c- b9 n, Y5 C) G5 Q
* R. ]" T2 M1 o5 T2 B6 ~5 e////////////////////////////////////////////////////////////////////
! B( v  a3 L1 D: p& R' r//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,
: h6 Y) F7 z. |' o; e% v( p8 N3 c0 C! Y//    加载文法文件。
' P4 C- c8 m. K. f. f) j6 R- q//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
: J9 g# _' ^8 V. ^; q" d//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。9 Z" [+ ]" [1 F/ z' Q% Z% f! @
//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。2 }; j  S; F" @! C2 }7 Y6 M# c
//返回值: HRESULT类型。& j; K/ f' |8 A0 M- u8 `
////////////////////////////////////////////////////////////////////. O% H! K) O8 w, z3 ~
HRESULT Create (const DWORD   SRType,
& C4 ^4 o( p& Z( J- V$ Q      const WCHAR   *pwcGramFileName = L"grammar.xml",
' m& X5 {$ h9 \      const DWORD   dwLanguage = SP_CHINESE );
! E* m6 U$ L( K( g
6 [) N. x  u: C+ l3 P' U( z' M' J7 u  p2 P$ a3 f- R
//**********************************设置部分*************************************
5 J# B' Y0 ]& I3 A$ ?, U
; G! T% B1 j6 _) F% b+ a4 T$ S2 d////////////////////////////////////////////////////////////////////
( P" j" j: Z3 U' P$ [0 z8 G3 H//功能: 设置要处理的上下文接受的事件。
- s+ c3 B. E; C) k, z4 R0 L//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,; ]8 W+ V+ ^. \
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
7 x9 c7 P1 D3 O& r/ N//    件都会收到通知。
$ K7 [) D0 z0 D' w. v" k, `//返回值: HRESULT。
: L* U2 `1 h) T" N" r////////////////////////////////////////////////////////////////////
# T, B. g( Y/ ?7 H; p! lHRESULT SetInterest ( const ULONGLONG   ullInterest );
% M: w) b# {: A* s# \
2 ]' H8 ^% {0 j/ n0 B' K. c////////////////////////////////////////////////////////////////////
5 y3 l3 t- e) [/ m: u//功能: 设置某个规则的状态(激活或者取消激活)。
2 G: ?/ L  X5 @, l; F. ]( P) S//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,0 j5 {4 N, n& [7 n) _. A
//    FALSE表示取消激活。
- R/ ~1 B; \  v& |//返回值: HRESULT。
( k9 y8 M. Q3 l0 _; `0 D+ k////////////////////////////////////////////////////////////////////# N3 q. S% X$ z  E
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
! y0 Q8 i/ w0 c4 ?; ^. R- S& G- F, ^4 Y" Q1 x/ ?
; D/ ^& D, A* T# e3 b* b
////////////////////////////////////////////////////////////////////- x0 h3 _( I# Q- n  ~% y
//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
0 d: s8 B# T2 P: I% V3 I' Y' P//    风输入。) V1 v& f) D3 b( v2 u1 A* \5 S2 A
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。: B7 K7 d2 W$ W3 I& E# P5 ?
//返回值: HRESULT。
" x. d3 V6 q) U1 ?8 [9 f% Z////////////////////////////////////////////////////////////////////
2 M" l7 n' s  a3 I' W1 y2 c2 [HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
) l* R. r+ ]* d: d+ A! f9 y& o( W2 a6 E; g: {8 n- A
////////////////////////////////////////////////////////////////////- u- z; v# Z3 s% f4 v( q7 i& D
//功能: 取消从.wav文件识别。恢复从麦克风识别。
# ]1 b! A; r6 A) O, t/ I, G//参数: 无。" s) N7 x! b. e  q8 A8 b$ o# g
//返回值: HRESULT。* _  f6 I. n) o( C# z0 z* n& y, J
////////////////////////////////////////////////////////////////////
) \% M1 W: ]2 n6 p. E' f" W9 UHRESULT UnSetInputWithWav ( );8 |% o0 g2 V5 I0 v7 f& b

( b- s& [0 k6 r+ d" A9 _//***********************识别开始,结束,识别结果的处理**************************5 c& |/ @. i2 q4 i3 Q& Y

( T$ h& B: I. N5 G////////////////////////////////////////////////////////////////////1 U) V' s- \4 p; Q+ I4 t& s
//功能: 识别开始(将所有规则激活)。) C1 |0 X, e/ ?
//参数: 无. {( {0 _3 l% @8 X* G) G
//返回值: 无。) h' U6 L7 F5 q, V3 \  R) O
////////////////////////////////////////////////////////////////////
" Y2 |. ^: \7 f' \void StartRecognize ( );
$ [3 P( i) }) Q
" F6 U* f9 B% |2 b////////////////////////////////////////////////////////////////////$ R/ J, Z2 b8 h/ f* ^, @, }# C+ S/ y
//功能: 识别结束(将所有规则取消激活)。
; a. V; @7 F7 V' W& F% O7 x! |* J//参数: 无。
0 B- Z! `, ]% |& f: |//返回值: 无。
, v% u) f. D' f# j& v////////////////////////////////////////////////////////////////////+ @2 X  T, C2 `$ E: h: j+ c
void EndRecognize ( );% a3 I# J% H: s, c) B" C6 Q0 j0 J

% N1 M. ~) o% F4 _  O; |0 p, N8 b+ vpublic:9 f4 Q/ P# u6 n+ b
////////////////////////////////////////////////////////////////////' }8 u- Z$ T% }
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
; ]. e1 O+ r- h2 ~9 n" ?//参数: 无。0 w8 c- Y3 l/ h; p; L; u" m
//返回值: 无。
+ J) j+ i  `8 x////////////////////////////////////////////////////////////////////
, D" L+ A, S, a; w+ V* w! jvoid ProcessRecoEvent ( );( [5 m% `' V* B/ C- z
; P* f  T8 }  }  I& [! |8 R
protected:) |2 ^  Q5 c: P- e) Q/ [
////////////////////////////////////////////////////////////////////
/ r2 L" b2 N% d7 e//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。* A* e  Q1 @! G0 V
//参数: pPhrase:ISpPhrase类型。
' H0 `4 O% Y% B6 }; H( Q3 `//返回值: 无。; [9 s' U0 b: q* x( o3 Y+ B6 q
////////////////////////////////////////////////////////////////////: x7 e8 h$ N6 e: Y7 y- B4 a
void OnRecoSuccess ( ISpPhrase *pPhrase );1 k4 |% x) M: i6 e6 \# L2 n, U, K
# \9 Q4 H$ v/ j. F0 y) D! I
public:
/ _9 B' h7 S( b0 y  e3 b' Y; X% l4 s6 e////////////////////////////////////////////////////////////////////: F6 g: D% [1 Z8 A" H) ~
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
9 A2 Q. V- D+ g8 D' O//    需要在派生类重载。规则ID必须以常量形式预先定义。, d+ }% H* M- {1 [- M
//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。# z/ i5 v( x  i" `# b0 ^8 r
//返回值: 无。
5 G2 P5 v2 N- S9 C& K////////////////////////////////////////////////////////////////////& h' U4 H& r  [
virtual void ExecuteCommand ( const ULONG ulRuleID,
( d6 r1 Y- t) ^" t( ]* s" `          const ULONG ulVal );
$ W7 {0 L; Z' V$ s2 F" @. s& P+ M: N% _% D" g
////////////////////////////////////////////////////////////////////7 C) n! O7 k9 q4 p* v/ k9 x
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。6 U  \$ \: X# k
//参数: 无。
) u+ q& D( W# G$ L//返回值: 无。. D4 @7 e& z( v6 ^# |+ \7 C
////////////////////////////////////////////////////////////////////9 L' o0 t7 U. B5 ?- X, z/ O" o5 \3 N$ @
virtual void OnRecoFail ();% u+ U- I- `$ L; t4 _* x

  |  X6 m" ]5 j" f////////////////////////////////////////////////////////////////////5 ]+ E0 d: T8 Q: T) g
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。# x; b9 }' q: V! K6 P
//参数: 无。
: x, M( ]3 ~. w( y- E3 H, |/ Z//返回值: 无。8 X4 H; {. D/ h4 b. d4 }7 ^8 F1 t
////////////////////////////////////////////////////////////////////4 ]2 x: u. Z0 y1 b( x1 p
virtual void OnStreamStart ();' o, K9 X3 k: T" o5 a0 Z

  C+ ?6 V' u; I) J% }////////////////////////////////////////////////////////////////////
! f! Q& K" k7 N//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
% @% O! T- C. z" _; y# J$ `  L//参数: 无。
; C; ?; r; ^+ ~6 J. e7 u6 T//返回值: 无。
5 i- L5 A) f9 ~. R1 n9 y4 r1 L% E////////////////////////////////////////////////////////////////////& [8 l' m4 O# Q) I+ B
virtual void OnStreamEnd ();  v1 [1 y9 g/ X

+ f3 G: e4 c5 G. b% k1 o9 r};& s, `* i0 W) G5 l
4 H( f8 ~3 @5 p% X

9 M2 o( l, V2 U/ U, i/ ]& A' C+ ~7 p6 w1 k) `
#endif    //LANE_SPEECH_DLL_H1 K: M4 z7 e3 a; r9 f7 a

) ?: B. _4 E! I4 y, t2 ]! O# A///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////; m0 {2 I& z/ ~( B  e3 \! e6 z. v
8 u! l9 @$ L& D" @) j
////////////////////////////////////////////////////////
' {9 l: E1 w0 M: F//( d) d- x  ~# Z. m6 |
// 文件:LaneSpeech.cpp$ c+ S3 ~+ U( m0 q' _
// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能; r  `; F. ^% L( |% m8 R! N1 r
//    语音识别只支持命令模式,不支持连续模式' L1 u& C7 ^' G! e' g
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
* P6 f$ x* c- b, T8 W$ N// 日期: 2004.10
7 ?* w& g" Y" ~// 版本:1.2
/ e# u0 s+ Y7 C9 w' H: J// + X5 l0 t  Q9 R  E- Q
//
3 B- `1 Q5 b) z( m0 r4 W- k% H/ P& K////////////////////////////////////////////////////////- c/ m& g/ R3 Q' v+ D8 q

7 k4 Q4 k" d5 K3 I$ a+ ]/ V4 @$ _8 |( P
# A9 Y5 d# p; i! S: P5 I
#include "LaneSpeech.h"
. Y! b5 X* K4 d  \* O$ b0 Q
4 c: p; d& M1 \. ^//-----生成动态连接库和静态库的处理----------------
8 Z  A' _- F9 f& `* d( }7 v2 p+ |#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
# F; A- Q" q  ~4 t8 S
# a/ X9 V) b) {5 OBOOL APIENTRY DllMain( HANDLE hModule, 5 x5 _3 E6 A" U# M
                       DWORD ul_reason_for_call, & D, c  G1 N0 m
                       LPVOID lpReserved
& X% o, a' t, E* T; q/ i* ], L      )
, f+ a: W' N. u, T/ x6 O$ J+ p{
2 L! B2 F# b6 y( R6 w    switch (ul_reason_for_call)
7 `( R% ~- I8 T6 u1 g$ i{
4 |, }7 d. O3 V# {( _0 ^   case DLL_PROCESS_ATTACH:+ z' v( [# [; c$ x  }
    CoInitialize(NULL);
5 D" J, {/ \+ [7 s2 p2 r9 C    break;
" u% Y- Y/ x3 |# n0 J8 ]; [& G. s. x. z$ n  
1 c# D7 P! i6 v   case DLL_THREAD_ATTACH:
3 X( A& Q9 K5 q$ L# C    break;# m9 |5 }2 u! c# f, ?
  2 o  f6 j, N8 B# X
   case DLL_THREAD_DETACH:
6 }0 |1 q0 M* w2 n1 x7 R1 A( N    break;
. r7 V5 s9 K. |/ K3 ~  : j; z/ _& [4 p7 u* t+ R9 U
   case DLL_PROCESS_DETACH:8 r" w6 G# k% A2 ~' D
    CoUninitialize();2 }! E3 k& H. R5 I" b% m) V  n
    break;
( E3 e; [# w( N. V    }' c. l$ [' o& Q
    return TRUE;
. T; @1 @; s- d5 }" A6 W}
, P- f  }/ e$ f
- ^& J5 N) e% ?3 Y& }( K#endif //USE_SPEECH_DLL% f* ]8 e! ~& _0 ?+ Z5 }) d

1 Y8 r- R" d1 x1 @% B# n: }# L" b5 o: J6 f7 Z. q5 ^4 d, B/ J' Y$ p

! I1 f7 T1 c' Y) ?9 `) e: x  @///////////////////////////////////////////////////////////////
% d) P/ |& {, ~8 b! a. Y+ ~: T$ z
////////////////////////////////////////////////////////////////////& M( X" Y, e) d) ^
//功能: 弹出一个信息框。
3 H$ U! D) w1 h/ q//参数: lpText:是对话框信息。lpCaption:对话框标题。2 F  b% o& _, Q
//返回值: 无。, ?. T: c! d& @% n( F* u
////////////////////////////////////////////////////////////////////
2 S/ I7 D4 }) i4 d8 ?( Pinline void ShowError ( const LPCTSTR lpText = "ERROR",# l# _+ d$ W) n# T
        const LPCTSTR lpCaption = "ERROR" )
9 F. d3 M5 `3 z1 C9 ^: n{
3 M/ o' t4 q5 M" _   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );4 c$ B7 p7 V6 u( g7 J
}) N1 ?, s, n: v

/ \0 C( p( ^; ^; k8 m% w////////////////////////////////////////////////////////////////////- J/ t  S' h# a( I" H5 a
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
3 L+ x* X( X- s3 |//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
& W: g4 [" f9 Z0 O3 n4 y//    lpCaption:对话框标题。
" n) e/ I  t( W4 ]2 b- I: q3 F//返回值: 有错则为FALSE,没错则返回TRUE。+ R) V: r1 D1 a8 u- U* ^7 h
////////////////////////////////////////////////////////////////////
" C' z8 X# [4 W( v- Sinline BOOL CheckHr ( const HRESULT &hr,$ r$ s, @3 a+ n! a: Z, `3 a
        const LPCTSTR lpText = "ERROR",
+ V3 |0 F& [1 g: l        const LPCTSTR   lpCaption = "ERROR" )
) o: l; d( _: i5 }* {7 T+ b{
3 B7 t& L) R7 M1 `2 o# L( u4 J   if ( FAILED( hr ) ) {6 D( p5 A3 m$ d8 ?% c9 D  Y- Y
    ShowError ( lpText, lpCaption );+ x, q# e. X2 Z$ T
    return FALSE;
# Q  m  @$ {5 A8 J5 O3 n   }6 |9 B7 e1 O* d
   return TRUE;
" p/ S. L$ f. l1 f6 f; I* ]! h}3 y1 _" n$ T6 ~9 v+ G

( p0 i5 s3 F' O6 x8 f8 p6 ?) w6 [: U3 z9 `3 l9 {/ @8 d1 f+ S
///////////////////////////////////////////////////////////////////////
8 n% k4 {8 P& j///////////////////////////////////////////////////////////////////////
( |/ j2 {; Z* k+ ?$ A/ @( d//4 C( U' a+ w) ~6 J9 @
//         CTTS7 K; a5 V! t% [3 c) I
//4 n5 V0 Q# d1 q, v: ^
///////////////////////////////////////////////////////////////////////
% }: d, H( J4 d- @" t8 Y///////////////////////////////////////////////////////////////////////" y3 M6 C0 k; ^5 a
& U7 ?3 `" ^1 p( \1 a9 P) T. F
////////////////////////////////////////////////////////////////////
9 g# l2 g7 ^- j8 H//保存关联窗口句柄。初始化COM。8 G& s+ Q: E9 o: V3 E, o8 n
////////////////////////////////////////////////////////////////////% G* \6 Q7 e" L6 T  V
CTTS::CTTS ( const HWND hWnd )" O6 ]- h. X7 B$ g
{% k" [3 z7 l4 a5 p* ]
m_hWnd    = hWnd;0 K; P4 X; B! t) j1 o
m_pVoice   = NULL;: `1 ~9 i9 d# H
m_pToken   = NULL;
6 B. p% K! v! t% u0 O( e. am_pOutputStream = NULL;
6 W+ L' x# }6 C$ ], }, em_pAudio   = NULL;
/ N7 N! Y. F, l) H7 B& }" _}
  ]' I$ R) E3 W' G- b% b8 Y. R$ H, j* }
////////////////////////////////////////////////////////////////////% T0 e7 t5 W( o
//释放所有对象。( M2 E/ n' k# S  q
////////////////////////////////////////////////////////////////////
8 ~6 _4 |9 D6 d* WCTTS::~CTTS ()# B0 @, K* a+ z# w9 b/ n4 ?$ U, Y5 \
{- W& p* Q0 v% `
if( m_pToken) {8 Z1 Y# K) s& n; k/ K, k6 o
   m_pToken.Release();& j. Z# g! ^# F5 T) t: z
   m_pToken = NULL;
8 c3 }. h  P9 D3 M$ _* S}- l& e3 V1 v; v9 S, r
if( m_pAudio ) {
1 D7 S# Y" d; w0 x5 {   m_pAudio.Release();
. B" |  w# V: r+ s& [( |5 k! ?   m_pAudio = NULL;9 l: ?3 Z5 F* {9 H
}) u: J2 c, k0 `7 H. E4 {# k1 C) G
if ( m_pOutputStream ) {
2 u3 d2 @2 q* S( k3 v   m_pOutputStream.Release();
& J% J5 N$ F0 y   m_pOutputStream = NULL;
1 d% g/ [) H( `! ]/ V/ H3 P7 x1 _}
; y( `" ?0 k+ b2 k9 Pif( m_pVoice ) {
1 q3 t; R8 W5 t# }   m_pVoice.Release();
4 L4 E3 V  O( x   m_pVoice = NULL;# v: b5 p* S+ X# s4 n& V
}! Q% ^- \( |) x
}* r, x! S' E4 _. {3 ^
1 V# k2 ?6 h. ^9 i/ s
////////////////////////////////////////////////////////////////////3 I5 ?7 C9 k5 D  r
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。* g" }$ G4 Q+ u7 r3 v
////////////////////////////////////////////////////////////////////
$ R+ e/ m& w( i. p! AHRESULT CTTS::Create( const CSR * pSR,8 y8 |; V- s* x2 H5 H
       const DWORD dwLanguage )' k( v  r$ W" \6 w4 x
{% h' b% O6 R! ]  A" d" a$ l3 ?
HRESULT hr;% e( n5 c8 F7 j; z- J- \2 z! |
hr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
* R* W+ `+ u' P' O- I! x8 D) _" fif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
& N% I7 r1 F: l  Y0 W$ j   return hr;+ |( c; }! v0 ]( \
}
7 ?- X/ X7 _" Q/ ^* L! V% u  ?! ?) N! a/ _4 L: r# |; d% p/ g
SetLanguage ( dwLanguage );
. s% i4 d9 v) P* u, H; |( ~7 z3 w# I" G7 ^
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流- a" B- C9 S9 F/ j1 R6 Z3 m
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
7 V6 E2 b  r5 d* x9 u: o    return hr;% U7 T+ @, ^; W  M3 n4 X/ m4 N( A
}
, v' o7 B3 k- f/ r0 ?( H) T" [: u4 O$ D  p# n! i( z
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
8 r' j5 x8 K1 w  L. p/ X. D//SPEI_END_INPUT_STREAM 表示完成流输出。
5 l3 a5 G) l& u4 c: T4 bhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
; v( c9 v4 o' L4 y* r; S9 H9 I' n; n         SPFEI( SPEI_END_INPUT_STREAM ),
. h% H- s6 S. q5 _; H6 h3 ~            SPFEI( SPEI_START_INPUT_STREAM ) |
% [, P+ M' A6 ]1 c$ f" b" ?            SPFEI( SPEI_END_INPUT_STREAM ) );6 G) a( ^4 Y9 @
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
5 a  ]! x* ^5 N- X  B5 o    return hr;! C6 g$ A' z2 L. H
}: {8 G, v& W/ S3 U( q: X
# R! N" X7 a  O: c
//设置通知消息% I0 f) {# I/ t  X! \4 A, A
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
$ r# X% c' s% e) fif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
# ^/ H, l- r- {% ?$ K, Y    return hr;7 t6 {; {& l4 X/ L: u- d
}4 F8 c% [. w: c* _/ b
8 Z$ C- M' Q6 ?$ d3 T9 r2 e. l
return hr;5 j) y1 R, s. K3 Q8 j1 `
}
  r( p2 b5 r5 L3 ?2 W- q
: P7 t- Z& ?) w- u& L7 {////////////////////////////////////////////////////////////////////
- ?+ w8 [7 L- ?# M5 Q//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。1 m0 G  r  i. p
//并设置兴趣,设置通知事件。
5 l# G" {+ I5 f. i////////////////////////////////////////////////////////////////////
4 H: B5 a  M& H3 X% ]HRESULT CTTS::Create( const DWORD dwLanguage )
5 I6 c! t, ^) H6 S8 v& R{3 {9 I8 z; Z8 V( q" L' r
HRESULT hr;
4 T3 y2 h' D! g- shr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
+ W3 a/ \2 T+ rif ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {8 F' m7 @* I7 ^1 K8 ^& X. n
   return hr;+ n2 F" `, R' r+ Z9 x8 C
}6 }6 {: L9 B# B" S) P0 J, F

% w. L1 T, G! i  j" PSetLanguage ( dwLanguage );5 f; g$ o, @" x, B
7 b- V: e3 ^( p, b" Z
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流  V6 B' ^9 y0 w: Q* O2 |. `
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {8 B9 i4 C: w1 h5 l# F' D
    return hr;: u( t* a. ]! G" r( p/ U" ?" j
}, w1 @2 r, ^. Z# T* f+ L, S0 v
# Y# y2 J3 F1 Z
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
" j$ r* o7 _# _+ m2 H+ ~2 {//SPEI_END_INPUT_STREAM 表示完成流输出。, D5 \6 c5 u6 G( Q% ^4 ]- J/ V3 x
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |, p2 l% y# u* \# S
         SPFEI( SPEI_END_INPUT_STREAM ),% q7 G1 X9 I- @- n
            SPFEI( SPEI_START_INPUT_STREAM ) |2 s9 h- v. R2 f. N
            SPFEI( SPEI_END_INPUT_STREAM ) );, a# L4 Y9 y1 d& C1 S1 a
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
! @9 Q& G. z& [" o6 H" Y    return hr;! Y$ ^1 P3 s" G2 r6 A! o: I+ k
}0 J( d' Q5 o& h$ E' j, ^9 Z+ U5 h

0 V! ?' x9 v  L( m, S$ i//设置通知消息7 L2 A% z3 b* t, y7 P/ d9 e' y$ K
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );6 E' j4 e" k& @4 ~
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {, [; \, b* x+ @5 b# z
    return hr;( ]. j/ F% E) z3 g# ^/ Z' m
}" c. d  I* V( J% v7 Z) @
+ B2 A* ~8 X7 e$ ^1 C" s
return hr;
0 m" R- ?: Z8 e0 d# i2 R. @}. {5 t. G: T5 z. p- p$ S
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件2 n# D, E) D0 s/ q+ n- M$ [
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
; `2 j! C. [: U" R. f& O{
! n+ I. @) y- [. Y  t3 [" N$ S    ::CoInitialize(NULL);//初始化语音环境
8 t4 k; s8 P3 {' n4 M3 Q/ s8 b    ISpVoice * pSpVoice = NULL;//初始化语音变量
( `2 ?# J( I  U! l6 }7 K5 a3 l6 f    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { 0 h; Z- q1 z# J/ J4 ]5 K+ I0 u
        cout << "Failed to create instance of ISpVoice!" << endl; - W2 N" a/ [% e6 }9 b
        return -1; - C  Z4 h0 F7 G& ^+ i2 I
    }

- ]# b3 c2 O- S8 ?) p' }1 r# n7 r: }    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量! j( _! r( ], ?4 [) I2 O
    ::CoUninitialize();//释放语音环境

  ~7 h7 B& a9 M' ~    return 0;
9 }; e# \$ ?1 i' G  n! Y6 n9 W( n}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序$ C) W& @( m9 t4 `+ o
1 H( q2 Q: W5 O& l/ i; q  s
1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
8 X4 G! a+ I1 _( I' N  }/ m: r
http://download.microsoft.com/do ... -US/speechsdk51.exe   
( y* U3 |# L1 `8 p! ^Speech SDK 5.1安装包 (68   MB)     
9 S2 h; D% B/ ~5 B: T8 T- Whttp://download.microsoft.com/do ... chsdk51LangPack.exe      ' Z7 X0 j, f, }
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
; A$ @! X$ |0 b& g! G0 ~4 E" n+ G) f" k/ ?$ |* m
2.下载后,执行安装& Z* _5 h9 o# i' w: q" `
) N' V- H' [4 n5 r
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
/ Q. ~1 n1 ]' {1 Q' T) R7 x' U/ o$ C, Y* z% u, J/ C, d# J3 p
3.VC的环境配置$ w* {9 ]4 M/ M. C

$ y. k5 |7 X3 \在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
- {# B" L; s1 {7 o2 B9 F! {+ [3 d) W. b, C
工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.' o, c! y: W7 k; [' Z
0 p. Y  k" S% f: m9 n* F
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
% H( ~- e7 M4 M1 N1 y" W
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-5-2 07:37 , Processed in 0.019742 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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