数学建模社区-数学中国

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

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

- @! b) W# [& m+ L6 d 华 中 师 范 大 学 卢 小 海(flier@126.com)

! Z* o& N, @$ Z$ a1 m7 R( `

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

& y0 E* Z I, `. ^9 [9 W# g4 L

+ f- x- [6 s3 \7 R0 |8 G Y ---- 金 山 词 霸2000 的 英 文 全 文 朗 读 功 能 相 信 一 定 给 尝 试 过 的 用 户 留 下 了 很 深 刻 的 印 象, 而 作 为 一 个 程 序 设 计 者, 你 一 定 也 想 在 自 己 的 程 序 中 加 入 类 似 的 功 能 吧, 因 为 那 将 让 自 己 的 程 序 增 色 不 少。 6 O' ]) O# g& ~" z# z ----其 实 这 并 不 是 一 件 困 难 的 事, 因 为 金 山 词 霸 实 际 上 也 只 是 直 接 使 用 了MS 的TTS(Text -to -Speech) 技 术 而 已, 通 过 对MS Speech API 的 编 程, 我 们 完 全 可 以 实 现 比 其 更 强 大 的 功 能。 下 面, 让 我 们 在Delphi 环 境 下 实 际 尝 试 一 下。

( R4 g1 M* h) J

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

* _' g* @6 F! v6 t0 Z: P* {, J5 e" P

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

& p* v! @: v0 q

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

) g" \8 a% ~2 f9 B" K% M2 L8 J

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

8 |6 l) ~5 C9 H: v" N3 N2 B: x7 ?

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

! y( G, J* _$ O5 f6 g% O* F( E

... , H) d& H: | C e procedure TfrmMain.FormCreate(Sender: TObject);7 u. }- Y, J9 d+ K% h- @ \+ K4 B" W begin% p: l1 n( I! F0 C* g+ w FISpeech := CoVTxtAuto_.Create; & z8 I9 Q% {0 G+ c1 f7 j3 S- q1 @ S FISpeech.Register(‘Demo Site', ‘Demo App'); 1 G; }8 x6 F3 }0 o2 U( o" r' C$ D Z end; 7 N1 _& Y$ E2 A9 T2 t...

4 r; r8 K) [5 l, F) E

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

7 _: m g# B1 U7 N8 i9 o0 f

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

$ H4 I/ q9 J* G4 c: N$ ?. P

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

, m8 D7 R1 I3 X0 o& Z

Form 定 义 如 下:

M! l& S& D! j' ~, }* [

