STILLCODING

STILL CODING / NOTES

텍스트로 쓰는 악보 ABC 표기법과, 샘플 없이 피아노 소리 만들기

JH Kim

Songnote는 글자로 적은 악보를 오선보로 보여 주고, 브라우저 안에서 피아노 소리로 연주하는 작은 스튜디오입니다. 포털에서는 Piano Play라는 이름으로 소개합니다. 이 글은 두 부분으로 나뉩니다. 앞부분은 누구나 바로 따라 할 수 있는 ABC 표기법 입문, 뒷부분은 녹음된 피아노 소리 없이 소리를 직접 합성한 방법입니다.

1. ABC 표기법이란

ABC는 1990년대부터 민속음악 연주자들이 이메일과 게시판으로 곡을 주고받으려고 쓰기 시작한 텍스트 악보 형식입니다. 오선보를 그릴 수 없는 환경에서도 알파벳과 기호만으로 음높이, 길이, 박자, 조성을 적을 수 있습니다. 텍스트라서 버전 관리가 쉽고, 한 줄만 고쳐도 곡이 바뀌므로 “고치면서 들어 보는” 연습에 잘 맞습니다.

머리말(헤더)

악보는 머리말 몇 줄로 시작합니다.

X:1
T:나의 첫 연주
M:4/4
L:1/4
Q:1/4=100
K:C
C D E F | G A B c | [CEG]4 |]
필드뜻예시의 의미
X:곡 번호첫 번째 곡
T:제목나의 첫 연주
M:박자표4/4박자
L:기본 음표 길이숫자 없이 쓴 음표는 4분음표
Q:템포4분음표 기준 분당 100박
K:조성C장조. Songnote에서는 반드시 있어야 합니다

음높이와 길이

첫 곡: 작은 별

X:1
T:작은 별
M:4/4
L:1/4
Q:1/4=96
K:C
C C G G | A A G2 | F F E E | D D C2 |]

이 여섯 줄을 Songnote 에디터에 붙여 넣고 저장하면 바로 오선보와 소리로 확인할 수 있습니다. G2를 G로 바꾸거나 K:C를 K:G로 바꿔 보면서, 한 글자가 소리를 어떻게 바꾸는지 들어 보는 것이 가장 빠른 학습 방법입니다.

강약과 연주 기호

ABC 표준 장식 기호도 쓸 수 있습니다. !p!, !mf!, !f!는 셈여림, !<(! … !<)!는 크레센도, (CDEF)는 레가토, .D는 스타카토, !accent!는 악센트입니다. Songnote는 이 기호를 오선보에 표시할 뿐 아니라 실제 소리의 세기와 길이에도 반영합니다.

피아노 특유의 연주 효과는 ABC 표준에 없어서, 주석 형태의 전용 지시문을 따로 만들었습니다. 박 단위로 구간을 지정합니다.

% songnote tremolo start=0 end=4 rate=8
% songnote pedal start=4 end=8
% songnote glissando start=8 end=10 from=C4 to=C5

주석(%)으로 시작하므로 다른 ABC 프로그램에서 열어도 악보가 깨지지 않습니다. 호환성을 지키면서 기능을 넓히는 방법으로 이 형식을 골랐습니다.

2. 샘플 없이 피아노 소리 만들기

보통 웹 피아노는 실제 피아노를 녹음한 샘플(SoundFont)을 내려받아 재생합니다. 소리는 좋지만 수 MB에서 수십 MB를 받아야 하고, 첫 소리가 나기까지 기다려야 합니다. Songnote는 샘플을 하나도 쓰지 않고, Web Audio API의 사인파 발진기(oscillator)를 겹쳐서 소리를 만듭니다. 이 방식을 가산 합성(additive synthesis)이라고 합니다.

기본 주파수

MIDI 번호 m인 음의 기본 주파수는 평균율 공식으로 구합니다.

f = 440 × 2^((m − 69) / 12)

A4(MIDI 69)가 440Hz이고, 반음 올라갈 때마다 2의 12제곱근(약 1.0595)배가 됩니다.

배음을 겹친다

악기 소리가 사인파 하나와 다르게 들리는 이유는 배음 때문입니다. 기본 주파수의 2배, 3배, 4배 … 주파수 성분이 각각 다른 세기로 섞입니다. Songnote는 음마다 최대 6개의 사인파를 겹치고, 다음 세 가지로 피아노다운 느낌을 냅니다.

  1. 배음별 지수 감쇠: 피아노 줄은 친 순간이 가장 크고 점점 작아집니다. 높은 배음일수록 더 빨리 사라지게 해서, 처음에는 밝고 시간이 지나면 둥글어지는 소리를 만듭니다.
  2. 약한 비조화성: 실제 피아노 줄은 딱딱해서 배음이 정확한 정수배보다 조금씩 높습니다. 이 미세한 어긋남을 넣으면 전자음 같은 느낌이 줄어듭니다.
  3. 짧은 어택과 릴리스: 소리가 0에서 순간적으로 켜지거나 꺼지면 “틱” 하는 잡음이 납니다. 수 밀리초의 짧은 경사를 넣어 이를 없앴습니다.

여러 음을 동시에 칠 때 음량이 넘치지 않도록 마지막 단계에 컴프레서를 둡니다. “부드러운 음색” 옵션은 높은 배음의 비중을 줄인 버전입니다.

소리와 화면을 맞추는 스케줄러

자바스크립트 타이머(setTimeout)는 정확하지 않습니다. 탭이 바쁘면 수십 밀리초씩 밀립니다. 그래서 재생은 Web Audio의 오디오 시계(currentTime)를 기준으로 하고, 약 120ms 앞을 내다보며 곧 연주할 음을 미리 예약합니다. 화면의 음표 강조와 피아노 롤은 같은 오디오 시계를 읽어서 그립니다. 탭이 숨겨지면 재생을 멈추는데, 백그라운드 탭에서는 타이머가 크게 느려져 박자가 어긋나기 때문입니다.

정리

악보는 서버가 아니라 이 브라우저에만 저장됩니다. Songnote의 곡 라이브러리에서 예제를 열고 한 글자씩 고쳐 보세요.