Griffin-Lim算法
Griffin-Lim算法(英语:Griffin-Lim algorithm,Griffin-Lim signal estimation algorithm),又称Griffin-Lim信号估计算法、葛氏林氏算法。
该算法于1984年由Daniel W. Griffin和Jae S. Lim提出[1],是一种从短时距傅里叶变换的大小(short-time Fourier transform magnitude, STFTM)重建信号的算法。
在做语音任务时,如语音合成,语者变换等,通常都是生成或修改目标信号的时频谱。 因缺少相位信息,无法直接从时频谱还原回声音频号,且由于每一帧(frame)时频谱与相邻帧的时频谱在时间上有所重叠,因此具有相互关系,对应的相位在帧与帧之间也应有相关系性,故无法直接使用任意随机的相位数值来重建信号。
然而直接从时频谱估计相位并不容易,Griffin-Lim算法使用了迭代的方式,从给定时频谱去重建相位信息,其迭代目标是让重建信号的时频谱与给定的时频谱的均方误差越小越好。
算法概述
给定一时频谱 ,欲重建一信号,使此重建信号的时频谱愈接近 愈好。
设 是第i次重建的信号, 为短时距傅里叶变换, 是反短时距傅里叶变换。
、 分别代表 的短时傅里叶变换的大小及相位,即
。
重建过程如下,
1. 随机初始化 ,则
在第i次迭代
2. 对 作时频分析获取大小及相位,
3. 将 中的大小 以 取代
4. 重建信号,
5. 重复步骤2~4,直到满足迭代停止条件
实现
Python实现
以下代码示范使用numpy及librosa包来实现Griffin-Lim算法。
其中S是欲产生信号的时频谱,n_iter是算法迭代次数,n_fft是频格(frequency bin)大小,hop_length是窗函数每次移动的长度,window是短时距傅里叶变换的窗函数类型。[2]
def GLA(S, n_iter = 100, n_fft = 2048, hop_length = None, window = 'hann'):
hop_length = n_fft//4 if hop_length is None else hop_length
phase = np.exp(2j*np.pi*np.random.rand(*S.shape))
for i in range(n_iter):
xi = np.abs(S).astype(np.complex)*phase
signal = librosa.istft(xi, hop_length = hop_length, window = window)
next_xi = librosa.stft(signal, n_fft = n_fft, hop_length = hop_length, window = window)
phase = np.exp(1j*np.angle(next_xi))
xi = np.abs(S).astype(np.complex)*phase
signal = librosa.istft(xi, hop_length = hop_length, window = window)
return signal
参见
- 相位声码器
- LWS算法[3]
- 人工神經声码器
参考文献
- ^ D. Griffin and Jae Lim, "Signal estimation from modified short-time Fourier transform," in IEEE Transactions on Acoustics, Speech, and Signal Processing, vol. 32, no. 2, pp. 236-243, April 1984.
- ^ 存档副本. [2020-01-14]. (原始内容存档于2020-11-21).
- ^ Le Roux, Jonathan & Kameoka, Hirokazu & Ono, Nobutaka & Sagayama, Shigeki. (0002). Fast Signal Reconstruction from Magnitude STFT Spectrogram based on Spectrogram Consistency.