// File: waveio.cpp #include "precomp.h" #include "waveio.h" //==========================================================================; // // 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 - 1996 Microsoft Corporation. All Rights Reserved. // //--------------------------------------------------------------------------; // // waveio.c // // Description: // Contains routines for opening and closing RIFF WAVE files. // // //==========================================================================; //--------------------------------------------------------------------------; // // 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 ) { 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)) { // TCHAR ach[255]; // 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()