펭귄맨 : Spectrogram의 이해
1. 서
이번 포스팅에서는 그동안 계속 언급해온 Spectrogram에 대해 알아보는 시간을 갖는다. 가장 중요한 것은 왜 spectrogram을 입력으로 해야하는지 명확히 인지하는 것이다. 음악은 단순한 소리의 연속을 넘어서 복잡한 구조와 패턴을 갖고 있기 때문에 소리를 수치화하고 시각화하는 과정이 필수적이다. 이러한 과정에서 spectrogram이 어떤 역할을 할 수 있을지를 중심으로 알아보기로 하자.
2. 오디오 스펙트럼(Audio Spectrum)
스펙트럼은 여기저기서 많이 들어본 단어이다. 대표적으로 뉴턴이 프리즘으로 했던 빛의 스펙트럼 실험이 있다. 우리가 다루는 것은 오디오 스펙트럼인데, 오디오 스펙트럼은 음향신호를 주파수와 진폭으로 분석하여 나타낸 것이다. 지난 포스팅에서 Can't Help Falling In Love의 time domain 에서의 파형을 Fourier transform을 통해 frequency domain으로 변환시켰었는데, 그렇게 나온 결과물 또한 오디오 스펙트럼에 해당하는 것이다.
사람의 가청주파수는 20 ~ 20,000 Hz 이고, 음악 등 일상 소리 대부분이 이 범위에 포함된다. 가청 주파수에서도 여러 기준으로 주파수를 구분할 수 있는데, 아래의 그림을 참고삼아 확인하고 넘어가자.
3. 스펙트로그램(Spectrogram)
(1) 스펙트로그램의 개념
오디오 스펙트럼은 오디오 신호에 포함된 여러 주파수를 식별할 수 있어 주파수 분석, 노이즈 제거, 오디오 압축 등의 응용에 활용할 수 있다. 그러나 스펙트럼은 특정 순간의 주파수 성분을 보여주는 정적인 분석 도구이다. 음원파일로부터 악보를 추출해야 하는 이번 프로젝트에서는 시간에 따른 주파수의 변화를 분석해야 하기에 스펙트로그램이 필요하게 된다.
스펙트로그램이란 시간에 따른 신호의 주파수 스펙트럼 변화를 나타내는 2차원 이미지이다. 스펙트럼이 특정 순간의 주파수 성분과 그 진폭만을 보여주는 1차원적 정보라면, 스펙트로그램은 여기에 시간축이 추가되어 각 시간대별로 그 순간의 스펙트럼을 보여주는 2차원적 정보를 제공한다. 아래 그림을 보면 이해가 쉽다.
(2) 비교개념 - 멜 스펙트로그램, MFCC
멜 스펙트로그램(Mel Spectrogram)이란 오디오 신호의 스펙트로그램을 멜 척도로 변환한 것이다. 여기서 멜 척도란 실제 주파수를 인간의 청각 인식에 더 가깝게 매핑하는 비선형 척도이다. 인간의 청각은 높은 주파수에서 넓은 주파수 간격을 더 넓게 인식하는 특성이 있는데, 쉽게 말해 낮은 주파수에서는 미세한 차이를 잘 감지하지만 높은 주파수에서는 덜 민감하게 인식한다는 것이다. 멜 척도는 이를 반영하여 낮은 주파수(약 20 ~ 500Hz라고 한다)에서 더 세밀한 해상도를 제공하고, 높은 주파수에서는 주파수 간격을 넓게 설정하여 상대적으로 낮은 해상도를 제공한다.
MFCC(Mel-Frequency Capstral Coefficients)는 멜 스펙트럼(Mel Spectrum)을 기반으로 하는 오디오 처리 기법이다. 오디오 신호의 짧은 구간(프레임)에 대한 멜 스펙트로그램을 사용하여 DCT(Discrete Cosine Transform)을 통해 더욱 압축한 형태로 변환하는데, 이 과정을 통해 중요한 특성을 추출하게 된다. 결과적으로 MFCC를 통해 오디오 데이터의 feature를 뽑아 벡터화할 수 있게 된다. MFCC는 음성 인식에서 굉장히 유용하게 쓰인다.
프로젝트 펭귄맨에서는 스펙트로그램을 활용할 계획이다. 우선 MFCC는 오디오 데이터에서 가장 중요한 특성을 압축해서 표현하기 때문에 정확한 음높이나 duration을 식별하는데 한계가 있다고 판단하였다. 가장 깊게 고민한 부분은 일반 스펙트로그램과 멜 스펙트로그램중에 어떤 것을 사용할지 여부였는데, 모든 주파수 범위에서 일관된 해상도를 제공하는 스펙트로그램이 적합할 것이라고 판단하였다. 다만, 많은 프로젝트에서 멜 스펙트로그램이 사용되는 이유가 있을 것이기에 프로젝트 진행중 멜 스펙트로그램이 더 적합하다고 생각되면 주저없이 변경하려고 한다.
(3) Can't Help Falling In Love의 스펙트로그램
늘 하던 것 처럼 Can't Help Falling In Love의 스펙트로그램을 만들고 살펴보자. 다음과 같은 파이썬 코드를 작성한다.
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
# 오디오 파일 로드
audio_path = "../../pianosound/Can't_Help_Falling_In_Love.wav"
y, sr = librosa.load(audio_path)
# Short-Time Fourier Transform (STFT)
D = np.abs(librosa.stft(y))
# 스펙트로그램을 데시벨 단위로 변환
S_db = librosa.amplitude_to_db(D, ref=np.max)
# 스펙트로그램 시각화
plt.figure(figsize=(10, 4))
librosa.display.specshow(S_db, sr=sr, x_axis='time', y_axis='hz')
plt.colorbar(format='%+2.0f dB')
plt.title('Spectrogram')
plt.show()
위 코드를 실행하면 다음과 같은 스펙트로그램을 얻을 수 있다.
위는 5마디 분량의 Can't Help Falling In Love을 스펙트로그램으로 나타낸 것이다. 코드를 작성한 김에 Can't Help Falling In Love의 Full 버전과 실제 연주버전의 스펙트로그램을 각각 확인해보자.
악보프로그램에서 재생한 음원과 실제 연주자의 음원은 육안으로 보더라도 꽤 많은 차이가 있음을 확인할 수 있다. 물론 이러한 차이는 당연한 것이다. 예를 들어 악보프로그램에서는 페달 같은 요소를 넣지 않았는데 이것만으로도 꽤 큰 차이가 발생할 것이다. 실제 연주자의 연주로 학습을 시킨다면 데이터를 어떻게 처리해야 할지 고민을 해봐야 할 것 같다.
4. 결어
드디어 프로젝트 진행을 위한 이론적 공부를 마쳤다. 물론 '필요성을 사전에 인지한 이론적 공부'를 마쳤다고 표현하는 것이 정확할 것이다. 프로젝트를 진행하면서 공부가 필요한 부분들은 계속해서 발견될 것이고 이는 수시로 공부해가면서 채워나갈 예정이다. 이제 본격적으로 모델을 탐색하고, 데이터셋을 찾거나 제작하는 등 프로젝트의 핵심 파트들을 시작해보자.