블로그 목록
Fundamentals15분 읽기

소리는 어떻게 숫자가 되는가 — PCM, MP3 압축, 스피커 재생까지

마이크가 공기 진동을 전기로 바꾸는 원리, ADC의 샘플링과 양자화, PCM 원본 데이터, MP3 심리음향 압축(주파수/시간 마스킹), 디코딩과 DAC, 스피커가 숫자를 소리로 바꾸는 전체 과정.

PCMMP3ADCDAC오디오기초

소리는 공기의 진동입니다. 마이크는 이 진동을 전기 신호로 바꾸고, 컴퓨터는 전기 신호를 숫자로 바꿉니다. 이 숫자 나열이 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이지만 체감 품질은 거의 같음

© 2026 Frank Kim. All rights reserved.