TTS(Text to Speech)初识&服务端应用(Ma

背景

最近项目中有个用户输入英语输出音频的场景,因此开始学习了文本转语音的一些知识,并找到一些实现方案实现了需求。

TTS介绍

TTS(Text to Speech, 文本转语音)是指将一般语言文本转换为音频的技术。一般应用于智能助手、盲人助手等应用的语言交互模块中。

实现原理

输入文本(text),输出音频波形(waveform),一般流程分为两步:文本分析、声波生成。

1. 文本分析

提取文本中关于语音生成的信息。一般有3个流程:文字规范化、语音分析、还有韵律分析。

1
2
3
4
5
6
7
8
css复制代码a. 文字规范化
这一步主要是确定语言文字组成,确定词句的开始结束,将非语言文字转为对应文字或者过滤去除。

b. 语音分析
这一步主要是把词句中的发音音标标记出来,以便后续根据音标组成生成词句音频。

c. 韵律分析
这一步主要是分析出词句的语音语调(重音、边界、音长、主频率),以生成更真实音频。

2. 声波生成

根据提取的信息生成声波波形。一般有两种方法:拼接法、参数法。

1
2
3
4
5
6
7
8
9
markdown复制代码* 拼接法
需要准备大量音素或音节的音频库,根据文本分析出的信息,将词句对应的音素音节以适当的方式调节对齐拼接。
优点是音质比较高比较自然。
缺点是需要足够齐全的音频库和适合的拼接方式,不然输出的音频就会失真甚至错误。

* 参数法
使用经过学习的统计模型,输入文本分析结果,预测得到音频的波形参数,再合成生成结果音频。
优点是对音频库要求不高。
缺点是输出音质比较不自然。

服务端应用方案

参考了7 个开源的TTS(文本转语音)系统推荐一文,根据服务端需求选择使用了MaryTTS。

MaryTTS介绍

MaryTTS是一款基于Java语言的开源TTS系统。由德国人工智能研究中心DFKI的语言技术实验室和萨尔大学Saarland University的语音学机构合作创立,现由MMCI的多层次模型语音处理小组和DFKI维护。

当前5.2版本支持德语、英式美式英语、法语、意大利语、卢森堡语、俄语、瑞典语、泰卢固语和土耳其语,以及更多其他语言准备接入。同时,MaryTTS也带有便于快速添加新语言支持和生成语音的工具。

应用

MaryTTS在github(marytts)上提供开源的核心代码和服务端实现代码,也在bintray上提供了封装服务(附带一个美式女性英语音源)的依赖。同时,也有在线网站进行效果试用和可直接安装的应用(包含小工具)提供下载

1
2
3
4
5
6
7
8
9
10
11
12
13
xml复制代码<repositories>
<repository>
<url>https://jcenter.bintray.com</url>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>de.dfki.mary</groupId>
<artifactId>voice-cmu-slt-hsmm</artifactId>
<version>5.2</version>
</dependency>
</dependencies>

代码实现

分析源码,发现其中的主要类如下:

  • MaryConfig

音源、语言、合成参数等配置信息。

  • Mary

TTS系统的核心类,处理音源、配置等资源的加载,加载相关模块。

  • MaryRuntimeUtils

Mary的运行工具,提供给外部调用初始化、获取配置信息等方法。

  • LocalMaryInterface

默认实现的转码接口,可以选择配置一个环境中存在的音源,提供生成音频、生成声音信息文本等方法。

具体实现:

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
kotlin复制代码import marytts.LocalMaryInterface
import marytts.util.data.BufferedDoubleDataSource
import marytts.util.data.audio.DDSAudioInputStream
import marytts.util.data.audio.MaryAudioUtils
import java.io.File
import java.sql.Timestamp
import java.time.Instant
import javax.sound.sampled.AudioFileFormat
import javax.sound.sampled.AudioSystem

/**
* @author hac
* @description: 文本转Wav
*/
class TTWavUtil {

companion object {

private val ttsMap = MaryTTSVoiceType.values().associate {
val tts = LocalMaryInterface()
tts.voice = it.value // 设置音源
Pair(it, tts)
}

/**
* 文本转wav文件
* @param text 文本
* @param output 输出wav文件
* @param voiceType 声音类型
*/
fun ttWavFile(text: String, output: File, voiceType: MaryTTSVoiceType) {
val maryTTS = ttsMap[voiceType]!!
val audio = maryTTS.generateAudio(text)
val samples = MaryAudioUtils.getSamplesAsDoubleArray(audio)
val outputAudio = DDSAudioInputStream(BufferedDoubleDataSource(samples), audio.format)
AudioSystem.write(outputAudio, AudioFileFormat.Type.WAVE, output)
}

}

/**
* 声音类型
*/
enum class MaryTTSVoiceType(val code: Int, val value: String) {

CMU_SLT_HSMM(0, "cmu-slt-hsmm"),
DFKI_SPIKE_HSMM(1, "dfki-spike-hsmm"),
DFKI_POPPY_HSMM(2, "dfki-poppy-hsmm"),
;

}

}

添加音源

音源依赖会在MaryConfig类加载的时候通过ServiceLoader加载运行环境中存在的MaryConfig子类。

1
arduino复制代码private static final ServiceLoader<MaryConfig> configLoader = ServiceLoader.load(MaryConfig.class);

每个音源都可以以Jar包引入的方式添加到服务中。

而音源Jar包则可以通过MaryTTS提供的小工具生成的。将MaryTTS的应用软件包下载解压后,其bin目录下的marytts-component-installer就是生成音源Jar包的工具。


运行会出现GUI操作界面,选择需要的语言下需要的音源进行下载。

Jar包会被下载到解压目录下的lib目录下,将Jar包引入项目即可。

结语

初探了TTS知识并研究使用MaryTTS作为应用方案进行了开发,但是TTS背后还有更多值得深入学习的知识,如音频数字化技术、参数法中的HMM隐马尔可夫模型、新型声波生成方式中的神经网络算法Wavenet等,感兴趣也可再深入探索一番。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%