걸그룹 tripleS의 팬덤에 대한 내용은 WAV(tripleS) 문서 참고하십시오.
🎵 오디오 코덱 | |||
{{{#!wiki style="margin: 0 -10px -5px; min-height: 26px" {{{#!folding [ 펼치기 · 접기 ] {{{#!wiki style="margin: -6px -1.5px -13px" |
<colbgcolor=#555>
손실 압축 |
<colbgcolor=#555><colcolor=#fff>일반 | MP1 · MP2 · MP3 · mp3PRO · AAC · Musepack · WMA · Vorbis · Opus · USAC |
음성 특화 | AMR-NB · AMR-WB · AMR-WB+ · WMA Voice · Speex · Opus · Codec 2 · EVS · Lyra | ||
다중채널 특화 | AC-3 · SDDS · DTS · AC-4 | ||
블루투스 | SBC · aptX · AAC · LDAC · SSC( Samsung Seamless Codec · Samsung Scalable Codec) · LC3 | ||
무손실 압축 | FLAC · ALAC · APE · TAK · WMA Lossless · TTA · WavPack | ||
무손실 무압축 | PCM ( WAV · AIFF) | ||
관련 문서: MIDI · DSD | |||
관련 틀: 그래픽 · 오디오 · 비디오 |
1. 개요
WAVeform audio format웨이브폼 오디오 포맷(웨이브 오디오 포맷)의 준말. WAVE라고도 한다. 일부 프로그램에서는 한국어 번역 오류나, 이해를 돕기 위해 파형 오디오 포맷이라고 칭한다.
2. 상세
마이크로소프트 윈도우에서 표준적으로 사용되는 RIFF을 기반으로 한 컨테이너 이며 주로 PCM 데이터를 저장할 때 사용한다. 예를 들어 CD에 있는 여러 파일들을 어떠한 형태로도 압축을 하지 않고 하나의 파일로 만들었을 때에 해당하는 윈도우용 오디오 포맷의 규격이라고 보면 된다.FLAC 형식이 무손실 압축 포맷이라면, 이쪽은 무손실 무압축 포맷이다. 이미지 파일로 치자면 BMP나 TIFF, 또는 DSLR 등에서 지원하는 RAW 파일과 비슷하다고 할 수 있다. 이 때문에 보통 WAV 파일의 용량은 FLAC의 2배 이상이다. 초당 비트레이트는 1411.2 kbps.[1]
위에서 서술한 특징 덕분에 프로그래머가 사운드 관련 코드를 짤 때 WAV 파일을 쓰면 편리하다. MP3 확장자는 편집 후 재압축하면 음질이 손상될 우려가 있고, 손실형 압축을 해버리면 편집에 문제가 생길 수 있으므로 WAV 확장자를 쓰는 것이 프로그래머나 편집자에게는 훨씬 좋다. 베가스 프로에서 작업을 할 때 MP3 음원 파일을 불러오면 음질이 깨지는 경우가 발생하기도 하지만, WAV 파일은 이런 일이 일어나지 않는다. MP3 파일은 작업이 끝난 파일을 다른 사람에게 전달할 때나 필요할 시 변환 프로그램으로 변환해 이용한다.
BMP처럼 4 GB 용량 제한이 있어서 기존 PCM 규격의 WAV 형식으로 2시간 이상의 멀티채널 오디오를 저장하기에는 한계가 있다. 그래서 기존 WAV 대신에 Wave64 컨테이너나 RF64 규격의 WAV 컨테이너에 저장하기도 한다. 혹은 멀티채널 오디오를 모노 채널로 분리하여 각 채널을 PCM 규격의 WAV 파일로 따로 저장하기도 한다.
이런 이유로 영화나 드라마의 사운드를 작업하는 사람들은 PCM 규격의 WAV 컨테이너를 쓰는 것을 상당히 난감해하는 편이다.
WAV 파일은 PCM 뿐만 아니라 ADPCM이나 MPEG Layer-3 등의 다른 코덱을 사용해서 압축하는 것도 가능하다. 예를 들어 Windows 7의 테마별 효과음이 MP3 160 kbps로 압축된 WAV 파일을 사용한다. Windows XP의 녹음기에서 압축된 WAV 파일을 열면 파형이 표시되지 않고, 회색으로 나온다. 하지만 비압축 PCM이 아닌 다른 규격으로 만들어진 WAV 파일은 찾아보기 어려운데, ADPCM을 제외한 대부분의 코덱은 해당 포맷에서 지원하는 컨테이너를 사용하는 경우가 일반적이기 때문이다.
비압축 포맷의 특성상 재생시 CPU 등의 하드웨어 리소스 부담이 적어 게임 개발때 BGM은 FLAC, MP3, OGG를 사용하더라도 동시에 많은 소리를 재생할 일이 많은 SE(효과음)은 WAV 포맷을 사용하는 편이다. 0.5초 내외의 WAV 파일 크기는 부담되지 않기도 하다.
권장하지는 않지만 WAV 파일에도 태그를 저장할 수 있다. Windows Vista 이상에서 파일 탐색기를 통해 태그를 볼 수 있다. 하지만 파일 탐색기에서는 WAV 파일의 태그를 보는 것만 가능하고 수정할 수는 없기 때문에 별도의 프로그램을 사용해야 한다. 또 유니코드 사용을 고려하지 않았기 때문에 언어가 맞지 않으면 문자 깨짐 현상이 발생한다. 애초에 WAV 파일은 ID3 등을 비롯한 메타데이터를 염두에 두고 제작되지 않았기 때문에 명세에도 없다. 플레이어에 따라서는 음원 파일을 재생하지 못하는 상황까지도 발생할 수 있다. 무손실 음원에 메타데이터 태그를 저장하고 싶다면 FLAC을 이용하자.
3. 호환성
대부분의 사운드 편집 프로그램에서 기본적으로 지원한다.[2] 다만, 똑같은 wav 파일이라도 샘플당 비트수(bits per sample)나 주파수(frequency)에 따라서 올바르게 재생이 되지 않는 경우가 있을 수 있다.음악 파일 기준으로 MIDI, APE와 함께 2013년 이후 출시된 삼성 TV에서, Vorbis, WMA와 함께 2014년 이후 출시된 LG TV에서 지원하고 있다. 물론 USB 포트에 꽂은 경우만 해당된다.
4. 속성과 그 의미
- Sample: 소리 정보의 가장 작은 단위. 샘플 하나 하나는 단지 각 시점에서 소리의 크기를 나타낼 뿐이다. 음악을 듣는 것은 음원(=샘플을 모아놓은 자료)으로부터 소리를 복원하는 과정을 거쳐야 하고, 소리의 고주파음, 저주파음 같은 정보 또한 음원을 통해서만 알아낼 수 있다.
- Bits per sample: 양자화 정도. 샘플 하나마다 소리의 세기를 몇 비트로 저장했는지를 나타낸다. 값이 커질 수록 음량을 정확하게 저장할 수 있다. 가장 많이 쓰이는 값은 16bit로, 소리의 세기를 2^16 즉 65,536 단계로 나누어 저장했다는 뜻이다. 4bit / 8bit unsigned int / 16bit int / 24bit / 32bit float 등의 자료형이 쓰인다.
- Sampling frequency: 샘플링 주파수. 소리로부터 초당 샘플링한 횟수를 의미한다. 음원에서 가장 많이 쓰이는 값은 44.1 kHz로, 인간이 들을 수 있는 소리 정보를 매우 잘 커버하는 값이다. 48 kHz 또한 자주 쓰이는 값이고, 어떤 음원 파일들은 16 kHz / 192 kHz 등의 값을 가지고 있다. 아주 가끔 WAV 파일을 재생하는데 웬 이상한 노이즈가 잔뜩 끼어 나오는 경우가 있는데, 이는 십중팔구 프로그램이 해당 음원의 샘플링 주파수를 제대로 처리 못하는 경우이다.
- Channel: 몇 개의 스피커에 알맞은 음원인지를 나타낸다. 각 채널별로 샘플링된 데이터가 따로 저장되어 있다. 예를 들어, 2채널(Stereo) 음원을 재생하면 왼쪽과 오른쪽 스피커에 다른 값이 입력되는데, 1채널(Mono) 음원의 경우 왼쪽과 오른쪽 스피커로 완전히 같은 값이 입력된다.
- 비트레이트: 음원이 재생될 때 초당 읽어들이는 비트 수. Sampling frequency와 bits per sample, channel에 의해 결정되며, 값이 클수록 고품질 음원을 저장할 수 있다.
- 코덱: 음원 데이터가 저장되는 방식. WAV 파일은 PCM 코덱을 쓰는데, 이는 음원 데이터에 별도의 가공을 하지 않는다.
4.1. 용량 계산법
위에서 말한 각 속성별 특징에 따라 계산 공식은 아래와 같이 나온다.(BITS PER SECOND) = (bit per sample) × (frequency) × (channels)[3]
(CAPACITY) = (time) × (BITS PER SECOND) / 8 / (2의 10배수 거듭제곱)
예를 들어, PCM 16bit int, 44.1kHz, Stereo의 속성을 가지고 있는 20초짜리 음원이 있다고 가정해 보자.
그렇다면 용량은 20×16×44100×2/8 = 352만 8000 바이트 ≒ 3.36MB가 나온다. 그리고 비트레이트는 16×44100×2 = 141만 1200bps = 1411.2kbps가 되는 것이다.
44100Hz, PCM 16비트, 모노 채널의 경우 12시간이면 대략 30GB. 스테레오 채널이면 60GB 정도를 소모한다. 그러니 녹음기기에서 wav 파일로 저장할 때는 조심하자. 보통 FAT32 파티션으로 포맷되어 있는 경우가 많은데, FAT32 파티션의 단일 파일 최대 용량은 4GB로 제한되어 있기 때문이다.
4GB가 되는 시점에서 자동으로 끊겨서 분할 저장되고 새로운 파일로 이어지면 다행인데, 기기에 따라서는 안 되고 녹음이 중단되는 경우가 있을 수 있다. 자동 분할이 되더라도 용량이 금방 꽉 찰 수 있고.
저장 공간을 싹 비워두고 1~2시간 정도 짤막하게 녹음하면 별 문제 없겠지만, 길어질 것 같다면 mp3 파일 포맷 사용을 권장한다.
5. 파일 구조
WAVE 파일의 구조는 다음과 같이 정의된다. 파일 전체가 하나의 범용 컨테이너인 RIFF를 사용하며 그에 따라 wav 파일 포맷 자체도 RIFF 청크로 되어있으며, 하위 청크들도 전부 RIFF 컨테이너 형식으로 되어있다.전용 포맷을 사용하지 않고 범용 포맷을 사용하다 보니 다른 데이터 필드로부터 유도할 수 있는 여러 잉여스러운 데이터 필드가 많이 보인다.
5.1. RIFF 청크
#!syntax cpp
WaveFile {
char8_t identifier[4]; // "RIFF"
uint32_t length;
char8_t format_type[4]; // "WAVE"
subchunks_info subchunks;
}
subchunks_info {
fmt_chunk_info fmt_chunk;
fact_chunk_info fact_chunk?;
peak_chunk_info peak_chunk?;
data_chunk_info data_chunk;
}
오프셋 | 필드 | 길이 | 설명 |
0 |
identifier
|
4 |
RIFF 청크 식별자: 값은 문자열 "RIFF" .
|
4 |
length
|
4 | RIFF 청크 전체 필드 데이터 크기의 총합. 파일 자체가 하나의 RIFF 청크이므로 결과적으로는 [math((파일\ 크기) - 8)]. |
8 |
format_type
|
4 |
하위 청크에 담길 데이터 포맷의 식별자: 문자열 "WAVE" .
|
12 |
subchunks
|
(가변) | 기본적으로 음원 데이터에 대한 정보가 담겨있는 fmt 청크와 실제 음원 데이터가 담겨있는 data 청크로 이루어져 있으며, 인코딩 방식에 따라 fact 청크나 peak 청크 같은게 추가되기도 한다. |
5.2. fmt 청크
#!syntax cpp
fmt_chunk_info {
char8_t identifier[4]; // "fmt "
uint32_t length;
uint16_t format_code;
uint16_t channel_count;
uint32_t sampling_rate;
uint32_t data_rate;
uint16_t block_length;
uint16_t bits_per_sample;
}
오프셋 | 필드 | 길이 | 설명 |
0 |
identifier
|
4 |
fmt 청크 식별자: 문자열 "fmt " [4]
|
4 |
length
|
4 |
fmt 청크 전체 필드 데이터들의 크기의 총합 [math(= (\mathrm{fmt\ 청크의\ 크기}) - 8)] |
8 |
format_code
|
2 | 음원이 어떻게 인코딩되어 있는지 나타내는 코드 |
10 |
channel_count
|
2 | 채널 개수 |
12 |
sampling_rate
|
4 | 매 초당 나타낼 수 있는 샘플 수 |
16 |
data_rate
|
4 |
1초에 얼마나 많은 데이터를 채울 수 있는지 바이트로 나타낸다. [math(= \mathtt{sampling\_rate} \times \mathtt{block\_length})] |
20 |
block_length
|
2 |
각 채널의 음량 정밀도의 총합 [math(= \mathtt{channel\_count} \times \dfrac{\tt bits\_per\_sample}{8})] |
22 |
bits_per_sample
|
2 | 샘플 하나당 음량을 얼마나 정밀하게 표현할지 몇비트로 나타낸다. A/μ 법칙 알고리즘의 경우 일본과 미국 표준으로 8비트(0x08)가 지정되어 있다. |
length
는 인코딩 알고리즘을 나타내는 format_code
에 따라 달라진다.코드 |
length
|
인코딩 | 설명 |
0x01 | 16 | 정수 비트 PCM | |
0x02 | 50 | Microsoft ADPCM | |
0x03 | 16 | IEEE 754 부동소수점 | 정수 비트 PCM보다 더 넓은 범위의 음량 표현이 가능하나, 부동소수점 특성상 음량이 커질수록 정밀도는 떨어진다. 샘플값이 출력에 따른 피크를 넘겨버리면 클리핑 현상이 발생할 수 있다. 0dBFS에 해당하는 정수 최대 값을 실수 1.0으로 나타낼 뿐 PCM과 다를게 없다. |
0x06 | 18 | ITU-T G.711 A-law | -1.0~1.0(0dBFS)의 값을 0에서 255 사이의 값으로 특정 수식을 통해 비선형 로그스케일로 압축하여 인코딩하는 알고리즘. |
0x07 | 18 | ITU-T G.711 μ-law | A-law와 비슷한 수식을 이용하여 양자화한다. |
0x11 | 20 | IMA ADPCM | |
0x31 | 20 | GSM 6.10 | |
0x38 | 16 | NMS ADPCM | |
0x40 | 20 | G721 ADPCM |
ADPCM(적응식 차동 펄스 부호 변조)이 어떻게 작동하는지에 대해서는 위키백과와 Microsoft Docs를 참조하자.
IMA ADPCM, GSM 6.10, NMS ADPCM, G721 ADPCM 알고리즘의 경우 한 파일에 한 개의 채널밖에 인코딩하지 못한다. 이들 알고리즘은 fmt 청크 기본 데이터 필드 뒤에 여러 추가 정보들이 붙는다.
5.3. fact 청크
PCM이 아닌 다른 양자화 알고리즘으로 인코딩한 경우, 즉 fmt 청크의format_code
가 0x01이 아닌 다른 값인 경우 무조건 fact 청크가 존재하게 된다.#!syntax cpp
fact_chunk_info {
char8_t identifier[4]; // "fact"
uint32_t length;
uint32_t sample_count;
}
오프셋 | 필드 | 길이 | 설명 |
0 |
identifier
|
4 |
fact 청크 식별자: 문자열 "fact"
|
4 |
length
|
4 |
fact 청크 전체 필드 데이터들의 크기의 총합. 데이터 필드가 sample_count 하나밖에 없으므로 0x04의 값을 갖는다.
|
8 |
sample_count
|
4 |
채널 한 개당 샘플 개수 [math(= \dfrac{\tt sampling\_rate}{\tt channel\_count})] |
5.4. PEAK 청크
양자화 알고리즘이 부동소수점으로 인코딩된 경우, 즉 fmt 청크의format_code
가 0x03일 때에는 무조건 PEAK 청크가 존재하게 된다.#!syntax cpp
ᅟpeak_chunk_info {
char8_t identifier[4]; // "PEAK"
uint32_t length;
uint32_t version;
time32_t timestamp;
peak_info peak[channel_count];
}
peak_info {
float32_t value;
uint32_t position;
}
오프셋 | 필드 | 길이 | 설명 |
0 |
identifier
|
4 |
PEAK 청크 식별자: 문자열 "PEAK"
|
4 |
length
|
4 |
PEAK 청크 전체 필드 데이터의 크기의 총합 [math(= 8 \times (\mathtt{channel\_count} + 1))] |
8 |
version
|
4 | PEAK 청크의 버전. 현재 버전 1에 대해서만 명세가 존재하므로, 필드는 0x01의 값을 가진다. |
12 |
timestamp
|
4 | 마지막으로 PEAK 정보가 수정된 UNIX 시간 |
16 |
peak
|
(가변) | 채널별 PEAK 정보가 들어있는 데이터 필드 |
16 + 8n |
value
|
4 | 채널 한 개당 나타나는 최대 피크 값. 1.0인 경우 0 dBFS를 뜻한다. |
20 + 8n |
position
|
4 | 샘플 부호에 상관없이 최대 피크값이 처음으로 나타나는 샘플 프레임 번호. 당연하게도 0부터 센다. |
5.5. data 청크
#!syntax cpp
data_chunk_info {
char8_t identifier[4]; // "data"
uint32_t length;
uint8_t sound_data[];
}
오프셋 | 필드 | 길이 | 설명 |
0 |
identifier
|
4 |
data 청크 식별자: 문자열 "data"
|
4 |
length
|
4 |
data 청크 데이터 sound_data 의 길이
|
8 |
sound_data
|
(가변) | 실제 음원 데이터 |
format_code
가 0x01
[5]또는 0x03
[6]인 경우, 프레임에서는 각 채널의 샘플 데이터가 차례로 나타나며, 샘플의 바이트 순서는
리틀 엔디안이다. 샘플 데이터가 채널 개수만큼 모여 프레임을 이루고, 프레임이 모여 1초를 채우면 블록이 된다.예를 들어, [math(\mathtt{channel\_count} = 2,\ \mathtt{sampling\_rate} = 8,\ \mathtt{bits\_per\_sample} = 16)]이라면, 다음과 같이 나타난다.
음원 데이터 | |||||||||||||||||||||||||
시간 | 1초 | 2초 | 3초 | ||||||||||||||||||||||
샘플 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | |
<colbgcolor=#f5f5f5,#2d2f34> 채널 1 (Left) |
<colbgcolor=#f5f5f5,#2d2f34> 선행 | F6 | 97 | 63 | D9 | C6 | D9 | 5A | 9B |
s a m p l e |
s a m p l e |
s a m p l e |
s a m p l e |
f r a m e |
f r a m e |
f r a m e |
f r a m e |
block | |||||||
후행 | B8 | 29 | BB | B9 | 8D | D0 | 26 | 59 | |||||||||||||||||
채널 2 (Right) |
선행 | 44 | 7C | FD | 12 | B3 | AE | 9E | BB | 34 | 30 | FA | 31 | ||||||||||||
후행 | B9 | 84 | 57 | 4B | AB | 6C | EA | B3 | 43 | 67 | 96 | D9 |
6. 관련 문서
7. 외부 문서
[1]
44.1 kHz, 16비트, 스테레오 기준
[2]
Windows 10에 기본적으로 깔려있는 음성 녹음기 앱은 wav를 지원하지 않고 손실 압축 포맷인
m4a로만 저장한다.
[3]
이때, 접두사를 붙이고 싶다면 위 공식으로 나온 값을 10의 정수 거듭제곱으로 나누면 된다.
[4]
후행 공백에 주의한다.
[5]
정수
[6]
실수