数学建模社区-数学中国

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

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

9 E, t0 {+ X$ n华 中 师 范 大 学 卢 小 海(flier@126.com)

/ ? q6 P/ e& L3 [ S! q# F3 c1 l

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

! _4 d& @' Y3 o8 I4 C! V, X

& |9 p" W% r1 U: O' l. ~9 I ---- 金 山 词 霸2000 的 英 文 全 文 朗 读 功 能 相 信 一 定 给 尝 试 过 的 用 户 留 下 了 很 深 刻 的 印 象, 而 作 为 一 个 程 序 设 计 者, 你 一 定 也 想 在 自 己 的 程 序 中 加 入 类 似 的 功 能 吧, 因 为 那 将 让 自 己 的 程 序 增 色 不 少。 4 |$ Q, b& Z7 P) `----其 实 这 并 不 是 一 件 困 难 的 事, 因 为 金 山 词 霸 实 际 上 也 只 是 直 接 使 用 了MS 的TTS(Text -to -Speech) 技 术 而 已, 通 过 对MS Speech API 的 编 程, 我 们 完 全 可 以 实 现 比 其 更 强 大 的 功 能。 下 面, 让 我 们 在Delphi 环 境 下 实 际 尝 试 一 下。

, V, l, Y* I2 n8 W5 f0 t

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

% ^/ K7 C3 D8 K6 a0 O$ S

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

" c" W* s r# j( o

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

' {5 x8 x" A4 e; p; z

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

9 v" |$ S; b; Q6 u. ], Z

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

9 ^7 I/ D6 a- P$ j$ ]: r4 k

..." [" c9 j: J1 ?( N+ U" X/ @ procedure TfrmMain.FormCreate(Sender: TObject); , |$ j" L$ u( m! A! o: g' a begin" G, B! M! x' b! ^' ~ `) R2 t FISpeech := CoVTxtAuto_.Create;% g* y5 I# `" @5 z% @ FISpeech.Register(‘Demo Site', ‘Demo App'); D1 h2 Q- F. P5 T end;; M: j w4 b+ Y# E. r& p w: I ...

9 q) m1 Z5 ~9 z" u9 w) a

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

' x1 b( t: l' V" ~% q5 E

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

1 q! l [( t2 ^1 ^% }) Y

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

/ N4 P# z/ ]# d( u8 z- n0 E

Form 定 义 如 下:

5 b% V( _" W' j" T# x

object frmMain: TfrmMain 3 d! n# Q0 J: i6 T$ p Left = 296% b4 G" O. l ^3 D1 G* A Top = 187- I# ]3 X1 B: Z+ J! x0 l BorderStyle = bsDialog V1 z$ t; \ J% I0 O" f) T6 @4 y6 _ Caption = ‘ 英 文 全 文 朗 读 演 示' 4 O4 o4 Q; m9 l" {! a4 T! f ClientHeight = 185 7 N# K( u$ e4 O2 A0 q ClientWidth = 456/ _1 k& a( e5 c3 [* Q Color = clBtnFace b% F& c$ G( ]6 _ Font.Charset = GB2312_CHARSET, x8 R" r8 u* \# u! [ Font.Color = clWindowText 5 C: \0 Y% ]! o& c. s6 ` Font.Height = -12+ P/ e. Z0 [% W, l7 x6 r Font.Name = ‘ 宋 体' 3 u$ b& j5 k" N1 h Font.Style = [] 7 y* Q& Q3 K) M OldCreateOrder = False: M( d. Y9 V2 X Position = poDesktopCenter 3 a, R8 b% m0 E$ A8 b% F& H OnCreate = FormCreate/ c X3 ]$ g. |0 a! z9 C! z PixelsPerInch = 960 J- ?, z9 N6 l$ @' `0 N TextHeight = 125 c l* F# `1 S v( T: b object memText: TMemo : t: C8 r3 z3 O/ b Left = 82 \( O: b' J U2 m3 v5 ?" q Top = 8- w3 z( b- b$ z2 z3 B( n# ^2 j Width = 361/ P4 P! e1 ]) ^) s" v0 F! } Height = 169* ?" B l' ]' E2 c7 D& e ScrollBars = ssVertical ; t" m8 f+ K* A' d! A I; C. _ TabOrder = 0 l+ p* b' i" B5 X. g! J end# I0 T) w6 Q' [) G7 R1 W+ z object btnRead: TButton 8 H/ o8 e, b! @0 r% o Left = 376 ) n; B5 Q A; p% K! U Top = 8 5 C3 B7 X( r) \, Z8 R7 S Width = 75 ! z1 e% C/ y) R; } Height = 25 2 a! d- A! h2 |1 _ Caption = ‘ 朗 读( &R)'5 }/ s( c* d) o0 {; R1 h TabOrder = 1 & j* S9 ^( r# k6 k5 `8 h+ ` OnClick = btnReadClick % a8 K' w4 I! z, x3 E end( u3 ^- Q( C- `" p7 B- L object btnPause: TButton$ h4 d3 g9 } F7 a& h1 I7 @ k Left = 376 & T) [) \) n# q2 Y Top = 40& h& P2 J7 U) N, e% S Width = 75% N: o& ?2 x0 U! E3 t( t9 r7 I Height = 25 # A* b; l, S2 R! o. O Caption = ‘ 暂 停( &P)'( P9 g4 o- _ ]- x9 M. h Enabled = False/ L! B4 a7 m$ ]9 @) {" |9 W) w TabOrder = 2* B: \3 S" K% Z OnClick = btnPauseClick/ L4 x+ M8 S$ g/ t: r# M end9 S. D* D2 p+ K$ l& h( U( S" _ object btnStop: TButton% Y P) P) d+ A/ T3 ? Left = 376 . x8 X8 o$ q( ? Top = 72& ]4 V( X, F. N: D Width = 75& t, B" S+ S" x2 ?/ f' Z; D; r Height = 25 6 e6 \& r) n, k+ t( [ Caption = ‘ 停 止( &S)'' ~& Z* J h7 K' q3 h: @! O6 Y Enabled = False: _, B5 t( H+ G3 z1 U: n* H8 E TabOrder = 3 + B7 h1 d1 A0 H OnClick = btnStopClick / m( D- }- c7 V; M1 @: Q end + W5 [# X1 }. }/ t object btnForward: TButton5 t" u! n: Q9 i7 p( ~2 J$ k O Left = 376 / `! u% b& M0 N) p7 n) L# s' h Top = 120; R" R' ?, B! z) o- T Width = 753 t: Z9 K# y, ^ Height = 25 ! {7 V0 s) {. G x; o7 x9 | Caption = ‘ 下 一 句( &N)'" |' T) N ?6 B- l% B Enabled = False' X, q$ ~2 s8 C- |$ z TabOrder = 4 + E3 R& _; S6 Y7 G! ~ R2 m h, ^ OnClick = btnForwardClick9 i9 p9 t+ r0 V8 L end6 ^8 a% q" r7 Q3 W- h object btnRewind: TButton $ W; O; l6 i5 E4 ]- v [ Left = 376 9 \+ V, t: d$ b, ]3 V Top = 152( t( l- _' r) V4 O6 @ Width = 75 ' `( v; {$ D9 {* p Height = 25 $ g5 k# U5 B( U3 M4 H6 H' B Caption = ‘ 上 一 句( &W)' # u& W, n1 w9 h2 u4 s' I. ] Enabled = False' I5 f; }8 _4 E; I8 Z. [ TabOrder = 5; _, {) R3 S7 d+ z$ x* j' v OnClick = btnRewindClick O# t& [/ _. c8 t( p( N& C. C end ' {2 n8 O+ V! L+ Q6 k end

9 A; z4 G: C9 L U

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

7 H4 H) ]' y+ U3 Y7 A

---- 1. 朗 读 与 停 止

% a) v) H' Y0 ~( E( x7 {. @7 J

