|
예광탄 프로그램 |
조 : 2조 |
작성자 : 김동영 | |
작성일 : 2011. 1. 24 | |
제목 : Wave 포맷 분석 및 데이터 출력 |
Wave Format
1) RIFF chunk
type |
byte |
내용 |
의미 |
char |
4 |
“RIFF” |
파일의 종류가 RIFF 파일을 의미 |
DWORD |
4 |
FILE SIZE |
현재부터 끝까지의 파일 크기 |
char |
4 |
“WAVE” |
Wave 파일을 의미 |
2) FMT sub-chunk
type |
byte |
내용 |
의미 |
char |
4 |
“fmt” |
Chunk ID |
DWORD |
4 |
16 | 18 |
Chunk Size |
short |
2 |
wFormatTag |
PCMWAVEFORMAT의 값(1:PCM ) |
short |
2 |
nChannels |
채널수(1:모노, 2:스테레오) |
DWORD |
4 |
nSamplesPerSec |
샘플링 수 |
DWORD |
4 |
nAvgBytesperSec |
초당 샘플 바이트 |
short |
2 |
BlockAlign |
샘플당 바이트 |
short |
2 |
wBitsPerSample |
샘플당 비트수 |
3) Data sub-chunk
type |
byte |
내용 |
의미 |
char |
4 |
“data” |
데이터 청크의 시작 |
DWORD |
4 |
DATA SIZE |
데이터의 크기 |
|
|
DATA |
데이터 |
SoundInfo 클래스는 RIFF Chunk(ParentChunk 클래스)와 FMT Sub-Chunk(SubChunk 클래스)와 Data Sub-Chunk(DataChunk)를 관리해주는 클래스이다.
SoundInfo.cpp
생성자에서 각각의 Chunk별로 데이터들을 얻는다.
SoundInfo::SoundInfo(HANDLE hFile) { parent_chunk=new ParentChunk(hFile); sub_chunk=new SubChunk(hFile); data_chunk=new DataChunk(hFile); }
ParentChunk의 데이터를 얻어온다.
char *SoundInfo::GetFiletype() { return parent_chunk->GetFiletypeC(); } int SoundInfo::GetFilesize() { return parent_chunk->GetFilesizeC(); } char *SoundInfo::GetMediatype() { return parent_chunk->GetMediatypeC(); } |
각 Chunk별로 Wave파일의 속성이 맞는지 확인한다.
bool SoundInfo::CheckParentChunk() { return parent_chunk->IsAvailChunk(); } bool SoundInfo::CheckSubChunk() { return sub_chunk->IsAvailChunk(); } bool SoundInfo::CheckDataChunk() { return data_chunk->IsAvailChunk(); } |
SubChunk의 데이터를 얻어온다.
char *SoundInfo::GetMagic()//매직 { return sub_chunk->GetMagicC(); } int SoundInfo::GetPt()//chunk size { return sub_chunk->GetPtC(); } short SoundInfo::GetFormat()//포맷 { return sub_chunk->GetFormatC(); } short SoundInfo::GetChannelcnt()//채널수 { return sub_chunk->GetChannelcntC(); } int SoundInfo::GetSamples_persec()//초당샘플수 { return sub_chunk->GetSamples_persecC(); } int SoundInfo::GetBytes_persec() //초당바이트수- 평균값임 { return sub_chunk->GetBytes_persecC(); } short SoundInfo::GetSize_sample() //샘플1개의사이즈 { return sub_chunk->GetSize_sampleC(); } short SoundInfo::GetBits_persample()//샘플한개의비트수 { return sub_chunk->GetBits_persampleC(); } short *SoundInfo::GetSize_extend()//옵션의사이즈 { return sub_chunk->GetSize_extendC(); } |
DataChunk의 데이터를 얻어온다.
char *SoundInfo::GetDataMagic() { return data_chunk->GetDataMagicC(); } int SoundInfo::GetDataSize() { return data_chunk->GetDataSizeC(); } short* SoundInfo::GetData() { return data_chunk->GetDataC(); }
ParentChunk.cpp
Filetype,filesize,mediatype을 읽어온다.
{ DWORD dwRead; ReadFile(hFile,filetype,4,&dwRead,0); ReadFile(hFile,&filesize,4,&dwRead,0); ReadFile(hFile,mediatype,4,&dwRead,0); } |
bool ParentChunk::IsAvailChunk() { return (strcmp(MAGIC_FILE_TYPE,filetype)==0)&&(strcmp(MAGIC_WAVE_TYPE,mediatype)==0); }
char *ParentChunk::GetFiletypeC()
{
return filetype;
}
int ParentChunk::GetFilesizeC()
{
return filesize;
}
char *ParentChunk::GetMediatypeC()
{
return mediatype;
}
SubChunk.cpp
ChunkID,ChunkSize, PCMWAVEFORMAT의 값,채널수,샘필링수,초당 샘플 바이트,샘플당 바이트, 샘플당 비트수를 얻어온다.
*단, pt(ChunkSize)가 18일 경우에는 SubChunk의 2바이트 이후 DataChunk사이와 SubChunk 사이에 ChunkData가 한 개 더 있다. 그래서 ChunkID와 ChunkSize와 Chunk데이터를 얻어왔다.
SubChunk::SubChunk(HANDLE hFile) { DWORD dwRead; ReadFile(hFile,magic,4,&dwRead,0); ReadFile(hFile,&pt,4,&dwRead,0); ReadFile(hFile,&format,2,&dwRead,0); ReadFile(hFile,&channelcnt,2,&dwRead,0); ReadFile(hFile,&samples_persec,4,&dwRead,0); ReadFile(hFile,&bytes_persec,4,&dwRead,0); ReadFile(hFile,&size_sample,2,&dwRead,0); ReadFile(hFile,&bits_persample,2,&dwRead,0);
//pt가16과18이아닌경우는배제 if(pt==18 ) { size_extend = (short *)malloc(2); ReadFile(hFile,size_extend,2,&dwRead,0); } } |
ChunkID(magic)이 “fmt”이 아니거나 format(PCMWAVEFORMAT)값이 1(Wave Format이 PCM 방식) 이 아닐 때 0을 리턴한다.
bool SubChunk::IsAvailChunk() { return (strcmp(MAGIC_SUB_TYPE,magic)==0)&&(format==PCMWAVE_FORMAT); }
|
char *SubChunk::GetMagicC()//ChunkID
{
return magic;
}
int SubChunk::GetPtC()//ChunkSize
{
return pt;
}
short SubChunk::GetFormatC()//포맷
{
return format;
}
short SubChunk::GetChannelcntC()//채널수
{
return channelcnt;
}
int SubChunk::GetSamples_persecC()//초당샘플수
{
return samples_persec;
}
int SubChunk::GetBytes_persecC() //초당바이트수- 평균값임
{
return bytes_persec;
}
short SubChunk::GetSize_sampleC() //샘플1개의사이즈
{
return size_sample;
}
short SubChunk::GetBits_persampleC()//샘플한개의비트수
{
return bits_persample;
}
short *SubChunk::GetSize_extendC()
{
return size_extend;
}
DataChunk.cpp
DataChunk::DataChunk(HANDLE hFile) { DWORD dwRead; ReadFile(hFile,magic,4,&dwRead,0); ReadFile(hFile,&datasize,4,&dwRead,0); data=(short *)malloc(datasize); short _data; }
int j=0;
for(int i=0;i<datasize;i=i+2)
{
ReadFile(hFile,&_data,sizeof(short),&dwRead,0);
data[j]=_data;
if(dwRead == 0)
{
break;
}
j++;
}
ChunkID가 “DATA”가 아니면 0을 리턴한다.
bool DataChunk::IsAvailChunk() { return (strcmp(MAGIC_DATA_TYPE,magic)==0); }
char *DataChunk::GetDataMagicC()
{
return magic;
}
int DataChunk::GetDataSizeC()
{
return datasize;
}
short* DataChunk::GetDataC()
{
return data;
}
|