此文将介绍利用微软TTS引擎,在录入数据时进行即时语音校对的示例。
这是一项非常简单且非常实用的技术,此功能在行业软件中使用的话,将会使用户的录入准确率大幅提高,还可减少甚至取消后期核对工作。
你需要使用以下类库来操作TTS:
在文章末尾处提供的源代码中将包含此类库。
现在开始编写这个示例程序:
新建一个WinForm项目,引入上述dll,在窗体后台代码中添加对其命名空间的引用:
using
DotNetSpeech;
由于我们还需要用到正则表达式,所以也将其所在命名空间一并引用:
using
System.Text.RegularExpressions;
然后来设计一个基本的用户界面:
添加一个BackgroundWorker组件:
为其DoWork事件添加处理:
private
void
backgroundWorker1_DoWork(
object
sender, DoWorkEventArgs e)
{
SpeechVoiceSpeakFlags SpFlags
=
SpeechVoiceSpeakFlags.SVSFlagsAsync;
SpVoice Voice
=
new
SpVoice();
Voice.Rate
=
-
3
;
Voice.Speak(e.Argument.ToString(), SpFlags);
}
Voice.Rate属性是用来设置语速的修正值的,我希望它读慢点,所以就设为了-3。
这个事件处理的功能就是在后台将接收到的字符串通过TTS念出来。
我们再来编写一个方法,来统一对backgroundWorker1进行调用:
void
朗读(
object
内容)
{
try
{
backgroundWorker1.RunWorkerAsync(内容);
}
catch
(Exception er)
{
MessageBox.Show(er.Message,
"
提示
"
, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
为了便于演示,加上我个人习惯,我将此方法名称设为了中文。
由于语音处理需要一定时间,在此期间如果再度调用backgroundWorker1的RunWorkerAsync方法,将会引发异常,所以需要进行捕获。
实际应用中如需要照顾较高速度的录入,可以采用多个BackgroundWorker组件,轮流滚动处理。
接下来就是为每个输入框定义朗读方式了,我们会在用户按下回车键时,进行语音处理,并将光标跳转到下一个输入框。
首先设置序号输入框的事件处理:
private
void
numericUpDown1_KeyDown(
object
sender, KeyEventArgs e)
{
if
(e.KeyData
!=
Keys.Enter)
return
;
朗读(numericUpDown1.Value);
textBox1.Select();
}
然后是品名的:
private
void
textBox1_KeyDown(
object
sender, KeyEventArgs e)
{
if
(e.KeyData
!=
Keys.Enter)
return
;
朗读(textBox1.Text);
numericUpDown2.Select();
}
这两个都比较简单,九十直接念出原文。
单价则有些不同:
private
void
numericUpDown2_KeyDown(
object
sender, KeyEventArgs e)
{
if
(e.KeyData
!=
Keys.Enter)
return
;
朗读(
"
¥
"
+
numericUpDown2.Value);
numericUpDown3.Select();
}
在其内容前加了人民币符号,它阅读时就会这样读:九百六十七元
数量与之类似:
private
void
numericUpDown3_KeyDown(
object
sender, KeyEventArgs e)
{
if
(e.KeyData
!=
Keys.Enter)
return
;
朗读(numericUpDown3.Value
+
"
件
"
);
textBox2.Select();
}
内部编号有些特殊,我期望它能够将每个字母或数字都单独念出,这可以通过加注拼写标记来实现:“<spell></spell>”
但是这样还有一个问题,就是他读数字的时候会将其读作英文,这不是我们所希望的,这还需通过加注语言标记来修正:“<voice required=""Language=804""></voice>”
故此我们需要附属一个方法来将源文本格式化:
private
void
textBox2_KeyDown(
object
sender, KeyEventArgs e)
{
if
(e.KeyData
!=
Keys.Enter)
return
;
朗读(加注中文标记(textBox2.Text));
button1.Select();
}
string
加注中文标记(
string
原字符串)
{
return
string
.Format(
"
<spell>{0}</spell>
"
, Regex.Replace(原字符串,
@"
(.)
"
,
@"
<voice required=""Language=804"">$1</voice>
"
));
}
好了,最后是提交按钮的事件处理,我们也要让他朗读点东西:
private
void
button1_Click(
object
sender, EventArgs e)
{
listBox1.Items.Add(
new
{
序号
=
numericUpDown1.Value,
品名
=
textBox1.Text,
价格
=
numericUpDown2.Value,
数量
=
numericUpDown3.Value,
内部编号
=
textBox2.Text
});
朗读(numericUpDown1.Value
+
"
号,添加完毕
"
);
numericUpDown1.Value
++
;
numericUpDown2.Value
=
0
;
numericUpDown3.Value
=
1
;
textBox1.Text
=
textBox2.Text
=
""
;
numericUpDown1.Select();
}
至此这个示例就完成了,其使用效果见下面这段视频:
源代码下载
插播个小喇叭广播:
我的MailMail现已正式发布,现在开始到9月1日0时止举办免费赠送注册码活动,欢迎参与^^:http://www.cnblogs.com/SkyD/archive/2008/08/28/1278463.html