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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////7 @, m, v' \$ _. E4 [
//1,生成动态连接库时,要#define USE_SPEECH_DLL,
- S" D7 U8 W9 B, g# I//      并且#define LANE_SPEECH_EXPORTS
& S9 [% v, Y; i3 |8 E: |//2,使用动态连接库时,要#define USE_SPEECH_DLL
) Y& f: z1 u, Z; n//3,声称和使用静态连接库时,什么都不需要
, ~" K: Y, `3 O- M& d& N! z* F//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),
; ^" Y) C% I6 @0 y: ^//      动态连接库就不用调用了。( v! D0 c. B# r
////////////////////////////////////////////////////////
  q5 v% ]. v) A# o7 ?( I3 b" z6 v#ifndef LANE_SPEECH_H' e6 t' a) ^2 K/ k4 f" r0 o
#define LANE_SPEECH_H
& M! \5 L1 z* W& g( W# S# @1 [" V. \1 J' B8 ^) y: f
#include <windows.h>
4 [' \6 N! ^& T3 T#define _ATL_APARTMENT_THREADED
8 m" h7 q+ y6 i5 I/ Y#include <atlbase.h>9 y1 y5 R/ @, U  G6 o6 W+ U7 c
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: J9 {. H& b2 l
#include <atlcom.h>
9 S7 v9 N% h9 p1 `, \#include <sphelper.h>   //sapi需要的头文件- S# S; S$ \$ C$ C2 j( ?. i1 d
9 u6 t; O) L& ?
//-----生成动态连接库和静态库的处理----------------
  K' r- b# y1 P  u$ B#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
1 Q* |  E& i% p9 s/ Y$ ]" r( I" Y, y6 F8 X& B
#ifdef LANE_SPEECH_EXPORTS
: V# T) S! C. O   #define LANE_SPEECH_DLL __declspec(dllexport)! v  q" e, W6 K" H: }1 J
#else
$ t6 W) v) t% Q/ l3 [" f   #define LANE_SPEECH_DLL __declspec(dllimport)6 L- j, Q" {6 H. q6 o' v
#endif
& b$ N/ L9 ?0 P( K0 U, a. d
' y( |1 O1 B  [3 }' T; w//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关/ `9 g& g% k) v3 W
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
! i6 S$ U+ C! @. d#pragma warning( disable : 4251 )2 `( l8 b/ t/ V) B, B

" _& M6 g, y! x: a8 e; T9 ?: t( S#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)
- j5 e1 M( ^: X( v: l- ]#define LANE_SPEECH_DLL
; `2 X1 [8 Z) f# H) I! V
3 M; @  G! h% Z, r#endif //USE_SPEECH_DLL; N2 i  j4 ~' s* h

, x& l8 `( n% I" b% U) W( b; G5 b7 n% E- b. S- V: b2 d
//***************************常量***********************+ f5 |9 O% q# R$ O% L, z5 H4 e
. q# }- i& x. u  e. Q! Z
/////////公共常量-----------------" X/ O: n3 N$ u% r7 u0 w
const DWORD   SP_CHINESE = 0x0000; //简体中文.9 @' w3 ?: y! t! a
const DWORD   SP_ENGLISH = 0x0001; //英语.1 H% s6 D- z) a. |8 W; w" O

& i. y: d6 z3 v2 k  X5 J/////////CTTS常量-----------------+ c% o# C: g3 @0 Q% Q7 f2 X( S" n
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。& x% L8 i0 l2 @
! j0 @4 _9 e: Z8 l( n8 z
/////////SR常量-------------------: a( O: z5 I6 n/ |! g
const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。
% H4 f3 v$ I0 {# F  W& [const DWORD   SR_INPROC = 0x0000; //独享类型的SR.( H% U/ G5 x' q; {- Y7 y4 l5 |
const DWORD   SR_SHARE = 0x0001; //共享类型的SR.( ?* M7 J( U5 {- V7 R, `
. A' h* }4 J  J' y$ A9 U% [
//以下常量仅作例子用。$ i/ x( l( |- w( L7 f: F0 p
#define VID_TopLevelRule 9000   //顶级规则ID
2 }6 w' r" O) L9 F$ x#define VID_SubLevelRule1 9001   //子规则ID
* d8 ~8 @9 W" L. y4 q) I( h8 \2 F#define VID_SubLevelRule2 9002   //子规则ID" L3 n$ r1 ]$ \; S+ e
#define VID_SubLevelRule3 9003   //子规则ID7 k; a- ^" V  U

$ h4 K# S. ^6 W8 ^' n1 s. d1 @7 a2 W9 t
//*************************类声明************************, |4 C* A7 \2 Z& ~! l( m

0 v# l' l) D# ~! H7 T/ @" x; W$ P, T* Q0 t1 P+ e
class CSR;' D' N% M1 q2 T* ]2 v
///////////////////////////////////////////////////////////////////////9 e  O2 g2 U. D1 a% N$ ^  [
///////////////////////////////////////////////////////////////////////
6 N; t( G0 x5 r' p; c- A//& f5 e5 O3 w5 l4 C4 D
//         CTTS
6 T6 _" Q1 e: O//
' H2 c# n( j( G! }1 d* X) X1 z///////////////////////////////////////////////////////////////////////( f. U0 |+ ?4 X0 \
///////////////////////////////////////////////////////////////////////3 }5 q( x5 q0 g- v/ j

( j" o/ t& h. S' b# eclass LANE_SPEECH_DLL   CTTS& r$ V; f* w/ y- [
{
& V  ]8 C9 N% z: pprotected:
3 r& S: h) l# p3 d- d3 oHWND       m_hWnd;     // 关联的窗口句柄。
  Y7 |. E1 F2 Z& N
* P! @1 L$ w2 X, L( iCComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。( z3 c) l$ W$ O8 @2 w
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
$ r5 N# ?7 ]* i$ Y; SCComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)9 V$ Y5 H; R" g% y
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
. d3 h; E; p; ^! _& m
: r7 O/ `$ h0 ?. s- Epublic:, j) y9 j) [% R, V4 C7 {3 ~7 I
//********************************初始化部分********************5 j& i& `3 q2 _4 E
+ b6 y1 d0 s  u& `
////////////////////////////////////////////////////////////////////
1 |% s) \6 n( n//功能: 保存与识别引擎关联的窗口句柄。3 H7 f% I, ^6 f+ h- V# W
//参数: hWnd:要关联的窗口句柄。
0 a- k# \' l8 L+ g//返回值: 无。- A7 f- f% _8 w4 f
////////////////////////////////////////////////////////////////////
& p! w" ?; \, R- y7 X% q0 ~/ y* sCTTS ( const HWND hWnd );
- ]3 d8 O- P3 e7 B* E, m/ _# E+ w% S7 u+ Y4 R$ m
////////////////////////////////////////////////////////////////////
, Y" H) S" _9 |3 f7 g8 V//功能: 释放所有的对象。3 l" a( [9 P1 U0 Q" Y' a5 r. O
//参数: 无。
$ |& E0 V" J, x" @# _//返回值: 无。
& M: Z! R% Y, F6 S1 [0 |: o////////////////////////////////////////////////////////////////////
: n. a3 N2 c4 {# f' @~CTTS ();; ]: G+ u! A; v

. F" c: x% {1 F3 h/ y////////////////////////////////////////////////////////////////////
% a" q2 t! ^# \7 N+ P( t" a//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。
& J; u) \+ e0 C//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
2 b! P; h9 ?6 m$ L//    SP_ENGLISH为英文。( {! w6 w  P7 Z; R& g4 p/ Z
//返回值: HRESULT类型。7 j: n: W) F9 z) Q4 J$ c3 P$ D6 e6 w/ o
////////////////////////////////////////////////////////////////////; H3 s' N! z3 I0 W6 s& M: a$ t3 X
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );- O: w; ], A1 [. ~

& |5 N: e3 l% s9 m////////////////////////////////////////////////////////////////////
; U% N6 @* h# _$ v//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,+ J) `( R& B, T$ I. n  y* p
//    通知事件。  [3 {  C0 z3 ?1 [! U% D6 w! {. y. F
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
& o, a6 ]3 K2 T$ n, ^; m- Z2 f4 c3 E//    SP_CHINESE为中文,SP_ENGLISH为英文。
) ^; O3 f; r6 A7 o' m1 }//返回值: HRESULT类型。
/ D# j9 J; R( R+ f# d////////////////////////////////////////////////////////////////////: r2 t$ E% ^0 E7 |+ b
HRESULT Create ( const CSR * pSR,; @8 O2 C2 j( O# Z7 n8 B4 h
       const DWORD dwLanguage = SP_CHINESE );
- _7 k1 f) c8 S/ J
: ]* w7 o0 ]: C! X. c: P* b/ [# p/ L* O6 j$ F' W8 _: k
//********************************设置部分***************************************% Y$ O8 B, i3 A7 g2 a2 d  v6 c1 j% [

- g0 W8 v; \& o% U! o////////////////////////////////////////////////////////////////////
. D; ^1 u7 E4 y' t//功能: 设置朗读声音的语言种类。3 B  d( ]5 D) d2 a
//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
. Z. z4 d3 c5 W  C( h4 O//返回值: HRESULT类型。" x. z' n8 j7 p- n: r* W8 C; Y
////////////////////////////////////////////////////////////////////
4 P4 p3 B/ s/ ?7 `! JHRESULT SetLanguage ( const DWORD dwLanguage );4 t) w( q% q6 M+ b' C, r
+ O' j( Q" Q! I4 c
////////////////////////////////////////////////////////////////////+ f9 I/ U- F$ P$ V
//功能: 设置要处理的的事件。9 c$ M+ H& A3 o2 {
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
5 Y/ H" D3 j) R9 v! X6 k# W: {" e4 B//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
) g4 [6 C* ?# E3 ?: R+ D+ ^, K//    件都会收到通知。% j7 w$ j1 s4 p: D0 t( W4 i
//返回值: HRESULT。
3 n0 ^4 ~% s- s2 }' K7 {////////////////////////////////////////////////////////////////////
  ~, s) J) j0 x% `HRESULT SetInterest ( const ULONGLONG   ullInterest );
; P" W. k- C- r2 ^. E" R0 U3 V; }$ ?0 B/ \- b0 d+ y5 c) @
////////////////////////////////////////////////////////////////////
5 {" a6 f7 s! b1 }//功能: 设置朗读声音的音量。
4 U: K  B" v. w- `- @8 w9 S$ c//参数: usVolume:音量数值应该从0到100
5 @  W7 I( o: X2 x//返回值: 无。4 ~7 a8 j: f. K+ V3 B$ L$ U
////////////////////////////////////////////////////////////////////
, z* S' {( Q7 R4 Dvoid SetVolume ( USHORT usVolume );
" V( x2 p# Q9 |0 i* H# z6 ^9 J: k7 {, U! T
////////////////////////////////////////////////////////////////////
7 M5 y' _+ B/ Y! R2 Z//功能: 得到朗读声音的音量。7 }/ s1 d9 e; H7 w: Z
//参数: 无。9 [0 d) V7 h9 _$ Y
//返回值: 音量数值,应该从0到100。
/ G+ E( r8 n5 t! x+ e" k////////////////////////////////////////////////////////////////////
8 o$ X1 m' f( `" ]  KUSHORT GetVolume ( );3 B# A+ O9 p; m1 Y  q' i

. r' U  X# u  N: R////////////////////////////////////////////////////////////////////
2 _, E: {$ J1 a//功能: 设置朗读声音的音速。
. I& h$ o+ [8 g& _# T/ D5 f* [0 |* o//参数: RateAdjust:音速,参数范围从-10到10。
, b/ {# z& x! J1 z* U1 f//返回值: 无。
) z8 Y+ J5 E4 J0 c+ y////////////////////////////////////////////////////////////////////' v* e9 R( Y: E# V0 W. E, A; @
void SetRate ( LONG RateAdjust );
7 X% y- O& N; R# @2 M7 c6 T$ q
////////////////////////////////////////////////////////////////////, Y2 g2 k: }( B0 m2 r1 Y
//功能: 得到朗读声音的音速。
* F! V( s4 m0 R2 r" U) \//参数: 无。
2 s0 R/ @* x! k4 f% l0 [# Q- i- H//返回值: 音速,参数范围从-10到10。9 S; N& N0 V5 e
////////////////////////////////////////////////////////////////////
% H5 R0 D3 Y( ILONG GetRate ( );
5 }4 r( E# d4 {. B, ~/ E
9 R1 |+ q3 s' X5 z; z////////////////////////////////////////////////////////////////////" g/ O% M& t7 ^1 t+ J1 C" l7 M* K
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
2 H8 Y5 |" P. `//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。! j. \0 u/ d& d9 ]! {
//返回值: HRESULT。2 _7 R* }8 f! }6 T
////////////////////////////////////////////////////////////////////
& m" P6 \8 e4 H0 r. fHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");! g; ~4 m5 Q. d4 B* [5 a( m) a8 h

8 z# _# E! d  ?, W0 v////////////////////////////////////////////////////////////////////
- o5 X$ o0 o) s2 e5 S//功能: 设置朗读的声音从音箱输出。# ?  l8 L4 s( X0 L* j
//参数: 无。
) [9 _) P( c) J$ |; ?//返回值: HRESULT。2 q$ I3 _" K  f( K5 N& g8 Z: H
///////////////////////////////////////////////////////////////////// Q8 |' y! W- C  f* y" s7 c
HRESULT UnSetOutputWithWav ();7 v- L8 i4 x* _* d' a

9 l; }$ q0 Q1 r% Q' a+ d
* a' h" O1 V4 F: O9 d4 L9 M9 l//**********************播放语音,文本到语音转换部分*****************************
7 J/ k# Q3 d' k4 n2 g' q& |2 F( U$ l( M* U! j& T
////////////////////////////////////////////////////////////////////
! S4 V+ K: i% O" ]% ^; g//功能: 停止朗读。如果朗读为同步方式,则不能停止。
7 a4 `8 G4 |5 {! r$ l//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
1 j# P+ a/ L& M/ L  Z//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,) j" S& i! R! I5 D% }, x
//    SVSFIsXML为朗读带xml标记的文本。" K3 J+ d+ U8 r9 [
//返回值: HRESULT。
! x4 @/ f) B5 n% A8 r# c5 i* O6 I- @////////////////////////////////////////////////////////////////////
/ |1 K, O0 d7 ~  r- hHRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
- ^, G! S5 F" @0 q& R& D8 X/ z, |9 k1 l1 U
////////////////////////////////////////////////////////////////////' R$ p3 k2 ^% L
//功能: 停止朗读。如果朗读为同步方式,则不能停止。% @% ^: J* T5 t: C1 S2 p
//参数: 无。" C2 h1 p0 D) [1 K. [4 c
//返回值: 无。
0 Z+ f9 Y7 i/ Z. L( ]7 V////////////////////////////////////////////////////////////////////5 L  d2 [3 D& D3 J: a5 P
void Stop ( );
5 W* m- P( @3 w1 `6 h6 D3 L9 p
////////////////////////////////////////////////////////////////////. F& N  J6 B" ]8 Y$ {$ V* s
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
& u: U, V3 _7 ]- @" O//参数: 无。
" ?# S9 R  l) l1 r. J0 Z- L: R//返回值: 无。; O6 g2 `* b( o6 ~( |
////////////////////////////////////////////////////////////////////1 D# _9 r1 u+ D% j) q# D: f; D1 i2 _
void Pause ();
1 S7 M* Z5 j# }. u
2 g4 w& I- q' R5 \2 _////////////////////////////////////////////////////////////////////# R, E2 E, Q- }( O+ }
//功能: 从暂停的地方继续朗读。
1 \  B! }) p" m2 }2 _  I+ f9 Q//参数: 无。
( l7 F' ~( E# p/ _" @' l//返回值: 无。0 k& {0 ^- L8 V7 u
////////////////////////////////////////////////////////////////////" ^; O2 Z* h+ |
void Resume ();6 ]/ R; j" ?6 f9 T. \

+ O1 T9 l) _- r: c+ F" m4 r0 b8 f, J  p; `
//********************************处理事件部分***********************************
" |* Z& ^( o* x1 w% U9 G# h; r( u3 a; Q: f. `
public:1 ?: o( S2 q0 @7 Y. n
////////////////////////////////////////////////////////////////////  w: [0 l2 i3 n9 l) \; K9 ~
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。, Y$ Z; c, t8 ^
//参数: 无。
; }- J6 c# Z% k4 R# ]//返回值: 无。1 |$ E7 N: l1 b5 K3 |
////////////////////////////////////////////////////////////////////- L( B1 h6 ]8 `) S
void ProcessTTSEvent ();
$ l3 h$ y/ _. u' N. n
4 V/ ~/ W5 e* o  E6 B6 _% @# ?7 @8 S; e" M' n
////////////////////////////////////////////////////////////////////
0 x- i: K. [6 k- B  J' z//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。9 O1 O9 ^! b* f' c. r
//参数: 无。# v2 ^3 b3 c1 x  j) G3 o  ~
//返回值: 无。
* ~; J: B4 u' s5 |////////////////////////////////////////////////////////////////////
/ e4 d3 s. s3 d: `; D3 _/ Yvirtual void OnStreamStart ();) K8 g' |& Y3 g/ X, Y+ L
( m* K! G3 T3 g- M! [6 d
////////////////////////////////////////////////////////////////////! [: g- N; i4 b0 t3 B
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。8 Q% s" X  I4 |) r. D
//参数: 无。
7 @* p. R2 w  K3 e- [//返回值: 无。5 u' B, U9 O7 s' Z% ~
////////////////////////////////////////////////////////////////////
9 H6 x- X  }$ T! ?: E& Hvirtual void OnStreamEnd ();" w" U  V5 [9 I) ^- R( B
};
  U) H+ u4 q7 A
) V/ n' d; L, D) J# @+ Q# F. i6 e& j, D! @* V
///////////////////////////////////////////////////////////////////////
7 Z& M/ z7 b$ f' g* e6 v///////////////////////////////////////////////////////////////////////% a6 [% C# ~. B
//         CSR, V# L4 r" j  f! C7 T% Q
//
9 j0 u) W2 t- K( X///////////////////////////////////////////////////////////////////////: f/ s% {) q9 X6 X
///////////////////////////////////////////////////////////////////////
; F, {1 D% \$ x7 E. Y+ d
& H) [9 {6 K6 T  Y4 p4 hclass LANE_SPEECH_DLL   CSR& V+ r0 m  U0 z% y
{$ z* n8 d- r; b" j1 G% v
! q8 }# c$ p  N& T
protected:+ P1 I) s1 T, p; {, b
HWND m_hWnd;; s; m7 Q% c& X5 y5 x

* i5 s$ I7 g4 j; }public:3 z/ c' }3 R1 J9 o0 J( a8 K8 \& Q
CComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。8 E3 z2 [% N' ~' `
CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
; i" V- N# N, x5 fCComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。
# Q3 [& f# k# v2 MCComPtr<ISpStream>    m_pInputStream; // 流()的接口。  n3 W5 r( X6 u) N7 y
CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。2 V" M) s% ]# u; r7 y
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
0 c6 K0 ~4 t: _/ Zpublic:
# H* u* |9 i$ pstatic ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
$ o+ ]* A9 I4 X; K" ~7 ^% F% I4 @2 A+ v6 k% r; l: |$ A; B
5 b+ r: ?- Z6 T4 C
protected:
3 m9 r, w4 o$ _9 W//***************************辅助功能部分****************************************
- d0 R$ v6 }1 b# d% ]. Y% |8 @  t" W
////////////////////////////////////////////////////////////////////3 D& H8 R* }. L( \. G2 y* P1 X
//GrammarID加一,每个GrammerID必须不同。
  w' C: [9 }6 e# r2 K+ B6 D% K////////////////////////////////////////////////////////////////////
' e/ G& g: l3 S- s" rstatic void UpdateGrammerID ( );
( x+ Q$ f7 k4 A) o$ [8 R$ L# M7 A3 F/ o  c6 M6 Z
4 T6 g1 I, Y# O* s; a8 o
public:; g% e# m5 [' h9 o- ?: u
///////////////////////////////////////////////////////////////////// y& \3 b1 I% c& y' |$ v5 ~
//功能: 友员。TTS中的从SR引擎中建立voice对象。
1 N. _' V% [3 x* U; b( L//参数: pSRContext:SR上下文对象的指针。5 l# V: G, s- y; z+ ?' T
//返回值: HRESULT类型。" A; i, u/ n0 [! e; @4 L  ~
////////////////////////////////////////////////////////////////////: ^% x  O/ ^; }. ^
friend HRESULT CTTS::Create ( const CSR * pSR,5 K6 D; s! N% S% u0 V2 w, B
          const DWORD dwLanguage );
( g6 x% `; P1 u: T+ ?2 s& B6 O3 Q$ ~& [/ [% `. F
. b( t& P( t8 r0 d/ ?$ ^7 S6 h& i# b
//****************************初始化部分*****************************************
) Q1 B9 e$ B* ~/ t$ I( S
; M' B; H+ e( V3 X///////////////////////////////////////////////////////////////////// m( K/ T+ k4 o1 i
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。
- @/ E$ x: V- C1 p//参数: hWnd:要关联的窗口句柄。5 W: p$ ]3 O" X  ?4 |: A3 D
//返回值: 无。
0 A/ H) s7 L3 ]/ Z- P0 C  Q& E2 V7 T////////////////////////////////////////////////////////////////////, \5 J; u7 y! f, q1 u' @7 e! Y4 X' I
CSR ( HWND hWnd );' M! D+ Y9 G; N1 T
  o% p% N* _9 {( M  ^5 R; Q
////////////////////////////////////////////////////////////////////
+ J$ @& M# j( q+ Q4 r  q//功能: 释放所有的对象。: w9 B' r: q5 A" Z0 b% e, l0 o
//参数: 无。! c+ d8 G+ d" S# N6 T! p
//返回值: 无。
( F% g+ j7 E7 O9 t9 ^% N////////////////////////////////////////////////////////////////////
7 G/ F& P! y! e' @, c- P, b. h5 E~CSR ( );
5 X( O' j1 h% ~  f. f6 k3 D1 i5 \
////////////////////////////////////////////////////////////////////' Z; ^+ q& x/ L9 c
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,0 K0 Y% z/ K  a- i- Y7 e$ N$ Y
//    加载文法文件。5 U# O* Y1 C1 S' A' s' _) n9 c
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
  i3 I; h" P6 [4 ?' r//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。. J; W: }0 ?8 J% H8 K* a3 ]
//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。6 @$ R3 u( `/ n) O( D
//返回值: HRESULT类型。! Q: h  j) l+ t
////////////////////////////////////////////////////////////////////$ i2 i% `& ^. p0 G/ X
HRESULT Create (const DWORD   SRType,
0 O( @' ~* K' O  K3 ~      const WCHAR   *pwcGramFileName = L"grammar.xml",
9 K8 ~+ }9 S. E& |4 X8 L3 Q  H9 l      const DWORD   dwLanguage = SP_CHINESE );$ t/ W% A* ~6 r" G+ [

; d2 F: ?. O1 u! l
. x! }6 `8 l4 E2 r3 L/ t0 p//**********************************设置部分*************************************
- e% z0 F$ [' z0 i
1 [) ]+ Q2 w9 o////////////////////////////////////////////////////////////////////
/ z- F7 g4 f: V9 A+ y3 G//功能: 设置要处理的上下文接受的事件。
3 Z7 g6 `  q8 B//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,9 s  d. Q% ^# K, F/ A
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
1 G' s' B% X. B, Q+ H! Q; p5 B//    件都会收到通知。) j! X+ v# ]9 o% _- X& D# g
//返回值: HRESULT。
# v4 j) n. A' ?6 Z+ f1 s$ r////////////////////////////////////////////////////////////////////' Z+ L+ g& ^" v: c# ^9 y( X6 M
HRESULT SetInterest ( const ULONGLONG   ullInterest );
/ k% h5 I4 H; v3 n0 S4 v0 R
8 O3 F( \$ U% v1 N/ U8 C////////////////////////////////////////////////////////////////////1 x: A& R5 u) \6 H, \
//功能: 设置某个规则的状态(激活或者取消激活)。, r2 p3 l3 Q5 }7 G+ B
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,
8 i4 U! Q) A6 l9 g( w8 i7 ]! Q//    FALSE表示取消激活。9 e) n* E" k, `# [+ N( T5 T
//返回值: HRESULT。
" z/ w3 }  P# J8 Z: Q8 X////////////////////////////////////////////////////////////////////4 O0 T) o. t7 z3 I
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
# O, M+ z5 q' S- f+ W4 q8 E# s. n: {/ r; L9 Z" j7 e0 t
" b  G) ^! ?, e* B" Y
////////////////////////////////////////////////////////////////////
. f) X& x$ v2 V7 E' K+ ]/ s//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克7 B$ @; h" C. z, a4 C8 a9 Z. k
//    风输入。! [1 `$ s* {3 c
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
0 @# z2 o( i9 S( H$ y# x//返回值: HRESULT。
8 K" K$ f0 R+ W( q////////////////////////////////////////////////////////////////////9 ?5 w9 Q' \# Z- G9 ~! Y3 V
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );5 d' \3 t/ f# i
6 @3 |' }; v) u5 L, f( m
////////////////////////////////////////////////////////////////////
& h9 z# L1 w! S1 V//功能: 取消从.wav文件识别。恢复从麦克风识别。
* S* Q. b% z! w- A. f, D, A* u//参数: 无。$ Y4 q- T& l7 ^/ ^" K0 o
//返回值: HRESULT。# T3 v  G; {8 M5 i5 i4 X' z6 S
////////////////////////////////////////////////////////////////////! }2 V6 x4 r- Z! j- v& a: e) o3 |9 D1 ^
HRESULT UnSetInputWithWav ( );& T# F6 ]2 f: M( t, W' I
0 \7 A  E+ \! ~# z9 H
//***********************识别开始,结束,识别结果的处理**************************
( @9 x5 c! `5 T9 _8 _" T4 m; B1 w" e7 \/ a" Y" f; w# _+ ]
////////////////////////////////////////////////////////////////////
3 j* u' o8 o, ?+ ]//功能: 识别开始(将所有规则激活)。* Z. ^# J/ u" b' ^) R
//参数: 无' w; M; Z8 ]# s! n6 }
//返回值: 无。
/ R6 [; t3 u2 B7 W////////////////////////////////////////////////////////////////////* f4 F' `1 D7 q' y
void StartRecognize ( );
" U1 \' M% ^6 b2 J! G3 _
% s7 |! f% g3 E5 l2 {, |0 ]////////////////////////////////////////////////////////////////////
: V+ M4 V& _! n( W//功能: 识别结束(将所有规则取消激活)。  a6 Y) e* i6 U$ b6 a  i
//参数: 无。
! ^& I- p$ \0 p3 g$ H% o//返回值: 无。7 Z: E4 a: u5 c4 f' w1 O0 r% b: _
////////////////////////////////////////////////////////////////////
4 M, s2 ?+ i8 y1 a2 ^void EndRecognize ( );
. s  F9 L0 K% Z- ?- `
' h" T! D$ m% Tpublic:
) L& \9 I& f# R) D& L0 Z# B% w////////////////////////////////////////////////////////////////////" w4 i3 L0 f/ S# O. l& V
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
1 l, d* `' Y2 M- w6 y//参数: 无。
8 U- F& h  |4 K/ A& _( ~% ?2 |  k//返回值: 无。
) U  n$ s: Y# R7 q% H( b% i////////////////////////////////////////////////////////////////////
' G( \% i1 m5 n8 Mvoid ProcessRecoEvent ( );" H% {0 \4 e: w4 a! \& }

' ^2 M' ~% R- O4 @3 H& |protected:- U) a6 v* z( X' y* J# o/ A$ K
///////////////////////////////////////////////////////////////////// k- |' c' }& n0 `
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。  M: v. ]& `7 I/ J) }
//参数: pPhrase:ISpPhrase类型。6 P: k, b0 ]( ]% c
//返回值: 无。4 j. `+ k3 r8 U
////////////////////////////////////////////////////////////////////
8 `9 a( r1 f- m7 ]1 l9 dvoid OnRecoSuccess ( ISpPhrase *pPhrase );
) ?% x0 x) [. V, a# \# |  ]- C, |: H5 h! x, J8 t
public:: ?" F8 k4 U  p& P  z  ^7 [" ~
////////////////////////////////////////////////////////////////////
5 Y4 |5 S# Q+ P) `//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
5 Y/ x! |; R9 [6 a2 x# ^7 Y//    需要在派生类重载。规则ID必须以常量形式预先定义。$ v8 z9 Z' V0 V* m% Q( E- P
//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。+ a3 |* D( T* {* V- h3 e9 a  K
//返回值: 无。9 ?8 X* W: x- ]# c2 a( M
////////////////////////////////////////////////////////////////////+ y$ M0 C; m( c% H! k) p
virtual void ExecuteCommand ( const ULONG ulRuleID,6 v2 X2 i3 U) J" o' s
          const ULONG ulVal );
2 D' B( N  `! `( l6 X" X# J  |; B/ z/ M9 V) g% h# ]
////////////////////////////////////////////////////////////////////
% {7 k6 W3 ^- E% P' Q0 d//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。, E* d) m) ~# R; b* ^4 R. _
//参数: 无。
" j, m" G) h* s& l//返回值: 无。( S& Y8 z+ |1 L8 |3 T6 f
////////////////////////////////////////////////////////////////////
. C+ ~% v% ]  B$ U0 w) |3 mvirtual void OnRecoFail ();
8 ?! N1 l; u: q& v5 z& K. u5 V9 e5 w' P, a" q" H
////////////////////////////////////////////////////////////////////9 d  z9 G! |7 t5 K3 r- ]1 m
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
' c9 Z, \4 L/ m. C//参数: 无。
% U7 O" I4 }  V) d! @//返回值: 无。  V% H+ R8 c- X) J  P
////////////////////////////////////////////////////////////////////% A3 E: O( E1 ]& ~7 Z; n2 r* c
virtual void OnStreamStart ();" G4 z2 g4 L! z; h7 R. g4 r
% r. A1 t1 |4 @3 b
////////////////////////////////////////////////////////////////////6 ^2 O8 v& c, D0 H$ q$ L$ t. t
//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
) `7 D4 m' F# h( n//参数: 无。
5 c9 d0 Q& B) k//返回值: 无。* w8 W2 E( W5 A) C6 W
////////////////////////////////////////////////////////////////////
  Y0 K' a* q5 p' R! W1 N" V6 ]2 Pvirtual void OnStreamEnd ();
) V! d( e! z5 z: W5 [$ H  P; F" a/ ?/ n- M! L1 H! G
};
4 Z& @2 f& j$ O- Y3 s4 [' P! U8 H7 K, j- J2 H5 B
: [9 c6 ]- E6 P- a

" ^' _7 C4 D7 R/ I9 Y#endif    //LANE_SPEECH_DLL_H! |' m) {1 @2 J5 G) x4 I: O

( @  D: {8 g/ h; X8 x///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+ h( K$ z2 Z' u  \3 q
" k1 P6 i1 [. A
////////////////////////////////////////////////////////
6 g  w! Z$ w" ?# D//, v! n& m  X/ g8 _3 a
// 文件:LaneSpeech.cpp
5 y7 U9 _. ^- D3 W% P: Z2 ~( w, x// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
* W5 |6 ]+ ?3 D# }$ c8 v' T+ v//    语音识别只支持命令模式,不支持连续模式, [" y- u& R  q
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
! t) B& M* W' I- v/ e// 日期: 2004.10
: N3 n% G7 n! E6 e6 R// 版本:1.2
/ {# G$ A: n- W! E- c4 U//
" F: C# K# P) J) C( z# c//! P! @* b/ s5 f( p9 Y/ ?
////////////////////////////////////////////////////////
' d2 m8 w* f+ o$ ?7 s7 X2 C5 R: r7 v
. @. x3 r6 V6 n' b

5 u6 P: c1 g- Y# R2 w( W#include "LaneSpeech.h"3 ?+ V1 c0 c7 y
! _5 ^# D1 q9 z& K# {5 h) D
//-----生成动态连接库和静态库的处理----------------
2 ^, U) e, C) |6 L$ M; A#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类9 O' Z  S& T: P  W8 t

4 [$ C+ q- e1 k4 P, eBOOL APIENTRY DllMain( HANDLE hModule, 7 a$ b1 f& d5 P" b
                       DWORD ul_reason_for_call,
) y+ ^5 P* M9 f7 L7 D7 G                       LPVOID lpReserved
7 N7 B. u. n1 k' m+ [2 Q1 P3 E2 K      )
6 E: `2 A  |# i+ O3 _{
+ Y1 m" O: S! o. D. c    switch (ul_reason_for_call)
  }, W; x$ p( r; Z- D  e{" t( z/ M1 K& L3 q5 G6 h: g
   case DLL_PROCESS_ATTACH:  \& M, D7 ?: P% n' u
    CoInitialize(NULL);
7 B7 [3 h7 m/ G6 d: l( b8 ]& G6 ~    break;, t% A+ x4 r1 K6 w. i$ [6 K% H
  
; a3 t/ Q. O9 @5 y' I" ^  v   case DLL_THREAD_ATTACH:$ a& I' U: f# U3 N) }" ^
    break;
6 ?, D* q8 N1 V$ q& I  
4 f) ]5 c& o$ |# L- z1 W   case DLL_THREAD_DETACH:
: n0 ^2 w8 W* I  R. S. N/ W    break;
% P2 X: @" I$ z$ p7 R1 I% n. X/ f* I  9 B. A, C" H' y( ], }
   case DLL_PROCESS_DETACH:
! `6 p: X  M; g1 B& Z    CoUninitialize();
3 D4 R- B3 C0 S9 @4 S7 D& i  @4 a    break;5 }2 _1 a" Q; L3 B( e
    }
; m6 l; u9 ~- B- Z" y- w    return TRUE;6 T. A! ]9 l; c. b+ i9 g2 _
}
- h1 ?& u- x8 o3 S5 S. h& h: f4 V8 |2 n# r- [' ?9 b
#endif //USE_SPEECH_DLL
! f' B2 _3 R; B- F- t8 q
/ h) q4 S: v( N! J3 X- x) k; i0 P" c. Z% W* f
  R0 C1 J/ g. W
///////////////////////////////////////////////////////////////
: E+ b6 e; U( I+ ?, \- B3 I! s$ R4 @
////////////////////////////////////////////////////////////////////+ _; I  K. x! i
//功能: 弹出一个信息框。
: c; V' i  N( z, n6 K/ I1 \4 I//参数: lpText:是对话框信息。lpCaption:对话框标题。
! U0 u  z3 m; z5 a//返回值: 无。% ?  G6 c, f$ h8 H  ~+ [4 @
////////////////////////////////////////////////////////////////////
1 v9 ?2 X4 b. L% tinline void ShowError ( const LPCTSTR lpText = "ERROR",
! X- j& e' t2 |- ^0 C; e        const LPCTSTR lpCaption = "ERROR" )
$ w3 N* [# |9 g4 {{9 a! j6 r. f# S
   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
: k  {$ v) M; w8 e}
/ m( k/ [2 v3 Z  g  P9 O7 J
) N" i" k4 M5 K' b////////////////////////////////////////////////////////////////////7 ~/ j6 I2 ~. h9 [1 m
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
/ r' m9 s) c$ e" L7 \, p//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。( ]! |. }6 J9 b
//    lpCaption:对话框标题。
( B! O  `7 H5 Z! X/ \/ g2 C//返回值: 有错则为FALSE,没错则返回TRUE。
- I& W4 m- g9 W& O////////////////////////////////////////////////////////////////////: z% q' _- f6 W  ^
inline BOOL CheckHr ( const HRESULT &hr,
( t2 f0 e) B; P6 [, ?        const LPCTSTR lpText = "ERROR",9 z2 n- J7 B; F/ O! ]
        const LPCTSTR   lpCaption = "ERROR" )
# g" G' y" r, r& E1 r; E% h; p) I{7 I7 b5 B! a5 p6 l" y; p6 j4 H
   if ( FAILED( hr ) ) {( S6 {5 W+ W3 {8 Y5 ]
    ShowError ( lpText, lpCaption );9 h& Z- f7 N% _& `' o
    return FALSE;
. X7 u8 `: Q/ X. O; T. n3 ?+ h9 r   }
. O9 B3 o8 Y) _0 T) Y: n   return TRUE;8 D7 o6 F, ^7 Z2 R0 g
}" R2 D* U; i3 X" \0 k$ \  F* H; U

; ~( U* F! `1 C: t3 a& M5 w; l
///////////////////////////////////////////////////////////////////////1 B5 [2 V5 K7 h. q9 F
///////////////////////////////////////////////////////////////////////
4 ?2 r* G  G9 N% h0 X//
$ W# k0 Z2 s# T, J! t//         CTTS/ J- y: N. p6 T* D" K/ h' i
//
0 m- o5 A, ~5 o& J$ \; m9 `///////////////////////////////////////////////////////////////////////
! ^2 C. t. `& G3 ?) U% v. r( P! q///////////////////////////////////////////////////////////////////////
7 v) P7 c7 p* a' f+ i1 d4 ?0 e, _$ \
////////////////////////////////////////////////////////////////////
4 u- t4 i" G& a/ r( [, U6 n//保存关联窗口句柄。初始化COM。. X- D; J# A0 G% b
////////////////////////////////////////////////////////////////////+ w. P) [0 H) R8 D
CTTS::CTTS ( const HWND hWnd )
8 T. ?: I% M% O  t. |{
7 g3 ]1 k- J2 W3 O0 I3 m0 L* i5 Sm_hWnd    = hWnd;& K3 I; H9 n2 `. m
m_pVoice   = NULL;6 {  k: F# K3 x+ o. |* J
m_pToken   = NULL;
2 F' v1 P2 H% y0 c$ mm_pOutputStream = NULL;
; _: W# i2 Y$ [( f) M/ i$ Nm_pAudio   = NULL;
. `2 S. D6 }" a- t: I2 q1 u. N9 N}3 K7 q$ t: z1 Q1 l; ]) P) o
3 G; z4 T+ W( u% A
////////////////////////////////////////////////////////////////////
% v3 a# ?, d. c& y6 y; k, M//释放所有对象。6 z; z3 O; o+ [8 H
////////////////////////////////////////////////////////////////////
% v, g1 |6 D7 T- ICTTS::~CTTS ()# B& p6 s& G: i5 y  ?
{
! g- v; t5 L0 pif( m_pToken) {3 a8 |8 |* d) v  E2 F) E
   m_pToken.Release();" X; v7 M. c5 e/ {2 n6 z
   m_pToken = NULL;
, [$ O/ u9 M( @9 y6 g0 c: K8 d- O) I( _}
% c* `' z4 X$ z, |if( m_pAudio ) {( f. T8 k5 S' s1 n' P! r
   m_pAudio.Release();5 }/ `5 w- f) V% H4 v$ j. @
   m_pAudio = NULL;
6 o5 X) B" b, u. J}
! A( t% m6 C4 sif ( m_pOutputStream ) {
- `9 h5 u( `0 j2 b   m_pOutputStream.Release();! c4 e5 v$ L' @! Y% f# [8 R( C
   m_pOutputStream = NULL;
1 P; t% `# n3 U% W+ C3 w}* E. x2 H/ G' j
if( m_pVoice ) {
4 c  `" M( j+ B; x) }* S' K$ c4 i   m_pVoice.Release();
9 O7 M8 ~$ g  |$ v  _9 z   m_pVoice = NULL;" `/ q3 Y) W" C8 A3 l4 |
}. U# R* y, Q. _2 a5 H
}
& y8 L0 X* g- X7 S. ~0 l( y! x6 a! B/ _
////////////////////////////////////////////////////////////////////
# I/ b3 m$ u6 W* g7 c//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。# l( Y; {* P" p8 K
////////////////////////////////////////////////////////////////////& [9 Z' H2 U4 }
HRESULT CTTS::Create( const CSR * pSR,/ K( O9 d$ o9 M$ }7 P2 y: k# x
       const DWORD dwLanguage )
- t9 e) Q' z1 N8 @, K{/ _+ ?. S9 P, T! i( |
HRESULT hr;; N) K5 s' D0 X
hr = pSR->m_pSRContext->GetVoice ( &m_pVoice );$ i8 w: @# O) z' [3 T( p
if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
% D0 h7 ?: c. q! E1 i/ `   return hr;1 h5 h6 A3 s' I
}9 W5 O: B+ z9 m

5 M$ @% G- @; c3 ^5 xSetLanguage ( dwLanguage );$ c; `7 C7 Z0 V

( O& c! |7 a- S' t( Whr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
$ _* l9 _5 Q" b# E5 v! eif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
% `6 |6 m' n1 C4 e    return hr;. _- n4 q( U$ `! n/ @
}
% K& T) ~' \. t  ?% [0 y% t7 m4 Z. p3 t. k- S3 J; F$ [: ?
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
# E2 N# J/ y9 w, y+ n: n! s//SPEI_END_INPUT_STREAM 表示完成流输出。
4 H. _% r0 j7 K3 v! v9 zhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |6 [$ G- D) D+ r* Y" n  {( `2 {1 A' ~7 Q
         SPFEI( SPEI_END_INPUT_STREAM ),, T- e; G, f8 W' P8 O8 z$ X& y) ]
            SPFEI( SPEI_START_INPUT_STREAM ) |# S: ^1 q) o0 h% t7 M
            SPFEI( SPEI_END_INPUT_STREAM ) );' \* V0 u( _# [$ N+ n
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {% V- z4 m1 g) u0 Z
    return hr;5 h0 G' q1 L  m; e0 Q5 ~
}. S% X) {" }+ j

  ]! A" n0 A5 c//设置通知消息, W2 W$ O+ O! V* V
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
. E" L& W$ Q7 c+ h3 }+ @0 f" Eif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {: @  S, }5 ]8 M3 |
    return hr;
