오디오 기초
Sound
소리 또는 음 또는 ‘음파’는 공기나 물 같은 매질의 진동을 통해 전달되는 종파 or 파동(Wave)
자연에서의 신호는 자연스러운 곡선을 그리고 컴퓨터에서 받아들이는 신호는 1과 0으로 극단적인 딱딱한 모양으로 그리기 때문에 이 차이를 컴퓨터는 이해, 표현하기 위해 아날로그 신호를 샘플링을 통해 단위 시간 당 샘플의 개수로 쪼갠다
※ Sampling Rate는 이산적인 신호를 만들기 위해 연속적 신호에서 얻어진 단위시간(1초)당 샘플링 횟수를 정의한다.
아날로그에서 디지털로 변환하는 A/D Converter는 **표본화 → 양자화 → 부호화** 과정을 거친다.
**- 표본화**
연속된 신호를 이산 신호로 변환, 나이키스트 정리에 따르면
표본화 시 원음을 그대로 반영하기 위해서는 원음이 가지고 있는
주파수의 2배 이상을 표본화 해야한다.
※ 인간의 가청 주파수는 20 Hz ~ 20,000 Hz에 이른다.
즉 가청 주파수의 최대값인 20,000 Hz의 아날로그 원음을 표본화 할 경우
최소한 2배인 40,000 Hz 이상의 개수로 샘플링 해야 한다는 뜻이다.
**- 양자화**
표본화된 각 점의 진폭을 얼마 만큼의 정밀도로 표현 할 것 인가에 대한 정의.
bit 단위로 진폭을 이산 값으로 쪼개는 것이다.
Audio의 CD를 예로 들 경우 16bit를 적용하게 되는데
이를 계산하면 2의 16승으로 65,535개의 정보로 나타낼 수 있다.
당연하게도 bit수가 클 수록 데이터의 크기는 커지게 된다.
**- 부호화**
표본화와 양자화된 데이터를 **코드화**하고 압축 (01010011)
자연 에서의 신호 : Analog Signal
컴퓨터 에서의 신호 : Digital Signal ( 0 or 1 )
3 elements of Wave
- Frequency (주파수) : 주기적인 현상이 단위 시간 동안 몇 번 반복했는지를 뜻함
- Amplitude (진폭) : 주기적으로 진동하는 파의 진동 폭
- Phase (위상) : 반복되는 파형의 한 주기에서 첫 시작점의 각도 혹은 어느 한 순간의 위치
- ※번외 - Period (주기) : 1 cycle의 시간
- 주기에서 주파수를 계산 : frequency = 1 / Period(Time)
- 5 Hz = 1 / 0.2s
- ※번외 - wavelength (파장) : 1 cycle의 길이
- 파동에서 주파수를 계산 : lambda:λ(m) = 파동의 속도(m/s) / 주파수 진동수(Hz)
- 66.4 m = 332m/s / 5hz
http://www.schezade.co.kr/board/guide/board_view.html?no=37&page=6&no_list=
Sine wave OR Sinuoid
사인 곡선의 모양을 유지하면서 일정한 속도로 진행하는 파
Sine wave 공식
Generate Numpy Sine wave
import numpy as np
import matplotlib.pyplot as plt
f = 1 # frequency : 1초 마다 발생하는 진동 수
fs = 20 # sample_rate : 단위시간 당 샘플링 횟수
A = 1 # amplitude : 위상
t = np.linspace(0, 1, fs)
p = 0 # phase
y = A * np.sin(2 * np.pi * f * t + p)
plt.plot(t, x)
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('sample_rate 20')
plt.show()
- 20개의 값으로 샘플링 된 파동의 모습
- 20개의 값으로 샘플링 된 값의 위치
Sample_rate 개수에 따른 곡선 모양 변화도
샘플링된 값이 많아질 수록 곡선의 모양이 점점 부드러워 짐을 확인 가능합니다
※ 단위 시간 당 샘플링의 개수를 잘게 쪼갤수록 정보 손실이 줄어들어 위와 같이 부드러운 곡선을 보이지만 그 만큼의 데이터의 크기가 늘어남
Complex Wave
하나의 정현파가 아닌 두 가지 이상의 진폭, 주파수, 위상이 다른 정현파가 복합된 형태의 파형을 의미
※ 대부분은 소리는 정현파가 아닌 훨씬 복잡한 형태를 가진 복합파이며 복합파 안에서 일정 주기로 같은 모양으로 파동이 반복이 된다면 “주기파”이고 정현파가 합쳐져서 형성된 파형 이라는 것을 알 수 있다.
- 440 hz, 261 hz 에 대한 정현파 생성 예시는 그 중 0.006초 동안의 파형을 나타낸다
import numpy as np
import matplotlib.pyplot as plt
f = 440 # frequency
fs = 16000 # sample_rate
A = 1 # amplitude
t = np.linspace(0, 1, fs)
p = 0 # phase
x = A * np.sin(f * 2 * np.pi * t + p)
plt.plot(t[:100], x[:100])
plt.title('frequency 440')
plt.show()
f = 261 # frequency
fs = 16000 # sample_rate
A = 1 # amplitude
t = np.linspace(0, 1, fs)
p = 0 # phase
x2 = A * np.sin(f * 2 * np.pi * t + p)
plt.plot(t[:100], x2[:100])
plt.title('freequency 261')
plt.show()
- 440 hz + 261 hz = 복합파 생성
complex_wave = x + x2
plt.figure(figsize=(14,8))
plt.plot(t[:500], complex_wave[:500])
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.title('complex wave')
plt.show()
푸리에 변환 : Fourier Transform
모든 함수를 삼각함수의 합으로 나타내는 것.
시간이나 공간에 대한 함수를 시간 또는 공간 주파수 성분으로 분해하는 변환을 말한다.
푸리에 변환 공식
https://ko.wikipedia.org/wiki/푸리에_변환
위 GIF를 보면 실제 파동들은 서로 다른 사인파의 합계라는 푸리에 변환의 아이디어를 보여준다.
컴퓨터에서는 이산 값만 처리가 가능하기 때문에 DFT(Discrete Fourier Transform)을 한다.
- N = 샘플 수
- n = 현재 샘플
- k = 현재 주파수
- xn = 샘플 n에서의 사인 값
- Xk = 진폭과 위상의 정보를 모두 포함하는 DFT
위 방정식의 마지막 표현식은 삼각함수를 복소 지수 함수에 연결하는 오일러 공식에서 파생되었다.
https://ko.wikipedia.org/wiki/위상#:~:text=위상(phase%2C 位相)은,순간의 위치를 말한다.
https://ko.wikipedia.org/wiki/진동수
https://ko.wikipedia.org/wiki/소리
https://ko.wikipedia.org/wiki/샘플링_속도#:~:text=샘플링 레이트(영어%3A sampling rate,%2C s−1)이다.
https://www.kjorl.org/journal/view.php?number=2333
https://suyeon96.tistory.com/12?category=403292
https://lucaseo.github.io/posts/2020-06-07-dsp-basic-s01-8/
- ratsgo 참고
https://ratsgo.github.io/speechbook/
- 이수안컴퓨터연구소 오디오 음성 처리 시리즈
https://www.youtube.com/watch?v=oltGIc4uo5c&list=PL7ZVZgsnLwEGskuPmm2-pYsNKY8Ihs5AP