⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wave.cpp

📁 《Visual C++视频技术方案宝典》配套光盘
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	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);
			(BYTE*) pmmioinfoOut->pchNext++;
			//*((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)
		{
		nError = mmioClose(*phmmioOut,NULL );
		*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(
			TCHAR*pszFileName,                      // (IN)
			UINT *cbSize,                           // (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(
				TCHAR*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);         

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -