找回密码
 注册
查看: 5665|回复: 2

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////
0 D' ?% J% ]: T7 N+ j+ S' J//1,生成动态连接库时,要#define USE_SPEECH_DLL,
: B+ Q7 z& Q3 u  q1 Y//      并且#define LANE_SPEECH_EXPORTS1 o7 U* w) O! Q# t; B- j3 p5 k" t7 ^# Z8 j
//2,使用动态连接库时,要#define USE_SPEECH_DLL* J/ `. W9 V$ {6 }5 w- |
//3,声称和使用静态连接库时,什么都不需要
+ R# Y# ?$ U5 {/ j  T//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),% i* L% l. k9 ?+ a& y
//      动态连接库就不用调用了。! M" ~! b& A* t0 }2 }7 Q3 ^# p: ~
////////////////////////////////////////////////////////2 [7 I) f; K; a- o
#ifndef LANE_SPEECH_H
  g- c# b- D$ v) V( P#define LANE_SPEECH_H
  l' L! ~  E5 O, K
- q; {; A! b0 I6 Y; [$ x/ ?3 e#include <windows.h>
" g2 n) Q4 Y5 B6 Z: n) {% u#define _ATL_APARTMENT_THREADED
' U& |2 p3 n/ W2 o$ x- \- m#include <atlbase.h>
0 Z2 d$ @1 Y2 K1 a( }6 O* 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 _Module2 \1 L9 h- y) r/ \! W: A, B7 W
#include <atlcom.h>
( x0 |% u1 p4 A' C#include <sphelper.h>   //sapi需要的头文件
+ S- F6 {$ l0 h. `6 j5 H5 _0 H* g- g# R0 V* R
//-----生成动态连接库和静态库的处理----------------
& k" U: P! q, t, L#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
3 ^1 ~0 V( i3 U! b2 ]- D4 {( c  m* `' v3 o$ [
#ifdef LANE_SPEECH_EXPORTS% V: T) G0 b* y0 R! s2 ^7 J
   #define LANE_SPEECH_DLL __declspec(dllexport)5 A: t$ d% j# \7 o
#else* T$ v5 R% u8 `" }
   #define LANE_SPEECH_DLL __declspec(dllimport)
; P3 x& [- a  G: Z  i) T( @" {#endif
2 n" V( l) C; y# t7 v7 y" [5 ?
- }3 c# c1 f& r' @  a! B, O//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关
* ^) O" l9 s  V: a5 K+ W% S. h//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。/ f1 }" d" ]3 s* f
#pragma warning( disable : 4251 )" ]! a9 @* f, S9 F  L8 R+ Q4 L

  B5 B6 `! }$ Q$ k+ c- d8 Y#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)" {# L5 A, e5 e" V
#define LANE_SPEECH_DLL# }& v/ F/ o6 N' E2 A
+ Q$ Y$ m' N' y+ }$ H0 @$ z/ F- J  D  o
#endif //USE_SPEECH_DLL  ^7 T! h1 Q3 F$ T. ]8 z
  \, G% v3 r4 D- P
6 o9 A" o+ H2 M. x% h: R/ i
//***************************常量***********************9 s, l/ {! f$ V' j0 M5 {
/ D. M  u8 Q; x0 P) ?
/////////公共常量-----------------
' Q- p/ z3 y9 u  G4 z. p  d- Hconst DWORD   SP_CHINESE = 0x0000; //简体中文.1 H' ]& h9 J4 R
const DWORD   SP_ENGLISH = 0x0001; //英语.
( k3 Z" g+ `+ }) d
! g( a- d3 _- u4 i8 W) `/////////CTTS常量-----------------
8 r9 K1 g% f8 O) k! f9 {( nconst UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。5 M' Y1 {4 k9 [- m
- o4 o; p5 i& [
/////////SR常量-------------------
0 l# Z$ c" _- c: iconst UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。8 e; z* u+ Z, r. w4 h
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
% k( v+ a. Z3 i; Pconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.
& l7 C: {1 G) \- O  a; q2 s$ r+ Y, e% f9 s( D- p
//以下常量仅作例子用。; p' @  C: C! d2 ~! H
#define VID_TopLevelRule 9000   //顶级规则ID: v1 T& i4 L  O# Z' U
#define VID_SubLevelRule1 9001   //子规则ID/ n# k; z7 H( A4 }, U: h5 R
#define VID_SubLevelRule2 9002   //子规则ID6 a, ^6 ?% w/ a+ H. _
#define VID_SubLevelRule3 9003   //子规则ID# f9 n9 Z$ z% K3 j: R+ D
8 e9 J  {6 d3 ^- d
: w6 x' n: e; g; Z* @! v4 Z* f6 H
//*************************类声明************************
2 f. r0 t& @: |: e+ Y9 z/ c, H4 `
# V; {/ e" w6 K: P* J( B: \
# L; d1 v9 k7 a3 t5 R2 Eclass CSR;
1 {9 `5 F6 ^# a1 P/ r1 `* J///////////////////////////////////////////////////////////////////////( q1 g1 ~* y+ K# {, d) Z
///////////////////////////////////////////////////////////////////////
# F( [  Q% ?# _  G0 i//
3 F; \8 L5 N0 }/ Z//         CTTS
8 o) k' y# k; F$ {8 {3 @7 a7 \; x# g//
0 O! w$ b0 Y/ X( g3 c1 [; P- b///////////////////////////////////////////////////////////////////////
$ ]  _- b' ~* \7 U///////////////////////////////////////////////////////////////////////7 i5 j' y; W0 T' P5 T* J+ F5 `3 y
# ^$ ?5 y9 [$ d! y5 i) h
class LANE_SPEECH_DLL   CTTS
- K; |* B0 A* V: w* V{
; G3 T! r) i4 f8 y; w: yprotected:$ @2 b3 [) x; G; V& U) g
HWND       m_hWnd;     // 关联的窗口句柄。
, Y4 s$ J* m  S" E7 d! u3 P  n- X, [. g2 b
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。  S* a! J/ P3 C0 b* I
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。: y( Z$ F" }/ c% M; j& A9 y5 @
CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)& T3 f  T, n# _+ S% C
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。
+ p7 g" N% d! \9 o* h/ m! G# P; o! U  A4 P) f" b! }9 p
public:
# ^$ F7 I) I4 G6 t# I//********************************初始化部分********************
7 |  Y. F+ R5 q! T+ Q' q9 M. Q, }# B( V! A
////////////////////////////////////////////////////////////////////
4 c- x6 X$ a3 }! F9 J3 w" H  k' P! s//功能: 保存与识别引擎关联的窗口句柄。4 B$ q' V- v' w
//参数: hWnd:要关联的窗口句柄。
" g$ Y% p2 ^' w& k5 ^//返回值: 无。) h9 u% X" T) A& q
///////////////////////////////////////////////////////////////////// c8 Y3 _2 @5 q
CTTS ( const HWND hWnd );
- Y2 y7 X( p+ T( O1 K' `0 {) s; h7 w* ], V6 W4 p
////////////////////////////////////////////////////////////////////
2 X( n( @% Y9 ]) D* @2 M/ V! z//功能: 释放所有的对象。$ h# h1 x% s2 o9 i7 ^$ w
//参数: 无。
6 m" \# l/ E# z2 h" q//返回值: 无。! M; j0 V* |& k7 q
////////////////////////////////////////////////////////////////////7 M; n+ S/ x. E2 R2 y# f/ O
~CTTS ();
5 ]' N3 W7 }  J7 N
+ U8 S7 C6 [  E$ d% \////////////////////////////////////////////////////////////////////4 b) l5 B* x  l# T& u5 K
//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。
$ N% e9 T; U8 J//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
  ?$ ~! n$ W- E) p9 C) d//    SP_ENGLISH为英文。
