Griffin-Lim演算法

Griffin-Lim演算法(),又稱Griffin-Lim訊號估計算法葛氏林氏演算法

該演算法於1984年由Daniel W. Griffin和Jae S. Lim提出,是一種從短時距傅立葉變換的大小(, STFTM)重建訊號的演算法。

在做語音任務時,如語音合成,語者轉換等,通常都是生成或修改目標信號的時頻譜。
因缺少相位資訊,無法直接從時頻譜還原回聲音訊號,且由於每一幀(frame)時頻譜與相鄰幀的時頻譜在時間上有所重疊,因此具有相互關係,對應的相位在幀與幀之間也應有相關聯性,故無法直接使用任意隨機的相位數值來重建訊號。

然而直接從時頻譜估計相位並不容易,Griffin-Lim演算法使用了迭代的方式,從給定時頻譜去重建相位資訊,其迭代目標是讓重建訊號的時頻譜與給定的時頻譜的均方誤差越小越好。

演算法概述
給定一時頻譜S ,欲重建一訊號,使此重建訊號的時頻譜愈接近S 愈好。

設x_{i} 是第i次重建的訊號,f 為短時距傅立葉變換,f^{-1} 是反短時距傅立葉變換。

S_{i} 、P_{i} 分別代表x_{i} 的短時傅立葉轉換的大小及相位,即

f(x_{i}) = S_{i}e^{jP_{i}}, j = \sqrt -1 。

重建過程如下,

  1. 隨機初始化P_{0} ,則x_{0} = f^{-1}(Se^{jP_{0}})

在第i次迭代

  1. 對x_{i} 作時頻分析取得大小及相位,f(x_{i}) = S_{i}e^{jP_{i}}
  1. 將S_{i}e^{jP_{i}} 中的大小S_{i} 以S 取代
  1. 重建訊號,x_{i+1} = f^{-1}(Se^{jP_{i}})
  1. 重複步驟2~4,直到滿足迭代停止條件

實作
Python實作
以下代碼示範使用numpy及librosa套件來實作Griffin-Lim演算法。

其中S是欲產生訊號的時頻譜,n_iter是演算法迭代次數,n_fft是頻格(frequency bin)大小,hop_length是窗函數每次移動的長度,window是短時距傅立葉變換的窗函數類型。

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(2jnp.pinp.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演算法
  • 類神經聲碼器

参考文献

评论 (0)

  • 还没有评论,来抢沙发吧。