🐍 Python & library/librosa

[Librosa] music/audio processing library Librosa 사용법 Tutorial - (3) Audio feature extraction

복만 2021. 9. 23. 18:32

music/audio processing library Librosa 사용법 Tutorial

(1) Install, import and load

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

(3) Audio feature extraction

(4) Audio feature processing

 

 

Audio data를 이용해 genre classification, instrument recognition, melody extraction 등의 task를 수행하려면 audio data의 feature을 추출해야 한다.

Librosa를 이용해 RMS, Spectral statistics, MFCC, Chroma를 구하는 방법에 대해 소개하겠다.

 

I. RMS

RMSRoot-Mean-Square로, waveform의 amplitude envelope를 구하는 것이다.

수식은 다음과 같다.

 

$\sqrt{\frac1N \sum_{m=0}^{N-1}(x(m-l\cdot R)w[n])^2}$

 

코드는 다음과 같다.

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

 

다음과 같이 RMS plot을 확인할 수 있다. Waveform의 Amplitude envelope와 일치하는 것을 확인할 수 있다. instrument의 종류나, volume을 확인하는 데에 사용될 수 있다.

times = librosa.times_like(rms)
plt.plot(times, rms[0])

(좌) waveform / (우) RMS

 

 

II. Spectral Statistics

Spectrum에서 얻을 수 있는 통계적인 feature 세 가지가 있다.

 

Centroid

 

$SC(l)=\frac{\sum_{k=0}^{N-1}f_k\cdot |X(k,l)|}{\sum_{k=0}^{N-1}|X(k,l)|}$ $*f_k=\frac{k}{N} f_s$

 

Spectrum의 질량중심(Center of mass)을 구한다. Frequency들의 magnitude에 따른 centroid들의 weighted sum이라고 생각하면 된다.

 

Spectral Bandwidth

 

$SB(l)=\frac{\sum_{k=0}^{N-1}(f_k-SC(l))^2\cdot |X(k,l)|}{\sum_{k=0}^{N-1}|X(k,l)|}$ $*f_k=\frac{k}{N} f_s$

 

Spectrum의 bandwidth를 측정한다. Frequency들의 magnitude에 따른 centroid의 s.t.d.들의 weighted sum이라고 생각하면 된다.

 

Spectral Flatness

 

$SF(l)=\frac{^N\sqrt{\Pi_{k=0}^{N-1}|X(k,l)|}}{\frac{1}{N}\sum_{k=0}^{N-1}|X(k,l)|}$

 

Spectrum의 noisiness (또는 tonality)를 구한다. Frequency들의 기하평균'(geometric mean)에 대한 산술평균(arithmetic mean)의 비를 이용해 구할 수 있다. 1에 가까울수록 white noise (maximum flatness)를 의미한다.

 

다음과 같이 세 Spectral Statistics를 구할 수 있다.

y, sr = librosa.load(librosa.ex('trumpet'))
cent = librosa.feature.spectral_centroid(y=y, sr=sr)
spec_bw = librosa.feature.spectral_bandwidth(y=y, sr=sr)
flatness = librosa.feature.spectral_flatness(y=y)

 

다음과 같이 시각화할 수 있다.

times = librosa.times_like(cent)
librosa.display.specshow(librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max), y_axis='linear', x_axis='time')
plt.plot(times, cent.T, label='Spectral centroid', color='w')
plt.plot(times, spec_bw.T, label='Spectral bandwidth', color='y')
plt.legend()

 

times = librosa.times_like(cent)
librosa.display.specshow(librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max), y_axis='linear', x_axis='time')
plt.plot(times, cent.T, label='Spectral centroid', color='w')
plt.fill_between(times, cent[0] - spec_bw[0], cent[0] + spec_bw[0], alpha=0.5, label='Centroid +- bandwidth')
plt.legend()

 

plt.plot(librosa.amplitude_to_db(flatness*1024, ref=np.max).T)
plt.title('Spectral flatnes')

 

 

III. MFCC

Mel-Frequency Cepstral Coefficient (MFCC)는 음색 (timbre)을 추출하기 위해 가장 많이 이용되는 방법 중 하나이다.

Audio frame의 spectrum envelop를 추출해 pitch-invarient하고, feature dimension이 크지 않다는 장점이 있다.

 

MFCC를 구하는 방법은 다음과 같다.

 

1. Mel-spectrum을 구하고, 40-128 정도로 차원을 축소한다.

2. Log compression을 진행한다.

3. Discrete Cosine Transform (DCT)를 수행한다. DCT로 얻은 coefficient들 중, 가장 낮은 frequency부터 13-20개 정도의 coefficient만 사용한다. 이것이 MFCC이다.

 

이렇게 얻은 MFCC를 이용해 Inverse DCT->Inverce mel transform을 하여 waveform을 복원할 수 있다.

 

두 가지 방법을 이용해 MFCC를 구할 수 있는데, 하나는 waveform에서 바로 구하는 것이고, 하나는 위에서 설명한 과정을 직접 수행하는 것이다.

 

첫 번째 방법은 다음과 같다.

y, sr = librosa.load(librosa.ex('trumpet'))
mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)

 

두 번째 방법은 다음과 같다.

mel_S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=40, n_fft=1024) #reduce dim to 40
log_mel_S = librosa.power_to_db(mel_S)
mfcc = librosa.feature.mfcc(S=log_mel_S, n_mfcc=13)

 

n_mfcc argument를 조정해 과정 4.의 coefficient 개수를 설정할 수 있다. default값은 20이다.

 

Output은 (n_mfcc, t) shape의 numpy array이다.

 

MFCC를 이용해 원래의 waveform을 복원하는 방법은 다음과 같다.

y_mfcc = librosa.feature.inverse.mfcc_to_audio(mfcc, n_mels=40)

 

다음과 같이 시각화할 수 있다.

fig, ax = plt.subplots(nrows=3, figsize=(15,15))

img1 = librosa.display.specshow(librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max), x_axis='time', y_axis='linear', ax=ax[0])
ax[0].set(title='Spectogram')
fig.colorbar(img1, ax=ax[0])

img2 = librosa.display.specshow(mfcc, x_axis='time', ax=ax[1])
ax[1].set(title='MFCC')
fig.colorbar(img2, ax=ax[1])

img3 = librosa.display.specshow(librosa.amplitude_to_db(np.abs(librosa.stft(y_mfcc)), ref=np.max), x_axis='time', y_axis='linear', ax=ax[2])
ax[2].set(title='Reconstructed Spectogram')
fig.colorbar(img3, ax=ax[2])

 

 

IV. Chroma

모든 음표는 12개의 pitch(음높이)와 octave로 구성되어 있다.

Chroma는 각 audio frame의 octave는 무시하고, 12개의 pitch class에 대한 분포를 나타낸 것이다.

Pitch class는 C, C#, D, D#, E, F, F#, G, G#, A, A#, B로 구성되어 있다.

 

Chroma 역시 waveform에서 바로, 또는 amplitude spectrum을 이용해 생성할 수 있다.

 

첫 번째 방법은 다음과 같다.

y, sr = librosa.load(librosa.ex('nutcracker'), duration=15)
chroma = librosa.feature.chroma_stft(y=y, sr=sr)

 

두 번째 방법은 다음과 같다.

S = np.abs(librosa.stft(y))
chroma = librosa.feature.chroma_stft(S=S, sr=sr)

 

시각화하면 다음과 같다.

librosa.display.specshow(chroma, y_axis='chroma', x_axis='time')
plt.colorbar()

반응형