数学建模社区-数学中国

标题: 在程序中加入英文朗读功能 [打印本页]

作者: 韩冰    时间: 2005-1-26 12:57
标题: 在程序中加入英文朗读功能

4 B; v1 |! w0 i5 F% e; i 华 中 师 范 大 学 卢 小 海(flier@126.com)

, q [9 L& t9 S ~! K3 d

各位朋友,请加入本站邮件列表,你将得到本站最新更新及动态。

$ |0 m4 Y( p9 W" M9 V8 e$ x

, H. w3 l$ F/ }1 h! M ---- 金 山 词 霸2000 的 英 文 全 文 朗 读 功 能 相 信 一 定 给 尝 试 过 的 用 户 留 下 了 很 深 刻 的 印 象, 而 作 为 一 个 程 序 设 计 者, 你 一 定 也 想 在 自 己 的 程 序 中 加 入 类 似 的 功 能 吧, 因 为 那 将 让 自 己 的 程 序 增 色 不 少。 * \8 |7 B( E2 _: C- Q; d----其 实 这 并 不 是 一 件 困 难 的 事, 因 为 金 山 词 霸 实 际 上 也 只 是 直 接 使 用 了MS 的TTS(Text -to -Speech) 技 术 而 已, 通 过 对MS Speech API 的 编 程, 我 们 完 全 可 以 实 现 比 其 更 强 大 的 功 能。 下 面, 让 我 们 在Delphi 环 境 下 实 际 尝 试 一 下。

' S: J: [, J( T! k/ T

----首 先 从 金 山 词 霸 的 光 盘 上\ciba 目 录 下 运 行 并 安 装mstts.exe(MS TTS engine) 和spchapi.exe(MS Speech API)。

! J [' p* r n4 u* M& i& Y

----再 在Delphi 里 新 建 一 个Application。

5 @8 c) i a7 T/ t7 C$ T# g

----然 后 从Delphi 的 菜 单Project/Import Type Library... 中 选 击Add..., 浏 览 到Windows 目 录 下 的Speech 子 目 录 里, 打 开vtxtauto.tlb, 可 以 看 到 下 面Class names 中 会 出 现 我 们 需 要 的 接 口 的 包 装 类 的 名 字TVTxtAuto, 注 意 对 话 框 底 部 的Generate Component Wrapper 需 要 被 选 中, 点 击Create Unit 就 可 以 打 开 一 个 名 为VTxtAuto_TLB 的Unit。

- I1 ?' b( H5 }( R% f# M1 y

----至 此, 我 们 就 可 以 开 始 实 际 编 程 了。

& I; J& j6 k5 A# E3 m) x

----首 先 在Form 的OnCreate 中 对 需 要 使 用 接 口 初 始 化 并 进 行 注 册:

; f, Z( d7 ^0 ]* w! S5 D C

... 2 @1 M5 x$ y5 I5 r4 p8 r- [ procedure TfrmMain.FormCreate(Sender: TObject); v$ s* d8 _, ?0 e9 a begin) y/ A6 V& R2 Q. k) _3 F FISpeech := CoVTxtAuto_.Create;' r. i# a6 }. D' O* _4 [+ }4 Y* f: c FISpeech.Register(‘Demo Site', ‘Demo App');" b7 B$ c$ [# H; r end;! [# i2 k: r0 E3 f ...

9 X' @2 ]# o1 Y2 L% y1 \) v1 m. b! Q

----由 于Delphi 对 接 口 进 行 了 良 好 的 包 装, 因 此 只 需 直 接 建 立 包 装 类, 其 他 后 台 的 操 作 如 接 口 的 查 询、 释 放 等 交 给Delphi 在 后 台 自 动 完 成。

6 s6 a6 A) T2 N/ V8 ~0 P2 h& i* b

----注 意 这 里 的Register 操 作 是 必 不 可 少 的, 因 为 可 能 有 多 个 程 序 不 同 设 置 使 用TTS 引 擎。

1 o1 i, \/ C) N8 j* n

----然 后 在MainForm 上 放 一 个TMemo 和 若 干 个 TButton, 并 在 其OnClick 中 加 入 对 应 的 代 码。

