DSUTIL.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:
Windows编程
开发平台:
Visual C++
- /*==========================================================================
- *
- * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
- *
- * File: dsutil.cpp
- * Content: Routines for dealing with sounds from resources
- *
- *
- ***************************************************************************/
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <windowsx.h>
- #include <mmsystem.h>
- #include <dsound.h>
- typedef struct
- {
- BYTE *pbWaveData; // pointer into wave resource (for restore)
- DWORD cbWaveSize; // size of wave data (for restore)
- int iAlloc; // number of buffers.
- int iCurrent; // current buffer
- IDirectSoundBuffer* Buffers[1]; // list of buffers
- } SNDOBJ, *HSNDOBJ;
- #define _HSNDOBJ_DEFINED
- #include "dsutil.h"
- static const char c_szWAV[] = "WAV";
- ///////////////////////////////////////////////////////////////////////////////
- //
- // DSLoadSoundBuffer
- //
- ///////////////////////////////////////////////////////////////////////////////
- IDirectSoundBuffer *DSLoadSoundBuffer(IDirectSound *pDS, LPCTSTR lpName)
- {
- IDirectSoundBuffer *pDSB = NULL;
- DSBUFFERDESC dsBD = {0};
- BYTE *pbWaveData;
- if (DSGetWaveResource(NULL, lpName, &dsBD.lpwfxFormat, &pbWaveData, &dsBD.dwBufferBytes))
- {
- dsBD.dwSize = sizeof(dsBD);
- dsBD.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLDEFAULT | DSBCAPS_GETCURRENTPOSITION2;
- if (SUCCEEDED(IDirectSound_CreateSoundBuffer(pDS, &dsBD, &pDSB, NULL)))
- {
- if (!DSFillSoundBuffer(pDSB, pbWaveData, dsBD.dwBufferBytes))
- {
- IDirectSoundBuffer_Release(pDSB);
- pDSB = NULL;
- }
- }
- else
- {
- pDSB = NULL;
- }
- }
- return pDSB;
- }
- ///////////////////////////////////////////////////////////////////////////////
- //
- // DSReloadSoundBuffer
- //
- ///////////////////////////////////////////////////////////////////////////////
- BOOL DSReloadSoundBuffer(IDirectSoundBuffer *pDSB, LPCTSTR lpName)
- {
- BOOL result=FALSE;
- BYTE *pbWaveData;
- DWORD cbWaveSize;
- if (DSGetWaveResource(NULL, lpName, NULL, &pbWaveData, &cbWaveSize))
- {
- if (SUCCEEDED(IDirectSoundBuffer_Restore(pDSB)) &&
- DSFillSoundBuffer(pDSB, pbWaveData, cbWaveSize))
- {
- result = TRUE;
- }
- }
- return result;
- }
- ///////////////////////////////////////////////////////////////////////////////
- //
- // DSGetWaveResource
- //
- ///////////////////////////////////////////////////////////////////////////////
- BOOL DSGetWaveResource(HMODULE hModule, LPCTSTR lpName,
- WAVEFORMATEX **ppWaveHeader, BYTE **ppbWaveData, DWORD *pcbWaveSize)
- {
- HRSRC hResInfo;
- HGLOBAL hResData;
- void *pvRes;
- if (((hResInfo = FindResource(hModule, lpName, c_szWAV)) != NULL) &&
- ((hResData = LoadResource(hModule, hResInfo)) != NULL) &&
- ((pvRes = LockResource(hResData)) != NULL) &&
- DSParseWaveResource(pvRes, ppWaveHeader, ppbWaveData, pcbWaveSize))
- {
- return TRUE;
- }
- return FALSE;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // SndObj fns
- ///////////////////////////////////////////////////////////////////////////////
- SNDOBJ *SndObjCreate(IDirectSound *pDS, LPCTSTR lpName, int iConcurrent)
- {
- SNDOBJ *pSO = NULL;
- LPWAVEFORMATEX pWaveHeader;
- BYTE *pbData;
- UINT cbData;
- if (DSGetWaveResource(NULL, lpName, &pWaveHeader, &pbData, &cbData))
- {
- if (iConcurrent < 1)
- iConcurrent = 1;
- if ((pSO = (SNDOBJ *)LocalAlloc(LPTR, sizeof(SNDOBJ) +
- (iConcurrent-1) * sizeof(IDirectSoundBuffer *))) != NULL)
- {
- int i;
- pSO->iAlloc = iConcurrent;
- pSO->pbWaveData = pbData;
- pSO->cbWaveSize = cbData;
- pSO->Buffers[0] = DSLoadSoundBuffer(pDS, lpName);
- for (i=1; i<pSO->iAlloc; i++)
- {
- if (FAILED(IDirectSound_DuplicateSoundBuffer(pDS,
- pSO->Buffers[0], &pSO->Buffers[i])))
- {
- pSO->Buffers[i] = DSLoadSoundBuffer(pDS, lpName);
- if (!pSO->Buffers[i]) {
- SndObjDestroy(pSO);
- pSO = NULL;
- break;
- }
- }
- }
- }
- }
- return pSO;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- void SndObjDestroy(SNDOBJ *pSO)
- {
- if (pSO)
- {
- int i;
- for (i=0; i<pSO->iAlloc; i++)
- {
- if (pSO->Buffers[i])
- {
- IDirectSoundBuffer_Release(pSO->Buffers[i]);
- pSO->Buffers[i] = NULL;
- }
- }
- LocalFree((HANDLE)pSO);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- IDirectSoundBuffer *SndObjGetFreeBuffer(SNDOBJ *pSO)
- {
- IDirectSoundBuffer *pDSB;
- if (pSO == NULL)
- return NULL;
- if (pDSB = pSO->Buffers[pSO->iCurrent])
- {
- HRESULT hres;
- DWORD dwStatus;
- hres = IDirectSoundBuffer_GetStatus(pDSB, &dwStatus);
- if (FAILED(hres))
- dwStatus = 0;
- if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
- {
- if (pSO->iAlloc > 1)
- {
- if (++pSO->iCurrent >= pSO->iAlloc)
- pSO->iCurrent = 0;
- pDSB = pSO->Buffers[pSO->iCurrent];
- hres = IDirectSoundBuffer_GetStatus(pDSB, &dwStatus);
- if (SUCCEEDED(hres) && (dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
- {
- IDirectSoundBuffer_Stop(pDSB);
- IDirectSoundBuffer_SetCurrentPosition(pDSB, 0);
- }
- }
- else
- {
- pDSB = NULL;
- }
- }
- if (pDSB && (dwStatus & DSBSTATUS_BUFFERLOST))
- {
- if (FAILED(IDirectSoundBuffer_Restore(pDSB)) ||
- !DSFillSoundBuffer(pDSB, pSO->pbWaveData, pSO->cbWaveSize))
- {
- pDSB = NULL;
- }
- }
- }
- return pDSB;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- BOOL SndObjPlay(SNDOBJ *pSO, DWORD dwPlayFlags)
- {
- BOOL result = FALSE;
- if (pSO == NULL)
- return FALSE;
- if ((!(dwPlayFlags & DSBPLAY_LOOPING) || (pSO->iAlloc == 1)))
- {
- IDirectSoundBuffer *pDSB = SndObjGetFreeBuffer(pSO);
- if (pDSB != NULL) {
- result = SUCCEEDED(IDirectSoundBuffer_Play(pDSB, 0, 0, dwPlayFlags));
- }
- }
- return result;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- BOOL SndObjStop(SNDOBJ *pSO)
- {
- int i;
- if (pSO == NULL)
- return FALSE;
- for (i=0; i<pSO->iAlloc; i++)
- {
- IDirectSoundBuffer_Stop(pSO->Buffers[i]);
- IDirectSoundBuffer_SetCurrentPosition(pSO->Buffers[i], 0);
- }
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- BOOL DSFillSoundBuffer(IDirectSoundBuffer *pDSB, BYTE *pbWaveData, DWORD cbWaveSize)
- {
- if (pDSB && pbWaveData && cbWaveSize)
- {
- LPVOID pMem1, pMem2;
- DWORD dwSize1, dwSize2;
- if (SUCCEEDED(IDirectSoundBuffer_Lock(pDSB, 0, cbWaveSize,
- &pMem1, &dwSize1, &pMem2, &dwSize2, 0)))
- {
- CopyMemory(pMem1, pbWaveData, dwSize1);
- if ( 0 != dwSize2 )
- CopyMemory(pMem2, pbWaveData+dwSize1, dwSize2);
- IDirectSoundBuffer_Unlock(pDSB, pMem1, dwSize1, pMem2, dwSize2);
- return TRUE;
- }
- }
- return FALSE;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- BOOL DSParseWaveResource(void *pvRes, WAVEFORMATEX **ppWaveHeader, BYTE **ppbWaveData,DWORD *pcbWaveSize)
- {
- DWORD *pdw;
- DWORD *pdwEnd;
- DWORD dwRiff;
- DWORD dwType;
- DWORD dwLength;
- if (ppWaveHeader)
- *ppWaveHeader = NULL;
- if (ppbWaveData)
- *ppbWaveData = NULL;
- if (pcbWaveSize)
- *pcbWaveSize = 0;
- pdw = (DWORD *)pvRes;
- dwRiff = *pdw++;
- dwLength = *pdw++;
- dwType = *pdw++;
- if (dwRiff != mmioFOURCC('R', 'I', 'F', 'F'))
- goto exit; // not even RIFF
- if (dwType != mmioFOURCC('W', 'A', 'V', 'E'))
- goto exit; // not a WAV
- pdwEnd = (DWORD *)((BYTE *)pdw + dwLength-4);
- while (pdw < pdwEnd)
- {
- dwType = *pdw++;
- dwLength = *pdw++;
- switch (dwType)
- {
- case mmioFOURCC('f', 'm', 't', ' '):
- if (ppWaveHeader && !*ppWaveHeader)
- {
- if (dwLength < sizeof(WAVEFORMAT))
- goto exit; // not a WAV
- *ppWaveHeader = (WAVEFORMATEX *)pdw;
- if ((!ppbWaveData || *ppbWaveData) &&
- (!pcbWaveSize || *pcbWaveSize))
- {
- return TRUE;
- }
- }
- break;
- case mmioFOURCC('d', 'a', 't', 'a'):
- if ((ppbWaveData && !*ppbWaveData) ||
- (pcbWaveSize && !*pcbWaveSize))
- {
- if (ppbWaveData)
- *ppbWaveData = (LPBYTE)pdw;
- if (pcbWaveSize)
- *pcbWaveSize = dwLength;
- if (!ppWaveHeader || *ppWaveHeader)
- return TRUE;
- }
- break;
- }
- pdw = (DWORD *)((BYTE *)pdw + ((dwLength+1)&~1));
- }
- exit:
- return FALSE;
- }