' r& U0 E2 u8 A! {+ F& Q  K//返回值: HRESULT类型。
  E( w) C$ H9 }////////////////////////////////////////////////////////////////////4 F% _' P+ j$ |# O3 n) C: Z1 B
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );. v1 c* ~! ~# N- L& K

5 v, b2 E) K* A: ?////////////////////////////////////////////////////////////////////
* e0 F9 h9 e7 e, F# m9 J//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
: f7 h8 `- |6 h* H' }# n//    通知事件。
  A  O& M5 [% \; B5 u$ l//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,) |" ]; q. `  K# @
//    SP_CHINESE为中文,SP_ENGLISH为英文。
# o) g3 @# ~& X2 h: F//返回值: HRESULT类型。
% x5 g* t0 U& S) J. `////////////////////////////////////////////////////////////////////
; }! f( ~+ ]: X  j7 ^, y( o2 SHRESULT Create ( const CSR * pSR,
8 Q1 O" z2 n/ e* Y       const DWORD dwLanguage = SP_CHINESE );: _1 R& c# ?5 S
" k& P+ N, z; Z# ^* k

8 A3 B, ~0 ^& e' D& c, G* f//********************************设置部分***************************************
6 o! }8 W4 q4 G" ^4 l/ r' b
- V  f( B' M6 T  S, j* n////////////////////////////////////////////////////////////////////$ E6 {: m  g" a0 q0 ^9 F2 U
//功能: 设置朗读声音的语言种类。
7 E- I  _! {+ y1 Y//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
( d% j' R  h; T. m% O7 X//返回值: HRESULT类型。1 E# ?( d( u/ V9 X" g; E$ n" f5 C
////////////////////////////////////////////////////////////////////( B% ]  k. K: H) w: ?6 l
HRESULT SetLanguage ( const DWORD dwLanguage );& ?6 `/ p; P; k8 t& M. `8 F

+ Z4 A6 \- b6 o' u% n' Q////////////////////////////////////////////////////////////////////
4 @& b/ B/ y/ m" {* V, A- s//功能: 设置要处理的的事件。" v/ `! A$ q7 ?. f  `5 l3 q- A
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,2 u% K8 C, E& E2 o0 S% M  v
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事0 `% p& F2 U1 |# Z& H2 w
//    件都会收到通知。5 O, c' z0 r- R0 H
//返回值: HRESULT。
- }, E& W0 N0 o  P////////////////////////////////////////////////////////////////////1 d: u1 c% U3 A$ u7 ~4 ^5 ~
HRESULT SetInterest ( const ULONGLONG   ullInterest );" }# w7 \" P4 \1 s  Y

