WAV
WAV 또는 WAVE는 웨이브폼 오디오 포맷(웨이브 오디오 포맷, Waveform audio format)의 준말로 개인용 컴퓨터에서 오디오를 재생하는 마이크로소프트와 IBM 오디오 파일 포맷 표준이다. 덩어리째로 데이터를 저장하기 위한 RIFF 비트스트림 포맷 방식에서 변화한 것으로, 아미가에 쓰이는 IFFF와 매킨토시 컴퓨터에 쓰이는 AIFF 포맷에 매우 가깝다. 가공되지 않은 오디오를 위한 윈도 시스템에 쓰이는 기본 포맷이다. 윈도 상에서는 WAV가 비압축 형식만 있는 것이 아니고 여러 압축 코덱을 이용할 수 있다. 그러나 윈도 비스타부터는 기본 지원 포맷이 WMA으로 바뀌었다.
WAV는 비압축 오디오 포맷으로, 프로그램 구동음이나 일반 수준의 녹음용으로 사용되지만 전문 녹음용으로는 WAV가 아닌 다른 비압축 포맷이 더 많이 쓰이기도 한다. 참고로 일부 라디오 방송국에서는 MP2이라는 압축 오디오 포맷 대신 비압축 WAV 포맷을 사용하는 경우도 있다.
Wav merge
웨이브파일의 FMT Sub-chunk 헤더정보가 동일할 경우 아래와 같이 PCM정보를 합칠 수 있다.
#include <stdio.h>
#include <Windows.h>
#pragma pack (push, 1)
struct WaveHeader
{
// RIFF header.
char ChunkID[4];
unsigned int ChunkSize;
char Format[4];
// FMT Header.
char SubChunk1ID[4];
unsigned int SubChunk1Size;
short AudioFormat;
short NumChannels;
unsigned int SampleRate;
unsigned int ByteRate;
short BlockAlign;
short BitsPerSample;
// DATA Header.
char SubChunk2ID[4];
unsigned int SubChunk2Size;
};
#pragma pack (pop)
int _tmain(int argc, _TCHAR* argv[])
{
FILE * rf1 = fopen("1.wav", "rb");
FILE * rf2 = fopen("2.wav", "rb");
FILE * wf = fopen("12.wav", "wb");
if (rf1 != NULL && rf2 != NULL && wf != NULL) {
WaveHeader rf1_wave_header = {0,};
WaveHeader rf2_wave_header = {0,};
fread(&rf1_wave_header, sizeof(WaveHeader), 1, rf1);
fread(&rf2_wave_header, sizeof(WaveHeader), 1, rf2);
BYTE * rf1_pcm = new BYTE [rf1_wave_header.SubChunk2Size];
BYTE * rf2_pcm = new BYTE [rf2_wave_header.SubChunk2Size];
memset(rf1_pcm, 0x00, sizeof(*rf1_pcm) * rf1_wave_header.SubChunk2Size);
memset(rf2_pcm, 0x00, sizeof(*rf2_pcm) * rf2_wave_header.SubChunk2Size);
// Read pcm data
int read_count1 = fread(rf1_pcm, sizeof(BYTE), rf1_wave_header.SubChunk2Size, rf1);
int read_count2 = fread(rf2_pcm, sizeof(BYTE), rf2_wave_header.SubChunk2Size, rf2);
// merge
WaveHeader wf_wave_header = {0,};
memcpy(&wf_wave_header, &rf1_wave_header, sizeof(rf1_wave_header));
// calc.
wf_wave_header.ChunkSize += rf2_wave_header.SubChunk2Size;
wf_wave_header.SubChunk2Size += rf2_wave_header.SubChunk2Size;
// file write.
fwrite(&wf_wave_header, sizeof(wf_wave_header), 1, wf);
fwrite(rf1_pcm, sizeof(BYTE), rf1_wave_header.SubChunk2Size, wf);
fwrite(rf2_pcm, sizeof(BYTE), rf2_wave_header.SubChunk2Size, wf);
}
fclose(rf1);
fclose(rf2);
fclose(wf);
return 0;
}