WAVEIO.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:
Windows编程
开发平台:
Visual C++
- //==========================================================================;
- //
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- // PURPOSE.
- //
- // Copyright (C) 1992 - 1997 Microsoft Corporation. All Rights Reserved.
- //
- //--------------------------------------------------------------------------;
- //
- // waveio.c
- //
- // Description:
- // Contains routines for opening and closing RIFF WAVE files.
- //
- //
- //==========================================================================;
- #include <windows.h>
- #include <windowsx.h>
- #include <mmsystem.h>
- #include <mmreg.h>
- #include <memory.h>
- #include "appport.h"
- #include "waveio.h"
- #include "debug.h"
- //--------------------------------------------------------------------------;
- //
- // WIOERR wioFileClose
- //
- // Description:
- //
- //
- // Arguments:
- // LPWAVEIOCB pwio:
- //
- // DWORD fdwClose:
- //
- // Return (WIOERR):
- //
- //--------------------------------------------------------------------------;
- WIOERR WIOAPI wioFileClose
- (
- LPWAVEIOCB pwio,
- DWORD fdwClose
- )
- {
- //
- // validate a couple of things...
- //
- if (NULL == pwio)
- return (WIOERR_BADPARAM);
- //
- // get rid of stuff...
- //
- // wioStopWave(pwio);
- if (NULL != pwio->hmmio)
- {
- mmioClose(pwio->hmmio, 0);
- }
- // FreeWaveHeaders(lpwio);
- #if 0
- if (pwio->pInfo)
- riffFreeINFO(&(lpwio->pInfo));
- if (pwio->pDisp)
- riffFreeDISP(&(lpwio->pDisp));
- #endif
- if (NULL != pwio->pwfx)
- GlobalFreePtr(pwio->pwfx);
- _fmemset(pwio, 0, sizeof(*pwio));
- return (WIOERR_NOERROR);
- } // wioFileClose()
- //--------------------------------------------------------------------------;
- //
- // WIOERR wioFileOpen
- //
- // Description:
- //
- //
- // Arguments:
- // LPWAVEIOCB pwio:
- //
- // LPCTSTR pszFilePath:
- //
- // DWORD fdwOpen:
- //
- // Return (WIOERR):
- //
- //
- //--------------------------------------------------------------------------;
- WIOERR WIOAPI wioFileOpen
- (
- LPWAVEIOCB pwio,
- LPCTSTR pszFilePath,
- DWORD fdwOpen
- )
- {
- UINT u;
- TCHAR ach[255];
- WIOERR werr;
- HMMIO hmmio;
- MMCKINFO ckRIFF;
- MMCKINFO ck;
- DWORD dw;
- //
- // validate a couple of things...
- //
- if (NULL == pwio)
- return (WIOERR_BADPARAM);
- //
- // default our error return (assume the worst)
- //
- _fmemset(pwio, 0, sizeof(*pwio));
- werr = WIOERR_FILEERROR;
- pwio->dwFlags = fdwOpen;
- //
- // first try to open the file, etc.. open the given file for reading
- // using buffered I/O
- //
- hmmio = mmioOpen((LPTSTR)pszFilePath, NULL, MMIO_READ | MMIO_ALLOCBUF);
- if (NULL == hmmio)
- goto wio_Open_Error;
- pwio->hmmio = hmmio;
- //
- // locate a 'WAVE' form type...
- //
- ckRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');
- if (mmioDescend(hmmio, &ckRIFF, NULL, MMIO_FINDRIFF))
- goto wio_Open_Error;
- //
- // we found a WAVE chunk--now go through and get all subchunks that
- // we know how to deal with...
- //
- pwio->dwDataSamples = (DWORD)-1L;
- #if 0
- if (lrt=riffInitINFO(&wio.pInfo))
- {
- lr=lrt;
- goto wio_Open_Error;
- }
- #endif
- //
- //
- //
- while (MMSYSERR_NOERROR == mmioDescend(hmmio, &ck, &ckRIFF, 0))
- {
- //
- // quickly check for corrupt RIFF file--don't ascend past end!
- //
- if ((ck.dwDataOffset + ck.cksize) > (ckRIFF.dwDataOffset + ckRIFF.cksize))
- {
- DPF(1, "wioFileOpen() FILE MIGHT BE CORRUPT!");
- DPF(1, " ckRIFF.dwDataOffset: %lu", ckRIFF.dwDataOffset);
- DPF(1, " ckRIFF.cksize: %lu", ckRIFF.cksize);
- DPF(1, " ck.dwDataOffset: %lu", ck.dwDataOffset);
- DPF(1, " ck.cksize: %lu", ck.cksize);
- wsprintf(ach, TEXT("This wave file might be corrupt. The RIFF chunk.ckid '%.08lX' (data offset at %lu) specifies a cksize of %lu that extends beyond what the RIFF header cksize of %lu allows. Attempt to load?"),
- ck.ckid, ck.dwDataOffset, ck.cksize, ckRIFF.cksize);
- u = MessageBox(NULL, ach, TEXT("wioFileOpen"),
- MB_YESNO | MB_ICONEXCLAMATION | MB_TASKMODAL);
- if (IDNO == u)
- {
- werr = WIOERR_BADFILE;
- goto wio_Open_Error;
- }
- }
- switch (ck.ckid)
- {
- case mmioFOURCC('L', 'I', 'S', 'T'):
- if (ck.fccType == mmioFOURCC('I', 'N', 'F', 'O'))
- {
- #if 0
- if(lrt=riffReadINFO(hmmio, &ck, wio.pInfo))
- {
- lr=lrt;
- goto wio_Open_Error;
- }
- #endif
- }
- break;
- case mmioFOURCC('D', 'I', 'S', 'P'):
- #if 0
- riffReadDISP(hmmio, &ck, &(wio.pDisp));
- #endif
- break;
- case mmioFOURCC('f', 'm', 't', ' '):
- //
- // !?! another format chunk !?!
- //
- if (NULL != pwio->pwfx)
- break;
- //
- // get size of the format chunk, allocate and lock memory
- // for it. we always alloc a complete extended format header
- // (even for PCM headers that do not have the cbSize field
- // defined--we just set it to zero).
- //
- dw = ck.cksize;
- if (dw < sizeof(WAVEFORMATEX))
- dw = sizeof(WAVEFORMATEX);
- pwio->pwfx = (LPWAVEFORMATEX)GlobalAllocPtr(GHND, dw);
- if (NULL == pwio->pwfx)
- {
- werr = WIOERR_NOMEM;
- goto wio_Open_Error;
- }
- //
- // read the format chunk
- //
- werr = WIOERR_FILEERROR;
- dw = ck.cksize;
- if (mmioRead(hmmio, (HPSTR)pwio->pwfx, dw) != (LONG)dw)
- goto wio_Open_Error;
- break;
- case mmioFOURCC('d', 'a', 't', 'a'):
- //
- // !?! multiple data chunks !?!
- //
- if (0L != pwio->dwDataBytes)
- break;
- //
- // just hang on to the total length in bytes of this data
- // chunk.. and the offset to the start of the data
- //
- pwio->dwDataBytes = ck.cksize;
- pwio->dwDataOffset = ck.dwDataOffset;
- break;
- case mmioFOURCC('f', 'a', 'c', 't'):
- //
- // !?! multiple fact chunks !?!
- //
- if (-1L != pwio->dwDataSamples)
- break;
- //
- // read the first dword in the fact chunk--it's the only
- // info we need (and is currently the only info defined for
- // the fact chunk...)
- //
- // if this fails, dwDataSamples will remain -1 so we will
- // deal with it later...
- //
- mmioRead(hmmio, (HPSTR)&pwio->dwDataSamples, sizeof(DWORD));
- break;
- }
- //
- // step up to prepare for next chunk..
- //
- mmioAscend(hmmio, &ck, 0);
- }
- //
- // if no fmt chunk was found, then die!
- //
- if (NULL == pwio->pwfx)
- {
- werr = WIOERR_ERROR;
- goto wio_Open_Error;
- }
- //
- // all wave files other than PCM are _REQUIRED_ to have a fact chunk
- // telling the number of samples that are contained in the file. it
- // is optional for PCM (and if not present, we compute it here).
- //
- // if the file is not PCM and the fact chunk is not found, then fail!
- //
- if (-1L == pwio->dwDataSamples)
- {
- if (WAVE_FORMAT_PCM == pwio->pwfx->wFormatTag)
- {
- pwio->dwDataSamples = pwio->dwDataBytes / pwio->pwfx->nBlockAlign;
- }
- else
- {
- //
- // !!! HACK HACK HACK !!!
- //
- // although this should be considered an invalid wave file, we
- // will bring up a message box describing the error--hopefully
- // people will start realizing that something is missing???
- //
- u = MessageBox(NULL, TEXT("This wave file does not have a 'fact' chunk and requires one! This is completely invalid and MUST be fixed! Attempt to load it anyway?"),
- TEXT("wioFileOpen"), MB_YESNO | MB_ICONEXCLAMATION | MB_TASKMODAL);
- if (IDNO == u)
- {
- werr = WIOERR_BADFILE;
- goto wio_Open_Error;
- }
- //
- // !!! need to hack stuff in here !!!
- //
- pwio->dwDataSamples = 0L;
- }
- }
- //
- // cool! no problems..
- //
- return (WIOERR_NOERROR);
- //
- // return error (after minor cleanup)
- //
- wio_Open_Error:
- wioFileClose(pwio, 0L);
- return (werr);
- } // wioFileOpen()