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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
" Y" R6 l9 i! f//1,生成动态连接库时,要#define USE_SPEECH_DLL,
- @$ v; q8 f3 }. I, u0 T//      并且#define LANE_SPEECH_EXPORTS. c7 b7 ^. [& [0 `8 V
//2,使用动态连接库时,要#define USE_SPEECH_DLL
* i: l* c# m+ e//3,声称和使用静态连接库时,什么都不需要: {/ \1 J1 O4 h4 n
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),7 H8 o, Q) y& S2 h! G4 H
//      动态连接库就不用调用了。7 e  |& f! E+ e) H3 ?
////////////////////////////////////////////////////////
3 e$ |7 C9 _- `' c/ w#ifndef LANE_SPEECH_H/ b8 X+ I: s: `& J: L$ M, H
#define LANE_SPEECH_H/ J/ x( Y- T1 p, r+ ^: Y1 Z
8 ]( ^& g: E& r, m' C) }
#include <windows.h>. s& u* [0 W2 [* Z2 n. _. [
#define _ATL_APARTMENT_THREADED
/ Y' g' X) v( x#include <atlbase.h>
& b% Y1 H' I- a, Z' y7 h1 nextern 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
1 J9 x: |& C' G; g. U4 Y8 A#include <atlcom.h>
! ~9 ?& F- \& q3 ?2 n#include <sphelper.h>   //sapi需要的头文件6 V. K% D' d$ z* ]; X' f2 w7 G+ h

3 k* |' k; R6 t4 i" `/ q) b//-----生成动态连接库和静态库的处理----------------! y' ^7 `5 W6 [) Z. H6 y
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
6 t) P& C* d5 N
5 g& G% A0 ^, T2 z" {8 H1 r7 ^#ifdef LANE_SPEECH_EXPORTS
" I+ _" m2 Z9 T. ^& K' U3 k* H   #define LANE_SPEECH_DLL __declspec(dllexport)8 m+ K3 ?. [. O4 ^9 f6 T7 @
#else
) @' k1 e4 L6 J9 f) P" R" z, C   #define LANE_SPEECH_DLL __declspec(dllimport)
+ T' y, R; I( d4 Q! ?' a" [#endif4 [! s( L) l, V# b
7 p( o% E& q, m- \: W3 ~- T0 h
//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关
$ x/ _4 s3 Z6 k: z7 d) w6 P//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。; \- y) h  `) o5 [
#pragma warning( disable : 4251 )
3 ^8 d/ ]' ?) K6 y) A. u; O$ G7 @: k4 N2 M  Q) \
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)) w+ L( y9 c9 T5 W* g8 C) |
#define LANE_SPEECH_DLL. T0 h2 Y5 B0 @' |  E
  }2 R8 Z3 f3 W  s  p
#endif //USE_SPEECH_DLL
5 k0 _7 H, |" h+ K6 \7 N) \! y$ X5 H! Y: p! e) A

% p6 J# Y# ]: [) `; z* ~//***************************常量***********************  g6 |1 P2 r& W
' J0 G" u% ~% N4 t2 x
/////////公共常量-----------------
! Y! d2 N: v, Q/ Econst DWORD   SP_CHINESE = 0x0000; //简体中文.
( ?3 d0 ^6 v4 t+ `const DWORD   SP_ENGLISH = 0x0001; //英语.
7 {8 ]2 r+ D; G$ A! C6 I3 _) u/ V
$ a" R8 v" M6 i! }! ]8 K/////////CTTS常量-----------------
, N% j' T0 H7 K2 m! q3 o+ D' bconst UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
" j' [8 i) s5 S: x
6 [4 O* K' m" \/////////SR常量-------------------; d. }7 c2 C4 g* h
const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。0 v+ R8 X. P: L, h7 {0 @. ]6 H
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
" E* d! ]  W3 bconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.. }6 i- I+ {$ U' b1 N# Q+ O4 b1 T9 B
/ |6 i# Y7 b, y3 U" \3 z; j
//以下常量仅作例子用。# m! {( f3 ^7 C" P
#define VID_TopLevelRule 9000   //顶级规则ID; W/ i2 m6 y/ M; O' a- \* K# C
#define VID_SubLevelRule1 9001   //子规则ID6 {7 _/ F/ l7 j
#define VID_SubLevelRule2 9002   //子规则ID
! t! S# W* q$ |, W! ?& W1 }#define VID_SubLevelRule3 9003   //子规则ID- ?* p: Y, f2 ^) A1 f$ {

- p/ h0 _. C: R- H
8 J6 v' z2 k+ c+ l( Y# E//*************************类声明************************2 I7 O9 e+ O* j- |) J
; o+ w' [2 V; X: y% E/ b5 @

- s0 i% b) f% lclass CSR;1 H& j4 k( Q; L+ h* |' q' j6 K
///////////////////////////////////////////////////////////////////////
1 K* i9 B0 \5 k///////////////////////////////////////////////////////////////////////" ~: ]  h, O6 x0 f& N9 O! x4 ~
//
4 s7 j8 c0 u  M* h0 h2 X//         CTTS
9 G0 I; X& u' Z//+ ]5 y1 \" o  D3 a/ a
///////////////////////////////////////////////////////////////////////5 c, n( M% n  j1 d0 ^* T% K
//////////////////////////////////////////////////////////////////////// f: G7 P  ]' k

: |. l; G. s7 J: }class LANE_SPEECH_DLL   CTTS. O  n0 {. ]; Z% o! J9 p
{) c. t# a; V2 E
protected:
+ s* o+ S+ o+ v. z! B8 ?) ^. FHWND       m_hWnd;     // 关联的窗口句柄。7 ]! `9 w. @# ?% M. `! q; p
+ n# |- [) l$ i# {- F
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。1 K2 s; L' u% F% e
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
" Q( s; C/ L4 }/ z) S; eCComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)) @# I, r% {$ z- O5 g$ l- o
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
: Y4 ]3 a' f, g4 m8 T" A, Z( V& b4 c: Q& g- n* _1 E) n' Y
public:6 o* ^0 B7 N9 Y& }8 S
//********************************初始化部分********************
/ [% h" t* `) U5 X
) ^8 I) a3 j  E////////////////////////////////////////////////////////////////////
  u# c( n; k* G: G! [& P$ [" j7 z1 \//功能: 保存与识别引擎关联的窗口句柄。
