WAV音频格式解析C代码

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;

}

 

 

 

你可能感兴趣的:(音频格式解析,wav格式)