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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////. ~& `1 A8 Q1 L, A! O) W
//1,生成动态连接库时,要#define USE_SPEECH_DLL,- v8 l) o. L  ^8 J% R
//      并且#define LANE_SPEECH_EXPORTS
  O2 w8 Y5 ~) z6 i# U* H//2,使用动态连接库时,要#define USE_SPEECH_DLL) C8 Y1 \7 I; d2 ~5 N7 s* D8 W
//3,声称和使用静态连接库时,什么都不需要+ ?. A+ C7 @' D7 e0 }9 s
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),
0 c3 g# h; L0 k. q//      动态连接库就不用调用了。' U9 v6 ^3 R4 b
////////////////////////////////////////////////////////
4 Q, a# w& H0 g# I3 x% Y5 R#ifndef LANE_SPEECH_H, O: e7 R9 ]8 i- k
#define LANE_SPEECH_H
$ Y% ~+ @% [% ]8 Y, X. w0 F+ M- e# Q3 w+ l% N
#include <windows.h>9 X: K8 R- g, J5 N! q
#define _ATL_APARTMENT_THREADED6 Z+ ?/ `/ F8 p$ @% k
#include <atlbase.h>
( ]; P0 c  c6 X( t: a- S9 Rextern 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 _Module8 T1 c; S" ?- t4 I
#include <atlcom.h>
* ^; V/ M# c9 F/ E/ }  Z0 f#include <sphelper.h>   //sapi需要的头文件
) N% x; F* D) r  _$ w
7 _9 g5 R+ c: ~//-----生成动态连接库和静态库的处理----------------( M  x! ^8 X# y# p3 r1 D  z
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类$ n' C* |2 l9 U" |# N4 v4 j* |: V

) O$ x7 [* s+ @! p) _3 r#ifdef LANE_SPEECH_EXPORTS2 m' Y& l; H* y1 t0 l
   #define LANE_SPEECH_DLL __declspec(dllexport), i- h& L& e$ K4 F& T
#else
0 i6 d: U+ l1 U3 q. C- G: m5 [   #define LANE_SPEECH_DLL __declspec(dllimport)
: B5 U. O& Y1 w" G: Y9 V! e1 @1 R% }5 R#endif2 {& j3 J) S$ j& ~! f
- n# M5 H) G. a' z0 U
//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关' O: M( R# [1 K. ]. H5 M' s
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
8 ^6 M) c/ Q- r7 a#pragma warning( disable : 4251 )
9 _& @( n- @* T' Q1 h+ q2 m1 h
, K% u- \" p' D) E4 Z2 a#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)
3 ]4 t# d, _" M+ e#define LANE_SPEECH_DLL
  x1 z0 q. d8 X5 x: k4 B
# E1 a; P9 E& C' c#endif //USE_SPEECH_DLL
/ F' I$ R& p" N# _& Y: u5 ~$ \3 v% L8 \( ?, a- r1 f

