Griffin_lim算法详解
声码器
声码器是语音分析和合成的一一种工具,目前主要用来将将声学参数转换成语音波形,即合成。
常见的传统声码器有 WORLD, STRAIGHT及其变种等; 还有目前较火的神经网络声码器,如WaveNet,一种可训练的基于深度神经网络的声码器,可生成高质量的语音波形。
GL算法
Griffin_lim声码器是将语谱图转回波形的一种算法。主要思想为已知幅度谱,未知相位谱,通过迭代生成相位谱,并用已知的幅度谱和计算得出的相位谱,重建语音波形。因为常见的特征MEL-spectrum 和 linear-spectrum里面节缺少相位信息。
由1984年的这篇文章提出:
Griffin, Daniel, and Jae Lim. “Signal estimation from modified short-time Fourier transform.” IEEE Transactions on Acoustics, Speech, and Signal Processing 32.2 (1984): 236-243
算法步骤
就是一个迭代算法,利用帧frame之间相位的约束来实现迭代收敛。
- 幅度谱Amplitude矩阵A1已知 ,无相位谱,所以先随机初始化一个相位谱w1;
- 用相位谱和已知的幅度谱经过IFFT,得到时域信号y1(此时相位并不准确);
- 对该时域信号再做STFT得y2,计算y2的幅度谱A2和相位谱为w2;
- 用新的相位谱w2和原幅度谱A1再IFFT,得到时域信号y3,如此重复。
代码实现
def griffin_lim(S, hparams):
'''librosa implementation of Griffin-Lim
Based on https://github.com/librosa/librosa/issues/434
'''
angles = np.exp(2j * np.pi * np.random.rand(*S.shape))#随机生成相位谱w1
S_complex = np.abs(S).astype(np.complex)# A1
y = _istft(S_complex * angles, hparams) # y1
for i in range(hparams.griffin_lim_iters):
angles = np.exp(1j * np.angle(_stft(y, hparams))) #w2,w3...
y = _istft(S_complex * angles, hparams) #y2,y3...但已知是A1
return y
数学推导
上图最后得到的更新方程如下:
其中: