C ++读取16位音频文件 - 数据大小不正确

时间:2013-09-13 11:28:53

标签: c++ audio wav

我正在尝试读取.wav文件,但是,每当我尝试读取16位音频文件时,“数据”块大小不正确,但是,对于8位文件,它是正确的。代码如下:

#pragma pack(push, 1)
struct s_riff_hdr
{
  char id[4];
  uint32_t size;
  char type[4];
};

struct s_chunk_hdr
{
   char id[4];
   uint32_t size;
};

struct s_wavefmt
{
  uint16_t format_tag;
  uint16_t channels;
  uint32_t sample_rate;
  uint32_t avg_bytes_sec;
  uint16_t block_align;
};

struct s_wavefmtex
{
  s_wavefmt fmt;
  uint16_t bits_per_sample;
  uint16_t extra_size;
};

struct s_pcmwavefmt
{
  s_wavefmt fmt;
  uint16_t bits_per_sample;
};

bool readWave(ifstream &file)
{
   s_riff_hdr riff_hdr;
   s_chunk_hdr chunk_hdr;
   uint32_t padded_size;
   vector<uint8_t> fmt_data;
   s_wavefmt *fmt = NULL;

   file.read(reinterpret_cast<char*>(&riff_hdr), sizeof(riff_hdr));
   if (!file) return false;

   if (memcmp(riff_hdr.id, "RIFF", 4) != 0) return false;

   cout << "size=" << riff_hdr.size << endl;
   cout << "type=" << string(riff_hdr.type, 4) << endl;

   if (memcmp(riff_hdr.type, "WAVE", 4) != 0) return false;

   // chunks can be in any order!
   // there is no guarantee that "fmt" is the first chunk.
   // there is no guarantee that "fmt" is immediately followed by "data".
   // There can be other chunks present!

   do
   {
       file.read(reinterpret_cast<char*>(&chunk_hdr), sizeof(chunk_hdr));
       if (!file) return false;

       padded_size = ((chunk_hdr.size + 1) & ~1);

       cout << "id=" << string(chunk_hdr.id, 4) << endl;
       cout << "size=" << chunk_hdr.size << endl;
       cout << "padded size=" << padded_size << endl;

       if (memcmp(chunk_hdr.id, "fmt ", 4) == 0) 
       {
           if (chunk_hdr.size < sizeof(s_wavefmt)) return false;

           fmt_data.resize(padded_size);

           file.read(reinterpret_cast<char*>(&fmt_data[0]), padded_size);
           if (!file) return false;

           fmt = reinterpret_cast<s_wavefmt*>(&fmt_data[0]);

           cout << "format_tag=" << fmt->format_tag << endl;
           cout << "channels=" << fmt->channels << endl;
           cout << "sample_rate=" << fmt->sample_rate << endl;
           cout << "avg_bytes_sec=" << fmt->avg_bytes_sec << endl;
           cout << "block_align=" << fmt->block_align << endl;

           if (fmt->format_tag == 1) // PCM
           {
              if (chunk_hdr.size < sizeof(s_pcmwavefmt)) return false;

              s_pcmwavefmt *pcm_fmt = reinterpret_cast<s_pcmwavefmt*>(fmt);

              cout << "bits_per_sample=" << pcm_fmt->bits_per_sample << endl;
           }
           else
           {
              if (chunk_hdr.size < sizeof(s_wavefmtex)) return false;

              s_wavefmtex *fmt_ex = reinterpret_cast<s_wavefmtex*>(fmt);

              cout << "bits_per_sample=" << fmt_ex->bits_per_sample << endl;
              cout << "extra_size=" << fmt_ex->extra_size << endl;

              if (fmt_ex->extra_size != 0)
              {
                  if (chunk_hdr.size < (sizeof(s_wavefmtex) + fmt_ex->extra_size)) return   
                     false;

                  uint8_t *extra_data = reinterpret_cast<uint8_t*>(fmt_ex + 1);
                // use extra_data, up to extra_size bytes, as needed...
             }
          }
      }
      else if (memcmp(chunk_hdr.id, "data", 4) == 0)
      {
          // process chunk data, according to fmt, as needed...
        //cout << padded_size;
        file.ignore(padded_size);
        if (!file) return false;
    }
    else
    {

        // process other chunks as needed...
        file.ignore(padded_size);
        if (!file) return false;
    }
}
while (!file.eof());

return true;
}

我试图将“padded_size”从8位转换为16位,然而,再次,这似乎不想工作。任何帮助将不胜感激。

0 个答案:

没有答案