home *** CD-ROM | disk | FTP | other *** search
/ Game Audio Programming / GameAudioProgramming.iso / Game_Audio / audio_sdk / src / AudioLib / Wave.cpp < prev    next >
C/C++ Source or Header  |  2002-07-15  |  18KB  |  607 lines

  1. /***********************************************************\
  2. Copyright (C) James Boer, 2002. 
  3. All rights reserved worldwide.
  4.  
  5. This software is provided "as is" without express or implied
  6. warranties. You may freely copy and compile this source into
  7. applications you distribute provided that the copyright text
  8. below is included in the resulting source code, for example:
  9. "Portions Copyright (C) James Boer, 2002"
  10. \***********************************************************/
  11.  
  12. #include "Audio.h"
  13. #include "Wave.h"
  14.  
  15. using namespace std;
  16. using namespace Audio;
  17.  
  18. IMPLEMENT_POOL(Wave);
  19.  
  20.  
  21.  
  22. LRESULT CALLBACK CustomMMIOProc(
  23.   LPSTR lpmmioinfo,  
  24.   UINT uMsg,         
  25.   LONG lParam1,      
  26.   LONG lParam2       
  27. )
  28. {
  29.  
  30.     char cBuffer[MAX_PATH];
  31.  
  32.     LRESULT ret = 0;
  33.  
  34.     MMIOINFO* pMMIOINFO = (MMIOINFO*)lpmmioinfo;
  35.     IAudioStream* pStream = (IAudioStream*)pMMIOINFO->adwInfo[0];
  36.  
  37.     switch(uMsg)
  38.     {
  39.     case MMIOM_OPEN:
  40.         {
  41.             strcpy(cBuffer, (char*)lParam1);
  42.             cBuffer[strlen(cBuffer) - 1] = 0;
  43.             if(!AudioMgr()->CreateAudioStream(pStream))
  44.                 return MMIOERR_CANNOTOPEN;
  45.             if(FAILED(pStream->Open(cBuffer)))
  46.                 return MMIOERR_CANNOTOPEN;
  47.             pMMIOINFO->adwInfo[0] = (DWORD)pStream;
  48.         }
  49.         break;
  50.     case MMIOM_SEEK:
  51.         {
  52.             if(!pStream)
  53.                 return 0;
  54.             ULARGE_INTEGER lnNewPos;
  55.             LARGE_INTEGER liSeek;
  56.             liSeek.QuadPart = lParam1;
  57.             pStream->Seek(liSeek, lParam2, &lnNewPos);
  58.             pMMIOINFO->lDiskOffset = (DWORD)lnNewPos.QuadPart;
  59.         }
  60.         break;
  61.     case MMIOM_READ:
  62.         {
  63.             if(!pStream)
  64.                 return 0;
  65.             uint32 nRead;
  66.             pStream->Read((void*)lParam1, lParam2, &nRead);
  67.             pMMIOINFO->lDiskOffset += nRead;
  68.             return nRead;
  69.         }
  70.     case MMIOM_CLOSE:
  71.         {
  72.             pMMIOINFO->lDiskOffset = 0;
  73.             pMMIOINFO->adwInfo[0] = 0;
  74.             SAFE_RELEASE(pStream);
  75.         }
  76.         break;
  77.     };
  78.  
  79.     return ret;
  80. }
  81.  
  82.  
  83.  
  84. uint32 Wave::s_nWaveCount = 0;
  85.  
  86. // Constant value to overestimate decompression buffer size
  87. const uint32 ACM_BUFFER_OVERESTIMATE = 2048;
  88.  
  89. //------------------------------------------------------------------------//
  90. // Constructs the class.  Call Open() to open a wave file for reading.  
  91. // Then call Read() as needed.  Calling the destructor or Close() 
  92. // will close the file.  
  93. Wave::Wave()
  94. {
  95.     memset(&m_ck, 0, sizeof(MMCKINFO));
  96.     memset(&m_ckRiff, 0, sizeof(MMCKINFO));
  97.     m_pwfx    = NULL;
  98.     m_hmmio   = NULL;
  99.     m_dwSize  = 0;
  100.     m_bEOF = false;
  101.     memset(&m_DestFormat, 0, sizeof(WAVEFORMATEX));
  102.     m_hACMStream = 0;
  103.     m_pCompressBuffer = 0;
  104.     m_nCompressBufferSize = 0;
  105.     m_pDecompressBuffer = 0;
  106.     m_nDecompressStart = 0;
  107.     m_nDecompressEnd = 0;
  108.     m_nDecompressBufferSize = 0;
  109. }
  110.  
  111. //------------------------------------------------------------------------//
  112. // Destructs the class
  113. Wave::~Wave()
  114. {
  115.     if(!s_nWaveCount)
  116.         mmioInstallIOProc(mmioFOURCC('W', 'A', 'V', ' '), 0, MMIO_REMOVEPROC);
  117.     Close();
  118.     SAFE_DELETE_ARRAY(m_pCompressBuffer);
  119.     m_nCompressBufferSize = 0;
  120.     SAFE_DELETE_ARRAY(m_pDecompressBuffer);
  121.     m_nDecompressBufferSize = 0;
  122. }
  123.  
  124.  
  125. //------------------------------------------------------------------------//
  126. // Opens a wave file for reading from an IAudioStream system
  127. bool Wave::Open(string sFileName)
  128. {
  129.     if(!s_nWaveCount)
  130.     {
  131.         if(!mmioInstallIOProc(mmioFOURCC('W', 'A', 'V', ' '), &CustomMMIOProc, MMIO_INSTALLPROC))
  132.             return false;
  133.     }
  134.     sFileName += "+";
  135.     // Open the wave file using the installed io procedure function
  136.     m_hmmio = mmioOpen((char*)sFileName.c_str(), NULL, MMIO_ALLOCBUF | MMIO_READ);
  137.  
  138.     s_nWaveCount++;
  139.  
  140.     return OpenMMIO();
  141. }
  142.  
  143. //------------------------------------------------------------------------//
  144. // Open a wave file format from a memory buffer
  145. bool Wave::Open( BYTE* pbData, uint32 dwDataSize)
  146. {
  147.     // Indicate to read from a memory buffer
  148.     MMIOINFO mmioInfo;
  149.     ZeroMemory( &mmioInfo, sizeof(mmioInfo) );
  150.     mmioInfo.fccIOProc = FOURCC_MEM;
  151.     mmioInfo.cchBuffer = dwDataSize;
  152.     mmioInfo.pchBuffer = (CHAR*) pbData;
  153.  
  154.     // Open the memory buffer
  155.     m_hmmio = mmioOpen(NULL, &mmioInfo, MMIO_READ);
  156.  
  157.     s_nWaveCount++;
  158.     return OpenMMIO();
  159. }
  160.  
  161. //------------------------------------------------------------------------//
  162. bool Wave::OpenMMIO()
  163. {
  164.     // Read the wave header file
  165.     if(!ReadMMIO())
  166.     {
  167.         // ReadMMIO will fail if its an not a wave file
  168.         mmioClose(m_hmmio, 0);
  169.         return Error::Handle("Wave Error: ReadMMIO");
  170.     }
  171.  
  172.     // Reset the file to prepare for reading
  173.     if(!Reset())
  174.     {
  175.         mmioClose(m_hmmio, 0);
  176.         return Error::Handle("Wave Error: Reset");
  177.     }
  178.  
  179.     // Set (or estimate) the size of the decompressed wave data
  180.     if(m_hACMStream)
  181.     {
  182.         MMRESULT error = acmStreamSize(m_hACMStream, m_ck.cksize, &m_dwSize, 
  183.             ACM_STREAMSIZEF_SOURCE);
  184.         if(error)
  185.             return Error::Handle("Could not estimate size for non-PCM data conversion");
  186.     }
  187.     else
  188.     {
  189.         m_dwSize = m_ck.cksize;
  190.     }
  191.     return true;
  192. }
  193.  
  194.  
  195. //------------------------------------------------------------------------//
  196. // Verifies that this is a wave file, and allocates and 
  197. // fills out the wave format header structure.
  198. bool Wave::ReadMMIO()
  199. {
  200.     // chunk info. for general use.
  201.     MMCKINFO        ckIn;   
  202.     // Temp PCM structure to load in.
  203.     PCMWAVEFORMAT   pcmWaveFormat;         
  204.  
  205.     // Make sure this structure has been deallocated
  206.     SAFE_DELETE_ARRAY(m_pwfx);
  207.  
  208.     if(mmioSeek( m_hmmio, 0, SEEK_SET ) == -1)
  209.         return false;
  210.  
  211.     if( ( 0 != mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) ) )
  212.         return Error::Handle("Wave Error: mmioDescend");
  213.  
  214.     // Check to make sure this is a valid wave file
  215.     if( (m_ckRiff.ckid != FOURCC_RIFF) ||
  216.         (m_ckRiff.fccType != mmioFOURCC('W', 'A', 'V', 'E') ) )
  217.         return Error::Handle("Wave Error: mmioFOURCC"); 
  218.  
  219.     // Search the input file for for the 'fmt ' chunk.
  220.     ckIn.ckid = mmioFOURCC('f', 'm', 't', ' ');
  221.     if( 0 != mmioDescend( m_hmmio, &ckIn, &m_ckRiff, MMIO_FINDCHUNK ) )
  222.         return Error::Handle("Wave Error: mmioDescend");
  223.  
  224.     // Expect the 'fmt' chunk to be at least as large as <PCMWAVEFORMAT>;
  225.     // if there are extra parameters at the end, we'll ignore them
  226.     if( ckIn.cksize < (LONG) sizeof(PCMWAVEFORMAT) )
  227.         return Error::Handle("Wave Error: sizeof(PCMWAVEFORMAT)");
  228.  
  229.     // Read the 'fmt ' chunk into <pcmWaveFormat>.
  230.     if( mmioRead( m_hmmio, (HPSTR) &pcmWaveFormat, 
  231.         sizeof(pcmWaveFormat)) != sizeof(pcmWaveFormat) )
  232.         return Error::Handle("Wave Error: mmioRead");
  233.  
  234.     // Allocate the waveformatex, but if its not pcm format, read the next
  235.     // word, and thats how many extra bytes to allocate.
  236.     if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM )
  237.     {
  238.         memcpy(&m_DestFormat, &pcmWaveFormat, sizeof(pcmWaveFormat) );
  239.         m_DestFormat.cbSize = 0;
  240.     }
  241.     else
  242.     {
  243.         // Read in length of extra bytes.
  244.         WORD cbExtraBytes = 0L;
  245.         if( mmioRead( m_hmmio, (CHAR*)&cbExtraBytes, sizeof(WORD)) != sizeof(WORD) )
  246.             return Error::Handle("Wave Error: mmioRead");
  247.  
  248.         m_pwfx = (WAVEFORMATEX*)new CHAR[ sizeof(WAVEFORMATEX) + cbExtraBytes ];
  249.         if( NULL == m_pwfx )
  250.             return Error::Handle("Wave Error: new");
  251.  
  252.         // Copy the bytes from the pcm structure to the waveformatex structure
  253.         memcpy( m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat) );
  254.         m_pwfx->cbSize = cbExtraBytes;
  255.  
  256.         // Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
  257.         if( mmioRead( m_hmmio, (CHAR*)(((BYTE*)&(m_pwfx->cbSize))+sizeof(WORD)),
  258.             cbExtraBytes ) != cbExtraBytes )
  259.         {
  260.             SAFE_DELETE( m_pwfx );
  261.             return Error::Handle("Wave Error: mmioRead");
  262.         }
  263.  
  264.         // Since this is a non PCM format, we must retrieve an appropriate
  265.         // PCM format to convert to.
  266.         ZeroMemory(&m_DestFormat, sizeof(WAVEFORMATEX));
  267.         m_DestFormat.wFormatTag = WAVE_FORMAT_PCM;   
  268.         
  269.         MMRESULT error = acmFormatSuggest(NULL, m_pwfx, &m_DestFormat, 16, 
  270.             ACM_FORMATSUGGESTF_WFORMATTAG);
  271.         if(error)
  272.             return Error::Handle("Could not suggest PCM format to convert to");
  273.  
  274.         error = acmStreamOpen(&m_hACMStream, NULL, m_pwfx, &m_DestFormat,
  275.             NULL, 0, 0, 0);
  276.         if(error)
  277.             return Error::Handle("Could not open format conversion stream");
  278.  
  279.     }
  280.  
  281.     // Ascend the input file out of the 'fmt ' chunk.
  282.     if( 0 != mmioAscend( m_hmmio, &ckIn, 0 ) )
  283.     {
  284.         SAFE_DELETE( m_pwfx );
  285.         return Error::Handle("Wave Error: mmioAscend");
  286.     }
  287.  
  288.     return true;
  289. }
  290.  
  291.  
  292. //------------------------------------------------------------------------//
  293. // Resets the internal m_ck pointer so reading starts from the 
  294. // beginning of the file again 
  295. bool Wave::Reset()
  296. {
  297.     m_bEOF = false;
  298.  
  299.     if( m_hmmio == NULL )
  300.         return false;
  301.  
  302.     // Seek to the data
  303.     if( -1 == mmioSeek( m_hmmio, m_ckRiff.dwDataOffset + sizeof(FOURCC),
  304.         SEEK_SET ) )
  305.         return Error::Handle("Wave Error: mmioSeek");
  306.  
  307.     // Search the input file for the 'data' chunk.
  308.     m_ck.ckid = mmioFOURCC('d', 'a', 't', 'a');
  309.     if( 0 != mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) )
  310.         return Error::Handle("Wave Error: mmioDescend");
  311.     
  312.     // Reset the pointers in the decompression buffer
  313.     m_nDecompressStart = 0;
  314.     m_nDecompressEnd = 0;
  315.  
  316.     return true;
  317. }
  318.  
  319.  
  320. //------------------------------------------------------------------------//
  321. // Reads section of data from a wave file into pBuffer and returns 
  322. // how much read in pdwSizeRead, reading not more than dwSizeToRead.
  323. // This uses m_ck to determine where to start reading from.  So 
  324. // subsequent calls will be continue where the last left off unless 
  325. // Reset() is called.
  326. bool Wave::Read( BYTE* pDestBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead )
  327. {
  328.     MMIOINFO mmioinfoIn; // current status of m_hmmio
  329.  
  330.     if( m_hmmio == NULL )
  331.         return false;
  332.     if( pDestBuffer == NULL || pdwSizeRead == NULL )
  333.         return false;
  334.  
  335.     if( pdwSizeRead != NULL )
  336.         *pdwSizeRead = 0;
  337.  
  338.     if( 0 != mmioGetInfo( m_hmmio, &mmioinfoIn, 0 ) )
  339.         return Error::Handle("Wave Error: mmioGetInfo");
  340.      
  341.     // Data member specifying how many bytes to actually
  342.     // read out of the wave file.
  343.     uint32 nDataIn = 0;
  344.     BYTE* pWaveBuffer = 0;
  345.     uint32 nStreamRead = 0;
  346.  
  347.     // If we're decompressing this data... (ignore if using PCM)
  348.     if(m_hACMStream)
  349.     {
  350.         // Prepare the ACM buffers for decompression
  351.         if(!PrepareACMBuffers(nDataIn, nStreamRead, dwSizeToRead))
  352.             return false;
  353.  
  354.         // Use the oversized compression buffer to read the source
  355.         // before sending it to the decompression routines.
  356.         pWaveBuffer = m_pCompressBuffer;
  357.     }
  358.     else
  359.     {
  360.         // If we're not decompressing data, we can directly 
  361.         // use the buffer passed in to this function.
  362.         pWaveBuffer = pDestBuffer;
  363.         nDataIn = dwSizeToRead;
  364.     }
  365.  
  366.  
  367.     // Begin reading from the actual wave data
  368.     if( nDataIn > m_ck.cksize ) 
  369.         nDataIn = m_ck.cksize;  
  370.     m_ck.cksize -= nDataIn;
  371.  
  372. /*
  373.     // Should do a comparison test to see if the new
  374.     // reader is faster than a byte-by-byte copy.
  375.     // For now, I'm assuming it probably is by a
  376.     // small degree.
  377.     for( DWORD cT = 0; cT < nDataIn; cT++ )
  378.     {
  379.         // Copy the bytes from the io to the buffer.
  380.         if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
  381.         {
  382.             if( 0 != mmioAdvance( m_hmmio, &mmioinfoIn, MMIO_READ ) )
  383.                 return Error::Handle("Wave Error: mmioAdvance");
  384.  
  385.             if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
  386.                 return Error::Handle("Wave Error: mmioinfoIn.pchNext");
  387.         }
  388.  
  389.         // Actual copy.
  390.         *((BYTE*)pWaveBuffer+cT) = *((BYTE*)mmioinfoIn.pchNext);
  391.         mmioinfoIn.pchNext++;
  392.     }
  393. */
  394.  
  395.     uint32 nRead = 0;
  396.     uint32 nCopySize;
  397.     while(nRead < nDataIn)
  398.     {
  399.         // Copy the bytes from the io to the buffer.
  400.         if (0 != mmioAdvance(m_hmmio, &mmioinfoIn, MMIO_READ))
  401.             return Error::Handle("Wave Error: mmioAdvance");
  402.  
  403.         if (mmioinfoIn.pchNext == mmioinfoIn.pchEndRead)
  404.             return Error::Handle("Wave Error: mmioinfoIn.pchNext");
  405.  
  406.         // Actual copy.
  407.         nCopySize = mmioinfoIn.pchEndRead -  mmioinfoIn.pchNext;
  408.         nCopySize = ClampMax<uint32>(nCopySize, nDataIn - nRead);
  409.         memcpy(pWaveBuffer + nRead, mmioinfoIn.pchNext, nCopySize);
  410.         nRead += nCopySize;
  411.         mmioinfoIn.pchNext += nCopySize;
  412.     }
  413.  
  414.     if( 0 != mmioSetInfo( m_hmmio, &mmioinfoIn, 0 ) )
  415.         return Error::Handle("Wave Error: mmioSetInfo");
  416.  
  417.     // Report the number of bytes read
  418.     if( pdwSizeRead != NULL)
  419.         *pdwSizeRead = nDataIn;
  420.  
  421.     // Check to see if we hit the end of the file
  422.     if(m_ck.cksize == 0)
  423.         m_bEOF = true;
  424.  
  425.     // Convert to a PCM format if required
  426.     if(m_hACMStream)
  427.     {
  428.         // Decompress the wave data stored in the compress buffer
  429.         if(!DecompressData(nDataIn, pDestBuffer, dwSizeToRead, pdwSizeRead))
  430.             return false;
  431.     }
  432.  
  433.     return true;
  434. }
  435.  
  436.  
  437. //------------------------------------------------------------------------//
  438. bool Wave::PrepareACMBuffers(uint32& nDataIn, uint32& nStreamRead, uint32 dwSizeToRead)
  439. {
  440.     // This is where we overestimate by a specified amount.  Note
  441.     // that we reduce the overestimation by the amount of valid
  442.     // data left over in the decompression buffer from the last
  443.     // call to this function.
  444.     nStreamRead = dwSizeToRead + ACM_BUFFER_OVERESTIMATE - 
  445.         (m_nDecompressEnd - m_nDecompressStart);
  446.     nStreamRead = ClampMin<int>(nStreamRead, ACM_BUFFER_OVERESTIMATE);
  447.  
  448.     // Use acmStreamSize to get a rough estimate of how much data we
  449.     // should read from the wave file to decompress to fill at
  450.     // least dwSizeToRead bytes.  cbDataIn should end up slightly
  451.     // more than dwSizeToRead.
  452.     MMRESULT error = acmStreamSize(m_hACMStream, nStreamRead, &nDataIn, 
  453.         ACM_STREAMSIZEF_DESTINATION);
  454.     int iErrorCount = 0;
  455.     while(error)
  456.     {
  457.         // acmStreamSize cannot estimate below certain minimum sizes,
  458.         // so we attempt to increase the minimum estimation until
  459.         // we either succeed or fail 10 times.
  460.         nStreamRead += ACM_BUFFER_OVERESTIMATE;
  461.         DebugOut(5, "acmStreamSize() failed.  Resizing estimated buffer to %u", nStreamRead);
  462.         error = acmStreamSize(m_hACMStream, nStreamRead, &nDataIn, 
  463.             ACM_STREAMSIZEF_DESTINATION);
  464.         iErrorCount++;
  465.         if(iErrorCount > 10)
  466.             return Error::Handle("Could not estimate compressed stream data");
  467.     }
  468.  
  469.     // Check to see if we need to grow the conversion buffer
  470.     if(nStreamRead > m_nDecompressBufferSize)
  471.     {
  472.         uint8* pTempBuffer = new BYTE[nStreamRead];
  473.         DebugOut(1, "Allocating new buffer size of size %d", nStreamRead);
  474.         // Copy any valid data into the beginning of the new buffer if
  475.         // there is any valid data there
  476.         if(m_nDecompressStart != m_nDecompressEnd)
  477.             memcpy(pTempBuffer, m_pDecompressBuffer + m_nDecompressStart, 
  478.                 m_nDecompressEnd - m_nDecompressStart);
  479.         m_nDecompressBufferSize = nStreamRead;
  480.         SAFE_DELETE_ARRAY(m_pDecompressBuffer);
  481.         m_pDecompressBuffer = pTempBuffer;
  482.     }
  483.     else
  484.     {
  485.         // Otherwise, just move any "leftover" data back 
  486.         // to the beginning of the buffer.
  487.         memmove(m_pDecompressBuffer, m_pDecompressBuffer + 
  488.             m_nDecompressStart, m_nDecompressEnd - m_nDecompressStart);
  489.     }
  490.     // Reset the data markers
  491.     m_nDecompressEnd = m_nDecompressEnd - m_nDecompressStart;
  492.     m_nDecompressStart = 0;
  493.     
  494.     // Now, if needed, create (or recreate) our compressed buffer, 
  495.     // which is larger than the actual destination size.
  496.     if(m_nCompressBufferSize < nDataIn)
  497.     {
  498.         SAFE_DELETE_ARRAY(m_pCompressBuffer);
  499.         m_pCompressBuffer = new uint8[nStreamRead];
  500.         m_nCompressBufferSize = nDataIn;
  501.     }
  502.  
  503.     return true;
  504. }
  505.  
  506.  
  507. //------------------------------------------------------------------------//
  508. bool Wave::DecompressData(uint32 nDataIn, BYTE* pDestBuffer, 
  509.     uint32 dwSizeToRead, DWORD* pdwSizeRead)
  510. {
  511.     // Prepare the converstion data
  512.     ACMSTREAMHEADER StreamHeader;
  513.     memset(&StreamHeader, 0, sizeof(ACMSTREAMHEADER));
  514.     StreamHeader.cbStruct = sizeof(ACMSTREAMHEADER);
  515.     StreamHeader.pbSrc = m_pCompressBuffer;
  516.     StreamHeader.cbSrcLength = nDataIn;
  517.     StreamHeader.pbDst = m_pDecompressBuffer + m_nDecompressEnd;
  518.     StreamHeader.cbDstLength = m_nDecompressBufferSize - m_nDecompressEnd;
  519.     MMRESULT error = acmStreamPrepareHeader(m_hACMStream, &StreamHeader, 0);
  520.     if(error)
  521.         // Signal an error, but go on anyway
  522.         Error::Handle("Could not prepare wave format conversion stream header");
  523.  
  524.     // Do the actual non-PCM to PCM data conversion
  525.     if(!error)
  526.     {
  527.         error = acmStreamConvert(m_hACMStream, &StreamHeader, 
  528.             ACM_STREAMCONVERTF_START | ACM_STREAMCONVERTF_END |
  529.             ACM_STREAMCONVERTF_BLOCKALIGN);
  530.         if(error)
  531.             return Error::Handle("Error converting non-PCM data to PCM format");
  532.     }
  533.  
  534.     // Add the number of bytes read to the "valid content" 
  535.     // markers in the uncompressed buffer
  536.     m_nDecompressEnd += StreamHeader.cbDstLengthUsed;
  537.  
  538.     // Determine how much data we can actually copy
  539.     uint32 nDataToCopy;
  540.     if((m_nDecompressEnd - m_nDecompressStart) < dwSizeToRead)
  541.         nDataToCopy = m_nDecompressEnd - m_nDecompressStart;
  542.     else
  543.         nDataToCopy = dwSizeToRead;
  544.  
  545.     // Copy the decompressed data from our oversized buffer to the
  546.     memcpy(pDestBuffer, m_pDecompressBuffer, nDataToCopy);
  547.     
  548.     // Record how many bytes were actually read
  549.     if( pdwSizeRead != NULL)
  550.         *pdwSizeRead = nDataToCopy;
  551.  
  552.     // Advance the start of the valid data pointer by the 
  553.     // amount of data copied
  554.     m_nDecompressStart += nDataToCopy;
  555.     
  556.     // Clean up any internal conversion data
  557.     if(!error)
  558.     {
  559.         error = acmStreamUnprepareHeader(m_hACMStream, &StreamHeader, 0);
  560.         if(error)
  561.             return Error::Handle("Error in cleaning up non-PCM conversion data");
  562.     }
  563.  
  564.     return true;
  565. }
  566.  
  567.  
  568. //------------------------------------------------------------------------//
  569. // Closes the wave file 
  570. bool Wave::Close()
  571. {
  572.     mmioClose( m_hmmio, 0 );
  573.     m_hmmio = NULL;
  574.     SAFE_DELETE_ARRAY(m_pwfx);
  575.     m_dwSize  = 0;
  576.     m_bEOF = false;
  577.  
  578.     m_nDecompressStart = 0;
  579.     m_nDecompressEnd = 0;
  580.  
  581.     s_nWaveCount--;
  582.  
  583.     return true;
  584. }
  585.  
  586.  
  587. //------------------------------------------------------------------------//
  588. void Wave::Destroy()
  589. {
  590.     Close();
  591.     Wave::DestroyObject(this);
  592. }
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.