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

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

[复制链接]
发表于 2011-5-23 17:04:22 | 显示全部楼层 |阅读模式
///////////////////////////////////////////////////////// [* ^6 Y  y  }& H; A
//1,生成动态连接库时,要#define USE_SPEECH_DLL,
4 a, }: j& m% H4 t//      并且#define LANE_SPEECH_EXPORTS- Y, X2 r% S$ C( u' O
//2,使用动态连接库时,要#define USE_SPEECH_DLL. P7 n8 ]! h% C) ]' X& D, F& }* ~) d
//3,声称和使用静态连接库时,什么都不需要$ g8 g- i7 ^$ Q* y7 u1 }5 @& n
//4,另外主程序中静态连接库要调用的方式里要调用CoInitialize( NULL )和CoUninitialize(),* P; D% w, |0 d: S/ J) N) l
//      动态连接库就不用调用了。
/ H, {2 t4 j/ C///////////////////////////////////////////////////////// e8 f* A. R. D, c0 X" z1 x
#ifndef LANE_SPEECH_H
! d' j) }" K/ O! E; {6 f#define LANE_SPEECH_H/ ?% O& R8 L) a. W0 s5 @

8 l; y/ @2 H+ K' r, d#include <windows.h>
: ^  m0 I0 v/ v  E4 [#define _ATL_APARTMENT_THREADED. R# d& a! f  D3 W' s; n2 k+ w
#include <atlbase.h>& s9 Z4 ~  b8 U5 R; E
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/ T" \' I; j$ ^0 _
#include <atlcom.h>
  }" n0 i: D; O6 A9 G/ [#include <sphelper.h>   //sapi需要的头文件
3 g' X5 M# J  R: X% {" V
: [" r# q! p/ [//-----生成动态连接库和静态库的处理----------------( W+ ~' Q! A. V1 G" P+ `0 @
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
7 c8 p# F' H4 w$ P% v- t$ D, _
& \/ z) r; {  x. c  z! `6 y; ~#ifdef LANE_SPEECH_EXPORTS
( k" x6 h7 U. `- h4 }( o8 ?   #define LANE_SPEECH_DLL __declspec(dllexport)
$ e+ D4 k; K8 v9 o1 |* o% y7 o#else
9 A* `9 d( Y4 Y$ _   #define LANE_SPEECH_DLL __declspec(dllimport)" j7 s% h3 }. S6 ]. ?9 g
#endif( C! q7 O8 ~/ C3 r* ^" @7 \! T& n" D

; w1 Z3 q$ T# `1 t6 ~//这个警告我现在还没闹清楚是怎么回事了,估计是DLL和com或atl有关( j' |7 w5 C1 [: `; k2 p7 c# W
//暂时只能屏蔽掉它,在静态库里就不会出现这个警告。
( ^; v$ o4 A* G# y#pragma warning( disable : 4251 )! A/ a. P, G( p7 m# {0 v% `+ @8 G
6 Y0 R. o/ d+ H6 g( E6 K* i8 a" B
#else     //没定义USE_SPEECH_DLL,则不声明导出或导入类(LANE_SPEECH_DLL就为空)
. z* w; C" m. m+ p4 o. ?' J8 t#define LANE_SPEECH_DLL9 K8 O; n. [- i

$ n; ~% l' ?. ^( l: L9 u; {6 W#endif //USE_SPEECH_DLL
- a0 ?7 ^  z3 t' {! t- ], ^( g; q" c4 [+ i9 N) x6 `

+ C. V4 U1 B7 u//***************************常量***********************" X) ?/ \, A) Y  G9 S
  m" X+ B; o. Q& `
/////////公共常量-----------------$ a- D9 h: [! Y0 r* v
const DWORD   SP_CHINESE = 0x0000; //简体中文.2 u6 _* |: V0 u- [. ?+ }) q
const DWORD   SP_ENGLISH = 0x0001; //英语.% {' M$ a/ C8 O. f: Z, Y. b! a' Y
  j; j- `6 x" W
/////////CTTS常量-----------------/ u- U0 v( H- `/ ]6 s. Y" w% Y
const UINT   WM_SPEAK = WM_USER + 4444; //触发事件产生的消息。
4 Q( e  e; f" t3 |6 M+ z; k8 q. Z
  R8 t2 Q7 E- n+ `4 q/////////SR常量-------------------
/ v+ ^7 z( `7 c% U' O" J. c+ kconst UINT   WM_RECOEVENT = WM_USER + 3333; //触发事件产生的消息。
5 M$ z/ u" q7 {0 Bconst DWORD   SR_INPROC = 0x0000; //独享类型的SR.5 u. q! F6 r0 o- ?* _2 \# l/ @
const DWORD   SR_SHARE = 0x0001; //共享类型的SR." A. j% E% s* F7 V" \2 v; S: Q

% R; c- C; W0 O, r6 ^0 ]1 V//以下常量仅作例子用。
& z/ V7 |+ J' E8 }" }#define VID_TopLevelRule 9000   //顶级规则ID
6 ?" }% T6 s" ^5 F8 G# _) m/ T#define VID_SubLevelRule1 9001   //子规则ID
) K& j) H: W- v! e. C/ ?- P#define VID_SubLevelRule2 9002   //子规则ID  K" [$ i! X) i2 d+ q9 {
#define VID_SubLevelRule3 9003   //子规则ID- Z! I. y) W& H. u
$ ^! ~) |6 o, ^( c# @
" w, i& |2 [5 m9 _. u& R
//*************************类声明************************
, H0 R, ?6 K5 `, H8 A% J  O
( f5 J, o5 ^2 K" z9 Q% J
+ x/ y/ E. V) g5 z9 q3 L' Bclass CSR;
* [7 f9 w+ r3 J# k///////////////////////////////////////////////////////////////////////! q* ]. B$ @) }, F+ D- y
///////////////////////////////////////////////////////////////////////% h$ s# t- |5 _( w; O
//# g( j5 N. k6 ?! J8 z! W3 @: S- q
//         CTTS) V, z+ _4 M5 \5 t. u$ G7 G5 C" f
//
4 t6 l: ]  C; {4 _///////////////////////////////////////////////////////////////////////
* _- i" U7 r# c7 P' y///////////////////////////////////////////////////////////////////////* q$ e3 R8 X$ `, @- b! {

" A+ }. D4 w4 h  {( Wclass LANE_SPEECH_DLL   CTTS# L: {- }8 ?" F
{
% G5 w) P# m; g7 T& R/ f, z, oprotected:7 B9 I! a; C- U. P
HWND       m_hWnd;     // 关联的窗口句柄。, D& U2 ^! E% U2 C2 ^: G

" x: \# \* }6 r+ N# `9 ~$ d& FCComPtr<ISpVoice>    m_pVoice;    // 声音对象的指针。6 U1 p) h3 Z& J2 p  y" D( `8 V
CComPtr<ISpObjectToken>   m_pToken;    // token对象的指针。5 Z+ v  }4 ]3 {; F: ~
CComPtr<ISpAudio>    m_pAudio;    // 音频对象的指针。(用来保存原来默认的输入流); w- E) i; ~2 W9 ?) d+ |3 s
CComPtr<ISpStream>    m_pOutputStream; // 输出到文件的流对象。9 Z& n4 s( q0 @. l0 q  C

- v- X; v/ s8 bpublic:( s5 t$ v* S8 j. r; Y. e8 S8 v& t
//********************************初始化部分********************$ c! \; J2 I' ^4 }2 `

) I" B0 s# ~& T6 ~) H////////////////////////////////////////////////////////////////////5 H" F7 D, R5 ^# }6 S
//功能: 保存与识别引擎关联的窗口句柄。
! e% C9 G0 B$ Q3 S6 r; y$ t& |/ S//参数: hWnd:要关联的窗口句柄。
2 {9 ^* w% r) d$ E6 `: a9 H( v//返回值: 无。' k6 ^' p+ I, P2 r, ?6 Y) v0 a1 }2 {
////////////////////////////////////////////////////////////////////
' z1 E  k& S+ ]8 YCTTS ( const HWND hWnd );
) e% q' n! l* E  A5 U. U( V9 Q7 ~2 O' H( y$ g; ?- s
////////////////////////////////////////////////////////////////////7 N& n8 g; }' I
//功能: 释放所有的对象。+ {% a: g7 z% G0 r
//参数: 无。, j3 L8 P% H; c4 u0 Q8 D) A; ^$ f
//返回值: 无。
# u+ o0 H4 s6 ^, n////////////////////////////////////////////////////////////////////
9 x- i$ s  V- p( M: @$ |9 w~CTTS ();1 g+ s$ D8 `; G

& G& y1 w: Z( D, r- G% w# E////////////////////////////////////////////////////////////////////
$ }' G+ @: l# ]4 A//功能: 建立一个voice对象。设置要是别的语言种类,消息,通知事件。6 K* X7 x, S% m9 l  j& S2 O
//参数: dwLanguage:要朗读的语言种类,SP_CHINESE为中文,
# ~" G* Z9 w3 {) P- q: |2 U% S//    SP_ENGLISH为英文。1 H7 }0 o8 }% f$ L2 Y  k1 B( {7 t1 x
//返回值: HRESULT类型。9 P# U1 \6 K9 K9 v4 b/ H& v# d
////////////////////////////////////////////////////////////////////& v) F" g  {7 e$ e' H
HRESULT Create( const DWORD dwLanguage = SP_CHINESE );3 u5 Q: q$ c3 L. ?

* j7 A$ I% M4 n; j# j1 i////////////////////////////////////////////////////////////////////
5 y" F) P  \) U$ g//功能: 从一个SR引擎建立一个voice对象。设置要是别的语言种类,消息,
' W; t2 p% c# M! K% M$ ^) e//    通知事件。# G" ~8 p) S' n* |
//参数: pSRContext:SR引擎的指针。dwLanguage:要朗读的语言种类,: H: q; G" h5 f
//    SP_CHINESE为中文,SP_ENGLISH为英文。" _* d6 p* m: z+ U' m6 v7 [
//返回值: HRESULT类型。
8 M. `- Q3 W( y+ S# I1 j& R/ z/ y+ G////////////////////////////////////////////////////////////////////" ]8 Z+ m& D* r$ c
HRESULT Create ( const CSR * pSR,
8 p! I8 ~$ i6 x       const DWORD dwLanguage = SP_CHINESE );" ]+ M4 B* M7 c7 |" s2 U
+ J% `" @; t/ R. E$ ~: X
  [; K6 b9 a3 l9 h5 j
//********************************设置部分***************************************
5 p3 Z1 A% T+ V+ O0 [- F6 _4 d4 T+ R: o3 L: d/ [( K4 F
////////////////////////////////////////////////////////////////////: S) u3 D) e# m
//功能: 设置朗读声音的语言种类。. X  y; ?& e9 m; _) Q0 X
//参数: dwLanguage:语言种类。SP_CHINESE为中文,SP_ENGLISH为英文。
& D! M4 P/ P( h6 I7 V1 o//返回值: HRESULT类型。
8 B9 B9 U0 @5 }! L6 X1 C6 D$ `1 k////////////////////////////////////////////////////////////////////. h: a1 Q/ t7 G) n* a9 @5 ]
HRESULT SetLanguage ( const DWORD dwLanguage );
% H& L- z6 Z/ U- Y" o7 Z3 h' h. x5 b+ Z7 R% v) R* R3 T
////////////////////////////////////////////////////////////////////( o  z2 z' u% {, \, c) x
//功能: 设置要处理的的事件。
8 W* s3 V- p$ x* o" o//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,' d4 z' g5 x) P' T
//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事+ V1 F+ D7 H! H- j. l, w9 z: ^
//    件都会收到通知。
; t" L6 r0 z7 F, F" I; u4 ^# z( t! D//返回值: HRESULT。
5 h& ?( Y: }9 X/ B3 v. ^4 M////////////////////////////////////////////////////////////////////
2 i# [) h3 G) `) o$ o! [  d1 JHRESULT SetInterest ( const ULONGLONG   ullInterest );
: D9 x/ g6 I2 v! q$ c+ a$ w+ f/ H
  ^* z3 G, Q- h7 U" U4 J. j8 D////////////////////////////////////////////////////////////////////
5 `3 w, t8 J( f* A//功能: 设置朗读声音的音量。, J! c, ^! y2 G% g! ]8 }
//参数: usVolume:音量数值应该从0到1008 b3 Q* K! \$ d3 S, F
//返回值: 无。5 Y, P; h& _' G' g$ j9 T
////////////////////////////////////////////////////////////////////
) R5 f, S- l) B) E# j# p. bvoid SetVolume ( USHORT usVolume );% }7 G& l# r  Q; V7 V4 |/ b" a

+ g9 }4 L# o. F; ?# R* g8 X( P( s////////////////////////////////////////////////////////////////////& Y& k8 G5 n  f$ h+ l! ]9 f
//功能: 得到朗读声音的音量。1 |& Z' ^) C0 J5 {" W" L7 U8 a
//参数: 无。
3 X9 F$ S8 @9 m. d3 r# |//返回值: 音量数值,应该从0到100。8 M1 L, e" \, U; }, s$ q7 S9 d
////////////////////////////////////////////////////////////////////; h4 H( F/ x4 W
USHORT GetVolume ( );/ E1 \/ N: U- C" C! ]2 }3 ]

7 A3 E. J! ^, z/ k" L////////////////////////////////////////////////////////////////////
; G* Y. q$ i6 ?' C: j//功能: 设置朗读声音的音速。# R2 Z5 \$ j" M
//参数: RateAdjust:音速,参数范围从-10到10。
8 H9 i2 G& Q/ V. h2 v6 ~( t//返回值: 无。
4 J* @% i, n. H9 i////////////////////////////////////////////////////////////////////7 x0 Y; h1 t6 ^2 S9 B
void SetRate ( LONG RateAdjust );- A- o. L; a7 Z

; n, B4 i! J1 ~5 H8 c////////////////////////////////////////////////////////////////////! z5 t* ?( ?! k5 B* n3 N7 [1 r: B
//功能: 得到朗读声音的音速。
* j6 w/ h7 W- |4 O! A3 v//参数: 无。
/ n" G8 z% V' i0 N: n//返回值: 音速,参数范围从-10到10。
& v# |! l4 k* I0 f. r6 D, O////////////////////////////////////////////////////////////////////
% t1 [, ?' Z$ Y- Q+ N5 V# zLONG GetRate ( );( O" j! [* o$ \, ]& B* X" U8 }

  E4 [6 h3 U* v3 D/ f$ U% M+ O////////////////////////////////////////////////////////////////////
# j' B# ]4 ^: T- f: M; X5 U//功能: 设置朗读的声音流到.wav文件,如果不调用此函数则默认从音箱输出。
: _, P: q8 w4 B# c4 f//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
  y% {# D0 j; ^4 K//返回值: HRESULT。, C7 F% t2 W# u9 V; {1 h5 k
////////////////////////////////////////////////////////////////////
5 @, R& A* o' p' CHRESULT SetOutputWithWav ( const WCHAR *pszFileName = L"TtsOut.wav");2 _3 x& T/ F. O6 G1 @; ?
  B; G0 V2 s& r; b; z5 F. h. q# O8 Y
////////////////////////////////////////////////////////////////////
' y0 p. \( W8 e7 ~7 @//功能: 设置朗读的声音从音箱输出。" \( H+ s; N& u% I: j, H  }" L2 ?
//参数: 无。
9 h8 M$ {" |' H& I1 H* `& ~) D//返回值: HRESULT。3 T1 V# J5 }; X  P; i7 y- k
////////////////////////////////////////////////////////////////////
; x; R& X* P0 S- Y, nHRESULT UnSetOutputWithWav ();+ q3 @  E- ~/ q# \* |* c' R
/ }( b! z- S) m( B/ `' M" J
) }# c+ t8 i, m, |8 J$ A: i# z
//**********************播放语音,文本到语音转换部分*****************************
0 q: z5 x" i& Y; H% c
) P$ B% X4 n9 G////////////////////////////////////////////////////////////////////0 e7 \1 ^) }+ i- g. b) N) U
//功能: 停止朗读。如果朗读为同步方式,则不能停止。) I" b2 H: p$ e) X" Z# j9 H: e
//参数: pwcs:要朗读的字符串,需用" L"" "转换,可以是包含xml标记
" d# J7 Y6 P9 |) {; r  a1 A//    的字符串。dwFlags:朗读方式。SPF_ASYNC为异步,SVSFDefault为同步,' `6 Y' [  F( D# v
//    SVSFIsXML为朗读带xml标记的文本。
: ?8 S5 {4 B; p3 |, Z  ?//返回值: HRESULT。: K( R! l: K+ z: c6 P
////////////////////////////////////////////////////////////////////( O0 n) d% |  E1 q5 j
HRESULT Speak ( const WCHAR *pwcs, const DWORD dwFlags = SPF_ASYNC );1 p( _# T& |  q0 ^# {2 ^0 W
7 g) N. V2 U9 j6 J
////////////////////////////////////////////////////////////////////
4 A: ^! M( v5 n; N//功能: 停止朗读。如果朗读为同步方式,则不能停止。
3 M/ }1 d  Y7 d2 V( b) _//参数: 无。
1 v& |" W' T4 E//返回值: 无。
* L; k* a9 R; ?1 f0 q; E8 d1 N) v////////////////////////////////////////////////////////////////////
* C, Y( N& B: u: V& j  V8 h* Pvoid Stop ( );
# \0 ?. Q  q" O7 J; \. {( J2 ]0 o/ d) H7 e/ N
///////////////////////////////////////////////////////////////////// [2 ~+ A0 B$ ?# a' M
//功能: 暂停朗读。如果朗读为同步方式,则不能暂停。
( ?/ P) y. Y5 R5 b( r6 N//参数: 无。+ m$ c! ^. w# U. G+ b. O9 C
//返回值: 无。; A, o( S" @* _$ z# C
////////////////////////////////////////////////////////////////////6 r- V7 g/ n3 d' B6 N
void Pause ();3 h' B2 i. U) f4 ?8 h9 o$ \

9 G) J) ]( s( d& A1 p$ [. U////////////////////////////////////////////////////////////////////
! O6 E, G8 G' M% L: v& j7 O0 U//功能: 从暂停的地方继续朗读。
' @2 b  H/ v8 L7 c//参数: 无。
4 ]. f7 ~) W7 ?- @; I2 l- n//返回值: 无。
) N/ n  S7 i. y3 T  V# M7 O' s# ~1 m////////////////////////////////////////////////////////////////////  x/ V0 e* ?. K' z& |
void Resume ();0 a  x; q( b+ ]4 e6 j5 m8 S- [5 \, K" P

8 F7 H& P8 D. A8 Y+ L9 S
6 b; x0 q( ~0 X) X  [2 g//********************************处理事件部分***********************************4 A) z, T8 q1 ^+ w
  s! B$ u4 S' @- G# C( @4 H' @
public:
" g+ d1 q- @7 k# s" q5 U: Q( p////////////////////////////////////////////////////////////////////7 q- d+ s+ l$ X! U% e0 \
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
* b; [, S# \6 k//参数: 无。' t7 O- T/ k$ G1 M. d* ]
//返回值: 无。7 Q8 A: U( ~, d+ r
////////////////////////////////////////////////////////////////////4 K. g8 N% k; `& Q+ z
void ProcessTTSEvent ();
& p6 X+ Q- X) K, I3 p8 \1 X
! n  c+ W) ?5 ?2 T; g: ^, s
5 K+ d1 F4 G" m5 Z////////////////////////////////////////////////////////////////////% D9 E" |- i7 O) z1 ?5 D& q. S
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
  o; A6 T4 B) D# Y//参数: 无。
9 l, N8 n; H. ?' D* J9 z//返回值: 无。5 U$ J5 k& P* ^7 q8 {' R; b" X3 n! g
////////////////////////////////////////////////////////////////////
2 u& @- D) f7 X( P% @4 X1 {virtual void OnStreamStart ();
$ E7 u5 o$ B0 ^' }# y
4 W5 {5 j3 b2 Z0 [9 b( s////////////////////////////////////////////////////////////////////4 Y3 @3 _9 U4 @) C! a9 s
//功能: 为虚函数。当输出流结束时要触发的动作,需要在派生类重载。
: C8 \3 a' m8 I5 Z//参数: 无。
) w$ E5 n+ q' f' B" k//返回值: 无。
" t1 w& T# A8 m. b4 x////////////////////////////////////////////////////////////////////
6 U0 W, V; I' {. U; O6 evirtual void OnStreamEnd ();" C# S4 }& A( F! Z' V- v- |9 T; r
};
+ [9 p0 o( P8 |) l& G; k
  r# {, R1 J3 p! z- V! E
9 _" K3 p4 D( [( j5 H2 G///////////////////////////////////////////////////////////////////////1 G. y- x- s4 `. M8 b
///////////////////////////////////////////////////////////////////////
  G% p8 `* U9 [$ b/ F6 q; P//         CSR
0 G# X# f" c5 j& D1 `, U  O( L//
$ b4 S4 j  \4 L" c# Y///////////////////////////////////////////////////////////////////////1 \9 I/ E: i9 }( Y5 d6 F% a- G
///////////////////////////////////////////////////////////////////////+ u$ n) j$ k9 o: W: T5 w/ g0 n
* k1 E# h2 T. t3 i
class LANE_SPEECH_DLL   CSR7 U$ a( {7 b! @$ q  c( e& [
{, X0 B- j4 @/ U

# d) d! e" g1 M5 u, lprotected:. ?+ z) B8 ^9 _  Z
HWND m_hWnd;
3 d% ^2 a8 z8 u9 R! L7 E5 l* d5 H- E, y; t, }3 m
public:
2 W- i1 T' |5 b) G8 k* Z$ o2 XCComPtr<ISpRecognizer>   m_pSREngine; // 语音识别引擎(recognition)的接口。
+ F; J* X9 O# O6 [9 I, E9 Z% cCComPtr<ISpRecoContext>   m_pSRContext; // 识别引擎上下文(context)的接口。9 ^2 g9 y3 d) |& W0 d& K
CComPtr<ISpRecoGrammar>   m_pSRGrammar; // 识别文法(grammar)的接口。$ W% m7 y- M7 V5 ]: I
CComPtr<ISpStream>    m_pInputStream; // 流()的接口。: Q* ~1 a3 U% _; C) x- Z' {/ d
CComPtr<ISpObjectToken>   m_pToken;   // 语音特征的(token)接口。  N) w- s; }! ?" e0 r# G
CComPtr<ISpAudio>    m_pAudio;   // 音频(Audio)的接口。(用来保存原来默认的输入流)
- n5 T) [; z* g# N: bpublic:
# _7 q' }! e6 Dstatic ULONGLONG    ullGrammerID; // Grammer的标识符, 64位无符号整型 每建立一个Grammar,加一。0 k1 V' {3 o- |0 X, R5 [. m; _

6 g" J2 k/ y4 R( f$ J
! @# e# P+ h) n& r5 [protected:
: R2 _8 F! W' Q3 z6 w$ A//***************************辅助功能部分****************************************
; J/ F1 s) c  Y$ S9 E# \# V8 v) s" s. L
////////////////////////////////////////////////////////////////////3 x+ R- j  d* \, M  n5 @" s) u
//GrammarID加一,每个GrammerID必须不同。7 V! \9 l5 Z. q/ w: t8 ^/ ?
////////////////////////////////////////////////////////////////////
: z. \# a- @' H" [( \% I' gstatic void UpdateGrammerID ( );
9 Z# c) h, Y( _& ?0 ~; C4 `, v+ B) d1 T3 u4 P) p

; D+ M7 p; K& g" L1 p/ |public:* ?8 P% `' ]: `+ u6 `( M
////////////////////////////////////////////////////////////////////
) H1 T$ G6 T7 G, c8 I+ C. G5 H6 X//功能: 友员。TTS中的从SR引擎中建立voice对象。
8 {- s" ~' ~# C3 W' e, u3 l3 S9 ]//参数: pSRContext:SR上下文对象的指针。: P5 `( X, p, T% v' O7 L& [! S
//返回值: HRESULT类型。3 [* [! N- K& `
////////////////////////////////////////////////////////////////////8 Y7 L" Y7 k7 e7 R( M; j8 {
friend HRESULT CTTS::Create ( const CSR * pSR,4 |( [! u! ?5 R# O6 O' c5 C$ j
          const DWORD dwLanguage );2 @+ x+ \  y, @& m3 Q

% J/ j+ }8 \! D7 a/ j+ s' J
- k$ w/ D9 i! W) A//****************************初始化部分*****************************************
1 d- `4 Q. f" }& I0 ^. S3 C' @6 y- k7 n0 ?- Y5 @
////////////////////////////////////////////////////////////////////
- {. a* y. A$ f( D//功能: 保存与识别引擎关联的窗口句柄,更新GrammarID。7 Z" J3 |& W  X- r, r
//参数: hWnd:要关联的窗口句柄。
; h" _. H$ H% x6 [//返回值: 无。; q- J, I0 |$ l4 |* i/ e: O
////////////////////////////////////////////////////////////////////$ O& ?$ ^6 Q* s8 M& q6 T6 s
CSR ( HWND hWnd );
% `* y4 E# A7 N
9 W- B: f( G6 ^; m4 s6 K+ X////////////////////////////////////////////////////////////////////9 D  b# H& @0 N& Y7 u
//功能: 释放所有的对象。$ M4 b( A3 x8 T) L" v* g8 r" g
//参数: 无。8 v+ M( l: @! m% x8 A
//返回值: 无。6 i  R# e' H1 ?
////////////////////////////////////////////////////////////////////
5 M) s/ [- G- P* @2 {~CSR ( );
6 e2 G6 D9 C4 F' K- ^: g7 H
& Z3 H& x) {( }- p$ y////////////////////////////////////////////////////////////////////3 h* W0 M# u* [, N2 `
//功能: 建立各个接口的对象。设置要是别的语言种类,消息,通知事件,0 R, B, S, [* R0 Y& b
//    加载文法文件。4 k* }& X. e) }; ?' p* N! K5 d
//参数: SRType:识别引擎的类型,SR_INPROC为独享类型,SR_SHARE共享类型。9 u* `0 Y! M5 ~0 Y3 ^4 o4 n1 {! o) X
//    pwcGramFileName:文法文件的文件名,要用" L"" "转换为WCHAR型。
5 @9 p6 ]8 C( B! ^( D9 [//    dwLanguage:要是别的语言种类,SP_CHINESE为中文,SP_ENGLISH为英文。# U  I/ H8 a+ L( x; R$ g
//返回值: HRESULT类型。" l0 B$ L6 ~0 @) j$ P: M, J+ z
////////////////////////////////////////////////////////////////////( p" F( e& i( H7 T. ~
HRESULT Create (const DWORD   SRType,
0 y+ @9 Y9 p* `5 A      const WCHAR   *pwcGramFileName = L"grammar.xml",# E% Z' L# O. n$ R9 T2 U4 U
      const DWORD   dwLanguage = SP_CHINESE );& W8 n" t3 b. O1 |6 C
. o: M* x' R# n- ^+ d/ z1 b
/ d) ?) F& M( w
//**********************************设置部分*************************************
- w7 m/ D& u% B3 r' Z! W9 I! X4 ^% \* W9 G3 G
////////////////////////////////////////////////////////////////////
: [" j" l. |& W6 ?7 W//功能: 设置要处理的上下文接受的事件。
; r, j' |+ G, d* N* V" S8 H1 M; K. w//参数: ullInterest:来自enum SPEVENTENUM,要用SPFEI()转化为64bit的,
8 [6 a* ?5 w6 {& [# d, j& Y//    设置多个事件用运算符" | "。 用SPFEI_ALL_SR_EVENTS表示全部事
/ n3 Z5 ?8 x  @  M1 X//    件都会收到通知。6 M* L4 O8 {# G$ C0 X$ R
//返回值: HRESULT。
' L! r2 {+ ~$ v1 Y" S" T. y////////////////////////////////////////////////////////////////////" _: V" _6 J. Q9 D( {" }' ^5 L
HRESULT SetInterest ( const ULONGLONG   ullInterest );
* A8 ^( v7 j% \) K5 H0 e1 Y- f; r5 l/ O# h8 c" Z  \. k# P
////////////////////////////////////////////////////////////////////+ r9 E8 z$ n) h. P' N% u2 r1 D& j
//功能: 设置某个规则的状态(激活或者取消激活)。
/ p6 e9 N! I! {3 D8 @) G//参数: pszName:规则名,要用" L"" "转换。bFlag:TRUE表示激活,8 n7 z5 k; W& m, F6 \
//    FALSE表示取消激活。& M- z4 P/ C, I/ x, {3 I: U* P5 o! X
//返回值: HRESULT。
5 R, f0 {% V/ B////////////////////////////////////////////////////////////////////# U4 k4 n1 Z" D# [
HRESULT SetRuleState ( const WCHAR   *pszName, const BOOL   bFlag );
0 G0 T: ~$ b. R. W3 J
" E, v$ c4 l2 y+ c. E! J1 Y; ~! y* Z' j, b: ]' d6 b. Q
////////////////////////////////////////////////////////////////////7 y( l- L" |, ?* M% s) c4 b2 X4 t
//功能: 设置识别引擎从.wav文件识别语音,如果不调用此函数则默认从麦克
" N1 V7 j2 o% l//    风输入。
6 X% U: d  u% e' [7 E6 a//参数: pszFileName:.wav文件的文件名。要用" L"" "转换。
- J( X. B$ G8 p2 x2 e# E6 `//返回值: HRESULT。
& j& y- `9 i8 s/ s& t1 |1 S////////////////////////////////////////////////////////////////////
  l( n7 z: z# t+ xHRESULT SetInputWithWav ( const WCHAR *pszFileName = L"sr.wav" );! O9 y/ ?9 J% ]" Z, g
* r; j( S1 h  ^2 c7 {$ `
////////////////////////////////////////////////////////////////////* u# a  T* ~" V% q
//功能: 取消从.wav文件识别。恢复从麦克风识别。- t5 N, w- `( @2 _
//参数: 无。* h8 l) u5 _& A' V! U
//返回值: HRESULT。
+ @! M  s$ s4 e! J2 V3 q+ ~# X////////////////////////////////////////////////////////////////////9 P) g3 x, E4 Q# q- ?' p
HRESULT UnSetInputWithWav ( );# N3 b& E; c, {4 {  N3 n5 J8 F
0 a9 }: S8 }( ~) S" j* Z
//***********************识别开始,结束,识别结果的处理**************************; R' {5 h* U& \$ C- I* L

" l, S5 J! h0 `1 `& F, k' R////////////////////////////////////////////////////////////////////
6 \! F) a( y# q/ }6 y//功能: 识别开始(将所有规则激活)。
" p: t1 h5 F6 v% @) W, O//参数: 无
4 W0 z  l, @- P; \; H$ ?9 X9 E) Q( s& o* L//返回值: 无。
& j9 D3 y, j: ?; t" J////////////////////////////////////////////////////////////////////, F3 R7 N- p$ D0 a: d' _) ^) D: I
void StartRecognize ( );
7 m+ I) h9 e6 P/ ~( t% k3 b3 p- s3 J- e
////////////////////////////////////////////////////////////////////( z0 ~& S' P" e! J2 ~: @9 K
//功能: 识别结束(将所有规则取消激活)。) W5 o/ ]3 T5 ^8 X& q/ \
//参数: 无。
9 @7 }/ n, Z# W) ?//返回值: 无。
, _! Y8 v. a1 k* K2 [////////////////////////////////////////////////////////////////////# T: e" V2 f- N0 B+ W& [
void EndRecognize ( );# [  y$ c2 ~8 U7 ^+ q

3 e: {7 S: K* V* H  |9 Rpublic:
; H8 T6 I% z" e1 Q5 ~////////////////////////////////////////////////////////////////////, |" X0 f3 B0 m7 ?( ~' b. p) ]9 t
//功能: 处理发生的事件。系统自动调用,不需要用户自己处理。
& P" G( g, q1 i) i; ?# M& t//参数: 无。/ Z0 O3 O9 b) M/ {% K/ E5 n; `
//返回值: 无。
9 j& j8 J0 y( U* a" Q" w4 z////////////////////////////////////////////////////////////////////
7 Y- ^9 [$ q1 B1 h9 ^) o2 vvoid ProcessRecoEvent ( );
; a& k% u" f* a$ K% B8 [" E+ J9 L( A2 b5 T% \' ^! @+ \' Z
protected:  {9 I6 _" J& b2 d* M: U2 k
////////////////////////////////////////////////////////////////////
  f# W1 {( S3 w' F) r+ d2 `! W//功能: 识别成功时要调用的函数。系统自动调用,不需要用户自己处理。
* s. |5 [3 v$ R  [$ a0 v- t//参数: pPhrase:ISpPhrase类型。# X$ U: \* T7 Y' i+ x
//返回值: 无。
3 i& L9 H7 A- l, p  I: z////////////////////////////////////////////////////////////////////
$ X0 S6 g) c, o2 n: fvoid OnRecoSuccess ( ISpPhrase *pPhrase );: e1 E) l. G; c/ |+ O6 N0 K& y

- Q: t" p% [2 m1 Vpublic:# t9 y$ n, ?3 Y. C
////////////////////////////////////////////////////////////////////9 Y0 Y* u( n' y+ y0 d9 e
//功能: 识别成功后,根据规则的ID决定动作。系统自动调用。虚函数,
- z0 c! A7 w4 K  @//    需要在派生类重载。规则ID必须以常量形式预先定义。! D4 v8 O+ F" u" }
//参数: ulRuleID:顶级规则的ID。ulVal:子规则的ID。
4 K4 H. I# p) M, M6 R/ Y//返回值: 无。
8 w3 {* X0 k$ L' A9 e0 m////////////////////////////////////////////////////////////////////
- s0 B# r- J; J$ Y  V! A  wvirtual void ExecuteCommand ( const ULONG ulRuleID,2 K) k) {! d* r8 D+ I
          const ULONG ulVal );, ^* j8 Q; O7 x9 Z
# _- R; f. H, D! f
////////////////////////////////////////////////////////////////////7 c: D; [% F5 @: v3 Q1 l5 h
//功能: 识别失败时的动作,系统自动调用。虚函数,需要在派生类重载。
4 I# e3 r) U$ z//参数: 无。4 W$ `9 B8 F* K! U8 j
//返回值: 无。' M/ n# }1 K# S: B9 c3 O
////////////////////////////////////////////////////////////////////, N1 t  {. n/ M' d, h  e0 T# O
virtual void OnRecoFail ();5 S9 P6 k+ ]% G9 d
- a7 \7 h. B- j! n8 F
////////////////////////////////////////////////////////////////////
7 q4 _. ~; l; d  F//功能: 为虚函数。当输入流开始时要触发的动作,需要在派生类重载。
( n8 [9 V7 t4 z( \& y) }//参数: 无。
# [2 E4 S* V  I( u2 b0 w. N) ^* l+ d//返回值: 无。, h" |/ |' {2 B' f
////////////////////////////////////////////////////////////////////
2 O( D. i% q/ |9 R, ^( L3 _$ \9 Yvirtual void OnStreamStart ();4 {: n5 Q, e! o2 ^1 U
8 i! |* @, d7 l6 W: y: l
///////////////////////////////////////////////////////////////////// Q3 c, i. J7 D# i$ ]
//功能: 为虚函数。当输入流结束时要触发的动作,需要在派生类重载。
$ H1 }  ?3 L: _8 R2 U  O+ j8 {//参数: 无。
, x% O, r; m! t, H//返回值: 无。
) ?2 h/ k; x5 U' _6 J9 Y6 z9 g7 R////////////////////////////////////////////////////////////////////# K8 z6 N4 Q5 {5 r3 |
virtual void OnStreamEnd ();& Y1 K: u; `7 |+ m. h

# }5 f& {( Z# ]+ i};
. @- @( {& V( o* J8 d. T  t7 @6 B  ~# W  {+ U- S
, [6 J: ?$ W: [

$ T% S4 M0 @; S- I. T, {( j% X#endif    //LANE_SPEECH_DLL_H
0 r( D; h" V* \: o& {! D4 Q- E8 \. J7 f/ e5 E
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3 g8 F& P* w: O9 b
. m4 @3 i7 f) P' {2 k) u( C' A////////////////////////////////////////////////////////
1 p  ^$ A# f3 R5 @4 @//
. x! Q& H( Z% r7 v  ]0 R// 文件:LaneSpeech.cpp) C+ I& j4 H- J- Y, a. x5 y
// 功能:封装的speech sdk5.1 的文本语音合成(TTS)和语音识别(SR)功能
; r" B: x/ x1 B# X6 y6 [& T/ D//    语音识别只支持命令模式,不支持连续模式
4 T/ V7 [; I6 H! v4 T. ^! F2 w// 作者:吕宝虹(Lane), msn: lkjx82@msn.com, qq: 36199085 i" r4 _" B- Z9 I
// 日期: 2004.10
' U! r' J. j: H* E+ [// 版本:1.2
/ M6 v# S: x8 e" j# q# u// % W) I2 h1 |5 V$ k# j. u: x* f
//
$ m# ]& U# N: _0 P- `  {, k& G  b////////////////////////////////////////////////////////
$ x7 ^+ V& O% _5 T( n" I
4 ]' J. h- D' d# X, c3 j+ e8 q& N& Z: E0 O6 V

" B+ w3 t1 n& H/ `* _: ?5 y0 W#include "LaneSpeech.h"
9 ~5 h+ x0 t6 y$ y; o5 F  j7 s; D0 F/ K7 d
//-----生成动态连接库和静态库的处理----------------0 I  e2 C5 _* H9 J9 M4 x! c& u
#ifdef USE_SPEECH_DLL //定义了USE_SPEECH_DLL,就按生成DLL,声明导出导入类
" O; M' Y% P2 D8 {6 e. w1 C* [3 Q1 k  c
BOOL APIENTRY DllMain( HANDLE hModule, 1 |) O$ o: G: f# V. e
                       DWORD ul_reason_for_call, & r2 r% T; W. w+ l3 K
                       LPVOID lpReserved, i; B* j; E/ A- N, s. O& G
      )7 v( O0 m: U' p! S
{' }( G, c* ?; Q" o3 A2 L
    switch (ul_reason_for_call)
- ~" y6 @/ Z8 q, s' D{
% |5 D4 F8 S' H, t   case DLL_PROCESS_ATTACH:# Z  A$ W7 N% A
    CoInitialize(NULL);
. u- x- I0 F# P  t6 }: ]6 ~    break;2 \8 d( L$ z. _
  
. Q9 ]1 R* I, ]+ b4 R" g! F* t   case DLL_THREAD_ATTACH:6 i/ z3 \4 K  R+ S
    break;
) c  P" z% p& }! b1 D% ?3 v% c  + c. R- r6 [7 t& k8 w
   case DLL_THREAD_DETACH:, [* Z# L; s6 l# I# k7 X4 o
    break;& R" G7 d# X0 L# r
  ! |1 B  T: w6 r, ?
   case DLL_PROCESS_DETACH:1 Q( t7 W4 m' M; o/ z* \
    CoUninitialize();
9 L* ]0 s, r' ^9 R! U    break;( E8 m8 x; s$ |1 @
    }2 Z, {6 u& h2 e$ l4 z5 K) T
    return TRUE;* M6 F$ M( K  d! r8 I
}
* f9 [4 U7 R, n7 w! \* V* N
+ M8 p, l4 U# p  R; z/ y#endif //USE_SPEECH_DLL) u% M$ I# G& _' O3 P# o4 y5 n

1 L0 T6 R6 K  ]+ v8 p3 |# h; i- x" V) f; v  C% O" ^" Y5 e
' `9 Y, H: p/ y
///////////////////////////////////////////////////////////////
8 T; ]+ ^$ U2 j' v. ]( X
  g& Y8 w2 T2 G# v+ Z////////////////////////////////////////////////////////////////////  D( Y9 {) E# ~, ?6 E% r& h
//功能: 弹出一个信息框。1 J8 i- {! L( w* l
//参数: lpText:是对话框信息。lpCaption:对话框标题。
, @! U1 J& }3 f! E! |6 B: }//返回值: 无。
" R4 ^5 {4 B, f) H1 g# g2 ?/ a& E////////////////////////////////////////////////////////////////////: ]3 F2 S; j. }3 D
inline void ShowError ( const LPCTSTR lpText = "ERROR",
% f( D  }9 {! {1 |        const LPCTSTR lpCaption = "ERROR" )
  |; ?# s+ m! Q! t1 O{" [2 V7 f& b# B5 d; q
   ::MessageBox( NULL, lpText, lpCaption, MB_OK | MB_ICONERROR );. E' a& I* j4 T
}4 r# [: _7 P: }5 r

8 }6 c# r3 b3 ]8 [) h////////////////////////////////////////////////////////////////////
, f% H3 {  |, S5 T7 H//功能: 检查一个HRESULT类型的值,如果是错误的值则,弹出信息框提示错误。8 o# q% v0 p  K: i/ {
//参数: hr:要检查的HRESULT的引用。 lpText:是对话框信息。
( U; T; T# ?0 U* W) ^- K- s6 U//    lpCaption:对话框标题。1 r/ Y; M- r  b2 M( p
//返回值: 有错则为FALSE,没错则返回TRUE。! l, ?$ z% V5 C* C5 u5 Z4 r+ ]
////////////////////////////////////////////////////////////////////& o( q8 Q6 i$ x+ D
inline BOOL CheckHr ( const HRESULT &hr,
: G& s* p3 f7 ]        const LPCTSTR lpText = "ERROR",% r- \! O; @. t- ]1 W
        const LPCTSTR   lpCaption = "ERROR" )
* P7 ]3 A! F; V{! c5 I. g# l6 c' c$ j; ^# V' k
   if ( FAILED( hr ) ) {: A9 [4 H6 z: ?* _# C
    ShowError ( lpText, lpCaption );% _& K, Q1 a( r( y4 H  Y
    return FALSE;' C+ N! o5 q0 |; I. [- }
   }
7 v: `# ~. ?9 A$ s" a   return TRUE;/ i' G) o0 a- i" w9 q* Q  |
}
* R+ M. v, E7 N" }0 E& Y& f7 d" s% j) U; ?8 a. `
5 Q* M- _* ~' S9 a
///////////////////////////////////////////////////////////////////////, S- B7 L# c' R8 n) b/ r
///////////////////////////////////////////////////////////////////////: X" O+ C; j$ ^+ d
//
" x3 R8 f% |" z; z; C1 N5 W2 p% B0 n//         CTTS
% d$ b" P" C# X8 [! J" v//' E) Y8 T7 h. k9 B7 u7 ~+ i
///////////////////////////////////////////////////////////////////////% K1 p; V% z' K- |2 W
///////////////////////////////////////////////////////////////////////
  Z3 \, r( H# }: ^1 [
4 g$ t4 W* }) y4 x9 F////////////////////////////////////////////////////////////////////  h: O6 y& X7 E, j3 Y) A* k
//保存关联窗口句柄。初始化COM。* e& f" j( M2 t! s4 _: M8 x
////////////////////////////////////////////////////////////////////
! j( G. T/ h; U5 Y2 l+ g7 dCTTS::CTTS ( const HWND hWnd )
/ s3 [' {. z0 P5 y: M  v6 e{8 B. B% u* a9 }% T$ A* m* R& _; [' ~, q
m_hWnd    = hWnd;1 P) X6 E3 V* Y1 {1 _6 R8 \
m_pVoice   = NULL;
) ^, e! T# O* ^2 Sm_pToken   = NULL;/ b% |, h) }  l, P
m_pOutputStream = NULL;! A/ T4 k* M! P) W
m_pAudio   = NULL;
' [" T# \! f8 \- c}" h% y  w- ]; N8 f4 B( M' @
* e) Z% f' A  s8 v& o( s( {
////////////////////////////////////////////////////////////////////) l3 M; L" q. h3 D; W2 ?
//释放所有对象。& `- F" f$ y$ k) l: v
////////////////////////////////////////////////////////////////////: e4 o! O- ^  V4 G6 ?- V" G  X% d! i
CTTS::~CTTS ()
3 S, K6 S# ?( l- O$ ]1 l$ n{! E2 ?' d( R# o* h( O, a
if( m_pToken) {
8 P* e6 h5 \; n* n, u   m_pToken.Release();9 v; I+ V" J2 h# T: D2 x
   m_pToken = NULL;
2 w6 b8 H& B6 ^, h+ T' ^}
7 K6 U4 l* X6 E/ j+ }* s' r+ oif( m_pAudio ) {
: U7 P2 H3 E+ v   m_pAudio.Release();2 q7 \8 m, F: s* F
   m_pAudio = NULL;2 g; i  d) Z0 g7 r4 W  x3 e# m/ A$ w
}7 w: m: b& z  w
if ( m_pOutputStream ) {
) N  t, G/ a; s9 V9 K% c2 p   m_pOutputStream.Release();
- i( Q3 L/ {. J( r% }! T6 K   m_pOutputStream = NULL;
; _9 ^; R  w' ?4 H$ ]- u/ B}6 ]/ u, `+ k/ ?/ u( I- w2 J
if( m_pVoice ) {+ Y/ Z9 I5 C4 x2 X+ {/ h  U$ K0 G' H
   m_pVoice.Release();
/ f; h2 J9 s, z( e" t: W7 V' u! B   m_pVoice = NULL;& _/ e) w/ R3 [
}; W/ Y# [0 O& M3 C3 d2 h* k+ @: X
}
! k% t' v5 i8 o# Z" K7 S0 ?; s; b: A
. z! [  m" Z5 y  a////////////////////////////////////////////////////////////////////
" n  S, n: n& E; N9 [//从SR的上下文中得到voice对象。此函数在CSR中被声明一个友员。' J% z+ E, d5 b8 M2 z& b
////////////////////////////////////////////////////////////////////2 h% v: K9 \( h
HRESULT CTTS::Create( const CSR * pSR,* P% e" J2 R% M. ~) P9 p
       const DWORD dwLanguage )8 O9 `* x+ R# c0 h. h
{* P, _1 X  `, q: a  J( i" E
HRESULT hr;
9 b/ G. }: x' M7 \! v% }hr = pSR->m_pSRContext->GetVoice ( &m_pVoice );; O7 Z) ]/ O5 d* q
if ( !::CheckHr ( hr, "pSRContext->GetVoice()" ) ) {
6 X* q0 x4 ]) b. I3 N( E   return hr;' I( X. f. M2 t( a$ |3 k0 |
}
+ S# n. {7 ^- i( G$ n" A
' F3 S4 d: w7 J# USetLanguage ( dwLanguage );# F& R/ b, l0 ]* x0 H1 Q

8 _; B$ P5 w9 b+ I5 D7 o% ?hr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流
! a9 X- u8 v9 @" j+ d* ^& Kif ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {
9 C3 H3 i5 I( G! T" j    return hr;
( _0 d5 w7 Q$ z* F% t}
/ \; {) N' p! V+ o
2 V6 k5 N5 H- p* e//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM: B7 \7 @8 M0 P7 D) d
//SPEI_END_INPUT_STREAM 表示完成流输出。
3 y/ i3 W. A+ E+ H& O' N7 lhr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |, i! `& b6 ^( F% a3 B6 m& F
         SPFEI( SPEI_END_INPUT_STREAM ),
" ?: L7 v7 f) V8 y6 n* V$ P' d7 K            SPFEI( SPEI_START_INPUT_STREAM ) |% C. q! v$ y* s* B: h* b
            SPFEI( SPEI_END_INPUT_STREAM ) );
( I) P% v% O* q0 r6 hif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
. ]7 y7 r" E  a* P    return hr;! e. K7 |0 `& ]2 ~
}- j: u: n: k+ G" `. Q7 T, _
% j, w& M# Q4 e) f+ v+ X7 Y! \
//设置通知消息# V) N" v6 S* U% c1 K2 n3 ?7 e' q
hr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
. s, D2 o% E" Mif ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {, G1 Y' t# N- y5 K/ K! K
    return hr;
. G5 b$ ?" v& t, T( O5 T}
0 Y+ L  ?7 U' A- z% b5 V; e2 d+ ~9 D  x- }+ ^
return hr;
; ~# C- ^$ Y9 R% A, v/ W}
) ?8 l9 e" z8 i# \" j& h* k9 F* D/ ?5 R$ R. a
////////////////////////////////////////////////////////////////////
8 h8 Z% g4 k' y! q//单独(相对于从SR的上下文中得到voice对象)建立一个voice对象。
. y; S; E9 y1 [& H. t//并设置兴趣,设置通知事件。* ~% P! j6 h) H: f3 ?) r9 n5 @
////////////////////////////////////////////////////////////////////* e- \& T# `; `; `
HRESULT CTTS::Create( const DWORD dwLanguage )
8 A& J+ ^, |+ ]% q9 g9 m4 C{
$ J6 K8 \: a8 @7 B" G% v! u& hHRESULT hr;! r$ D1 H" R# }' T% ~7 f
hr = m_pVoice.CoCreateInstance ( CLSID_SpVoice );
/ @9 h  m  Y$ s3 q# c  _if ( !::CheckHr ( hr, "m_pVoice.CoCreateInstance()" ) ) {7 f( |+ c9 v0 M) R# U" {
   return hr;( R7 p9 m0 ^1 T1 F8 j
}
7 p1 V4 |+ G& |7 M
+ V  j8 L* x* _' I& D3 {SetLanguage ( dwLanguage );* G: |- Y3 L; k, y( l

3 R2 C/ q5 p. ~- m( H  W1 Jhr = SpCreateDefaultObjectFromCategoryId ( SPCAT_AUDIOIN, &m_pAudio );//建立一个默认音频流9 w: a9 Z; u) V3 t6 d- F! a7 S9 w
if ( !::CheckHr ( hr, "CreateDefaultObjectFodd()" ) ) {. e+ J2 q6 d( B  K1 k
    return hr;
$ I% Y) n1 ]1 N7 F}
  \3 G0 x: a9 z( V" R2 v+ h0 ^7 s- [4 z% Q
//SPEI_START_INPUT_STREAM表示输出对象开始接受流输出SPEI_START_INPUT_STREAM
; s. ?- m( L; d' T//SPEI_END_INPUT_STREAM 表示完成流输出。
: Y# [1 S- o$ v! B. Ghr = m_pVoice->SetInterest( SPFEI( SPEI_START_INPUT_STREAM ) |
  ]# |! X8 c+ ^: y         SPFEI( SPEI_END_INPUT_STREAM ),7 H) {3 G8 ]4 e/ }
            SPFEI( SPEI_START_INPUT_STREAM ) |- j' t! b7 y; M8 O1 K$ v, B! {
            SPFEI( SPEI_END_INPUT_STREAM ) );
) P/ D( [* \  C- Qif ( !::CheckHr ( hr, "m_pVoice->SetInterest()" ) ) {
8 i4 g: w% e1 l1 V    return hr;
8 \" `1 A0 H0 B, @' I}$ _9 A. J/ `0 U/ ?; @$ w7 N
5 L7 m7 w# L" W6 b& o
//设置通知消息
) t/ j+ v2 Z6 Q4 a  shr = m_pVoice->SetNotifyWindowMessage( m_hWnd, WM_SPEAK, 0, 0 );
% Q8 q" v3 Y6 `7 v8 @- x% ?if ( !::CheckHr ( hr, "m_pVoice->SetNotifyWindowMessage()" ) ) {
2 Q& }: ^" L% N6 e4 l" h    return hr;  T4 X) ^4 [- s; A  {7 l
}
! y. ?% [  V; X9 G! `# B4 o8 F
) e7 v, D, h0 r/ L5 Dreturn hr;" }% D* S1 s$ y  d3 H5 v
}/ `8 B  N1 ~8 i( \
 楼主| 发表于 2011-5-23 17:06:27 | 显示全部楼层

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

第一个小程序
装好SDK后,我们当然要运用了,要不然我们装它干什么呢。我觉得写程序的乐趣就在于自己写出了一个能运行的程序,那种成功的感觉很好。好了废话不多说了,接下去就来写第一个能运行的程序吧。
1、新建一个Win32 Console Application空工程,在工程里面新建一个C++ Source File。
2、首先当然是包含头文件
#include <sphelper.h>//语音头文件+ Q8 s0 [3 J5 `8 @2 \
#include <iostream.h>//C++头文件,用来提示错误信息
3、然后是主函数
int main()
7 V# B5 Y" \$ U, _5 D" A$ V7 T4 t2 Q% g{/ g- X# |% q0 h* Q, R
    ::CoInitialize(NULL);//初始化语音环境+ m  O& r$ h/ P# Y
    ISpVoice * pSpVoice = NULL;//初始化语音变量
! w  A; Y, d# Q$ ?, K  K4 d    if (FAILED(CoCreateInstance(CLSID_SpVoice, NULL,CLSCTX_INPROC_SERVER, IID_ISpVoice, (void **)&pSpVoice)))  
    //给语音变量创建环境,相当于创建语音变量,FAILED是个宏定义,就是来判断CoCreateInstance这个函数又没有成功创建语音变量,下面是不成功的提示信息。
    { . ^' Z6 g' }9 p7 I
        cout << "Failed to create instance of ISpVoice!" << endl; 5 G, J* o' K0 m4 k: j
        return -1;
, F3 F& t# t6 `    }

6 f: u2 |+ d" \! J" a; f. T! U- b    pSpVoice->Speak(L"Hello World!", SPF_DEFAULT, NULL);//执行语音变量的Speek函数,这个函数用来读文字。
    pSpVoice->Release(); //释放语音变量
6 A' Z2 |- N& X* H. E( S! y    ::CoUninitialize();//释放语音环境
5 J6 q$ ?5 z& ~; J
    return 0;2 k$ j% Z9 k* y1 ~* \+ t1 q" q
}
4、第一个程序就这样写完了,运行读出了Hello World,是不是觉得很神奇呢,呵呵~~~~~
回复

使用道具 举报

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

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

VC6.0下开发Speech SDK5.1程序
4 U7 M! Z9 d& D& M; a- F, D( ?  u. w& j  P& [& J& T' h/ o: K( C
1.首先开发得需要Microsoft Speech SDK的支持,以下是下载地# B9 P; I. j% x: }, d- u
3 l6 C+ \) @) @- u0 ?& k
http://download.microsoft.com/do ... -US/speechsdk51.exe   , J3 `  x, Z) N. M
Speech SDK 5.1安装包 (68   MB)     8 w) P0 p4 a8 k2 o) L/ z; y
http://download.microsoft.com/do ... chsdk51LangPack.exe      
3 L% O" k8 @- G% H9 J- s中文和日文语言包(上面的安装包只支持英文,如果要你的程序支持中文则下载此包)(81.5   MB)  
$ M6 r7 v) j8 u5 s' f
2 ]' ^; @# ~) h3 j3 F! j7 k4 J) Y2.下载后,执行安装
, Z9 t. T8 {# E4 Z5 n( r
# G( G+ ]& q1 r& ^下载完毕后首先运行SpeechSDK51.exe,它其实是个压缩包,不是可执行文件,解压时选择解压到的路径,然后,运行解压出来的可执行文件,默认安装路径为C:\Program Files\Microsoft Speech SDK 5.1。运行那个中文语言补丁包SpeechSDK51LangPack.exe,和上面的一样过程,这也是个自解压文件,不过这个第二步不需要选择安装路径,运行一下就行。) V( H0 n% h" N: M. h; F
) Z+ }% A  V. n& F# O
3.VC的环境配置& P) o4 j2 f) N. j& E

1 W* ^, \0 V3 F6 |1 y* U8 F在应用SDK的开发前当然得需要对工程环境进行配置,我用的是VC6.0(其他情况类似),配置的过程如下:
" ?1 g5 P3 L" P$ L- i* Q. T* \
# u+ l5 E( l$ T+ r/ O4 K# ]工具->选项->项目->VC++目录,在"显示以下内容的目录"下拉框中选择"包含目录"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Include到目录中去。再选择"库文件"项,添加一项C:\Program   Files\Microsoft   Speech   SDK   5.1\Lib\i386到目录中去.
7 E  b0 n) N7 k- {# X- E& F# d5 y& G9 B2 z
好到这里为止Speech SDK5.1的配置算是完成了,接下去就可以写程序了。呵呵~~~~~~~
6 R0 ^9 b" y0 y  n
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-5-2 10:18 , Processed in 0.021931 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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