数学建模社区-数学中国

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

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

) {: ?9 a9 @( k; b8 O' a# o2 \4 R 华 中 师 范 大 学 卢 小 海(flier@126.com)

7 }" g. H" f' V

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

* i. O2 n' n( f

1 ^7 p% [, h+ \& y/ [( j ---- 金 山 词 霸2000 的 英 文 全 文 朗 读 功 能 相 信 一 定 给 尝 试 过 的 用 户 留 下 了 很 深 刻 的 印 象, 而 作 为 一 个 程 序 设 计 者, 你 一 定 也 想 在 自 己 的 程 序 中 加 入 类 似 的 功 能 吧, 因 为 那 将 让 自 己 的 程 序 增 色 不 少。 : Q3 ]+ S+ s' b; H$ s3 \! E7 e----其 实 这 并 不 是 一 件 困 难 的 事, 因 为 金 山 词 霸 实 际 上 也 只 是 直 接 使 用 了MS 的TTS(Text -to -Speech) 技 术 而 已, 通 过 对MS Speech API 的 编 程, 我 们 完 全 可 以 实 现 比 其 更 强 大 的 功 能。 下 面, 让 我 们 在Delphi 环 境 下 实 际 尝 试 一 下。

* G# |' Q1 j8 A+ O, x

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

( i' S5 }/ B1 s7 U& p) z- t

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

* H6 I$ N! {( s+ J; A( f) _

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

* k" \$ @( r9 H# ^

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

9 y) e1 R( \- }, {3 D+ \% [

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

! Q; F/ [6 b/ G

...4 w0 O5 y0 [6 r0 _ procedure TfrmMain.FormCreate(Sender: TObject);3 ~) L1 e' A8 M4 u' _( U# e% e, F6 j begin( V( d! r* z! ^/ M& D5 p$ q FISpeech := CoVTxtAuto_.Create;5 z- ?: X0 ^6 U9 X. e+ b/ M FISpeech.Register(‘Demo Site', ‘Demo App'); " {/ p; [. S# i% s* L# W end; $ @8 w. i8 V4 U8 a...

* d- L2 Z1 U* T, w

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

u+ B4 W- u# q% R1 a

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

1 v9 d0 f6 G2 x1 r: r

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

6 e5 P, R7 C: M/ g4 _+ ?( S: Z9 k

Form 定 义 如 下:

8 F) N7 o. v u

object frmMain: TfrmMain + l4 A0 `2 N8 ?5 r0 Y Left = 296( {/ h- K1 r! g' Y Top = 187& k5 v! }) k- \- Z1 n BorderStyle = bsDialog2 f% M3 I1 a, V7 v6 w Caption = ‘ 英 文 全 文 朗 读 演 示' R5 p/ ~* N$ ~" v ClientHeight = 185+ D" O+ ^* z: @2 u0 \) a ClientWidth = 456; a3 Z) @! d; W6 x Color = clBtnFace7 b3 j% i# {2 \" q Font.Charset = GB2312_CHARSET ' O. N5 X, w! J5 R5 L# Y0 ] Font.Color = clWindowText 9 J9 l% c4 k& q" Z/ b Font.Height = -12" T) O- r! X' l3 ~ Font.Name = ‘ 宋 体'& A& u( a/ B$ L) ]4 _1 X: k$ e Font.Style = []; O# M# n& q- O9 L! N9 ^ OldCreateOrder = False % W' o. w1 `; e% F Position = poDesktopCenter. `& M0 g2 z* b( S0 l OnCreate = FormCreate2 S# @3 r, s9 ~4 g7 I5 }0 g PixelsPerInch = 96 * {- g! Z. Y' f8 ?- l1 Z8 l TextHeight = 12* ~; ?$ Q0 D! f2 I: s. } object memText: TMemo 1 s+ J4 N& h) x9 H0 M Left = 8, F& }! |" W% r. o# r. a Top = 8% u! \% E: Q+ n. V9 i# H+ Q' } Width = 361 : }! Y9 Y& u( {( c% H6 S Height = 1694 W* U# g& n- V8 \0 B ScrollBars = ssVertical 4 ]8 S0 s3 V+ @4 t$ ]0 q6 ~ TabOrder = 04 o' ]) Y/ B( i5 N7 Z! ]7 A7 ~/ p end$ O3 [9 n" n) y" D object btnRead: TButton ' Y2 c N( ]" k0 w, d' z Left = 376 ?! C3 u" y" X: K Top = 84 v$ W0 Y7 a, h1 q9 v9 ` Width = 759 B2 ~: J3 K( l5 m+ ^) U Height = 25 " K4 y" j* S$ F5 O! M R0 u Caption = ‘ 朗 读( &R)' ) c& |) _& I* s. R, a, U' [ TabOrder = 1 . i$ R6 u. M/ }% g OnClick = btnReadClick4 ^# a4 X' c7 r3 p- B$ H end: |' Q, _& M7 r) Z! d* _% `4 n8 l6 x object btnPause: TButton% H& C, P7 e0 I Left = 3765 j7 I# n7 t4 h) K" l% I; D( T9 s Top = 40 $ |6 Q0 v2 u' d! [* v Width = 75 ( X, G( m: c% Q1 W7 ~ Height = 25! e5 I' m7 S; ?; m0 K Caption = ‘ 暂 停( &P)' ! I- L/ d6 y* s" _2 w0 F5 V Enabled = False w0 L" |$ X1 f TabOrder = 2: r _6 q7 M, x- m OnClick = btnPauseClick : n$ T/ V* }! V) F* ^$ o% h8 g end 5 L! J* G7 B, A" ~% x( K: n% f! \ object btnStop: TButton) X+ ~1 V; X+ J* A* x4 g Left = 376 : k, W& @& @9 G; I5 ]+ W) z Top = 72/ v. d( K9 O6 N# l Width = 75 / N) U/ [( C: D7 p0 r6 Y! l4 o5 ]" } Height = 25 / Y3 }4 c# R6 C; R6 L Caption = ‘ 停 止( &S)'! ~: m% y E0 T! J7 C Enabled = False% J+ U" d" x- X2 U4 q0 L TabOrder = 36 B/ w$ t$ H0 q1 U OnClick = btnStopClick 1 c3 T" W0 p7 ]. {. M) r; F end( I$ I" S" J/ A1 o7 y1 U: N object btnForward: TButton 4 B }- D5 e/ \6 B+ k( d- Z Left = 376; d5 O/ Q) h, [) R: V Top = 1209 r5 ?0 L3 h4 a( Z Width = 75 % t6 ?0 D4 |7 W, E$ G5 W; e h9 f/ p Height = 25 9 S# \0 u& v3 y Caption = ‘ 下 一 句( &N)' " q! }" P7 |- a6 Z Enabled = False 6 d) U/ d- C; F TabOrder = 4 % O7 o0 K1 ]5 M' p0 C! e$ a OnClick = btnForwardClick " @! k( J- \! }! g end6 [2 E& W1 Z" [% Q+ w) q2 w object btnRewind: TButton 5 [) U4 m/ {9 M+ F Left = 376 % U& |3 `' M% ], B Top = 152- e) d7 D7 h, q Width = 75 : w! X2 P F4 ]1 L+ Q/ [ Height = 25 ' v+ e- L6 b! f9 H' N Caption = ‘ 上 一 句( &W)'( ?7 t- u. t3 E7 z R! Y( y Enabled = False & ~0 Y" ~" h7 I: ^ TabOrder = 5 4 n6 J& ]5 L* e- N2 v# q, b" m9 m ` OnClick = btnRewindClick 2 p' L1 M0 n# Y end $ e5 p- d- w7 Z& t1 D end

0 G$ e% l# R5 x: f1 ?

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

! ?( O8 y& t( c& ]

---- 1. 朗 读 与 停 止

6 _$ N) H" U$ Z, O5 ] ?

... 5 H( G2 H0 {. n* Qprocedure TfrmMain.btnReadClick(Sender: TObject); ( P; }1 P* ~' A, V begin# ^2 {" {+ _5 m2 ~& k2 M- Y FISpeech.Speak(memText.Lines.Text, vtxtst_ 7 n H/ j% w4 n8 E& S: g READING);9 Q4 r8 @3 P i' | btnPause.Enabled := True; ) I0 f/ E8 j% E4 e% J( F/ E. G btnStop.Enabled := True; ; r* p# P1 X) ^( [" c) P0 { end;4 S: e, q/ \; w4 h; q7 [! E3 { $ _0 e' N: A4 x0 u4 g procedure TfrmMain.btnStopClick(Sender: TObject);9 e: S4 {; m0 s. S) N begin ; i0 d( d( |0 V6 v FISpeech.StopSpeaking; 7 z: A- T6 }. o8 Y btnPause.Enabled := False;" L- `! S9 k/ s3 Y1 a: q! m btnStop.Enabled := False; 2 N! D* V5 T& X( P: o$ X% k: D btnPause.Caption := ‘ 暂 停( &P)'; ; y( T/ E# {- I' [& x$ Z* V end; O/ d6 z, {0 L7 `3 W8 O' _ ...

: |5 y$ ~; w- D, _2 f

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

- {) p. N: J8 s5 W * m1 w' C5 j7 D4 w$ u' R$ Z

---- 2. 暂 停 与 恢 复

) D* ^, y% m' B8 ]$ C

... / l" N2 ]) u$ Aprocedure TfrmMain.btnPauseClick(Sender: TObject);2 u& h" G' h: E3 D9 R Y begin1 p# W2 S( s& N! g- G with FISpeech do( @! q( t- \4 f4 {0 ]+ V: l5 Z if IsSpeaking then8 |$ T0 u7 Q9 @ begin % R! d$ n# S0 y4 E" C AudioPause; 4 j" s; Z6 ^) D7 Y6 x: q, I7 Y btnPause.Caption := ‘ 恢 复( &R)'; 1 d+ D" R: A: x p6 T end / }- J* m% U" H9 j2 R% ` else1 |+ f5 G: Q' O, O: M9 R begin ) D8 m5 [) x* T3 G/ l AudioResume;$ k1 N1 z# b% x. R% X# L6 Z+ ` btnPause.Caption := ‘ 暂 停( &P)';8 \3 ]: ^5 w) ^1 X end;& L- x: g o8 l' N- y8 L3 W end;3 N! M1 x6 I* ^# F! X ...

! _5 v4 I. n+ J5 I/ S- z3 S3 t

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

) H7 z3 b1 P% v& W7 B9 k) |, x

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

8 {0 {- D& o' e& _( h+ j7 I

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

# v$ |+ N$ P& m# b5 }5 ^ b

...- V# Q5 D% S! P5 m& P IVTxtAuto = interface(IDispatch)7 w. S8 l0 _8 r7 K6 k" n& y" g ...; _3 y% z! k+ \# ~ property Speed: Integer read Get_Speed write Set_Speed; & u" g: S8 i1 j5 @+ K0 }- a; P( \ property Enabled: Integer read Get_Enabled write Set_Enabled; " u, Q( s3 Y9 Z# X* v ... 0 W8 _9 ?; |$ L7 _end; 9 W( {5 k9 t4 v1 }) j# m ...

# g8 f% R+ b H5 _

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

4 e7 R. \8 h9 m; c# h1 V" r: j( N

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

7 \* t! {- s1 d1 B2 u/ n9 Z* j

----本 文 程 序 在Win NT/98 + Delphi 4/5 环 境 下 调 试 通 过。 6 r K4 l& n `7 x! X) s+ c ) F- l7 U1 z# M7 y3 O4 K






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