완벽하다고 말씀드리기 힘들지만.. 일단 동작은 합니다. ^^;
가끔 웨이브 파일 헤더가 좀 다른경우가 있는데.. 그런 예외처리는 하지 않았구요.
보시면..무지 간단함을 아실거예요. (2004.12.27 LGH)
// 16bit -> 8bit 변환.
int WaveFile_16bitTo8bit(char *pInputFile, char *pOutputFile)
{
int len;
short *in;
unsigned char *out;
WAVE_HEADER tHeader;
CFile cf;
if(!cf.Open(pInputFile, CFile::modeRead)) {
return -1;
}
DWORD dwFileSize = cf.GetLength();
int nRead = cf.Read(&tHeader,
sizeof(WAVE_HEADER)); // wave 헤더를 읽어온다.
if(nRead <= 0)
return -1;
len = tHeader.nDataSize;
int size1 = sizeof(short);
int size2 = sizeof(unsigned char);
in = (short*)malloc(sizeof(short)*len/2);
out = (unsigned char*)malloc(sizeof(unsigned
char)*len/2);
cf.Read(in, len);
cf.Close();
// 16bit -> 8bit
Wave_16bitTo8bit(in, len/2, out);
//save output file
if(!cf.Open(pOutputFile, CFile::modeCreate |
CFile::modeWrite)) {
free(in);
free(out);
return -1;
}
tHeader.nBitPerSample =
8; //
bit per sample 설정 - 8bit
tHeader.nDataSize = len /
2; //
실제데이터의 크기.
cf.Write(&tHeader,
sizeof(tHeader)); //
wave 헤더를 먼저 기록.
cf.Write(out, sizeof(unsigned char)*len/2);
cf.Close();
free(in);
free(out);
return 0;
}
// 16bit -> 8bit 변환.
void Wave_16bitTo8bit(short *in, int sample_num, unsigned char *out)
{
int i;
unsigned char tmp;
for(i = 0 ;i < sample_num; i++)
{
//8bit = (unsigned
char)(16bit / 256 + 128);
tmp = (unsigned char)(in[i] /
256 + 128);
out[i] = tmp;
/*
if(tmp > 128){
out[i]
= 128;
}
else if(tmp < -128){
out[i]
= -128;
}
else{
out[i]
= tmp;
}*/
}
}
typedef struct _WAVE_HEADER
{
char pRIFF[4]; //
RIFF 파일이라는 지정
int nTotalSize; //
현재 다음부터 마지막까지의 파일 크기, 즉 파읽크기 - 8
char pWave[4]; //
"WAVE" : 웨이브 파일
char pFmt[4]; //"fmt"
:자식 청크 시작
int nWaveFormatSize; //
웨이브 포맷 사이즈
short nCompCode; //
Compression Code. 1:PCM, 2:Microsoft ADPCM ....
short nChannels; //
Channels수
int nSampleForSec; //
초당 샘플수
int nSampleBytesForSec; //
초당 평균 샘플 바이트
short nBlockAlignment; //
short nBitPerSample; //
//short nAuxInfoSize; //
부가정보 크기
char pData[4]; //
"data" : 데이터 청크
int nDataSize; //
데이터의 크기
}WAVE_HEADER;
// 이건.. 반대로 8bit -> 16bit 입니다. 인자부분 잘 보면서.. 호출 함수를 변경하시면 됩니다.
void Wave_8bitTo16bit(unsigned char *in, int sample_num, short *out)
{
int i;
short tmp;
for(i = 0 ;i < sample_num; i++)
{
//16bit = ((short)8bit -
128)*256;
tmp = ((short)in[i] - 128) *
256;
if(tmp > 32767){
out[i]
= 32767;
}
else if(tmp < -32768){
out[i]
= -32768;
}
else{
out[i]
= tmp;
}
}
} |