다운로드
작성자: admin 작성일시: 2018-11-22 21:16:40 조회수: 227 다운로드: 32
카테고리: 기타 태그목록:

사운드 프로세싱 기초

소리는 공기를 구성하는 입자들이 진동하는 현상이다. 공기의 진동을 측정하는 양적 기준을 음압(sound pressure)라고 한다. 사운드 데이터란 이 음압의 변화를 기록한 시계열 데이터이다.

사인 함수

음압의 변화를 나타내는 시계열 데이터 중 가장 단순한 형태가 사인 함수(sine function)이다. 우선 사인 함수에 대해 알아보자. 삼각 함수 중 하나인 사인 함수(sine function)는 다음과 같은 3가지 특징을 가진다.

  • 진폭(amplitude) $A$: 위 아래로 움직이는 폭
  • 주파수(frequency) $\omega$ 또는 $2\pi$: 진동 속도. 주파수가 높으면 빠르게 진동한다.
  • 위상(phase) $\phi$: 사인 함수의 시작 시점. 위상 만큼 출발이 늦어진다.

사인 함수를 수식으로 표현하면 다음과 같다. 여기에서 $t$는 시간을 나타내며 보통은 초(second) 단위이다.

$$ A \sin\left(\omega t - \phi \right) \;\;\; \text{또는} \;\;\; A \sin\left(2\pi f t - \phi \right) $$

주파수(frequency)는 초당 진동의 횟수를 나타낸다. 1회전의 각도가 $2\pi$ 라디안(radian)이므로 보통은 초당 라디안(radian4 per second) 단위로 표시하지만 이 값을 $2\pi$로 나누어 헤르쯔(Hz)라는 단위로 표시할 수도 있다. 1 Hz는 1초에 한 번 진동하는 주파수이다. 위 식에서 $\omega$는 초당 라디안 단위의 주파수이고 $f$는 헤르쯔 단위의 주파수이다.

$$ \omega = 2\pi f $$

다음은 여러가지 사인 함수를 보여주는 코드이다. 이 코드에서 A는 진폭, w는 주파수 p는 위상을 나타낸다.

In [1]:
t = np.linspace(0, 1, 100)

plt.plot(t, 1 * np.sin(2 * np.pi * t + 0), ls="-", label=r"$\sin\left(2\pi{t}\right)$ 주파수 1Hz. 진폭 1, 위상 0")
plt.plot(t, 2 * np.sin(2 * np.pi * t + 0), ls="--", label=r"$2\sin\left(2\pi{t}\right)$ 진폭이 2로 커진 경우 ")
plt.plot(t, 1 * np.sin(3 * np.pi * t + 0), ls=":", label=r"$\sin\left(3\pi{t}\right)$ 주파수가 1.5Hz로 커진 경우")
plt.plot(t, 1 * np.sin(2 * np.pi * t - 0.3), ls="-.", label=r"$\sin\left(2\pi{t} - 0.3\right)$ 위상이 늦춰진 경우")
plt.ylim(-2.2, 3)
plt.xticks(np.linspace(0, 1, 5))
plt.legend()
plt.title(r"$A\sin\left(\omega{t}+\phi\right)$")
plt.show()

코사인 함수는 사인 함수와 위상만 90도 즉, $\frac{\pi}{2}$ 차이가 있으므로 사인 함수의 일종으로 볼 수 있다.

$$ \cos(2\pi t) = \sin \left( 2\pi t - \frac{\pi}{2} \right) $$

주기와 주파수의 관계

주파수 $\omega$의 역수를 주기 $T$라고 한다. 주기는 1번의 진동에 필요한 시간을 뜻한다.

$$ \omega = \dfrac{2\pi}{T} $$

따라서 사인 함수는 다음처럼 쓸 수도 있다.

$$ A \sin\left(\dfrac{2\pi}{T} t - \phi \right) $$

싱글 톤

주파수는 사람에게 음의 높이(tone)로 인식된다. 사인파처럼 주파수가 일정한 음압 시계열은 사람에게 음높이가 일정한 "삐-"하는 기계음으로 들리기 때문에 하나의 사인파로 이루어진 소리를 싱글 톤(single tone)이라고도 한다. 전화를 걸 때 수신자가 전화를 받기 전까지 재생되는 통화연결음(ring tone)은 보통 400Hz~450Hz의 싱글 톤을 사용한다.

In [2]:
def single_tone(frequecy, rate=44100, duration=1):
    t = np.linspace(0, duration, int(rate))
    y = np.sin(2 * np.pi * frequecy * t)
    return y

y = single_tone(400)

주피터 노트북에서는 다음 코드로 사운드 데이터를 표시할 수 있다.

In [3]:
from IPython.display import Audio, display
display(Audio(y, rate=44100))

음계에서 사용되는 가온다(middle C)음은 261.62Hz의 싱글 톤이다. 반음(semitone, half tone, half step)이 올라갈 때마다 $2^{\frac{1}{12}}$배만큼 주파수가 높아지고 12반음 즉, 1옥타브(octave)가 올라가면 주파수는 2배가 된다. 다음 코드는 가온다로부터 한 옥타브의 음에 대해 계산한 주파수이다.

In [4]:
notes = 'C,C#,D,D#,E,F,F#,G,G#,A,A#,B,C'.split(',')
freqs = 220. * 2**(np.arange(3, 3 + len(notes)) / 12.)
notes = list(zip(notes, freqs))
notes
Out:
[('C', 261.6255653005986),
 ('C#', 277.1826309768721),
 ('D', 293.6647679174076),
 ('D#', 311.1269837220809),
 ('E', 329.6275569128699),
 ('F', 349.2282314330039),
 ('F#', 369.9944227116344),
 ('G', 391.99543598174927),
 ('G#', 415.3046975799451),
 ('A', 440.0),
 ('A#', 466.1637615180899),
 ('B', 493.8833012561241),
 ('C', 523.2511306011972)]
In [5]:
octave = np.hstack([single_tone(f) for f in freqs])
display(Audio(octave, rate=44100))