Skip to content

Yanshee 人工智能 3 让机器人成为会说话的好朋友

UBTEDU edited this page May 22, 2018 · 1 revision

课程目标

通过本教程了解语音合成的一些概念及经典语音合成的流程。了解一些常见的语音合成技术的优势及不足。最后在YanShee机器上安装开源语音合成程序eSpeak来实现机器人说话,让机器人成为一个爱说话的好孩子。

课程引入原因

让机器人像人类一样说话,就是我们通常意义上的语音合成技术(Test to Speech 简称TTS),语音合成现在被广泛地应用于机器人,智能音响,手机等设备中。现在我们使用的语音合成技术在自然度和音质都有了很大的提高。而在其本身的智能性方面也得到了不少提升。虽然在很多方面机器人说话还远远不如人类合理和具有思考性等等。但是了解目前的主流TTS技术已经是本课的重点关心的内容了。在这个教程里我们将介绍语音合成的基本原理及步骤。让大家不再觉得语音合成是一个很神秘的东西。

环境准备

硬件

• YanShee

• Wireless keyboard and mouse

• HDMI monitor

软件

• Xshell、Rasbian

语音合成原理

语音合成就是通常我们说的TTS(text to speech),它涉及到了语言学、语音学、自然语言处理、信号处理、模式识别等,是一门典型的交叉学科。一般来说,可以分为文本分析、韵律处理和语音合成三大模块。可以理解为通过一系列的数学方法建模,从原始的语音库中取出对应的最小单元,再利用合成技术对最小单元进行重音,语调等调整和修改,最后得到一个音频。

下面是一个典型的语音合成的流程:

文本分析

对输入文本进行语言学分析,逐句进行词汇的、语法的和语义的分析,以确定句子的低层结构和每个字的音素的组成,包括文本的断句、字词切分、多音字的处理、数字的处理、缩略语的处理等。

韵律处理

是指语音合成系统所输出的语音的质量,一般从清晰度(或可懂度)、自然度和连贯性等方面进行主观评价。清晰度是正确听辨有意义词语的百分率;自然度用来评价合成语音音质是否接近人说话的声音,合成词语的语调是否自然; 连贯性用来评价合成语句是否流畅。自然度取决于韵律因素,像措辞和重读,声音的中断和持续,这决定音节的长度和语音的节奏。 这些特征可以指出句子强调的重点,在合适的地方断句等。

语音合成

把处理好的文本所对应的单字或短语从语音合成库中提取,把语言学描述转化成言语波形。 常用的语音合成技术有共振峰合成、LPC合成、PSOLA拼接合成和LMA声道模型技术合成等。这些语音合成技术各有特点,也各有不足。

共振峰合成

首先由于它是建立在对声道的模拟上,因此,对于声道模型的不精确势必会影响其合成质量。另外,实际工作表明,共振峰模型虽然描述了语音中最基本最主要的部分,但并不能表征影响语音自然度的其他许多细微的语音成分,从而影响了合成语音的自然度。另外,共振峰合成器控制十分复杂,对于一个好的合成器来说,其控制参数往往达到几十个,实现起来十分困难。

LPC参数合成

PSOLA技术保持了传统波形拼接技术的优点,简单直观,运算量小,而且还能方便地控制语音信号的韵律参数,具有合成自然连续语流的条件.因此得到了广泛的应用。

PSOLA技术也有其缺点。首先,PSOLA技术是一种基音同步的语音分析/合成技术,首先需要准确的基因周期以及对其起始点的判定。基音周期或其起始点的判定误差将会影响PSOLA技术的效果。其次,PSOLA技术是一种简单的波形映射拼接合成,这种拼接是否能够保持平稳过渡以及它对频域参数有什么影响等并没有得到解决,因此,在合成时会产生不理想的结果。

LMA声道模型

这种方法具有传统的参数合成可以灵活调节韵律参数的优点,同时又具有比PSOLA算法更高的合成音质。

开源语音合成程序eSpeak

现在很多公司都开发了各自的语音合成程序,如科大讯飞、百度、腾讯、阿里等。但是这些商业的语音合成程序我们无法深入地用来学习。eSpeak是一个开源的语音合成软件,它代码精简、支持多种语言并且合成快速。最重要的是他的代码是开放的,我们可以从eSpeak学习一个完整的语音合成。eSpeak使用了上面介绍的共振峰的方法来合成语音,所以eSpeak合成的声音清晰、快速,但是并不真实平滑。