object frmMain: TfrmMain % u% i0 S* t) V9 O$ o c Left = 296$ U/ [, J4 h+ t+ | Top = 187 2 z, `, y: L5 o2 \$ h4 e5 B BorderStyle = bsDialog) b3 C4 U4 h% g Caption = ‘ 英 文 全 文 朗 读 演 示'5 \/ c1 x2 o0 L( k ClientHeight = 185 7 w( l4 m- L1 |' J/ p0 v8 ~9 H# n ClientWidth = 4565 s+ ]8 `% r$ z2 \4 X8 J, A/ q Color = clBtnFace6 ]4 D0 q2 ~& }* _ Font.Charset = GB2312_CHARSET 1 H: ~4 t a( {& g Font.Color = clWindowText 2 X8 a1 C' l+ c* d7 V; h Font.Height = -129 x' b9 V% H: F+ u l& s Font.Name = ‘ 宋 体' 3 D4 N U* U; h8 m* L7 I" c# o Font.Style = []$ T3 T, p5 b2 v1 ]* y OldCreateOrder = False$ W2 W9 s3 k+ \ Position = poDesktopCenter ( \0 ?: j! d4 I; i" A3 R* Q( Q OnCreate = FormCreate u' x4 [% e+ I% S PixelsPerInch = 96 9 b, U0 M- j. Y8 y0 G H TextHeight = 12) \' _% w7 Z1 M5 A: c object memText: TMemo # }5 x; d& z8 s5 P" S+ z Left = 8; Y4 y4 b$ V9 G) i7 n5 l Top = 84 [5 `, |8 b7 c* X) t T( } Width = 361 , D* K2 i/ l( e# y Height = 1692 f3 A; L: L9 o3 x, W ScrollBars = ssVertical) r6 \1 @% d2 J( ~ TabOrder = 0: k2 H% p5 Y: n% j end ; j( S* `6 o/ j: k) R6 ]$ i7 ~ object btnRead: TButton+ ^" P" D- ]6 f( C' o/ n% I Left = 376 # G. ^$ G& A# D5 q: d4 K3 _: V# K Top = 85 c& N1 y9 c+ w9 Q, X. G Width = 75 * {$ o# r, L$ B% ?; z Height = 25 / u W2 X% @1 s. O8 |7 U2 c2 M Caption = ‘ 朗 读( &R)' # k+ q4 \4 ^* h) ^ TabOrder = 17 S! E E k- K; @. d+ A/ u; i5 o OnClick = btnReadClick 9 W/ k6 O& `: q K( I3 {1 _9 p, P end 3 G& ?- Q8 o1 ^0 { object btnPause: TButton 1 t2 D* c8 `- S4 T" m Left = 376( S; f3 u6 d3 K3 c; P Top = 404 P! n0 I/ U9 Z& Q; ?; d7 d/ ~ Width = 75 ! q# G; g9 R0 L0 ?' Q$ ~! y: m; ?' Y Height = 25 7 B- y" G; ?" v; n2 S1 ] Caption = ‘ 暂 停( &P)' + I; \' _9 C% [2 O! G Enabled = False , @6 [/ z# _ D% c! M TabOrder = 2 & K/ M% n5 M; k7 j: U% z+ V OnClick = btnPauseClick ' K: D( F( `$ B end 8 p: E# p0 }7 ?# V/ U) X3 k object btnStop: TButton ) h$ E& A1 E) G) M7 R( W5 X5 b Left = 376 $ j$ z& c& B% H: a5 n% K+ [5 w Top = 723 a3 N- Z" A/ X8 O1 b& q, K: N: x Width = 75 4 V) R* j" U* M: P+ g4 j* o Height = 25) H" i" ~2 O- w7 [ Caption = ‘ 停 止( &S)'! p7 `+ U s3 N2 Q# q2 D2 |9 Q Enabled = False I! o6 f" z; k% ^& J7 e TabOrder = 33 L3 }* y. l; P OnClick = btnStopClick7 \0 B; M! F9 Z- S9 A4 I end 6 l {) k! ?( N" O2 b4 x( K& M object btnForward: TButton0 ~4 f$ K5 m2 d5 i. B Left = 376 4 T |+ `( \# j# w( l; G: ]+ N Top = 120! v) }# h. ^+ z1 ^5 I4 ? Width = 75! f, ^6 X3 E+ T Height = 25" f" H5 w7 E# {8 t Caption = ‘ 下 一 句( &N)'$ f! w9 }7 `: {* r K4 { Enabled = False ' P7 o9 [) q2 |! w TabOrder = 4 . `( w4 V9 e0 g0 c) Y! w; ^& m OnClick = btnForwardClick ) f7 V# Y6 I7 L1 | end9 T1 O3 w( B, ~& m, A object btnRewind: TButton ) Z M1 O) s' F" e+ j; N0 Z, l Left = 376 & ]+ y. e: X, W- f. }- p2 {7 z Top = 1529 {4 L' h' L2 F( L4 @ Width = 755 J/ k/ i1 U2 H# _8 Y. J8 E' L Height = 25+ |/ {9 Y$ F6 l$ \ Caption = ‘ 上 一 句( &W)' ' T |5 f+ }, m5 I* u+ g Enabled = False ) w, p; n3 `$ D TabOrder = 52 @/ g) M6 Z7 o* s OnClick = btnRewindClick6 s$ d, R/ D: Y end4 K& f3 W% r$ E0 p. @ end

5 `9 @5 i2 O8 f4 _. p

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

' i- M t$ d! c" @

---- 1. 朗 读 与 停 止

8 j1 J3 ]. N+ O6 f3 O9 ~

... % D# b% k- K1 @procedure TfrmMain.btnReadClick(Sender: TObject);, `( I3 c m/ P) o" i D begin8 u" O3 P8 `, ~2 v0 c FISpeech.Speak(memText.Lines.Text, vtxtst_ ' e& n. o2 A- j; L. k0 [ READING);+ X. A7 T- S; s6 X, H2 N btnPause.Enabled := True; 2 n }2 d% W, m* v1 Q. t: d0 b btnStop.Enabled := True;6 h) r, S, P E3 i end; & @4 [2 Z. z7 I; t 0 ^9 r4 ^% X3 b( g0 X procedure TfrmMain.btnStopClick(Sender: TObject); * U. ^1 s% L- m7 O' n$ J begin5 A4 Y+ {5 k- R0 d& Z0 } FISpeech.StopSpeaking; 7 N9 {0 o! ^7 M( X3 E- o( n1 r btnPause.Enabled := False; / |% ~5 K. X8 p$ w* t% c5 b6 T btnStop.Enabled := False; ' u6 E2 d( B$ E( K- b; b btnPause.Caption := ‘ 暂 停( &P)';- A! H+ c/ M7 F3 s end; 9 ?8 P6 |$ r+ M$ ?% S ...

4 u$ k2 S4 T" K: K3 e

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

; [5 R" N! d9 B7 G2 ~! ?6 [8 s. F7 F , S, X9 Q& {8 ~

---- 2. 暂 停 与 恢 复

# s' w% r Z2 W& W

...# J. k; g9 V) \/ w7 n4 b; R procedure TfrmMain.btnPauseClick(Sender: TObject);8 d8 S7 t1 [1 H. m4 R3 z+ O begin 9 O- f" j) o8 W) g4 P with FISpeech do/ F j# u; v, q0 R: E, u- t if IsSpeaking then" y; G3 D. W& N* F. E begin) M: ?, U* q3 Z' q" e! M# C AudioPause; $ K5 y4 I. m' W7 p1 p1 c" v btnPause.Caption := ‘ 恢 复( &R)';* ]. o. U n& R# b# S end " G. R* \9 h n else 6 J r3 M" I6 ~% l: v4 f- Q2 c begin+ ?4 [0 I# G5 X4 {. b AudioResume; - J" {) c+ _9 Y- d( G btnPause.Caption := ‘ 暂 停( &P)';* r, x: a3 d3 r1 g. O end; 9 D8 [$ R6 Z2 H; g7 \+ Mend; 1 e4 }2 X( `* Z0 g9 ?" q& W...

1 _. M' r' [1 c' j* f! Q+ C

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

2 b1 x& H, S1 }# B$ J

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

) l' c9 n( S q9 }! k0 M, N

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

3 O8 G4 A1 M: N( l" L

...8 [0 f- E6 E- d0 [ IVTxtAuto = interface(IDispatch) , [& e/ G5 _$ N( | ...) I8 g I) k* k- Q6 @9 I property Speed: Integer read Get_Speed write Set_Speed;2 N: Z/ v' n' @ property Enabled: Integer read Get_Enabled write Set_Enabled; # s/ [" Y2 ~5 z ...3 e" C! y2 i8 Z' _- K8 r" J end;# j# i" u; h. Y7 f ^ ...

7 N% e [5 \5 R$ t. K- |

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

- G# K) K& c. e) g3 E6 u% [8 W b" M

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

+ x- U$ D- p+ d" m( D0 G

----本 文 程 序 在Win NT/98 + Delphi 4/5 环 境 下 调 试 通 过。 * K9 Y3 l& E9 g# d % H- J2 i. v z& v1 m) S






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