讯飞语音合成 如何选择发音人

问题描述

讯飞语音合成有多个发音人,如何选择一个合适的发音人呢?我的解决方法是,选择符合要求的,然后每个都听一遍.最后选出一个合适的.

我的要求

我是用来朗读技术文章的,文章中要英文也有中文,所以我要选择支持中英文的发音人。发音人列表
这里有一张图片
符合我条件的发音人如下:

名称属性语言参数名称引擎参数备注
小燕青年女声中英文(普通话)xiaoyan默认
小宇青年男声中英文(普通话)xiaoyu
小研青年女声中英文(普通话)vixy
小琪青年女声中英文(普通话)vixqxiaoqi
小峰青年男声中英文(普通话)vixf

无法直接循环下载

下面写个demo,要求输入一段文字,然后使用上述的多个发音人分别来合成.下载下来我再一个个的听,选出一个英文清晰,阅读节奏合适的发音人.
因为要批量下载,我首先想到的是,循环调用下载方法不就行了如下所示:

for (......)
{
	// 3.创建一个SpeechSynthesizer对象
	SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer();
	// 4.设置合成参数
	......
	mTts.synthesizeToUri(Input, fileName, synthesizeToUriListener);
}

但是我失败了,这样并不会合成多个音频。只会合成一个。经过测试之后,我发现,调用完毕下载方法后,主线程就结束了.
…最后经过一番思索解决方案如下.

创建下载线程

线程的知识我有点忘了,合成音频的方法最后会回调onSynthesizeCompleted这个方法,我在下载线程DemoListRunable中设置一个isEnd标记,当开始下载一个音频的时候,把isEnd设置为flase,下载完毕后设置为true.
在主线程中,通过不断的来查询这个标记,从而知道是否下载完毕。

package demo;
import com.iflytek.cloud.speech.SpeechConstant;
import com.iflytek.cloud.speech.SpeechError;
import com.iflytek.cloud.speech.SpeechSynthesizer;
import com.iflytek.cloud.speech.SynthesizeToUriListener;
public class DemoListRunable implements Runnable
{
	public static boolean isEnd=false;
	String fileName;
	String Input;
	String voiceName;
	public DemoListRunable(String voiceName, String fileName, String Input)
	{
		this.voiceName = voiceName;
		this.fileName = fileName;
		this.Input = Input;
	}
	public void run()
	{
		// 3.创建一个SpeechSynthesizer对象
		SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer();
		// 4.合成参数设置,详见《MSC Reference Manual》SpeechSynthesizer 类
		// 设置发音人
		// 小燕 青年女声 中英文(普通话) xiaoyan 默认
		// 小研 青年女声 中英文(普通话) vixy
		// 小琪 青年女声 中英文(普通话) vixq xiaoqi
		// 小宇 青年男声 中英文(普通话) xiaoyu
		// 小峰 青年男声 中英文(普通话) vixf
		// 4-1 设置发音人
		mTts.setParameter(SpeechConstant.VOICE_NAME, voiceName);//
		// 设置要下载的文件名
		mTts.setParameter(SpeechConstant.SPEED, "50");
		// 设置语调,范围0~100
		mTts.setParameter(SpeechConstant.PITCH, "50");
		// 设置音量,范围0~100
		mTts.setParameter(SpeechConstant.VOLUME, "50");
		// TODO Auto-generated method stub
		System.out.println(
				"    正在合成 " + fileName.substring(0, fileName.lastIndexOf("."))
						+ " 朗读样例" + " 下载位置:" + fileName);
		mTts.synthesizeToUri(Input, fileName, synthesizeToUriListener);
	}
	// 1 设置合成监听器
	static SynthesizeToUriListener synthesizeToUriListener = new SynthesizeToUriListener()
	{
		// progress为合成进度0~100
		public void onBufferProgress(int progress)
		{
		}
		// 会话合成完成回调接口
		// uri为合成保存地址,error为错误信息,为null时表示合成会话成功
		public void onSynthesizeCompleted(String uri, SpeechError error)
		{
			//表明下载完成
			isEnd=true;
			if(error==null)
				System.out.println("        合成成功");
			else 
				System.out.println("        合成失败");
		}
		@Override
		public void onEvent(int arg0, int arg1, int arg2, int arg3, Object arg4,
				Object arg5)
		{
			// TODO Auto-generated method stub
		}
	};
}

主线程

package demo;
import java.util.Scanner;
import com.iflytek.cloud.speech.SpeechConstant;
import com.iflytek.cloud.speech.SpeechUtility;
import replace.Replace;
public class DemoList
{
	static Scanner scanner = new Scanner(System.in);
	public static void main(String[] args)
	{
		// 2 将“XXXXXXXX”替换成您申请的APPID
		SpeechUtility.createUtility(SpeechConstant.APPID + "=XXXXXXXX");
		// 5设置要合成的文本
		System.out.println(
				"######################################## 讯飞语音合成系统 ########################################");
		System.out.println("输入要合成的文字(以: \"#exit\"作为结束符):");
		StringBuffer sbBuffer = new StringBuffer(10240);
		String line = null;
		while (scanner.hasNext())
		{
			line = scanner.nextLine();
			if ("#exit".equals(line))
			{
				break;
			}
			sbBuffer.append(line.concat("\r\n"));
		}
		System.out.println(
				"---------------------------------- 特殊字符处理 ----------------------------------");
		// 处理输入文本,替换容易读错的特殊字符.
		String Input = Replace.replaceTitle(sbBuffer.toString());
		Input = Replace.replaceEnglish(Input);
		System.out.println(Input);
		System.out.println(
				"---------------------------------- 特殊字符处理 ----------------------------------");
		String[] fileNameArr = new String[]
		{"小燕xiaoyan.pcm", "小研vixy.pcm", "小琪vixq.pcm", "小宇xiaoyu.pcm",
				"小峰vixf.pcm"};
		String[] voiceNameArr = new String[]
		{"xiaoyan", "vixy", "vixq", "xiaoyu", "vixf"};
		for (int i = 0; i < fileNameArr.length; i++)
		{
			DemoListRunable runable=new DemoListRunable(voiceNameArr[i], fileNameArr[i], Input);
			DemoListRunable.isEnd=false;
			Thread thread=new Thread(runable);
			thread.start();
			//等待下载完毕
			while(!DemoListRunable.isEnd)
			{
				try
				{
					Thread.sleep(1000);
				} catch (InterruptedException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

其中Replace这个类用来预处理朗读的文本.包括替换容易读错的字符,添加空格以加入停顿等。代码参见讯飞语音合成 发音不准确怎么解决

实验结果

下载好音频后,逐个听一半,比较一番,我的到如下结果:

发音人连贯性英文准确性
小燕xiaoyan可以英文准确
小研vixy可以英文准确
小琪vixq英文可能不准确
小峰vixf慢没有节奏英文发音不全
小宇xiaoyu可以英文发音不好

通过比较我发现:

  • 女发音人中,
    • 小燕xiaoyan小研vixy这两个发音人可以用,还有就是小燕xiaoyan(默认)读的时候有写破音,最后我选择小研vixy这个发音人。
    • 小琪vixq读的有点慢,但是中英文之间切换比较好。
  • 而男发音人小峰vixf小宇xiaoyu读英文的时候声音小不清晰,读音不标准。

具体情况还是以实验为主.

原文链接: 讯飞语音合成 如何选择发音人

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值