(A Vocoder-Based High-Quality Speech Synthesis System for Real-Time Applications)
声码器(英语:Vocoder,发音: /ˈvoʊkoʊdər/),源自人声编码器(英语:voice encoder)的缩写,又称语音信号分析合成系统,对声音进行分析与合成的系统,主要应用于合成人类语音。
Analysis分析、Manipulation操作与Synthesis合成。
Analysis分析过程主要是指从一段原始声音波形中提取声学特征如线性谱、低频、MFCC;Manipulation操作过程是指对提取出的原始声学特征进行压缩等降维处理,使其表征能力进一步提升;
Synthesis合成过程是把此声学特征恢复至原始的声音波形。
实际上所有的Vocoder都可通过一种简单的模型实现,此模型就是线性时不变系统。要了解声码器,就要先了解声学模型。
根据人的发声机理,最经典的就是源-滤波模型。左侧代表声音输入,右侧代表声音输出。整体过程为一个基于人发声机理的经典源-滤波器模型,也就是输入的激励部分通过线性时不变系统进行操作;随后输出的声道谐振部分作为合成语音。
输入部分被称为Source Excitation Part:激励部分,右侧输出结果被称为Vocal Tract resonance Part:声道谐振部分。
如果对应人体发声结构进行分析,激励部分对应肺部气流与声带共同作用形成的激励,而声道谐振部分对应于声道的调音运动,对声进行调制。
目前常见声码器分两种,一种是基于传统信号处理算法,如STRAIGHT,Griffim Lim等,还有今天提到的World。第二种是近些年兴起的基于神经网络的声码器(MelGAN、LPCNet等)。
WORLD的计算复杂度更低,更适合用于低性能计算设备。另外,WORLD不需要大量的数据进行训练,直接基于信号处理算法计算。
WORLD可以实现实时、高质量的语音合成。比传统的系统速度快10倍以上,RTF(real time factor)表明它可以应用于实时系统。高质量的语音合成系统包括基频F0提取,谱包络估计算法,和参数估计的合成算法。之前的研究:STRAIGHT可以合成高质量的语音,对语音很容易进行操作。为了满足实时性,提出简化版–Real time STRAIGHT,减少了计算复杂度,但是大大削弱了语音质量。
WORLD声码器的本质:source-filter模型。
WOLRD提取三种声学特征:
基频F0:(声源,即声带震动,发出一串脉冲信号 pulse train),决定了脉冲序列中的各个脉冲的位置。
谱包络(spectrum envelop):也叫频谱参数(Spectrum Parameter, SP),也就是通过 filter声道(喉腔、口腔、嘴唇、牙齿等),在这些部位的共同调制下,我们能够发出不同的音色、不同的元音辅音。这些部位共同组成一个滤波器系统。描述了该帧的音色和语音的内容,是线性时不变系统的频率响应。
非周期信号参数(aperiodic parameter,AP):描述了白噪声与脉冲序列能量的比例。WORLD认为,声源是白噪声与脉冲序列的混合,而不是“非黑即白”。对于清音,白噪声比例很高,非周期比值很高;而对于浊音,白噪声比例很低,非周期比值很低。
source-filter模型,就是激励信号进入一个线性时不变系统(卷积操作),最终得到语音信号。
WORLD 包含三个语音分析模块和一个语音合成模块,语音分析模型包括 DIO 模块、CheapTrick 模块、PLATINUM 模块。
WORLD会重点提取原始波形中的基频、频谱包络与非周期信号,这三种声学特征对应三种提取算法:负责提取基频的DIO(后面有的用harvest算法)、将提取的F0基频同波形一块输入提取频谱包络SP的CheapTrick,以及将F0、SP和波形一同输入提取非周期信号的D4C,最终将三种声学特征通过合成算法输出恢复其原始波形信号。合成语音是通过将最小相位谱与激励信号进行卷积得到。
F0是周期信号的最长持续时间的倒数(基频会产生二次谐波,三次谐波,周期是基频的整数分之一,最长的周期则理论上会对应频率最低的部分,在语谱图上对应最下边的亮线,频率能量最高的部分),有很多算法估计F0,,有两种特性:一个是时域特征,比如自相关,一个是频域特征,比如倒谱cepstrum。
WORLD用DIO估计F0,比YIN、SWIPE要快,但是性能依然很好。DIO分为三步:
a. 不同频带的低通滤波器:因为不知道F0的基频,所以这一步包含不同周期的sin低通滤波器;
b. 计算得到各个可能的F0的可靠性,因为由基波分量组成的sin信号包含四个间隔(两个顶点、两个过零点),如图所示。如果滤波器得到的间隔长度是一致的,说明是同一个基波。
c. 从某个时间点的正弦波中提取出四个周期信号并计算置信度也就是标准差,随后选择标准差最低,置信度最高的基波。
首先看一个简单的声学频谱包络,我们的声音包含不同频率的信号,覆盖0到18000Hz,每个频率都有其振幅(以分贝为单位),定义每种频率波的振幅最高点连线组成的图形为包络。
谱包络也是一个重要的参数,如下图所示,是指在频率-振幅图中,用平滑的曲线将所有共振峰连接起来,这个平滑的曲线就是谱包络。
提取谱包络难度在于估计的结果取决于the temporal position,很难消除它的影响。典型算法有Cepstrum和LPC(linear predictive coding)。LPC就是线性预测编码,其原理为用若干个语音取样过去值的加权线性组合不断逼近一个语音取样值;Cepstrum则是基于复数倒谱拥有频谱幅度与相位信息的原理,通过对一个信号进行FFT、取绝对值、取对数、相位展开、IFFT的变化处理,从而得到其相应的倒谱图实现。
WORLD用CheapTrick去做谱分析,它的思想来源于pitch synchronous analysis (基音同步分析),其过程是先将不同基频进行适配加窗操作与平衡,以及功率平滑操作,随后将信号在频域进行同态滤波操作。
Cheaptrick算法:
包含三个步骤:F0自适应窗,平滑功率谱,以及用于平滑和频谱重建的提升处理。
计算步骤:
a. 第一步:f0自适应窗。计算窗口波形下的功率谱。
采用窗长为3T0的汉宁窗,T0是基音周期。窗的功率在w0处比主瓣(0Hz)低30 dB,这表明谐波结构对邻近结构的影响小于30分贝。由于实际语音包含时间波动、非周期性和噪声,我们假设30dB足够小。
原文公式:
该方程表明,被加窗的周期信号的总功率是时间稳定的。
b. 第二步:频域平滑功率谱。
对数功率谱用于倒频域的处理,但功率谱值为0时对应倒频域值为负无穷,会导致致命的错误。所以该步骤是为了确保功率谱没有0值。
通过一个矩形窗对(1)得到的功率谱进行简单滤波,角频率w0=2pai/T0。矩形窗长设为(2/3)*w0,窗长为 (3/2)T0=1.5T0,为了确保相邻结构之间的影响低于第一步提到的30dB。
c. 第三步:在倒频域提升。去除离散化引起的频率波动。同时进行了谱恢复。
下图是周期脉冲计算时变分量的一个例子。为了精确计算nT0时刻的时变分量,信号的采样频率为65,536 Hz, F0为128 Hz, FFT长度为65,536,信号的长度为1s,帧移的长度为一个样本,1/65536。该图表明时变分量收敛于nT0。为了去除时变分量,提取低频率分量,我们采用了一个sinc函数作为满足要求的提升。
进行specialized liftering (ps是功率谱pw的倒谱)
倒谱(cepstrum):信号的傅里叶变换谱经过对数运算后再进行傅里叶反变换。由于一般傅里叶谱是复数谱,因而又称复倒谱。
(4)(5)都是提升函数,(4)for smoothing,是一个频域窗函数,在倒谱域中如下图所示,nT0的值都为0,这样可以去除时变分量。(5)for spectral recovery。其中参数q0为1.18,q1为-0.09。(6)为倒谱。
mixed excitation和aperiodicity经常用在合成中。在Legacy-STRAIGHT 和 TANDEM-STRAIGHT算法中,aperiodicity被用于合成周期和非周期的信号。WORLD则直接用从波形、F0、和谱包络中得到的mixed excitation的非周期信号,主要有两种算法:Plantinum算法与D4C算法,在WORLD中我们主要采用D4C算法,基本可分为计算、修正参数与估计Band-aperiodicity。
PLUTINUM算法:
PLATINUM 窗长2T,窗函数X(w),被最小的相谱分割。相谱Sm(w),可以计算为:
提取的excitation function可以表示为:
在PLATINUM中,每一个声带振动相关的temporal position必须确定,它是由F0和波形共同决定的。步骤是:
a. 确定出有声的部分;
b. 确定这个部分时间上的中心位置ta;
c. 时间间隔ta±T0,在这个区间的temporal position有最大值y(t)^2,将这个数值定义为初始值,一旦初始值被确定,基于声码器的合成算法自动计算其他的vocal position(声带位置),定义为基于F0 contour脉冲响应的起源。
这个过程在每一个有声段都被重复执行。
图2显示了波形(线)和使用PLATINUM(圆)计算的位置。与TD-PSOLA相似,波形由长度为2T0的汉宁窗。
Legacy-STRAIGHT and TANDEM-STRAIGHT依靠周期和非周期的response计算声带振动,TANDEM-STRAIGHT直接用周期响应,Legacy-STRAIGHT操纵group delay以避免嗡嗡声。
在WORLD中,声带的振动是基于最小相位响应和激励信号上计算的。WORLD比STRAIGHT的卷积要少,因此计算力的需求更少。F0被用于决定每一个声带振动的初始时间位置。
图4 说明了WORLD和STRAIGHT从输入语音提取激励信号,并且合成语音的过程。最上边是输入的wav,中间是卷积之前的激励信号;下边是合成的wav。因为Legacy 和TANDEM的激励信号不仅取决于谱包络,也取决于非周期性,它从拉平的谱包络中计算。
matlab代码如下:
filter_object = CheapTrick(y, fs, f0);
source_object = D4C(y, fs, f0);
y = Synthesis(source_object, filter_object)
代码非常简单,但要理解原理还是有一定难度。
深度理解合成部分代码可参考:world合成
下面简单讲解一下:
WORLD的执行命令::x–input waveform; fs采样率; f0基频,最后合成的时候只用到f0和spec
TANDEM-STRAIGHT的执行命令:第1步提取的基频会在后续步进行优化,source表示f0和非周期信息(ap)
legacy-STRAIGHT:f0和ap的信息在同一步里边提取
python实现
现有专门的pyworld库
import pyworld
import librosa
import numpy as np
# 加载音频
path = "D:/a.wav"
x, fs = librosa.load(path, sr=16000) #librosa load输出的waveform 是 float32,
x = x.astype(np.double)
# 参数设置
frame_period = 5.0
hop_length = int(fs * frame_period * 0.001)#16000*5*0.001=80 5ms,80点
fftlen = pyworld.get_cheaptrick_fft_size(fs)#1024
# 参数提取
f0, timeaxis = pyworld.harvest(x, fs, frame_period=period, f0_floor=71.0, f0_ceil=800.0)
sp = pyworld.cheaptrick(x, f0, timeaxis, fs)
ap = pyworld.d4c(x, f0, timeaxis, fs)
coded_sp = pyworld.code_spectral_envelope(sp, fs, dim)
decoded_sp = pyworld.decode_spectral_envelope(coded_sp, fs, fftlen)
# 合成
y = pyworld.synthesize(f0, decoded_sp, ap, fs, frame_period)
# 画图
plt.figure()
librosa.display.waveplot(x, sr=fs)#原始波形
plt.figure()
librosa.display.waveplot(y, sr=fs)#合成波形
# 绘制F0
plt.figure()
plt.plot(timeaxis, f0, linewidth=2, label="1_F0 contour estimated by Harvest")
plt.xlabel("Time [sec]")
plt.ylabel("Frequency [Hz]")
plt.legend(fontsize=18)
plt.show()
得到结果如下: