TWaveReader.cpp
上传用户:anhe341234
上传日期:2021-04-11
资源大小:398k
文件大小:5k
源码类别:

Windows编程

开发平台:

Visual C++

  1. //---------------------------------------------------------------------------
  2. #pragma hdrstop
  3. #include "TWaveReader.h"
  4. #pragma package(smart_init)
  5. //---------------------------------------------------------------------------
  6. namespace AudioReader
  7. {
  8. TWaveReader::TWaveReader(const char* filename)
  9. {
  10.   my_filename = new char[lstrlen(filename)+1];
  11.   lstrcpy(my_filename,filename);
  12.   
  13.   hfile = mmioOpen(const_cast<char *>(filename),NULL,MMIO_READ);
  14.   if(!hfile)
  15.     throw(ErrCannotOpen);
  16.   if(RIFFGetWaveFormat(wf))
  17.   {
  18.     if (wf.wFormatTag != WAVE_FORMAT_PCM || wf.nChannels != 2
  19.                 || wf.wBitsPerSample != 16)
  20.       throw(ErrFormatNotSupported);
  21.   }
  22.   else
  23.     throw(ErrBadFile);
  24. }
  25. //---------------------------------------------------------------------------
  26. TWaveReader* TWaveReader::MakeCopy()
  27. {
  28.   return new TWaveReader(my_filename);
  29. }
  30. //---------------------------------------------------------------------------
  31. TWaveReader::~TWaveReader()
  32. {
  33.  if(hfile) mmioClose(hfile,0);
  34. }
  35. //---------------------------------------------------------------------------
  36. __int64 TWaveReader::Seek(__int64 SamplePos)
  37. {
  38.   //SamplePos <<= 2; //Bytes per channel*channels per sample
  39.   IsEof = SamplePos > GetLength() || RIFFSetStartPoint((DWORD) SamplePos*4);
  40.   return SamplePos; 
  41. }
  42. //---------------------------------------------------------------------------
  43. bool TWaveReader::RIFFGetWaveFormat(WAVEFORMATEX& wf)
  44. {
  45.   MMCKINFO mmckinfoParent;
  46.   MMCKINFO mmckinfoSubchunk;
  47.   mmioSeek(hfile,0,SEEK_SET);
  48.   // Locate a "RIFF" chunk with a "WAVE" form type to make
  49.   // sure the file is a waveform-audio file.
  50.   mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
  51.   if (mmioDescend(hfile, &mmckinfoParent, NULL, MMIO_FINDRIFF) == MMSYSERR_NOERROR)
  52.   {
  53.     // Find the format chunk (form type "FMT"); it should be
  54.     // a subchunk of the "RIFF" parent chunk.
  55.     mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
  56.     if (mmioDescend(hfile, &mmckinfoSubchunk, &mmckinfoParent,
  57.         MMIO_FINDCHUNK) == MMSYSERR_NOERROR)
  58.     {
  59.        if (mmioRead(hfile, (HPSTR) &wf, sizeof(WAVEFORMATEX)) !=
  60.            sizeof(WAVEFORMATEX))
  61.          return false;
  62.        //mmioAscend(hfile,NULL,0);
  63.        return true;
  64.     }
  65.     else
  66.         return false;
  67.   }
  68.   else
  69.       return false;
  70. }
  71. //---------------------------------------------------------------------------
  72. DWORD TWaveReader::RIFFGetWaveDataSize() //also positions file pointer to beginning
  73.                                         //of data stream
  74. {
  75.   MMCKINFO mmckinfoParent;
  76.   MMCKINFO mmckinfoSubchunk;
  77.   mmioSeek(hfile,0,SEEK_SET);
  78.   // Locate a "RIFF" chunk with a "WAVE" form type to make
  79.   // sure the file is a waveform-audio file.
  80.   mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
  81.   if (mmioDescend(hfile, &mmckinfoParent, NULL, MMIO_FINDRIFF) == MMSYSERR_NOERROR)
  82.   {
  83.     // Find the format chunk (form type "FMT"); it should be
  84.     // a subchunk of the "RIFF" parent chunk.
  85.     mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
  86.     if (mmioDescend(hfile, &mmckinfoSubchunk, &mmckinfoParent,
  87.         MMIO_FINDCHUNK) == MMSYSERR_NOERROR)
  88.     {
  89.         return mmckinfoSubchunk.cksize;
  90.     }
  91.     else
  92.         return 0;
  93.   }
  94.   else
  95.       return 0;
  96. }
  97. //---------------------------------------------------------------------------
  98. bool TWaveReader::RIFFSetStartPoint(int ByteOffset)
  99. {
  100.   MMCKINFO mmckinfoParent;
  101.   MMCKINFO mmckinfoSubchunk;
  102.   mmioSeek(hfile,0,SEEK_SET);
  103.   // Locate a "RIFF" chunk with a "WAVE" form type to make
  104.   // sure the file is a waveform-audio file.
  105.   mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
  106.   if (mmioDescend(hfile, &mmckinfoParent, NULL, MMIO_FINDRIFF) == MMSYSERR_NOERROR)
  107.   {
  108.     // Find the data chunk (form type "data"); it should be
  109.     // a subchunk of the "RIFF" parent chunk.
  110.     mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
  111.     if (mmioDescend(hfile, &mmckinfoSubchunk, &mmckinfoParent,
  112.         MMIO_FINDCHUNK) == MMSYSERR_NOERROR)
  113.     {
  114.        return mmioSeek(hfile, ByteOffset, SEEK_CUR ) == -1;
  115.     }
  116.     else
  117.         return 0;
  118.   }
  119.   else
  120.       return 0;
  121. }
  122. //---------------------------------------------------------------------------
  123. int TWaveReader::FillBuffer(Buffer& buffer, int numsamplesrequested)
  124. {
  125.         //int distance =  buffer.data.end() - buffer.data.begin();
  126.         
  127.         //Convert from samples to 16 bit stereo audio
  128.         unsigned int numbytes = numsamplesrequested<<2;
  129.         char* readbuffer = new char[numbytes];
  130.         unsigned int cbRead = mmioRead(hfile,readbuffer,numbytes);
  131.         //buffer.data.resize(buffer.data.size() + numbytes,0);
  132.         buffer.data.insert(buffer.data.end(),readbuffer,readbuffer+numbytes);
  133.         delete[] readbuffer;
  134.         if(cbRead<numbytes) IsEof = true;
  135.         
  136.         return cbRead>>2;
  137. }
  138. //---------------------------------------------------------------------------
  139. }//namespace AudioReader