librosa語音信號處理


  librosa是一個非常強大的python語音信號處理的第三方庫,本文參考的是librosa的官方文檔,本文主要總結了一些重要,對我來說非常常用的功能。學會librosa后再也不用用python去實現那些復雜的算法了,只需要一句語句就能輕松實現。

先總結一下本文中常用的專業名詞:sr:采樣率、hop_length:幀移、overlapping:連續幀之間的重疊部分、n_fft:窗口大小、spectrum:頻譜、spectrogram:頻譜圖或叫做語譜圖、amplitude:振幅、mono:單聲道、stereo:立體聲

讀取音頻

librosa.load(path, sr=22050, mono=True, offset=0.0, duration=None)

讀取音頻文件。默認采樣率是22050,如果要保留音頻的原始采樣率,使用sr = None

參數

  • path :音頻文件的路徑。
  • sr 采樣率,如果為“None”使用音頻自身的采樣率
  • mono bool,是否將信號轉換為單聲道
  • offset float,在此時間之后開始閱讀(以秒為單位)
  • 持續時間:float加載這么多的音頻(以秒為單位)

返回:

  • 音頻時間序列
  • sr 音頻的采樣率

重采樣

librosa.resample(y, orig_sr, target_sr, fix=True, scale=False) 

重新采樣從orig_sr到target_sr的時間序列

參數

  • 音頻時間序列。可以是單聲道或立體聲。
  • orig_sr y的原始采樣率
  • target_sr 目標采樣率
  • fixbool,調整重采樣信號的長度,使其大小恰好為 $\frac{len(y)}{orig\_sr}*target\_sr =t*target\_sr$
  • scalebool,縮放重新采樣的信號,以使y和y_hat具有大約相等的總能量。

返回

  • y_hat :重采樣之后的音頻數組

讀取時長

librosa.get_duration(y=None, sr=22050, S=None, n_fft=2048, hop_length=512, center=True, filename=None)

計算時間序列的的持續時間(以秒為單位)

參數:

  • 音頻時間序列
  • sr y的音頻采樣率
  • STFT矩陣或任何STFT衍生的矩陣(例如,色譜圖或梅爾頻譜圖)。根據頻譜圖輸入計算的持續時間僅在達到幀分辨率之前才是准確的。如果需要高精度,則最好直接使用音頻時間序列。
  • n_fft S的 FFT窗口大小
  • hop_length S列之間的音頻樣本數
  • center布爾值
    • 如果為True,則S [:, t]的中心為y [t * hop_length]
    • 如果為False,則S [:, t]從y[t * hop_length]開始
  • filename 如果提供,則所有其他參數都將被忽略,並且持續時間是直接從音頻文件中計算得出的。

返回:

  • 持續時間(以秒為單位)

讀取采樣率

librosa.get_samplerate(path)

參數

  • path :音頻文件的路徑

返回:音頻文件的采樣率

寫音頻

librosa.output.write_wav(path, y, sr, norm=False)

將時間序列輸出為.wav文件

參數

  • 路徑保存輸出wav文件的路徑
  • 音頻時間序列。
  • sr y的采樣率
  • normbool,是否啟用幅度歸一化。將數據縮放到[-1,+1]范圍。

過零率

計算音頻時間序列的過零率。

librosa.feature.zero_crossing_rate(y, frame_length = 2048, hop_length = 512, center = True) 

參數:

  • 音頻時間序列
  • frame_length 幀長
  • hop_length :幀移
  • center:bool,如果為True,則通過填充y的邊緣來使幀居中。

返回:

  • zcr:zcr[0,i]是第i幀中的過零率
y, sr = librosa.load(librosa.util.example_audio_file())
print(librosa.feature.zero_crossing_rate(y))
# array([[ 0.134,  0.139, ...,  0.387,  0.322]])

波形圖

librosa.display.waveplot(y, sr=22050, x_axis='time', offset=0.0, ax=None)

繪制波形的幅度包絡線

參數

  • 音頻時間序列
  • sr :y的采樣率
  • x_axis str {'time','off','none'}或None,如果為“時間”,則在x軸上給定時間刻度線。
  • offset水平偏移(以秒為單位)開始波形圖
import librosa.display
import matplotlib.pyplot as plt

y, sr = librosa.load(librosa.util.example_audio_file(), duration=10)
librosa.display.waveplot(y, sr=sr)
plt.show()

短時傅里葉變換

librosa.stft(y, n_fft=2048, hop_length=None, win_length=None, window='hann', center=True, pad_mode='reflect')

短時傅立葉變換(STFT),返回一個復數矩陣使得D(f,t)

  • 復數的實部:np.abs(D(f,t))頻率的振幅
  • 復數的虛部:np.angle(D(f,t))頻率的相位

參數:

  • y:音頻時間序列
  • n_fftFFT窗口大小,n_fft=hop_length+overlapping
  • hop_length幀移,如果未指定,則默認win_length / 4。
  • win_length每一幀音頻都由window()加窗。窗長win_length,然后用零填充以匹配N_FFT。默認win_length=n_fft
  • window:字符串,元組,數字,函數 shape =(n_fft, )
    • 窗口(字符串,元組或數字);
    • 窗函數,例如scipy.signal.hanning
    • 長度為n_fft的向量或數組
  • center:bool
    • 如果為True,則填充信號y,以使幀 D [:, t]以y [t * hop_length]為中心。
    • 如果為False,則D [:, t]從y [t * hop_length]開始
  • dtypeD的復數值類型。默認值為64-bit complex復數
  • pad_mode如果center = True,則在信號的邊緣使用填充模式。默認情況下,STFT使用reflection padding。

返回:

  • STFT矩陣,shape =(1 + $\frac{n_{fft} }{2}$,t)

短時傅里葉逆變換

librosa.istft(stft_matrix, hop_length=None, win_length=None, window='hann', center=True, length=None)

短時傅立葉逆變換(ISTFT),將復數值D(f,t)頻譜矩陣轉換為時間序列y,窗函數、幀移等參數應與stft相同

參數

  • stft_matrix :經過STFT之后的矩陣
  • hop_length :幀移,默認為$\frac{win_{length}}{4}$
  • win_length :窗長,默認為n_fft
  • window:字符串,元組,數字,函數或shape = (n_fft, )
    • 窗口(字符串,元組或數字)
    • 窗函數,例如scipy.signal.hanning
    • 長度為n_fft的向量或數組
  • center:bool
    • 如果為True,則假定D具有居中的幀
    • 如果False,則假定D具有左對齊的幀
  • length:如果提供,則輸出y為零填充或剪裁為精確長度音頻

返回

  • 時域信號

幅度轉dB

librosa.amplitude_to_db(S, ref=1.0)

將幅度頻譜轉換為dB標度頻譜。也就是對S取對數與這個函數相反的是librosa.db_to_amplitude(S)

參數

  • 輸入幅度
  • ref :參考值,振幅abs(S)相對於ref進行縮放,$20*log_{10}(\frac{S}{ref})$

返回

  • dB為單位的S

功率轉dB

librosa.core.power_to_db(S, ref=1.0)

將功率譜(幅度平方)轉換為分貝(dB)單位,與這個函數相反的是librosa.db_to_power(S)

參數

  • S輸入功率
  • ref :參考值,振幅abs(S)相對於ref進行縮放,$10*log_{10}(\frac{S}{ref})$

返回

  • dB為單位的S
import librosa.display
import numpy as np
import matplotlib.pyplot as plt

y, sr = librosa.load(librosa.util.example_audio_file())
S = np.abs(librosa.stft(y))
print(librosa.power_to_db(S ** 2))
# array([[-33.293, -27.32 , ..., -33.293, -33.293],
#        [-33.293, -25.723, ..., -33.293, -33.293],
#        ...,
#        [-33.293, -33.293, ..., -33.293, -33.293],
#        [-33.293, -33.293, ..., -33.293, -33.293]], dtype=float32)