... 4 n) W+ A9 o4 |6 Kprocedure TfrmMain.btnReadClick(Sender: TObject); 1 L& v1 {6 A1 o( T begin" N! e" s9 i7 R* Y- n2 s FISpeech.Speak(memText.Lines.Text, vtxtst_ 7 v4 k! [$ k3 _READING);9 M0 x! u4 I! b/ F8 R8 ` btnPause.Enabled := True; . } d, w5 G) p2 I btnStop.Enabled := True;2 y$ l/ g2 M8 d end;+ h4 w h3 W2 @- H0 H. J 2 A- b, q& I% ]4 T w0 i V procedure TfrmMain.btnStopClick(Sender: TObject); " O% c4 G" y) V. G. m9 {3 E begin7 [0 L6 r X7 N- K FISpeech.StopSpeaking;* D5 P" H& j- Z% D btnPause.Enabled := False; ; C: W' ?" t0 }, B% D5 u j( j btnStop.Enabled := False; 1 g7 R/ _; r9 j# v- n2 t8 \ btnPause.Caption := ‘ 暂 停( &P)';0 s8 B. U, t9 H" c! X& y end;0 `) j/ O, K# O# x' N ...

0 d5 @) W5 P4 S

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

2 S, O. c' l4 \ $ D+ o$ V+ H9 i( l1 E

---- 2. 暂 停 与 恢 复

4 E+ O! E5 F+ p4 I) ~

...5 t: d" ?7 A, u p7 @" s procedure TfrmMain.btnPauseClick(Sender: TObject);3 |' |5 w8 Y) Q6 y3 t5 F begin) P0 B$ d7 u. x6 z6 ] with FISpeech do ) |+ @1 k$ F3 r$ W7 S8 d5 \ if IsSpeaking then+ n8 `* t* s, m" W& J' P6 ~$ Y( n begin 6 p: j) `$ F* Z% c* J# }$ d" _ AudioPause; , E# p: `! W$ k! G9 y btnPause.Caption := ‘ 恢 复( &R)';3 i' ~# |9 w2 f) b4 U end0 d6 b4 s o0 g8 | else ; ~5 a4 v. f! X7 r2 C6 c0 _ begin 9 `. P; y% L4 ?* G1 W6 m8 C AudioResume; - Y! ]: X# t7 t3 h; y btnPause.Caption := ‘ 暂 停( &P)';- c: m9 n: _2 m( k7 R end; 9 {' U" v1 i$ Oend; 7 g$ r' z& ~$ @! p( h9 T...

, m3 ?: a4 ]' ~* v

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

5 t2 r* v4 s5 |' S% x1 D$ @

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

& P7 l6 j) a' k! Y8 ^8 i3 x- e6 s$ _

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

b* j+ [' N; f( Q3 t9 I; A1 O

... ( t3 w" @" E5 eIVTxtAuto = interface(IDispatch). W' N+ [8 R2 D. r( c1 T( r0 M ..." o. W' c/ p2 f" A property Speed: Integer read Get_Speed write Set_Speed; e( n. V- m. ~, }# C; d property Enabled: Integer read Get_Enabled write Set_Enabled; 6 U. o/ m5 ]/ v* k/ z2 J ... % t# S+ Z* l) ?# Y }, j! O8 L) tend;- ?+ g4 W5 N+ _, `3 W ...

* _3 Z& f S0 D; E" s

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

# n: x* l, Q7 H% }5 D) E$ S

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

# G4 K; H* [* a' U

----本 文 程 序 在Win NT/98 + Delphi 4/5 环 境 下 调 试 通 过。 % C5 u1 k( ~6 v Q1 ^3 P& a$ {- P% K5 o






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