📄 dxwave.cpp
字号:
// 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;
}
// 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);
}
int WaveOpenFileB(
LONG cchBuffer, // (IN)
HPSTR pchBuffer, // (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.
MMIOINFO mmioInfo;
// Initialization...
*ppwfxInfo = NULL;
nError = 0;
hmmioIn = NULL;
ZeroMemory(&mmioInfo, sizeof(MMIOINFO));
mmioInfo.fccIOProc=FOURCC_MEM;
mmioInfo.cchBuffer=cchBuffer;
mmioInfo.pchBuffer=pchBuffer;
if ((hmmioIn = mmioOpen(NULL, &mmioInfo, 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 = (struct tWAVEFORMATEX *)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);
}
int WaveLoadFileB(
LONG cchBuffer, // (IN)
HPSTR pchBuffer, // (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 = WaveOpenFileB(cchBuffer, pchBuffer, &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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -