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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
$ b/ H+ e, G; t//1,生成动态连接库时,要#define USE_SPEECH_DLL,* o5 U8 Z( K& L7 T% z
//      并且#define LANE_SPEECH_EXPORTS
' V, }9 C7 R9 g- v0 a/ y" `//2,使用动态连接库时,要#define USE_SPEECH_DLL
# H$ f" i" M1 y% S+ y! K//3,声称和使用静态连接库时,什么都不需要; j( j( Y; ^; v4 f. ]
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),' a+ ~. O* @3 t  R7 z/ r  N+ N
//      动态连接库就不用调用了。3 i. Q% o+ w9 t( N. s! \% [' c
////////////////////////////////////////////////////////+ r  I1 T) e+ e5 ~) ?* ?9 P1 u9 k  g
#ifndef LANE_SPEECH_H
* ^1 s6 T- w2 o& f#define LANE_SPEECH_H
9 N6 X4 \) q4 T+ v3 B& [0 i
& b' G0 s7 C0 e, w, L+ Y#include <windows.h>
# g) l- T/ k' L7 [5 O  q4 h#define _ATL_APARTMENT_THREADED& e* h# l- `* V
#include <atlbase.h>7 [& A: w: i: F7 ]
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
- a! T9 P  {5 {: ?0 I( r, X6 `#include <atlcom.h>. B  e6 @5 {$ U  v' b" ~  }% N
#include <sphelper.h>   //sapi需要的头文件/ o3 m% [7 J- ]7 Z
5 c* e+ L& l  r2 W
//-----生成动态连接库和静态库的处理----------------
. o2 W. q4 c7 n; a  k" i#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
. y' V4 r9 {; Q3 U* g* U
" I$ a" {/ ?3 |( N# g$ y  e#ifdef LANE_SPEECH_EXPORTS
( u: Y& Q3 O, U: n9 y, {   #define LANE_SPEECH_DLL __declspec(dllexport)6 n+ Z3 u# i9 a1 ]  V& [
#else4 F% _- l  K0 r. M' Q3 x
   #define LANE_SPEECH_DLL __declspec(dllimport)
* R* A! Y$ Z0 n" N9 s#endif  l7 W9 J  J/ q) M! [  I
0 g% i/ c% i  A3 P
//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关
' \5 t0 m5 ~1 P8 b//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
3 K  n8 g+ w  A2 f#pragma warning( disable : 4251 )  g% D/ S7 P4 i% L# I

3 Y9 D' K1 C5 Y#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)8 u* \  `3 [% K. M& q% v  l
#define LANE_SPEECH_DLL  D/ P. a; s$ B
; T; ~; C: k/ l& O, u
#endif //USE_SPEECH_DLL* Q* _- d" B, x  F4 o+ S3 g

) X( `$ @2 X5 L0 Q
# @# `6 u# m/ q; d6 x- K//***************************常量***********************
6 \) h7 f4 O5 i, X' d+ t' [0 L+ `# B7 g" h
/////////公共常量-----------------
- R  c9 f8 O5 ?  B; T: rconst DWORD   SP_CHINESE = 0x0000; //简体中文.' W( x$ n( n  \. L$ K
const DWORD   SP_ENGLISH = 0x0001; //英语.0 a( I' |- V. n5 O, g9 \

$ v! N) T9 `  j8 N9 q& r1 I) Q/////////CTTS常量-----------------! o' L$ O7 D. {9 U8 R" j8 I& g* }" L
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。! {$ Q2 l, R! G+ n

( b: q: g, Y" K9 {/////////SR常量-------------------
. \7 Z, U7 n5 Z/ B$ I9 A+ Mconst UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。" a/ p- R0 D. \, m2 a; R" c
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
8 O' V1 }5 N) h5 y1 D* Sconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.5 `" d' ?2 E. I/ c$ y; S% r6 |# v
" C7 u: X" o( g2 }+ i
//以下常量仅作例子用。* l' _1 M2 R8 k2 p$ p
#define VID_TopLevelRule 9000   //顶级规则ID2 L" |8 H" j1 ~3 y! g9 r* S
#define VID_SubLevelRule1 9001   //子规则ID
" J; \+ c) W. ?8 m#define VID_SubLevelRule2 9002   //子规则ID2 i% y) l2 U( n/ \$ {/ V
#define VID_SubLevelRule3 9003   //子规则ID
! f: _. E; P! x" ^/ X3 l' v6 O! {

  H# m0 B7 h2 m, w* j//*************************类声明************************# `* J9 i) J6 _
& A3 H1 b8 F& f8 Q) j

% b7 Y8 D0 x2 aclass CSR;
& i3 ^! H( ?/ r4 c) ^6 b2 \9 q///////////////////////////////////////////////////////////////////////% C  e/ F! T' P, Y" a& p
///////////////////////////////////////////////////////////////////////: m( o: |# r6 S
//
! U  {5 C  A6 u8 {3 M% ?//         CTTS& K: C) J* f4 Z* T
//
$ \: [5 V4 B0 h) z/ Y# S0 x///////////////////////////////////////////////////////////////////////# L6 D: W, M  {# e7 S  [+ N
///////////////////////////////////////////////////////////////////////
2 t/ c. h- N( ^$ M1 ^3 p+ z0 \2 f
9 z8 f/ i8 C; }2 E* I0 qclass LANE_SPEECH_DLL   CTTS
$ f3 X9 L. P  }( H/ m{
1 _* p% X( E+ C: bprotected:3 O# ], ]  a9 R  V6 b  Z- J
HWND       m_hWnd;     // 关联的窗口句柄。
+ k. W$ [% b: r, ]3 y  J% Q$ M# V2 V' C1 S5 `
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。" K. e7 w8 A; a
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。5 O) Q9 k& u7 N- F' {+ d' T
CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)' k. W& k: p. v- ?* R
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。4 E2 s2 I8 L5 Q! V8 v) p& A

0 Y. u2 I! G- `: Z" ~& `% E5 @public:) e2 v9 t& O0 V( ~0 Q% E. H% s
//********************************初始化部分********************! O& W( M/ r' n% B9 A

  ^5 z" J/ a1 z0 q" e////////////////////////////////////////////////////////////////////- l5 Z+ E" Y, j
//功能: 保存与识别引擎关联的窗口句柄。
) B  W4 O0 ]# x  u//参数: hWnd:要关联的窗口句柄。. n% l  Q+ G  n/ d: D
//返回值: 无。
, I, u( i/ _" [$ ~9 Q1 L5 w- q////////////////////////////////////////////////////////////////////
6 G- p. u& a% H" T! JCTTS ( const HWND hWnd );# u, h# H" l) f* J+ [2 a' w

; B" |1 |  w, `////////////////////////////////////////////////////////////////////
; T. y0 z! C4 q$ x//功能: 释放所有的对象。
! A  h" m4 O: l8 _" i: R//参数: 无。+ G( g6 z6 x4 ~) T3 D5 a0 b( B$ p, ^
//返回值: 无。' }% `$ F8 X" f: B% }' K  U1 _
////////////////////////////////////////////////////////////////////: J/ N0 }/ `- @7 a! \
~CTTS ();0 n- f/ O2 O- U7 j+ ?
# |4 R$ j; j/ `. @0 b- S
////////////////////////////////////////////////////////////////////' j9 P" f6 j1 |1 x
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。7 o# }) V* B2 G& h) k: A& }
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,7 q. H7 A7 g1 A# M
//    SP_ENGLISH为英文。
9 d) l8 N8 G$ @+ k9 V+ M6 _2 p//返回值: HRESULT类型。
" g% ~3 g5 |1 r; Z/ K////////////////////////////////////////////////////////////////////
5 ?' P; O2 U* F- _5 hHRESULT Create( const DWORD dwLanguage = SP_CHINESE );
( m8 M/ Z  D9 f+ P1 R; H0 ]" O* ~, a, V( r' V& L  k0 K' H% ~
////////////////////////////////////////////////////////////////////
) ?# K: P. i* K0 P//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,% e& c  Y, L% g6 e, A! _+ |' x
//    通知事件。# Z3 O+ |* |1 S% f
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,% [0 l- W3 Y& A% k3 l6 P
//    SP_CHINESE为中文,SP_ENGLISH为英文。
9 w% c: V0 {3 v3 I" I8 j//返回值: HRESULT类型。
' }5 r# C& r  ]; a4 K////////////////////////////////////////////////////////////////////
( H( K( \6 Y" \# L+ p3 }HRESULT Create ( const CSR * pSR,. l/ z) E) s6 g9 r+ j& s: R
       const DWORD dwLanguage = SP_CHINESE );/ P. {, n5 z4 G9 I' Z( |1 d1 ]
% m  H! }8 T+ P9 D. ~

8 R4 i+ A' a* ^! F0 f% e* ]//********************************设置部分***************************************
& z& j8 y3 e* v  b/ q. G/ v/ G  z
* _9 R, y+ t6 |8 R. a$ z////////////////////////////////////////////////////////////////////
; H" X  u" D7 Z% W% c/ ~; o6 k/ p//功能: 设置朗读声音的语言种类。1 b. S9 ~, J; `( Z
//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。0 z+ }: q" ?( m) Y
//返回值: HRESULT类型。
% G( X  |. A' w! T////////////////////////////////////////////////////////////////////
. ]- y0 a" @8 a, JHRESULT SetLanguage ( const DWORD dwLanguage );
, h& l' J) c8 Z7 x5 n; k5 Y7 [4 F( ~' p  y
////////////////////////////////////////////////////////////////////" k8 H5 c0 C/ T& Q
//功能: 设置要处理的的事件。" u5 B4 r; f; a; T
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,5 J9 a0 B. b  c3 Z$ G1 [" M& ?6 J
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
* f9 n: g& [5 q+ y; r//    件都会收到通知。# n3 e8 {: I) I$ Y, T2 d
//返回值: HRESULT。$ q% V9 q0 {6 g7 z
////////////////////////////////////////////////////////////////////0 g& \& j' y! A4 A
HRESULT SetInterest ( const ULONGLONG   ullInterest );$ E: n1 y% x; E$ D* R' F4 h/ M! a
1 b8 @- j: H9 \; q  r8 j* I1 i, U
////////////////////////////////////////////////////////////////////" C0 w+ f5 O+ X3 e/ i( g$ }  y
//功能: 设置朗读声音的音量。5 m% G+ z9 s& U* j6 q- i8 l" ?
//参数: usVolume:音量数值应该从0到100) R. x- ~( t. ]! z
//返回值: 无。
# X+ i- H/ x) f+ n+ p- P3 d9 d////////////////////////////////////////////////////////////////////; `; j0 |- C1 D8 K7 B
void SetVolume ( USHORT usVolume );
9 t) m7 i$ O: `2 K; V$ j1 o- ^7 O+ j9 M8 h. e* M6 T$ M
////////////////////////////////////////////////////////////////////
2 O+ {8 I6 U& |+ @//功能: 得到朗读声音的音量。8 k3 J+ \' B3 P& m- f( \
//参数: 无。3 a, w$ @4 z+ s6 L- p! K1 z$ z
//返回值: 音量数值,应该从0到100。& ^/ F( p1 U# g* Q" V  x
////////////////////////////////////////////////////////////////////
3 m5 v3 ?3 H- `- n( C1 _2 Z* b" {USHORT GetVolume ( );* _* g- m% @  j) _

  j, D+ C% U8 m) Y* E////////////////////////////////////////////////////////////////////5 i) X4 b2 ]' b  ?  E0 e
//功能: 设置朗读声音的音速。
0 X  K- v/ K5 y//参数: RateAdjust:音速,参数范围从-10到10。
; e2 V% q+ _5 T: `+ i0 S; a//返回值: 无。7 D/ k$ R4 h9 J0 e
////////////////////////////////////////////////////////////////////
  @# y7 o+ @$ a8 H7 Gvoid SetRate ( LONG RateAdjust );
: a. b# M. c, B
. X% h4 R; B) ]0 X  I- Y////////////////////////////////////////////////////////////////////
. d# I( C6 S& x, s! @$ c//功能: 得到朗读声音的音速。
& g1 x  Y% p0 l/ u! A//参数: 无。
, q* M# l7 l' t' F5 u# U//返回值: 音速,参数范围从-10到10。
$ U% K& Y3 z) s' f' C////////////////////////////////////////////////////////////////////
3 d8 p; q* F5 K) BLONG GetRate ( );) F8 P  y4 {! d! g6 F( r( [
% O3 D0 b1 u" b  v8 {( d1 J7 ?% L
////////////////////////////////////////////////////////////////////: v0 s) F1 h! w7 t  H6 K0 Q# d
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
, J. F5 v/ L( |( ~: n! ^8 E//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
2 j, B# J  `, n0 ^! V7 l9 x//返回值: HRESULT。
* x: }. g7 Q1 j$ t////////////////////////////////////////////////////////////////////: Q! ?1 c% D1 k6 y3 R. [
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");
0 U3 _) k; ]0 B, D6 U1 X% C3 C7 f# F
; Y4 k) ]& y/ }. V) k, f1 r////////////////////////////////////////////////////////////////////
, ~$ c+ A- k" e' ?! O0 i0 M//功能: 设置朗读的声音从音箱输出。3 w" |- y" Z% j( l/ `
//参数: 无。
: a# c( g: n& P//返回值: HRESULT。
6 m, n4 A9 \! h. C6 a////////////////////////////////////////////////////////////////////* W" Y6 |4 N1 y
HRESULT UnSetOutputWithWav ();
. n6 C: L' z/ d, h# D( `) l
& g8 i5 D- a& F6 |1 Z6 t3 r- W& W. S8 E0 D6 n
//**********************播放语音,文本到语音转换部分*****************************8 b/ \" t: j8 P; i8 T5 O% t, Q4 j3 Q
# \# H/ H: z3 A$ u% [
////////////////////////////////////////////////////////////////////* v. o3 F9 K. a- Z* @: b2 Q2 V4 A
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
. G' O, E" Z) Q& U* U//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记. \; k* V% V1 f
//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
8 J0 y9 J' L1 G. {, \/ |//    SVSFIsXML为朗读带xml标记的文本。
; ^$ X3 `0 k) Y2 z% k//返回值: HRESULT。
% D$ ]/ s$ T7 b1 l2 t' P////////////////////////////////////////////////////////////////////7 g3 h/ o% P. N) z. Y6 G
HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );9 N2 f; i. Y7 D# M# N
- }$ C: Q, |& A1 |7 d( s
////////////////////////////////////////////////////////////////////$ J- W$ m+ h& l: l5 {% D
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
$ h) i- }$ d5 y2 W4 I2 m//参数: 无。
/ d9 K3 C# n$ c2 _//返回值: 无。
7 M7 {0 N* ?9 ^/ ~* j- ^1 _////////////////////////////////////////////////////////////////////
1 d# u: f! Q: s4 U  kvoid Stop ( );
/ z5 Q# d2 k/ m2 [
( q* @- r; N1 z+ J: R////////////////////////////////////////////////////////////////////! Q: j! H- K) H$ f- |
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
% K! v# |+ d* u+ O//参数: 无。- l/ s. J  a6 t
//返回值: 无。0 [- w5 x, ^$ c4 T( i, m3 b
////////////////////////////////////////////////////////////////////' u  e. W4 J. V( V
void Pause ();
# U. e4 n4 R9 q. k- J
- \7 {4 ?, D1 i! ^4 p////////////////////////////////////////////////////////////////////# C1 r9 H) Y4 ^2 _7 M6 b6 S8 R
//功能: 从暂停的地方继续朗读。# ~) j$ G% P* B
//参数: 无。
+ [( e( f" q/ `# z+ Z//返回值: 无。
' l) g5 s1 }1 h$ O$ K. p////////////////////////////////////////////////////////////////////1 h' n9 @* a+ n; {: [' E
void Resume ();
5 b# @4 B, p) S% I' a% X! p6 Z

/ \$ O9 {2 j7 m- S' `//********************************处理事件部分***********************************
- P% l* _! o; Z1 |2 n
7 n4 f( W7 v% H/ S" R8 bpublic:
0 l* j3 j! J5 |% e8 Z2 s////////////////////////////////////////////////////////////////////) u* w% K  v& M
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。5 e% ?( w  R8 @! h" d0 H6 O
//参数: 无。: r1 _& [6 d* Y2 D
//返回值: 无。
1 _) U  X3 G0 M" |////////////////////////////////////////////////////////////////////
5 b+ G+ s! r6 z3 Q) C2 Q9 jvoid ProcessTTSEvent ();
, E% K; P6 Y# X4 Z, _. V" k
$ h9 P) b( u  g$ \$ Y3 I- B8 t- L" f' M8 K$ O
////////////////////////////////////////////////////////////////////
& i2 w! _% L: N7 A- L7 U: T//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。6 l0 J9 L- g7 {( h  C  {+ C/ W
//参数: 无。
# ]1 Z/ ]0 {. Z& a' _5 X5 n//返回值: 无。
/ }6 W# D: ?. \* R: X# @8 W////////////////////////////////////////////////////////////////////
0 S, L, D# }# B- L! @4 a. ?virtual void OnStreamStart ();
# E2 I0 Y  l  f0 t9 [
2 y" ~, S* U* Y1 |% n1 P////////////////////////////////////////////////////////////////////
! g1 X( [% ]) Q8 B5 v//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
6 p' Z8 Z8 U+ j" h+ r//参数: 无。% u  z7 F/ g4 O9 Y. G0 n
//返回值: 无。) @+ V+ \! w% O6 c* u% [9 e9 V6 Z
////////////////////////////////////////////////////////////////////8 \0 J8 f" R3 v. A* h
virtual void OnStreamEnd ();6 }, G" R8 D1 o& `! ~: e4 K
};
6 X+ L! V+ l" j' t8 q6 ~5 ]
+ H3 R* b6 p% a
1 [. d% a1 F6 \  ]/ O///////////////////////////////////////////////////////////////////////
7 \5 U  R# t, H- F6 P/ P( p///////////////////////////////////////////////////////////////////////
& G2 p( u; u& A$ C( s//         CSR% Z/ o. u/ ^. C3 t; [
//
6 h0 |, _- q# m$ h+ P9 v1 c///////////////////////////////////////////////////////////////////////1 L- C* x' N0 ?. n  I' m) k
///////////////////////////////////////////////////////////////////////
0 @/ }$ P8 ]# F4 s, \" |  v( T$ n4 y* h. N4 ]( f
class LANE_SPEECH_DLL   CSR; M% c7 n6 s; y6 }; d4 N: N
{
5 V) T3 a& Y: A# ?8 M  g3 _9 H3 Q- ^- [: @, F, S5 J
protected:* m/ a; \( a" K& W4 |
HWND m_hWnd;( P1 E9 a0 o& w( j* K- X  n$ }

. j; l5 |& G! d, \! D* y% tpublic:; G1 s4 f5 i5 L7 w& A
CComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
- a6 Z, ^: x2 OCComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。# p  d4 `) \3 j: V' N& T0 P( l
CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。0 F. t3 W% V/ l6 z
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。
5 @% Z! y/ g5 C7 WCComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。
' P9 S" e* F  z0 S2 V$ w2 C8 xCComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
, ]  M2 f6 f. q0 s+ _+ g3 xpublic:# R# r( i6 }# U8 b# u6 ?
static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
% s" \) z# K* q9 R
  |+ @3 P& f" A; }3 V
% p3 s' G6 y# }2 J+ Pprotected:1 k) X+ s; y0 V( L
//***************************辅助功能部分****************************************2 _+ Y& ~, A) O9 p6 Q
1 H) j' @8 ^  ~: X4 U& b/ J2 i
////////////////////////////////////////////////////////////////////- V* x! X, N3 \
//GrammarID加一,每个GrammerID必须不同。
: w% U1 r( @, ?+ T6 ?5 G. h& k; }////////////////////////////////////////////////////////////////////! O; T7 ?, n' V. t& L4 K% t
static void UpdateGrammerID ( );
$ w( x. I8 e  t8 c# y- m" x$ |% {( f4 t; c% Z" H

9 E6 R3 D: ~. dpublic:/ t4 o* }+ W- c+ M5 G5 _7 P
////////////////////////////////////////////////////////////////////9 y, s; |4 ]8 a, J
//功能: 友员。TTS中的从SR引擎中建立voice对象。+ A+ A9 Z( f0 V5 K( v
//参数: pSRContext:SR上下文对象的指针。
+ m7 S  m3 w8 a, z) R//返回值: HRESULT类型。
# x" @; {, _; w& j/ E9 X6 J9 ~////////////////////////////////////////////////////////////////////
* F- {# \7 F$ ~1 W5 ?% ?7 hfriend HRESULT CTTS::Create ( const CSR * pSR,  g: b7 J; c' [, K# q2 U
          const DWORD dwLanguage );
