问题描述
讯飞语音合成有多个发音人,如何选择一个合适的发音人呢?我的解决方法是,选择符合要求的,然后每个都听一遍.最后选出一个合适的.
我的要求
我是用来朗读技术文章的,文章中要英文也有中文,所以我要选择支持中英文的发音人。发音人列表
符合我条件的发音人如下:
名称 | 属性 | 语言 | 参数名称 | 引擎参数 | 备注 |
---|---|---|---|---|---|
小燕 | 青年女声 | 中英文(普通话) | xiaoyan | 默认 | |
小宇 | 青年男声 | 中英文(普通话) | xiaoyu | ||
小研 | 青年女声 | 中英文(普通话) | vixy | ||
小琪 | 青年女声 | 中英文(普通话) | vixq | xiaoqi | |
小峰 | 青年男声 | 中英文(普通话) | vixf |
无法直接循环下载
下面写个demo,要求输入一段文字,然后使用上述的多个发音人分别来合成.下载下来我再一个个的听,选出一个英文清晰,阅读节奏合适的发音人.
因为要批量下载,我首先想到的是,循环调用下载方法不就行了如下所示:1
2
3
4
5
6
7
8for (......)
{
// 3.创建一个SpeechSynthesizer对象
SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer();
// 4.设置合成参数
......
mTts.synthesizeToUri(Input, fileName, synthesizeToUriListener);
}
但是我失败了,这样并不会合成多个音频。只会合成一个。经过测试之后,我发现,调用完毕下载方法后,主线程就结束了.
……最后经过一番思索解决方案如下.
创建下载线程
线程的知识我有点忘了,合成音频的方法最后会回调onSynthesizeCompleted
这个方法,我在下载线程DemoListRunable
中设置一个isEnd标记,当开始下载一个音频的时候,把isEnd设置为flase,下载完毕后设置为true.
在主线程中,通过不断的来查询这个标记,从而知道是否下载完毕。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68package 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(" 合成失败");
}
public void onEvent(int arg0, int arg1, int arg2, int arg3, Object arg4,
Object arg5)
{
// TODO Auto-generated method stub
}
};
}
主线程
1 | package demo; |
其中Replace
这个类用来预处理朗读的文本.包括替换容易读错的字符,添加空格以加入停顿等。代码参见讯飞语音合成 发音不准确怎么解决
实验结果
下载好音频后,逐个听一半,比较一番,我的到如下结果:
发音人 | 连贯性 | 英文准确性 |
---|---|---|
小燕xiaoyan | 可以 | 英文准确 |
小研vixy | 可以 | 英文准确 |
小琪vixq | 慢 | 英文可能不准确 |
小峰vixf | 慢没有节奏 | 英文发音不全 |
小宇xiaoyu | 可以 | 英文发音不好 |
通过比较我发现:
- 女发音人中,
小燕xiaoyan
和小研vixy
这两个发音人可以用,还有就是小燕xiaoyan(默认)
读的时候有写破音,最后我选择小研vixy
这个发音人。小琪vixq
读的有点慢,但是中英文之间切换比较好。
- 而男发音人
小峰vixf
和小宇xiaoyu
读英文的时候声音小不清晰,读音不标准。
具体情况还是以实验为主.