; E' D8 {- W6 r$ b% E* G$ ^}( ?/ |/ t4 ]# _$ f4 T& @

/ L+ U' i* o9 g+ Areturn hr;
0 D3 u! n4 ^/ `( n& U}1 v4 D# x! R4 y, V' `

( t/ x& s/ A; e  g9 j( ~////////////////////////////////////////////////////////////////////
* z$ n9 _- Y: W- c9 E//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。# N( c: X+ u1 Z" h- ~
//并设置兴趣,设置通知事件。
/ a$ q5 m) G) ?0 P8 j////////////////////////////////////////////////////////////////////3 O# ^, z/ @+ E8 |: x" m' @7 u
HRESULT CTTS::Create( const DWORD dwLanguage )* z, n$ C9 x3 S4 `
{& ?) q. w- Y4 |0 h% T( m
HRESULT hr;
& e$ i. k, g8 C4 G1 t( uhr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );" S6 }; ^4 b. t/ K; o
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {+ Z4 g  x) L8 F& ?# X
   return hr;
+ [' K5 q8 ~9 S1 G}
' ]. z  [" E: p3 _6 t* h3 p$ ~6 T3 f0 l
SetLanguage ( dwLanguage );
& l( E; A! r) \  x3 ?8 T' N5 \' d3 Z  ?. B9 }
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
2 r/ p, y5 g/ D7 y: r$ `# gif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {+ u/ R0 O4 c2 q
    return hr;" x- l% E: O- @: v9 i& P
}- F& E$ R! Q8 r1 J2 g, W! n! S. b

