Logo Search packages:      
Sourcecode: catcodec version File versions  Download package

void Sample::ReadSample ( FileReader reader,
bool  check_size = true 
)

Reads a sample from a reader. It reads WAV files (if that is the only thing in the file). This function has some very strict tests on validity of the input file.

Parameters:
readerplace to read the sample from
check_sizewhether to check that our size makes sense with the size from the sample

Definition at line 104 of file sample.cpp.

References bits_per_sample, FileReader::GetFilename(), num_channels, FileReader::ReadDword(), FileReader::ReadRaw(), FileReader::ReadWord(), RIFF_HEADER_SIZE, sample_data, sample_rate, sample_size, and size.

Referenced by ReadCatEntry(), and Sample().

{
      assert(this->sample_data == NULL);

      if (reader.ReadDword() != 'FFIR') throw "Unexpected chunk; expected \"RIFF\" in " + reader.GetFilename();

      if (check_size) {
            if (reader.ReadDword() + 8  != size  ) throw "Unexpected RIFF chunk size in " + reader.GetFilename();
      } else {
            this->size = reader.ReadDword() + 8;
      }
      if (reader.ReadDword() != 'EVAW') throw "Unexpected format; expected \"WAVE\" in " + reader.GetFilename();
      if (reader.ReadDword() != ' tmf') throw "Unexpected format; expected \"fmt \" in " + reader.GetFilename();
      if (reader.ReadDword() != 16    ) throw "Unexpected fmt chunk size in " + reader.GetFilename();
      if (reader.ReadWord()  != 1     ) throw "Unexpected audio format; expected \"PCM\" in " + reader.GetFilename();

      this->num_channels = reader.ReadWord();
      if (this->num_channels != 1) throw "Unexpected number of audio channels; expected 1 in " + reader.GetFilename();

      this->sample_rate = reader.ReadDword();
      if (this->sample_rate != 11025 && this->sample_rate != 22050 && this->sample_rate != 44100) throw "Unexpected same rate; expected 11025, 22050 or 44100 in " + reader.GetFilename();

      /* Read these and validate them later on.
       * Saving them is unnecesary as they can be easily calucated. */
      uint32_t byte_rate   = reader.ReadDword();
      uint16_t block_align = reader.ReadWord();

      this->bits_per_sample = reader.ReadWord();
      if (this->bits_per_sample != 8 && this->bits_per_sample != 16) throw "Unexpected number of bits per channel; expected 8 or 16 in " + reader.GetFilename();

      if (byte_rate != this->sample_rate * this->num_channels * this->bits_per_sample / 8) throw "Unexpected byte rate in " + reader.GetFilename();
      if (block_align != this->num_channels * this->bits_per_sample / 8) throw "Unexpected block align in " + reader.GetFilename();

      if (reader.ReadDword() != 'atad') throw "Unexpected chunk; expected \"data\" in " + reader.GetFilename();

      /* Sometimes the files are padded, which causes them to start at the
       * wrong offset further on, so just read whatever amount of data was
       * specified in the top RIFF as long as sample size is within those
       * boundaries, i.e. within the RIFF. */
      this->sample_size = reader.ReadDword();
      if (this->sample_size + RIFF_HEADER_SIZE > size) throw "Unexpected data chunk size in " + reader.GetFilename();

      this->sample_data = (uint8_t *)malloc(this->size - RIFF_HEADER_SIZE);
      reader.ReadRaw(this->sample_data, this->size - RIFF_HEADER_SIZE);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index