+ |' U7 m$ U+ H9 x# ]//***************************常量***********************
+ b0 i! H3 b" g+ B- X( i' i3 D( y1 y, [6 T9 i
/////////公共常量-----------------) M( |$ t% T7 T" R
const DWORD   SP_CHINESE = 0x0000; //简体中文.8 l0 O: K& A) T
const DWORD   SP_ENGLISH = 0x0001; //英语.! Y, ~/ R: q/ ]2 H) s( q% N
2 Y5 r% O" w2 P0 Q4 g; ?% d( o
/////////CTTS常量-----------------2 T: R' R5 U) b7 ^4 M; q  m# {) P
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
9 J; C4 J( e# g5 C: I5 {* b4 A# g2 O/ R3 S
/////////SR常量-------------------8 i, O* t" \' o  |
const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。2 a" n& [+ s7 i. F8 R8 q/ q
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
! t# v7 O# Q0 Y, }5 s: E" X6 Mconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.
# [5 \- M. f' x$ \
/ e8 w9 k, R6 w/ i$ O( K//以下常量仅作例子用。6 Q$ I2 g$ s/ |" w" x
#define VID_TopLevelRule 9000   //顶级规则ID  @. ^) L6 l4 q; Q) F
#define VID_SubLevelRule1 9001   //子规则ID
6 V' U! Z, y0 J' M#define VID_SubLevelRule2 9002   //子规则ID$ M7 @" }3 W9 |1 v( ?# R
#define VID_SubLevelRule3 9003   //子规则ID
( Y1 d% e* f$ F5 ]! B  G
( p; n0 |0 g& c, g1 V% I( T) `& t4 g% U; d5 w. ^, l/ U. [
//*************************类声明************************
! ^) e1 b" [" [$ a: I% z' U! k+ f, D

: `- K( K. x0 G: m0 Uclass CSR;
0 q. ?, Y& O' h5 a/ C* H# i, S///////////////////////////////////////////////////////////////////////1 O# I8 Y% {( k  A- b& C
///////////////////////////////////////////////////////////////////////% v. J) H6 F0 l2 L- F
//
2 J+ K5 [* K! W: K) _# d  [//         CTTS
2 v9 I  I) A, I4 L6 F//
6 u- m) ]  F5 |9 W! a///////////////////////////////////////////////////////////////////////6 W* b8 E! a# C3 E) P; ]: w% r
///////////////////////////////////////////////////////////////////////
8 J: S5 _% o  u% G. f, U4 z! U3 ?. r& J0 R+ \$ ^
class LANE_SPEECH_DLL   CTTS% Q0 ~& Q) J1 P. G; c6 o" k9 K+ |: x
{& }$ I0 J6 s6 f/ }, d
protected:
( A' S+ x, `  e/ MHWND       m_hWnd;     // 关联的窗口句柄。* r- Y, [4 L" n" W. u
" g) E: s$ K. @, x: `; ]  T
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。
, Z+ r- E' N7 CCComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。. ]0 C; d3 l: ~- h2 T7 r" j
CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)
- V6 a( v+ F) oCComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
; a1 p3 |5 Y3 u. _5 K: v( j3 o9 \' X+ D( P% T) O
public:
% N8 x  @( u. N; j) j//********************************初始化部分********************
# E8 Q; t0 m, N# ]# I) d3 g* Q) D# `5 g/ R( E4 U5 f
////////////////////////////////////////////////////////////////////2 O' a7 x1 [: U4 U! Y
//功能: 保存与识别引擎关联的窗口句柄。9 \& B) r6 f' q, p) _5 V
//参数: hWnd:要关联的窗口句柄。  N8 h# J- _' m0 c5 U
//返回值: 无。" u; w+ m; i: f& r, [
////////////////////////////////////////////////////////////////////
2 Q, M1 T( z- `8 v( iCTTS ( const HWND hWnd );0 P0 }+ ^* h4 r( E) c

0 ?% q" \- Z' n+ i+ |- O2 Z7 R9 T////////////////////////////////////////////////////////////////////# W' L- P% z( |) q( c: o3 T
//功能: 释放所有的对象。
0 S) _% x4 p$ `1 ~$ t4 v//参数: 无。
7 w: \9 X' c4 X9 E9 P//返回值: 无。
$ [4 [+ n3 ^. \' ?+ H0 ^////////////////////////////////////////////////////////////////////
% O! ?/ I- w+ b* |6 A; [~CTTS ();7 \& Z2 x+ `& d" f1 g) {# f
% q( ]  ~  R6 Q, I
////////////////////////////////////////////////////////////////////& E* b; a. J9 D
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。$ @7 C# s& `$ O& B- }
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,, `. G. }" V$ T: ?' H# T
//    SP_ENGLISH为英文。- Z9 l2 ^9 f5 ~2 `- k
//返回值: HRESULT类型。
( k0 `, S% `5 f////////////////////////////////////////////////////////////////////
& o2 V) o3 V- v! {% v# EHRESULT Create( const DWORD dwLanguage = SP_CHINESE );! j) `. d7 u) ^1 x8 `

" W$ S( n# |+ @  G/ T2 M////////////////////////////////////////////////////////////////////( B- q: l6 w/ z. v9 x
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
! b6 D, W5 f/ y0 m//    通知事件。8 H& C8 U, Q+ k0 @0 M$ m
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
# P; ]2 I9 v& M  a9 d//    SP_CHINESE为中文,SP_ENGLISH为英文。
1 W8 ~- J  B7 t  c, t//返回值: HRESULT类型。
8 y2 X5 E) w$ |# y1 i+ }////////////////////////////////////////////////////////////////////
6 ~) {' r3 I' S; q2 Z8 {2 c, ~HRESULT Create ( const CSR * pSR,
% V) x- p* X+ B$ K       const DWORD dwLanguage = SP_CHINESE );+ y; U* X& Z/ P, Q* ^9 Q

# r; L8 v8 W2 d: A5 R7 y. D8 a* W1 [" T/ L+ V9 v5 ^) h) m$ Z5 L
//********************************设置部分***************************************
- N& ^* E+ b2 O& B
2 z/ i: N/ j  p/ `5 M////////////////////////////////////////////////////////////////////) c- Q0 I4 E% i+ a% w. r2 y  w
//功能: 设置朗读声音的语言种类。
; E1 t0 K, `9 E7 l* d, v5 W//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
6 L3 ^5 I' e5 k# N' a- V4 G//返回值: HRESULT类型。3 u6 ?: G2 S5 ~0 e) M
////////////////////////////////////////////////////////////////////  z: R8 D% J% l; q, h
HRESULT SetLanguage ( const DWORD dwLanguage );
: Y2 D6 g% i7 a$ r
- ^3 L' p% F, [, o3 W6 ^////////////////////////////////////////////////////////////////////
, L; W5 k& `  f; b0 ~: Y. L5 H//功能: 设置要处理的的事件。/ v9 f2 P7 L, |
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
) @$ S$ R- Z  `4 x$ P//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
! T% X( E8 a: R1 u8 O//    件都会收到通知。! U  a2 u# p! S3 R; }
//返回值: HRESULT。3 E: N. P8 a% n# Q9 O7 E! z" x
////////////////////////////////////////////////////////////////////9 C# `5 i0 k; U# B0 J% e* Q3 |% C
HRESULT SetInterest ( const ULONGLONG   ullInterest );4 I% @% R' Z% S( l4 H& w5 T
3 y. [' J7 z$ ~
////////////////////////////////////////////////////////////////////2 S1 A( S' h4 w
//功能: 设置朗读声音的音量。# v' g5 h3 N8 {
//参数: usVolume:音量数值应该从0到100
7 Z- S! k# \7 R2 {//返回值: 无。3 [* j. U: b% S4 V4 z1 B: f  @# a
////////////////////////////////////////////////////////////////////
8 [  r% H- y1 K2 w, w0 r4 evoid SetVolume ( USHORT usVolume );- b' P# I' t( h5 @$ J( a& v

4 q1 P- w- Z) b5 {0 }, B5 X" L6 M4 T////////////////////////////////////////////////////////////////////
% k" Y) _2 r+ ]' r0 }# s//功能: 得到朗读声音的音量。+ m* J$ S' ]- L0 x" o& i! D3 {
//参数: 无。
- o  A; o8 r' U7 _//返回值: 音量数值,应该从0到100。
- H  V$ |( A  a$ ?////////////////////////////////////////////////////////////////////
( I  e, _" w0 u) M7 A3 `USHORT GetVolume ( );6 x* O' `' V# G6 V0 \) K
" p: n% E1 F, H6 B
////////////////////////////////////////////////////////////////////
; I$ |0 ^' u  ^3 q//功能: 设置朗读声音的音速。
! d) {7 Y1 p+ B1 Q9 v+ D, O. u//参数: RateAdjust:音速,参数范围从-10到10。
, f( U! e7 N8 u  m% b//返回值: 无。
% Y: {; M, a  b0 V& {! }- D  [& l) F////////////////////////////////////////////////////////////////////) n' k) ~* l& `
void SetRate ( LONG RateAdjust );
0 J, t. [$ V5 f9 u7 v/ g/ c1 Z
4 ?1 n/ r) E/ @8 O$ Q- K////////////////////////////////////////////////////////////////////
- y$ e% q3 A* o% B0 g, P//功能: 得到朗读声音的音速。
; F( o7 k1 z* s* [//参数: 无。
. ]4 q; j2 W8 v6 d; U, l: l+ J//返回值: 音速,参数范围从-10到10。
9 P& `# h! a  ?- a8 ]! l+ F- H////////////////////////////////////////////////////////////////////
) k: ?8 s0 I2 _4 W1 NLONG GetRate ( );: R& B2 N$ G. E; Q

: n0 r7 P, s  V* @; Q* T7 `////////////////////////////////////////////////////////////////////, U! l! P; r5 N8 t
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
+ r( x# c0 i; v5 B3 |//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。& `4 `/ e, i2 o  q: v4 f3 N
//返回值: HRESULT。
8 c2 G5 |6 B9 y9 y& A4 e/ u, R' ~////////////////////////////////////////////////////////////////////
9 Z0 f, n7 Z- M* a8 ~5 IHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");
; E& q7 P: V+ ~& E( L1 L! A( u7 ~9 P# ^: g; C' E, e6 \0 q
////////////////////////////////////////////////////////////////////
) J' p* w; [: k! g% p, ]3 q//功能: 设置朗读的声音从音箱输出。
# x7 Y# Z# U" C- c3 p! M) x+ |8 t# a//参数: 无。
1 x: E* d" g; A* i5 f  }//返回值: HRESULT。
& _; u: J$ v4 U+ n1 z/ c////////////////////////////////////////////////////////////////////+ L, ~, }; G2 r3 z6 l* r: C+ m( U# z
HRESULT UnSetOutputWithWav ();( E+ {8 e  ]4 J: c! z  m
* s% A' Q8 }- X

% M2 F. |* Q' _! [1 W* l' Y//**********************播放语音,文本到语音转换部分*****************************
$ W& c7 c" Z1 Q! M3 B9 S4 m& E
" d; E% G  O% }; e1 |////////////////////////////////////////////////////////////////////
" H; c% i) U) h//功能: 停止朗读。如果朗读为同步方式,则不能停止。
# T0 f& G/ v+ V, j0 L1 J. ?) T  s/ y//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
) I- T" z$ t$ ]! _" j6 x//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,+ E& I4 @: A8 ^
//    SVSFIsXML为朗读带xml标记的文本。5 T$ [+ S7 X0 ]  b1 Y0 o/ W& y; S
//返回值: HRESULT。
1 c5 x$ U1 {0 K7 q  C9 X////////////////////////////////////////////////////////////////////3 }& Q/ {5 _0 E( Z2 e" Y
HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );) {; Z, d5 _+ U- A) s
: e* s  O$ o% p2 |, S2 a2 _
////////////////////////////////////////////////////////////////////! p0 U4 D, [- W: U8 q
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
5 y0 M0 g3 C8 u! a//参数: 无。
9 q2 p- G" j+ B//返回值: 无。
: D2 C* _$ _& c1 P9 j* N& y////////////////////////////////////////////////////////////////////
# C) x: Z6 ^# h" J' A0 Pvoid Stop ( );
7 _# ]1 k: p, q  f& l- f
% ?  E3 Y; E1 _" C$ @3 R////////////////////////////////////////////////////////////////////
; k7 e2 s! X2 L//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
5 t1 Q& W( b( Y; k//参数: 无。1 p/ V6 Q( ?' \% a$ c) M
//返回值: 无。
/ Q; M* L6 L- y2 ]( A////////////////////////////////////////////////////////////////////
$ b& g/ D: ]: H' X( Qvoid Pause ();
4 s3 p4 ?9 ]4 w2 |1 ~) z$ x7 R" J4 _* h
////////////////////////////////////////////////////////////////////0 t6 d' {5 i1 {4 K) \! z6 j1 c! c
//功能: 从暂停的地方继续朗读。! @5 T2 t( x# C2 A
//参数: 无。1 @3 p& H7 [. }; @8 R& H% `
//返回值: 无。8 M% r; @$ m8 p( x2 Q) y
////////////////////////////////////////////////////////////////////: E5 I+ M1 G. R6 D2 v# v- p' d; i
void Resume ();* s% Y3 X8 S* }
% L& w2 Y. y; D! z) n

8 |& _' C9 a2 v% f8 ]4 V//********************************处理事件部分***********************************! l( @+ |- v! h- s2 @
7 H# t5 b! p& v: g! f  X
public:
7 H& x. K% {: Y; t& @1 T. K# E////////////////////////////////////////////////////////////////////
; i$ C8 E( h. E. P& D$ [5 E//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
% p. i3 ]/ G1 O- H//参数: 无。3 T5 a3 G4 K0 z3 I) `
//返回值: 无。
6 P2 |3 |" _& i/ N$ x" e! h7 S. b7 `////////////////////////////////////////////////////////////////////
! w: G6 V  A  p$ ?' x. rvoid ProcessTTSEvent ();
( a$ c0 z3 u- b; N+ X" y7 }' B9 T

; Y9 Q, j; S8 i6 m3 q$ @) b) P8 P////////////////////////////////////////////////////////////////////+ K  t% g+ @, D' N2 i+ e; I
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
$ }- p) c" m0 E3 c- p  Z; U8 i5 p//参数: 无。
4 U; z. _8 j' o. b- _$ B3 m# N& h//返回值: 无。
. l. y6 B4 f  J# w# A' P, g0 m: h////////////////////////////////////////////////////////////////////
) a, `7 Z8 D9 Q8 K% ?, d9 ?virtual void OnStreamStart ();5 I' j' h2 a( `' G
2 N1 R' z- y; G, i* `
////////////////////////////////////////////////////////////////////; y2 x+ W$ A7 V3 \6 j  I+ y; O. F
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。; `- G3 ?) X( i5 p' U; P5 I' K
//参数: 无。3 M7 \& r  i2 B- D
//返回值: 无。& ?2 i& a  _* K% Z5 U3 t. i* q9 H! X
////////////////////////////////////////////////////////////////////
9 G6 @/ T3 T) K0 ~1 Z6 @virtual void OnStreamEnd ();, L- p# T5 _( g6 ~
};7 E( s. X2 R! z  h/ B- }! F) o

, R- C# }& w- p& ^  v! ?, G3 [) P4 @& X; L
///////////////////////////////////////////////////////////////////////
% q8 |+ I- Z- X& w1 p///////////////////////////////////////////////////////////////////////
2 A  X" w' ~7 V; r9 {0 T: x//         CSR
2 B& p% N( u7 @6 \//- k/ O) q8 _9 V$ U
///////////////////////////////////////////////////////////////////////
6 ^/ A) [) B! {) o//////////////////////////////////////////////////////////////////////// R  W, K* Y1 K6 @  }
7 ^! [  `2 ~' a0 B9 f) A
class LANE_SPEECH_DLL   CSR* p( {6 B9 x4 ]6 Y6 _
{
- G3 a( m1 E8 U" R5 {/ E' j# X9 h* K$ V; I. l
protected:5 `; i* T: H: O+ @5 q5 A
HWND m_hWnd;
* H, X5 z4 i/ p  c( L7 |" q
- E: E! u4 e: C" kpublic:
( j; H( f. e: i7 yCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。+ s; f. k# _( Z1 v
CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
( c% ?8 V- y2 _2 wCComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。
) D4 Y, r9 G! @3 K  V4 I+ zCComPtr<ISpStream>    m_pInputStream; // 流()的接口。
5 D: i0 u$ G5 GCComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。7 a- j- U9 H3 V( h# ?" D
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
. n- M9 g" q( s8 J" Npublic:$ C+ x8 l; ~% q8 ~5 F' H- }
static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
* [6 I5 L5 x3 d* q! J  s
% R  H5 C0 U' h4 m" A3 n  e- Z" t; P/ S5 ]$ D; f( d7 t
protected:) u4 ]7 e9 p+ p! `
//***************************辅助功能部分****************************************3 E' ?% U, H& n% P) b9 q
3 d. P  X9 K; b
////////////////////////////////////////////////////////////////////
8 e. f" {  k( ?0 c  L1 v% f//GrammarID加一,每个GrammerID必须不同。' z+ B0 Q  ], U
////////////////////////////////////////////////////////////////////
% p+ L9 f% `7 H% H- Nstatic void UpdateGrammerID ( );
# |' P' a' S5 ]9 Q. B5 t' m
: b$ k$ N  t, k+ F" ?% {8 A
6 g/ J! R9 J& P4 k; K, f+ d! Qpublic:/ ^, l+ t$ G) K; |0 K! T+ c
////////////////////////////////////////////////////////////////////
$ f9 ]0 O$ [7 k6 x' L0 L5 [$ o//功能: 友员。TTS中的从SR引擎中建立voice对象。
5 G+ b1 X3 ^/ T: l9 n, M& |3 m//参数: pSRContext:SR上下文对象的指针。( o) z6 Y2 y" b# p
//返回值: HRESULT类型。3 E& g% [% g( Y. u  C6 B
////////////////////////////////////////////////////////////////////2 M* _  p; `6 x. A
friend HRESULT CTTS::Create ( const CSR * pSR,0 |1 ]1 u8 _* D+ K( v; j3 T3 a
          const DWORD dwLanguage );1 I: v5 U8 e) M& ~2 u- ~* u5 G( N; h

( B0 f0 @$ Q% c* E  O5 ^. x6 B! G) d8 R5 I' a  \/ Q6 A9 j  {! p0 ]
//****************************初始化部分*****************************************
; I3 v$ g" ?3 H2 p. G2 w. F% ]- z6 c( W
////////////////////////////////////////////////////////////////////9 x2 e- X7 X3 `- }0 I
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。
" x) ~1 {' R# W//参数: hWnd:要关联的窗口句柄。0 Z" K: T* Y1 V3 i
//返回值: 无。
9 {' `! Z' U/ Y: y8 i" H2 F6 o& j////////////////////////////////////////////////////////////////////
# ^; |% v9 Y( c2 C) I9 mCSR ( HWND hWnd );; Q& z" y- Q- w' t; H; o

& N$ U" H9 E* J* I' W: E5 e* a////////////////////////////////////////////////////////////////////
% M* B: F+ M! @8 b. f  `) l//功能: 释放所有的对象。2 w) s2 A3 @9 N. m
//参数: 无。- B- y5 u5 u& G
//返回值: 无。
7 ?! G% u9 n1 Z. M////////////////////////////////////////////////////////////////////
4 f1 g& R9 W" Z1 y, G. t~CSR ( );
. o8 w9 L( w! b* Z/ n! K  a6 r4 d6 G
////////////////////////////////////////////////////////////////////$ \) `2 ^# ?% t/ K( P( O
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件," A( X2 N1 z3 a( x
//    加载文法文件。
. }1 N1 J! V+ R//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。2 m1 R% Y& {: t' V
//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
3 ]% ], o, R8 j. \//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。* i0 i9 `* v6 j& F  I2 \, z
//返回值: HRESULT类型。
) `3 m7 {$ D8 }% V. q////////////////////////////////////////////////////////////////////' G- \7 _( ^- ]- U% W. Q
HRESULT Create (const DWORD   SRType,
. ~9 t! n% e* P% f      const WCHAR   *pwcGramFileName = L"grammar.xml",4 ~  j- H/ R6 i5 `0 f- H: j# e+ ~
      const DWORD   dwLanguage = SP_CHINESE );& y7 T- n/ @1 a" D9 e

) Y+ Y" t0 o( g" q
% i3 `0 T( p" {//**********************************设置部分*************************************
2 ^% ?9 @' i: @$ _4 }# C, b3 J( W* _4 x  g
////////////////////////////////////////////////////////////////////
8 h' O. K! J1 p" L. b6 {0 k+ a8 G/ y//功能: 设置要处理的上下文接受的事件。8 M6 a7 s3 J; g: w
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
  c# P; K' E) G  _, `//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
0 B' c+ h+ v8 M//    件都会收到通知。
. P# G" P/ ^% _7 ?7 z- @5 X4 J//返回值: HRESULT。
8 _7 p0 ?2 M- a9 b& ~////////////////////////////////////////////////////////////////////
* [* ?3 }% B7 F( p* kHRESULT SetInterest ( const ULONGLONG   ullInterest );
; ^- ^) Z! r8 l) N4 J. @- M1 _/ t3 C! ^1 |2 g
////////////////////////////////////////////////////////////////////
+ R9 [) e  ^4 _9 j' A: J//功能: 设置某个规则的状态(激活或者取消激活)。
' w: h+ W* s4 }+ s4 I, X( I1 Z' N/ f0 F//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,6 d4 A+ X# L- W9 b7 A0 U8 k
//    FALSE表示取消激活。2 l+ N6 W  e  P4 `
//返回值: HRESULT。4 v1 g* v4 Z6 X  W; F/ y) _7 k' w
////////////////////////////////////////////////////////////////////# c7 ?  B0 I/ k( ]
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );& z, C, N  E3 u: A! N; W; J, \

2 }( f# F( M0 c$ ?; y  K2 s: e# n8 E+ K1 a# H$ o
////////////////////////////////////////////////////////////////////
+ l. A9 A  v- n5 K9 [. |//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
: T5 Z5 o9 d9 v* R//    风输入。
+ S/ B. Q0 D5 C% m3 A//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
" ]4 p0 B/ m9 s& O( ]1 ^//返回值: HRESULT。
5 {/ r5 i! O- Y0 w/ F; p  Q- ^; U6 D  X////////////////////////////////////////////////////////////////////$ b8 h) T2 ]  f* \  m
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
3 A+ k/ z4 n6 T9 K3 p9 E
" d( _* b" t. \0 g, F8 k! T6 ]////////////////////////////////////////////////////////////////////; Z( A5 U2 L7 f9 d. V
//功能: 取消从.wav文件识别。恢复从麦克风识别。
; `* Z- N0 |) z8 F( x//参数: 无。( M; h7 d: I5 D3 X
//返回值: HRESULT。
6 k$ E5 o" i/ {: y////////////////////////////////////////////////////////////////////$ {# o. J. c$ Y" O, V# i/ K: K
HRESULT UnSetInputWithWav ( );0 ?( e/ `$ N/ V2 I7 E% ]. p
; }& J/ v. Z$ v6 Y- A, @4 d
//***********************识别开始,结束,识别结果的处理**************************
3 U- [1 u* b  n8 L/ @+ ^0 z0 v' j% P! U# t3 \" z+ g) p
////////////////////////////////////////////////////////////////////
0 ]$ d: b  n: O: ~//功能: 识别开始(将所有规则激活)。/ M% n. b2 ~! I$ V
//参数: 无
) d: U# i3 R: |2 B//返回值: 无。
$ r7 {# k( I2 [+ l; l/ _////////////////////////////////////////////////////////////////////8 f3 i% Q  V6 s" Q# y& d' N7 e
void StartRecognize ( );: s: D$ ~) _! ]. q% ]
8 c: p9 ~" ^4 ~% f
////////////////////////////////////////////////////////////////////
2 r2 n$ D$ X1 j6 J% V! A. E: Y% [//功能: 识别结束(将所有规则取消激活)。5 h3 w0 T+ c8 e0 m1 }
//参数: 无。
: U( V4 O* E3 p( M7 J" M//返回值: 无。
6 L& L2 e" `4 L////////////////////////////////////////////////////////////////////2 {. W- g. [. {. x6 ]
void EndRecognize ( );
, r4 D/ L" r7 o/ z
7 J5 i8 u: i0 T# C" z% }public:, V4 S! |1 O/ K
////////////////////////////////////////////////////////////////////8 i  z) Q  w& x8 L5 j  N
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
, \9 R$ p) h& s! W' x( h( h//参数: 无。  {- k& V$ T+ [' t$ K& |) ~/ o+ A. s
//返回值: 无。+ f6 n! u5 k+ w: \: s9 F# j
////////////////////////////////////////////////////////////////////
- b4 q5 G  E' N5 o+ ^4 Z9 E' c! kvoid ProcessRecoEvent ( );
8 j, n( K  l( ^9 m& U8 u- p! ], O
protected:, E- W" h! E& J8 c
////////////////////////////////////////////////////////////////////
: h0 H3 u+ ?- C//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。
: O; {% m3 o( z4 G  C# Y' s//参数: pPhrase:ISpPhrase类型。; S0 a$ E) P/ E% |! W8 u! y) j' S
//返回值: 无。/ \- c$ p! W* x7 d* X7 \
////////////////////////////////////////////////////////////////////7 e/ H6 v$ ^7 C+ @9 ^# F
void OnRecoSuccess ( ISpPhrase *pPhrase );
# x3 A7 U3 [6 q# l2 P+ N$ J& ^: e' h, ]( J/ t
public:
$ P: [& y. G. e0 G) `. y////////////////////////////////////////////////////////////////////* V! p9 \$ m% q* m5 I! K2 W. E, h
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,% v$ h  p& r6 g5 Y; x7 O
//    需要在派生类重载。规则ID必须以常量形式预先定义。
5 z5 Q5 `, _9 p% b7 A//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
" e5 l. F/ d5 C8 g& p* T//返回值: 无。( k. x( l" T0 G
///////////////////////////////////////////////////////////////////// `0 I/ L" Q$ |3 \
virtual void ExecuteCommand ( const ULONG ulRuleID,
& z; `& U& A: ?7 b- v" l5 i          const ULONG ulVal );
/ s4 o' q, h7 p# u6 e0 V, m$ o$ l1 C! `  U+ L' v  {! ?3 L8 K5 e: L
////////////////////////////////////////////////////////////////////' f8 H/ f# O) k6 Q; {" b2 ^1 E
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
/ `  j& w& Q" d# F3 f+ A//参数: 无。
" m% k9 \' r( s4 |8 i//返回值: 无。6 w3 `: `' U/ R; x* c! m8 z' k' ~: j
////////////////////////////////////////////////////////////////////
' ]/ P+ b, q7 @virtual void OnRecoFail ();
6 \  O) @: v6 |6 s* o& u# J7 [# F0 ~! L( r* }* ~# Y, ]
////////////////////////////////////////////////////////////////////. I) [* E% D$ q& s
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。+ X% q& Q0 D% w+ J
//参数: 无。* A: g* I% q' s' a1 H
//返回值: 无。
  J  i- }" ?6 v  ~, L////////////////////////////////////////////////////////////////////* P* r7 k% k8 q% z% J& i
virtual void OnStreamStart ();
2 A! @7 G4 e) }3 V" e* \( Q  r1 m2 A, K* y
////////////////////////////////////////////////////////////////////
0 |; }# X( @: ^$ E. Q//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
1 ?5 _7 |/ t; f( [  `//参数: 无。# ^" c1 T/ ^& M$ j
//返回值: 无。
7 u" P7 S2 K3 j////////////////////////////////////////////////////////////////////" n- V2 V. ]" ?
virtual void OnStreamEnd ();& x. A, Q& b9 J) g5 Y

% e# e5 s! B% z0 h' d};
9 S( ^3 m. c5 `( ]/ T6 `. Q# B: n4 L
! W0 b) R6 e+ B3 i! A
% U3 W+ S9 Y/ r8 R
#endif    //LANE_SPEECH_DLL_H. k! t& ^0 l, ^# y. X
' G* u$ t! N/ P' B, P1 V
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9 k# W5 B6 W" y2 P  K3 u/ Y" L* @
% x" q* u. s" `- x
////////////////////////////////////////////////////////
3 i3 I) Y- |3 F# s# T" ^; N" \) i//
6 L! `3 ]: }  F# J' Q0 M7 u, t// 文件:LaneSpeech.cpp' P- |! F1 C. O
// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能$ `' F2 n5 G. T. _4 ~& V
//    语音识别只支持命令模式,不支持连续模式( k2 D" f# I( _1 j  b/ P0 w3 g
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 36199084 ?8 y2 H" u7 J) A% R& ^& l
// 日期: 2004.10
0 Y& H# N- L8 a- E// 版本:1.2
; h! S" t3 w1 m- I, |// 0 G: V# [$ K4 G- o; r2 H
//9 S; P) N& |1 S' {  j" g+ J, ?7 G$ d
////////////////////////////////////////////////////////: u4 O! W6 f8 `* C  E) O5 i

5 \, |4 v* e- o* m3 w8 ^9 Q+ T9 @& c* `

5 N" C! F# v0 y% Y/ x; i#include "LaneSpeech.h"% |6 g4 a, G. V4 S0 Y1 e+ h
+ g$ A& c+ b  y9 f6 r
//-----生成动态连接库和静态库的处理----------------
% w% ?; o' F' m" }9 ]5 L6 j$ S#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
% C& V( h8 z! G! Y9 y$ C  ?7 y' w4 g* k& B- p- R
BOOL APIENTRY DllMain( HANDLE hModule, ( {0 h# ]% X% K( m
                       DWORD ul_reason_for_call, 7 }5 l1 Q& n. r
                       LPVOID lpReserved
/ o4 ?0 ?6 `* w" b      )
9 X5 @) }; Z5 L/ h, Y# `8 F{" i7 B* I6 J9 M, @0 V& t4 [. t
    switch (ul_reason_for_call)
# H5 }, @( S# P2 s9 ^- \{. L5 Y* b2 X* ^4 P5 b
   case DLL_PROCESS_ATTACH:! F5 t1 e7 |8 G  w1 B5 ^% u
    CoInitialize(NULL);
% b# Y/ J$ N% P; g6 r5 q    break;6 b- s- q/ w/ n7 {# ?5 p2 g
  
9 _8 J  I! s! x" A; v9 W7 Z   case DLL_THREAD_ATTACH:, y& q; D4 ?" O6 \0 l: D. {, K
    break;! g6 Q( ]9 {# J9 |1 q: X
  " C! V$ ?$ ?* O( @3 O% w. ]
   case DLL_THREAD_DETACH:
0 N" ~  X- @" _, b3 ~    break;
( p: E' s& b5 R' A) S  ' X% L" r$ @$ a5 ]- L" ^
   case DLL_PROCESS_DETACH:$ r( [5 R, B! n. R. H0 S
    CoUninitialize();1 _3 a, G, J6 ^* F# G* [+ ^
    break;
6 N; S( H* s. z# d    }: r6 \1 [7 [" d: T. N( M# _0 L3 R, K! _
    return TRUE;- m  H. P( s6 F; L! z1 N
}
  d! v  N% s+ E  F& B  e" k& w6 G: v
#endif //USE_SPEECH_DLL
1 p8 f! C2 C2 e- T* {" o- Y( P; q; X& h0 Q

# s. I# @8 W2 Q9 m7 e
0 ^% H  L. E0 y* j///////////////////////////////////////////////////////////////
; U  M0 M5 N, \* r2 F
$ |+ ]. l- n+ Y5 q3 \2 Q* i) `////////////////////////////////////////////////////////////////////
6 V. {" u: E; }4 M! q//功能: 弹出一个信息框。$ H, x) S1 U5 f  Y  u8 Q
//参数: lpText:是对话框信息。lpCaption:对话框标题。
* J9 i4 l" v# f- [//返回值: 无。% h6 {" G. w! [# W+ A- p) [
////////////////////////////////////////////////////////////////////  |7 E% |0 H5 O0 Z& i. |: t
inline void ShowError ( const LPCTSTR lpText = "ERROR",8 p* Y1 O8 w- s& _+ f( A8 {
        const LPCTSTR lpCaption = "ERROR" )
) m1 ?; B! D) p{
% G4 C; Y0 \+ ?8 r, l   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
2 n; K6 e6 u/ Q. l5 T}( Q# z/ [* \. x& ?

- T& T: ^# U; n$ S////////////////////////////////////////////////////////////////////4 {% |/ P7 r) c' S
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。1 j4 y7 z8 o' j! E
//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。/ g$ L4 h; g% b0 E3 X3 _' Z& M! a
//    lpCaption:对话框标题。
0 E3 P; ~" J' i+ Z) k//返回值: 有错则为FALSE,没错则返回TRUE。
- m4 p( p* o4 ^- Z/ P////////////////////////////////////////////////////////////////////7 W& l; j2 ~+ U
inline BOOL CheckHr ( const HRESULT &hr,
" b7 H! H/ y# u& U        const LPCTSTR lpText = "ERROR",
; K& U4 U" l$ P6 v0 n        const LPCTSTR   lpCaption = "ERROR" )* j" p. j  ]* d! A6 j, L9 }( F
{7 Z0 a( g4 e# R* n4 a9 O5 @
   if ( FAILED( hr ) ) {* k/ R$ m" N! `1 T+ K  O# \
    ShowError ( lpText, lpCaption );
. t+ f; `; K& E* a    return FALSE;; P: ~5 q/ t' e( O, N1 X+ d0 h
   }
* Z' h' n) N' E   return TRUE;& F+ j- A( _% b2 i
}
* O2 p0 `) [; P- @3 K5 v8 z, Y  e8 k9 T0 ~* G
+ b+ p$ @! L0 U6 Y# C/ A$ Y2 b! q
///////////////////////////////////////////////////////////////////////
* n: g4 M* L( p0 [. L( |0 x+ w$ P///////////////////////////////////////////////////////////////////////' P! c% K' l* {' ^
//# s* j' H4 T5 a# ^% h3 e, ]) H, @$ C3 P
//         CTTS
6 |$ Y, s1 {$ u* L//8 m, @- Y  I$ M2 p
///////////////////////////////////////////////////////////////////////5 f% @' X) ]' @, l/ Q6 ~% s. N
///////////////////////////////////////////////////////////////////////
3 A% S. g( K" @% S0 X- k7 f  e5 N6 _7 O5 p6 U* A7 x
////////////////////////////////////////////////////////////////////
# K) n- G+ ^" I: a' N1 ~//保存关联窗口句柄。初始化COM。5 E" f' x6 L# e$ A
////////////////////////////////////////////////////////////////////
" y7 \; a; i3 J! v) X% CCTTS::CTTS ( const HWND hWnd )
5 w  \1 x3 Q  W8 R4 R{
" t  z0 E) ]* p; i+ zm_hWnd    = hWnd;7 p/ j' N- H5 i6 S# o! @
m_pVoice   = NULL;
/ Y9 P. P0 t, q7 ym_pToken   = NULL;0 i# s% a, y- D+ e  s
m_pOutputStream = NULL;+ I: J. T0 J# W/ @
m_pAudio   = NULL;
. @5 Q: ^, t) D+ g- P}* b, s& ~, \$ R6 Q

4 b* V3 q) M& ~, U5 `$ v1 K////////////////////////////////////////////////////////////////////8 ]. K( h0 a# K0 j% f
//释放所有对象。- U/ K5 S! b, ~3 f" L/ G  b
///////////////////////////////////////////////////////////////////// f6 @7 f% H' l$ i% ?6 n4 h
CTTS::~CTTS ()
& w) I' {! h2 D, }" D{' u' ]8 K( k4 v" I/ j0 X/ l% e
if( m_pToken) {1 y% z& W, f+ a8 M9 R$ @+ ]
   m_pToken.Release();
' }" N$ \8 ^5 W# O   m_pToken = NULL;7 G! S5 z7 G) h$ h' ], e
}; `3 D" R0 u6 Q9 X' }, a
if( m_pAudio ) {- t0 c4 L* I: z/ W4 C" A( z
   m_pAudio.Release();% i/ b/ G5 g3 J- B  c# T0 S
   m_pAudio = NULL;
" f2 l2 |0 q+ w1 A( d6 Q}8 t& T' D: F& d# `# z
if ( m_pOutputStream ) {6 v3 q* v& i+ ~8 r
   m_pOutputStream.Release();
) G2 b7 o: i) L0 m4 P   m_pOutputStream = NULL;9 K( K& f: @* p7 _2 s; w
}# C* }$ S/ ~# k. j7 w+ o# h
if( m_pVoice ) {/ c# u* t; S& y1 z0 n7 g: v
   m_pVoice.Release();+ q8 s. p! ^. s4 V
   m_pVoice = NULL;
& ]" m1 L! A2 G4 o* h- D0 m" B; t  m}  q5 c' A4 U$ z  k0 r
}9 P  O* U" f+ r

1 X: Z, i4 W: H' u4 d////////////////////////////////////////////////////////////////////: f6 L6 x+ N2 Z/ R( F9 U. W
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。7 }& W, X6 V& r. g4 N8 P
////////////////////////////////////////////////////////////////////
3 `) |( ^5 i- W; `4 k9 X  q! iHRESULT CTTS::Create( const CSR * pSR,8 h2 k: v' }7 @
       const DWORD dwLanguage )
- |' w4 K9 F; Q# q% n6 L0 B{
* {% L! l6 e( {HRESULT hr;
/ }3 {0 e/ z1 ^5 ghr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
& X% f8 a) b6 U7 r, \if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {( y  r1 L! G; U9 j0 E" t& X
   return hr;# |) w* d0 w) \7 a' N9 J% ~
}
! Y+ V' o& w* }# W+ M: |+ F; b- F  I. }
SetLanguage ( dwLanguage );
9 s  K  W$ d! p& b8 |/ Z3 e6 [
# Y$ ?" a4 G( lhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
+ `0 W$ j% T: Rif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {. Y( |0 L/ v& i+ t* Z
    return hr;1 y' v8 D* Q# E! a
}
2 u9 V0 ^+ B! c. Y
1 }( B, q9 U9 f//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
6 N3 I* Y' C& \5 N+ s* T//SPEI_END_INPUT_STREAM 表示完成流输出。
# n6 r" h- b3 z& M: `. Ehr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |8 z8 W9 B+ v& |# s, X
         SPFEI( SPEI_END_INPUT_STREAM ),1 m* w- U  p1 ?" S' g
            SPFEI( SPEI_START_INPUT_STREAM ) |
6 k- L# ~( g( K2 d            SPFEI( SPEI_END_INPUT_STREAM ) );# Q. u: D6 ^  ~5 d# R( ]
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
& A. G  D) ]# V9 \9 B: }8 L    return hr;
8 }+ h' o9 j; e6 P}3 g5 H; n6 I# W: T
% `/ H$ k4 ]2 H2 }; |
//设置通知消息
4 o$ s4 L5 {  m& j# G/ ]( j' chr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );# w' |5 Z$ L4 [' M0 C
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
9 W  ~' O- l6 r2 M8 i    return hr;
# |$ Y4 ?) n' w, G3 q}
9 h$ s9 P' j% B" X$ k% |
; Y0 t+ c. ?8 v4 |2 V8 H5 ureturn hr;
1 x8 H* ^1 U7 d}
! B# q4 E' t- y% }& T
$ J$ C. A$ J2 e( ?////////////////////////////////////////////////////////////////////" a, f; m6 ^  M) ^$ T: o
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
& v6 I8 V2 y  g; P2 g4 h5 M//并设置兴趣,设置通知事件。9 `5 w, h! F. J6 Q/ d' O
////////////////////////////////////////////////////////////////////9 s2 G7 E7 m8 _$ _
HRESULT CTTS::Create( const DWORD dwLanguage )
! U! `5 `- S3 V: p: t- m{: e0 }7 t' W4 j/ Z" E" g% f; U
HRESULT hr;
. L' u$ q2 S" p+ [5 U. Q0 ohr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );3 \0 r/ F7 E* c7 `
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {8 n* F6 J  ~! t- Z  M9 z
   return hr;
) ]1 \2 h' R$ V! f' Y/ t# S4 G}( Q( `8 k- [& Q

/ Q0 W$ [2 q* v0 A7 L0 {$ O0 ySetLanguage ( dwLanguage );8 L/ q  {: z  {. X

( G# C! D, `* z" c5 d7 @  Bhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流5 e( H3 H9 P7 @/ R! i
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
& {! A4 k- r" i/ _    return hr;( e; L5 N8 L' @. ^: r1 n" I
}1 o' B) q+ _! }# ~" V4 \
2 @. }. U4 ^4 m0 |% @# X. n- x+ n
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM# s. K  I/ o8 t7 h3 b9 r
//SPEI_END_INPUT_STREAM 表示完成流输出。. p; V: S$ B3 `0 ~$ v
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
* I( L% b  {3 p1 m7 U& ^0 I         SPFEI( SPEI_END_INPUT_STREAM ),/ C6 p/ o5 x/ w5 \4 W1 [
            SPFEI( SPEI_START_INPUT_STREAM ) |
$ N! x/ ^5 ]& |1 Q            SPFEI( SPEI_END_INPUT_STREAM ) );
& b. {# O; r8 f; Oif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {7 }5 v% P# m9 U
    return hr;
  f: ]; m4 I6 Q% W( z: W}
8 P: G& B9 C8 f4 {+ q* [3 q/ J7 }# t6 L
//设置通知消息! h- U. \8 ~, R7 ^. M
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );% [! e1 i4 S0 N; r: [1 {. g# _& G
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {! p' f1 g/ F1 v3 A# V
    return hr;5 q* U' E; u: y5 M7 `% }4 S- [7 `; |
}
8 o, R! r7 ?/ ~3 m- ?) |: {) X& I
8 x6 ]" q  A: X# G# E  @return hr;3 w) ~: [8 U) u0 h( }) _( Z/ s
}7 j" @3 y1 f2 L& ?
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件6 m2 D8 v5 s/ _. k9 u
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()) g( |4 n/ f( H, g
{6 [2 t. ^8 P0 s) b; P
    ::CoInitialize(NULL);//初始化语音环境" v9 l+ S- |( o7 k) t$ T
    ISpVoice * pSpVoice = NULL;//初始化语音变量
. t/ p% z( ~% o. r7 k- e' W  h- {    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
  v( {5 F- y6 t8 X4 M& O3 B0 U4 F        cout << "Failed to create instance of ISpVoice!" << endl; 5 j$ X& P/ y9 g2 p
        return -1;
. u& Y  M! D- X7 E$ a+ b    }

, u1 \* }: g, t6 m1 s# f; V* \- j    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
) c9 L7 T! Y) |& C; I9 w4 a3 m" z    ::CoUninitialize();//释放语音环境
! S& }) G+ _+ y5 A
    return 0;0 F' @8 `# ?) f
}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序
- R- |% A6 a4 [* B8 h4 _5 J
* a! y) S- z$ x" ~1 ~( q: I1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地; d: i6 w) e" r

4 j6 m  Z2 i/ x* o+ nhttp://download.microsoft.com/do ... -US/speechsdk51.exe   
: k6 a! r5 m4 _0 @2 v5 hSpeech SDK 5.1安装包 (68   MB)     ( L4 v& j1 _3 }
http://download.microsoft.com/do ... chsdk51LangPack.exe      
7 p2 e3 V, t& q# E5 s1 j中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
( e% y* V6 {% H% ^& G
: A! d  M9 `  P+ J$ d$ @2.下载后,执行安装# Z  ?& p! P1 h
. H  s& s& `) s1 Z; G2 J! d" |8 ]5 V
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。
/ D3 H  x: S8 `: Z+ R* u; P( I
' U( F6 y! H$ s: k* }3.VC的环境配置, [% c# J; B; X" a3 _
/ R$ F- w9 ~. {4 {
在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:/ F6 S: l2 Y$ [  O- X

. p3 L+ W: y' N/ R; y工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
1 h0 i! A' C, d" ]$ N% g% O
1 ^  X7 O) G$ I4 C, }- ]$ P好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
2 H+ Z. g4 U# ]9 Z
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-8 23:21 , Processed in 0.036652 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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