: |' c" `) H8 C8 q+ j' j; J- ?0 V//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM& r: O" I1 G- S7 s0 y
//SPEI_END_INPUT_STREAM 表示完成流输出。2 \% C, F1 v: T0 B3 }# _5 Z
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |  o; i0 z5 i$ o+ i$ R
         SPFEI( SPEI_END_INPUT_STREAM ),' [6 [) D9 o) G" q9 s4 O3 m
            SPFEI( SPEI_START_INPUT_STREAM ) |
) |6 e9 S+ \2 ]+ f2 J: _' G) e/ s            SPFEI( SPEI_END_INPUT_STREAM ) );7 B+ W- f. \5 C9 P+ c7 ~6 _
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {! ^9 I6 [6 w; [2 ?
    return hr;; H- y) j1 g* q9 A
}" l# {- s: y0 ~
( B4 h+ O& Z! y& a0 J" h! \  A; c- i8 |
//设置通知消息2 p/ n7 N" J  c; P0 ?4 h# k% U4 ]
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
0 s1 Y. R7 k+ k# z1 Q& B! vif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {1 w( m2 p1 {! b
    return hr;8 A% r  k6 q3 {/ v0 k9 K
}: p  ^( k$ V* \, t5 @# C

! B% ^0 S' J/ s* n; ]return hr;
6 @# j" M! t. p% q% K& c}+ B, ]6 E; M& G! e
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件9 z0 t4 {6 h' q) |9 P+ b8 |% |* \6 j
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()% W6 K: |3 Q  c
{
& b0 n  o% m+ ^) A: v# F/ l    ::CoInitialize(NULL);//初始化语音环境
( f4 u- ^) b: z# [& ?4 Q+ D% @+ l6 H    ISpVoice * pSpVoice = NULL;//初始化语音变量8 M* o( b. y/ t7 Y/ C$ D
    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
; }$ B% W$ e4 ^2 C  X( M2 y        cout << "Failed to create instance of ISpVoice!" << endl; 4 U5 _! ~2 {" B+ T$ n# {  R
        return -1; 4 N  X- A0 P2 c3 Y% j0 y9 h5 }5 H
    }

" J% K2 F$ i; G! R* X. G    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量  t1 A) O7 e8 I0 d+ A. q' o
    ::CoUninitialize();//释放语音环境

* m7 f2 k1 p  E  F    return 0;) Q$ |. o1 U7 O0 D* b3 l+ R+ j
}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序
/ v' }7 t: z0 [6 `
( U: x9 [0 L; n( ?. E( b# ~3 v1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
7 h7 f. R8 o: y! q- J2 Y( E) A& `" G; d+ H8 g6 u2 h
http://download.microsoft.com/do ... -US/speechsdk51.exe   ( o/ q) L% [* S1 X' d9 e
Speech SDK 5.1安装包 (68   MB)     
+ _6 r- e" Q! bhttp://download.microsoft.com/do ... chsdk51LangPack.exe      , N4 H: Y+ S8 \0 U! V
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  : _& _1 Q" o: ]

2 D. Q$ Q2 c7 r& Z1 C1 C; l0 B2.下载后,执行安装
/ a% i  c( t  a( |' b' W1 E" c6 [4 X" {# _8 g- J" \+ r) |0 Q
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。+ O8 P. B- {$ g& p% E* t
( V7 m3 j  U$ i8 S3 F1 N
3.VC的环境配置
1 L$ Y) t! P7 q3 v
5 I5 _# f; B4 k& l5 U在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:& w3 X1 M8 Y  y3 T) a

- q- p2 S4 s+ P( F, U; _工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
) E5 G* f. Q$ ]7 g3 Z8 q8 p8 S1 U, r/ |* ^' ~
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~/ F" H" a& Y  o4 ]3 x
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-8-13 22:42 , Processed in 0.023678 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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