WAVE.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:24k
源码类别:
Windows编程
开发平台:
Visual C++
- /*==========================================================================
- *
- * Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
- *
- * File: wave.c
- * Content: Wave library routines.
- * This file is used for loading/saving waves, and reading and
- * writing waves in smaller blocks.
- * Uses WaveOpenFile, WaveReadFile and WaveCloseReadFile for
- * single block access to reading wave files.
- * Uses WaveCreateFile, WaveWriteFile, WaveCloseWriteFile for
- * single block access for writing wave files.
- * Uses WaveLoadFile to load a whole wave file into memory.
- * Uses WaveSaveFile to save a whole wave file into memory.
- *
- ***************************************************************************/
- /* PROTOTYPES */
- #include <windows.h>
- #include <mmsystem.h>
- #include "wave.h"
- #include "wassert.h"
- #include "windowsx.h"
- /* ROUTINES */
- /* -------------------------------------------------------*/
- /* This function will open a wave input file and prepare it for reading,
- * so the data can be easily
- * read with WaveReadFile. Returns 0 if successful, the error code if not.
- * pszFileName - Input filename to load.
- * phmmioIn - Pointer to handle which will be used
- * for further mmio routines.
- * ppwfxInfo - Ptr to ptr to WaveFormatEx structure
- * with all info about the file.
- *
- */
- int WaveOpenFile(
- char *pszFileName, // (IN)
- HMMIO *phmmioIn, // (OUT)
- WAVEFORMATEX **ppwfxInfo, // (OUT)
- MMCKINFO *pckInRIFF // (OUT)
- )
- {
- HMMIO hmmioIn;
- MMCKINFO ckIn; // chunk info. for general use.
- PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in.
- WORD cbExtraAlloc; // Extra bytes for waveformatex
- int nError; // Return value.
- // Initialization...
- *ppwfxInfo = NULL;
- nError = 0;
- hmmioIn = NULL;
- if ((hmmioIn = mmioOpen(pszFileName, NULL, MMIO_ALLOCBUF | MMIO_READ)) == NULL)
- {
- nError = ER_CANNOTOPEN;
- goto ERROR_READING_WAVE;
- }
- if ((nError = (int)mmioDescend(hmmioIn, pckInRIFF, NULL, 0)) != 0)
- {
- goto ERROR_READING_WAVE;
- }
- if ((pckInRIFF->ckid != FOURCC_RIFF) || (pckInRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E')))
- {
- nError = ER_NOTWAVEFILE;
- goto ERROR_READING_WAVE;
- }
- /* Search the input file for for the 'fmt ' chunk. */
- ckIn.ckid = mmioFOURCC('f', 'm', 't', ' ');
- if ((nError = (int)mmioDescend(hmmioIn, &ckIn, pckInRIFF, MMIO_FINDCHUNK)) != 0)
- {
- goto ERROR_READING_WAVE;
- }
- /* Expect the 'fmt' chunk to be at least as large as <PCMWAVEFORMAT>;
- * if there are extra parameters at the end, we'll ignore them */
- if (ckIn.cksize < (long) sizeof(PCMWAVEFORMAT))
- {
- nError = ER_NOTWAVEFILE;
- goto ERROR_READING_WAVE;
- }
- /* Read the 'fmt ' chunk into <pcmWaveFormat>.*/
- if (mmioRead(hmmioIn, (HPSTR) &pcmWaveFormat, (long) sizeof(pcmWaveFormat)) != (long) sizeof(pcmWaveFormat))
- {
- nError = ER_CANNOTREAD;
- goto ERROR_READING_WAVE;
- }
- // Ok, allocate the waveformatex, but if its not pcm
- // format, read the next word, and thats how many extra
- // bytes to allocate.
- if (pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM)
- cbExtraAlloc = 0;
- else
- {
- // Read in length of extra bytes.
- if (mmioRead(hmmioIn, (LPSTR) &cbExtraAlloc,
- (long) sizeof(cbExtraAlloc)) != (long) sizeof(cbExtraAlloc))
- {
- nError = ER_CANNOTREAD;
- goto ERROR_READING_WAVE;
- }
- }
- // Ok, now allocate that waveformatex structure.
- if ((*ppwfxInfo = GlobalAlloc(GMEM_FIXED, sizeof(WAVEFORMATEX)+cbExtraAlloc)) == NULL)
- {
- nError = ER_MEM;
- goto ERROR_READING_WAVE;
- }
- // Copy the bytes from the pcm structure to the waveformatex structure
- memcpy(*ppwfxInfo, &pcmWaveFormat, sizeof(pcmWaveFormat));
- (*ppwfxInfo)->cbSize = cbExtraAlloc;
- // Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
- if (cbExtraAlloc != 0)
- {
- if (mmioRead(hmmioIn, (LPSTR) (((BYTE*)&((*ppwfxInfo)->cbSize))+sizeof(cbExtraAlloc)),
- (long) (cbExtraAlloc)) != (long) (cbExtraAlloc))
- {
- nError = ER_NOTWAVEFILE;
- goto ERROR_READING_WAVE;
- }
- }
- /* Ascend the input file out of the 'fmt ' chunk. */
- if ((nError = mmioAscend(hmmioIn, &ckIn, 0)) != 0)
- {
- goto ERROR_READING_WAVE;
- }
- goto TEMPCLEANUP;
- ERROR_READING_WAVE:
- if (*ppwfxInfo != NULL)
- {
- GlobalFree(*ppwfxInfo);
- *ppwfxInfo = NULL;
- }
- if (hmmioIn != NULL)
- {
- mmioClose(hmmioIn, 0);
- hmmioIn = NULL;
- }
- TEMPCLEANUP:
- *phmmioIn = hmmioIn;
- return(nError);
- }
- /* This routine has to be called before WaveReadFile as it searchs for the chunk to descend into for
- reading, that is, the 'data' chunk. For simplicity, this used to be in the open routine, but was
- taken out and moved to a separate routine so there was more control on the chunks that are before
- the data chunk, such as 'fact', etc... */
- int WaveStartDataRead(
- HMMIO *phmmioIn,
- MMCKINFO *pckIn,
- MMCKINFO *pckInRIFF
- )
- {
- int nError;
- nError = 0;
- // Do a nice little seek...
- if ((nError = mmioSeek(*phmmioIn, pckInRIFF->dwDataOffset + sizeof(FOURCC), SEEK_SET)) == -1)
- {
- Assert(FALSE);
- }
- nError = 0;
- // Search the input file for for the 'data' chunk.
- pckIn->ckid = mmioFOURCC('d', 'a', 't', 'a');
- if ((nError = mmioDescend(*phmmioIn, pckIn, pckInRIFF, MMIO_FINDCHUNK)) != 0)
- {
- goto ERROR_READING_WAVE;
- }
- goto CLEANUP;
- ERROR_READING_WAVE:
- CLEANUP:
- return(nError);
- }
- /* This will read wave data from the wave file. Makre sure we're descended into
- the data chunk, else this will fail bigtime!
- hmmioIn - Handle to mmio.
- cbRead - # of bytes to read.
- pbDest - Destination buffer to put bytes.
- cbActualRead- # of bytes actually read.
- */
- int WaveReadFile(
- HMMIO hmmioIn, // IN
- UINT cbRead, // IN
- BYTE *pbDest, // IN
- MMCKINFO *pckIn, // IN.
- UINT *cbActualRead // OUT.
- )
- {
- MMIOINFO mmioinfoIn; // current status of <hmmioIn>
- int nError;
- UINT cT, cbDataIn;
- nError = 0;
- if (nError = mmioGetInfo(hmmioIn, &mmioinfoIn, 0) != 0)
- {
- goto ERROR_CANNOT_READ;
- }
- cbDataIn = cbRead;
- if (cbDataIn > pckIn->cksize)
- cbDataIn = pckIn->cksize;
- pckIn->cksize -= cbDataIn;
- for (cT = 0; cT < cbDataIn; cT++)
- {
- /* Copy the bytes from the io to the buffer. */
- if (mmioinfoIn.pchNext == mmioinfoIn.pchEndRead)
- {
- if ((nError = mmioAdvance(hmmioIn, &mmioinfoIn, MMIO_READ)) != 0)
- {
- goto ERROR_CANNOT_READ;
- }
- if (mmioinfoIn.pchNext == mmioinfoIn.pchEndRead)
- {
- nError = ER_CORRUPTWAVEFILE;
- goto ERROR_CANNOT_READ;
- }
- }
- // Actual copy.
- *((BYTE*)pbDest+cT) = *((BYTE*)mmioinfoIn.pchNext)++;
- }
- if ((nError = mmioSetInfo(hmmioIn, &mmioinfoIn, 0)) != 0)
- {
- goto ERROR_CANNOT_READ;
- }
- *cbActualRead = cbDataIn;
- goto FINISHED_READING;
- ERROR_CANNOT_READ:
- *cbActualRead = 0;
- FINISHED_READING:
- return(nError);
- }
- /* This will close the wave file openned with WaveOpenFile.
- phmmioIn - Pointer to the handle to input MMIO.
- ppwfxSrc - Pointer to pointer to WaveFormatEx structure.
- Returns 0 if successful, non-zero if there was a warning.
- */
- int WaveCloseReadFile(
- HMMIO *phmmio, // IN
- WAVEFORMATEX **ppwfxSrc // IN
- )
- {
- if (*ppwfxSrc != NULL)
- {
- GlobalFree(*ppwfxSrc);
- *ppwfxSrc = NULL;
- }
- if (*phmmio != NULL)
- {
- mmioClose(*phmmio, 0);
- *phmmio = NULL;
- }
- return(0);
- }
- /* This routine will create a wave file for writing. This will automatically overwrite any
- existing file with the same name, so be careful and check before hand!!!
- pszFileName - Pointer to filename to write.
- phmmioOut - Pointer to HMMIO handle that is used for further writes
- pwfxDest - Valid waveformatex destination structure.
- pckOut - Pointer to be set with the MMCKINFO.
- pckOutRIFF - Pointer to be set with the RIFF info.
- */
- int WaveCreateFile(
- char *pszFileName, // (IN)
- HMMIO *phmmioOut, // (OUT)
- WAVEFORMATEX *pwfxDest, // (IN)
- MMCKINFO *pckOut, // (OUT)
- MMCKINFO *pckOutRIFF // (OUT)
- )
- {
- int nError; // Return value.
- DWORD dwFactChunk; // Contains the actual fact chunk. Garbage until WaveCloseWriteFile.
- MMCKINFO ckOut1;
- dwFactChunk = (DWORD)-1;
- nError = 0;
- *phmmioOut = mmioOpen(pszFileName, NULL,
- MMIO_ALLOCBUF | MMIO_READWRITE|MMIO_CREATE);
- if (*phmmioOut == NULL)
- {
- nError = ER_CANNOTWRITE;
- goto ERROR_CANNOT_WRITE; // cannot save WAVE file
- }
- /* Create the output file RIFF chunk of form type 'WAVE'.
- */
- pckOutRIFF->fccType = mmioFOURCC('W', 'A', 'V', 'E');
- pckOutRIFF->cksize = 0;
- if ((nError = mmioCreateChunk(*phmmioOut, pckOutRIFF, MMIO_CREATERIFF)) != 0)
- {
- goto ERROR_CANNOT_WRITE; // cannot write file, probably
- }
- /* We are now descended into the 'RIFF' chunk we just created.
- * Now create the 'fmt ' chunk. Since we know the size of this chunk,
- * specify it in the MMCKINFO structure so MMIO doesn't have to seek
- * back and set the chunk size after ascending from the chunk.
- */
- pckOut->ckid = mmioFOURCC('f', 'm', 't', ' ');
- pckOut->cksize = sizeof(PCMWAVEFORMAT); // we know the size of this ck.
- if ((nError = mmioCreateChunk(*phmmioOut, pckOut, 0)) != 0)
- {
- goto ERROR_CANNOT_WRITE; // cannot write file, probably
- }
- /* Write the PCMWAVEFORMAT structure to the 'fmt ' chunk if its that type. */
- if (pwfxDest->wFormatTag == WAVE_FORMAT_PCM)
- {
- if (mmioWrite(*phmmioOut, (HPSTR) pwfxDest, sizeof(PCMWAVEFORMAT))
- != sizeof(PCMWAVEFORMAT))
- {
- nError = ER_CANNOTWRITE;
- goto ERROR_CANNOT_WRITE; // cannot write file, probably
- }
- }
- else
- {
- // Write the variable length size.
- if ((UINT)mmioWrite(*phmmioOut, (HPSTR) pwfxDest, sizeof(*pwfxDest)+pwfxDest->cbSize)
- != (sizeof(*pwfxDest)+pwfxDest->cbSize))
- {
- nError = ER_CANNOTWRITE;
- goto ERROR_CANNOT_WRITE; // cannot write file, probably
- }
- }
- /* Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk.
- */
- if ((nError = mmioAscend(*phmmioOut, pckOut, 0)) != 0)
- {
- goto ERROR_CANNOT_WRITE; // cannot write file, probably
- }
- // Now create the fact chunk, not required for PCM but nice to have. This is filled
- // in when the close routine is called.
- ckOut1.ckid = mmioFOURCC('f', 'a', 'c', 't');
- ckOut1.cksize = 0;
- if ((nError = mmioCreateChunk(*phmmioOut, &ckOut1, 0)) != 0)
- {
- goto ERROR_CANNOT_WRITE; // cannot write file, probably
- }
- if (mmioWrite(*phmmioOut, (HPSTR)&dwFactChunk, sizeof(dwFactChunk)) != sizeof(dwFactChunk))
- {
- nError = ER_CANNOTWRITE;
- goto ERROR_CANNOT_WRITE;
- }
- // Now ascend out of the fact chunk...
- if ((nError = mmioAscend(*phmmioOut, &ckOut1, 0)) != 0)
- {
- nError = ER_CANNOTWRITE; // cannot write file, probably
- goto ERROR_CANNOT_WRITE;
- }
- goto DONE_CREATE;
- ERROR_CANNOT_WRITE:
- // Maybe delete the half-written file? Ah forget it for now, its good to leave the
- // file there for debugging...
- DONE_CREATE:
- return(nError);
- }
- /* This routine has to be called before any data is written to the wave output file, via wavewritefile. This
- sets up the data to write, and creates the data chunk.
- */
- int WaveStartDataWrite(
- HMMIO *phmmioOut, // (IN)
- MMCKINFO *pckOut, // (IN)
- MMIOINFO *pmmioinfoOut // (OUT)
- )
- {
- int nError;
- nError = 0;
- /* Create the 'data' chunk that holds the waveform samples. */
- pckOut->ckid = mmioFOURCC('d', 'a', 't', 'a');
- pckOut->cksize = 0;
- if ((nError = mmioCreateChunk(*phmmioOut, pckOut, 0)) != 0)
- {
- goto ERROR_CANNOT_WRITE; // cannot write file, probably
- }
- if ((nError = mmioGetInfo(*phmmioOut, pmmioinfoOut, 0)) != 0)
- {
- goto ERROR_CANNOT_WRITE;
- }
- goto CLEANUP;
- ERROR_CANNOT_WRITE:
- CLEANUP:
- return(nError);
- }
- /* This routine will write out data to a wave file.
- hmmioOut - Handle to hmmioOut filled by WaveCreateFile
- cbWrite - # of bytes to write out.
- pbSrc - Pointer to source.
- pckOut - pointer to ckOut filled by WaveCreateFile
- cbActualWrite - # of actual bytes written.
- pmmioinfoOut - Pointer to mmioinfoOut filled by WaveCreateFile.
- Returns 0 if successful, else the error code.
- */
- int WaveWriteFile(
- HMMIO hmmioOut, // (IN)
- UINT cbWrite, // (IN)
- BYTE *pbSrc, // (IN)
- MMCKINFO *pckOut, // (IN)
- UINT *cbActualWrite, // (OUT)
- MMIOINFO *pmmioinfoOut // (IN)
- )
- {
- int nError;
- UINT cT;
- nError = 0;
- *cbActualWrite = 0;
- for (cT=0; cT < cbWrite; cT++)
- {
- if (pmmioinfoOut->pchNext == pmmioinfoOut->pchEndWrite)
- {
- pmmioinfoOut->dwFlags |= MMIO_DIRTY;
- if ((nError = mmioAdvance(hmmioOut, pmmioinfoOut, MMIO_WRITE)) != 0)
- {
- goto ERROR_CANNOT_WRITE;
- }
- }
- *((BYTE*)pmmioinfoOut->pchNext)++ = *((BYTE*)pbSrc+cT);
- (*cbActualWrite)++;
- }
- ERROR_CANNOT_WRITE:
- // What to do here? Well, for now, nothing, just return that error. (maybe delete the
- // file later?
- return(nError);
- }
- /* This routine will close a wave file used for writing. Returns 0 if successful, else
- the error code.
- phmmioOut - Pointer to mmio handle for saving.
- pckOut - Pointer to the MMCKINFO for saving.
- pckOutRiff - Pointer to the riff MMCKINFO for saving.
- pmmioinfoOut- Pointer to mmioinfo for saving.
- cSamples - # of samples saved, for the fact chunk. For PCM, this isn't used but
- will be written anyway, so this can be zero as long as programs ignore
- this field when they load PCM formats.
- */
- int WaveCloseWriteFile(
- HMMIO *phmmioOut, // (IN)
- MMCKINFO *pckOut, // (IN)
- MMCKINFO *pckOutRIFF, // (IN)
- MMIOINFO *pmmioinfoOut, // (IN)
- DWORD cSamples // (IN)
- )
- {
- int nError;
- nError = 0;
- if (*phmmioOut == NULL)
- return(0);
- pmmioinfoOut->dwFlags |= MMIO_DIRTY;
- if ((nError = mmioSetInfo(*phmmioOut, pmmioinfoOut, 0)) != 0)
- {
- // cannot flush, probably...
- goto ERROR_CANNOT_WRITE;
- }
- /* Ascend the output file out of the 'data' chunk -- this will cause
- * the chunk size of the 'data' chunk to be written.
- */
- if ((nError = mmioAscend(*phmmioOut, pckOut, 0)) != 0)
- goto ERROR_CANNOT_WRITE; // cannot write file, probably
- // Do this here instead...
- if ((nError = mmioAscend(*phmmioOut, pckOutRIFF, 0)) != 0)
- goto ERROR_CANNOT_WRITE; // cannot write file, probably
- nError = mmioSeek(*phmmioOut, 0, SEEK_SET);
- if ((nError = (int)mmioDescend(*phmmioOut, pckOutRIFF, NULL, 0)) != 0)
- {
- goto ERROR_CANNOT_WRITE;
- }
- nError = 0;
- pckOut->ckid = mmioFOURCC('f', 'a', 'c', 't');
- if ((nError = mmioDescend(*phmmioOut, pckOut, pckOutRIFF, MMIO_FINDCHUNK)) == 0)
- {
- // If it didn't fail, write the fact chunk out, if it failed, not critical, just
- // assert (below).
- nError = mmioWrite(*phmmioOut, (HPSTR)&cSamples, sizeof(DWORD));
- nError = mmioAscend(*phmmioOut, pckOut, 0);
- nError = 0;
- }
- else
- {
- nError = 0;
- Assert(FALSE);
- }
- // CANTWRITEFACT:
- /* Ascend the output file out of the 'RIFF' chunk -- this will cause
- * the chunk size of the 'RIFF' chunk to be written.
- */
- if ((nError = mmioAscend(*phmmioOut, pckOutRIFF, 0)) != 0)
- goto ERROR_CANNOT_WRITE; // cannot write file, probably
- ERROR_CANNOT_WRITE:
- if (*phmmioOut != NULL)
- {
- mmioClose(*phmmioOut, 0);
- *phmmioOut = NULL;
- }
- return(nError);
- }
- /* This routine will copy from a source wave file to a destination wave file all those useless chunks
- (well, the ones useless to conversions, etc --> apparently people use them!). The source will be
- seeked to the begining, but the destination has to be at a current pointer to put the new chunks.
- This will also seek back to the start of the wave riff header at the end of the routine.
- phmmioIn - Pointer to input mmio file handle.
- pckIn - Pointer to a nice ckIn to use.
- pckInRiff - Pointer to the main riff.
- phmmioOut - Pointer to output mmio file handle.
- pckOut - Pointer to nice ckOut to use.
- pckOutRiff - Pointer to the main riff.
- Returns 0 if successful, else the error code. If this routine fails, it still attemps to seek back to
- the start of the wave riff header, though this too could be unsuccessful.
- */
- int WaveCopyUselessChunks(
- HMMIO *phmmioIn,
- MMCKINFO *pckIn,
- MMCKINFO *pckInRiff,
- HMMIO *phmmioOut,
- MMCKINFO *pckOut,
- MMCKINFO *pckOutRiff)
- {
- int nError;
- nError = 0;
- // First seek to the stinking start of the file, not including the riff header...
- if ((nError = mmioSeek(*phmmioIn, pckInRiff->dwDataOffset + sizeof(FOURCC), SEEK_SET)) == -1)
- {
- nError = ER_CANNOTREAD;
- goto ERROR_IN_PROC;
- }
- nError = 0;
- while (mmioDescend(*phmmioIn, pckIn, pckInRiff, 0) == 0)
- {
- // quickly check for corrupt RIFF file--don't ascend past end!
- if ((pckIn->dwDataOffset + pckIn->cksize) > (pckInRiff->dwDataOffset + pckInRiff->cksize))
- goto ERROR_IN_PROC;
- switch (pckIn->ckid)
- {
- // explicitly skip these...
- case mmioFOURCC('f', 'm', 't', ' '):
- break;
- case mmioFOURCC('d', 'a', 't', 'a'):
- break;
- case mmioFOURCC('f', 'a', 'c', 't'):
- break;
- case mmioFOURCC('J', 'U', 'N', 'K'):
- break;
- case mmioFOURCC('P', 'A', 'D', ' '):
- break;
- case mmioFOURCC('c', 'u', 'e', ' '):
- break;
- // copy chunks that are OK to copy
- case mmioFOURCC('p', 'l', 's', 't'):
- // although without the 'cue' chunk, it doesn't make much sense
- riffCopyChunk(*phmmioIn, *phmmioOut, pckIn);
- break;
- case mmioFOURCC('D', 'I', 'S', 'P'):
- riffCopyChunk(*phmmioIn, *phmmioOut, pckIn);
- break;
- // don't copy unknown chunks
- default:
- break;
- }
- // step up to prepare for next chunk..
- mmioAscend(*phmmioIn, pckIn, 0);
- }
- ERROR_IN_PROC:
- {
- int nErrorT;
- // Seek back to riff header
- nErrorT = mmioSeek(*phmmioIn, pckInRiff->dwDataOffset + sizeof(FOURCC), SEEK_SET);
- }
- return(nError);
- }
- /** BOOL RIFFAPI riffCopyChunk(HMMIO hmmioSrc, HMMIO hmmioDst, const LPMMCKINFO lpck)
- *
- * DESCRIPTION:
- *
- *
- * ARGUMENTS:
- * (LPWAVECONVCB lpwc, LPMMCKINFO lpck)
- *
- * RETURN (BOOL NEAR PASCAL):
- *
- *
- * NOTES:
- *
- ** */
- BOOL riffCopyChunk(HMMIO hmmioSrc, HMMIO hmmioDst, const LPMMCKINFO lpck)
- {
- MMCKINFO ck;
- HPSTR hpBuf;
- //
- //
- //
- hpBuf = (HPSTR)GlobalAllocPtr(GHND, lpck->cksize);
- if (!hpBuf)
- return (FALSE);
- ck.ckid = lpck->ckid;
- ck.cksize = lpck->cksize;
- if (mmioCreateChunk(hmmioDst, &ck, 0))
- goto rscc_Error;
- if (mmioRead(hmmioSrc, hpBuf, lpck->cksize) != (LONG)lpck->cksize)
- goto rscc_Error;
- if (mmioWrite(hmmioDst, hpBuf, lpck->cksize) != (LONG)lpck->cksize)
- goto rscc_Error;
- if (mmioAscend(hmmioDst, &ck, 0))
- goto rscc_Error;
- if (hpBuf)
- GlobalFreePtr(hpBuf);
- return (TRUE);
- rscc_Error:
- if (hpBuf)
- GlobalFreePtr(hpBuf);
- return (FALSE);
- } /* RIFFSupCopyChunk() */
- /* This routine loads a full wave file into memory. Be careful, wave files can get
- pretty big these days :).
- szFileName - sz Filename
- cbSize - Size of loaded wave (returned)
- cSamples - # of samples loaded.
- ppwfxInfo - Pointer to pointer to waveformatex structure. The wfx structure
- IS ALLOCATED by this routine! Make sure to free it!
- ppbData - Pointer to a byte pointer (globalalloc) which is allocated by this
- routine. Make sure to free it!
- Returns 0 if successful, else the error code.
- */
- int WaveLoadFile(
- char *pszFileName, // (IN)
- UINT *cbSize, // (OUT)
- DWORD *pcSamples, // (OUT)
- WAVEFORMATEX **ppwfxInfo, // (OUT)
- BYTE **ppbData // (OUT)
- )
- {
- HMMIO hmmioIn;
- MMCKINFO ckInRiff;
- MMCKINFO ckIn;
- int nError;
- UINT cbActualRead;
- *ppbData = NULL;
- *ppwfxInfo = NULL;
- *cbSize = 0;
- if ((nError = WaveOpenFile(pszFileName, &hmmioIn, ppwfxInfo, &ckInRiff)) != 0)
- {
- goto ERROR_LOADING;
- }
- if ((nError = WaveStartDataRead(&hmmioIn, &ckIn, &ckInRiff)) != 0)
- {
- goto ERROR_LOADING;
- }
- // Ok, size of wave data is in ckIn, allocate that buffer.
- if ((*ppbData = (BYTE *)GlobalAlloc(GMEM_FIXED, ckIn.cksize)) == NULL)
- {
- nError = ER_MEM;
- goto ERROR_LOADING;
- }
- if ((nError = WaveReadFile(hmmioIn, ckIn.cksize, *ppbData, &ckIn, &cbActualRead)) != 0)
- {
- goto ERROR_LOADING;
- }
- *cbSize = cbActualRead;
- goto DONE_LOADING;
- ERROR_LOADING:
- if (*ppbData != NULL)
- {
- GlobalFree(*ppbData);
- *ppbData = NULL;
- }
- if (*ppwfxInfo != NULL)
- {
- GlobalFree(*ppwfxInfo);
- *ppwfxInfo = NULL;
- }
- DONE_LOADING:
- // Close the wave file.
- if (hmmioIn != NULL)
- {
- mmioClose(hmmioIn, 0);
- hmmioIn = NULL;
- }
- return(nError);
- }
- /* This routine saves a wave file in currently in memory.
- pszFileName - FileName to save to. Automatically overwritten, be careful!
- cbSize - Size in bytes to write.
- cSamples - # of samples to write, used to make the fact chunk. (if !PCM)
- pwfxDest - Pointer to waveformatex structure.
- pbData - Pointer to the data.
- */
- int WaveSaveFile(
- char *pszFileName, // (IN)
- UINT cbSize, // (IN)
- DWORD cSamples, // (IN)
- WAVEFORMATEX *pwfxDest, // (IN)
- BYTE *pbData // (IN)
- )
- {
- HMMIO hmmioOut;
- MMCKINFO ckOut;
- MMCKINFO ckOutRIFF;
- MMIOINFO mmioinfoOut;
- UINT cbActualWrite;
- int nError;
- if ((nError = WaveCreateFile(pszFileName, &hmmioOut, pwfxDest, &ckOut, &ckOutRIFF)) != 0)
- {
- goto ERROR_SAVING;
- }
- if ((nError = WaveStartDataWrite(&hmmioOut, &ckOut, &mmioinfoOut)) != 0)
- {
- goto ERROR_SAVING;
- }
- if ((nError = WaveWriteFile(hmmioOut, cbSize, pbData, &ckOut, &cbActualWrite, &mmioinfoOut)) != 0)
- {
- goto ERROR_SAVING;
- }
- if ((nError = WaveCloseWriteFile(&hmmioOut, &ckOut, &ckOutRIFF, &mmioinfoOut, cSamples)) != 0)
- {
- goto ERROR_SAVING;
- }
- ERROR_SAVING:
- return(nError);
- }