欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

TTS(文本到语音)初学者知识和服务器端应用程序(MaryTTS)

最编程 2024-03-22 11:25:50
...

背景

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

TTS介绍

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

实现原理

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

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

a. 文字规范化
这一步主要是确定语言文字组成,确定词句的开始结束,将非语言文字转为对应文字或者过滤去除。
    
b. 语音分析
这一步主要是把词句中的发音音标标记出来,以便后续根据音标组成生成词句音频。
    
c. 韵律分析
这一步主要是分析出词句的语音语调(重音、边界、音长、主频率),以生成更真实音频。

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

* 拼接法
需要准备大量音素或音节的音频库,根据文本分析出的信息,将词句对应的音素音节以适当的方式调节对齐拼接。
优点是音质比较高比较自然。
缺点是需要足够齐全的音频库和适合的拼接方式,不然输出的音频就会失真甚至错误。
    
* 参数法
使用经过学习的统计模型,输入文本分析结果,预测得到音频的波形参数,再合成生成结果音频。
优点是对音频库要求不高。
缺点是输出音质比较不自然。

服务端应用方案

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

MaryTTS介绍

MaryTTS是一款基于Java语言的开源TTS系统。由德国人工智能研究中心DFKI的语言技术实验室和萨尔大学Saarland University的语音学机构合作创立,现由MMCI的多层次模型语音处理小组和DFKI维护。
当前5.2版本支持德语、英式美式英语、法语、意大利语、卢森堡语、俄语、瑞典语、泰卢固语和土耳其语,以及更多其他语言准备接入。同时,MaryTTS也带有便于快速添加新语言支持和生成语音的工具。

应用

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

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

具体实现:

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子类。

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等,感兴趣也可再深入探索一番。