博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用语音即时校对输入内容
阅读量:6871 次
发布时间:2019-06-26

本文共 2809 字,大约阅读时间需要 9 分钟。

原文:

 

 

此文将介绍利用微软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://txsfl.baihongyu.com/

你可能感兴趣的文章
练习E-R图书管理数据库
查看>>
网页防止跨框架攻击
查看>>
Linux-1:安装&忘记密码&CRT连接centos 6.5
查看>>
JQuery之DataTables强大的表格解决方案
查看>>
mvn编写主代码与测试代码
查看>>
SPSS简单使用
查看>>
SqlSugar-事务操作
查看>>
@ResultMapping注解
查看>>
GPUImage相关(转)
查看>>
Windows平台分布式架构实践 - 负载均衡 上
查看>>
JS、JQuery和ExtJs的跨域处理
查看>>
Bootstrap 模态对话框 remote指定内容加载
查看>>
StackExchange.Redis 访问封装类
查看>>
玩转spring boot——开篇
查看>>
Tomcat连接参数的优化,主要是针对吞吐量做优化
查看>>
js根据选中的复选框,隐藏那一行
查看>>
[gj]三国攻势图
查看>>
Nginx使用教程(一):Nginx编译参数详解
查看>>
最近面试的几个额外问题
查看>>
OpenCms JSP 模板开发——创建一个简单的JSP模板
查看>>