2 분 소요

서론

Librosa는 오디오와 음악 분석을 위해 Python에서 제공하는 Package다.
Librosa를 이용해서 졸업작품을 했었는데 그 때는 주파수, window, 이러한 개념도
모른 채 spectrogram을 이용한 음성 인식 AI를 만들기에 급급해
아쉬운 마음에 다시 분석해보자는 마음으로 포스팅을 시작한다.


시작하기에 앞서 PinkLAB님의 유튜브 채널을 Clone Coding하고
개념적인 내용을 더 첨부하려고 한다.

시작해보자

먼저 해당 코드가 업로드 된 Github 주소이다.
Jupyter 환경에서 Coding 하였으며 numpy, librosa, matplotlib를 사용하였다.

pip install librosa
pip install numpy


코드

도(DO), 미(MI), 솔(SOL) 파형 출력

# import 부분
import librosa.display, librosa
import IPython.display
import warnings
import numpy as np
import matplotlib.pyplot as plt
warnings.simplefilter("ignore")
sr = 22 * 1000
ts = 1/sr # 1 주기
time = np.arange(0, 1, ts) # [start, stop, step)
# 주파수을 22000Hz로 가로 22000 등분

time을 출력해보면 아래와 같은 결과가 나온다

array([0.00000000e+00, 4.54545455e-05, 9.09090909e-05, …, 9.99863636e-01, 9.99909091e-01, 9.99954545e-01])
22000등분한 x 좌표가 나온다.


def sin_wave(amp, freq, time):
    return amp * np.sin(2 * np.pi * freq * time)
  • amp는 진폭
  • 2π * 주파수 = 1초에 주기가 몇 번 반복되는 지
  • time은 Θ를 구하기 위해서
DO = sin_wave(1, 261.6256, time)
MI = sin_wave(1, 329.6267, time)
SOL = sin_wave(1, 391.9954, time)

plt.figure(figsize=(12, 5))
plt.plot(time, DO, label='DO', color = 'red')
plt.plot(time, MI, label='MI', color = 'blue')
plt.plot(time, SOL, label='SOL', color = 'green')
plt.xlim(0, 0.05)
plt.legend()
plt.grid()
plt.show()

음계의 주파수를 참고하여 sin 그래프를 그려보자.

주파수가 높을수록 1주기의 길이가 짧아지는 것을 알수 있다.
즉, 1초에 진동하는 속도가 빠를 수록 높은 소리가 난다.

IPython.display.Audio(data=SOL, rate=sr)

Jupyter 환경에서 해당 파형의 소리를 확인해보자.

젓가락 행진곡의 음정을 분석해보자

모든 코드를 업로드하면 저작권의 문제가 있을 수 있으므로,
stft를 사용하여 시간별 주파수를 알아내는 법으로
더 나아가 librosa에서 제공하는 Chroma 기법을 통해서 시간별 음정을 얻어낼 수 있다.
방법은 위의 업로드 된 유트브 링크를 확인해보자.

여기서 stft의 원리를 간단히 요약하자면,
푸리에 변환을 사용하여 각 음계에 해당하는 특정 주파수를 얻어내는 방법이다.

sin 또는 cos 그래프를 원 위에 표현하는 방법을 사용하면 위와 같은 그래프로 표현이된다.
여기에 진동수의 간격을 줄일 수록 1초에 회전해야하는 그래프의 바퀴 수가 늘어나게 된다.
유튜브 링크를 참고해서 이론을 알고 싶다면 확인해보자.

이렇게 감긴 그래프에서 대부분의 무게 중심은 그래프의 원점에 가까이 있는데
오른쪽에 치우치게 되는 구간이 생긴다.
해당 그래프의 Hz 수만큼의 바퀴 수 일 때다 그렇게 시간별로
해당 그래프를 그릴 수 있는 수식을 사용해서
무게 중심을 확인한다음, 무게 중심이 치우치게 되는 구간을 해당 시간대의 주파수로 추출할 수 있다.


만약 두 음정이 합성되어 있다면, 무게 중심이 치우치게 되는 구간이 두 번 나타나게 된다.
그 두 구간이 음정에 해당하는 Hz가 된다.

푸리에 변환을 통해 추출된 결과에서 특정 주파수를 제거하고
다시 푸리에 변환을 실시하면(역 푸리에 변환) 해당 주파수가 빠진
잘 사용한다면 잡음을 제거한 Audio를 만들 수 있다.

chopstick, sr = librosa.core.load('test_sound.wav') # 젓가락 행진곡

draw_chroma(chopstick, sr) # Chroma 분석

마무리

이를 통해 소리를 어떻게 분석하는지
주파수의 의미, sr의 의미 등등 알게 되었다.

다음에는 wav를 Spectrogram으로 변환하고 왜 그렇게 되는지에 대해서 알아보고자 한다.

업데이트:

댓글남기기