안녕하세요. 오늘은 WAV파일에대해 알아보겠습니다.
이 글의 목적은 MCU에서 WAV파일을 읽을때 알아야 할 내용을 알아보는게 목적입니다.
WAVE파일은 RIFF(Resource Interchange File Format)구조를 사용합니다.
RIFF 구조는 아래의 그림과 같습니다. 일반적으로 44바이트가 파일정보이고, 나머지가 음원데이터입니다.
RIFF구조는 chunk단위를 사용합니다. chunk단위는 구조가 ID(4바이트),SIZE(4바이트),DATA(N바이트)로 이루어집니다.
WAV파일은 세가지 영역으로 구분됩니다.


위에있는 WAV파일을 RIFF 구조에맞게 해석해보겠습니다.
(리틀 엔디안 방식)
1. RIFF
1) ChunkID (4바이트)

ChunkID입니다.
2) ChunkSize (4바이트)

파일의 크기입니다. 업로드한 파일의 크기는 1.83MB입니다.
0x001D4C24 = 1922724바이트
RIFF사양에서 ChunkSize는 ChunkID크기(4바이트)와 자기자신 ChunkSize(4바이트)는 포함하지 않도록 되어있습니다.
1922724-8 = 1922716BYTE = 1.83MB
그러므로 MCU에서 파일의 크기를 읽으려면 해당 부분을 읽으면 됩니다.
3) Format (4바이트)

파일의 FORMAT입니다. wav파일은 항상 "WAVE"입니다. .wav파일이 아니라 .avi파일인경우 "AVI "가 됩니다.
그러므로 MCU에서 wav파일인지 읽으려면 해당 부분을 읽으면 됩니다.
2. FMT (Format)
1) Subchunk1ID (4바이트)

2) Subchunk1Size (4바이트)

fmt청크 사이즈입니다. RIFF의 ChunkSize와 마찬가지로 ID와 자기자신을뺀 크기이므로 16 입니다.
3) AudioFormat (2바이트)

오디오 포맷이고 0x0001은 PCM포맷을 의미합니다. PCM(Pulse Code Modulation)은 가장 단순한 디지털 오디오 저장방식(비압축) 입니다. 일정 주기마다 아날로그 신호의 세기를 측정해서 정수값으로 저장합니다.
오디오포맷으로 PCM말고 다른 포맷도 가능한데 MCU에서 사용할때는 주로 PCM포맷만 사용합니다. 다른 포맷을 사용하면 MCU가 디코딩을하거나 전용 코덱칩을 사용해야합니다.
3) NumChannels (2바이트)

1은 모노이고 2는 스테레오입니다. 3채널 이상도 가능합니다.
4) SampleRate (4바이트)

0xBB80 = 48000Hz
샘플레이트는 1초동안 몇번 샘플링했는지를 의미합니다. 48000이므로 1초에 48000개의 샘플값이 들어있습니다.
MCU에서는 일반적으로 무조건 읽어야하는 데이터입니다.
5) ByteRate (4바이트)

0x02EE00=192000바이트
1초당 몇 바이트가 재생되는지 알려주는 데이터입니다.
ByteRate = samplerate * numberchannels * bitspersample/8
= 48000 * 2 *16/8 = 192000
bitspersample은 일반적으로 bit단위이므로 byte로 단위를 맞추기위해 나누기8을 합니다.
I2S통신을 하는경우에 MCU에서는 I2S 모듈에게 1초에 192000바이트의 데이터를 보내야 정상 속도로 소리가 납니다.
6) BlockAlign (2바이트)

0x0004 = 4
오디오 데이터에서 한 번에 재생해야 하는 최소 단위입니다. 4이므로 4바이트입니다.
BlockAlign = numchannels * bitpersample/8
= 2*16/8 = 4
스테레오 2채널, 16비트샘플이므로 아래와 같이 표현됩니다.
[L1_Low][L1_High][R1_Low][R1_High] → BlockAlign 4 bytes
[L2_Low][L2_High][R2_Low][R2_High] → BlockAlign 4 bytes
7) BitsPerSample (2바이트)

0x0010 = 16비트
각 샘플이 몇 비트로 저장하는지를 나타냅니다. 16비트이므로 -32768 ~ +32767 범위의 정수로 소리 세기를 표현합니다.
MCU에서는 일반적으로 무조건 읽어야하는 데이터입니다.
3. DATA
1) Subchunk2ID (4바이트)

2) Subchunk2Size (4바이트)

0x1D4C00 = 1920000 바이트
Duration = Subchunk2Size / ByteRate
= 1920000 / 192000 = 10초
오디오 데이터의 길이를 의미합니다. 해당값을 읽어서 계산하면 wav파일이 몇초짜리인지 계산이 가능합니다.
3) data (N바이트)
음원데이터입니다.
0x7FFF=32767, 0x8001=32767 두 값을 보내고있는 사각파입니다.
