소리는 공기의 진동입니다. 마이크는 이 진동을 전기 신호로 바꾸고, 컴퓨터는 전기 신호를 숫자로 바꿉니다. 이 숫자 나열이 PCM이고, MP3는 PCM에서 사람 귀가 못 듣는 부분을 잘라내 용량을 1/10로 줄인 것입니다. 소리가 숫자가 되는 전체 과정을 처음부터 정리합니다.
소리란 — 공기의 진동
스피커/성대가 공기를 밀고 당기면
공기 분자가 물결처럼 퍼져나감
압력
+1 ─╮ ╭─╮ ╭─
│ │ │ │
0 ──┼──╯──┼──╯──── 시간
│ │
-1 ─╯ ╰─
이 파형이 고막을 진동시키면 → 뇌가 "소리"로 인식
높은 소리 = 진동이 빠름 (주파수 높음, Hz 큼)
큰 소리 = 진동이 큼 (진폭 큼)
사람이 들을 수 있는 범위: 20Hz ~ 20,000Hz
20Hz = 매우 낮은 웅웅 소리 (거의 못 느낌)
440Hz = 피아노 '라' (A4)
4,000Hz = 전화 벨소리 영역
20,000Hz = 극고음 (나이 들면 못 들음)
20,000Hz 위 = 초음파 → 사람은 절대 못 들음
마이크 — 진동을 전기 신호로
어떻게?
마이크 안에는 **얇은 막(다이어프램)**이 있습니다. 공기 진동이 이 막을 흔들면 전기가 발생합니다.
공기 진동 → 다이어프램 흔들림 → 전기 신호 발생
공기 압력 다이어프램 전기 신호(전압)
+1 ─╮ ↕ 흔들림 +0.5V ─╮
│ │
0 ──┼── ── 정지 ── 0V ──┼──
│ │
-1 ─╯ ↕ 반대로 -0.5V ─╯
공기가 밀면 → 막이 안으로 → +전압
공기가 당기면 → 막이 밖으로 → -전압
진동 패턴 그대로 전압 패턴으로 복사됨
왜 전기 신호로 바꾸나?
공기 진동은:
- 멀리 못 감 (수 미터면 사라짐)
- 저장 못 함 (흘러가면 끝)
- 복사 못 함
전기 신호는:
- 케이블로 수 킬로미터 전달 가능
- 저장 가능 (테이프, 디지털)
- 복사 무한 가능
- 증폭 가능 (앰프)
하지만 아직 "아날로그" — 연속적인 전압 변화
컴퓨터는 연속 값을 다룰 수 없음 → 디지털 변환 필요
ADC — 아날로그를 디지털(숫자)로
ADC (Analog-to-Digital Converter) 가 전기 신호를 숫자로 바꿉니다. 두 단계로 이루어집니다.
1단계: 샘플링 (Sampling) — "얼마나 자주 찍을까?"
연속적인 파형을 일정 간격으로 측정합니다.
아날로그 파형 (연속):
╭─╮
╱ ╲ ╭─╮
───╱─────╲───╱───╲──── 시간
╲ ╱
╰─╯
샘플링 (이산적으로 찍기):
●
● ●
● ●
●
●
↑ ↑ ↑ ↑ ↑ ↑ ↑ ← 일정 간격으로 전압을 측정
t0 t1 t2 t3 t4 t5 t6
각 시점의 전압 값을 하나씩 기록
샘플레이트 (Sample Rate)
1초에 몇 번 찍느냐 = 샘플레이트
8,000Hz = 전화 품질 (1초에 8천번 측정)
44,100Hz = CD 품질 (1초에 44,100번 측정) ← 가장 보편적
48,000Hz = 영상/방송 표준
96,000Hz = 고음질 스튜디오
왜 44,100Hz인가?
→ 나이퀘스트 정리(Nyquist Theorem):
원본을 완벽 복원하려면 최대 주파수의 2배로 샘플링해야 함
사람 귀 한계 = 20,000Hz
20,000 × 2 = 40,000Hz 이상 필요
여유를 두고 44,100Hz로 결정 (1980년대 CD 규격)
왜 2배여야 하나? (직관적 이해)
1000Hz 소리 = 1초에 1000번 진동
초당 1번만 찍으면 (1Hz 샘플링):
● ← 파형이 뭔지 전혀 모름
─────────────────── 시간
초당 1000번 찍으면 (1000Hz 샘플링):
● ● ● ● ● ● ● ● ← 꼭대기만 찍힘, 올라가는지 내려가는지 모름
초당 2000번 찍으면 (2000Hz 샘플링):
● ● ● ●
● ● ● ● ← 꼭대기와 골짜기 모두 포착 → 원본 복원 가능!
진동 1주기를 표현하려면 최소 2개 포인트 필요
→ 최소 2배 속도로 샘플링해야 파형을 살릴 수 있음
2단계: 양자화 (Quantization) — "얼마나 정밀하게 기록할까?"
측정한 전압을 정해진 단계의 정수로 반올림합니다.
실제 전압: 0.7823V
4비트 양자화 (16단계):
0.7823 → 가장 가까운 단계 12 → 기록: 12
정밀도 낮음, 원본과 차이 큼
8비트 양자화 (256단계):
0.7823 → 가장 가까운 단계 200 → 기록: 200
좀 더 정밀
16비트 양자화 (65,536단계): ← CD 표준
0.7823 → 가장 가까운 단계 51,234 → 기록: 51234
사람 귀로 원본과 구분 불가능!
비트 깊이 (Bit Depth)
8비트 = 256단계 → 전화 품질 (잡음 들림)
16비트 = 65,536단계 → CD 품질 (충분히 깨끗) ← 표준
24비트 = 16,777,216단계 → 스튜디오 (매우 조용한 곳에서 차이)
비트 수가 높을수록:
- 작은 소리도 정밀하게 기록 가능
- 잡음(양자화 오차)이 줄어듦
- 파일 크기가 커짐
PCM — 디지털 오디오의 원본
PCM (Pulse Code Modulation) = 샘플링 + 양자화의 결과물. 가공 없는 원본 오디오 데이터입니다.
"안녕하세요" 3초를 CD 품질로 녹음하면:
샘플레이트: 44,100Hz (초당 44,100개 숫자)
비트 깊이: 16비트 (각 숫자가 -32768 ~ +32767)
채널: 스테레오 (2채널)
숫자 개수 = 44,100 × 3초 × 2채널 = 264,600개
각 숫자가 2바이트(16비트)이므로:
264,600 × 2바이트 = 529,200바이트 ≈ 529KB
PCM 데이터가 실제로 어떻게 생겼나
시간순으로 나열된 정수들:
시간(ms) 왼쪽채널 오른쪽채널
0.000 0 0 ← 조용
0.023 1024 980 ← 소리 시작
0.045 3200 3150
0.068 8192 8100
0.091 16384 16200 ← 점점 커짐
0.113 32767 32500 ← 최대 음량!
0.136 28000 27800 ← 줄어듦
0.159 16384 16200
...
이 숫자를 초당 44,100개씩 스피커에 보내면
스피커가 그 패턴대로 진동 → 원래 소리 재현
양수 = 스피커 앞으로 밀기
음수 = 스피커 뒤로 당기기
0 = 정지 (무음)
PCM의 문제 — 너무 크다
3분짜리 노래 (CD 품질):
44,100 × 180초 × 2채널 × 2바이트 = 31,752,000바이트 ≈ 30MB
앨범 10곡이면 300MB
스트리밍으로 보내려면 대역폭 부담
→ 압축이 필요 → MP3, AAC, OGG 등 등장
MP3 압축 — 어떻게 1/10로 줄이나?
핵심 원리: 사람 귀의 한계를 이용
MP3는 심리음향학(Psychoacoustics) 을 기반으로 합니다. 사람 귀가 못 듣거나 안 듣는 소리를 찾아서 버립니다.
기법 1: 주파수 마스킹 (Frequency Masking)
큰 소리 옆의 작은 소리는 안 들림
주파수 →
볼륨
▲
│ ╭──╮
│ ╱ ╲ ← 1000Hz에서 큰 소리
│ ╱ ╲
│ ╱ ████ ╲ ← 마스킹 영역 (이 안의 소리는 안 들림)
│ ╱ ████ ╲
│╱ ████ ╲
└──────────────── 주파수(Hz)
800 1000 1200
1000Hz에서 큰 드럼 소리가 나면
900Hz~1100Hz 사이의 작은 소리는 들리지 않음
→ 작은 소리 데이터를 버려도 사람은 모름!
실제 예시:
콘서트에서 드럼이 쿵 치는 순간
옆 사람 기침 소리가 안 들리는 것과 같음
기법 2: 시간 마스킹 (Temporal Masking)
큰 소리 직후에는 작은 소리가 안 들림
볼륨
▲
│ ╭─╮
│ │ │
│ │ │ ████ ← 큰 소리 직후 수ms간 작은 소리 안 들림
│ │ │ ████
└──┴─┴────── 시간
심벌즈 "쨍!" 직후 0.005초간은
다른 작은 소리를 넣어도 안 들림
→ 이 구간의 데이터도 버릴 수 있음
기법 3: 절대 청각 한계 (Absolute Threshold)
주파수별로 사람이 들을 수 있는 최소 볼륨이 다름
볼륨
(dB)
80 ─╮ ╭─ ← 20Hz, 18000Hz는
60 ─│ │ 매우 커야 들림
40 ─│ │
20 ─╰──╮ ╭──╯
0 ────╰───────────────────╯─────── ← 2000~5000Hz가 가장 잘 들림
20 100 1k 4k 10k 20kHz
20Hz 근처: 80dB 이상이어야 들림
4000Hz 근처: 0dB(아주 작은 소리)도 들림
18000Hz 이상: 대부분 사람이 못 들음
→ 각 주파수별로 "이 볼륨 이하는 어차피 못 들음" 기준선 아래를 다 버림
MP3 인코딩 과정 요약
PCM 원본 (30MB)
↓
1. 시간 → 주파수 변환 (MDCT)
파형 숫자들을 주파수별 성분으로 분해
"이 26ms 구간에 500Hz가 크고, 3000Hz가 작다"
↓
2. 심리음향 모델 적용
- 주파수 마스킹: 큰 소리 옆 작은 소리 → 버림
- 시간 마스킹: 큰 소리 직후 작은 소리 → 버림
- 청각 한계: 못 듣는 주파수 → 버림
↓
3. 양자화 + 허프만 코딩
남은 데이터를 더 적은 비트로 표현
자주 나오는 패턴에 짧은 코드 배정
↓
MP3 파일 (3MB) ← 1/10 크기!
비트레이트와 품질
비트레이트 = 1초에 몇 비트를 쓸 건가
128kbps: 초당 16KB 사용 → 많이 버림 → 보통 품질
192kbps: 초당 24KB 사용 → 적당히 버림 → 좋은 품질
320kbps: 초당 40KB 사용 → 거의 안 버림 → CD에 가까움
비트레이트가 높을수록:
버리는 소리가 적음 → 원본에 가까움 → 파일이 커짐
Google TTS의 경우:
음성(사람 목소리)은 주파수 범위가 좁아서 (300~3400Hz)
128kbps면 충분히 깨끗함
MP3 디코딩 — 압축된 데이터를 다시 소리로
녹음(인코딩)의 정반대 과정입니다. MP3 파일 안의 압축 데이터를 원래 파형 숫자(PCM)로 복원하고, 그 숫자를 전기 신호로 바꿔 스피커를 흔듭니다.
1단계: MP3 → PCM (디코더)
MP3 프레임 1개 (압축된 ~400바이트)
↓ 허프만 디코딩
짧은 코드를 원래 숫자로 복원
(ZIP 해제와 비슷)
↓ 역양자화 (Dequantization)
거칠게 표현된 숫자를 원래 스케일로 복원
↓ 역MDCT (Inverse MDCT)
주파수 성분 → 시간 순서 파형으로 변환
"500Hz가 크고 3000Hz가 작다"
→ [0, 1024, 3200, 8192, ...] 시간순 숫자로
↓
PCM 샘플 1152개 (26ms 분량의 파형 숫자)
[0, 1024, 3200, 8192, 16384, 32767, 28000, ...]
인코딩 때 버린 소리는?
인코딩 때:
원본 PCM → 안 들리는 소리 제거 → 남은 것만 압축 → MP3
디코딩 때:
MP3 → 압축 해제 → PCM 복원
↑
버린 소리는 돌아오지 않음!
그래서 MP3는 "손실 압축" (lossy compression)
ZIP은 "무손실 압축" (lossless) — 원본 100% 복원
하지만 버린 건 "사람이 못 듣는 소리"이므로
귀로 들으면 원본과 거의 차이 없음
2단계: PCM → 전기 신호 (DAC)
DAC (Digital-to-Analog Converter) 가 숫자를 전압으로 바꿉니다. ADC의 정반대입니다.
PCM 숫자: 0 16384 32767 16384 0 -16384 -32767
↓ ↓ ↓ ↓ ↓ ↓ ↓
DAC 출력: 0V +0.5V +1.0V +0.5V 0V -0.5V -1.0V
숫자 하나하나를 전압으로 변환
초당 44,100번 출력 → 계단 모양 전압
전압
+1V ─ ●
+0.5V ─ ● ●
0V ── ● ● ← 계단 모양 (이산적)
-0.5V ─ ●
-1V ─ ●
↓ 저역통과 필터 (Low-pass filter)
전압
+1V ─ ╭─╮
+0.5V ─ ╱ ╲
0V ── ╱ ╲ ← 부드러운 곡선 (연속적)
-0.5V ─ ╲
-1V ─ ╰─
계단을 부드럽게 이어주는 것이 저역통과 필터
→ 원래의 아날로그 파형이 복원됨!
DAC는 어디에 있나?
스마트폰: 칩셋 안에 내장 DAC
노트북: 사운드카드(오디오 칩) 안에
이어폰 잭: DAC → 앰프 → 이어폰 순서
USB-C 이어폰: 이어폰 안에 DAC 내장
블루투스: 이어폰 안에서 디코딩 + DAC 처리
Lightning/USB-C로 바뀌면서
폰에서 DAC를 빼고 이어폰에 넣는 추세
→ 3.5mm 잭 사라진 이유 중 하나
3단계: 전기 신호 → 소리 (스피커)
스피커 구조:
자석 (고정)
┌─────────┐
│ N S │
│ ┌───┐ │
│ │코일│ ← 전기 신호가 흐르는 코일
│ └─┬─┘ │
└────┼────┘
│
┌────┴────┐
│ 진동판 │ ← 코일에 붙어서 같이 움직임
│(콘/다이어│
│ 프램) │
└─────────┘
↓
공기 진동 → 소리!
전기 +전압 → 코일 자기장 → 콘이 앞으로
전기 -전압 → 반대 자기장 → 콘이 뒤로
전기 0V → 자기장 없음 → 콘이 정지
PCM 숫자 +32767 → +1V → 콘이 최대한 앞으로 → 공기 최대 압축
PCM 숫자 -32767 → -1V → 콘이 최대한 뒤로 → 공기 최대 팽창
PCM 숫자 0 → 0V → 콘 정지 → 무음
이 과정이 초당 44,100번 반복되면
공기가 원래 소리와 같은 패턴으로 진동
→ 고막이 진동 → 뇌가 "소리"로 인식!
브라우저에서 이 과정이 일어나는 순서
new Audio(url).play() 호출하면:
1. 네트워크: MP3 바이너리 다운로드
ff f3 10 c4 00 1c ...
2. Demuxer: 프레임 파싱
ff f3 → "MP3 프레임이다!"
헤더에서 비트레이트(128kbps), 샘플레이트(44100Hz) 추출
3. Decoder: MP3 → PCM 복원
허프만 디코딩 → 역양자화 → 역MDCT
프레임당 1152개 PCM 샘플 생성
4. Audio Context: PCM 버퍼링
디코딩된 PCM을 링 버퍼에 쌓음
재생 위치 추적, 볼륨/이퀄라이저 처리
5. OS Audio API: PCM → 사운드 드라이버
브라우저 → OS(CoreAudio/ALSA/WASAPI)
→ 사운드카드 DAC → 아날로그 전기 신호
6. 하드웨어: 전기 → 소리
DAC → 앰프(증폭) → 스피커/이어폰 → 공기 진동 → 🔊
데이터 포맷 비교 — 각 단계에서 데이터가 어떻게 생겼나
같은 "안녕하세요" 3초를 각 단계별로 비교합니다.
┌──────────────────────────────────────────────────────────────┐
│ 단계 │ 포맷 │ 크기 │ 데이터 모습 │
├──────────────────────────────────────────────────────────────┤
│ 공기 진동 │ 아날로그 │ - │ 연속적 압력 변화 │
│ 마이크 출력 │ 아날로그 전압│ - │ -0.5V ~ +0.5V │
│ PCM (원본) │ 정수 배열 │ 529KB │ [0, 1024, 3200..]│
│ WAV 파일 │ PCM+헤더 │ 529KB+44B │ RIFF....WAVEfmt. │
│ MP3 (압축) │ 프레임 연속 │ ~48KB │ ff f3 10 c4 ... │
│ base64 │ ASCII 문자열 │ ~64KB │ //NExAARi3AC... │
│ JSON 응답 │ UTF-8 텍스트 │ ~64KB+α │ {"audioContent":"│
│ Buffer (메모리)│ 바이트 배열 │ ~48KB │ <Buffer ff f3..> │
│ PCM (복원) │ Float32 배열 │ 529KB │ [0.0, 0.031, ..] │
│ DAC 출력 │ 아날로그 전압│ - │ 연속적 전압 변화 │
│ 스피커 │ 공기 진동 │ - │ 소리! │
└──────────────────────────────────────────────────────────────┘
왜 단계마다 포맷이 다른가?
각 단계의 "소비자"가 다르기 때문:
PCM (정수 배열)
→ 오디오 편집 소프트웨어가 직접 처리하기 좋은 형태
→ 더하기/곱하기로 믹싱, 볼륨 조절 가능
→ 단점: 너무 큼
MP3 (압축 바이너리)
→ 저장/전송에 최적화 (1/10 크기)
→ 단점: 직접 재생 불가, 디코딩 필요
base64 (ASCII 문자열)
→ JSON/HTTP 텍스트 프로토콜에서 안전하게 전송
→ 단점: 33% 더 커짐
Buffer/Uint8Array (메모리 바이트)
→ 프로그램이 메모리에서 직접 다루는 형태
→ R2 업로드, 파일 저장, 네트워크 전송에 사용
Float32 PCM (복원된 파형)
→ Web Audio API가 사용하는 형태
→ 정수 PCM과 같지만 -1.0 ~ +1.0 소수로 정규화
→ 볼륨 계산이 편리 (0.5 곱하면 반으로)
결국 같은 소리를 각 단계의 목적에 맞게
표현 방식만 바꾸는 것
전체 여정 — 소리에서 숫자까지
🔊 소리 (공기 진동)
↓ 마이크 (다이어프램 → 전기)
⚡ 아날로그 신호 (연속적 전압 변화)
↓ ADC - 샘플링 (44,100번/초 측정)
↓ ADC - 양자화 (16비트 정수로 반올림)
🔢 PCM (원본 디지털 오디오) — 30MB/3분
↓ MP3 인코더 (심리음향 모델로 안 들리는 부분 제거)
📦 MP3 (압축 오디오) — 3MB/3분
↓ base64 인코딩 (바이너리 → 텍스트)
📝 base64 문자열 — JSON으로 전송 가능
↓ Buffer.from(_, 'base64')
📦 MP3 바이너리 복원
↓ 브라우저 Audio 디코더
🔢 PCM 복원 (압축 해제)
↓ DAC (디지털 → 아날로그)
⚡ 전기 신호
↓ 스피커 (전기 → 진동)
🔊 소리!
WAV vs MP3 vs AAC — 포맷 비교
WAV:
PCM 그대로 + 간단한 헤더
무손실, 파일 큼 (30MB/3분)
편집용, 원본 보관용
MP3:
심리음향 압축 (손실)
1/10 크기 (3MB/3분)
가장 보편적, 특허 만료됨
AAC:
MP3의 후속 (더 효율적 압축)
같은 품질에서 MP3보다 20% 작음
Apple Music, YouTube 사용
OGG Vorbis:
오픈소스 대안
MP3과 비슷한 품질/크기
Spotify 사용
정리
소리가 파일이 되는 과정:
1. 마이크: 공기 진동 → 전기 신호
- 다이어프램이 공기 압력을 전압으로 변환
- 진동 패턴이 전압 패턴으로 그대로 복사됨
2. ADC: 전기 신호 → 숫자 (PCM)
- 샘플링: 초당 44,100번 전압 측정 (Nyquist: 최대 주파수의 2배)
- 양자화: 측정값을 16비트 정수로 반올림 (65,536단계)
3. MP3 인코더: PCM → MP3 (1/10 크기)
- 주파수 마스킹: 큰 소리 옆 작은 소리 제거
- 시간 마스킹: 큰 소리 직후 작은 소리 제거
- 청각 한계: 못 듣는 주파수 제거
- 남은 데이터를 허프만 코딩으로 추가 압축
핵심 인사이트:
MP3는 "데이터"를 줄이는 게 아니라
"사람이 못 듣는 소리"를 줄이는 것
그래서 용량은 1/10이지만 체감 품질은 거의 같음