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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
9 @; I' @8 _. R//1,生成动态连接库时,要#define USE_SPEECH_DLL,
( @0 u# k8 X$ b//      并且#define LANE_SPEECH_EXPORTS
  Q7 y( c( W, a7 T6 K+ e( `% ?//2,使用动态连接库时,要#define USE_SPEECH_DLL
, H# t3 i4 A& d0 P( X5 H0 Z" b& x//3,声称和使用静态连接库时,什么都不需要. o9 m' O+ d) @2 [! @
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),) F5 H( g9 P# j8 V
//      动态连接库就不用调用了。, V' Q" n3 ^' e* _. O
////////////////////////////////////////////////////////) H( T" A; n4 }9 y# R: T
#ifndef LANE_SPEECH_H
+ \7 A$ [, z6 [5 i4 [#define LANE_SPEECH_H
: e' k- Q! M% S5 G1 q3 `, a7 @% d: g* d( ^
#include <windows.h>
' L* j3 t% ~! ?3 r; j6 O#define _ATL_APARTMENT_THREADED  O! x  N4 i6 p. \% ~
#include <atlbase.h>1 S6 r( o. ]5 ~$ M  Q& ~
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
4 k+ L% C# @& j1 ?$ i2 }1 b- }) J#include <atlcom.h>
4 z* Q6 N* j# {# y8 G#include <sphelper.h>   //sapi需要的头文件
0 q2 N9 l, a3 X$ }2 S# c" g  @$ |* g- `
//-----生成动态连接库和静态库的处理----------------# i5 P( A/ S4 H0 j1 A: w# w& Z" n3 l
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
( H6 D1 Z! N6 p7 ?4 o, Y% f
& `/ G( v% @9 M' g8 D#ifdef LANE_SPEECH_EXPORTS0 i+ u# W& g" E0 e
   #define LANE_SPEECH_DLL __declspec(dllexport)
! V* x% e& ~( \1 \, F#else
: B% u5 D! R% N; s   #define LANE_SPEECH_DLL __declspec(dllimport)
5 ^0 N8 L! k+ c/ j# p  M#endif
* ?+ R) {% j. A/ z; g
' z6 V/ g: O' J+ n7 V1 Y//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关
5 h3 y4 @! t$ D! t6 _//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
+ x4 L; u" ]5 t7 |) T( j#pragma warning( disable : 4251 )
; j* N/ k% ^8 E* B9 z' `0 L9 G% S: V  D: E& b' ?8 e
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)
, R* R* m8 d) [/ ]0 B#define LANE_SPEECH_DLL, K4 O, O; h3 K
' h- K" t' w* y4 l+ e- N7 T4 b
#endif //USE_SPEECH_DLL" Q5 u' E% s' ^- X

0 d( \0 D/ {1 o1 t2 j0 [
4 Y4 Q& T8 u1 S9 q//***************************常量***********************
0 x0 O- ~( X% @7 x
& ]$ X) |* V. l  |( g/////////公共常量-----------------
8 N2 z5 C0 P4 j- ?- t( Pconst DWORD   SP_CHINESE = 0x0000; //简体中文.
* e8 u( x/ H) [2 L. k  M( mconst DWORD   SP_ENGLISH = 0x0001; //英语.
! ^- {# @" t6 d/ b8 k% j: L; m/ _7 n
, h1 m% J+ q2 l7 a$ T6 K/////////CTTS常量-----------------1 Y$ _& f  e$ _. `8 R
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
. i/ r! g% i, e! C& w$ |3 V1 f! ?1 I3 j/ n( B- `6 {
/////////SR常量-------------------
9 z. c- K5 h2 q0 g. |. w( xconst UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。+ ?  M& f8 _6 c* S: @
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.7 j2 b, }, f( C
const DWORD   SR_SHARE = 0x0001; //共享类型的SR.
  f4 F8 Z; w7 m) a( d& R- [" T( L* V. U* s+ d4 z! D- Y/ u& q
//以下常量仅作例子用。' H! w5 R/ _4 I- Q! b
#define VID_TopLevelRule 9000   //顶级规则ID3 i! Q/ m8 d5 x  Y0 A
#define VID_SubLevelRule1 9001   //子规则ID4 [2 r5 E/ F$ `$ A# h. m% G7 H3 W
#define VID_SubLevelRule2 9002   //子规则ID3 _# f. k5 Y* U9 g  L+ p2 \
#define VID_SubLevelRule3 9003   //子规则ID
, _$ D4 T/ \" Q+ }, D# P4 Z; o: ?
# R2 Z9 K& w- _. s( F6 m8 l9 G, L1 W  L  i( p  w& a/ R- S
//*************************类声明************************
$ Q3 _$ `: x1 g6 d# k* [
6 o/ N7 W, Q1 @5 ?0 }
/ U# r" [' {# G# qclass CSR;
* x2 R3 @3 n1 \1 ~9 G" t# l: ^0 l///////////////////////////////////////////////////////////////////////0 G) F% P: l# H" n0 H& {4 ^
///////////////////////////////////////////////////////////////////////9 O7 M0 Y$ p( M7 n. H
//# U6 i6 U; f- d1 i
//         CTTS0 |7 _  ~7 h8 d5 z! M
//2 M( D/ K( i) ]- J" B" z% d
///////////////////////////////////////////////////////////////////////
/ L0 s2 m/ i& D. |# z///////////////////////////////////////////////////////////////////////
' j$ k, _- {: w9 w( s$ ^  d: `9 G% ]  h3 I
class LANE_SPEECH_DLL   CTTS
/ b! X) S1 E  Y5 v{
( x- d, \$ c# J4 bprotected:* u6 c4 k  T: @9 e
HWND       m_hWnd;     // 关联的窗口句柄。
3 j+ Q' C- A  ]; P  s/ g
6 A' A: G: }# q+ LCComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。
1 T3 a# e/ a4 f# W7 ACComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
( X: i. h+ k' `) p4 bCComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)  G( o5 t# u0 |7 H- j
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。1 k5 J+ n3 R: m& j& F: ?+ }# K4 Y- ^

' G+ n3 [& L* l! ~public:
  o' l; _" ^- C//********************************初始化部分********************) Z' c  h9 J6 e9 V% `* ]6 n

+ l( v" E$ ]* ?////////////////////////////////////////////////////////////////////
9 _' \4 q+ b: C( N4 O( v9 w//功能: 保存与识别引擎关联的窗口句柄。
5 m. T( K* S) r" f//参数: hWnd:要关联的窗口句柄。- Q7 M. |% [! t4 J1 q
//返回值: 无。; a; y. J' K7 _- _6 n
////////////////////////////////////////////////////////////////////' I3 o1 G4 d# b
CTTS ( const HWND hWnd );8 p) a! j4 Z3 M5 h

) R# J. e- q$ `/ ~" {4 F0 D////////////////////////////////////////////////////////////////////
; T) h) P3 o3 r//功能: 释放所有的对象。; c. \4 k: j' f" o' U, }% }: J
//参数: 无。
+ Y( l6 G! L% }( R6 |1 g//返回值: 无。
* q4 `7 D: g& U////////////////////////////////////////////////////////////////////
; n0 r1 [) S3 o' L~CTTS ();
) T5 R2 w  |$ p
4 N* K/ C7 K! ?- ]! d5 a////////////////////////////////////////////////////////////////////$ Z7 x  F7 N4 S+ V
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。1 b' W6 R8 T$ N  H% _
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
% E( g. Q( H2 U) g//    SP_ENGLISH为英文。. q8 B3 z  o4 L' ^
//返回值: HRESULT类型。( t! j/ i9 t/ K+ J
////////////////////////////////////////////////////////////////////9 N* I6 g5 e- U& F! ~8 p6 E: y
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );
  j/ @- V+ D  l8 y( h
4 A. h  e2 S; k) r. z  e////////////////////////////////////////////////////////////////////6 p4 M4 M' I5 A  A
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
7 g& |* ~# v$ \  t/ b$ F7 k//    通知事件。
: @8 o+ S8 Z, R5 @$ q( k, Y//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类," Y3 A7 b$ o5 B; D
//    SP_CHINESE为中文,SP_ENGLISH为英文。% K& i/ N$ G1 t, F  e  D7 p
//返回值: HRESULT类型。) e2 P0 x4 t+ u4 p' P$ {* l
////////////////////////////////////////////////////////////////////+ u+ E, V+ @0 S8 L
HRESULT Create ( const CSR * pSR,9 P( k$ e' p& L( h) v2 j
       const DWORD dwLanguage = SP_CHINESE );
0 ^" s. e- T3 Y. S
4 f; E- X+ \) N! W. t. ?% C0 E4 H* C
//********************************设置部分***************************************
. L! S5 t( F5 q3 k3 l. T& ~) o2 i9 C; g
////////////////////////////////////////////////////////////////////1 o4 i% }9 a0 S  ~
//功能: 设置朗读声音的语言种类。
+ w' x- o7 ~5 q) F1 b6 p! c//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
7 N: W$ i- d  a' f* _( G5 t8 f4 k$ m//返回值: HRESULT类型。$ T! E' k: K! L; T
////////////////////////////////////////////////////////////////////4 W" ^# H2 ]# o! _
HRESULT SetLanguage ( const DWORD dwLanguage );
# }' z& b3 @/ Q( h' q0 M7 z. z: Z1 ?& z
////////////////////////////////////////////////////////////////////
, I- l: ]8 A/ y0 N8 `# m7 \- t. C3 H//功能: 设置要处理的的事件。+ D6 ]4 k: Q; {' N( Q8 f* f
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
5 |2 {, `. {4 C//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
; \5 H/ c1 x' Y/ M: t//    件都会收到通知。
& D3 S/ P7 u/ M//返回值: HRESULT。
. @9 t0 O. K- \, Y4 {7 B////////////////////////////////////////////////////////////////////  P% S. o  q3 D5 }
HRESULT SetInterest ( const ULONGLONG   ullInterest );
: Q) w3 Y5 x1 a  Z% Z$ Z/ B2 B& D- z
////////////////////////////////////////////////////////////////////
+ d% H6 y" L* s9 J# ~2 A5 v& G//功能: 设置朗读声音的音量。; [. k- }- U+ q3 V! z7 c, h0 n: q
//参数: usVolume:音量数值应该从0到100
/ t0 ^- B0 }8 d% a* t# `//返回值: 无。, ?6 y, q2 Z) I& ~8 s5 F  _7 C1 Y
////////////////////////////////////////////////////////////////////2 w- ]0 r: A- P8 Y# t* Q
void SetVolume ( USHORT usVolume );: w: v5 v3 T1 E1 J) c" s# d

6 r  L) ]. @" O( \7 \, m////////////////////////////////////////////////////////////////////
' T# E4 N) D' o//功能: 得到朗读声音的音量。7 K; K3 ^+ k) }6 E: y2 [
//参数: 无。
6 d# E% w5 G" c0 u* V//返回值: 音量数值,应该从0到100。- \; n, b, z# M: w/ [- |9 X
////////////////////////////////////////////////////////////////////2 J& a7 `! n- M; Q& d* W' R
USHORT GetVolume ( );
  B, y( l7 c: i6 a# O$ m
4 E( Y( U9 z( p5 q# J2 k8 t1 Q7 K. A////////////////////////////////////////////////////////////////////
% c# a- \' p  {" `* D/ M//功能: 设置朗读声音的音速。
) h7 f& ^. g: R3 I( t; a//参数: RateAdjust:音速,参数范围从-10到10。/ c) v1 h  s" o8 Y4 q
//返回值: 无。
4 t! W9 y  Q" \& ^* G////////////////////////////////////////////////////////////////////- j# k$ _/ C( k- w2 }( b- W7 C
void SetRate ( LONG RateAdjust );9 t& ]  C+ T# h& x  y5 T& ~% x

% ~; H- ]  j, s5 B5 q////////////////////////////////////////////////////////////////////
& q% u5 i6 y4 Z. Z6 L//功能: 得到朗读声音的音速。# N8 v7 ?: ~& A
//参数: 无。1 s/ V5 V) C/ U6 I, _
//返回值: 音速,参数范围从-10到10。
3 `$ H8 F' f! ~////////////////////////////////////////////////////////////////////
) e  X5 b/ b" X$ h: nLONG GetRate ( );
5 N7 q5 o1 n  P2 Q
- P* D" Z$ w, a4 r7 B+ W////////////////////////////////////////////////////////////////////
7 l% {/ H+ U# t3 x( X. f' ^//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
8 D- x: j6 V7 f5 M  t) v//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。- i8 p4 \) J) k  U; P
//返回值: HRESULT。
: f; {! I+ ]- `7 @1 r6 ~////////////////////////////////////////////////////////////////////
7 b2 Y- h- R( U$ i4 O- G/ {* z# q' g& pHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");
  ]' A) l+ l! h7 r3 l, o4 Z
5 ~4 q2 `9 n. k0 T, r8 u0 m////////////////////////////////////////////////////////////////////
9 K2 p2 n: U5 k& W//功能: 设置朗读的声音从音箱输出。' k% G5 c( `* R' Q8 \
//参数: 无。
- Z1 e! L. M* @" \6 S//返回值: HRESULT。7 M6 {6 o- ^2 [# F9 }+ N
////////////////////////////////////////////////////////////////////: t, o- {. k' D/ G4 M* R8 y8 g3 q
HRESULT UnSetOutputWithWav ();& N) Z1 R, w& w% i. S) S
. @* w) @0 F# |: U2 s7 y! o/ X9 P& X. K

1 R4 \7 }2 C0 m8 s2 v//**********************播放语音,文本到语音转换部分*****************************
' o1 T' A  W2 x9 I6 D3 d+ E0 v0 y& y" w; H4 T) j- a4 m  K
////////////////////////////////////////////////////////////////////& O6 p# O! W/ w' e/ ?& b2 `
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
2 z7 J0 \  T7 B; F1 y2 e1 O* e//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
  l( [: |  L7 \" ^; v//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
1 j8 p1 @/ \, v# o8 i//    SVSFIsXML为朗读带xml标记的文本。6 ]" _! ?0 ]) a/ a% W
//返回值: HRESULT。# n5 `* }: y+ O$ R+ \2 q
////////////////////////////////////////////////////////////////////
0 r' }! i# r  [& F) bHRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );/ ?1 r! d% [: D" c1 l# `# b

6 G  ~1 G" ?% d, u& ]& [////////////////////////////////////////////////////////////////////
& Z/ f0 a1 \( y. d/ e" ^//功能: 停止朗读。如果朗读为同步方式,则不能停止。
$ |3 x" t' O# C* S# ?+ p) k' C5 q//参数: 无。/ C' }7 z& S0 o- w  v
//返回值: 无。  ^; r, [! f# |  \; z  G, g
////////////////////////////////////////////////////////////////////2 W5 K3 C5 G6 N6 P2 M. f6 V
void Stop ( );
. B1 Q  I& q4 k8 Y
5 |- d: W$ U: [! P$ M. T& L////////////////////////////////////////////////////////////////////
3 y& @2 E! I, a' K7 q, f//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
7 E& S* |2 `$ O6 L* d//参数: 无。
% R# R( G; M1 L( `* m2 w//返回值: 无。" e- f" M% E4 R4 O. E) K, j% W' h
////////////////////////////////////////////////////////////////////4 s6 b* t2 Z/ Z, ^) g0 U
void Pause ();% ]4 S( _  f2 t4 ?1 K) B! @( `

& L/ |# v& R3 V- h/ b  N////////////////////////////////////////////////////////////////////
+ G6 Q+ n$ v( [6 U+ Y//功能: 从暂停的地方继续朗读。" L' w( W$ k% h; ?
//参数: 无。% k% w# l: b/ R
//返回值: 无。' l* D$ k7 ~4 [( V% {4 d6 d6 [
////////////////////////////////////////////////////////////////////* B8 P' @2 ^' y. b+ O
void Resume ();6 }5 M2 o9 ~0 p* Z

4 C0 h3 A8 p7 X( b6 x2 `; v+ h2 M9 m: i2 _  C
//********************************处理事件部分***********************************1 T" W- \3 D. Q: p+ a0 N

2 ?  r. b7 D( N: u( t5 Cpublic:
% U! Y+ d1 }) }: h8 @2 K: |8 H////////////////////////////////////////////////////////////////////  Q# x5 L7 d+ ^1 P
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
; [9 E% L  Z8 r* x. v$ B//参数: 无。5 Z6 e+ [  K  Z! |
//返回值: 无。" B  ]/ {+ n% F/ S3 o0 l
////////////////////////////////////////////////////////////////////6 r$ A4 V! Y2 U
void ProcessTTSEvent ();1 s0 a5 o& y3 `

" C# H0 f3 @" g9 d  d  O% t
- A3 x+ y3 p! ^: @( r$ t* m////////////////////////////////////////////////////////////////////
, B) S% m3 \, w; B' i3 U//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
2 n, X" q# }1 c0 q; I//参数: 无。
4 L6 T4 a2 f" C" t9 q//返回值: 无。  |$ k/ y" T1 N9 [" e3 B, F
////////////////////////////////////////////////////////////////////- P+ u2 _4 U" @: Q) M
virtual void OnStreamStart ();
3 v( x, Y; \: a7 i$ u! ]4 o9 X- A
) {; q4 Q5 r4 z: _) P8 G////////////////////////////////////////////////////////////////////
/ E# t0 b. o1 f" D  }/ Z3 X7 l//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。8 [) q8 T4 w8 W4 x: ^
//参数: 无。
( O$ }$ P) j* x; d4 M! U3 d8 m//返回值: 无。4 c! i1 p  ~% }8 p1 b; s
////////////////////////////////////////////////////////////////////
( R, E( @2 f: X7 evirtual void OnStreamEnd ();/ f2 U6 |0 X( t* i5 g
};! E5 j6 w% j* @3 D

5 i$ j  l. y5 p" s
& u9 E+ e, _& w% i) V$ t% x; Y" e///////////////////////////////////////////////////////////////////////
/ I! V' g/ M7 t9 I///////////////////////////////////////////////////////////////////////& G% p$ Z+ u0 [% r9 b* v' L
//         CSR
% c7 P6 X, N& e/ O! g- |//7 M/ Z; k* ?4 \
///////////////////////////////////////////////////////////////////////
3 T, ]( m; K: C! `1 z6 s6 A///////////////////////////////////////////////////////////////////////
0 d* t; k- Q; r% I$ k: e
( ~8 _" N0 G5 m/ m5 Hclass LANE_SPEECH_DLL   CSR+ Y  I* }" ^! P
{9 |# f2 V* Y3 ]0 D2 J9 e, d$ g
. R3 U5 E% r" C2 x9 [* s# d$ H
protected:" ?: g7 y" c) J. I) K5 Z6 f
HWND m_hWnd;' n; o7 q, Y6 b0 F3 N: x% ]% d3 `* A

7 g/ x) q0 e6 g  j4 T% Gpublic:
' q, t2 a1 p9 d/ f' }) JCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
! u; D5 w+ Z6 sCComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
& X) k0 U5 A. w: |CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。! r9 j/ V; d$ y) d6 m8 _9 R
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。* p1 G" G& R1 |$ Y9 C3 I
CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。! L: y8 `( m7 Y$ L) {% L& M, ]9 v
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
5 t$ }3 N* w; x6 \  opublic:
! o/ x# R4 f* R8 \  B+ ystatic ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
5 |  }* G6 o0 [
, r) I5 h2 [# X& ?8 l# d% T; n, ^1 b! G, C' J7 g
protected:6 V& F- A0 V& g- P
//***************************辅助功能部分****************************************
9 ]7 d+ V2 @' A! [" f, J/ B' i/ E, r+ `2 n0 c, G  M
////////////////////////////////////////////////////////////////////, L, _) q5 }! m6 T8 Q. M
//GrammarID加一,每个GrammerID必须不同。
7 A. _- a0 G1 C2 Z2 u/ c////////////////////////////////////////////////////////////////////1 g% o) c6 {& W" d
static void UpdateGrammerID ( );2 Y3 Y  Q" r5 O) _+ J

# K+ S( Q7 q, O# T3 L/ v" H! ^9 X3 O  x, {; z+ r
public:
, T( A' o4 @+ h) Y" ~+ `( ?) I////////////////////////////////////////////////////////////////////5 V% B0 _$ A! x* K4 v8 B
//功能: 友员。TTS中的从SR引擎中建立voice对象。
$ N) y4 ?; k$ a- v0 ~//参数: pSRContext:SR上下文对象的指针。) y; {) z+ X; m$ y
//返回值: HRESULT类型。- |, R+ @9 i4 r# S# D7 Z
////////////////////////////////////////////////////////////////////
) e3 A* u4 L6 D) G8 H8 Z8 Rfriend HRESULT CTTS::Create ( const CSR * pSR,
6 Z: k9 b% m  R8 D; Z) q1 R5 K( J          const DWORD dwLanguage );
5 m+ Y  x& M! h: A" E2 A) e* d# R! y6 T

- Z6 @8 }' A' f" J5 N  u4 V//****************************初始化部分*****************************************
" R5 Q* j( E, n% U% a! |  N6 V7 v
$ A: Z$ Y. O" u. W3 T////////////////////////////////////////////////////////////////////
' n) D. x/ {* s1 v# |8 ~" H! R//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。; f2 t0 r# E. U3 t' V9 a* z
//参数: hWnd:要关联的窗口句柄。
9 U$ l6 [9 g: p5 G+ k- X//返回值: 无。. U5 I2 v% X! n+ R4 }0 T/ E# ?. B
////////////////////////////////////////////////////////////////////  w$ X1 l/ l9 C' c# T8 O# R6 v% ?
CSR ( HWND hWnd );4 E& x( h- r8 R2 z, U' d$ D

& d# T& h  a. Z& }////////////////////////////////////////////////////////////////////- P2 W" s0 ^8 y
//功能: 释放所有的对象。5 `* Q8 A1 ]& C, z& ]$ L& d
//参数: 无。
! K( ]1 Q9 P( I8 E8 T6 v3 O//返回值: 无。
# T" r9 p5 m# n8 C+ v% {+ T1 O////////////////////////////////////////////////////////////////////
1 B, f5 r, X1 M~CSR ( );2 H/ `4 W' ?  N! c

2 }4 {6 [8 {( {( g2 h, A2 U///////////////////////////////////////////////////////////////////// ?7 ~) x& J. y
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,$ k5 M# a" `# y& d, W1 _2 d/ `, U7 L
//    加载文法文件。# j" n  J2 f; Q# i5 q
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
$ l2 o3 I; @! B6 P' x//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。% K) ~5 M6 I1 X
//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。
/ D0 M$ V; W# L8 |4 W) c//返回值: HRESULT类型。
( F( ]  h9 Y( d- ]# u- Q////////////////////////////////////////////////////////////////////# N8 _2 b% d1 c# t
HRESULT Create (const DWORD   SRType,  P, R  F" Y0 A; ~0 o
      const WCHAR   *pwcGramFileName = L"grammar.xml",# b. G, a: x6 C9 l5 f
      const DWORD   dwLanguage = SP_CHINESE );" L4 [1 ~. j4 q% z! d+ \% T. o
) b8 z  Q' V8 c! y8 F
- [4 d! V; ?- Z+ f/ M1 ?0 n8 n+ y
//**********************************设置部分*************************************, H4 f  F* w( |9 A6 D
, Q- J4 |. E; D% B8 J- h* J
////////////////////////////////////////////////////////////////////
  C. q# K- s: T5 b: i: L  V) z# Z- \//功能: 设置要处理的上下文接受的事件。
+ K1 {6 h3 G! J7 S: \% h) L5 m//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
* j) o! a: G$ h) e$ b//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事; H" X3 S" r3 D) D( N' |
//    件都会收到通知。
, h# c8 c. j! f: k  M1 J3 b3 O$ a//返回值: HRESULT。
1 l3 [! h$ A( O////////////////////////////////////////////////////////////////////3 G8 ]. u% d+ i  ]- |
HRESULT SetInterest ( const ULONGLONG   ullInterest );
6 h) o7 q/ e( X  n5 W+ t) S+ I
  j' o1 Z1 I6 j( h1 d* P0 V////////////////////////////////////////////////////////////////////
5 ?7 B9 R4 m) b% m& E2 K% N//功能: 设置某个规则的状态(激活或者取消激活)。
1 W1 I. e7 e" ~1 Z+ H# Z//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,$ c7 D9 v: R& W8 ^2 a+ n' b/ e4 n
//    FALSE表示取消激活。
: s  z* R" X( q//返回值: HRESULT。
$ d$ k/ k, \$ n& _. M////////////////////////////////////////////////////////////////////
; R5 R( H" x; F3 i& @HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );9 s" t9 P+ P! Y
3 ]. k4 A+ L& I  b. N; r

0 L" R0 U# M. W. l2 o1 U5 S////////////////////////////////////////////////////////////////////0 @# X; s! o! o) v) F- K
//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
: I" W  S9 L) p2 \( M4 x0 g6 N//    风输入。
- t0 x4 g( R0 i7 Z4 h3 T) R//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。; W: v# u7 P- j
//返回值: HRESULT。
* p, A" M) Z* {& {! _////////////////////////////////////////////////////////////////////: D2 q0 G2 y  x" B
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
4 i8 A0 b+ v3 m; a
, ^1 ]" z! [1 q( f% K////////////////////////////////////////////////////////////////////
) O2 J3 `, Y) W" @1 m4 n  ]//功能: 取消从.wav文件识别。恢复从麦克风识别。
+ |' l: m$ J1 P& U0 w//参数: 无。
( n, T6 J4 `7 X2 i//返回值: HRESULT。
( ~, e; [' z1 w- x3 b0 Q9 H+ v, U////////////////////////////////////////////////////////////////////  D  h( ?, G; ?
HRESULT UnSetInputWithWav ( );
/ W3 I& |6 f7 B4 y* x
6 z: B  F7 b+ p; `& Z//***********************识别开始,结束,识别结果的处理**************************
  b  L1 ?; M" g* z8 X1 a5 ^) S4 ~; j3 d. D
////////////////////////////////////////////////////////////////////1 f( [# u3 C; n* Z8 `- r
//功能: 识别开始(将所有规则激活)。. o7 m: k0 R, |; [" n7 B3 O
//参数: 无6 }' y' e  R0 M! [# r( U; y! f1 s
//返回值: 无。) t/ P8 B4 {3 L$ ~! R2 w
////////////////////////////////////////////////////////////////////
. i" x2 P" a) Y; g; {& n% vvoid StartRecognize ( );, E6 v6 \7 t% P! a! b) `5 \
) j% _7 d# U: l: D* G' A
////////////////////////////////////////////////////////////////////
' I/ y+ v- b/ q4 |* ?1 A//功能: 识别结束(将所有规则取消激活)。
$ ~7 n( ~: Y2 O- ~//参数: 无。
2 i" s; L, M7 {8 T6 V2 R+ j5 G$ G//返回值: 无。7 _; L& P' J) h: S  k+ z4 l0 j
////////////////////////////////////////////////////////////////////: e; j) N+ ]. }/ k. c% o
void EndRecognize ( );
7 N  I2 r2 T- ]* E5 P
) c4 ^( v2 F- z" x9 }4 s" J% gpublic:
  B" Q! T/ K  g////////////////////////////////////////////////////////////////////
" \% R& }+ O9 M, r; @. U//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。. S  }+ X0 q  q. B  ?! h/ M
//参数: 无。: j6 }% P# x. _% p$ F5 f
//返回值: 无。  P5 @) F  {2 d( S
////////////////////////////////////////////////////////////////////
9 b, I, g% R$ S  O3 }: s7 I7 zvoid ProcessRecoEvent ( );
" Q9 V$ ~3 {% x: p: X
' l/ y9 N& M/ P6 lprotected:: ^" I9 _( l$ Z) O
////////////////////////////////////////////////////////////////////2 \& B# i; l7 g# V1 F; k, Y
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。
0 k- N# b/ X8 M//参数: pPhrase:ISpPhrase类型。" g% w) ~& ~  G; {: a
//返回值: 无。" [. @9 t- {$ I6 C
////////////////////////////////////////////////////////////////////9 R* ^6 v; \" `2 s
void OnRecoSuccess ( ISpPhrase *pPhrase );2 e' u! C  \* {, L# A3 g1 J
) Z! M/ O0 m0 }/ G' A
public:
8 M% M/ V8 ]" \: E/ X5 B$ `. R. o////////////////////////////////////////////////////////////////////
0 `0 z3 V+ W1 [" N4 W! Y" C7 _//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
  C+ _: j$ c! D0 A+ b) T//    需要在派生类重载。规则ID必须以常量形式预先定义。  W3 \+ e9 H/ N: k, {) l
//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。7 R- d! j9 `% m( @+ g5 ^% t
//返回值: 无。$ Y, K/ a7 T+ z" Z4 t6 K! l3 Z
////////////////////////////////////////////////////////////////////6 C& V" J' u; |' U9 S  _4 ]
virtual void ExecuteCommand ( const ULONG ulRuleID,
! j1 j7 W  u5 k          const ULONG ulVal );
- |( q7 o. ~1 e% t5 h3 I1 W& L) |3 K7 X, b, [5 P
////////////////////////////////////////////////////////////////////
# p( c! e  v" |. C, u- ]% I( X//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
1 f9 d' J, p& L* n. k: y. |//参数: 无。. `3 K& E' \0 K5 u# _% \' ?
//返回值: 无。; m/ L2 J- D- H! q/ u
////////////////////////////////////////////////////////////////////
6 x) @& M* W  W7 ?. h% J1 q$ Cvirtual void OnRecoFail ();
) U+ I$ w! c& R5 p' f6 _" Z4 e2 U( m. R8 M) |
////////////////////////////////////////////////////////////////////
: ^7 m% L4 k' c' z//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
, n2 Y( t1 l" i* c2 }$ l$ H* K/ z& C//参数: 无。
9 P% o7 N& ~3 K: u/ W//返回值: 无。6 @! b) h) `6 b. Y1 E7 U4 Y
////////////////////////////////////////////////////////////////////
" t& I' ]  m7 q& E& H9 nvirtual void OnStreamStart ();
  I2 y" _' T- ]" p6 C+ K4 X$ w/ I. k( o4 i6 e5 V; t7 h4 o
////////////////////////////////////////////////////////////////////
8 n2 b2 h9 [! z//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
+ g, L5 a4 U. Z//参数: 无。
; w% C7 q- t) R' }' B- b4 Y5 \//返回值: 无。
/ q( n2 X0 k2 y2 u////////////////////////////////////////////////////////////////////% q; I6 z4 s: H5 |8 H; d
virtual void OnStreamEnd ();
; ~9 [5 w: G: o% k: L
8 u' f5 y" O  O0 ]0 v0 f5 p};
) q: S1 ~! h+ M" v
! t8 e) {6 [# h3 [" W+ d5 p4 A) P# x' _1 ~0 S

: x6 Y" j( O; _: F) P& Q( r#endif    //LANE_SPEECH_DLL_H
( v9 A. j$ ?4 @- H, `2 {  T% a9 Q
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3 _; l% T  d. P! T( A& O) j) h0 m% f( h5 P% Z6 q
////////////////////////////////////////////////////////) r: F  L" v2 {2 {, l
//
4 {+ E& r+ D" b' m* ?// 文件:LaneSpeech.cpp8 G2 T, R6 z' P" ^5 N2 Q' ]
// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
% B7 E: }4 l1 I- e( }/ _$ n5 y  k//    语音识别只支持命令模式,不支持连续模式- s& T. Z" t; w; s$ p# A
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908. A3 e& W, s7 z
// 日期: 2004.104 W% o8 m/ Z' _) J. U0 u' E. ]
// 版本:1.2( j9 q1 @: C! q% A, f* }
// , R4 X9 p0 t* }
//. G: Q2 w$ J! \9 d2 J& H; O
////////////////////////////////////////////////////////! Y8 q4 J6 W  G/ {4 _  Z8 K4 _0 x

% O: W1 A. _* z+ ^5 F  \& t- ^) _6 m

+ K1 k' ]% N: d. p" {#include "LaneSpeech.h"
0 v% ^$ Q) N, W3 f3 O& v( H4 U- Y) y8 c5 d* s
//-----生成动态连接库和静态库的处理----------------
2 H* y, x) p: b/ x; k! h) ~) [6 I#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
8 q  ^9 ^, g" `) v/ j4 j" V/ X! \! r* D& o% }, T
BOOL APIENTRY DllMain( HANDLE hModule,   J$ X& Z5 o# E+ |+ d  E* |
                       DWORD ul_reason_for_call,
; f) g4 F% a6 ~/ K( i( {5 c                       LPVOID lpReserved& R& _, x0 s% n* v. W: G
      )
+ B9 @& E0 I# O. n. x; G{+ d  [3 m7 w: W- u% ]8 T& v
    switch (ul_reason_for_call)3 Z% E- p) M6 X/ ]" w5 s% Q
{
; H+ R  O6 G2 Q4 \6 B& O   case DLL_PROCESS_ATTACH:% M* ?( N4 J& A: j
    CoInitialize(NULL);
. X% r0 n2 X  ?& v! d& i# r6 j    break;( W  j* w. Y2 S3 C: p
  
; N6 D; G, S1 Q3 _( G   case DLL_THREAD_ATTACH:
9 q$ \6 h, F9 t4 C    break;
' K9 R  n3 ]/ I" o$ F7 c0 E  3 n! l7 \" T( @/ v$ C7 L7 |* U
   case DLL_THREAD_DETACH:( |+ ^3 P" p% D+ R6 N, `" i: l( z
    break;( \6 G4 \/ `% A! B
  ; m( |5 c2 Y4 U, m9 Q
   case DLL_PROCESS_DETACH:# v0 L+ p  |0 Q0 b
    CoUninitialize();0 f7 j/ P1 J/ @1 g+ O
    break;6 Z+ w; @- M) Z3 U# N
    }  s  l# |* Q; ^" \# t3 g& ^
    return TRUE;) ?  T* m- s2 V2 c
}
5 l" R4 t, j3 W3 H* v7 R0 c. P7 [( [2 J) D5 \
#endif //USE_SPEECH_DLL
. }) h  b7 j1 d  Q
9 ^' K0 d" I6 [" k
, s) c4 w0 V8 h% [4 K. a+ I! Z9 Z/ c, ]
///////////////////////////////////////////////////////////////2 G  }$ ^  k( b( _2 i( t6 E

+ z$ p4 h/ g; n. J) y////////////////////////////////////////////////////////////////////
$ G* ~5 M: O. e0 t6 J+ ^//功能: 弹出一个信息框。
, E/ ^' W! g  Y2 \, L//参数: lpText:是对话框信息。lpCaption:对话框标题。2 f* n; L) T/ }% \0 R& h# R+ G4 M7 V. E
//返回值: 无。
4 \5 n8 ]9 L$ c# ~7 y////////////////////////////////////////////////////////////////////+ V* B/ p) l/ X* ^
inline void ShowError ( const LPCTSTR lpText = "ERROR",
# R2 N+ ~/ J( N  K! b) m& Z* |        const LPCTSTR lpCaption = "ERROR" )+ n' Q( y) }+ _. n  _5 w9 C
{
- m: k$ ?8 L; z$ S4 g& Q   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );( D9 n4 W( C) N9 a+ o  ~1 X
}
7 z! F" V$ X) H2 ]5 W+ ^1 p7 y% `8 Q# h
////////////////////////////////////////////////////////////////////; a/ X7 v1 ~( w. T- x1 C( i9 ]
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。# e9 x$ A7 t) u; x
//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
; m8 F2 S9 ]+ a/ W2 O7 \/ j3 R* ^//    lpCaption:对话框标题。3 O) F0 l/ u: a1 @
//返回值: 有错则为FALSE,没错则返回TRUE。
) L0 M5 c8 n4 y5 E8 K# t3 B+ a2 S////////////////////////////////////////////////////////////////////9 ^7 I( e5 W$ a+ s9 Z/ d8 w
inline BOOL CheckHr ( const HRESULT &hr,
& w' x7 G2 ~: Y# h+ l& c3 p1 ^        const LPCTSTR lpText = "ERROR",
) n+ G2 F- i. T# `, a+ u0 c        const LPCTSTR   lpCaption = "ERROR" )
% v. ~5 ~  V& y. x) e, W{
; _* a; g& i2 G- C2 e   if ( FAILED( hr ) ) {
% s: N1 L3 }$ Q. i+ g) E& k+ x  B* _) @    ShowError ( lpText, lpCaption );
7 e/ Y! ~4 w6 |4 _' f    return FALSE;8 s2 L  g2 b% a" j# h7 z
   }
( |4 y8 s8 O8 S9 m; @   return TRUE;+ x1 z6 o  v; e3 l
}9 u) \5 o. [/ X: L& i

, k% b* G9 \* P2 b' x$ A0 B% p: Q8 @0 Z1 v  Y
///////////////////////////////////////////////////////////////////////
/ p7 F2 f( m; G( P1 P* f2 u///////////////////////////////////////////////////////////////////////. m  ~: W  T; }$ b& q
//
9 _3 ^6 r8 h: A3 y6 T9 h//         CTTS
: J: s; m' N0 ~. |3 V3 N) x/// x5 p/ }3 |/ P% d) ?
///////////////////////////////////////////////////////////////////////
" Q0 m. z1 N  _! p3 b: x///////////////////////////////////////////////////////////////////////1 o4 e* q' G) ?  j
+ K5 ~& F5 O1 p& i9 G" M% ~- Q
////////////////////////////////////////////////////////////////////  c3 Z% B+ x; x
//保存关联窗口句柄。初始化COM。
4 g7 b( d9 u" C$ P4 H% h; K# S////////////////////////////////////////////////////////////////////
* v5 P7 k& Z( x4 n5 ]5 \CTTS::CTTS ( const HWND hWnd )
5 f& A- v& R5 O2 E/ c{
$ C/ t+ Z4 [8 o- zm_hWnd    = hWnd;
1 p: k3 K/ {. T# l  [; ?  Mm_pVoice   = NULL;2 w9 ]4 `2 I6 M3 N' c$ f
m_pToken   = NULL;
/ R7 D$ [( Z! U7 ]) Tm_pOutputStream = NULL;
# C& m, [# q" D  k, Pm_pAudio   = NULL;
9 b$ F9 y7 Y5 D$ J4 i- ?}
$ W+ _7 _* }5 L9 G4 C& u8 o: N" V0 j* ^, P
///////////////////////////////////////////////////////////////////// D4 i, b2 q) ?& S, K; M0 A
//释放所有对象。
4 h. J; w( n! n. J8 h. s; ^0 D////////////////////////////////////////////////////////////////////4 h. ^. ?& a! x( U
CTTS::~CTTS ()
0 z: o1 U+ H9 j, a9 U( B4 H' M' L{4 @+ g5 H/ Y6 y- P, Z
if( m_pToken) {' J" Y/ y* p. h: c1 g$ A% v
   m_pToken.Release();
( W3 M2 q2 B: o( `: `8 |   m_pToken = NULL;
; m3 B9 m5 b: Y' C  q, Y}
% F$ A" `: E1 Jif( m_pAudio ) {
1 {" Q$ X- B# h   m_pAudio.Release();
! V  i! I! f6 q' u6 \- L+ X+ N- X   m_pAudio = NULL;% z8 l$ g/ T3 p. W
}  b8 w2 i6 N  u% [; @& y
if ( m_pOutputStream ) {
: H9 C  b9 A8 k) l   m_pOutputStream.Release();
7 l  C* F/ w1 Q  ?& O! A5 d: k   m_pOutputStream = NULL;7 q/ k; L" X" N4 u. @! ?& _$ e
}
9 M( H6 a9 v* w0 z/ Y5 Vif( m_pVoice ) {
& Y! z! H, T# O) r   m_pVoice.Release();; Q( t7 ^! z6 `/ X9 c
   m_pVoice = NULL;+ ^) G/ l8 M7 `4 N$ G! `  j0 h% }
}
7 ~3 G% z% |$ G: b+ J" v}, ~5 ?- }% ~) |$ L. s

# H/ U. E0 }' M8 `) f6 n% c3 ]+ u////////////////////////////////////////////////////////////////////* m7 _/ I4 o: v: C' i/ B+ C  F
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。
; e, N% g. \. Q9 _" d////////////////////////////////////////////////////////////////////
8 l/ V* b0 m+ e0 IHRESULT CTTS::Create( const CSR * pSR,
) f/ v! e, J1 k4 {2 J8 K       const DWORD dwLanguage )
! q. D' o8 ?& r4 u5 I{$ Q/ m% Z9 V1 ?- m7 V
HRESULT hr;
9 i8 O2 i' `% Vhr = pSR->m_pSRContext->GetVoice ( &m_pVoice );8 Y) i: A) a- s" R* e
if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {# \) r, L% `/ @" f
   return hr;$ O5 o8 W) R/ c% q. t: R
}
" }# d( ?8 D5 X' \7 H$ F# _
5 [$ g$ \& z1 p- }& LSetLanguage ( dwLanguage );) V: x+ t6 Q; R; \; ^

$ q1 h( D& i$ e# i" \, P! g' Xhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
: g5 l- b) }- t* p' N$ s# Zif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {5 z& E. t* s2 G* s9 a: r( J% e
    return hr;' ~  w4 V) B. }' f! N- v
}
# E2 ]) O3 L4 |, R2 q: U0 [' m$ U+ i$ T
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
2 v$ W' ~; P0 b; _6 L+ r//SPEI_END_INPUT_STREAM 表示完成流输出。! b' b7 U, p% @5 J8 W
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |) _% C# d! T8 t9 G
         SPFEI( SPEI_END_INPUT_STREAM ),& r, x1 V% B5 E5 q
            SPFEI( SPEI_START_INPUT_STREAM ) |
# a% b6 Q! w& `' n            SPFEI( SPEI_END_INPUT_STREAM ) );) Q8 L! w& m% r% d
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
. x! K+ \: W0 \# \: S    return hr;3 K, J, m/ S* l* T2 A& r4 ]; a
}/ c% L: {) I& q* M4 ?' m0 T* R

6 Y: C; I$ r2 q+ @/ n8 e% ]5 F//设置通知消息( P3 F! J7 c& ]0 ^8 B' ?" b
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
3 W6 u6 d* u8 P6 L& Sif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {, f) f/ ?9 F# T2 t* S/ d) s
    return hr;
. F. ?5 G0 i- r7 @}
* b% a* u' p; C/ O" Q& f
9 m+ l" \$ i" dreturn hr;
4 I# k& p+ H. h8 ~( t( s}
) C0 Z7 _3 u0 [% P2 v  t( Y# L2 L' S% v
////////////////////////////////////////////////////////////////////
( `  F$ t3 @- l1 Q) |//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。  U/ f: R% k9 p/ F+ p
//并设置兴趣,设置通知事件。
4 M& R6 L0 S& G7 B2 x////////////////////////////////////////////////////////////////////
% x" l! |4 D" H9 ?% ?) qHRESULT CTTS::Create( const DWORD dwLanguage )
" u; M8 H& F- Y6 P6 m{
8 Z* K0 ^$ p0 f' C4 ?* n  u- _' sHRESULT hr;% j% Z- ~3 D1 s  g
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
: y; Y* V  G( b7 k7 ]9 |1 }" ~) nif ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {( w; }+ `2 `1 k& ^/ R. X" o, u5 _
   return hr;
, G% L5 v7 L& q( c  b0 j0 C$ W}* C. a+ D! E( ?8 \  a

0 W" ]& ^* n# j6 h( fSetLanguage ( dwLanguage );
* p! {( C1 ^$ h* b! ~, P+ a8 v* L( S8 i+ b
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
- i) H% k4 @/ K! Aif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
$ _6 s1 R7 f) ?/ G! R1 ]    return hr;
* Z2 h0 ^- z$ p}
. Y& Z" ^' ]; o4 Y: q( P9 k# y+ ?" v9 H( S/ B1 r
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
5 K7 Z+ J2 `& y1 w8 k7 {//SPEI_END_INPUT_STREAM 表示完成流输出。4 J8 d) y! k8 T% z' {
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |1 v( e9 t# q+ L  B4 w$ [3 R
         SPFEI( SPEI_END_INPUT_STREAM ),2 U1 Y  E6 S0 o" O* Z
            SPFEI( SPEI_START_INPUT_STREAM ) |
* D2 L4 m: L$ f4 c/ {+ h8 [, F            SPFEI( SPEI_END_INPUT_STREAM ) );8 j( G6 A$ i3 `) ^* ]$ W% Y
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {9 [! M% {7 M9 w6 z3 j% h
    return hr;
4 N- l: S, @" S: P+ k7 H' l}2 N& V1 X0 u' W7 w; A, F
: t7 a5 G0 a5 z
//设置通知消息
( l  g' b- {4 ^- v6 y0 Bhr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
9 Q2 L  G1 p) @; D! X& aif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {/ f- c0 {: N4 m0 D- s; W6 t9 o
    return hr;/ O; x* V( f0 p$ p5 D$ I3 ^
}% {/ g6 R: L: g; c0 i

, v: i$ o7 J/ T- \return hr;" e( u6 s, E% J4 g6 X* I
}1 X+ Y) O( C& ?9 ~3 j, t% Y7 [
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件- `3 c8 J1 o) Q7 u: Z
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
4 p) A* R" m, V{
6 ]( |; B$ r2 V. c" a" _: P8 Q" B    ::CoInitialize(NULL);//初始化语音环境" a. f" P' P0 D
    ISpVoice * pSpVoice = NULL;//初始化语音变量
1 J& m( y: ~) H& ~; K6 w; e+ @& H    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
& l% ?& U* ^$ @2 Z1 T2 A        cout << "Failed to create instance of ISpVoice!" << endl; ( d& s; G- Q5 Z9 c) Y
        return -1; $ E0 i' g! `* g% Y
    }
. U, ^; G4 e+ j
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量! F0 X; x  F1 F/ ]6 R; }
    ::CoUninitialize();//释放语音环境

4 ~2 H% [) v% E  |2 p3 Y    return 0;
/ a4 j8 c3 c! H  A/ g}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序% Y/ J# V6 y( f/ V6 f

* {1 ]8 _- z. `* w. a( y0 n1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地) m, s$ a; j$ g7 K+ ~
3 T$ i- P& ~* U5 ]) K9 n
http://download.microsoft.com/do ... -US/speechsdk51.exe   ' j; W, R3 f2 {5 J
Speech SDK 5.1安装包 (68   MB)     , }$ v. A, @4 x; O8 w
http://download.microsoft.com/do ... chsdk51LangPack.exe      8 }, M% ^" g) E2 t
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)    K( a9 F# q# v& V/ T$ {

+ ?7 j* v& o* Y4 Z3 _' l2.下载后,执行安装- k3 R; q& d( n6 w! Y( d

8 g" u2 ~9 X1 y下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。7 V+ G6 ?$ f& n9 w
  a( w+ \6 i% ^9 P6 o3 J1 _: G- I5 @
3.VC的环境配置8 |) I' m- j' ~1 q: Y: h
/ \0 H/ J, K/ C3 N1 \& @  ~' v
在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
: I' @. f! T" b! L
% D, q1 z8 H! Y工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去./ I, t* B# l- e7 i: z
9 a' U4 v# |" ]$ ]1 M9 W9 w& t2 \
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
% j/ H+ m7 u: j6 F/ ?; p
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-30 02:12 , Processed in 0.022352 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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