|
& y f4 |* I+ Q3 P华 中 师 范 大 学 卢 小 海(flier@126.com) ) @ |! n! ~% ]. y
各位朋友,请加入本站邮件列表,你将得到本站最新更新及动态。
0 K. E0 j) d; f0 G- J. E- ]% Q( S
/ J: {' W0 M7 t1 k1 p& _ ---- 金 山 词 霸2000 的 英 文 全 文 朗 读 功 能 相 信 一 定 给 尝 试 过 的 用 户 留 下 了 很 深 刻 的 印 象, 而 作 为 一 个 程 序 设 计 者, 你 一 定 也 想 在 自 己 的 程 序 中 加 入 类 似 的 功 能 吧, 因 为 那 将 让 自 己 的 程 序 增 色 不 少。 ' h" V- a2 j/ z) h& C
----其 实 这 并 不 是 一 件 困 难 的 事, 因 为 金 山 词 霸 实 际 上 也 只 是 直 接 使 用 了MS 的TTS(Text -to -Speech) 技 术 而 已, 通 过 对MS Speech API 的 编 程, 我 们 完 全 可 以 实 现 比 其 更 强 大 的 功 能。 下 面, 让 我 们 在Delphi 环 境 下 实 际 尝 试 一 下。
. {( _0 K' |2 {----首 先 从 金 山 词 霸 的 光 盘 上\ciba 目 录 下 运 行 并 安 装mstts.exe(MS TTS engine) 和spchapi.exe(MS Speech API)。 : ]9 ?/ C) R- l; a% d$ H5 {' ~
----再 在Delphi 里 新 建 一 个Application。 0 _0 O: J* B3 E, ]. W
----然 后 从Delphi 的 菜 单Project/Import Type Library... 中 选 击Add..., 浏 览 到Windows 目 录 下 的Speech 子 目 录 里, 打 开vtxtauto.tlb, 可 以 看 到 下 面Class names 中 会 出 现 我 们 需 要 的 接 口 的 包 装 类 的 名 字TVTxtAuto, 注 意 对 话 框 底 部 的Generate Component Wrapper 需 要 被 选 中, 点 击Create Unit 就 可 以 打 开 一 个 名 为VTxtAuto_TLB 的Unit。 , w# h6 k( o, w9 f6 z% ]) A, d
----至 此, 我 们 就 可 以 开 始 实 际 编 程 了。 ; x4 A3 h2 B N0 [, Z" y: e( H
----首 先 在Form 的OnCreate 中 对 需 要 使 用 接 口 初 始 化 并 进 行 注 册: / ]6 E" Q3 s8 z9 |5 |- M
...6 j/ k J% Z( c
procedure TfrmMain.FormCreate(Sender: TObject);
5 ~- ~5 j0 D- y: z& n7 D- P8 a6 g begin
0 {, Q0 B' N' i& T' ~& l6 L FISpeech := CoVTxtAuto_.Create;
! V( e% F Y4 N: P9 F FISpeech.Register(‘Demo Site', ‘Demo App');" O) [( A0 z( @( m2 { C
end;- \2 B" k- p% p& C. S1 i8 e* G+ e [
... # D+ g6 s) y/ D8 i5 T: r
----由 于Delphi 对 接 口 进 行 了 良 好 的 包 装, 因 此 只 需 直 接 建 立 包 装 类, 其 他 后 台 的 操 作 如 接 口 的 查 询、 释 放 等 交 给Delphi 在 后 台 自 动 完 成。
# E9 h, u& C3 V: n3 Q----注 意 这 里 的Register 操 作 是 必 不 可 少 的, 因 为 可 能 有 多 个 程 序 不 同 设 置 使 用TTS 引 擎。 3 J- T$ o! [: F* n% B; `2 |* i) [
----然 后 在MainForm 上 放 一 个TMemo 和 若 干 个 TButton, 并 在 其OnClick 中 加 入 对 应 的 代 码。
* ~' T5 B x7 D( C6 zForm 定 义 如 下:
9 a' S! ?- Y! t object frmMain: TfrmMain
3 ~0 \& ]: e. e4 ] Left = 2960 M7 h( B+ O: [$ Z$ ^' g
Top = 187
. Z# J i' ?7 j5 r n/ Z- G BorderStyle = bsDialog( ?0 p6 I, `7 h0 ?3 A3 n, C
Caption = ‘ 英 文 全 文 朗 读 演 示'
$ b% [, B% D. h ClientHeight = 185/ L2 L& }4 p( M0 ~" P
ClientWidth = 456
8 E& K; ?2 \% o7 b6 _! \& `& Z# m% n Color = clBtnFace3 M6 _& p, X: U8 s" v
Font.Charset = GB2312_CHARSET
' t O( z+ F& N" F9 }* q- ^( J Font.Color = clWindowText4 C1 i, X2 Y- l( `; u% |+ V& Q
Font.Height = -12" B8 ?, U3 l7 g7 a: q# {9 [
Font.Name = ‘ 宋 体', v1 q( W: h+ |) H
Font.Style = []6 _! s2 f6 F, G8 [, J7 u+ W
OldCreateOrder = False) {1 O0 e. ~$ k5 t) o
Position = poDesktopCenter2 ~0 d0 E* B6 C# B
OnCreate = FormCreate
; D5 f8 L$ ]3 I, { U PixelsPerInch = 96
5 a- s" O0 {9 S: G) K. q' x7 D TextHeight = 12* z+ N( M7 O4 M0 @+ K }
object memText: TMemo0 h# {+ e; r7 m& K" b
Left = 88 v9 L/ K( y5 C7 V
Top = 8! Y0 ~3 v2 {5 W+ l1 a# c8 k
Width = 361. M; j! O2 B% D' b' G
Height = 169
! n/ t! Y1 m, }9 h: Z) ` ScrollBars = ssVertical
. j0 L+ H% R. D2 o# z* e TabOrder = 01 x3 F1 [& n( N! V* B0 N8 O' |% i
end1 @) T( ~4 b a3 E0 f
object btnRead: TButton! ~& P L/ i4 x& @
Left = 376, [0 D7 T5 e k$ T1 K! \1 A
Top = 8
) c& n+ V. D9 V8 x Width = 75
2 ]; b9 s: r! K7 Z$ e! I Height = 25
2 g( ]; k$ D: E2 F8 M Caption = ‘ 朗 读( &R)'2 k4 t+ d; D( P: e
TabOrder = 1: L# }8 \. J u6 ^1 |, t. f3 t
OnClick = btnReadClick" I3 M7 N, R- Q6 Z2 R6 f3 T0 K8 b
end+ ?% L8 [: u2 [6 n! f: a
object btnPause: TButton
; |7 g$ C& c/ w Left = 376
9 C, e. P/ ^/ R# [/ j" } Top = 400 o. a5 U' p# s
Width = 751 Y5 t, }8 W5 F; \% P* E ]
Height = 257 u2 ^6 z3 }" D9 L4 t' G& C
Caption = ‘ 暂 停( &P)' t% R2 V/ n" R6 g) w
Enabled = False, A; v2 ^- i# G) w- n( k, q/ y7 Z/ m
TabOrder = 2
: |) m1 [- Y$ a A OnClick = btnPauseClick3 J6 [$ @( r5 C0 O
end
9 m9 O$ M/ |0 M* ^- p, F2 C& E object btnStop: TButton
, M3 c# G; e% J* J% W" r1 F Left = 376( v. T- P7 @( k7 [1 a r
Top = 72! E0 p4 H! D1 Y" I1 e/ E2 f
Width = 75
4 w ]& i) @3 }) w4 R2 y8 K Height = 25
; O1 }1 I {9 D' v/ J$ O Caption = ‘ 停 止( &S)'
9 \ b& f# p+ h2 K+ O- }, k Enabled = False
" R; ^' n) a. C( a! c/ E# ] TabOrder = 3
8 p4 N2 f: m& J! {- ^; x% |0 a! w OnClick = btnStopClick* M+ F# I' i5 q- F& X" i
end
& X# p* h! v6 a/ ~* ] object btnForward: TButton
$ L0 Q8 T% `( q J( i4 i Left = 376
I& N" c" E- P* D1 w Top = 120
# w! W3 z4 U" l, H3 d9 F Width = 75
^4 u+ \0 c5 O Height = 25
6 _+ u# e& b& X( o6 w s. o. H Caption = ‘ 下 一 句( &N)'3 u( E/ k3 l7 w0 ^4 M$ g F- }. A5 }
Enabled = False8 d" s6 E4 H" l7 D& T4 _ E9 @
TabOrder = 4$ ]2 A0 g, H' ^2 ^
OnClick = btnForwardClick# h4 R: ~- W, q
end7 e& T- [- z0 S# d- @2 `
object btnRewind: TButton
2 N l% ]2 U9 }$ E! @ Left = 376
6 e6 o) S" r0 O7 e Top = 152" ?) m+ `1 l+ @4 V( P2 t! [4 d4 F
Width = 75
3 r' {" @: g: L$ k Height = 252 I3 { ~+ l) W, A3 H) M# P
Caption = ‘ 上 一 句( &W)'4 ~4 I' l4 ^* O/ e4 X$ B* K, B
Enabled = False/ G0 y3 A5 W6 j; O0 _+ }1 d
TabOrder = 5
c! l+ f" `# r- m/ r3 S4 [. h OnClick = btnRewindClick
( W4 Y3 S- h: M end2 d' f1 b3 K% k. r; C' }. R% }0 N6 R
end
% N: d, x+ [1 E$ h----关 键 代 码 段 如 下: - L0 W& h5 ~$ a# o4 J
---- 1. 朗 读 与 停 止
& S4 u' `2 z2 x+ J2 I3 \" Z% _ ...! H. G# }4 s; F; q ^
procedure TfrmMain.btnReadClick(Sender: TObject);
/ _% E( h) q8 }5 O' Z0 U- t" P begin- ^' L: y6 i% t1 |9 Z8 h
FISpeech.Speak(memText.Lines.Text, vtxtst_ % w* s3 c3 y% a* J! x5 t" e
READING);
: ]6 @; z7 J. Y6 C( q& P+ g# G% i9 t btnPause.Enabled := True;# t: X3 ?8 q. s2 _, n
btnStop.Enabled := True;
5 c) U. l/ U F7 Y7 y- Q$ \ end;
% E1 {2 }% i/ w2 O8 V( _$ K4 D$ { - U* u! {5 H. I$ e% x/ g
procedure TfrmMain.btnStopClick(Sender: TObject);
% e; M8 x" j9 c% F ? begin
1 m1 [- @, s& D FISpeech.StopSpeaking;
3 n, }" O0 _) B4 v, Y( B btnPause.Enabled := False;* O. z7 S3 f3 w: _9 g ]
btnStop.Enabled := False;
8 s1 v4 [6 L" I( S- u) @, S btnPause.Caption := ‘ 暂 停( &P)';
, U# m, r$ m% }9 n7 D/ e% G9 j end;
# O2 q+ [2 `3 C/ r7 v$ o, T ...
5 ?9 t2 P9 d9 A$ g----Speak 成 员 函 数 的 第 一 个 参 数 向TTS 引 擎 传 递 需 要 朗 读 的 文 字, 第 二 个 参 数 由 指 定 朗 读 时 使 用 的 语 气 和 优 先 级 的 两 个 符 号 合 并 而 成。
6 ~& R/ B4 a2 h9 m; E& y4 M4 f' { e1 v) i9 @; C
---- 2. 暂 停 与 恢 复
1 l4 @" r$ C: `! a" |( H- B; z ...
! A7 A" j: V3 o9 z0 v0 S7 o" Rprocedure TfrmMain.btnPauseClick(Sender: TObject); w' ]6 P" {/ J& `! H- Y
begin; ^" L; c1 z) J4 B# g2 z3 e
with FISpeech do
! o, B% z/ w8 t+ B if IsSpeaking then* ~/ ]' D7 B0 M: V' G
begin
" w) M# |5 e9 B# ]6 _ AudioPause;
' K, l- Y z& `% K" U! ~- ~ btnPause.Caption := ‘ 恢 复( &R)';
1 q3 L y. H# [/ S0 R) A& e end
4 u$ @6 [" @5 x: g" N6 R, U else" T9 N. a* i+ ]- T+ i$ T! b0 _' J
begin, Z. r. {' i! A* u/ I% o- o
AudioResume;
6 E G+ u8 k% \, z1 j btnPause.Caption := ‘ 暂 停( &P)';
8 d) f8 W& C. I end;
1 z$ b5 ?) R1 i; ^8 L9 Y: y$ d9 ~. Qend;- B6 T; M; {) d9 C
... " `) `7 C1 s# J% |1 Z' k
----这 里 通 过IsSpeaking 属 性 可 以 取 得 当 前 状 态, 然 后 通 过AudioPause 和AudioResume 暂 停 和 恢 复 朗 读。 1 X0 A! d9 v7 W ], B- l
----另 外 用 成 员 函 数AudioFastForward 和AudioRewind 可 以 向 前 和 后 跳 过 一 句 朗 读, 通 过 读 写Speed 属 性 还 可 以 取 得 或 设 置 朗 读 的 语 速, 单 位 是 字/ 分, 缺 省 值 为170。
7 q$ g" f9 |0 r2 u" A----注 意Speed 和Enabled 属 性 缺 省 设 置 是 只 写 的, 但 实 际 上IVTxtAuto 提 供 了Get_Speed 和Get_Enabled 函 数, 所 以 我 们 只 要 把VTxtAuto_TLB 单 元 中 的 声 明 修 改 一 下, 如: * Q+ }) i5 j+ @1 }/ f
...
" z/ e, \# j/ V: k, {" t) OIVTxtAuto = interface(IDispatch)
( ^2 A/ N7 g6 S! ?; ~ ...) J1 K4 d- y) n: z$ m( k
property Speed: Integer read Get_Speed write Set_Speed;4 U4 S6 |( g( N5 z: i2 Y" S `8 L! y
property Enabled: Integer read Get_Enabled write Set_Enabled;( l v4 n/ A, I- I$ z* S3 L* a9 t
...
0 z, t: A9 J2 m/ k+ n% ~6 \end;# V: c9 F& A* A) K; ?; }
... ( e( L" k! z2 S* F8 e4 h
----即 可 正 常 使 用Speed 和Enabled 属 性 了。 . i" [8 A( Y0 y, Q, |
----至 此, 一 个 简 单 的 英 文 全 文 朗 读 器 就 完 成 了, 有 兴 趣 的 朋 友 可 以 为 其 加 入 监 视 剪 贴 板, 热 键 激 活 等 功 能。
+ ~+ V8 Y4 h; q! }7 x g4 [----本 文 程 序 在Win NT/98 + Delphi 4/5 环 境 下 调 试 通 过。
4 j! o- u+ [2 N! m 0 w% Z" K$ ~6 k, a& b
|