. F6 c4 g$ G* e% k+ ^//参数: hWnd:要关联的窗口句柄。  R+ M( G/ Q6 x7 o" h. _9 E
//返回值: 无。+ K+ e" t, ?  b6 x5 `. o( p
////////////////////////////////////////////////////////////////////5 F+ O) C1 h& ?3 k- ^
CTTS ( const HWND hWnd );
! S& y0 a; o8 w4 J+ I( Q1 q8 ?4 Q% T
7 D" ~+ L# N, D5 z////////////////////////////////////////////////////////////////////+ X. R, o- o) P1 I4 ?& ]  X
//功能: 释放所有的对象。, Y8 N: A/ ^& R% S0 j) b
//参数: 无。' V* I) L4 L) U
//返回值: 无。' k. G! T; [0 ^3 p' Z
////////////////////////////////////////////////////////////////////5 J" H9 o( @' A  |$ i
~CTTS ();
4 M! o6 J' X4 z; d
4 l4 n4 K" Y7 Z) H4 z1 z0 n* V////////////////////////////////////////////////////////////////////
6 I+ ]  z5 C7 Z5 `9 |( I2 l8 \% Z/ u//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。7 h; ?5 l" P1 L3 T
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,: U# {: L5 e9 n' R, [
//    SP_ENGLISH为英文。
( W9 f6 M; U, H//返回值: HRESULT类型。3 z6 u) a" N- k& [: o0 x3 M% Q
////////////////////////////////////////////////////////////////////1 d! B$ {. o* Z) E& q& ]6 H
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );: w8 |6 A" J+ g& G
9 d- V& l3 {& s* |  {5 ^
////////////////////////////////////////////////////////////////////; r! t  M0 s1 T0 M% H
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
: p0 u% g, {! B' d; T: @0 Q* T) b//    通知事件。
/ s/ P) Z& Y6 Q. a2 p5 Q//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
4 h9 J4 y6 [, [2 N4 A9 ?//    SP_CHINESE为中文,SP_ENGLISH为英文。
; o0 u! c+ C4 G) d* V4 u0 B  Y( {6 j//返回值: HRESULT类型。, M0 X9 w9 q$ v! \  Q5 J
////////////////////////////////////////////////////////////////////6 m- c- X+ U$ o6 Z, N/ e1 e
HRESULT Create ( const CSR * pSR," x9 Y3 Z# a* k
       const DWORD dwLanguage = SP_CHINESE );1 @3 p% g( @# J# l0 I8 V8 w( D

( ?  U; c9 X# ~/ `. }
. ~, C$ D4 f+ ^, W7 s7 U- d' Y//********************************设置部分***************************************
4 i$ ?6 n9 x% f0 X- r! f6 f* h& u* D: }" g) }, y) p9 i$ ^) g
////////////////////////////////////////////////////////////////////
1 U4 r0 J) Z/ F; x7 Q# x//功能: 设置朗读声音的语言种类。" U+ ^  _  W4 n3 Z0 d" y" H/ _5 z
//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。8 |; K& h9 V) j, r! _2 c0 O& T. _; E
//返回值: HRESULT类型。
6 e: T" i- K# V: O6 o////////////////////////////////////////////////////////////////////
! c3 q( j; G$ QHRESULT SetLanguage ( const DWORD dwLanguage );4 f- Y* N& P. k8 j4 Q

9 d: z- `6 Y6 R8 x////////////////////////////////////////////////////////////////////" J# h% E  n8 @; U
//功能: 设置要处理的的事件。9 c- ~- B. l+ Z) ?3 G
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
/ A; K" Y$ `5 n( w  F2 p( D( O//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事9 c0 X7 Y' Q  y( g
//    件都会收到通知。
  a9 I, K  _* E. Y9 |//返回值: HRESULT。
7 ]! e: o/ ~+ ~5 J////////////////////////////////////////////////////////////////////# h7 p4 B6 k: s" {
HRESULT SetInterest ( const ULONGLONG   ullInterest );
. G/ ~3 h" b! _' f9 _: }
% u1 B$ G# @  I& ~/ _////////////////////////////////////////////////////////////////////
/ Y& o4 t( \4 _6 }* ^% a" m//功能: 设置朗读声音的音量。+ J! C7 h5 `( A5 Q3 T
//参数: usVolume:音量数值应该从0到100, _% X4 P: F  a3 m# ^. e. X
//返回值: 无。- N$ K' |- ~$ u- t0 X
////////////////////////////////////////////////////////////////////
) X' f9 W. W2 a( Q1 `void SetVolume ( USHORT usVolume );5 {6 d( e4 \- _  V; |  x: ~/ U& J

1 n0 ^6 Y, R1 k  K: i' y/ K& t////////////////////////////////////////////////////////////////////
8 y2 E- o/ h4 q//功能: 得到朗读声音的音量。- V1 f/ J1 X) \
//参数: 无。
, y, p% O9 q, z- a7 O//返回值: 音量数值,应该从0到100。
; I8 m/ Z5 J* r////////////////////////////////////////////////////////////////////: i& t- \6 u5 j' C$ C" ]2 h
USHORT GetVolume ( );
6 J2 s( t+ P+ E& V$ W" i+ k: m( F- q1 }
////////////////////////////////////////////////////////////////////
4 R. m4 H$ s) ^2 j$ K//功能: 设置朗读声音的音速。' u: |3 P( ]7 z7 _+ Z
//参数: RateAdjust:音速,参数范围从-10到10。; N8 n8 N) H3 x: C5 D- [( b
//返回值: 无。( W' ]) z: k- D3 ]
////////////////////////////////////////////////////////////////////
8 z: I# O+ {9 o1 g( P! j. H- A2 @void SetRate ( LONG RateAdjust );- J. l& z; H/ y, P4 V2 Z$ m

5 {' i7 I4 e9 S4 F! U3 q; Z5 z////////////////////////////////////////////////////////////////////* T- ^* E3 [& [% Q% D
//功能: 得到朗读声音的音速。
: P; u2 w. G- \$ E//参数: 无。
) l9 ]+ D2 R4 A1 N" l//返回值: 音速,参数范围从-10到10。3 ]! G# q7 }! Y1 z
////////////////////////////////////////////////////////////////////
/ }+ B2 g, B$ b- x. |& G' f: f- YLONG GetRate ( );. B0 X- S2 A4 g1 F* Y: P+ n7 ~/ b7 {' X
4 m& d  a* {7 b0 F
////////////////////////////////////////////////////////////////////+ A) k3 U1 N/ \- \
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
% h8 I! {. Z  L# V5 {//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。7 S4 T4 D8 ~: _
//返回值: HRESULT。
" L2 D1 W- ?' S: J  c! V* u////////////////////////////////////////////////////////////////////. e+ N; [% W  O0 R
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");0 M) @/ _# w  f( K9 H- m, H
) b- Y6 j* {+ o7 q* M6 k4 f
////////////////////////////////////////////////////////////////////
0 m; D  k; M" E9 F//功能: 设置朗读的声音从音箱输出。4 Z5 O1 \+ A4 z6 L; Y6 ]! e& A
//参数: 无。
% r0 K- V0 ]# M+ k//返回值: HRESULT。7 k  E# Y' z8 @& D! \. e  U1 D
////////////////////////////////////////////////////////////////////
( o6 B; J$ o) Q& X( k, UHRESULT UnSetOutputWithWav ();
1 [1 R+ u2 y! P$ C7 ~6 x% X) }) {( j& e, v
; r7 N+ z# ^# e2 f8 r( P
//**********************播放语音,文本到语音转换部分*****************************$ e% D0 d9 M$ M' @: x  i3 b
! C3 n: e, @- V8 ^
////////////////////////////////////////////////////////////////////* }2 j3 ~% e4 ^+ o3 m0 D. r
//功能: 停止朗读。如果朗读为同步方式,则不能停止。. j1 i$ I9 O: G7 H5 x) Z9 z
//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
" ]  N& D% j* d6 T: Z' y//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
& \# h5 F; P4 c//    SVSFIsXML为朗读带xml标记的文本。
! R2 y6 v8 I0 _8 R: Z& {* D//返回值: HRESULT。
: h8 Y5 C* F. \% o////////////////////////////////////////////////////////////////////
7 G5 K1 j0 \3 `HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
) A4 S2 Y8 j. P# [2 H
6 C6 x1 r# |  r/ V////////////////////////////////////////////////////////////////////
" h' e0 w: o) W) {$ @, a: A//功能: 停止朗读。如果朗读为同步方式,则不能停止。
6 k$ B8 Y+ L& e0 z: g6 O6 S//参数: 无。
  A/ n7 D$ B2 ~$ s3 g//返回值: 无。
& j0 o2 P8 \( }. _////////////////////////////////////////////////////////////////////; ^: U- t1 q& s3 U8 L9 E5 `
void Stop ( );
/ w& y2 h. {, R$ E
. \* ^/ b( u, ]9 v2 ]////////////////////////////////////////////////////////////////////0 c: o& [8 v* m/ f7 M) J9 `
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
5 ^$ h! E2 j0 m( s9 `! [2 A5 T# W0 s//参数: 无。1 \- E$ @0 X* e  k
//返回值: 无。0 ~! b' ~0 [- b% e! `: V
////////////////////////////////////////////////////////////////////
. V1 t7 S+ V6 h) dvoid Pause ();" X! X! v% d+ H1 P4 @- U
0 o  t9 u/ r4 N( U
////////////////////////////////////////////////////////////////////
0 r7 e3 W; C! C5 f/ l5 w* p/ @8 U//功能: 从暂停的地方继续朗读。, Z- w7 [3 T8 |9 E: o3 W4 x* h9 `
//参数: 无。3 `9 q- \, h; I5 |& M
//返回值: 无。
& a0 a* W& |' i# _////////////////////////////////////////////////////////////////////
4 j: ?+ v: K6 b6 svoid Resume ();+ A# S$ N5 }! q

5 J, e9 w) P! e# F3 f2 v% Y# V" c7 F" R7 s0 D- ^2 h
//********************************处理事件部分***********************************1 ~' B1 ], x2 T. V$ J, v3 y( g

) G. Y( g- U; ]. A, E' Mpublic:
& r: S9 o' |& s% U2 v4 W////////////////////////////////////////////////////////////////////
; m7 k& F. ]9 T$ |' \2 M- Q% |//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
2 B. E  Q8 Y9 ~) J* c& w//参数: 无。
" Z$ c* b' c* |( a: k5 ]9 o//返回值: 无。3 h8 Y- U( v$ T% ~# D
////////////////////////////////////////////////////////////////////
/ A' t7 ]1 \: H7 T8 h/ o- o) C9 H/ kvoid ProcessTTSEvent ();
* A* Z/ N5 V2 v/ @! J- @  n/ U" I) f/ q! f6 A+ n" U' W
7 j$ ]! t) j+ j0 B
////////////////////////////////////////////////////////////////////
8 W# s# i  p" F//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
6 W4 l. d0 j3 T0 T, \+ a# j//参数: 无。
. C" h; b6 \) n; V; O//返回值: 无。7 z; ]8 _. y+ j+ M" J& f. U2 u/ ^
////////////////////////////////////////////////////////////////////
3 s& K  M4 S( l% F& Pvirtual void OnStreamStart ();
- |8 N# b( f* u( o4 e) E" h
4 g6 D6 G" ~1 s, ?////////////////////////////////////////////////////////////////////4 \  i1 b! S) g6 q3 ]+ i  I
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。, O! t+ ]4 r. k, E, [% |4 {3 h
//参数: 无。; ]( G* F1 A" j- h1 O2 n  [0 ^' J, _
//返回值: 无。: e0 @# u  C/ Y! }. Z2 Q
////////////////////////////////////////////////////////////////////3 t( C/ ?* G' K/ f( b
virtual void OnStreamEnd ();+ [/ t4 e8 N6 {; ~+ C$ G6 N
};
8 \! H3 d. `$ K' D3 a2 }& q, Z4 B2 J5 M- }' p5 y0 L: p" m  E

. `- o- h4 c6 O///////////////////////////////////////////////////////////////////////. }7 K  ^% t0 y4 Z. x
///////////////////////////////////////////////////////////////////////- d0 M9 P4 U1 a/ N5 C& I
//         CSR
( g8 T$ U. y* X! z9 p# l//9 O% {0 u0 X' J
///////////////////////////////////////////////////////////////////////
2 ]1 i4 d  r) }+ u( f///////////////////////////////////////////////////////////////////////  k% J" s/ P2 h/ {

3 @, v$ X& o. J4 f$ P! j' _class LANE_SPEECH_DLL   CSR
5 i6 Q; f/ o  H+ n{
( Q, D7 x2 K$ H0 h1 s: E
! H3 V' J( }6 D! `. r6 _! b! p$ o. Aprotected:* b$ c  Q3 ?. E+ Q) q9 Z/ w
HWND m_hWnd;
' E2 o' z6 t" T4 K! F$ q! }, x2 r6 \3 G4 ]: X; r! U
public:
! }+ s* ]5 u' h; wCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
' ~0 Z7 a0 a6 |4 O" C7 K3 eCComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
$ @" v9 ?8 g* c" V; tCComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。
' i6 k- }; N1 X; |+ J9 DCComPtr<ISpStream>    m_pInputStream; // 流()的接口。. U$ v( k6 [2 i' f
CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。
7 a( o. u# z. Q  f5 n# @; LCComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)& l+ R+ B0 M- K2 ~7 g. {5 e
public:
7 ?- I! P# m/ v8 n0 C; b" Ystatic ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。. [# w( U8 i- S0 m1 ]# i

% J3 G0 Y. t. t
1 d, l) s9 ^; R2 t0 |protected:
' ]% x6 ^  b0 f8 m# o7 T* k. F//***************************辅助功能部分****************************************
$ q0 {) O3 k# i/ P$ `; j
3 X6 {6 s2 f  Z( v$ L9 o////////////////////////////////////////////////////////////////////
- I5 e) |& h: e( D//GrammarID加一,每个GrammerID必须不同。
" C. O% C- v6 z, X////////////////////////////////////////////////////////////////////7 ^: S. M7 B! @. @
static void UpdateGrammerID ( );# c/ D; u3 y* x/ v/ L( `1 Q( Q  n
% p  Q$ ^0 {  U  L" o2 H$ R
8 S* Y7 s$ [# c6 Z6 [9 V, R& E# F# U" z
public:" N0 D2 A. U4 q' A
///////////////////////////////////////////////////////////////////// Z- d8 I0 \  v8 {0 W2 B8 @3 l" a
//功能: 友员。TTS中的从SR引擎中建立voice对象。
, c# [  i6 r2 X: T) i  ?) L//参数: pSRContext:SR上下文对象的指针。1 h" ?9 s; O' ?% v
//返回值: HRESULT类型。( z' p. W2 y5 d$ T" @) }: e
////////////////////////////////////////////////////////////////////3 `) h( O- W2 N: W. r: u  H
friend HRESULT CTTS::Create ( const CSR * pSR,
1 v' d2 E6 n8 p2 q          const DWORD dwLanguage );
& _4 r* z" B$ S5 S4 a( h. x4 G* r- l0 E

0 x  [1 n" y1 E$ b0 g& c1 n* {//****************************初始化部分*****************************************
. N0 S* y1 y! Z9 M% g$ ^- Q% U. B2 i7 H
////////////////////////////////////////////////////////////////////
3 {. n/ U4 N' V( ~4 W//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。
1 i- o6 y0 c1 U$ I  ]% A7 F7 m//参数: hWnd:要关联的窗口句柄。* k# u( c% P, F$ q9 E1 f8 ^" R2 |
//返回值: 无。
) c! ]; n  o: b, x! V////////////////////////////////////////////////////////////////////
8 R- O4 G6 O( y! `0 E3 V3 FCSR ( HWND hWnd );! m$ d& U, `  ?; \, A- W# Z7 M  I
/ P1 o5 K# T9 `, a9 ?  Z
////////////////////////////////////////////////////////////////////5 p4 J6 t" `  o
//功能: 释放所有的对象。
' j4 x' T  t" [4 l5 c% _1 Z//参数: 无。: l8 z! j  l8 g( V& y) W, \
//返回值: 无。
! V2 X8 v6 W2 S5 R////////////////////////////////////////////////////////////////////) a( D" L, H4 A
~CSR ( );
9 W2 b& x, _; A/ [& g
0 r  _7 K5 N4 c6 c7 `' Q////////////////////////////////////////////////////////////////////
6 C8 ^: i' P% q  \- M+ {//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,
/ j7 w3 I) O/ k! h4 A//    加载文法文件。* p' U& S2 _5 r/ g( o3 A8 M
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
" J1 C  p6 b$ A1 f' D; e' Z5 U$ W//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。) I5 I! s6 p! Y" }# J
//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。, |$ Q( z3 d* `/ P8 e
//返回值: HRESULT类型。" M5 d' ]8 J% a' e5 n
////////////////////////////////////////////////////////////////////" a3 P, l' c/ E6 c
HRESULT Create (const DWORD   SRType,
- Q9 y2 R! l% C      const WCHAR   *pwcGramFileName = L"grammar.xml",* x( f' l" B$ Z; v
      const DWORD   dwLanguage = SP_CHINESE );% d7 I  ]' i; u
* u& A& c8 [- }* S8 y
7 ^+ D; V& k, Y9 e6 n6 o" X
//**********************************设置部分*************************************' g  J5 S2 W" P; O: k5 r
1 O+ d1 b! D- q3 l
////////////////////////////////////////////////////////////////////
! I8 R$ O/ _, U- `4 z6 n//功能: 设置要处理的上下文接受的事件。
: k: p; h9 O( M( U3 V  o//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
4 I' p( E1 Y& u' e. |$ ]" u& W//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事7 a4 t; v& j  g1 t0 ]/ t
//    件都会收到通知。
/ r+ Z2 ~0 G3 D6 A//返回值: HRESULT。
5 b" b" G; R  N////////////////////////////////////////////////////////////////////* [* w; h# z8 g
HRESULT SetInterest ( const ULONGLONG   ullInterest );
% Q! H: r1 D+ s& d6 C+ K9 v; n3 g+ L  U) {' [
////////////////////////////////////////////////////////////////////
. p: W* U  E: x" i//功能: 设置某个规则的状态(激活或者取消激活)。# e7 e4 T# A' b8 v' {
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,
5 A( d* p9 H1 W, C7 o/ I//    FALSE表示取消激活。
& t3 A; }5 _* J! c# c0 I//返回值: HRESULT。
9 K- t3 Y6 Y  S8 c////////////////////////////////////////////////////////////////////1 b0 ?" @' b# G+ P: I. t
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
, z2 W3 B1 ?- D2 R. z( x$ G9 ~6 H1 H6 g

3 q2 M+ T6 {. D* ?////////////////////////////////////////////////////////////////////
/ Z5 U; R$ j+ R/ e3 @//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
  X+ b# Y9 ~. @3 Y' q. a//    风输入。
: G+ ?, {, D# K: V//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。. k  f- Y8 ^2 O& }6 d; s, \
//返回值: HRESULT。
0 [2 e" K+ {/ s+ F2 h////////////////////////////////////////////////////////////////////
9 t' @" u- d( }2 E& H$ _$ BHRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );' P2 m" F$ G1 I5 B# s, T1 m- F
) W+ Z3 m& D1 Y1 G4 H$ u
////////////////////////////////////////////////////////////////////$ H1 B$ s$ V/ N0 ~) L
//功能: 取消从.wav文件识别。恢复从麦克风识别。
2 `$ W. S. r( h! v6 D//参数: 无。/ d  s% s) X$ u' W7 X8 V
//返回值: HRESULT。/ A, n* @: y; V
////////////////////////////////////////////////////////////////////9 {2 _" w' U) j+ \8 V- ^& Y4 D
HRESULT UnSetInputWithWav ( );
$ P$ C$ S3 k7 j( P: N
; G1 T7 t0 |. D7 T//***********************识别开始,结束,识别结果的处理**************************
; \: G" m5 k4 b4 c
/ R3 G$ E7 D5 a# Q0 t+ t////////////////////////////////////////////////////////////////////; i0 i9 l. O5 [% C% b4 P
//功能: 识别开始(将所有规则激活)。9 T  [5 {7 A. u# N2 ~+ {
//参数: 无
' x$ K% G: _; q& ?% T1 v//返回值: 无。
' x( Q9 ]# c+ b/ R5 g  n////////////////////////////////////////////////////////////////////
7 J' [# O" u! A7 S: C1 zvoid StartRecognize ( );
; i9 [( e1 N% g: m* N( |3 j; D
2 T& [3 B, Q, k' S8 S////////////////////////////////////////////////////////////////////: R; h, Y" l# B% \# O
//功能: 识别结束(将所有规则取消激活)。
5 P9 G  H+ P  f8 f7 @( N: o2 O//参数: 无。
* ^5 p( p% o2 \2 w! r# z0 B' Q+ U//返回值: 无。, o* P4 w/ V, T2 ]. A. y
////////////////////////////////////////////////////////////////////8 v- r! O8 u! r1 b3 ]
void EndRecognize ( );
/ P& S$ A) T, e! V( l- r+ n7 g% ?) I' R9 }6 N! S
public:8 V' n, E9 c& |8 t% Y
////////////////////////////////////////////////////////////////////
. {$ }5 g( x' E7 y$ E- ~//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
+ G. a" B  s+ c( `* L+ i//参数: 无。, z9 o- Z8 f. a' a7 d4 a7 v! c6 ]
//返回值: 无。
5 p/ W& a5 a* T. M; s////////////////////////////////////////////////////////////////////! g, b* L  X! C
void ProcessRecoEvent ( );
2 I6 c" t) R. A4 F: C8 b% c$ j. ]  J' b
protected:/ M# n/ g% j5 [7 b8 O
////////////////////////////////////////////////////////////////////
" K' N/ A- ]+ a//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。; T5 M2 b' j- b' t; a! `
//参数: pPhrase:ISpPhrase类型。
3 m6 v  u% x( j+ l) K5 ]//返回值: 无。1 _5 V8 V% G; K4 z
////////////////////////////////////////////////////////////////////
& h5 j/ P$ X0 X0 u& Uvoid OnRecoSuccess ( ISpPhrase *pPhrase );
7 D/ Q1 L& g! P- U) r, a5 a# c4 h/ j: z7 h& `2 B: F' {" T
public:
7 d. \5 o% G5 f/ u9 z( r, C( I////////////////////////////////////////////////////////////////////6 g2 N" V/ M) H4 a" _
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,; l9 h+ R, A- h, H
//    需要在派生类重载。规则ID必须以常量形式预先定义。
( u% u) ^* O6 Z# i; o//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。0 u9 q. F6 b0 H! b7 @  A. v% a" e
//返回值: 无。
" }# M* r$ x0 K' s8 Q/ l* Q////////////////////////////////////////////////////////////////////
0 x6 U9 H3 x8 X8 l) L$ Svirtual void ExecuteCommand ( const ULONG ulRuleID,! L4 z  z2 `5 J9 s2 ~! q; ~
          const ULONG ulVal );' W7 T$ `' E0 ^' i; F) |# Y1 _' P0 `
3 O& S/ s% T7 W4 S2 H( y
////////////////////////////////////////////////////////////////////! |9 E0 |* k2 t& @9 X1 z
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。$ K, T7 H& W6 l3 b1 O
//参数: 无。
9 `* l+ ]& ?( P) \+ B  ~//返回值: 无。! y# [) ^2 b0 [2 J4 h% g/ F1 W
////////////////////////////////////////////////////////////////////
, b& J% X* U* j& x( S& h" ]virtual void OnRecoFail ();8 N! S) q2 J3 P' G9 W

8 {- b: S+ }& W4 h////////////////////////////////////////////////////////////////////
/ g& U8 E. m) i- B2 l7 ~//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
2 B5 Z; m0 m7 y9 r( U/ x//参数: 无。
' |3 j4 R  ^+ Y1 A* w/ O//返回值: 无。
( L# I" o: d. x. g! i: T////////////////////////////////////////////////////////////////////  ~& }6 G5 J! b) W8 m
virtual void OnStreamStart ();
. _+ y* f( Q  M9 ~- G; S2 ?* W  L5 Y8 d2 S* E( ^5 x
////////////////////////////////////////////////////////////////////. A1 H( J) u6 e: W% x+ w5 _, J
//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
+ T9 z+ m3 ?) ~" C//参数: 无。
# o" C) N8 c# f3 ]0 b% t: n9 t2 f//返回值: 无。0 c$ ]5 X9 F( R! a( _& I( u
////////////////////////////////////////////////////////////////////
2 f3 ?, `$ X& w# Dvirtual void OnStreamEnd ();
! q' A& K" @0 |- w- o5 P" B4 [9 G* b) r& Q  w2 U
};' l0 j. A# F3 _0 ^1 {; b  y

2 p+ g& P" F* b% Y3 O& F& K. F1 k6 f- {6 a

& w5 K- @9 _5 j#endif    //LANE_SPEECH_DLL_H
' b; f0 R, G+ M- R0 k# G$ e$ l3 y' |! v  F# T1 d9 U; m4 ~
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7 E, J. a7 P, R5 n) a, b
7 i8 J0 \  R# a$ {////////////////////////////////////////////////////////
/ t& m' Z4 N# S- ^//
( b! ]! V+ |- w$ n9 F// 文件:LaneSpeech.cpp
2 @: E9 S( }) y. C# [4 S; Z. H1 J// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
/ S, `  ~1 ]! |! a3 r/ s//    语音识别只支持命令模式,不支持连续模式- }" o2 ]; b: ~0 [0 `! [; D
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
+ J" P4 W% P  j) {' H  z- U5 a// 日期: 2004.104 O. @' n+ y% L) N- l! D7 ]! L
// 版本:1.2
) O* V7 ~0 G: c) v: F// , s4 t3 ~8 [) f2 ~6 m
//
5 N: D5 X% x+ C+ p) X2 O////////////////////////////////////////////////////////# x  L2 |; {- S2 ^
: ?. P; ?0 d; z$ u5 m0 I

2 j8 N4 ]1 l9 a9 v+ \
/ Z( W4 f3 Z" o" Z6 R9 x0 u2 N#include "LaneSpeech.h"
) D, r' d" g. X2 D; e$ _0 w
9 W* i& ?2 b: Q: Q//-----生成动态连接库和静态库的处理----------------2 [( j/ m) E, z' d
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类, V% \5 P4 w. \' v  x! ^
6 V& b* j7 p1 o. E
BOOL APIENTRY DllMain( HANDLE hModule,
& G7 m/ k7 ]  _                       DWORD ul_reason_for_call,
; j4 P% z: a7 t' L' X7 B+ c8 i                       LPVOID lpReserved
8 y5 N- J4 O1 O# f      )
6 F  @( E. F1 A{
; K3 H/ Z* j3 R  S) g    switch (ul_reason_for_call)3 T: Y4 M. s1 x
{% L4 ?, L: p' {, J3 U* s2 v
   case DLL_PROCESS_ATTACH:
8 P5 Q( ^, k. T4 \1 P    CoInitialize(NULL);
) h( i: {/ ^1 F( D, I    break;' \1 w7 Q; |& P  Y5 u, f% c6 g
  8 O6 ^; _9 f2 P! n- E* y! n
   case DLL_THREAD_ATTACH:
; S$ F: N  k, W$ x    break;
0 i5 e8 m4 [6 z5 ]  ^; r7 ]! C  
+ w' Q1 _0 A) F; L: q' s0 O   case DLL_THREAD_DETACH:4 Y  S3 y2 Q" {( J, r
    break;' X: w( w' b+ D, J; J
  & J: O5 n  ]+ k+ ]9 l
   case DLL_PROCESS_DETACH:
2 E4 L- Y; P% M" ^    CoUninitialize();$ x8 ^$ `/ h9 `9 ~4 [8 q
    break;6 V9 _- P5 j9 V- q
    }
# f4 c' y6 Z& p9 s    return TRUE;
2 R: t( k! u/ d8 n9 ?7 w; E}
& j4 u7 q' b6 S3 W8 e: q$ {# E( Q9 d# h1 K) E1 L, K
#endif //USE_SPEECH_DLL
, T$ [! q* B$ A
- [6 h$ u$ Z: l+ H# Q
! i; x4 S2 g1 c* k2 }% h2 q0 f* [! O1 N2 c) h
///////////////////////////////////////////////////////////////
4 N3 s: h3 g3 M# Z) f/ A
& |0 k7 x7 q: x4 ~) z2 J////////////////////////////////////////////////////////////////////
! L0 D" d' `  I( J) }//功能: 弹出一个信息框。6 i! g/ g4 V# ^  I& c
//参数: lpText:是对话框信息。lpCaption:对话框标题。
, L0 F2 \$ {6 b" ?+ f6 F9 q  F//返回值: 无。
% R. N5 M( y8 n0 h. |/ h2 \5 \9 j////////////////////////////////////////////////////////////////////. z; j# K1 W! p$ o! x# L; `; U/ r
inline void ShowError ( const LPCTSTR lpText = "ERROR",
  z/ }0 A+ {7 X" v7 I( I        const LPCTSTR lpCaption = "ERROR" )7 p( W+ D" W4 q% j4 E
{
4 b( J& v7 N5 ?   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
1 I$ e# C8 W6 Z0 G. O  l& X: e}) m* K8 _6 Q& f, e% O' u! B1 |. q' G

: U2 @% C$ l9 p9 X////////////////////////////////////////////////////////////////////! w, u( e; U1 A* ^+ l
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
- p9 z" [( N3 N; \9 K; V//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。0 }# S6 O4 Z1 s
//    lpCaption:对话框标题。
1 Q( i: J/ \! V# N) R4 W//返回值: 有错则为FALSE,没错则返回TRUE。
2 ~/ J" M% g# y////////////////////////////////////////////////////////////////////+ {4 c8 n8 _& e. V* }9 W, ~# V  o3 V5 S
inline BOOL CheckHr ( const HRESULT &hr,$ r% c% G7 d3 I
        const LPCTSTR lpText = "ERROR",
5 Y, ~$ Y2 Y( [- @1 T& I5 p3 S        const LPCTSTR   lpCaption = "ERROR" )9 r1 o( G3 V7 U+ p( j' d
{
( N$ Q5 Q% p+ E3 v( C, @4 J) |: ?   if ( FAILED( hr ) ) {/ k& ~5 Z9 z' C3 h- ~' T4 }! J
    ShowError ( lpText, lpCaption );
: {5 w$ c6 o: l- P0 ?5 A6 \    return FALSE;9 d& b1 T2 L! N* t
   }3 u, r" Q7 u2 K
   return TRUE;
# P1 ?/ C  w3 C+ ?0 N. v% a}. |( }- k, G# r4 y7 L. T8 F0 F

' N/ V, {8 C& U/ v. K) n9 l2 |; j+ D
///////////////////////////////////////////////////////////////////////
" J# j" [( J& n- m3 z8 X  f0 ^///////////////////////////////////////////////////////////////////////2 t6 g/ Q1 U0 c7 {6 ^& z0 k6 x
//
& C$ I, d5 j* Z//         CTTS3 E; Z" G, B' V. Y! f& e4 }. @
//
" A- X9 j" l2 s3 \8 K6 D///////////////////////////////////////////////////////////////////////" e+ S" r3 g2 g
///////////////////////////////////////////////////////////////////////' P6 v  c3 p) l8 t. `8 J: {$ n

8 C! E, [: T* |& y3 k% q////////////////////////////////////////////////////////////////////- O' [. X4 \7 ]% J. d" h  v' ?
//保存关联窗口句柄。初始化COM。
1 g$ h% w+ z( N0 `; ^, R. h////////////////////////////////////////////////////////////////////7 ], e$ r( e" R2 s: e
CTTS::CTTS ( const HWND hWnd )) p/ b, }3 k2 I2 v! h
{9 j0 t) X4 G0 W- L% }
m_hWnd    = hWnd;2 D0 l0 n, M/ G3 _8 a, ~$ [2 m
m_pVoice   = NULL;
! `- P' p' c1 [m_pToken   = NULL;
" \  @7 ~# V: A( a: O& [m_pOutputStream = NULL;
# c5 G: w+ Q$ W3 k; im_pAudio   = NULL;) u, @9 d9 B7 X( k0 e  b9 l
}$ P2 f% I/ r2 v7 r9 U+ j
+ u$ z* a3 u* m- C' {
////////////////////////////////////////////////////////////////////* X+ Y: N+ S4 K2 B- w
//释放所有对象。
+ j( J' }2 l, e$ S9 u9 Y1 _: J////////////////////////////////////////////////////////////////////
8 n$ L( ?8 V9 n+ u2 q/ M4 FCTTS::~CTTS ()( J" j8 m3 c$ }. W" O
{
+ P$ H# F+ m, Y& u7 oif( m_pToken) {
0 \3 a, W! w6 i   m_pToken.Release();
! H$ x% Q  B- h  f   m_pToken = NULL;- U( o; B  o  }( A" F5 J6 R
}$ m& s2 y1 }. a9 r
if( m_pAudio ) {
0 A2 L  c5 B& d5 H+ `( @' b   m_pAudio.Release();1 r. Y* N1 c+ G( D+ t# n5 `+ p
   m_pAudio = NULL;
7 H6 i/ L( Y  f! f+ }& U2 {3 z2 D# a8 Z}7 s, E+ z. p3 G
if ( m_pOutputStream ) {( K9 q' z* Y! T
   m_pOutputStream.Release();- L; m  s. Q4 m
   m_pOutputStream = NULL;
8 K3 q7 r9 F; E, I}! L& s$ f4 p- G/ F, Y- S
if( m_pVoice ) {
4 b3 i7 t: z) u/ v  w# `3 h. _   m_pVoice.Release();& ~" Z; w6 Y7 `$ M
   m_pVoice = NULL;9 B1 L, o5 i' ]$ S7 T( G+ ]
}
; Y5 _8 D; h( d) ?2 n1 J2 m; A, A}* f1 \  C4 Q7 a$ ~9 i& R0 S

* J% L& A2 [" @( m5 h: \) [////////////////////////////////////////////////////////////////////
$ N% A6 a. i8 k* s' {- H. w# g! g1 [//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。
5 @) F8 h1 H; R  H- `////////////////////////////////////////////////////////////////////
5 N! L8 F8 e" X/ ]% S0 P4 SHRESULT CTTS::Create( const CSR * pSR,
& @6 R- b% J1 z/ D3 j( t" k       const DWORD dwLanguage ). n- l9 `7 N4 A0 g8 o3 v+ l3 f0 O
{+ \6 M" D6 O6 R$ G. s
HRESULT hr;
$ J- `; a# I* L6 A% y: p; rhr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
9 A. u. L- |1 H/ ~! d( Aif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {1 \0 y4 }' n# X  x' e/ m1 `  I% J3 n
   return hr;
  [$ H! S9 Q  d& \& r) W: r% [}
8 @. P  I. r( R  q* h+ J. p$ a, I- H
' Q8 J: k! E6 O6 C( j) j% wSetLanguage ( dwLanguage );
3 m  u6 a6 \" b! N; B7 |& ?3 Q2 T
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
- ^! f7 t5 S8 e5 Zif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
2 r1 q9 s; n3 Z  a) _0 u6 @; W" h    return hr;
# z; v+ a7 d  N- T/ p5 R+ Q8 k/ ]}
7 V5 q% [4 U5 ], [) R6 b/ o3 o' h3 d* h- M- `+ ]
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM5 \4 g% Z1 |9 s- i
//SPEI_END_INPUT_STREAM 表示完成流输出。, y- G* l: T4 |$ j  b
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |: \2 W$ \. _* s. ?3 p5 ~1 d
         SPFEI( SPEI_END_INPUT_STREAM ),
  Q9 h& f7 U/ Y9 k, v            SPFEI( SPEI_START_INPUT_STREAM ) |. w4 N+ L$ t: m
            SPFEI( SPEI_END_INPUT_STREAM ) );- Q; i4 s0 \! \% h5 a' C
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {0 q' h, J1 S$ }
    return hr;- j% I- X- e! H: W: p$ z; N! G
}
1 x" i1 A& H9 M9 b
( _. n. H6 K6 X( i& t) R  j* R* A//设置通知消息
  j2 g/ ^/ w& I2 A8 t" lhr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );& }, T  p# b7 d  X, w! v( r+ o5 [
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {6 q( H' W- U' U
    return hr;
9 R4 u1 O) w! s* _}! P' J; Q7 |+ K- ~6 M, V9 l  [

) x" W) r0 G- |6 a6 t; sreturn hr;
0 f/ x/ L  t  m5 }7 b( c}- ?$ n( n8 L9 e# S4 Y6 g3 N1 ]
" I( z3 Q4 ]: `3 F6 y% N) U
////////////////////////////////////////////////////////////////////2 Z( }5 _7 H7 `0 r2 j
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
, K' b6 B; F$ {  b( p2 P  i//并设置兴趣,设置通知事件。
" s& B1 m9 \0 E0 Y8 K. W# E; U////////////////////////////////////////////////////////////////////
- D( x5 H0 S4 H) WHRESULT CTTS::Create( const DWORD dwLanguage )
' y+ R- s' Q, j0 @0 D" h/ X{* D+ g2 Y3 u; I/ n
HRESULT hr;, h* n! O7 D4 W! f
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
0 D6 U! }6 G: G' z! W, cif ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {& d$ ]2 l" ^2 }) w3 D% n9 D
   return hr;3 ]; f) x! a- O4 q# a
}5 o, V. a8 E! U  j- v
/ ?" M# ?( e0 ^5 z2 l3 A
SetLanguage ( dwLanguage );& ]6 E' }) M9 ~

- p$ W: F) C+ u( }9 e; s! q0 Vhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流4 ^$ h# U/ r9 z
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
4 @; `9 v3 K/ L# q) o' O    return hr;6 [: t) B" g+ Y, [$ ?, U( `, }/ C
}
( f* O2 B! V, I6 D  V1 ^: v- B7 P) Z; ]+ [  `! U, Q
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
1 ^- g0 {$ c, \/ ], w//SPEI_END_INPUT_STREAM 表示完成流输出。8 K/ O8 r4 |. f! _4 o; m( E: b9 [
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
9 Y6 D' F, h1 D5 [2 k         SPFEI( SPEI_END_INPUT_STREAM ),
0 r0 j7 ?' x( B( A( W9 K3 Z7 c/ j            SPFEI( SPEI_START_INPUT_STREAM ) |
, c, n% Q) f9 G/ H9 b; _, o/ `            SPFEI( SPEI_END_INPUT_STREAM ) );  c' O' |# z6 D8 c6 W: M4 R6 L3 N
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {- U3 G2 A# S& a% u3 T+ c. C4 y
    return hr;6 T' n* [/ ~, q$ r/ ?
}
% B% t: u( c- q
3 r0 o2 d/ C7 M3 n//设置通知消息
& B8 \8 h+ x$ q; s9 n  Ihr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );4 U' Y  p% C6 ?- _7 F
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
" U2 @; T% B8 M1 x. m4 c$ g* ~    return hr;0 E3 k( U( m8 m- K) U+ @
}
" W. J+ R* B3 X0 A0 J; s# E
- `# e& x; ]0 ~$ y$ E8 j; S) ]1 vreturn hr;' m) Z# H; u3 d( R
}1 e/ ^" |1 ^$ Z# h8 O) n: @
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件  k9 ^2 F* U0 A' |
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
: t3 l- s" A$ d8 d5 M$ X* ~, }: H{
( ?4 P' d" f- s6 i* t2 U    ::CoInitialize(NULL);//初始化语音环境$ w; W' f$ ]. U2 m7 n8 ~3 e& G6 Z+ c; R
    ISpVoice * pSpVoice = NULL;//初始化语音变量% H' _# l& f2 }
    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { 4 Y: v7 @6 D0 I3 V
        cout << "Failed to create instance of ISpVoice!" << endl;
# P* P, E- W2 k# q: U1 h        return -1; 3 ^; y  ^. O' f! E! T
    }
7 t# W4 B8 j6 q- \- e0 @% J/ X; k
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量/ r) Y: F5 _. x( ], t. h8 Y" ?
    ::CoUninitialize();//释放语音环境

, j; x8 h& A. e0 C9 H    return 0;0 _" W: c( l  ]+ Y4 z
}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序
& K& i/ Z% C2 l7 T' @$ h  E3 F
- v  C) Q) E# N; X2 U" p1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
8 b: C$ y% F% S5 A6 c& ], e3 b
7 p: P" _) i$ T$ m/ uhttp://download.microsoft.com/do ... -US/speechsdk51.exe   2 V4 v7 q% @4 q1 n
Speech SDK 5.1安装包 (68   MB)     
7 f" X7 R: ?  N+ ~' S2 hhttp://download.microsoft.com/do ... chsdk51LangPack.exe      
8 _$ c! C& A% e1 M+ y+ w+ w中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  " P3 x) g) n9 G; X8 D0 R

. r! |( a1 I2 p  O& a! w2.下载后,执行安装
0 b9 K0 w* D! t5 v& k; N" Z. f2 \: f/ I3 \8 ]
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
- m# L! z( w' w  b# W" ~
9 o1 F8 T6 p5 N& m3.VC的环境配置/ m) O$ C( H- F& K- D
. @1 E6 e; `* c' x( I; [" ?; V) l
在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:3 v' C, j9 A. m$ Q

* y( s9 s' e* Y9 ?* m' C2 @工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
$ d6 W& P9 g1 D5 n2 ^% }) w# W9 S$ F
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
4 h  y/ c6 a2 N
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-5-4 17:15 , Processed in 0.019415 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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