1)文件头的结构体
typedef struct _wavFormatInfo{
unsigned short AudioFormat; // 1 for PCM. Linear quantization
unsigned short NumChannels; // 1->Mono, 2->stereo, etc..
unsigned long SampleRate; // 8000, 11025, 16000, 44100, 48000, etc..
unsigned long ByteRate; // = SampleRate * NumChannels * BitsPerSample/8
unsigned short BlockAlign; // = NumChannels * BitsPerSample / 8
unsigned short BitsPerSample; // 8->8bits, 16->16bits, etc..
} wav_format_info;
//可明确的数据
typedef struct _tagMsWavPcmHeader36{
unsigned char ChunkID[4]; // "RIFF"; The "RIFF" the mainchunk;
unsigned long ChunkSize; // FileSize - 8; The size following this data
unsigned char Format[4]; // "WAVE"; The "WAVE" format consists of two subchunks: "fmt " and "data"
unsigned char SubChunk1ID[4]; // "fmt "
unsigned long SubChunk1Size; // 16 for PCM. This is the size of the rest of the subchunk which follows this data.
wav_format_info FormatInfo;
} wav_pcm_header36;
//可存放不可知的fact 信息 和data 信息
typedef struct _wavDataInfo{
unsigned char DataName[4];//"data" or fact
unsigned long DataLen;
} wav_data_info;
//注:20+SubChunk1Size+8+(如果存在fact:+8+factDataLen)=headLen。
2)获取头和数据
int GetWavAudioFile(const char * fileName,char **_dataHead,char **_data,int * _headLen,int * _dataLen)
{
FILE *fpWav=NULL;
unsigned long size;
wav_pcm_header36 hwav;
wav_data_info datainfo;
char * tempbuf=NULL;
char *dataHead=NULL;
char *data=NULL;
int headLen=0;
int dataLen=0;
fpWav = fopen(fileName, "rb");
if (fpWav)
{
/*
* Get wave headdata and headlen
*/
fread(&hwav, sizeof(wav_pcm_header36), 1, fpWav);
printf(" wav_pcm_header36 len=%d \n",sizeof(wav_pcm_header36));
/* Check wave header */
if ( (0==memcmp(hwav.ChunkID, "RIFF", 4)) &&(0==memcmp(hwav.Format, "WAVE", 4)) &&
(0==memcmp(hwav.SubChunk1ID, "fmt ", 4)))
{
headLen=sizeof(wav_pcm_header36)-sizeof(wav_format_info)+hwav.SubChunk1Size;
int templen=headLen-sizeof(wav_pcm_header36);
tempbuf=(char * )malloc(templen);
fread(tempbuf,templen,1,fpWav);//多余的
fread(&datainfo,sizeof(wav_data_info),1,fpWav);//data 或 fact
headLen+=8;
if(0==memcmp(datainfo.DataName, "data", 4))
{
if(hwav.ChunkSize+8<headLen+datainfo.DataLen)
{
datainfo.DataLen=hwav.ChunkSize+8-headLen;
}
dataLen=datainfo.DataLen;
}
else if(0==memcmp(datainfo.DataName, "fact", 4))
{
fread(&datainfo, sizeof(wav_data_info), 1, fpWav);
headLen +=datainfo.DataLen+8;
if(0==memcmp(datainfo.DataName, "data", 4))
{
if(hwav.ChunkSize+8<headLen+datainfo.DataLen)
{
datainfo.DataLen=hwav.ChunkSize+8-headLen;
}
dataLen=datainfo.DataLen;
}
else
{
printf("this is no data ! %s \n",datainfo.DataName);
headLen=0;
datainfo.DataLen=0;
}
}
else
{
headLen=0;
datainfo.DataLen=0;
printf("this is error wav file! \n");
}
}
/*
* Get wave head and data
*/
if(headLen>0)
{
fseek(fpWav,0,SEEK_SET);
dataHead=(char*)malloc(headLen);
fread(dataHead, headLen, 1, fpWav);
*_headLen=headLen;
*_dataHead=dataHead;
if(dataLen>0)
{
data=(char*)malloc(dataLen);
fread(data,dataLen, 1, fpWav);
*_dataLen=dataLen;
*_data=data;
}
printf("this is all size:%d,head size=%d,data size=%d \n",hwav.ChunkSize+8,headLen,dataLen);
}
if(tempbuf!=NULL)
{
free(tempbuf);
}
fclose(fpWav);
fpWav = NULL;
if(headLen<=0||dataLen<=0||data==NULL||dataHead==NULL)
{
return -2;
}
}
else
{
printf("Open wave file %s failed!\n", fileName);
return -1;
}
return 1;
}