🐍 Python & library/librosa

[Librosa] music/audio processing library Librosa 사용법 Tutorial - (2) Audio data representations (Spectrogram, Mel-spectogram)

복만 2021. 9. 23. 17:30

music/audio processing library Librosa 사용법 Tutorial

(1) Install, import and load

(2) Audio data representations (Spectrogram, Mel-spectogram)

(3) Audio feature extraction

(4) Audio feature processing

 

 

librosa.load method를 이용하여 audio file을 불러오면 waveform의 형태로 데이터를 얻게 된다.

Waveform만으로는 audio data를 분석하기에 어려움이 있다.

이번 글에서는 Audio data를 분석하고 특징을 알아낼 수 있는 representation을 librosa로 얻는 방법에 대해 소개하겠다.

 

Spectrogram

Spectrogram은 Short-Time Fourier Transform (STFT)를 이용한 audio의 2D 표현법이다.

STFT란, 말 그대로 짧은 시간 동안의 데이터를 Fourier Transform하는 것이다.

STFT는 window를 이용해 waveform을 frame 단위로 나누어, 각각의 frame에 DFT를 한다.

DFT된 각 frame들을 합쳐 2D 데이터로 나타내고, 이를 통해 시간에 따른 frequency의 변화를 알 수 있다.

아래 그림에서 STFT의 과정에 대해 설명하고 있다.

 

https://kr.mathworks.com/help/dsp/ref/dsp.stft.html

 

아래 코드를 통해 spectrogram을 추출할 수 있다.

y, sr = librosa.load(librosa.ex('trumpet'))
S = librosa.stft(y, n_fft=2048, window='hann', hop_length=512)

 

주요 argument는 다음과 같다.

  • window : STFT에 사용할 window의 종류
  • n_fft : length of the windowed signal after padding with zeros. 즉, 각 frame은 window_length만큼 windowing된 후 n_fft만큼 zero-padding된다.
  • hop_length : number of audio samples between adjacent STFT columns. 즉 각 window center 간의 거리이다. default 값은 win_length // 4. 이 값이 작아질수록 frame의 개수는 많아지기 때문에, output의 column 개수가 많아진다. (window 하나당 frame 하나가 나온다고 생각하면 된다)

 

Output은 (1+n_fft/2, n_frames) 크기의 2차원 numpy complex-valued array이다.

n_frames는 input signal의 길이와 hop_length에 의해 결정된다:

n_frames = 1 + int((len(y) - frame_length) / hop_length)

 

amplitude_to_db method와 librosa.display를 이용해 시각화할 수 있다.

amplitude_to_db는 amplitude spectrogram을 dB-scaled spectrogram으로 바꿔주는 method이다.

($dB = 20log_{10}(\frac{amp}{amp_{ref}})$)

따라서 spectrogram의 aplituede인 np.abs(S)를 이용해 변환한다.

D = librosa.amplitude_to_db(np.abs(S), ref=np.max)
librosa.display.specshow(D, y_axis='log', x_axis='time')
plt.colorbar(format='%+2.0f dB')

 

 

Mel spectrogram

사람의 귀는 주파수의 범위에 따른 민감도가 다르다. 보통 낮은 주파수 대역의 소리에 더 민감한데, 이를 나타낸 것이 Mel scale이다.

https://en.wikipedia.org/wiki/Mel_scale

 

주파수를 mel scale로 변환하는 식은 다음과 같다.

 

$m=2595log_{10}(1+f/700)$

 

Mel spectrogram은 linear frequency의 spectogram을 mel scale로 mapping하여 low frequency는 부각하고, high frequency는 squeeze한 것이다.

audio data의 성분들도 low frequency 대역에 더 집중되어 있으므로, mel-spectrogram을 이용하면 이를 더 잘 볼 수 있다.

 

Librosa에서 두 가지 방법을 이용해 mel spectogram을 구할 수 있다.

첫 번째는 waveform을 이용해 바로 mel spectorgram을 구하는 것이다. 이 경우 내부에서 spectrogram을 구한 후 mel-spectrogram으로 변환한다.

y, sr = librosa.load(librosa.ex('trumpet'))
S = librosa.feature.melspectrogram(y=y, sr=sr)

 

두 번째는 위에서 구한 spectogram을 이용하는 것이다. Amplitude spectrogram에 제곱을 하여 power spectrum을 얻은 후, 이를 input으로 주면 된다.

D = np.abs(librosa.stft(y))**2
S = librosa.feature.melspectrogram(S=D, sr=sr)

 

마찬가지로 dB로 변환하여 시각화할 수 있다.

S_dB = librosa.power_to_db(S, ref=np.max)
librosa.display.specshow(S_dB, x_axis='time', y_axis='mel', sr=sr)
plt.colorbar(format='%+2.0f dB')

반응형