본문 바로가기
Developer/Librosa

[Python 음성 데이터 분석] Librosa 라이브러리 사용법

by Doony 2020. 7. 28.

지난 포스팅까지 파이썬을 활용하여 음성 데이터를 분석하는 전반적인 단계들에 대해 다뤘습니다. 중간중간 Librosa 패키지를 사용하는 방법에 대해서도 설명했습니다만, 아무래도 한 포스팅에서 모아서 요약해놓는 것이 좋을 것 같네요.


Librosa 라이브러리

Python에서 음원 데이터를 분석해주는 아주 고마운 라이브러리입니다. short time fourier transform이나 mel spectrogram, mfcc 등 흔히들 사용하는 기능들을 모두 제공하고 있습니다.


기본 셋팅

pip install librosa
import librosa


음원 데이터 불러오기

아래와 같이 간단하게 wav파일을 불러올 수 있습니다.

  • y: 음원의 파형 데이터
  • sr: sampling rate (주파수 분석 및 파형의 시간 간격을 결정)

1
2
audio_path = 'fileName.wav'
y, sr = librosa.load(audio_path)
cs

STFT (Short Time Fourier Transform)

Time 도메인의 파형을 Frequency 도메인으로 변형시키는 푸리에 변환입니다. 이 때, 전체 파형을 대상으로 하면 제대로 된 주파수 분석을 할 수 없기 때문에, 짧은 시간 단위로 분리해서 각각의 구간에 대해 변환을 합니다.

  • 설정하는 파라미터가 다양한데, 상세 설명은 이전 STFT 포스팅에서 확인하실 수 있습니다.

1
2
3
4
5
6
stft_result = librosa.stft(y, n_fft=4096, win_length = 4096, hop_length=512)
= np.abs(stft_result)
S_dB = librosa.power_to_db(D, ref=np.max)
librosa.display.specshow(S_dB, sr=sr, hop_length = 1024, y_axis='mel', x_axis='time', cmap = cm.jet)
plt.colorbar(format='%2.0f dB')
plt.show()
cs

Mel Spectrogram 생성

Mel Scale 변환을 통해 사람의 귀에 맞춰진(?) 스펙트로그램을 생성합니다. STFT로 나온 결과는 수치적으로는 객관적이지만, 실제 사람의 귀의 입장에서는 그렇지 않기 때문에 Mel Spectrogram을 사용합니다.

  • 파라미터는 STFT와 유사하며, n_mels를 통해 주파수 해상도를 결정합니다. 관련 포스팅 참고.
    반드시 아래와 같이 할 필요는 없고, 파형 원본 데이터인 y에서 바로 생성도 가능합니다. 파라미터들만 잘 설정해주면 됩니다.

1
2
3
4
5
= np.abs(librosa.stft(y, n_fft=n_fft, win_length = win_length, hop_length=hop_length))
mel_spec = librosa.feature.melspectrogram(S=D, sr=sr, n_mels=n_mels, hop_length=hop_length, win_length=win_length)
librosa.display.specshow(librosa.amplitude_to_db(mel_spec, ref=0.00002), sr=sr, hop_length = hop_length, y_axis='mel', x_axis='time', cmap = cm.jet)
plt.colorbar(format='%2.0f dB')
plt.show()
cs

MFCC 생성 (Mel Frequency Cepstral Coefficient)

MFCC는 Mel spectrogram에 DCT를 거쳐서 나온 결과값입니다. 스펙트로그램 대비 압축된 정보를 담고 있다고 볼 수 있으며, 압축하는 과정에서 손실이 발생, 노이즈가 제거되는 효과가 있습니다. 이 때문에 MFCC 값이 고유의 음성 정보를 담고 있다고 보기도 하는 것 같습니다. 주로 음성 데이터 분석을 할 때도 MFCC로 하는 것으로 알고 있습니다. 역변환을 하면 원본 파형데이터인 y의 형태로도 연산이 가능하기 때문입니다.

  • 파라미터는 n_mfcc가 있으며, 압축을 얼마나 할지에 대한 것입니다. 크면 클수록 스펙트로그램의 값을 더 잘 담아내며, 작을수록 손실이 많이 발생합니다. 관련 포스팅 참고.

1
2
= np.abs(librosa.stft(y, n_fft=n_fft, win_length = win_length, hop_length=hop_length))
mfcc = librosa.feature.mfcc(S=librosa.power_to_db(D), sr=sr, n_mfcc=n_mfcc)
cs

역변환 하는 방법

위에서 설명한 모든 방법은 역변환을 할 수 있습니다. 아래와 같이 Librosa에서 메소드들을 제공하며, 단계 순서에 관계없이도 역변환이 가능하기 때문에 파라미터 설정만 잘 맞춰주시면 됩니다.


1
2
3
4
feature.inverse.mel_to_stft(params)
feature.inverse.mel_to_audio(params)
feature.inverse.mfcc_to_mel(params)
feature.inverse.mfcc_to_audio(params) 
cs

역변환 시 다시 오디오 파형으로 그리는 방법?

음원을 주파수 분석하기 위해 FFT를 하는 것을 STFT로 진행한다고 위에서 언급했습니다. 보통 푸리에 변환은 역변환이 가능하기 때문에 바로 다시 음원으로 변형도 가능합니다만, 위 예제의 경우 보시다시피 np.abs(), 즉 절대값을 취하는 과정을 거쳐서 스펙트로그램을 만들었기 때문에 역변환이 불가능합니다.

Why?

푸리에 변환의 결과값이 위상값을 포함한 복소수로 이루어져 있기 때문입니다. 즉, STFT의 원본 결과값을 출력해보면 복소수 형태로 위상값을 포함하고 있다는 것을 알 수 있습니다. 그런데 abs로 절대화시키는 순간, 위상 정보를 잃게 됩니다.
때문에 이런 스펙트로그램에서 파형으로 다시 가기 위해서는 위상을 만드는 과정이 필요하게 됩니다.


Griffin-Lim

다양한 방식들이 있지만, librosa에서 griffin-lim이라는 방식을 제공하고 있습니다. 자세히 읽어보진 않았지만, iterative한 방식으로 위상값을 유추해내는 기법이라고 합니다. 원본 데이터의 위상과 정확히 일치하진 않더라도 이런 방식을 통해 오디오 파형으로 역변환이 가능합니다. 또 역변환된 음원과 원본 음원을 함께 들어보면 큰 차이가 나지는 않는 것 같습니다. 어차피 FFT의 결과값이 주기가 다른 sin들이기 때문이 아닐까 싶습니다. 주기가 다르기 때문에 위상이 차이가 나더라도, 그 안에서 상쇄되지는 않는 것 같습니다만! 혹시 차이가 발생하는 부분들이 있다면 댓글로 남겨주시면 감사하겠습니다.

댓글