首页 > 代码库 > (二)语音合成测试案例

(二)语音合成测试案例

上一章节大致描述了一下.NET Framework中的语音识别和语音合成的应用开发接口。接下来以一个测试案例来展示下SAPI的使用。以下案例均已VS2010 + Framework4.0为例。

用VS新建一个窗体应用程序。并添加引用。

image_thumb1

测试程序界面布局如下:

image_thumb3

下面是完成的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Speech.Synthesis;

namespace Synthesis
{
    public partial class FrmMain : Form
    {
        //语音合成引擎
        private SpeechSynthesizer speechSynthesizer;

        public FrmMain()
        {
            InitializeComponent();
            this.speechSynthesizer = new SpeechSynthesizer();
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            //获取系统已安装的语音库列表
            var voiceList = (from item in this.speechSynthesizer.GetInstalledVoices() select item.VoiceInfo.Name).ToList();
            this.cmbVoice.DataSource = voiceList;
            //var voiceList = this.speechSynthesizer.GetInstalledVoices();
            //foreach (var item in voiceList)
            //{
            //    this.cmbVoice.Items.Add(item.VoiceInfo.Name);
            //}
            //this.cmbVoice.SelectedIndex = 0;

            this.speechSynthesizer.Rate = 0; //语速值范围: -10 到 10
            this.speechSynthesizer.Volume = 100; //声音大小值范围: 0 到 100
            this.speechSynthesizer.SelectVoice(this.cmbVoice.Text); //设置用于合成的语音库
        }

        private void cmbVoice_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.speechSynthesizer.SelectVoice(this.cmbVoice.Text);  //改变当前语音库
        }

        private void btnSpeak_Click(object sender, EventArgs e)
        {
            //this.speechSynthesizer.SpeakAsync(this.txtContent.Text);
            this.speechSynthesizer.Speak(this.txtContent.Text);  //将文本合成语音
        }
    }
}

运行后,在文本框输入需要合成的文本,点击Speak,就OK了。

运行测试结果。

image_thumb[1]

image_thumb[3]

如果你看了第一章关于SAPI简述,那么你也可以使用第三方语音库来合成。如图:

image_thumb[9]

这声音还是比较接近自然语音的。(注意我提供的第三方语音库,安装好了需要用包里的破解文件覆盖源文件,否则这里合成时会多说一句广告语的(*^__^*) ,详见上一章的介绍)

在语音合成的技术中有一个难点就是多语言混合合成。如果说我们做一个电子书阅读器的话,除了阅读时语气和标点停顿外,那么多语言混合的问题也是一个头疼的事情,因为一本小说中混合多种语言那是常事。

先来看测试:

image_thumb[8]

我分别使用中、日、韩、英四种语言合成上述文本,测试结果如下:

1.中文语音包支持中英混合合成

2.英语语音包仅仅支持英文合成

3.日文语音包会把中文识别为日本合成,部分汉字可以,但是中文汉字比日文多得多,况且我们用的是简体,我基本认为不支持中日混合的。此外日文把英文本土化了所以日英混合是可以的,但是日文包读的英文单词是本土化之后的发音,听不习惯我也没有办法。这也是日本人英文烂的原因吧。

4.韩文语音包和日文语音包差不多,从我学韩文和日文的经验上看,他们两个国家的语言虽然都源自中文,但韩日成一个体系,基本大同小异。韩文语音包会把中文识别成韩文合成,同样我认为是不支持中韩混合的。其次就是韩文语音包可以支持日韩混合,不过发音用的是韩文的发音法,听着也很变扭。韩文也是和日文一样把英文本土化了。但是出乎意料的是我一向认为韩国人英语最差,其次是日本。没想到这个语音包的英文合成尽然比日文要好,但是也有很大的本土音听着别扭死了。因此韩语语音包基本支持日、韩、英的混合。

上述仅仅是简单测试结果。做这个测试是为了选择合适的语音包来开发我们的应用程序。如果你仅仅只需合成中文那么只用中文包就行了。但是混合合成也是一个不能避免的问题。怎么解决混合的问题。

市面上的解决方案做的比较好的就是讯飞的语音解决方案了。至于有没有提供开发用的API我了解不是很多。另一个途径就是云语音的解决方案,Google、百度、360都有吧,不过云语音需要网络支持。

一下给出一个混合的解决方案,在加载需要合成文本时需要先对文本做词法分析,把不同语言的文本用标记标识出来,一般可以使用XML文件。阅读时根据不同的语言调用不同的语音库就行了。

另外一个问题就是关于数字的。比如:

1234 这个你是读成一千二百三十四 还是 一 二 三 四 呢?

如果你要读成一千二百三十四就连写,否则需要加标点或空格隔开。

1234 读成一千二百三十四

1  2  3  4 就会读成 一 二 三 四

结束语:这篇仅仅是语音合成的一个测试案例,虽然案例简单但是也把开发中可能遇到的一些问题做了解释,这样可以避免开发时走弯路。或不知从何入手。

程序源码