평균율

Featured image

신디사이저를 만들겠다고 하면 oscillator의 주파수를 결정해주어야 하는데 대부분의 악기가 평균율에 맞춰져있으니까 이 주파수 값을 테이블로 가지고 있어야 한다. 그런데 막상 테이블을 보면 어떤 규칙으로 이게 결정된 것인가 궁금해할 수 밖에 없다.

신기하게도 한 옥타브는 12음계로 구성되어있고 주파수로 따지면 한 옥타브 높은 것은 기준 주파수 보다 2배 높은 것이고 한 옥타브 낮은 것은 1/2이 되는 것이라 linear가 아닌 exponential/log scale로 되어있구나 감이 오게 된다.

그러니까 한 음 (1 semitone)이 높다고 하는 것은 log scale로 봤을 때 다음 옥타브로 가는 것의 1/12이 되는 지점이 되는 것이다. 이게 뭔 소린가 싶을텐데..

\[2^{1/12} = 1.059463094359295\]

즉, 한음 높다고 하는 것은 기준 주파수 대비 1.059..배 높은 주파수라는 뜻이 된다. 그 다음 음은 그 음의 주파수에 다시 같은 수를 곱한 것과 같다.

그러니까 음의 높이는 더해지는 게 아니라 곱해지는 (그러니까 지수 단위에서 linear한 경향을 보이는) 그런 성질이 있다는 것이다.

평균율이란 것은 지수의 영역에서 모든 구간이 균일하게 (1/12) 나눠져있다는 뜻이다. 평균적으로…가 아니라 equally distributed in log-scale 이란 말이다.

여기서 샛길로 빠져보자면, 예를 들어 어떤 오디오 파일 데이터가 있다고 할 때 이것을 악보 혹은 미디파일의 형태로 변환을 시켜보고 싶다고 하자면 가장 쉽게 생각할 수 있는 것이 FFT로 오디오 신호를 관찰하는 것이다.

어떤 오디오 데이터를 FFT로 관찰하겠다고 하면 그 결과를 어떤 log scale로 분할해서 관찰해야 그 음이 어떤 음인지 이해할 수 있게 된다. 즉, 낮은 음의 영역에선 주파수 간격이 매우 촘촘하게 나눠지게 되고 높은 음으로 갈 수록 음과 음 간격이 점점 넓어지게 된다. FFT는 주파수 간격이 linear frequency scale로 되어있으니까 말이다.

아예 쓸데없는 주파수 구간을 관찰할 이유가 없으니까 log scale의 fourier transform을 하는 것이 오히려 더 바람직할텐데, 이렇게 하면 계산과정을 단순화시킬 수 없으니 FFT처럼 연산을 빠르게 수행할 수가 없다. 어쩔 수 없이 FFT의 point를 저음역을 관찰하는 최소의 resolution으로 잡아서 봐야 한다.

물론 전체적인 point수를 낮춰야 하니까 오디오 신호를 일반적인 음역에 맞춰서 decimation을 해야할 수 밖엔 없겠지만.

흔히 우리가 아는 주파수 값이란게 A4 = 440 Hz라고 하는 것이니까 이를테면 A0부터 관찰하겠다 하면 27.5Hz부터 관찰하게 되는 것이니까 이때 frequency bin간의 격차는 대략 29.1 Hz가 되는 것이다. 그보다 아래음으로 내려가면 FFT로 관찰하기 부담스러워지게 되는 것이고.

또 A8까지 관찰하겠다고 하면 16 x 440 Hz가 되니까 7040 Hz까지 봐야 한다. 앞의 계산한 소위 최소 구간으로 나눠서 보자면 대충 241 point가 된다. 대충 256 point FFT로 관찰한다고 하면 제법 decimation을 해서 7.45kHz 정도로 떨어뜨리고 뭐 등등..이런식으로 하게 될텐데 숫자에서 보는 것과 같이 생각보다 분해능이 별로 좋지 않고 요새 컴퓨터로 256 FFT를 돌리는 것은 일도 아니니까 실제로는 이렇게 관찰하진 않을 것이다. 왜? 이미 얘기했다시피 평균율의 음간격은 linear scale의 FFT에 맞아떨어지지 않기 때문이다.

오히려 높은 분해능으로 관찰하고 나중에 사용자의 필요에 의해서 quantization을 하는 식으로 가는 게 맞을 것이라고 본다. (이게 수많은 auto tune들이 하는 일이라고 본다만)

사실 간단한 게 좋은 거라고 어차피 높은 주파수를 들여다본다 하더라도 음색을 결정하는 하모닉만 잔뜩 있게 될 것이고 낮은 주파수를 들여다본다고 하면 뭔가 타악기스러운 부분만 나타나게 될 것이니까 말이다.

여기서 특별히 음이 있는지 없는지를 확인하려면 소위 detection theory를 적용해야 한다. threshold testing을 해야 되는 것이다. 그러려면 입력도 적당한 진폭이 되도록 automatic gain control도 해야 하고 긴 시간동안 계속 관찰하면서 그 기록을 남겨야되고 한정된 구간의 신호만을 가져다가 관찰하게 되니까 ringing도 막아줘야 하니까 windowing도 해야 한다.

과정을 정리해보자면..

1) sample rate control 2) automatic level control 3) windowing 4) FFT 5) calculating power spectrum (spectrogram) 6) threshold testing

여기서 빼놓을 수 없는 것이 전체적인 음악을 분석해서 tempo를 결정하는 것이다. 이것은 다른 툴을 이용하면 되니까.

대충 이게 인식이 잘 된다고 하면 단순히 분절된 음만 찾아내는 게 아니라 wheel 값까지 계산해서 midi로 제법 정확하게 떠낼 수도 있다고 본다 (그게 melodyne이 하는 일이지 싶다만). 실제로 melodyne을 돌려보면 생각보다 원하는 결과가 잘 나오진 않았다. 뭐니뭐니해도 음의 어택이 강한 악기들 (이를테면 타악기) 혹은 저음의 악기들의 하모닉 등등이 끼어들어서 순수한 note외의 것들이 마구마구 검출되는 결과가 나왔다.