plt.figure()
plt.subplot(2, 1, 1)
librosa.display.specshow(S ** 2, sr=sr, y_axis='log')  # 從波形獲取功率譜圖
plt.colorbar()
plt.title('Power spectrogram')
plt.subplot(2, 1, 2)
# 相對於峰值功率計算dB, 那么其他的dB都是負的,注意看后邊cmp值
librosa.display.specshow(librosa.power_to_db(S ** 2, ref=np.max),
                         sr=sr, y_axis='log', x_axis='time')
plt.colorbar(format='%+2.0f dB')
plt.title('Log-Power spectrogram')
plt.set_cmap("autumn")
plt.tight_layout()
plt.show()

功率譜和dB功率譜

頻譜圖

librosa.display.specshow(data,  x_axis=None, y_axis=None, sr=22050, hop_length=512)

參數:

  • data:要顯示的矩陣
  • sr 采樣率
  • hop_length :幀移
  • x_axis 、y_axis x和y軸的范圍
  • 頻率類型
    • 'linear','fft','hz':頻率范圍由FFT窗口和采樣率確定
    • 'log':頻譜以對數刻度顯示
    • 'mel':頻率由mel標度決定
  • 時間類型
    • time:標記以毫秒,秒,分鍾或小時顯示。值以秒為單位繪制。
    • s:標記顯示為秒。
    • ms:標記以毫秒為單位顯示。
  • 所有頻率類型均以Hz為單位繪制
import librosa.display
import numpy as np
import matplotlib.pyplot as plt

y, sr = librosa.load(librosa.util.example_audio_file())
plt.figure()

D = librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max)
plt.subplot(2, 1, 1)
librosa.display.specshow(D, y_axis='linear')
plt.colorbar(format='%+2.0f dB')
plt.title('線性頻率功率譜')