: Q5 V  S3 X& n3 H5 `" D% X, R$ k////////////////////////////////////////////////////////////////////
' I7 F* o0 |9 @9 @$ g2 Z//功能: 设置朗读声音的音量。
# R0 y0 M( X0 G) z+ ^  M9 e- m//参数: usVolume:音量数值应该从0到1003 C6 p) r  `( z" E% Y
//返回值: 无。
0 K: X9 g5 n% H8 o////////////////////////////////////////////////////////////////////
/ z0 V2 M' S& a" D' n7 D: x6 Mvoid SetVolume ( USHORT usVolume );% d2 R: n( p" H. F
' y9 {9 O/ W" |% x9 j% e
////////////////////////////////////////////////////////////////////
3 F2 F$ L: J  }2 J& b1 }+ O8 P% F//功能: 得到朗读声音的音量。
$ V- ]9 f$ C1 H5 J% M1 [7 a. D//参数: 无。
  |9 G8 _: E  U4 u- P: a//返回值: 音量数值,应该从0到100。
+ D. ?/ U! f$ f6 A* O////////////////////////////////////////////////////////////////////
1 v, |  y' X4 B1 OUSHORT GetVolume ( );1 k# `7 f( e* K! {

! k7 `4 |( j% |# w7 O////////////////////////////////////////////////////////////////////
+ ]2 U  r: n& y: b//功能: 设置朗读声音的音速。  c% x! g, _  |) p* K
//参数: RateAdjust:音速,参数范围从-10到10。
7 k# O4 d) I$ @7 Q5 b//返回值: 无。: g- q4 w# E; y
////////////////////////////////////////////////////////////////////
1 Y" N! I5 y% O1 `void SetRate ( LONG RateAdjust );2 [+ `% Q5 ]0 {
& o+ v' j& R+ R3 N5 o& y7 N
////////////////////////////////////////////////////////////////////: o' P" r/ F: k. J. ~& o
//功能: 得到朗读声音的音速。
2 C# Y6 I; N5 u' h4 s//参数: 无。: z3 `7 w$ R: [7 x
//返回值: 音速,参数范围从-10到10。& H+ t" D' m1 t6 C) T( q! @
////////////////////////////////////////////////////////////////////7 E  S( P" s/ s* e' f3 G/ p1 Q
LONG GetRate ( );  T) V$ t  c8 Z# S2 |( Z5 c

  l& y* G/ k8 P4 H7 W% G# R////////////////////////////////////////////////////////////////////3 a, S+ S  |$ L: R
//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。$ j- c8 X+ j& @. H: L
//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
/ ^- Q4 k$ P+ w$ a//返回值: HRESULT。
( \+ w$ O% S' l6 Z+ J////////////////////////////////////////////////////////////////////* d' H8 m& a  |" n  W, O! y
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");
3 p% M5 k9 G" s& G7 q8 p2 x" [+ u
////////////////////////////////////////////////////////////////////+ X3 M" D  r* X! j& H# ]; I
//功能: 设置朗读的声音从音箱输出。4 m9 g4 y# }( x( D2 }. V' z4 v
//参数: 无。
) Q7 v6 C# J% I" O( z) b" b//返回值: HRESULT。& ]$ Y' D7 {6 l3 V
////////////////////////////////////////////////////////////////////+ f+ M( p0 k% y+ Y' w& b9 s; V. K
HRESULT UnSetOutputWithWav ();
  i) T) M3 u( ]3 q0 N
8 i, Q! a6 H( f3 U5 ]0 H6 C* c, t  D6 k) i$ C
//**********************播放语音,文本到语音转换部分*****************************
. T7 k  Z) @, @5 f) f; u% [; q& J$ b5 r. @, {
////////////////////////////////////////////////////////////////////
. c$ K0 e# o: [6 _7 W//功能: 停止朗读。如果朗读为同步方式,则不能停止。
" Z/ U6 G& T, f1 @1 w; B& X//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
1 C: g1 x2 `6 E: s$ ?//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
5 S% s* p) M" o+ |/ W//    SVSFIsXML为朗读带xml标记的文本。
5 @' R) \/ N9 B* W  r0 R//返回值: HRESULT。
+ c: \6 P1 @' F( f$ ]! Z0 ^: W////////////////////////////////////////////////////////////////////
  ^8 `( ?2 [1 ^' _7 d6 ~( [HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
8 S4 V, P% e( b0 h4 s% X6 v3 h+ L; A1 A
' Y+ T- K5 `& j////////////////////////////////////////////////////////////////////
, B0 i  N, z8 \//功能: 停止朗读。如果朗读为同步方式,则不能停止。
) O# X+ D" l1 O0 u/ I8 N' U//参数: 无。* X: M5 L0 b9 ?
//返回值: 无。( B5 t) P/ \( y2 l
////////////////////////////////////////////////////////////////////" k, z/ U  J2 s' r
void Stop ( );& F3 x/ ~+ e& R1 z" o! z0 d; J+ [
$ x" y$ j; X9 m7 J7 [# E
////////////////////////////////////////////////////////////////////
8 F2 w' K1 Z" H: P3 m//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。- R2 ?9 F8 _+ u* O/ V, K, U1 o; P
//参数: 无。
' l4 A8 r+ D; W; V: T+ `4 P//返回值: 无。
5 V( T9 K. M9 T0 I/ i, G////////////////////////////////////////////////////////////////////! ~5 Z( p! c0 Y) Y
void Pause ();
4 N2 J. T0 [0 W& z( _) R
; k+ J9 Q& a* A" j0 j. k////////////////////////////////////////////////////////////////////
7 N1 t8 n' f, m: d//功能: 从暂停的地方继续朗读。
; q8 g& O: U! D2 x  ?//参数: 无。" v, a- |' c# X8 V# ~) g/ d
//返回值: 无。
. m( l4 l: o2 o2 ], T+ z$ R; U////////////////////////////////////////////////////////////////////
3 T$ ?5 _5 j6 Y0 W" ]void Resume ();
4 G. \$ N1 S1 {0 g8 t" ?; f  @& H1 P3 r

/ @- K. }, P' _% }' L//********************************处理事件部分***********************************, b; r/ `2 r4 f' K+ ^
8 u; n0 e0 G, U, [0 u
public:9 g2 W/ n) f; x" e9 e0 L
////////////////////////////////////////////////////////////////////, l5 X* l& i' T) |! \. H7 Q0 u; l: \
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
- j1 m# j( z9 ~7 z/ ?//参数: 无。$ E* A& a5 \4 o/ t9 I/ V
//返回值: 无。  `) m, G; x9 s0 |
////////////////////////////////////////////////////////////////////, P1 }. ?: S; n) Y$ J' U; ^
void ProcessTTSEvent ();
. _& P: n8 E; K2 x5 b* _# [! x! K( V" o- h* R( ~7 Q

. o+ K- t% f- H; r) I5 P////////////////////////////////////////////////////////////////////( ^+ m- M  E  Y
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
/ \6 b2 C; Z+ n2 }% t4 R6 {+ e//参数: 无。
  ^& H, ?7 P; k+ E) @: n' j) W//返回值: 无。
- i. @* @! O# P2 U" H& i1 J////////////////////////////////////////////////////////////////////
2 c0 h) z8 }0 {( G3 G* f$ [  lvirtual void OnStreamStart ();! A2 W8 l, ^+ W% L
3 w# A$ Y( u: @3 R1 v) {
////////////////////////////////////////////////////////////////////
1 e2 `$ y+ h2 I1 K+ l//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。7 n; {7 n/ {& n# K2 i. \& G7 x
//参数: 无。" ^% s4 {, t. D# t
//返回值: 无。
$ k, O6 T& \8 h  L1 W////////////////////////////////////////////////////////////////////( U* b! M1 h  Q
virtual void OnStreamEnd ();
/ A2 ]( Q( l  g};
& n- Z5 q% I/ i& }; m: R( M1 r" G; G9 A( L- g

9 Y: Z$ y& n$ _& z- F///////////////////////////////////////////////////////////////////////' R" f/ t) @; Y/ A) ?1 z
///////////////////////////////////////////////////////////////////////7 m1 W/ W' @. D- ?* d+ |$ z$ V% w
//         CSR9 q) p: A' n6 ^  U( ]5 u- [
//
9 o+ X! @8 F: b  O9 l  i. S. c///////////////////////////////////////////////////////////////////////2 q/ F2 k/ Y& c9 U
///////////////////////////////////////////////////////////////////////, f) q+ Q$ z2 r8 `
# O0 L% `" g+ ^' L/ v
class LANE_SPEECH_DLL   CSR
1 L1 `3 X7 u. ?6 f: k; h1 G{* E3 B6 C) d1 [! A

4 q  \; \. Z$ a: y0 }" uprotected:# W8 y! n" w( E  _6 {
HWND m_hWnd;6 ]2 `( K* h; Q" d

& I4 f* x; Y; G1 o! H  u0 epublic:
2 S- B1 h7 E9 E1 v" e: T4 s. T7 R. BCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。  N) s* b: |/ V, k. H3 V/ t. x
CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。: z2 t3 O9 K- l
CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。: Y8 R0 |& V( J  R- ^7 \
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。1 L( ?3 ~$ l( ^
CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。
6 c0 ]8 c! j* d! Y* d7 \3 }CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)( X( f. X% S9 u) d2 d
public:  j0 v3 o6 N6 l, G0 W' w
static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。
% X# v( x. k! [: `1 m. H
8 u0 D# Q: L" |& [  E
% T/ J: K; d& u3 ~9 Zprotected:8 P% d( h  z  [1 K/ L, ~) P
//***************************辅助功能部分****************************************
. v+ Z  i( f; a( r. D* ]: T# ]
! x& B, q* J! M7 W! O$ o4 B////////////////////////////////////////////////////////////////////
7 E  m) F* O& o9 m% A- c//GrammarID加一,每个GrammerID必须不同。* V" d! m: ~" C8 v& R
////////////////////////////////////////////////////////////////////
! Y( y$ g/ J" V2 S% b2 V, Cstatic void UpdateGrammerID ( );
/ b  ^4 v: y* P8 D+ M* N9 f$ m$ \+ q) u; m9 E
9 [2 |6 w( X2 ]! @( E' ~
public:& r+ S# n1 n% D) z* E, w2 \" g; m) p
////////////////////////////////////////////////////////////////////6 s) M& S! s1 _: }
//功能: 友员。TTS中的从SR引擎中建立voice对象。! R" k2 Q5 W1 p. n
//参数: pSRContext:SR上下文对象的指针。
9 B5 t+ a5 g- @7 b//返回值: HRESULT类型。8 x% N9 w6 Q$ P* V* Q) B
////////////////////////////////////////////////////////////////////
) v' o8 S' @; `) vfriend HRESULT CTTS::Create ( const CSR * pSR,) S/ c+ l' `1 t0 ~. D  e" P( P* ^& K
          const DWORD dwLanguage );# I9 s& M4 X7 y

$ `2 \! k" ~. C& \3 D3 D
$ P* R8 [4 z# S2 D" f$ a) [4 v7 z//****************************初始化部分*****************************************4 P' n% S! ]+ H! G' L

3 U4 F+ v  i# _+ w# S. P////////////////////////////////////////////////////////////////////3 q3 D$ z; }2 h  q& _2 @
//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。
# O' V* \* X0 z+ L/ [+ ]% b. m//参数: hWnd:要关联的窗口句柄。( N- d5 N7 |: O0 R
//返回值: 无。2 v* |) ]0 h( Q% @  G/ J6 l, u: \& U
////////////////////////////////////////////////////////////////////
1 [( d5 j% l0 M; u, CCSR ( HWND hWnd );
" A) l" d! ~+ R* d
# J7 ?3 v1 Q$ Y4 P+ T4 R" ~////////////////////////////////////////////////////////////////////# L$ g7 ]& _; u0 i5 j
//功能: 释放所有的对象。0 |- C' S) `/ N8 |9 ?3 }: i
//参数: 无。0 K  Q" L% i, f6 F
//返回值: 无。$ h8 {/ \- g) A& b1 V. {2 V% h
////////////////////////////////////////////////////////////////////
" f5 ?4 v8 p2 g2 b~CSR ( );' w/ J9 ]- S: T7 }0 @% Y+ \) X
  P+ r/ h, A1 X7 \( s) N- c
////////////////////////////////////////////////////////////////////
; j: w7 B, m; ^' z//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,6 Y0 D( M0 E* g$ {
//    加载文法文件。3 D: F4 C5 O' {; f
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
; t* b7 K. p. `( z//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
- b/ y8 k3 G4 h' s" @3 E# u+ f6 A//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。) H2 S' L. H* @$ F: j
//返回值: HRESULT类型。
: `. v5 W# D3 l/ h. y+ m; Z8 C////////////////////////////////////////////////////////////////////  V) i7 Z5 B8 W2 ]5 [
HRESULT Create (const DWORD   SRType,
$ {  o% n/ R, {  i# ^      const WCHAR   *pwcGramFileName = L"grammar.xml",
* V2 M0 d% ^4 X      const DWORD   dwLanguage = SP_CHINESE );7 y2 d: n6 d# [3 A, [( h
  r: m3 D1 u5 k9 N* L6 b# v- Q
: _) B) G. X/ c+ g, X; t
//**********************************设置部分*************************************, u# N" h' O5 S+ v* G
- _+ w5 |" K* f  [! }# f$ h8 i% ~
////////////////////////////////////////////////////////////////////% U0 B3 j& h4 R* F
//功能: 设置要处理的上下文接受的事件。2 S" R" M/ e* G; @/ N6 l
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,7 ^( X) [! @" m4 y
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
9 d' k, ~! S8 B//    件都会收到通知。2 Y- G- p! Y3 b- Z) n; t) o6 L
//返回值: HRESULT。
' a5 \; A) [- S0 A, C! b2 j5 Z////////////////////////////////////////////////////////////////////3 D/ H/ ^- w. i2 w
HRESULT SetInterest ( const ULONGLONG   ullInterest );, |. K9 W. e7 Z8 h
8 z& ^! {) [# x/ S/ |7 D
////////////////////////////////////////////////////////////////////1 |$ {6 E2 p* b
//功能: 设置某个规则的状态(激活或者取消激活)。
$ a3 j8 D( n9 t9 E) x4 @6 i4 i- a//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,
" B! A- ]2 t7 k5 U; E, o2 j//    FALSE表示取消激活。. s; y( l7 q  K/ c
//返回值: HRESULT。: a6 l) |  O9 P
////////////////////////////////////////////////////////////////////0 X8 K$ J& [8 T5 e2 I  S9 R& [
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );! y  z% d. K. P
! x, e5 Q! R: f) `0 ?$ s' k

* ~  w4 Q' o- a$ R2 L0 T8 R1 \; V////////////////////////////////////////////////////////////////////
. q% u! V: E7 i3 F5 Y//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
% T" y+ d/ E( [3 ?! K+ t//    风输入。
6 A# P; w/ s% s$ W& L) b3 N//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。& S2 g. _# d' s, N& R; P2 n
//返回值: HRESULT。
$ h# E6 R$ h. ~1 x7 d* P////////////////////////////////////////////////////////////////////5 ^+ B% ~! C8 ~) p
HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );# ?/ z  h3 m/ X/ B8 x
, t. B) X8 D9 P7 p7 c" g' h
////////////////////////////////////////////////////////////////////
7 }" K( J2 K4 K: s% |//功能: 取消从.wav文件识别。恢复从麦克风识别。
, _, X! U" ]8 p% ?9 \! [//参数: 无。% T) y, a  e6 I  J: b" f+ C; \! o9 p4 s
//返回值: HRESULT。! K3 F, g# O6 o2 U
////////////////////////////////////////////////////////////////////
0 q  D# n8 H" E0 `HRESULT UnSetInputWithWav ( );
( e* S; ?# l' j) y/ p2 M; C" P
: d$ _  L5 r; f% G+ T//***********************识别开始,结束,识别结果的处理**************************
" @  |8 N& ~7 d& D: K: c" x" K
9 r( {2 g2 n% v+ {# D////////////////////////////////////////////////////////////////////( D& @2 }% l9 W7 J+ v
//功能: 识别开始(将所有规则激活)。6 D+ g; _6 V! D$ t* w. V. z$ v  J' z+ [9 n# q
//参数: 无- e2 J2 O: ^. L
//返回值: 无。
7 B' h, }$ _8 f5 @, ?1 w////////////////////////////////////////////////////////////////////8 M& B1 \( p* ?, _3 }* N1 |5 g
void StartRecognize ( );, j% ?8 T# c0 y, y& @
+ \% c- K; B' p3 @
////////////////////////////////////////////////////////////////////6 @" }3 R. F6 }! U5 g, p: h' M
//功能: 识别结束(将所有规则取消激活)。, d. l" M7 z4 @- ^) i0 M: p
//参数: 无。# I' R2 G/ c. T  g3 l; R
//返回值: 无。
: q  K- ~/ K. R" t- [6 v////////////////////////////////////////////////////////////////////$ f; h7 M  K, }! N; M5 G7 |4 ]6 q
void EndRecognize ( );9 a# X+ Q5 ?8 Z/ F- C' @' g
% U9 I" p! t6 J4 \; a2 C. i
public:; I; Z* r$ T5 r8 S9 Y  h
////////////////////////////////////////////////////////////////////
& a' e% ^* @* @4 h4 }5 h//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。  e" I( `+ H) l  R
//参数: 无。
: Y+ R% `* S0 P/ b//返回值: 无。
: K5 y! l" `+ R( n////////////////////////////////////////////////////////////////////+ S# p# r2 C$ H
void ProcessRecoEvent ( );
1 d1 P( _6 w8 m1 h% Z, f9 ?
! p. D. d  W- T8 v/ \% Bprotected:& o" t/ L8 V$ N& X+ q
////////////////////////////////////////////////////////////////////9 N' l" u9 r& _7 v8 D" H5 ?0 ?" h
//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。
8 z: f# j% a9 |0 R5 T7 S, X  s2 C//参数: pPhrase:ISpPhrase类型。
( ?3 R$ ~% ^4 F2 S( H//返回值: 无。& {* D- t6 |( k& @& w
////////////////////////////////////////////////////////////////////
4 }8 y% L. Y* E" t9 ivoid OnRecoSuccess ( ISpPhrase *pPhrase );
9 c" A! s1 V' ~  Q
2 |% Z9 f5 e5 E; e9 tpublic:
) i$ W: y5 T# d/ p////////////////////////////////////////////////////////////////////" P, e* g8 |8 |! c* m; P) q
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
0 ]* S) L1 \( N//    需要在派生类重载。规则ID必须以常量形式预先定义。
1 ?+ u4 n, }% R, _0 I' B" [//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。! P$ f- ]9 t9 {; t& ^( n: z
//返回值: 无。. a7 o- V* ^, S" d
////////////////////////////////////////////////////////////////////
( j0 i3 K2 k/ T  ivirtual void ExecuteCommand ( const ULONG ulRuleID,/ E, [: {/ ?8 R+ d# i% q
          const ULONG ulVal );# P: V, c; r! ?1 I: a
" M8 Q( b- B% L. K7 t. S
////////////////////////////////////////////////////////////////////& r/ z$ g  }* r+ u
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。  ]/ o8 R6 L# L
//参数: 无。$ t7 D" v  M+ ?  n
//返回值: 无。, V3 T, h$ l# q# x
////////////////////////////////////////////////////////////////////
9 F' P9 M3 N+ V% Z# J5 W8 l  Evirtual void OnRecoFail ();$ p# u6 x8 x+ s& `; |

8 s. U! C% D; y3 r2 r: N7 G////////////////////////////////////////////////////////////////////) B8 M# K8 ?: n! f5 O7 w
//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
4 ^$ X/ n6 J0 W//参数: 无。
) E0 Z+ c8 k$ i- W: m- h' K1 }5 g//返回值: 无。8 c+ i8 u% m3 H- }* h9 M2 L
////////////////////////////////////////////////////////////////////- |7 W  R7 a! u; q- z5 |" z5 b
virtual void OnStreamStart ();9 B# {% y! {' ?' z* R9 N0 k

9 _# ]* h2 H8 ^) e5 Z1 [; ?////////////////////////////////////////////////////////////////////
9 X) s/ S9 h8 D* L: {) \9 v//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。* |  w' Q0 w( g! f5 K+ z
//参数: 无。
5 a$ r/ u; G7 o& M3 [" C; f1 w//返回值: 无。
0 M7 p3 c. q9 J  d" x) X////////////////////////////////////////////////////////////////////
3 t& H* b6 K2 i5 g7 D0 J1 F( N$ Zvirtual void OnStreamEnd ();
0 ?: j" r" |9 D; n  z* y! u3 ?5 Y' f! X
};' V* {7 R- H4 l, l& c) T
! j! Z. p, v2 u/ }

, S0 N* V0 z* `" v; L3 F: s7 W# O9 D' ^6 B9 `% E- ]+ ~
#endif    //LANE_SPEECH_DLL_H
% I% Z7 O1 }+ d4 S+ [; C5 N  P% D: @# g% C9 ?+ O) h. V
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
* H( G2 A8 t. z. f" a  A
; t/ a% h# E3 R# W  R2 V////////////////////////////////////////////////////////
- {3 ]/ [: O4 v* [; H/ g//
, k- @* W. S* q9 d% Y// 文件:LaneSpeech.cpp$ y- Z/ S' a. f1 W# s: h! v, @
// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能4 s( z2 p) O3 D) f, ^1 h
//    语音识别只支持命令模式,不支持连续模式0 G) P/ c* l& o4 r
// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 36199086 @& D5 C# U/ Q; q' L3 Q5 b' y( D
// 日期: 2004.100 X3 Q* j1 |0 i3 p, j) Z& B
// 版本:1.25 T# X7 @& L$ p: v& }
// ( K8 q0 i2 @% t- ^$ M' X
//
+ C5 z$ c" h7 h- U////////////////////////////////////////////////////////
2 q7 H3 r2 t8 l2 s* {" K  `( w4 E0 ?! G# |/ \3 j' m: A9 x
+ Y9 Z: F4 M$ _: B# R
+ L( K+ X) q8 z
#include "LaneSpeech.h"
1 u# j7 b4 U0 f/ F- D/ y# \( W1 _7 o( E2 t1 i4 z% I: i& I
//-----生成动态连接库和静态库的处理----------------
2 s! z8 X4 `3 V1 h#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
% Y- U2 o: r& o' n& w6 t4 L% f/ ~! Q9 p, ]3 g: P# G) w
BOOL APIENTRY DllMain( HANDLE hModule,
" E# T1 i' K* o4 P& M                       DWORD ul_reason_for_call,
& r/ ^4 L7 m8 t( @' N                       LPVOID lpReserved
( [, n% \, j- F      )+ _% J+ u: D( W. K. G( m
{
3 R% K5 q" i: A1 C9 I    switch (ul_reason_for_call)
9 J8 a7 q! E2 G( v; n; b& L/ O{2 P/ m, j0 t6 T  C, C8 E
   case DLL_PROCESS_ATTACH:0 o9 r/ z0 c% I6 U& @# s/ i
    CoInitialize(NULL);# [$ n! k8 X  G3 I  F8 R% j
    break;  z& a, D# F- o/ D! T9 x$ X
  
$ d2 E- v4 k! W# s& k   case DLL_THREAD_ATTACH:
2 ]0 o& @0 H3 d    break;
; D+ W1 B1 c) D- R  
; R0 C$ H% R  e; u   case DLL_THREAD_DETACH:1 g/ j, h% @" ?$ I, L
    break;+ ^; E% `3 w- @, `/ F7 T: w
  
( i# x- C: e, v* Q) K! X   case DLL_PROCESS_DETACH:
4 A% `, A8 B5 P3 X. U% ]' _7 b! R+ w    CoUninitialize();
3 d" R/ z; t- q4 K6 i+ x1 W    break;
0 X. M3 x* M: A" `/ e    }
; |. {4 d% z! S. }    return TRUE;5 n& X. `1 `/ s- T9 I. h+ v
}
# l) j0 b4 |5 x" |% V
% l0 P; ^. h" w#endif //USE_SPEECH_DLL
  ^7 S2 Z! ]; p" X$ C3 b+ r1 Y
- H) \6 I* h+ {+ x, a5 g
  ?6 S* k' f) W* B7 [% Y
; s, |' }" |4 @///////////////////////////////////////////////////////////////% _5 J( n- B0 B8 p2 s3 w
$ X# t+ p8 s( P) d+ S
////////////////////////////////////////////////////////////////////
/ u8 ?' Q* B2 d2 r7 r" v: p//功能: 弹出一个信息框。5 H- R" Q! O9 l* b3 a+ |
//参数: lpText:是对话框信息。lpCaption:对话框标题。
" g5 Q" i; X1 X! Z3 A6 R//返回值: 无。5 I( T# u& n  R  G
////////////////////////////////////////////////////////////////////; b( Z! k4 F0 f
inline void ShowError ( const LPCTSTR lpText = "ERROR",
+ d. j, L9 g; }8 t- G        const LPCTSTR lpCaption = "ERROR" )! `5 ^8 J. O. P& ~! Y( M* N. P
{
4 ?0 A; U' R" O1 ?) M2 H   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
( b2 n, I! G: W}
+ F2 ~: o, M; K) [# ~
& M6 C# z* e3 ^" z1 |* j$ g9 `5 w////////////////////////////////////////////////////////////////////
$ R' j& h7 m* H2 w) i5 I//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
1 e6 S& }9 O! ^& Y9 [: B- f//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。' U0 S' ~  @2 _+ D$ H* k
//    lpCaption:对话框标题。
1 q: g+ Q$ U2 U//返回值: 有错则为FALSE,没错则返回TRUE。8 f( y, G6 V6 ?" K
////////////////////////////////////////////////////////////////////# a* r0 V) {) Q0 _, C
inline BOOL CheckHr ( const HRESULT &hr,
; }1 X! j% e# t" W- [) H        const LPCTSTR lpText = "ERROR",
% `2 v! N$ a+ z2 w        const LPCTSTR   lpCaption = "ERROR" )
' x& y& X( [1 d+ j{
9 N* `: z' U- W6 N. x2 i5 @   if ( FAILED( hr ) ) {5 J1 M/ q4 A+ d: W4 b$ T7 n5 p8 {& x
    ShowError ( lpText, lpCaption );1 _1 K$ {0 K& W' i1 v1 V) w. {
    return FALSE;
, c- [" F. R4 H, _   }+ R1 [' Y% N; b) v1 y" m4 w
   return TRUE;/ x8 E- `9 q/ ]' _
}2 n( A  C+ U; t6 C

: K9 P) k& [9 [3 g) G0 j& T! F( T
+ t, M4 c) Z) S: w' B, s///////////////////////////////////////////////////////////////////////0 @1 q  }  H/ b' q
///////////////////////////////////////////////////////////////////////
4 I8 B0 l5 r7 ?  i4 z//
$ A% p' C( |' Y2 G- J8 t//         CTTS! }/ m* u( `' f3 @
//, O- k( r. q; U  o) g4 v
///////////////////////////////////////////////////////////////////////
% N/ ]  O' `2 T; r, \///////////////////////////////////////////////////////////////////////
4 W( o) [6 f8 b6 U
. V0 Z+ c0 s7 P1 J////////////////////////////////////////////////////////////////////
" T- `5 O5 L$ M+ n. b5 L//保存关联窗口句柄。初始化COM。) y" I' _$ W0 K& m# |0 m
////////////////////////////////////////////////////////////////////
' A- d+ d# w# C' mCTTS::CTTS ( const HWND hWnd )8 ]$ p1 j1 z, E- s, a* G! \
{( X' v) ]8 f. x
m_hWnd    = hWnd;
' V# h& J" B5 ~* V" K8 {m_pVoice   = NULL;% \+ L# j& A9 B/ q! \
m_pToken   = NULL;% h! g6 J& h' L7 ]9 a- n# d# j
m_pOutputStream = NULL;
# Q1 j3 L% X5 U8 E# m# d, tm_pAudio   = NULL;2 f4 q% S5 y6 Y4 W" l8 b
}- I! y, H* U5 i

9 M/ J; d" P- K3 K////////////////////////////////////////////////////////////////////( v3 ?2 G* E5 d- x" H0 d1 G
//释放所有对象。7 z1 Q+ @1 x, \6 h& q8 i. N5 d
////////////////////////////////////////////////////////////////////
: O7 \# O% D6 \$ m0 ]( JCTTS::~CTTS ()8 C9 D! X2 }4 M4 j. @
{
! D5 C- w" x8 A2 _! Q8 pif( m_pToken) {
: f4 U0 Y( I$ s6 F! B+ E, t: n+ }6 X   m_pToken.Release();, J5 H( `9 t% i+ v# l
   m_pToken = NULL;, ^" _( ~+ i' w/ A
}
' c( K: I6 g0 `2 G. M% Z$ \1 J) {# Aif( m_pAudio ) {0 ^. m* W$ J- ~
   m_pAudio.Release();
. C* ?2 B; o9 }# e   m_pAudio = NULL;# ^8 G6 u% e8 s
}: m4 g; d- \/ x. V' X' ]
if ( m_pOutputStream ) {9 i# ?2 Y/ S# L( N; z$ J! e$ A
   m_pOutputStream.Release();8 t0 T& y/ n8 J* x. i: k6 w7 z
   m_pOutputStream = NULL;
( p$ k  z, m/ Y4 W2 l}6 I+ l+ w. ~' T
if( m_pVoice ) {
! B9 c2 c; \, l% j# \: q7 B   m_pVoice.Release();
# Q& |: ?. X9 ?0 }" Y: E) \/ N   m_pVoice = NULL;
9 u; {0 v5 C: A8 |}! H) X& |# K0 c7 o8 g
}" h# D/ p% _, R7 U/ L/ d5 Y" Z2 _

* _- S  C, {+ D5 R. s) K////////////////////////////////////////////////////////////////////+ Q8 o. k5 M# U5 t0 \5 q
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。7 H+ C4 c* Z$ H" I) E' N4 S7 f, v
////////////////////////////////////////////////////////////////////
" M' D0 I# q: EHRESULT CTTS::Create( const CSR * pSR,9 _  u, _: X  w) L& E) S- t
       const DWORD dwLanguage )
, U. E% _- H& ^3 T! U$ K2 S- Y{
: K! d- ~- l" Z- D( _; `1 QHRESULT hr;
' L0 T# n* T. e2 }* ghr = pSR->m_pSRContext->GetVoice ( &m_pVoice );" g9 x- B% ?9 p
if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
$ [7 t: W. b. a! M( p7 E   return hr;
" f6 r8 l+ F' V* f7 `. j* z}3 ]6 f0 b8 Z' i( o
& ]3 g) `- e4 T, h) T( a  ^( ~
SetLanguage ( dwLanguage );8 A) h* w) D4 q% }3 U! M+ _; |/ ^

/ T4 `% B9 R9 p/ v# G/ Ihr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
6 Q& w5 ?) A; N5 aif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
. ~$ w' P" Q# s6 b2 k) l% v    return hr;( h" B+ K( i! h3 L; [
}! O  r! @/ |# r

7 H8 X+ `$ O/ \2 u5 t! [: V//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
$ X3 {6 g/ W) D) n//SPEI_END_INPUT_STREAM 表示完成流输出。* N8 y& T9 u( z: b9 y; J
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |. k. C, f4 K$ B& D
         SPFEI( SPEI_END_INPUT_STREAM ),  F& D5 ~. v2 g; K2 G
            SPFEI( SPEI_START_INPUT_STREAM ) |
$ U" r6 ?+ j6 q7 x; W            SPFEI( SPEI_END_INPUT_STREAM ) );
+ r  `* ]' ?: D) s3 _4 Bif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {) k- X" n! n2 j& q# M
    return hr;
; r: g( L) v4 Z) x! d* i# ]}7 `( O+ c" m- w$ B7 M8 v! |

( }" F& g( N  m5 D: a* ?: d//设置通知消息0 t" ]& J6 n% z
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
; f0 X2 c( Y7 M6 tif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
  }3 o& U  r" I2 Y" K' ?9 [6 k" g    return hr;' O) b; K. l2 S/ j+ i
}9 Z& P/ i$ p3 G4 ?

0 ^8 d; H: C6 b% t) ?return hr;
1 c7 w# N: D$ {8 G, O1 s1 r' x}/ _- d3 R: @% r( j4 O1 e
, ]  K7 y- D* M: M- z
////////////////////////////////////////////////////////////////////
0 M0 f# Z3 d5 E. D- {/ [//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。% \6 f4 g0 w: r4 h' z. T
//并设置兴趣,设置通知事件。
4 H. n5 l6 m9 ^5 j) T4 R3 j////////////////////////////////////////////////////////////////////7 p( i& t1 s- y/ @# Z
HRESULT CTTS::Create( const DWORD dwLanguage )4 p7 j9 c" j, T- `  }$ a9 e. g
{' O' W9 g* K; h; c
HRESULT hr;) y2 G8 y$ q3 E! ]$ L1 }% W1 P
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );' i" r# d, S. T
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {
9 n. }9 N9 w; U2 l2 ?   return hr;! ?) l! e$ {" ?, ]6 T1 e
}
( f" B: V0 d3 w, O+ f
: I5 E" y  @1 `) S. FSetLanguage ( dwLanguage );& d$ g& K- s4 ^! ^5 [7 o1 F: h
; |* g5 w, \2 D7 I/ q3 [3 p+ c
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流+ c" C: P  i% E8 g" C+ ?
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {# L1 q2 Q# t1 Z3 v4 W
    return hr;7 Y) K  W# E9 j9 K  T/ C
}
/ F5 U  ^# v! O8 [
8 Z8 }. H0 A; `* P0 N//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM3 {2 j, d# I  Q/ z" V, Z
//SPEI_END_INPUT_STREAM 表示完成流输出。8 f! Z3 _& N% ^) G  T
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
2 R9 ~  F7 v: D! ~. A% M+ i7 D' A         SPFEI( SPEI_END_INPUT_STREAM ),
  b+ N4 k; B6 X            SPFEI( SPEI_START_INPUT_STREAM ) |" g1 g/ S+ @3 V# ~  B8 `- T
            SPFEI( SPEI_END_INPUT_STREAM ) );/ H& Q) G0 ~! h7 M9 n
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {3 ]) p& J' @7 n. L
    return hr;" q" d" x7 G& J2 a- d+ C! q
}, a: |' o" }! ?/ t. h# v

+ m! C% B0 G; y0 n" c: r& h  W/ g; [//设置通知消息$ _* }" P1 {6 Z3 a. a
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
4 j0 t0 I/ A/ ]3 hif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
! W" n& Y3 \/ }0 [    return hr;+ {( ], z: V+ D( {. M8 M
}
; U5 f5 D# s/ `! [, x
5 a- Z; B, R/ B( \) Y, vreturn hr;
+ d+ N4 m: D* H$ ]}
. o6 r: b) B  Q; k6 r
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件
+ o1 R) \9 h5 d$ s8 Y#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()" P8 J  G. G3 x' Y  p
{) P5 e9 q6 B6 m' F0 V- m
    ::CoInitialize(NULL);//初始化语音环境
3 L# t5 n# h2 |4 q6 g) I    ISpVoice * pSpVoice = NULL;//初始化语音变量  E. c8 U+ f8 W% O9 f- z
    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { & D: U; ~4 S& D! @
        cout << "Failed to create instance of ISpVoice!" << endl; ) g0 p) @. }- F& ?
        return -1;
, K+ v+ q3 U" K: k" }+ @! j    }
5 B+ l8 J6 v) W, v
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量  c' i; b2 A' v
    ::CoUninitialize();//释放语音环境
, [0 V) _2 R. r* X
    return 0;9 m+ Q" y2 q$ E7 q3 T
}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序
2 p' J$ C' u; M+ ~/ Y" G
9 Q2 v1 {" d- }) o" w1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地  U0 P) M: d% q4 N0 E# ?

+ x& M3 L7 L# qhttp://download.microsoft.com/do ... -US/speechsdk51.exe   . d* v" B& t2 {& y9 {) |, m
Speech SDK 5.1安装包 (68   MB)     / o" v& T1 ~! I( u
http://download.microsoft.com/do ... chsdk51LangPack.exe      
% y# z/ b4 N8 O- g中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
1 V& Q$ D( x, d
  E4 ~# y$ \7 ?; g$ k2.下载后,执行安装5 [+ j7 t8 }+ G1 ?& M' F

# Z- t% R) a& e3 ^7 D0 w" a: q下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。% Q  o3 d6 t. Z" x

( j' |9 x8 C7 j' L9 G. j; ]( L3.VC的环境配置
2 y) |; q* {/ N8 K% W7 w+ U7 @* ~" f
! ]% M  J7 E( b# M, t& @$ F在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
, l; s1 i! n" a8 ?$ [- m# t. e& V& V7 v: G' u/ a1 Z/ A
工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
2 \# F! i) }4 ~: l6 _' X9 X0 f' S
" e+ r1 _) `0 H& d好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
# m- E+ W" P  p- [/ {3 l
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-10-1 23:06 , Processed in 0.019342 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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