예광탄 프로그램

: 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()

{

             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 읽어온다.

 

  

ParentChunk::ParentChunk(HANDLE hFile)

{

             DWORD dwRead;

             ReadFile(hFile,filetype,4,&dwRead,0);

             filetype[4]=0;

             ReadFile(hFile,&filesize,4,&dwRead,0);

             ReadFile(hFile,mediatype,4,&dwRead,0);

             mediatype[4]=0;

}

 

 

 

만약 filetype “RIFF” 아니거나 mediatype “WAVE” 아닌 경우 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가 한 개 더 있다. 그래서 ChunkIDChunkSizeChunk데이터를 얻어왔다.

 

 

SubChunk::SubChunk(HANDLE hFile)

{

             DWORD dwRead;

             ReadFile(hFile,magic,4,&dwRead,0);

             magic[4]=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);

            

             //pt1618이아닌경우는배제

             if(pt==18 )

             {

                           size_extend = (short *)malloc(2);

                           ReadFile(hFile,size_extend,2,&dwRead,0);

                           char fmagics[5]={0,};

                           ReadFile(hFile,fmagics,4,&dwRead,0);

                           int next;

                           ReadFile(hFile,&next,4,&dwRead,0);

                           char foo[4096];

                           ReadFile(hFile,foo,next,&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

 

ChunkID,DataSize,Data 얻어온다.

 

 

DataChunk::DataChunk(HANDLE hFile)

{

             DWORD dwRead;

             ReadFile(hFile,magic,4,&dwRead,0);

             magic[4]=0;

             ReadFile(hFile,&datasize,4,&dwRead,0);

            

             data=(short *)malloc(datasize);

             ReadFile(hFile,data,datasize,&dwRead,0);

}

 

 

 

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;

}

 

 

  

 

입력받은 Chunk들을 Edit박스에 나타내었고, 데이터들을 Lineto함수로 출력해주었다.

 

 

 

 

 

 

 

'기타 > 메신저' 카테고리의 다른 글

Wave분석 최종  (0) 2011.03.04
Wave 버젼  (0) 2011.02.06
워크샵 가기전 파일 백업  (0) 2011.01.26
개인 주간 계획서 1주차  (0) 2011.01.20
개인 일일 보고서 1일차  (0) 2011.01.20

+ Recent posts