plt.subplot(2, 1, 2)
librosa.display.specshow(D, y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('對數頻率功率譜')
plt.show()

Mel濾波器組

librosa.filters.mel(sr, n_fft, n_mels=128, fmin=0.0, fmax=None, htk=False, norm=1)

創建一個濾波器組矩陣以將FFT合並成Mel頻率

參數:

  • sr 輸入信號的采樣率
  • n_fft FFT組件數
  • n_mels 產生的梅爾帶數
  • fmin 最低頻率(Hz)
  • fmax最高頻率(以Hz為單位)。如果為None,則使用fmax = sr / 2.0
  • norm{None,1,np.inf} [標量]
    • 如果為1,則將三角mel權重除以mel帶的寬度(區域歸一化)。否則,保留所有三角形的峰值為1.0

返回:Mel變換矩陣

melfb = librosa.filters.mel(22050, 2048)
# array([[ 0.   ,  0.016, ...,  0.   ,  0.   ],
#        [ 0.   ,  0.   , ...,  0.   ,  0.   ],
#        ...,
#        [ 0.   ,  0.   , ...,  0.   ,  0.   ],
#        [ 0.   ,  0.   , ...,  0.   ,  0.   ]])
import matplotlib.pyplot as plt
plt.figure()
librosa.display.specshow(melfb, x_axis='linear')
plt.ylabel('Mel filter')
plt.title('Mel filter bank')
plt.colorbar()
plt.tight_layout()
plt.show()

計算Mel scaled 頻譜

librosa.feature.melspectrogram(y=None, sr=22050, S=None, n_fft=2048, hop_length=512, win_length=None, window='hann',
center=True, pad_mode='reflect', power=2.0)

如果提供了頻譜圖輸入S,則通過mel_f.dot(S)將其直接映射到mel_f上。

如果提供了時間序列輸入y,sr,則首先計算其幅值頻譜S,然后通過mel_f.dot(S ** power)將其映射到mel scale上 。默認情況下,power= 2在功率譜上運行。

參數

  • 音頻時間序列
  • sr 采樣率
  • 頻譜
  • n_fft FFT窗口的長度
  • hop_length :幀移
  • win_length 口的長度為win_length,默認win_length = n_fft
  • window 字符串,元組,數字,函數或shape =(n_fft, )
    • 窗口規范(字符串,元組或數字);看到scipy.signal.get_window
    • 窗口函數,例如 scipy.signal.hanning
    • 度為n_fft的向量或數組
  • centerbool
    • 如果為True,則填充信號y,以使幀 t以y [t * hop_length]為中心。
    • 如果為False,則幀t從y [t * hop_length]開始
  • power幅度譜的指數。例如1代表能量,2代表功率,等等
  • n_mels:濾波器組的個數 1288
  • fmax:最高頻率

返回:Mel頻譜shape=(n_mels, t)

import librosa.display
import numpy as np
import matplotlib.pyplot as plt

y, sr = librosa.load(librosa.util.example_audio_file())
# 方法一:使用時間序列求Mel頻譜
print(librosa.feature.melspectrogram(y=y, sr=sr))
# array([[  2.891e-07,   2.548e-03, ...,   8.116e-09,   5.633e-09],
#        [  1.986e-07,   1.162e-02, ...,   9.332e-08,   6.716e-09],
#        ...,
#        [  3.668e-09,   2.029e-08, ...,   3.208e-09,   2.864e-09],
#        [  2.561e-10,   2.096e-09, ...,   7.543e-10,   6.101e-10]])

# 方法二:使用stft頻譜求Mel頻譜
D = np.abs(librosa.stft(y)) ** 2  # stft頻譜
S = librosa.feature.melspectrogram(S=D)  # 使用stft頻譜求Mel頻譜

plt.figure(figsize=(10, 4))
librosa.display.specshow(librosa.power_to_db(S, ref=np.max),
                         y_axis='mel', fmax=8000, x_axis='time')
plt.colorbar(format='%+2.0f dB')
plt.title('Mel spectrogram')
plt.tight_layout()
plt.show()

提取Log-Mel Spectrogram 特征

  Log-Mel Spectrogram特征是目前在語音識別和環境聲音識別中很常用的一個特征,由於CNN在處理圖像上展現了強大的能力,使得音頻信號的頻譜圖特征的使用愈加廣泛,甚至比MFCC使用的更多。在librosa中,Log-Mel Spectrogram特征的提取只需幾行代碼:

import librosa

y, sr = librosa.load('./train_nb.wav', sr=16000)
# 提取 mel spectrogram feature
melspec = librosa.feature.melspectrogram(y, sr, n_fft=1024, hop_length=512, n_mels=128)
logmelspec = librosa.amplitude_to_db(melspec)        # 轉換到對數刻度

print(logmelspec.shape)        # (128, 65)

  可見,Log-Mel Spectrogram特征是二維數組的形式,128表示Mel頻率的維度(頻域),64為時間幀長度(時域),所以Log-Mel Spectrogram特征是音頻信號的時頻表示特征。其中,n_fft指的是窗的大小,這里為1024;hop_length表示相鄰窗之間的距離,這里為512,也就是相鄰窗之間有50%的overlap;n_mels為mel bands的數量,這里設為128。

提取MFCC系數

  MFCC特征是一種在自動語音識別和說話人識別中廣泛使用的特征。關於MFCC特征的詳細信息,有興趣的可以參考博客http:// blog.csdn.net/zzc15806/article/details/79246716。在librosa中,提取MFCC特征只需要一個函數:

librosa.feature.mfcc(y=None, sr=22050, S=None, n_mfcc=20, dct_type=2, norm='ortho', **kwargs)

參數:

  • y:音頻數據
  • sr:采樣率
  • S:np.ndarray,對數功能梅爾譜圖
  • n_mfcc:int>0,要返回的MFCC數量
  • dct_type:None, or {1, 2, 3}  離散余弦變換(DCT)類型。默認情況下,使用DCT類型2。
  • norm: None or ‘ortho’ 規范。如果dct_type為2或3,則設置norm =’ortho’使用正交DCT基礎。 標准化不支持dct_type = 1。

返回:

  • M: MFCC序列
import librosa

y, sr = librosa.load('./train_nb.wav', sr=16000)
# 提取 MFCC feature
mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=40)

print(mfccs.shape)        # (40, 65)

線性譜梅爾譜對數譜:經過FFT變換后得到語音數據的線性譜,對線性譜取Mel系數,得到梅爾譜;對線性譜取對數,得到對數譜。

參考

線性譜與梅爾譜

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM