개발이모저모

[python] librosa로 오디오 관련 그래프 그리기 (waveform, stft, spectrum, spectrogram, mfcc, Mel Spectrogram, chroma)

아티스트갓건 2022. 11. 10. 11:35

librosa로 오디오 관련 그래프를 그리는 법을 알아본다. 각 방식에 대한 자세한 설명은 생략하고...그래프를 그리는 법에 대해 알아보자

우선 필요한 모듈을 설치하고 import한다

pip install librosa
pip install matplotlib
pip install numpy

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

y, sr = librosa.load('test.wav')

print(y.shape) # (5477356,)
print(sr) # 22050

librosa는 오디오를 불러오고 오디오 처리를 위한 라이브러리이고

librosa.display는 librosa에 어울리게 그래프를 최적화 해주는 모듈이다 (본인은 ld로 줄여서 사용한다)

numpy는 librosa를 설치하면 자동으로 설치가 되지만 혹시 모르니 설치를 따로 해준다.

matplotlib 는 파이썬으로 그림이나 그래프 등을 그려주는 라이브러리인데 데이터과학을 하는 사람이라면 numpy, pandas와 더불어서 필수적으로 사용할줄 알면 좋다 (보통 matplotlib.pyplot as plt 로 많이 사용한다)

 

test.wav는 본인 컴퓨터에 있는 아무 wav파일 쓰면되고, print해서 나온 결과는 파일마다 다를것이다.

 

1. 오디오 웨이브폼 (audio waveform)

단순한 웨이브폼을 출력하는 방법이다

ld.waveshow(y = y)

plt.show()

librosa의 모듈은 대부분 기본 값 만으로도 보기좋고 괜찮은 결과를 만들어준다. 파라미터의 상세한 설명은 나중에 따로 올리겠다.

ld.waveshow 는 시간에 따라 오디오 신호가 변화하는 것을 출력해주는 모듈이다.

plt.show() 는 코드 상에서 만든 그래프를 그림으로 보여주는 모듈이다. matplotlib 에서 쓰이는 print 문 같은 것이다.

 

2. STFT ( Shot Time Fourier Transform ) Spectrogram

STFT 는 오디오 데이터를 주파수 - 시간 정보로 변환하는 방식이다. 단순 웨이브 폼에는 주파수 정보가 없고, 여기선 설명을 안하겠지만 단순 FFT에는 주파수 정보만 있고 시간 정보는 없기 때문에 데이터 과학을 할땐 STFT나 STFT를 응용한 데이터를 사용한다.

y, sr = librosa.load('test.wav') # 오디오 로드

stft = librosa.stft(y=y) # y를 stft로 변경
stft = np.abs(stft) # 절대값을 취해 복소수를 제거. 안해도 상관없으나 안하면 librosa.display에 값을 넣을 때 warning 메세지가 나옴
ld.specshow(
    data = librosa.amplitude_to_db(stft, ref = np.max), # 그냥 data = stft로 해도 상관없으나 그럼 잘 안보임. 데이터를 dB(데시벨) 값으로 변환하여 잘 보이게 표시함
    x_axis= 'time', # x 축은 시간
    y_axis= 'hz', # y 축은 주파수
    )
plt.title('STFT') # 안해도 됨. 표시되는 그래프의 제목을 입력하는 기능
plt.show() # 그래프 표시

STFT Spectrogram

3. MelSpectrogram

STFT는 단순히 주파수를 나열한 방식이라면 MelSpectrogram은 사람이 주파수를 인지하는 원리를 반영한 방식임. MelSpectrogram과 이후 나올 MFCC는 데이터과학에서 정말 많이 쓰임.

각종 오디오 프로그램 또는 시퀀서에서 제공하는 Spectrum의 경우 Scale을 조절할 수 있는 기능이 있는데 그것이 이것과 유사함

y, sr = librosa.load('test.wav')

melSpectrogram = librosa.feature.melspectrogram(y = y) # mel spectrogram 기본 모듈	
# melSpectrogram = librosa.feature.melspectrogram(y = y, n_mels = 40) # n_mels라는 인자로 mel 수 변경 가능. 기본값은 128

ld.specshow(
    data = librosa.amplitude_to_db(melSpectrogram, ref = np.max),
    x_axis = 'time',
    y_axis = 'mel'
    )

plt.title('Mel Spectrogram')
plt.show()

4. MFCC

Mel Spectrogram에 어쩌구 저쩌구 뭔갈 해서 해당 오디오의 특징을 뽑아내는거라고 함. 암튼 많이 쓰임

y, sr = librosa.load('test.wav')

mfcc = librosa.feature.mfcc(y = y) # mfcc는 이게 끝

ld.specshow(
    data = mfcc,
    x_axis= 'time',
    )

plt.title('MFCC')
plt.show()

5. Chroma

도 ~ 시 (총 12음)으로 표시하는 방법이다. stft, cqt, cens 3가지 방식이 있는데 그래프를 보면 각각의 특징이 조금씩 다르다. 이것도 자세한 설명은 나중에...

y, sr = librosa.load('test.wav')

# chroma 3가지 방식
chroma_stft = librosa.feature.chroma_stft(y = y)
chroma_cqt = librosa.feature.chroma_cqt(y = y)
chroma_cens = librosa.feature.chroma_cens(y = y)

# 그래프 그리기
_, axs = plt.subplots(nrows = 3) # 그래프 3개를 세로로 정렬

# librosa.display의 ax 인자를 활용하면 한 그림에 여러 그래프를 넣을 수 있다
ld.specshow(data = chroma_stft, x_axis= 'time', y_axis= 'chroma', ax = axs[0])
ld.specshow(data = chroma_cqt, x_axis= 'time', y_axis= 'chroma', ax = axs[1])
ld.specshow(data = chroma_cens, x_axis= 'time', y_axis= 'chroma', ax = axs[2])

# 각각의 그래프에 제목을 쓰는 방법
axs[0].set_title('chroma stft')
axs[1].set_title('chroma cqt')
axs[2].set_title('chroma cens')

plt.show()

chroma 시리즈. 각각의 특징이 조금씩 다르다

 

결론

오디오 각각의 표현 방식을 그래프로 나타내는 방법을 알아 보았다. 표현 방식별 상세한 설명은 추후에 하기로 하고, 가장 기본적으로 오디오 특징을 표현할 수 있는 코드와 이를 그래프로 나타내는 방법을 얻어가면 좋을것같다.