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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
////////////////////////////////////////////////////////9 x! X# W. X+ f1 x& V6 E. b! r) i8 {
//1,生成动态连接库时,要#define USE_SPEECH_DLL,
' s1 ]1 o, L+ ~//      并且#define LANE_SPEECH_EXPORTS* B7 H, G: c. u1 i9 d
//2,使用动态连接库时,要#define USE_SPEECH_DLL! y7 s; f9 i# x  Q- H0 N' `0 L$ `
//3,声称和使用静态连接库时,什么都不需要8 v3 t% p) y/ ]
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),
# \6 Y; K; F8 f//      动态连接库就不用调用了。
! z" \8 Q9 }4 ]- x! T8 S////////////////////////////////////////////////////////2 L0 U. i: I2 ^! J$ l
#ifndef LANE_SPEECH_H
' V/ y) t  t2 |3 Y+ |/ R# l#define LANE_SPEECH_H1 n; H: }6 P. e
" z* ~" W5 V7 \  G- o  F
#include <windows.h>
9 D3 U* o- t# M! n* X8 q#define _ATL_APARTMENT_THREADED
# C( X# E0 Z) S3 v( ?#include <atlbase.h>
* N: {1 W8 I+ b! qextern 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
# [+ Y, _& D) T. |4 t; O#include <atlcom.h>2 u. h" }. C8 k6 ^  k
#include <sphelper.h>   //sapi需要的头文件
. P2 g) F2 Z0 v) v3 u
" X2 e: S% _, Z//-----生成动态连接库和静态库的处理----------------% U: X" h& h: S& H
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类/ m/ H7 d7 `$ L

* ]7 S# D5 A4 M; g; b; d#ifdef LANE_SPEECH_EXPORTS6 B7 z3 P, a1 j8 a+ m
   #define LANE_SPEECH_DLL __declspec(dllexport)" Z& Q4 C, i/ x& f4 }2 p! o
#else
: r9 v4 C8 L! X! d# p   #define LANE_SPEECH_DLL __declspec(dllimport)" y; M+ Y( A7 N9 z; t
#endif% L( [1 [5 Q+ S1 h( \

& `* w0 h1 J* \1 w4 `4 i; ?//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关$ E6 t) L! k2 Y2 J3 v
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
* n" z; w9 K; Z( V5 Q* |, p/ J8 s#pragma warning( disable : 4251 ). u" U! Z& {0 a

. j) R& R- X2 Y$ F$ S#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)
+ S' `4 F3 u3 g; `#define LANE_SPEECH_DLL
! X, K2 D, A: M9 o9 q& c# `" J9 V& _3 f% Y! l0 ?
#endif //USE_SPEECH_DLL* @  v3 H3 P' j
  i0 g3 F2 E, A! J; {8 Q
- H6 g) T( m" f, `
//***************************常量***********************4 @8 p: t8 t0 }7 a
1 l4 M3 X0 K3 o. Y% S7 m$ y
/////////公共常量------------------ _7 D) K3 s; S  N1 \- p
const DWORD   SP_CHINESE = 0x0000; //简体中文.
0 Y, }. B( o% b& q1 ]/ ?! wconst DWORD   SP_ENGLISH = 0x0001; //英语.# q7 x' \9 x; f' M) P8 w& }4 X9 Y