$ D, k ?3 X) {

Form 定 义 如 下:

3 F. x: J' j+ g) \* T; u

object frmMain: TfrmMain + w8 `" L! Z) \' i6 P; M9 U1 m Left = 2960 b$ C- q" I6 Y5 H2 ~" |" W, h, L Top = 187# A0 P5 |6 `: C3 P: K- p BorderStyle = bsDialog% O! p9 p: b0 v9 J7 v% A8 W Caption = ‘ 英 文 全 文 朗 读 演 示' ! y- ~5 e& {, |/ U ClientHeight = 185 * Q+ b+ {9 M' e5 T ClientWidth = 456 6 C0 L9 E$ T4 a+ q1 s% |/ \$ K7 Y& [ Color = clBtnFace/ M* L1 |! q% A! J0 D u Font.Charset = GB2312_CHARSET G8 p' {- g; `* C, R: a3 t Font.Color = clWindowText 8 h: b4 @. U) \8 c5 t7 S Font.Height = -12 0 A0 t& {0 \2 q4 ]8 T4 g0 p Font.Name = ‘ 宋 体' : O: o- j2 A y Font.Style = [] 6 T5 Q: i( U* H7 I) L* f3 i- A0 ?3 L OldCreateOrder = False' D5 j3 U4 J2 w. i: c. b) ^/ f Position = poDesktopCenter . a+ Q* }" ~" a& S$ o# e OnCreate = FormCreate% Q6 `" ~% O6 Z4 t+ |( B( P PixelsPerInch = 96 ' n8 P% K K0 M) W8 I TextHeight = 12( l1 a5 d# h' v/ G! p object memText: TMemo ! ~) T$ ~$ m2 ?, [7 @5 [ Left = 8 6 r2 z0 T- r9 J2 J Top = 8 & v8 N, X- R1 n* r) H) | Width = 361 $ Z$ a' T+ t0 p/ W4 v5 ]2 P; l% K Height = 169 ( @; |) R1 h- z3 k5 n3 a/ ^ ScrollBars = ssVertical , ]9 ?1 L. n& ] TabOrder = 0 , {! }1 K; d4 h1 E- f. u end6 X% R8 C6 D% I! Y9 | W0 o object btnRead: TButton4 {8 x1 [) A) y Left = 376 3 y0 R8 Z# c, w4 O4 ?7 Q Top = 82 b5 t1 i( F5 m" L' z# k* x Width = 75 7 \" k- N- P4 r0 b/ |+ U% l Height = 25 y/ ~) s) [1 a8 C0 z1 w Caption = ‘ 朗 读( &R)' : v5 p. ^8 m( n3 @' W5 f TabOrder = 1 4 ]8 e/ N! ~& y$ O OnClick = btnReadClick $ j7 E# s- Q) \" U end " l- w4 [% ~! o& s0 s, h object btnPause: TButton' s+ t3 i. E& }: e0 G" B( r3 ~2 L) t; L Left = 376 & ~. I( |! E$ _, b Top = 400 i! h* B: g5 ?: b Width = 75( I2 _8 F" ^7 k8 t/ H% o Height = 25* n6 I& N/ x( \7 G% m5 S- X Caption = ‘ 暂 停( &P)': u+ I$ K% Z5 M* W0 g- k+ i& o2 g Enabled = False" I- j" N& r( e' ?6 n k0 R1 R TabOrder = 26 p& m" c" U6 U2 E OnClick = btnPauseClick 0 s* |. v3 T. @0 ^ end" d( ^" V* h( w( X. m" Y object btnStop: TButton $ s0 v2 k8 {6 l& O6 b7 ?, \8 ^ Left = 376 * P( `! V1 O3 y# D# ? Top = 72/ G; @0 d. u: R4 } Width = 758 B1 U' t$ L4 Z. `- w V+ r0 ^. P Height = 25 ( d0 N3 d4 t* H, d9 T% y Caption = ‘ 停 止( &S)'- V9 |* d$ u1 K! t6 E3 e Enabled = False # j9 ]/ I0 {$ O TabOrder = 36 }* _1 G: b* C8 ]; c OnClick = btnStopClick7 g i# g, N H7 k7 ]* j8 H end3 ^% j1 z2 g4 m7 v" V+ U! ^ object btnForward: TButton+ |: l2 b: p: v, m- S9 f& D3 T Left = 376- O1 Q. l3 C* L! y$ S* } Top = 120 % |! K: o7 T1 H Width = 758 N! a* T% }4 L% S Height = 250 E) I* v/ C K/ e/ U5 m. \ Caption = ‘ 下 一 句( &N)' * u- d3 T2 O! E- K, S# r, c Enabled = False+ N/ e" [6 [. c9 R+ C$ E. Y2 Q TabOrder = 4- r; E( |0 l: I, L7 x( f OnClick = btnForwardClick 4 e/ E* o: A' [- {. | f end' }% O6 ~) \" \$ w object btnRewind: TButton # E/ P3 y! b2 Y: c4 W% Z& _ Left = 376! q2 n7 R! u( f Y0 B# \" i6 D Top = 152 & r) J& m; i: H6 _# m( P/ M% ] Width = 75 ( t. r( V$ ^7 \/ [+ L0 |7 y Height = 251 y" F/ h& N5 m3 t/ ^% J( K Caption = ‘ 上 一 句( &W)'7 t( ]" b7 C! a9 I1 A3 | Enabled = False6 h$ ]. U# \7 `& ]' M9 E TabOrder = 5 8 F3 R ?: L4 X1 l! E7 w4 V5 C OnClick = btnRewindClick 2 D3 Z8 b( d* Q$ c$ i' H8 A2 I end 1 [8 C2 g, ^3 a) l end

( ]9 n2 \8 Y- y; ]

----关 键 代 码 段 如 下:

! O: g7 S2 p m' V

---- 1. 朗 读 与 停 止

8 ~* T. {2 S. d+ I' Y

... * x9 w4 r2 m$ G6 m6 iprocedure TfrmMain.btnReadClick(Sender: TObject); 1 a) \$ D$ t# ^+ F% e. v2 M; X begin" v: ` F8 q3 B- F. i9 D FISpeech.Speak(memText.Lines.Text, vtxtst_ 2 ~6 e& |6 Z% U7 R! W# z& N/ ?% N7 cREADING);& n% ^" ]( P, T2 c+ o4 t4 \- ?7 R btnPause.Enabled := True; z6 S6 s r7 h9 y& \: K$ F btnStop.Enabled := True;$ u$ u2 J" a; Z0 W9 m `5 y end;5 R! i* G. t; o% g0 x / J3 Q/ ?, x4 ?( c4 j' e5 x, @ procedure TfrmMain.btnStopClick(Sender: TObject); , V2 y0 X8 V+ }* w3 M. W& S begin3 w$ V# F1 j4 H) l, c2 H+ u9 z8 V9 w* ` FISpeech.StopSpeaking;9 [. C: V& {/ A) [# N btnPause.Enabled := False; % D }( Y& t" G: G$ E' c btnStop.Enabled := False; . r. w8 _* Q& G0 a btnPause.Caption := ‘ 暂 停( &P)'; 6 S0 m2 S7 L3 { end;: J2 y, p3 W1 H, c ...

8 [& ]- s, i C/ |+ B

----Speak 成 员 函 数 的 第 一 个 参 数 向TTS 引 擎 传 递 需 要 朗 读 的 文 字, 第 二 个 参 数 由 指 定 朗 读 时 使 用 的 语 气 和 优 先 级 的 两 个 符 号 合 并 而 成。

3 B% o* F' W3 p# M6 y8 G% T / @3 B5 h, o+ B9 c/ v

---- 2. 暂 停 与 恢 复

7 v4 J% F1 [( E5 i

...: Y5 e% u# { N% }3 s procedure TfrmMain.btnPauseClick(Sender: TObject);# f# S6 p% e$ I% i' D begin$ `5 G/ @. l8 n- f with FISpeech do 3 e6 \5 e3 j- t: F ` if IsSpeaking then+ t8 \" ^. {; [9 ]* g& r begin % e% l: K y9 ] AudioPause; - c6 A; |7 b6 ?& Y; d btnPause.Caption := ‘ 恢 复( &R)';$ h( T+ E: k% I! a' [. _7 A end7 R5 w# a+ B1 n9 {/ Z9 Y else 2 ]: v& i& f% Y, m begin. x1 o- H, f. M A- V- O/ s+ l AudioResume;2 _& O4 e" N+ g! t' L btnPause.Caption := ‘ 暂 停( &P)';0 I( A: }: C7 k# h end; 9 d6 }+ d- v \/ k$ L- E+ Oend; 0 R+ C+ u% e" Z4 X- r$ m, A, U...

' m4 B9 M4 j B+ U+ `3 t

----这 里 通 过IsSpeaking 属 性 可 以 取 得 当 前 状 态, 然 后 通 过AudioPause 和AudioResume 暂 停 和 恢 复 朗 读。

0 i3 Y1 p9 D+ e E% D+ R

----另 外 用 成 员 函 数AudioFastForward 和AudioRewind 可 以 向 前 和 后 跳 过 一 句 朗 读, 通 过 读 写Speed 属 性 还 可 以 取 得 或 设 置 朗 读 的 语 速, 单 位 是 字/ 分, 缺 省 值 为170。

) v( I0 f# k+ r; ? w9 s" M0 N

----注 意Speed 和Enabled 属 性 缺 省 设 置 是 只 写 的, 但 实 际 上IVTxtAuto 提 供 了Get_Speed 和Get_Enabled 函 数, 所 以 我 们 只 要 把VTxtAuto_TLB 单 元 中 的 声 明 修 改 一 下, 如:

. S4 F" y- Z4 Y( @0 k3 l$ E6 S

... 2 W( _: l& C% P+ xIVTxtAuto = interface(IDispatch) 5 }) `- K) b: L( W ...: E( g7 d- ~4 s" J2 o" F6 `8 q property Speed: Integer read Get_Speed write Set_Speed;5 G* o2 L' B8 i1 r property Enabled: Integer read Get_Enabled write Set_Enabled;0 j: _$ Z L `; d& o) Z ...0 t1 A: i2 h1 e/ W end;- P- O; g+ C4 D( P ...

* W# Y8 P! m. P. U" d

----即 可 正 常 使 用Speed 和Enabled 属 性 了。

9 ?5 h2 w' W4 E- d0 ]% ]: h

----至 此, 一 个 简 单 的 英 文 全 文 朗 读 器 就 完 成 了, 有 兴 趣 的 朋 友 可 以 为 其 加 入 监 视 剪 贴 板, 热 键 激 活 等 功 能。

S v( S% B& \0 U" B$ Q% O

----本 文 程 序 在Win NT/98 + Delphi 4/5 环 境 下 调 试 通 过。 9 w" k% c$ l b* o 7 @, r- e) O* B) t






欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5