详细信息可以参见:http://espeak.sourceforge.net/

eSpeak的安装

eSpeak可以从源码安装,也可以简单地通过Raspbian的APT源安装。命令如下:

$ sudo apt install espeak

eSpeak 的源码可以从下面网站上得到:https://sourceforge.net/p/espeak/code/HEAD/tree/trunk/

eSpeak的使用

eSpeak的使用非常简单。下面是一个例子。详细的命令行参数请使用”espeak –h”。

espeak -ven+f3 -k5 -s150 "Hello, I am Yanshee"

让机器人大声地读出传感器的值

这里我们用到了Yanshee的SDK。

下载网址: https://github.com/UBTEDU/YanShee-Raspi-SDK

根据网页中的README.md来编译SDK。

#! /usr/local/bin/python

import argparse
from subprocess import call
import time
import datetime
import RobotApi



#Calls the Espeak TTS Engine to read aloud a sentence
def text_to_speech(text):
	#	-ven+m7:	Male voice
	#  The variants are +m1 +m2 +m3 +m4 +m5 +m6 +m7 for male voices and +f1 +f2 +f3 +f4 which simulate female voices by using higher pitches. Other variants include +croak and +whisper.
	#  Run the command espeak --voices for a list of voices.
	#	-s180:		set reading to 180 Words per minute
	#	-k20:		Emphasis on Capital letters
	#call(" amixer set PCM 100 ", shell=True)	# Crank up the volume!

	cmd_start=" espeak -ven-us+m7 -a 200 -s180 -k20 --stdout '"
	cmd_end="' | aplay"
	
	call ([cmd_start+text+cmd_end], shell=True)

def main():

	text_to_speech("Hello! I am Yanshee!")  

        RobotApi.ubtRobotInitialize()
        robotinfo = RobotApi.UBTEDU_ROBOTINFO_T()
        robotinfo.acName="Yanshee_A21A"
        ret = RobotApi.ubtRobotDiscovery("SDK", 15, robotinfo)
        if (0 != ret):
            text_to_speech("Return value: " + str(ret))
            time.sleep(1)
        gIPAddr = robotinfo.acIPAddr

        # Connect to robot
        while True:
            #The robot name you want to connect
            ret = RobotApi.ubtRobotConnect("SDK", "1", gIPAddr)
            if (0 != ret):
                text_to_speech("Warning! Warning! Warning! Cannot connect to the robot")
            else:
                break

	while True: # Read the sensors
	    infrared_sensor = RobotApi.UBTEDU_ROBOTINFRARED_SENSOR_T()
	    iAddr = [17]
	    for Addr in iAddr:
	    	ret = RobotApi.ubtReadSensorValueByAddr("infrared",Addr,infrared_sensor,4)#Use ctypes size
	    	if ret != 0:
			text = "Can not read senor " + str(Addr) + " Error code " +  str(ret)
	    	else:
			#text = "Sensor " + str(Addr) + " is              " + str(infrared_sensor.iValue) + "centimeter"
                        text = "I have detected something " + str(infrared_sensor.iValue) + "centimeter ahead"
                        print infrared_sensor.iValue
	    	text_to_speech(text)
	    	time.sleep(1)


	#---------------------------Disconnect--------------------------------------
	RobotApi.ubtRobotDisconnect("SDK","1",gIPAddr)
	RobotApi.ubtRobotDeinitialize()

if __name__ == '__main__':
    main()

高级实验

为eSpeak添加新的语言支持。尝试优化eSpeak的发音,重音及在不同的上下文下重音的位置。

详细信息请参看:http://espeak.sourceforge.net/add_language.html

拓展阅读

目前TTS技术已经获得了非常快速的发展,市场上主流的市场是科大讯飞、百度、微软、亚马逊、谷歌等人工智能公司的技术。而我们通过对这种技能的学习可以为日后的开发和研究打下坚实的基础。例如:科大讯飞在2017年推出了讯飞实时翻译机。而目前随着语音技术的发展他们的配套设备诸如:环形麦克、智能拾音、消回声芯片模组等也如雨后春笋般来到了生产链的世界,未来世界将是一个语音无处不在的世界,而和它相关的各种机器人也将成为消费者用户的时尚新宠。