5 V; y4 r& p3 ~. U8 t7 Q8 `- k1 m
% {9 w! _. e/ e, g
//****************************初始化部分*****************************************
, U% A4 Z9 U% G) o
2 _8 h# Z) O* P/ [, B) V////////////////////////////////////////////////////////////////////
% E7 v& L0 P" \) d* ^/ M% m//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。" k" j! Z: j* ]/ _) a) D9 j
//参数: hWnd:要关联的窗口句柄。
' C- q1 Z3 M2 `9 f  r) U//返回值: 无。! c  d! E7 c# Y
////////////////////////////////////////////////////////////////////% W+ Y5 _, K% V/ P; L5 r! Z
CSR ( HWND hWnd );& s6 n: e( Z( l' t* n- W) m+ _

6 L& Q/ [& U. ?+ j8 B////////////////////////////////////////////////////////////////////
' `/ h8 i9 y1 ^" I//功能: 释放所有的对象。
% `$ B: A3 B* C9 N1 n& q//参数: 无。
4 j4 H5 U4 E1 J9 U, ?' S& O//返回值: 无。# f6 w: w- i2 L6 D+ `1 o" I
////////////////////////////////////////////////////////////////////
: q2 ~. X5 E$ _: U. a) R~CSR ( );
8 r, d$ \2 r$ E; i$ k5 A/ j
$ A* h) C9 i( ]* B0 S$ @, {////////////////////////////////////////////////////////////////////* f  N. {; U- M- A$ O4 B  [' h
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,/ V) Z) m% g+ n
//    加载文法文件。' W. p  z. [6 x0 Z7 B/ d
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
" M- g- r- c6 v# p& F+ ]+ i//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
9 y- g! y1 R5 t9 Z//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。
  m- u. e$ ?/ `' t- }/ d8 w//返回值: HRESULT类型。0 T; i6 ^* D, ?" H
////////////////////////////////////////////////////////////////////: T* |5 y# k5 Z5 n( A& W- V
HRESULT Create (const DWORD   SRType,* \2 ]# h2 ~" X# x, G
      const WCHAR   *pwcGramFileName = L"grammar.xml"," R) E/ G. l) ]3 V
      const DWORD   dwLanguage = SP_CHINESE );% }$ b7 }0 a+ w  ?

2 T9 q% Z$ c5 o/ F; L) H
* S, `- o: k4 i, v, d5 Z- ]) M//**********************************设置部分*************************************) H1 ]: g* E9 t2 r3 o( b
0 U% _3 h  ^7 ?% K! ^& G) Y
////////////////////////////////////////////////////////////////////
+ g9 p- o4 Y/ B8 f9 }//功能: 设置要处理的上下文接受的事件。
" I: M+ ]) O8 Z$ U2 a//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
2 d, ~% a+ \6 }0 y1 P: }//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事& D7 D8 S6 `2 j" p: r3 ^2 a
//    件都会收到通知。2 G$ b& h, R' G1 S/ Z8 m1 K" q
//返回值: HRESULT。4 G3 h, Y. G6 C, k$ o% L( x( t" Z
////////////////////////////////////////////////////////////////////% B* R- P2 G6 P4 y: f9 j1 k
HRESULT SetInterest ( const ULONGLONG   ullInterest );, C! ]: f% L& w$ [5 H
& S% g6 t* V* I% [0 p8 V3 V9 [
////////////////////////////////////////////////////////////////////
* b+ j; {" h& T' t8 Z/ F% ~//功能: 设置某个规则的状态(激活或者取消激活)。
* J: _/ m1 ]4 P1 |) L  Z8 d//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,
9 [  {+ M% O* y//    FALSE表示取消激活。
: h5 r  \6 y* Z2 l4 U  T//返回值: HRESULT。
! L3 e+ m5 d8 v! a////////////////////////////////////////////////////////////////////0 R6 f* |- i% W) F" n
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
" {- @6 {, {1 W8 Z& [2 F+ d- g* @4 \6 `" p/ Q' Z
" X9 z/ {# V2 i9 p9 k
////////////////////////////////////////////////////////////////////
7 s" I& S; Y. w9 z//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
& Q  g7 b: K6 U$ a) d( J) v//    风输入。
+ [9 G' @8 X$ i//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。  G1 y5 ], i; g
//返回值: HRESULT。
9 P6 h2 a: D! ]. g- G8 e5 c////////////////////////////////////////////////////////////////////: G# ~! p0 ?# O5 Y
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );$ X/ Q9 H8 z, n- F0 a
6 q. G0 t4 C3 ?5 H& ]
////////////////////////////////////////////////////////////////////
3 K4 e  X. C7 a//功能: 取消从.wav文件识别。恢复从麦克风识别。
* e7 k% E- F, N4 S8 V/ j//参数: 无。7 i& P; Y. O7 r" x! o
//返回值: HRESULT。
. E2 @. b; |9 c9 a5 @////////////////////////////////////////////////////////////////////+ F# u6 [$ _* b7 V+ k( g
HRESULT UnSetInputWithWav ( );& R  H# f4 B% ^0 e+ q8 ?+ M! p

( j$ R5 T& U4 w- H//***********************识别开始,结束,识别结果的处理**************************6 U" q! S  k7 W" K% D0 ]

% y7 f: l3 b& r; k////////////////////////////////////////////////////////////////////
: Y; u6 t; ]+ c7 g- |//功能: 识别开始(将所有规则激活)。
6 K1 K9 P" R) A" e) v: P- k//参数: 无
& g1 U' l& B" |' o6 l//返回值: 无。
: ~4 o; q0 ~: ^; ]; k////////////////////////////////////////////////////////////////////1 ~7 U/ Z; j; ]2 {3 {2 A6 u2 U
void StartRecognize ( );
+ N/ y4 p& ^: V, x0 C
) F+ k: }( s- Y2 X////////////////////////////////////////////////////////////////////
0 q$ W+ w( a2 _: K% {//功能: 识别结束(将所有规则取消激活)。" f8 y2 x& n& w4 O! x8 N8 Z( R8 |
//参数: 无。& X$ ^  c& E- P5 K
//返回值: 无。- x( Y! D3 a' B% Y$ Z/ N' x+ M
////////////////////////////////////////////////////////////////////( W: B: y# [! t1 V: E  P- i; ^2 \( U  _9 y0 m
void EndRecognize ( );6 @$ c) r% T# `7 o8 b9 n

! Q# j  d- ^$ Jpublic:7 B1 v2 ]$ C" e2 X" G. e& H
////////////////////////////////////////////////////////////////////
2 a2 T! Q* i" u( c! M( O//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
) l* I6 y0 F" P9 J; z/ g3 F7 y! v//参数: 无。
$ z/ h& \  r  L, s//返回值: 无。
# v/ t1 f  k1 `////////////////////////////////////////////////////////////////////
& g0 i5 J* s+ n0 tvoid ProcessRecoEvent ( );( j* g5 q3 n% {
5 B/ j* z6 u6 }
protected:
0 t' z) w# T6 E; O////////////////////////////////////////////////////////////////////1 ^2 }8 v5 K2 D5 `% g+ W
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。/ `( }8 u3 _4 c3 O9 q  o5 k
//参数: pPhrase:ISpPhrase类型。
) a3 W& K0 @5 m! q5 B//返回值: 无。
1 p! B- b4 z/ S& I! u////////////////////////////////////////////////////////////////////& D: Y' B  |! }' ~% g$ A
void OnRecoSuccess ( ISpPhrase *pPhrase );- ^1 s4 V' b! p6 }$ c) r
- @5 R  m& s8 C4 J9 D
public:- r/ _+ e& e6 G* R) _4 ]
////////////////////////////////////////////////////////////////////& B# G, k) N) C: E# [. \
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,! v: s4 @& c, X8 y) y: M
//    需要在派生类重载。规则ID必须以常量形式预先定义。/ X0 Y: t, x' ?2 g, e) [
//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
& q/ ^8 r5 j8 ^7 D) Z//返回值: 无。0 X/ q; H" `- R2 ~+ n0 h, p
////////////////////////////////////////////////////////////////////! M3 I* Y2 Z: \2 ^6 S, A
virtual void ExecuteCommand ( const ULONG ulRuleID,
1 j7 U% L5 k; h0 d2 `% m8 n          const ULONG ulVal );3 Q8 {9 D8 f; h) F; h

9 C# n3 \' H- H% y, e. o////////////////////////////////////////////////////////////////////+ B+ h0 `( ?2 C% C
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。: Q5 j& q" _  g6 V
//参数: 无。8 u, d' l) g1 \' ~5 o% _! Z3 ]0 c
//返回值: 无。
7 N  U9 n& k$ k7 `* T6 L& U////////////////////////////////////////////////////////////////////' y& S  b1 Z# a/ r. |8 q9 w
virtual void OnRecoFail ();
9 Q! n) v$ k+ I6 `( s' k8 a  B9 Q# @
- W- M* ?' g1 X5 H////////////////////////////////////////////////////////////////////* D. y. ^( _) n" W
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。' s5 Z6 ?3 {. a) l
//参数: 无。0 N% D+ U$ h) d: _% b/ s1 u
//返回值: 无。! C$ m3 L8 R3 l) n. u9 p
////////////////////////////////////////////////////////////////////
7 G, l7 A! F. U/ }virtual void OnStreamStart ();
6 H' n, ^$ w) Y, @) }4 p3 w' ?7 ?9 V- o$ A7 Q
////////////////////////////////////////////////////////////////////
, `: u& C# U* `+ f3 w//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
8 h& I# L( q3 n3 g: G3 P, L; }//参数: 无。
3 b% Z+ L( n, o4 w//返回值: 无。
5 {, U4 Q  U1 W& L2 [////////////////////////////////////////////////////////////////////
% Q2 q8 }% t3 [; S! [virtual void OnStreamEnd ();
% O6 c& ]1 ~# w$ P8 S
7 L$ q  t7 e# l! W1 b8 q* V};! e0 `* O( H4 U+ O
1 y1 P8 f1 u2 s" [8 X' L$ H

9 U2 T  h9 k# Z4 H. C7 C) Z( ]' x& B  u7 E5 s- L5 d
#endif    //LANE_SPEECH_DLL_H
; n7 l. d+ B7 U" D; H3 N4 C: [: h3 ^
' X  s7 q/ z  b2 f% O5 m6 g///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////: L2 }& ^% ^% ^  f
* y; n. a2 n3 [- Y
////////////////////////////////////////////////////////+ U, R5 I6 g0 u$ O# s% V; q
//
0 h6 c+ A, Q4 z, P. y3 J; v// 文件:LaneSpeech.cpp
3 ^- Z. }8 m* U. D8 s// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
' r; i( Y+ f( y) `6 ^$ E, `7 F; @//    语音识别只支持命令模式,不支持连续模式
( h! t( ^+ {! c5 P% O: L// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 3619908
: }* M1 x6 A* k* p9 f) V6 k// 日期: 2004.10
/ |- C1 R0 O3 K/ a// 版本:1.2
2 i5 F: }, S6 {1 |// / {8 C/ w" k0 ]- p* K0 `
//! x( S& K# [. N" A
////////////////////////////////////////////////////////* H! ~5 [: ?$ M; S
/ {5 q* p# d6 T8 I! }* d! D
0 V( {9 f+ c8 G
8 u7 J3 b" L* b; l
#include "LaneSpeech.h"
( I0 K6 Y  |5 i6 S7 {* G$ Z' {  L0 F% V
//-----生成动态连接库和静态库的处理----------------# i, J+ F4 O( D1 y
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
' Q6 D7 J& c2 S& W; a8 g9 S
5 h5 f7 s2 ?6 ZBOOL APIENTRY DllMain( HANDLE hModule, 6 H- k/ l8 ~( y5 l0 H3 z
                       DWORD ul_reason_for_call,
& B+ T; x1 N/ a% `: C                       LPVOID lpReserved2 i$ F% ?: L4 V, k0 f
      )
3 V1 v' g& l! d( j' ?9 s- [{
! _( ^0 I1 g1 ?' @9 O; G( |( E    switch (ul_reason_for_call)$ ^6 q4 s; V( R" |1 ^' F' K
{
' `4 A  r# V: H   case DLL_PROCESS_ATTACH:, y9 j6 |# ~' b+ S$ Q4 x
    CoInitialize(NULL);5 o0 |; i) ]& ?7 @" F9 _* K0 Y
    break;
) ^/ p1 b3 s1 y9 Z8 d  
% q% G9 e" B; j: v8 _   case DLL_THREAD_ATTACH:
' c# b. R  x6 E' ^% S4 E3 ]    break;
# E& B( n, S* A6 s" w$ [  0 V6 k( S- m: C' ]( O  V
   case DLL_THREAD_DETACH:
2 m4 o2 O6 n2 A8 ~6 y& h/ @$ h    break;0 A" U7 Y. l( p5 B: R5 G
  
7 ?8 r; b0 h' o* c1 ?; e- ^9 h   case DLL_PROCESS_DETACH:/ `" a, c' x  w/ h4 I
    CoUninitialize();
" l5 O5 t% s7 Q+ V. ?& D$ y; Z    break;
# W5 Y6 ]4 A3 m; A! l% R    }8 p/ B3 f" I6 v  T/ [
    return TRUE;
- N& G" u2 G* @}
. p0 b) G, }  J2 a' x# c
: `4 g' f- G- D4 W* N# L' B: J  K#endif //USE_SPEECH_DLL
* ^5 B# K4 S# v4 x" w" c
) i3 R# Y5 V+ n* d9 L
9 v) b: T" O2 d1 n2 o
( o6 F. N; I" G8 e! c* B///////////////////////////////////////////////////////////////
2 V8 N4 N9 {+ t$ E2 v# s
( w9 X* d& ~( v: U: h////////////////////////////////////////////////////////////////////- V6 X5 H2 S8 O5 W
//功能: 弹出一个信息框。
1 ?( f: R; e- S" r4 Y; B//参数: lpText:是对话框信息。lpCaption:对话框标题。
' _1 N/ ~) r3 R3 G* w% A9 w//返回值: 无。
9 F5 B6 }! B+ s( b9 k1 R9 C# g////////////////////////////////////////////////////////////////////6 {$ ~1 y5 ^  G7 E' \+ i; d! c
inline void ShowError ( const LPCTSTR lpText = "ERROR",2 W0 `- w. _" S7 W' i- F
        const LPCTSTR lpCaption = "ERROR" )
: e. }' b% Y$ N2 C{
8 W' ?' T- {% ^5 S3 L   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );/ G6 q# u/ W8 v) Q& @7 U& W5 W
}
4 g. q. N; i4 y3 Z$ e' c* B9 ?
# ^! q6 W3 }6 d////////////////////////////////////////////////////////////////////6 U* D# ?) Y% l- @; x
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
$ n" g" z; N+ O& s& k3 A//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
( s+ H4 S3 Y3 D1 ^: B" Y3 p  @8 G//    lpCaption:对话框标题。
& p' ^' d. w7 `4 [1 r+ Z! I& l# W4 e+ s//返回值: 有错则为FALSE,没错则返回TRUE。
7 c+ c( D3 t0 n. Q8 M+ U7 @4 H% n////////////////////////////////////////////////////////////////////% I' h! a; t! [8 Z* {- Q
inline BOOL CheckHr ( const HRESULT &hr,
; V! t3 A% i) v/ k2 M        const LPCTSTR lpText = "ERROR",! G2 p; P% `# d0 O
        const LPCTSTR   lpCaption = "ERROR" )3 h# p& L* [; J$ c- e- j2 y
{1 Z: g6 ]% t- j- ?( [% w
   if ( FAILED( hr ) ) {3 |! V0 y  M  |
    ShowError ( lpText, lpCaption );/ m7 N% {# a/ z. c2 W
    return FALSE;$ }. c- X  U' F9 q0 q9 \
   }
7 H2 `/ w/ d- `5 C  F! p   return TRUE;& K' _+ o6 v! a8 L& ~3 }
}
' @% g; o9 r1 l7 @/ ?( `: T  C& t5 U+ k1 V+ H

( I. _& M2 L% C4 D- y& h///////////////////////////////////////////////////////////////////////
( Y; N9 K: g, }///////////////////////////////////////////////////////////////////////
7 b; R- A0 U* ]1 t/ s% R//! Z$ |3 g4 T( p: F: L
//         CTTS
2 u' u* F) q( R+ B! X7 t% F//' f2 f3 E- j, w, a9 J* B$ t
///////////////////////////////////////////////////////////////////////1 T  }* X( R; M. B, v$ z  A/ X
///////////////////////////////////////////////////////////////////////+ R) e0 a8 h  C% F
) o) o5 b+ N3 ^0 `
////////////////////////////////////////////////////////////////////
" o5 ]0 j, r4 e//保存关联窗口句柄。初始化COM。, K' O& v$ }* @, [: t; [$ z
////////////////////////////////////////////////////////////////////
/ t. A. U; r8 P" T% z- y' _. j" ]CTTS::CTTS ( const HWND hWnd )! {3 ?4 O8 U5 A7 W! j& o
{( y5 t& E* K- B8 R2 ^, O" V( P/ t$ o* M
m_hWnd    = hWnd;$ C6 F8 h% g6 u* t7 [  g/ B& A4 V
m_pVoice   = NULL;( K0 ?' j. F! K- i
m_pToken   = NULL;/ o# T2 a5 Y% P: y/ j
m_pOutputStream = NULL;
; Z" S6 b  C5 N! N. {2 k/ im_pAudio   = NULL;
1 n6 g- f5 r( ]) C4 a" j}
; h" E& v5 F. }) t8 u) H7 A( }3 [, [, }2 N+ q: W/ z: v9 @/ x' l
////////////////////////////////////////////////////////////////////
/ X# ]4 b6 y5 C! j) Z9 |% D  ^. m//释放所有对象。- v  {+ H0 d' p$ {
////////////////////////////////////////////////////////////////////
+ d/ b, o" h9 n5 G4 |CTTS::~CTTS ()) O( o/ k) f1 e% \, f
{5 ?$ o; J/ c, k) C; t4 G5 `
if( m_pToken) {
( @: Y  A7 c) K. T+ n, J2 {   m_pToken.Release();" W( q, `% M) M0 h
   m_pToken = NULL;/ B! ?1 @  c7 U0 S0 |; M# S
}) S; e8 Y+ f8 q$ l
if( m_pAudio ) {
' H' G! |" h) \$ |* F: r- Q   m_pAudio.Release();7 \( u% `" N- |& c
   m_pAudio = NULL;
8 d4 V9 X1 X, l0 r4 W8 j7 n}
. l5 a0 d* S4 sif ( m_pOutputStream ) {
) E/ N  S, }. Z- p+ A* ?2 q   m_pOutputStream.Release();4 X* i' A# H" j; L3 I8 B1 l
   m_pOutputStream = NULL;
  I- n! Z3 ]) u  Y}8 ^9 a  c8 ^7 f/ |
if( m_pVoice ) {
! ]% j8 `5 O+ N$ l: X' U: `% g4 L   m_pVoice.Release();) B; y' ?5 b1 s
   m_pVoice = NULL;
! m# V# w$ `9 \: d! y$ A  `}
6 P% I1 N3 I* f  f0 H" ?8 A; @1 D}
2 O7 }9 l+ }6 f% D8 K9 V5 [' x9 {2 E
////////////////////////////////////////////////////////////////////
1 \& t1 _' s& k) ?. F//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。6 ]) w5 P- V' a' O8 T' y
////////////////////////////////////////////////////////////////////
; B3 v4 m1 w) K; ~  A8 wHRESULT CTTS::Create( const CSR * pSR,3 I9 G. a1 a* C. Q/ y, ~
       const DWORD dwLanguage )! p5 x" Y# O/ u6 B6 U) X6 _) l
{
0 h. r& i" w0 X3 h! y! {4 z3 AHRESULT hr;
, p' Z% ?0 J5 e% K+ e$ {* Bhr = pSR->m_pSRContext->GetVoice ( &m_pVoice );
; A7 h- e. ^% x6 Kif ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {; P3 R& m# o: \# a2 _' c% C
   return hr;
: J5 c3 @- K+ ^7 [! \}
- o7 i3 R; j! @' t% N  T! c# q( k. M3 a/ r
SetLanguage ( dwLanguage );. s  O2 ~; H7 v- u

1 P* T: x% }3 S8 A$ Y. V4 q0 Vhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
7 n0 l) B1 v+ Aif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {( u2 g. q; K' K9 e5 o& }7 c% @$ g
    return hr;
- H- |8 R6 f; i8 h  W}
/ ~, o- T" Z' Z1 f' f; Y. g5 i8 \3 h
7 R0 u- z4 n$ T: N//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM' P+ s, j7 h" w1 U3 z. }* e8 R
//SPEI_END_INPUT_STREAM 表示完成流输出。
" _8 X; d1 B8 @0 [  a3 c3 Thr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |, q9 T, d* \/ B. V% k4 n# W
         SPFEI( SPEI_END_INPUT_STREAM ),2 V2 Q3 t; P! y. d' c2 o/ W
            SPFEI( SPEI_START_INPUT_STREAM ) |
8 p7 }& B" q* U            SPFEI( SPEI_END_INPUT_STREAM ) );
5 {  Q" Z2 ]9 g& Jif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
2 V5 V" e% p( ^* g$ `    return hr;/ z3 m, Z/ I' ~6 I7 a2 C1 `  p
}
0 u% M; D7 o6 b$ g# Q) G- D9 \, @5 ^3 x0 g" h. N
//设置通知消息% [7 {9 ?' i) H" H# ~. k! F5 I
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );& s! k& ~* |' r- B0 O
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
( U9 ~3 V2 U8 }1 e    return hr;
( y- {. Y6 _' w2 k& I0 y% g! a}
+ p4 P1 Y# f: V$ Q5 s- c" d5 j* |: e& M2 o
return hr;
& l- t( p0 \3 j6 q% r}
: O7 \( B- ?  w2 F0 ^# Y3 e3 L% c4 n9 N7 M5 {2 E+ h' ~
////////////////////////////////////////////////////////////////////) z( L( f3 f; T' g( y
//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
4 A% }- }1 Q2 D. `$ d7 `1 t//并设置兴趣,设置通知事件。
% i1 v1 n# X6 h6 D! z////////////////////////////////////////////////////////////////////5 g' `3 l$ H- _, b2 e( i7 l% C
HRESULT CTTS::Create( const DWORD dwLanguage )
5 e/ Q) R1 d8 f; a7 ~{
# [: |" U/ y6 U1 q/ G. v- qHRESULT hr;& T7 S6 W  F, B0 C
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );: L- Q8 h9 R4 W2 t: Z
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {
9 d  B) B, U& J  s' n0 g8 m   return hr;
( C1 D6 i) G$ W6 _3 @}5 u2 F# t9 N8 @; D: O
* `$ S( V0 F' I2 g# G1 `: D
SetLanguage ( dwLanguage );. e% b) n- I$ k! [0 |

; Q/ Z. N& T9 y* r% `hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流+ Y% z) x6 l0 f7 ~3 U. E
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
2 e0 T' f; J* G* A5 X- _    return hr;
* J, R: e7 \; H0 B% V# g}" `1 y+ `0 G& _: m9 B

, T7 ^$ W8 t4 x" P+ b" F$ K) w//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
6 y9 b8 ^: z% P  s0 l//SPEI_END_INPUT_STREAM 表示完成流输出。
# M8 g8 W% W4 b5 ]( v! G+ thr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |' U8 t; v  u6 a& e* R2 P! c5 r
         SPFEI( SPEI_END_INPUT_STREAM ),& a* H7 H$ d/ k7 ^
            SPFEI( SPEI_START_INPUT_STREAM ) |
$ Y  j+ X# C0 |9 X            SPFEI( SPEI_END_INPUT_STREAM ) );+ E2 b) ~1 j( l2 r0 ^
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {0 M  r3 ]( a, c5 M8 B7 R, J
    return hr;
) x3 K, ?( v' t}
4 I. x1 h$ x6 o# ^7 g7 Z& u4 _8 V0 X) [% Q: M+ S$ ?: Y/ I
//设置通知消息
7 l0 ?1 b, V; N; ?- B1 |: Rhr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
. Q" W) k  W7 U! M" N. Zif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {8 w6 U! E6 R2 V2 [) d0 q
    return hr;
% s9 R9 f' h( @9 k7 d}- s- Y/ [/ b; j. N# T& K

# j2 w: J8 `0 ]) x4 k6 Sreturn hr;) s8 h; H0 S- ~3 L6 \$ u# D8 `3 K
}
8 L' X3 x+ k$ H& y' S( w* x% @
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件1 u! ~0 b$ i9 u1 |' P' p
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
( V7 x& p% @! F2 r6 B( s. `9 m{) T% f, t6 f9 ^/ b* t; Y; p
    ::CoInitialize(NULL);//初始化语音环境" t2 Z: q8 s- S' b2 ?& K5 x
    ISpVoice * pSpVoice = NULL;//初始化语音变量0 [. b& _8 D& M8 ]& O: m( u
    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { 2 X# |" M9 Y) x2 g/ p# s" @% o
        cout << "Failed to create instance of ISpVoice!" << endl;
7 A! S5 N& w/ r. h9 P7 n        return -1;
% l' G# {/ b  F$ |# d# b    }

* c+ i. ]. g+ h8 i- C# h) P    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量/ K$ o) s$ G$ o5 w6 m
    ::CoUninitialize();//释放语音环境

7 U" `  O9 n& ~( G    return 0;6 E3 B( _  P4 g5 {. J# ~8 B
}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序0 D7 V$ m" u$ ~0 p2 B

; p# \. B* }8 `% m6 d1 V+ Z% y% F1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
( P% z. v- \3 G* l/ k' _. M- F2 g1 |/ O5 Z" [; ^4 V: l
http://download.microsoft.com/do ... -US/speechsdk51.exe   
4 X, M, B3 J- P& n8 ~/ iSpeech SDK 5.1安装包 (68   MB)       h0 F$ t6 n! ^
http://download.microsoft.com/do ... chsdk51LangPack.exe      # r9 U* r; v, k$ x
中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  ; s! v/ Z7 d6 B1 `
3 \6 x4 ]/ f  E# `& L, b
2.下载后,执行安装% Q1 Y# Y8 X" a5 Z8 o  V  B0 t) q) _# T
3 l+ y- \& V7 U0 h. i
下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。' K/ }' _' d& H& N

3 e! U3 r" j6 G* F  u3.VC的环境配置0 ?( g/ S( N- T; K3 E

+ V" N" E& D/ p在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
: I) j9 J9 T' a: g' d, q5 k+ Y1 a& @5 E( q: ^
工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.' ]! K/ k6 y! W* n; B* V9 \, c
2 f0 W5 P% q0 U4 M/ z+ `
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~9 K7 y7 Q8 e  M6 G8 b8 `6 |+ x+ v& s
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-6-18 04:56 , Processed in 0.019248 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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