2 B" ?' u' X  \6 ?5 N& p/////////CTTS常量-----------------( l( ?' A6 [5 S+ g& l, o
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。8 f( {3 q, E5 @, I$ a, Z/ \

! U! k" ?, m. E. x( f" c/////////SR常量-------------------6 B4 H# ?% K0 J, {  @3 ^2 o
const UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。1 l: w% f0 D( y; R- y1 N( M
const DWORD   SR_INPROC = 0x0000; //独享类型的SR.
8 H) ~9 X) h5 I' s$ pconst DWORD   SR_SHARE = 0x0001; //共享类型的SR.! x" o1 w6 }6 |6 [

4 j2 T. J* A3 P! f# ^//以下常量仅作例子用。
. z) {3 d! b5 a8 N0 l#define VID_TopLevelRule 9000   //顶级规则ID
4 |* ?  ?/ D0 {#define VID_SubLevelRule1 9001   //子规则ID
4 ?1 X1 V$ N9 l& H9 g- ^7 s3 r#define VID_SubLevelRule2 9002   //子规则ID2 x6 J$ L7 a) U7 m; N
#define VID_SubLevelRule3 9003   //子规则ID
0 a. ^0 u/ Y# Y( |" a" D, j# r( K2 `' y( T, ^& w
: m% [% L+ l! j: H% k4 c
//*************************类声明************************' c6 A; y! }/ `# |5 N- F( v
1 [. O1 c" s, l3 b3 p6 z

7 H+ Z8 N4 N* `class CSR;  C( ^6 `) k' l+ O) m( j4 Z! r, d) h
///////////////////////////////////////////////////////////////////////
- {$ {! ^+ A, w7 ]/ P; Q///////////////////////////////////////////////////////////////////////6 V- \5 b0 u# C& ?+ q
//3 y$ L! `' |7 Y" J. F
//         CTTS
0 A1 A0 U# P6 n, b//% y" j# D8 @- E/ X& z
///////////////////////////////////////////////////////////////////////- D5 u8 {; `- T# i0 I  S8 Q8 g
///////////////////////////////////////////////////////////////////////0 M. a& K: T5 b: ~/ z- u

  P- X' a1 @9 J# N. B$ c  U) k8 ]class LANE_SPEECH_DLL   CTTS
' D2 T: L2 y6 M! ~6 r1 Q{
0 [+ b6 U; j& z0 iprotected:9 O1 S% I/ j& h- `0 o3 a8 |6 F
HWND       m_hWnd;     // 关联的窗口句柄。
3 z7 l4 p( G9 C& G$ K. P" d+ ^; J, t( {
CComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。
1 k. ?7 h( k+ h+ I) l* fCComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。
# }6 @7 X5 G1 H* z& Z. nCComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流)
- q9 o4 p$ Y& O* uCComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。- Z! E6 F. I/ n: v3 m; j

! U. z8 q" c2 N0 @5 Qpublic:5 i2 X9 c! z4 L1 E& }
//********************************初始化部分********************9 [& ~, D5 I/ y; ?4 e

5 d. ~& ~& g4 M1 I6 Z% ^5 \////////////////////////////////////////////////////////////////////
; ]: f3 o* K* V/ U//功能: 保存与识别引擎关联的窗口句柄。
: h& ?5 D" E; D/ I0 g! X) `6 ?+ \/ U//参数: hWnd:要关联的窗口句柄。
: ~1 |! r7 \6 u//返回值: 无。
- x- n8 p# |5 t$ l////////////////////////////////////////////////////////////////////9 R' W; `6 x4 O& U; o
CTTS ( const HWND hWnd );. m4 w5 Q3 ~7 o7 w8 N

% X- }: \& S7 y) `- ~7 ?# R. [0 r////////////////////////////////////////////////////////////////////. u: b, @* A4 ]1 ^
//功能: 释放所有的对象。8 B! Y0 r2 Y$ W! M
//参数: 无。1 ~% t8 x/ F8 k2 o
//返回值: 无。- ?0 s  R- u% x! x. e) N
////////////////////////////////////////////////////////////////////
& l( u9 @1 Z- ]~CTTS ();
: w0 \+ \% i: o6 |& k1 b7 v" L
# ^8 p3 Q: A6 H+ ^9 j6 z7 W////////////////////////////////////////////////////////////////////
9 }# E7 V9 L! g/ m( ]//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。7 ?3 R- B# Y8 k  j
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
6 G" z% H. i4 e& m8 {0 I: G& ^7 y//    SP_ENGLISH为英文。: P% t6 W4 k  k5 N/ S; e$ ]
//返回值: HRESULT类型。
' ?0 p3 o6 [8 K////////////////////////////////////////////////////////////////////# s1 h" B* H: z# u7 z$ a* r
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );
: Z4 ]! d5 m- A: f) f+ J; i, @/ u
% C4 l% d2 z) f3 @////////////////////////////////////////////////////////////////////0 `: a4 Z  u) s, f; Y
//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
5 Z3 c' o  v* l& z//    通知事件。/ ~; v: N3 k( X
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,
+ I8 x. E6 P( W/ n1 \4 ?+ u//    SP_CHINESE为中文,SP_ENGLISH为英文。
4 f" H6 o0 r( \' @$ \//返回值: HRESULT类型。
: E" g/ _4 D8 x! v1 P////////////////////////////////////////////////////////////////////9 r7 d. }6 `& B6 @  `* {3 G; i: }( ]
HRESULT Create ( const CSR * pSR,4 f5 m1 z2 J( C$ @* @# U  ]
       const DWORD dwLanguage = SP_CHINESE );( Q8 v' h+ T# V) g, y2 h+ b$ `

9 k/ T) [9 ~' k
7 V( K; E9 ]( Z# e1 H//********************************设置部分***************************************
) w9 r: G0 d! ?. f/ P: w% H6 \; k3 }* i' N5 R' ?, C: x
////////////////////////////////////////////////////////////////////
4 R  H- G2 U2 ~1 N0 U1 R//功能: 设置朗读声音的语言种类。
3 @  s; ~" Q7 P5 o//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。( C$ V; O4 }9 j; e' P! ^
//返回值: HRESULT类型。
4 A8 M0 o! C+ k////////////////////////////////////////////////////////////////////: {: S, d4 m  {* }8 k& w
HRESULT SetLanguage ( const DWORD dwLanguage );1 |( v2 i2 ?8 j0 X% Q, P2 a

1 }! C( G$ i# Y% Q0 Y7 c* d////////////////////////////////////////////////////////////////////. j' H, T+ r- G7 @# W# Z
//功能: 设置要处理的的事件。
) d3 K( r; |0 L2 X//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,* ^& Z- A+ J7 Z; i* P& i! e; r
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事- a" ?; ]  E3 l) a; E! j
//    件都会收到通知。
5 r3 I; J$ N6 _+ r//返回值: HRESULT。/ m/ B" S9 Z. o1 ~
////////////////////////////////////////////////////////////////////
4 p) M& X+ Z+ B! GHRESULT SetInterest ( const ULONGLONG   ullInterest );7 J2 g" e. v) G. q5 Z; g/ Y0 G) Z- h

! L4 X$ X+ l0 T0 Z2 l8 x. A////////////////////////////////////////////////////////////////////
! Q8 H2 E# l- a6 P//功能: 设置朗读声音的音量。
! M# \; P+ V* x# e/ Q4 C; z$ R3 T//参数: usVolume:音量数值应该从0到100& s. E$ M% {4 x4 u4 J
//返回值: 无。/ V  v4 w& e7 q- `* S' R* G4 S
////////////////////////////////////////////////////////////////////
3 `! u2 W0 ?/ s/ Wvoid SetVolume ( USHORT usVolume );
5 E) L0 j' b7 n; y! ~9 O3 N% g2 `7 ]( Q& F. O9 d) P, M
////////////////////////////////////////////////////////////////////
0 X  g+ a8 c* _( H5 s0 _& A# A//功能: 得到朗读声音的音量。, n: \& g# W# `
//参数: 无。+ W0 J; Z1 n3 A4 C1 c' H7 Z: U
//返回值: 音量数值,应该从0到100。- @9 R: ], Z: q1 u0 x7 u' E2 |8 g- P
////////////////////////////////////////////////////////////////////% k: }0 r/ f1 t& N# g' V# |
USHORT GetVolume ( );
, Z; a! j0 q$ J, q2 y, `
1 M/ F; d( S. ]) l/ H////////////////////////////////////////////////////////////////////& R5 I9 s3 _, i4 y1 W6 I) x
//功能: 设置朗读声音的音速。
7 O- v2 p4 \/ x. @//参数: RateAdjust:音速,参数范围从-10到10。7 F8 S2 a6 J* I* X8 [) S
//返回值: 无。: Z8 i& B$ F& r) l: F8 ~
////////////////////////////////////////////////////////////////////! n7 R* ?5 x, D0 U8 z/ c
void SetRate ( LONG RateAdjust );+ z- p+ \; _% W8 ~, V$ Z

/ z) a* B& }. R: d////////////////////////////////////////////////////////////////////
# c# s. o3 R$ k* [6 `3 G//功能: 得到朗读声音的音速。
& X+ b3 Q0 n  H! l6 p" e//参数: 无。
1 `+ [7 f$ f+ X! f//返回值: 音速,参数范围从-10到10。7 T: z0 |! \+ Q( _+ B
////////////////////////////////////////////////////////////////////& X3 l* Z7 X+ h9 ~7 C
LONG GetRate ( );0 D! \+ q8 n6 n2 ?7 c
: l7 b, i0 U; f, q, A4 u
////////////////////////////////////////////////////////////////////
8 U; O" m' n! Y- Z: n& p5 {//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
! T, E& z; {3 d) D8 y//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。) d- l' e+ |0 M' p
//返回值: HRESULT。
1 L, s  e$ G* U7 O) i" W, d///////////////////////////////////////////////////////////////////// m3 ~+ \0 I/ e/ B5 S2 p
HRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");* H: s) q! Z6 y

' g: y; C9 F" @2 K. l( c  a( v////////////////////////////////////////////////////////////////////7 j9 V* P/ a  G& _' S
//功能: 设置朗读的声音从音箱输出。5 d& V, ?, ]2 L" m# c
//参数: 无。+ _0 o- S/ [0 T9 T$ j
//返回值: HRESULT。& F- Q/ Y0 s+ }4 G+ C  v
////////////////////////////////////////////////////////////////////9 ?5 p; D" x  R: h
HRESULT UnSetOutputWithWav ();2 W+ r# ]4 ~6 c4 a; |, q6 X+ q; B

# O" ~- Y$ z: e) q( ?  ~8 T: h" ~! h: z! w. L4 F2 ^6 v3 ~! z! K
//**********************播放语音,文本到语音转换部分*****************************0 H9 B/ Q/ @9 X* w- E" @

$ v. M2 M$ e1 {4 |: g& k) |% @////////////////////////////////////////////////////////////////////3 R' }6 ?8 M. l, |) B! g1 _, n
//功能: 停止朗读。如果朗读为同步方式,则不能停止。
) K: a1 Q: x) d; ~3 a//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
# b& T* k& S; Z% x/ v0 i3 D//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,
& x1 m! v$ ^, D4 c' H//    SVSFIsXML为朗读带xml标记的文本。
* H! `& x* U. i- a' ?1 K! ~  `6 n//返回值: HRESULT。
; s5 S1 B7 W* k8 D8 V( H////////////////////////////////////////////////////////////////////
2 U( @- r( z; `/ PHRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );
2 @- }2 V: b2 A7 y+ D  K( P- y% q- H8 k* I
////////////////////////////////////////////////////////////////////
: |( _9 Z1 O  W//功能: 停止朗读。如果朗读为同步方式,则不能停止。
* c8 F# Q* c; M, ?( F, i: l//参数: 无。
" {8 X5 h/ D4 o' F/ M: ~//返回值: 无。  J. t% p% [; [1 V
////////////////////////////////////////////////////////////////////
  O' A4 ?- Z0 H6 P1 Mvoid Stop ( );" y% I( t& K; V) G+ r- I" i

. j2 _' {+ C) C////////////////////////////////////////////////////////////////////) ^/ r: `1 r- F6 X
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
3 p0 [& Y7 Q& c0 Z, V//参数: 无。" W; o" E5 j2 `+ e
//返回值: 无。
9 {  t# b( z( e" _////////////////////////////////////////////////////////////////////
, u! B0 z8 w2 e. M# Bvoid Pause ();. B+ z3 T+ p8 |: a6 r1 n) E

8 S: W6 }- [2 Q  T2 |8 W////////////////////////////////////////////////////////////////////) S0 A  `1 U% C7 _8 B% ?
//功能: 从暂停的地方继续朗读。. i$ |; G. U$ \( z% h, e
//参数: 无。
! [- |9 I/ U1 y. ]+ g//返回值: 无。
) m* m! F( g& V' U4 k////////////////////////////////////////////////////////////////////
( W1 O& a) |+ m  xvoid Resume ();+ E1 e- R9 B" r3 N9 }

6 }0 C/ x; v& L- j
4 m) r- W& o0 d' B, ?& c; Z& K//********************************处理事件部分***********************************# i2 C; j* K: q5 |
4 P* A  k. N& o+ I
public:1 M2 E  n8 b: R3 p! [) `0 Y" u
////////////////////////////////////////////////////////////////////& }2 w  j8 j, p: W, v( g$ F* O
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。6 T5 T1 u5 W$ U
//参数: 无。* L% u+ ~, [+ ]. M7 Z  R7 Z9 X
//返回值: 无。# I% E: I* l& S6 X  E3 E
////////////////////////////////////////////////////////////////////8 F8 N8 i* n7 Q" ?+ u! }8 l9 i
void ProcessTTSEvent ();
; z7 k3 Z6 c. S1 F- V' s7 z- o  D$ g' q* Y' g
' h' l* y) `& D% c8 Z" w
////////////////////////////////////////////////////////////////////
7 p: V. u3 |" A5 Q1 B) @//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
0 K* d, a2 I, x) S5 {//参数: 无。% {5 h, Z; q2 H5 P% B* E- k* n" O
//返回值: 无。
* _% a; N( x1 k" V" Z' e6 f////////////////////////////////////////////////////////////////////( a( W8 U2 F: X
virtual void OnStreamStart ();  n6 c7 ?% n$ |- z0 E
9 ~8 t* J3 M" o
////////////////////////////////////////////////////////////////////
  V  Z. U* A) _: f' ~- G% o//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
& ^9 q6 S6 s: I//参数: 无。
: m+ f+ j# s, k4 R3 C& F7 K0 S" b0 }//返回值: 无。
$ Y6 T: @" p" r: f////////////////////////////////////////////////////////////////////
  `  l& j) {4 @/ g, vvirtual void OnStreamEnd ();
( ^0 C5 H% d  O1 Y$ }};8 y+ b' j- i5 g6 t: `* Z+ C. E
" d! c/ A5 ~7 w3 E, {2 I) |5 W- d

9 o2 H7 P6 _% y7 _///////////////////////////////////////////////////////////////////////
! `: p3 n: x; j6 l% W///////////////////////////////////////////////////////////////////////
/ O; a8 c- X9 \9 g5 s& {+ v//         CSR0 e( P$ L* c% E% O% Y8 \
//' ?1 I/ S6 ~; @. C; U7 X8 R, ?
///////////////////////////////////////////////////////////////////////
. ?8 Y4 _9 o- M- f" {# E///////////////////////////////////////////////////////////////////////6 S% ]* c$ t- k0 p
6 y- \+ Z2 r9 h. V7 d  D
class LANE_SPEECH_DLL   CSR
' p- j2 I6 Q5 c: F{
  i! J, ~+ O0 n: c9 [/ t7 O% i. E3 P
protected:
7 K; n' h: Q5 H% K6 DHWND m_hWnd;
# p) ]$ u* A1 B) R2 j3 u2 t4 l" e1 W
public:
4 G% u) [' e* y: R. @" H; KCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。) T5 g4 P  u& ~% P1 D
CComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。
# s% t2 n& L# B; W* l! N9 CCComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。: f, o- \4 w% W! K) O7 t
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。
: P: B* l% g; x, g  J9 y1 V  wCComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。
1 I; t; ^, x1 [CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
0 t' \( ?" N' G+ z+ u4 gpublic:
5 j. Q/ w( b  v* C& A% [static ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。9 ?- Z3 n2 W( e: J% E- h2 K2 j2 s
( s, r" v+ K  \

/ i/ \, N* r: G. rprotected:: G: K. B' V5 U, p& Q* \2 i1 K
//***************************辅助功能部分****************************************
# v8 D& w5 ?  O  b- m1 g, R
& g- k( d; j  c/ y$ J( @3 h: S0 f& H////////////////////////////////////////////////////////////////////
" p* ^1 F& b( B, W//GrammarID加一,每个GrammerID必须不同。
% t! x+ @& `2 b7 E0 p$ i3 {+ h////////////////////////////////////////////////////////////////////+ g8 O$ t9 R4 ^8 f: J
static void UpdateGrammerID ( );
/ v1 z+ Y8 Y" \  M- e( Z7 p1 j( c  s" p8 I

* W$ p1 o) j% [( b7 upublic:
0 \4 M- L% p7 F////////////////////////////////////////////////////////////////////, G) S1 D9 _8 \) v- q+ |/ T
//功能: 友员。TTS中的从SR引擎中建立voice对象。$ G# q' {6 v+ M6 B3 z. D
//参数: pSRContext:SR上下文对象的指针。
8 ~4 j* r. Q4 H. r//返回值: HRESULT类型。
: w! [6 n7 D/ X, ]* G////////////////////////////////////////////////////////////////////: p  |1 l  \" d  q: p, l- F' S. x
friend HRESULT CTTS::Create ( const CSR * pSR,
7 t$ j; n3 Y# g1 b% }# R          const DWORD dwLanguage );  S% C5 a4 s7 c

( b7 F3 b  r  O
. j+ l% V) U% k4 ?5 R1 q, w//****************************初始化部分*****************************************
2 b5 W. |2 t" k
8 |5 P# Q; y% i( z% l////////////////////////////////////////////////////////////////////
* F* K8 p5 T4 \; M" A//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。+ a* Q: i+ s% [' X$ Q1 X
//参数: hWnd:要关联的窗口句柄。" s% u, o5 _' i- {% z7 f
//返回值: 无。3 s4 R% \* c  [2 R
////////////////////////////////////////////////////////////////////
: ~+ G9 |' w% s* C3 LCSR ( HWND hWnd );3 @7 q8 G* R: s1 c4 w, V: H8 g
/ S+ k( ?! K" E+ O
////////////////////////////////////////////////////////////////////2 E, C$ ~, c! k/ U8 C3 n( X
//功能: 释放所有的对象。
  g3 Z. U# s8 J# h7 U//参数: 无。
0 c; V5 G9 x* {& g5 P# b5 {8 s* B//返回值: 无。6 \* r& v; l+ ~9 F' C+ g9 k: q
////////////////////////////////////////////////////////////////////+ x9 n9 Y. y! c' c& o4 G9 M( D
~CSR ( );
& W" L3 F# {" v1 q0 U' h* \
. n' E; T( j* I# b1 |////////////////////////////////////////////////////////////////////
; B2 c' a1 Q1 f3 t; m//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,
, X/ U# ~5 X6 c" ~% g//    加载文法文件。
5 Q$ l2 Y% ]3 D4 M! c  I' A- i//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。
# A. M8 t; M$ O7 ]( Q//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。5 Q( q6 b7 o6 O
//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。
& a/ f1 t' p; o) ?//返回值: HRESULT类型。
) u3 R5 U: P: L! i////////////////////////////////////////////////////////////////////  l' \3 \/ S9 g7 K( z' f
HRESULT Create (const DWORD   SRType,8 ~0 [( C: Q- v
      const WCHAR   *pwcGramFileName = L"grammar.xml",
* F. `2 ?$ I, A( o7 G# \" W7 Q      const DWORD   dwLanguage = SP_CHINESE );
. E2 m  Q8 a5 q/ x, X$ `1 V0 T/ a2 j" g1 S5 _7 ?
1 F( a, L# R$ ^! ^5 K
//**********************************设置部分*************************************1 W: H$ R% U7 O4 C2 I/ I0 I/ o, L
. `% T6 o6 N5 t
////////////////////////////////////////////////////////////////////
+ A& @2 Y4 c* c/ {2 ^6 \* I. T//功能: 设置要处理的上下文接受的事件。- C. b; ?( Q) I$ x
//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,) Q0 g1 r  f. b* x) P
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事" C! F( u' ^0 @# w9 A4 H, w
//    件都会收到通知。
- B( s$ T, C+ h5 |//返回值: HRESULT。
6 s& M" {6 {. q2 o; p////////////////////////////////////////////////////////////////////- W2 m2 n. q) I, F* M; L
HRESULT SetInterest ( const ULONGLONG   ullInterest );3 @1 Q  q; x" c$ G

1 I* ?, \9 D# k& e1 z* d////////////////////////////////////////////////////////////////////
* B; P; W/ O( ^# K$ f8 I//功能: 设置某个规则的状态(激活或者取消激活)。% M$ S2 y/ h3 c! r! g  j, U
//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,  ]/ {' e1 `! C
//    FALSE表示取消激活。
5 m3 O, @  r+ f* u( U//返回值: HRESULT。
$ L, ~+ s  T0 w$ _- H////////////////////////////////////////////////////////////////////' H7 g& ^4 P4 ]8 U! P
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );( [1 A! ]  V) z" x4 X% W  t( n5 W3 r

0 L2 i  f- ^3 ?1 e
6 S1 R* A3 y  ^4 F+ n5 C7 `////////////////////////////////////////////////////////////////////
* f9 i* j& H" s" t/ p//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克3 U8 N6 S; k3 G8 T  _
//    风输入。
4 V8 f, x" l* S! [//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
' e2 ]1 s8 [& ^9 V//返回值: HRESULT。; @) j- N& ~# l: P
////////////////////////////////////////////////////////////////////
+ c9 O* \( p1 m5 n' s( |: y& n- ]; ~HRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );
: g/ C2 v% B) i$ |1 D  r0 z# s& F2 {2 i7 N7 z6 {6 z( y
////////////////////////////////////////////////////////////////////% U6 D5 }# H6 W0 B
//功能: 取消从.wav文件识别。恢复从麦克风识别。% r. A* Q4 C% j) K6 v
//参数: 无。& I) f- q4 z4 I2 J; P
//返回值: HRESULT。+ H, X: V) S3 U9 v5 T' q( C
///////////////////////////////////////////////////////////////////// n& j. G( y# X; N. w9 \
HRESULT UnSetInputWithWav ( );6 c4 i  w1 z: }! {7 D
$ |6 S" U( r% l5 e, [* N
//***********************识别开始,结束,识别结果的处理**************************. Q4 |; o. ~; E/ H9 U% l8 u1 U
# ]3 P- ]! U, ~& X- n, L' T+ R
////////////////////////////////////////////////////////////////////$ E, f* h( P$ l
//功能: 识别开始(将所有规则激活)。
* Z! j3 K2 F: T$ l! M//参数: 无6 `  R% L4 U& K$ t
//返回值: 无。. `  ?3 L4 C# |0 X+ }( a
////////////////////////////////////////////////////////////////////$ o, f; o, c: k1 A: q* p
void StartRecognize ( );
) E5 r" f) N" s4 _' x! k
7 J& [) z/ s! v6 t- i////////////////////////////////////////////////////////////////////0 M/ M8 g! }: }; O0 A. g1 O% Y
//功能: 识别结束(将所有规则取消激活)。1 a5 {' g3 R# W7 e" k: G
//参数: 无。8 K$ L8 Q2 ^2 A& l, Y) v* U
//返回值: 无。
3 M: y; e: h3 r////////////////////////////////////////////////////////////////////6 N, u6 M' l3 G* Z  U, X3 w
void EndRecognize ( );
  l3 \) e6 z  Z+ H# n$ D1 |
! c- i" b; l' [! npublic:
# ^* V3 A' U$ D  \////////////////////////////////////////////////////////////////////
" S" s9 {% A; J0 {//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
2 a! V$ C2 t4 [: \' n( m- [; M//参数: 无。! W1 I' e; y" \, F1 E% N
//返回值: 无。
# B0 d* @" Y' t) _* J9 h( H4 _////////////////////////////////////////////////////////////////////
, j( C  j3 X& U1 pvoid ProcessRecoEvent ( );
) b* k# k) x9 r  Y- Y
& E- B% x4 J& Q; }$ y% ~% k4 M7 d1 Sprotected:
2 d6 W" i+ x8 q////////////////////////////////////////////////////////////////////
! _# d. Y2 @) m% q2 k//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。; u) N5 K/ j. {
//参数: pPhrase:ISpPhrase类型。/ Q! Y, M  N5 X' i) [8 R( }+ \
//返回值: 无。# `* C* `  h) W! D. N4 J
////////////////////////////////////////////////////////////////////
9 @- X" [6 t4 Y& |void OnRecoSuccess ( ISpPhrase *pPhrase );6 u4 R4 W9 C* D

' `5 ~3 @& k$ B: f2 l* k! F+ [4 jpublic:6 O+ A" @4 u9 Y8 W6 ]* w. J
////////////////////////////////////////////////////////////////////
8 \8 p% [. z& s//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
3 ~5 r! z! w/ z1 V2 R//    需要在派生类重载。规则ID必须以常量形式预先定义。0 F8 a- L8 ^6 e2 N
//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。5 f6 y  m4 {/ d" f# Y
//返回值: 无。
4 G0 f2 U& J& c1 C2 P1 |. J# _////////////////////////////////////////////////////////////////////
+ p; ?9 Y& M9 e! }% {: N; D* I4 k& yvirtual void ExecuteCommand ( const ULONG ulRuleID,: W5 R7 K  @% @% u8 k* e% H
          const ULONG ulVal );5 g7 `$ R# S6 K+ f; k

" i: }$ A; P- |! W1 ?7 H7 @* b2 b) Q///////////////////////////////////////////////////////////////////// F' y% Z6 x  R3 W# J
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
. @+ B# u% `; L* E: ~1 V5 q//参数: 无。
2 A9 @1 u: V. C0 E) E//返回值: 无。9 @) C9 N) G4 \
////////////////////////////////////////////////////////////////////, i% U2 c5 n/ k! H5 W1 O) P
virtual void OnRecoFail ();
3 }  [# |( @# v
8 ?, c5 q7 b; U////////////////////////////////////////////////////////////////////
4 J# A3 y$ X% m' q- A' I* `7 s2 Z, k$ w//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
2 ]6 |) K+ b7 y$ X//参数: 无。. F$ o/ c2 M/ V& C
//返回值: 无。" l6 n* U* ?% h2 W% Q
////////////////////////////////////////////////////////////////////
5 h) F. _. @8 y- ^; |virtual void OnStreamStart ();& I0 F" b" J- F& N# P

7 i! w' f; k6 y6 n////////////////////////////////////////////////////////////////////
: S+ }! `9 ^' l/ l//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
' C  P7 g& l0 w0 x9 J+ W//参数: 无。5 x# m8 M; {* e. c
//返回值: 无。  r. w9 _, P" W* E: u
////////////////////////////////////////////////////////////////////0 ]  T+ r# ?+ K. y
virtual void OnStreamEnd ();. R' t8 o& J$ r

: [4 n# c3 Z8 G9 {* d- [- A5 t( [/ _};. R6 r7 ^5 v+ M2 f
& Z+ q8 c5 e9 `* a2 g$ n7 ?
5 S4 `( p7 w6 d8 f2 f1 a

+ R, n4 M; }) m+ L5 e+ G+ Z) @/ i#endif    //LANE_SPEECH_DLL_H
7 P3 c+ ]6 C1 y0 ?2 H$ s: }2 b/ {: q
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////5 N& g" l) q3 P. t

5 u, M- _- I7 W6 |5 ^0 d, R////////////////////////////////////////////////////////& j: W6 h9 Z* Z9 N6 r9 I4 S
//: X8 y. t- a7 r5 ?& T5 X, k
// 文件:LaneSpeech.cpp
( @, B. O7 A1 G5 c3 F// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能% r" k( H3 x) D# H8 W% h
//    语音识别只支持命令模式,不支持连续模式
3 I! ^7 o$ G. V  A# u// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 36199084 h8 d' b' ]& @
// 日期: 2004.10' w& _# x3 [8 @( H) p
// 版本:1.2- d1 j: i' q: R5 L/ m6 R
// ( ]1 w8 n" t6 Q* B& O
//! }' t# ?  E8 T' Y) O+ a5 u
////////////////////////////////////////////////////////! E* r  M$ N0 v2 X: P8 k

) P! R$ I* J% x0 A/ K
: o7 s2 E  s; G  \1 t; _; }( q6 L" ]0 z
#include "LaneSpeech.h"& h% M9 g3 L9 }$ C9 x2 z. Y9 h
' q) |4 |# ^/ e) L3 X
//-----生成动态连接库和静态库的处理----------------& X3 z& {6 u/ ]: F0 n5 f
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类6 p  w! [' ?5 g9 T
! _' O9 C3 @; p, Q# O, R
BOOL APIENTRY DllMain( HANDLE hModule,
; I# _! `( t+ ?( o- D  ^1 f                       DWORD ul_reason_for_call,
" Y% p4 p7 r7 |                       LPVOID lpReserved5 W3 D7 D* q: f, B: T" ]
      )( ?) ?! x4 m5 L, z7 n9 y$ S
{
: T# o- i3 B# P* j/ v    switch (ul_reason_for_call). ?8 i, W3 r7 p9 Q, j0 j, L8 }  ?* w
{+ K0 v' K2 r+ M( u# O5 S/ \% H
   case DLL_PROCESS_ATTACH:. m8 k- Z2 K) u; j4 s$ p1 g1 X2 U
    CoInitialize(NULL);
! U" S  `$ M8 i8 z2 C$ g: k    break;
+ T- x  x  m* [# l1 z- p* j( Z  
& a/ e0 i$ n% ]2 L& W$ D+ j. [   case DLL_THREAD_ATTACH:
8 h4 J0 ]- B! o: S$ X# K7 F: i9 f6 `    break;7 p% a3 y& ?- P, f/ j
  ; L$ X" q, [5 q) y  d5 T4 M
   case DLL_THREAD_DETACH:
- M) i" c0 j! Q7 I! }3 r: N- i    break;+ K7 @, _3 c5 U4 n" F( {' z
  7 m9 k0 w' F5 R4 P
   case DLL_PROCESS_DETACH:
4 x) \" ?/ p- M6 n: c  E    CoUninitialize();
, U& Y$ t. y+ ^$ W    break;  ^2 W1 x, {1 x1 J6 F
    }
6 A1 T  J1 K" k& y    return TRUE;7 m. E2 o: P% m' x: e
}
, k; O: O7 k# B, M
" P7 f- T' e+ A4 @/ Z+ @#endif //USE_SPEECH_DLL
7 H" L# l6 S: P* Y
1 t( o" ^" n5 a# z5 L$ m
# A" y7 }& g8 g9 h/ X* Z( k3 h# {# D& H: t  P8 O! C
///////////////////////////////////////////////////////////////( U  |; @% u1 N) Q' f$ F

! i' ^5 B) a* ^* q: c////////////////////////////////////////////////////////////////////" H# U& e- ^' }$ t$ _
//功能: 弹出一个信息框。1 o( V( P: J; [5 k1 E0 Y$ E
//参数: lpText:是对话框信息。lpCaption:对话框标题。8 s' Y9 r* j, z! K% ?0 y# P
//返回值: 无。9 e8 i% y1 F, b
////////////////////////////////////////////////////////////////////4 a9 C4 d7 j/ B" S% I
inline void ShowError ( const LPCTSTR lpText = "ERROR",
# M' Q4 f4 V# F9 D5 ^        const LPCTSTR lpCaption = "ERROR" )
/ c; ]# d- k! w% n7 m/ T{
# _9 M9 d, Z3 D$ O% t* y8 U& O   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );
0 O9 D. L' u' ]: C}) ]' `' T5 E( o0 G/ ~8 l7 o0 Q

$ b7 ^: q& j4 Y  G////////////////////////////////////////////////////////////////////  L! y  P7 q9 d, N$ n2 @$ ~
//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。
, p1 j$ v, ~# s2 u3 a//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
" o5 B/ L9 b! D" _1 C" D( G: i$ g//    lpCaption:对话框标题。
- Z# d4 ?! F# {( ?. O8 ?1 v//返回值: 有错则为FALSE,没错则返回TRUE。! Z+ G9 k- U5 p8 i3 o6 S8 R
////////////////////////////////////////////////////////////////////% ]- m  A5 w$ V  ~
inline BOOL CheckHr ( const HRESULT &hr,
+ h5 `9 o4 ?& l8 b. D; v. h' U        const LPCTSTR lpText = "ERROR",- q( V/ u: j* F; X1 P, G& w
        const LPCTSTR   lpCaption = "ERROR" )
" X+ M+ f% P/ a" V0 g4 d/ M{
. E- u; _4 C. ?. ?   if ( FAILED( hr ) ) {+ U3 c0 V- ]) ^( F" ?8 D' F
    ShowError ( lpText, lpCaption );: |/ d' |9 f3 O' O7 Q* B& R. K* G: H
    return FALSE;
4 i" y7 K4 v& ]# e7 N   }
; k+ _1 V. h, ^9 b: f   return TRUE;0 o3 G. H/ g; `
}; G& H0 L+ _. J% w2 }( q* ^3 a

* t& d2 n& D; Z6 _$ o8 v! J* Z& r6 N6 ~
$ G+ D- u- I1 U5 q/ H2 y///////////////////////////////////////////////////////////////////////7 [7 p1 q2 ?6 O8 k# ^/ p( j
///////////////////////////////////////////////////////////////////////
+ E3 y+ I& |. Y7 j9 m& W7 K//
* K  f& f' I  ^6 x//         CTTS9 c5 T- U) C# d9 t% n! o  E# q- a
//4 h: T" ?; g9 f" D" s* U( }0 C
///////////////////////////////////////////////////////////////////////
; D" A: j0 M, x( x///////////////////////////////////////////////////////////////////////
4 Y2 U- R# d6 I- q# n0 [$ o8 N0 [9 Q! N2 R- |4 U
////////////////////////////////////////////////////////////////////  }' I# B7 W5 u, V* x8 j9 b. q. q% b
//保存关联窗口句柄。初始化COM。. G5 l% H' l& b1 G. g
////////////////////////////////////////////////////////////////////
* ~8 i, t1 e1 L: Q2 G: C5 @! J! ]CTTS::CTTS ( const HWND hWnd )! @: `' y7 P" ^% c6 @! D
{
$ F/ G* R) ~. B' Im_hWnd    = hWnd;3 u6 W* a/ F  m3 l8 H
m_pVoice   = NULL;
* O; i( A. M6 o& dm_pToken   = NULL;7 W+ \  z$ S0 ]& }4 a. u
m_pOutputStream = NULL;0 q% ~4 S2 n1 n7 X/ T# \3 ~
m_pAudio   = NULL;$ c# X# k) _1 c+ C, k; J8 p3 I
}( D* L1 J; _' ]$ |; {

2 M$ w- s% Q6 R& B) `7 T/ d$ c////////////////////////////////////////////////////////////////////
* ~0 ^0 N) a' j2 S- l//释放所有对象。, p3 @; N/ G6 }3 Y3 n
////////////////////////////////////////////////////////////////////* W5 c" M+ F# G9 b% [" ~; Y
CTTS::~CTTS ()
0 N3 u# L; N  q0 f" L{5 w0 ]+ {2 x& B' B
if( m_pToken) {
+ @- c' c+ ~* e8 M2 B   m_pToken.Release();
( C7 A: U8 C5 k7 r   m_pToken = NULL;+ a' c4 S  `0 J( W5 M
}2 x+ h6 ]+ s3 [5 n5 K# I
if( m_pAudio ) {
2 X8 {0 r' Q% d% d4 n% r* ^   m_pAudio.Release();
$ M. Y% M. C* \- E9 g0 ^7 h   m_pAudio = NULL;
! V6 g9 x+ s1 ]) J}; f( W) M0 m, g
if ( m_pOutputStream ) {. [- z( ~. D. P) W
   m_pOutputStream.Release();  y% a: Q7 r4 ^+ b, J+ I2 D/ t+ Y
   m_pOutputStream = NULL;
6 c( x; O- i* \, l. r/ \) k}3 S) f. ^: H+ m5 [) e
if( m_pVoice ) {; g3 q) ~3 U7 C) }9 O) e6 H
   m_pVoice.Release();
0 Y" X9 P# w* W- K3 @   m_pVoice = NULL;. @/ I6 L8 A$ c: n: g' e2 b
}
3 ^7 u5 y- C! }; `" m9 w: y}) \* ^6 L. k4 b) \  H; N: G
' b( O8 T, R) T+ a4 J  M- ?6 P
////////////////////////////////////////////////////////////////////3 A% B: V- N: e6 t
//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。" N' Q! S2 K5 A: _* o1 h1 {+ D
////////////////////////////////////////////////////////////////////
* a2 `3 C' }7 M$ nHRESULT CTTS::Create( const CSR * pSR,$ P8 r+ p, T, r
       const DWORD dwLanguage )
0 k6 R6 G1 ]; Y' U+ U9 C{
; a, v" ]( h8 l' b8 oHRESULT hr;
0 @$ ?" t+ B' @( l$ d; i# Z, nhr = pSR->m_pSRContext->GetVoice ( &m_pVoice );3 J4 w1 r: k+ o
if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {9 d# v/ D1 h$ E$ W: A
   return hr;
3 ~. c% H: g: J* I* h1 j}
( Z, w4 u! q+ y% O, w/ c! C( k* E/ B3 E& I7 c
SetLanguage ( dwLanguage );
7 z& `" ?0 |8 q. p$ x. W8 m9 \" s
) i$ q' l; k+ K* X) ]8 rhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
5 r& L4 L8 R0 E/ h0 V/ eif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {! V3 _( c" [# V; n( L
    return hr;  e: V: [6 _6 P7 p' G9 D7 C# Y
}
# i: ?! G. j9 q% |& R* ^0 W
; O; X# r1 L$ B  O- |- R/ f//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM0 c+ ~( y# l9 z' s( o" J
//SPEI_END_INPUT_STREAM 表示完成流输出。
  p# C+ D/ j6 o+ S6 y: Shr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
1 U$ [1 A8 x& L$ P( F         SPFEI( SPEI_END_INPUT_STREAM ),
# f( f, q( f$ E' m            SPFEI( SPEI_START_INPUT_STREAM ) |+ U, k9 a6 S$ p# E6 x
            SPFEI( SPEI_END_INPUT_STREAM ) );5 u4 G- C1 `' g7 H5 u& [! z
if ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
/ J& H5 L+ |5 c7 P2 ^( U    return hr;
$ _: e6 x. j, M1 x; `' }}1 v7 M# E/ o) w+ N3 N

" T0 {2 M3 Y! v; h2 T' C//设置通知消息
' S% A2 [3 w- d* I( J$ s$ Rhr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );' A1 k0 F- J  l1 M# _
if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
  \' Q+ }' f* q1 u    return hr;
2 ^' L( n8 p3 v}" D/ l5 A( y) U0 ]
% n3 ]% ?& @  Q, W  c% }3 N
return hr;- P9 e! `7 E% }: {
}
- R# O' k" T2 H5 b, B
) O. Q( j* o2 w5 m////////////////////////////////////////////////////////////////////
5 d" `6 W" \: y/ E1 L' }//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。& E. N# K9 {- |- a' P; j) |, k) C
//并设置兴趣,设置通知事件。
) h7 ^4 O) y3 H7 M$ F" B////////////////////////////////////////////////////////////////////
2 P# V, y" U0 X5 GHRESULT CTTS::Create( const DWORD dwLanguage )
6 H9 S" a2 W* s$ b{
8 j2 k+ ~% Z7 q! u0 s& }HRESULT hr;1 p1 i+ h# Q& Z6 S$ h4 j& f  B
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );/ \/ w1 \/ _! c$ C
if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {
& ]! x9 ?7 b2 h9 C8 X7 u6 j   return hr;+ k! C6 _0 S8 V/ k% @. V& G
}
) q3 S) @- d& Z1 z, M; C. n: C9 f- A1 ~: O% |
SetLanguage ( dwLanguage );
! Q( o" g8 l5 A0 V  j+ B" _' p" A. `& E
hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
$ E# ?. x4 c( eif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {/ _5 d) e( y, l& ]
    return hr;
8 E/ f$ `% K2 C3 F/ L/ C# B; f}
( c$ M, ^8 U' A- _8 w' s7 I: {& o! m0 w" V
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM, D" A8 Q% s( j8 s0 t% \
//SPEI_END_INPUT_STREAM 表示完成流输出。' s1 k7 ~8 ]% s7 g8 C* J, y  v3 g
hr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
5 p: H/ N  F& d: R$ A. v# v         SPFEI( SPEI_END_INPUT_STREAM ),
: O* j. h( e( j8 r, X            SPFEI( SPEI_START_INPUT_STREAM ) |+ z: F4 B0 ?0 _2 x
            SPFEI( SPEI_END_INPUT_STREAM ) );
! {8 o5 J5 I0 lif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
  {$ m2 K! `3 m- L. U    return hr;
: @# O. A0 n+ b# f}5 w) C# ^) h6 X/ F4 J+ g+ o
/ \3 }& G, w- V2 p% Z( g: W
//设置通知消息
, d6 g& d# r8 u$ U1 h" ^" t) shr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
3 S9 p- F6 }0 l. d5 ]  jif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {) [4 w9 J% s4 [: `
    return hr;
( l3 M' {! x  ^  {}
" W- V  ~: l/ [. r2 Q# a1 g$ G
( B" E* b  ?  }5 m7 \5 Areturn hr;
9 o5 n9 E2 ?  z7 V# c3 ?$ g7 \+ P}; R  |0 g. A' V! ?2 N
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件
6 ?! f+ a1 J6 |: S; R  t, m#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
; _) k; R' K% F& K) F5 g{1 i! T" ?' ]& g& G8 _# c6 ^1 w
    ::CoInitialize(NULL);//初始化语音环境- J7 S- L& ]/ o+ I% G6 Z
    ISpVoice * pSpVoice = NULL;//初始化语音变量+ e* F+ \+ g* }. c& p* l) e% B
    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    {
! G) }9 a, F3 ^8 \8 U  q        cout << "Failed to create instance of ISpVoice!" << endl; 3 l2 e& h/ `# ]. V, \
        return -1;
( r2 E6 R3 Z# F8 u: Z6 ~+ d5 r    }
% R. t* E% g) q& D) C1 D3 f
    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量& P+ V3 d  ~) `8 E
    ::CoUninitialize();//释放语音环境

7 J. H1 [/ Z. [    return 0;8 n  a# f" ?- I7 Z( R% a) a
}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序# X& T2 ]% V5 j+ T" Y* ^

" T  u  P$ h7 b, \& Z8 {1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地
1 @- F3 p/ X3 s/ ?1 `& V6 R7 K) [% Y
http://download.microsoft.com/do ... -US/speechsdk51.exe   1 t  v; z( h5 l# H- B* v4 B
Speech SDK 5.1安装包 (68   MB)     
, l  Y# `  S0 [; C$ d( Rhttp://download.microsoft.com/do ... chsdk51LangPack.exe      
! l( Q9 h3 T9 v/ m: h( [9 ?中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
) U$ X& r. _$ H% p1 s) p- R# ]- R% _7 r& m# g0 r3 Y
2.下载后,执行安装
, @. m6 X" g- |( m2 j' s
6 e( Z4 P2 v# R. d* l下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。+ `: N% J8 f' m, M# {" e& U

: |& A& t# g1 W3.VC的环境配置
, {: p6 V' h% j, j8 [
8 ~6 H$ m, H+ n3 l; p( s1 B在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
: G1 @7 O4 l) y6 e/ C# D6 q; G
+ J; ^3 [( u% g5 d! M# L7 R工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
0 D% `( w/ Q" m% m' e4 R3 w  a1 u( C: U; r
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~5 v5 q' [* @; }& K0 g
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-11-14 18:12 , Processed in 0.034515 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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