www.pudn.com > 3D_Tank.rar > Sound.cpp
#include "Sound.h"
CSoundSet::CSoundSet()
{}
CSoundSet::~CSoundSet()
{}
BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription,
LPCSTR lpcstrModule, LPVOID lpContext)
{
if (lpGuid != NULL)
{
DSDevice device;
device.guid = *lpGuid;
device.strDevice = lpcstrDescription;
vecDSDevice *pvecDevice = static_cast(lpContext);
(*pvecDevice).push_back (device);
return TRUE;
}
else
{
DSDevice device;
device.strDevice = lpcstrDescription;
vecDSDevice *pvecDevice = static_cast(lpContext);
(*pvecDevice).push_back (device);
return TRUE;
}
}
BOOL CSoundSet::InitSoundDevice(HWND hwnd)
{
m_hWindow = hwnd;
HRESULT hr = S_OK;
hr = DirectSoundEnumerate(DSEnumCallback, &m_vecDevice);
if (FAILED(hr))
{ HrError(hr);}
IDirectSound8 *sound = 0;
hr = DirectSoundCreate8(NULL, &sound, NULL);
if (FAILED(hr))
{ HrError(hr);}
if (sound)
{ m_pSound.Reset(sound);}
else
{ return FALSE;}
hr = m_pSound->SetCooperativeLevel(m_hWindow, DSSCL_EXCLUSIVE);
if (FAILED(hr))
{ HrError(hr);}
DSBUFFERDESC dsbdesc;
::ZeroMemory (&dsbdesc, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
IDirectSoundBuffer *pSB = 0;
hr = m_pSound->CreateSoundBuffer (&dsbdesc, &pSB, 0);
if (FAILED(hr))
{ HrError(hr);}
if (pSB)
{ m_pPrimaryBuffer.Reset(pSB);}
else
{ return FALSE;}
WAVEFORMATEX wfx;
::ZeroMemory (&wfx, sizeof(WAVEFORMATEX));
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = 22050;
wfx.wBitsPerSample = 8;
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels ;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
hr = m_pPrimaryBuffer->SetFormat(&wfx);
if (FAILED(hr))
{ HrError(hr);}
return FALSE;
}
BOOL CSoundSet::AddSoundEffect(LPTSTR lptstrFile)
{
HRESULT hr = S_OK;
CWaveFile wf;
hr = wf.Open(lptstrFile, 0, WAVEFILE_READ);
if (FAILED(hr))
{ HrError(hr);}
DSBUFFERDESC dsbdesc;
ZeroMemory( &dsbdesc, sizeof( DSBUFFERDESC ) );
dsbdesc.dwSize = sizeof( DSBUFFERDESC );
dsbdesc.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME;
dsbdesc.dwBufferBytes = wf.GetSize();
dsbdesc.lpwfxFormat = wf.m_pwfx;
IDirectSoundBuffer *pSB;
hr = m_pSound->CreateSoundBuffer( &dsbdesc, &pSB, 0 );
if (FAILED(hr))
{ HrError(hr);}
IDirectSoundBuffer8 *pSB8;
hr = pSB->QueryInterface(IID_IDirectSoundBuffer8, reinterpret_cast(&pSB8));
if (FAILED(hr))
{ HrError(hr);}
pSB->Release();
CComPtr ptrSB8(pSB8);
char *pcPart1, *pcPart2;
DWORD dwSize1, dwSize2;
hr = ptrSB8->Lock( 0, 0,
reinterpret_cast( &pcPart1 ), &dwSize1,
reinterpret_cast( &pcPart2 ), &dwSize2,
DSBLOCK_ENTIREBUFFER );
if (FAILED(hr))
{ HrError(hr);}
DWORD dwSizeRead;
hr = wf.Read( reinterpret_cast( pcPart1 ), dwSize1, &dwSizeRead );
if (FAILED(hr))
{ HrError(hr);}
assert( dwSize1 == dwSizeRead);
hr = ptrSB8->Unlock( pcPart1, dwSize1, pcPart2, dwSize2 );
if (FAILED(hr))
{ HrError(hr);}
wf.Close();
vecSound vs;
vs.push_back(ptrSB8);
m_mapSound.insert(std::pair(lptstrFile, vs));
return TRUE;
}
BOOL CSoundSet::Play(LPTSTR lptstrFile)
{
mapSound::iterator pos;
pos = m_mapSound.find(lptstrFile);
if (pos != m_mapSound.end())
{
vecSound::iterator it = pos->second.begin();
for (; it != pos->second.end(); ++it)
{
DWORD dwStatus;
(*it)->GetStatus(&dwStatus);
if (dwStatus != DSBSTATUS_PLAYING)
{
(*it)->Play(0, 0, 0);
}
}
if (it == pos->second.end())
{
HRESULT hr = S_OK;
IDirectSoundBuffer *pSB = 0;
hr = m_pSound->DuplicateSoundBuffer((*pos->second.begin()).Get(), &pSB);
IDirectSoundBuffer8 *pSB8;
hr = pSB->QueryInterface(IID_IDirectSoundBuffer8, reinterpret_cast(&pSB8));
if (FAILED(hr))
{ HrError(hr);}
pSB->Release();
CComPtr ptrSB8(pSB8);
ptrSB8->Play(0, 0, 0);
pos->second.push_back(ptrSB8);
}
}
return TRUE;
}
BOOL CSoundSet::AddStreamSound(LPTSTR lptstrFile)
{
HRESULT hr = S_OK;
hr = m_wavStream.Open(lptstrFile, 0, WAVEFILE_READ);
if (FAILED(hr))
{ HrError(hr);}
DSBUFFERDESC dsbdesc;
ZeroMemory( &dsbdesc, sizeof( DSBUFFERDESC ) );
dsbdesc.dwSize = sizeof( DSBUFFERDESC );
dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY;
dsbdesc.dwBufferBytes = 6 * m_wavStream.m_pwfx->nAvgBytesPerSec;
dsbdesc.lpwfxFormat = m_wavStream.m_pwfx;
IDirectSoundBuffer *pSB = 0;
hr = m_pSound->CreateSoundBuffer( &dsbdesc, &pSB, 0 );
if (FAILED(hr))
{ HrError(hr);}
IDirectSoundBuffer8 *pSB8;
hr = pSB->QueryInterface(IID_IDirectSoundBuffer8, reinterpret_cast(&pSB8));
if (FAILED(hr))
{ HrError(hr);}
pSB->Release();
m_StreamSound.Reset(pSB8);
IDirectSoundNotify8 *pDSNotify = 0;
hr = m_StreamSound->QueryInterface(IID_IDirectSoundNotify, reinterpret_cast(&pDSNotify));
if (FAILED(hr))
{ HrError(hr);}
m_handleStart = CreateEvent(NULL, FALSE, FALSE, NULL);
m_handleMiddle = CreateEvent(NULL, FALSE, FALSE, NULL);
DSBPOSITIONNOTIFY dsbNotify1;
dsbNotify1.dwOffset = 0;
dsbNotify1.hEventNotify = m_handleStart;
hr = pDSNotify->SetNotificationPositions(1, &dsbNotify1);
DSBPOSITIONNOTIFY dsbNotify2;
dsbNotify1.dwOffset = m_wavStream.m_pwfx->nAvgBytesPerSec * 3;
dsbNotify1.hEventNotify = m_handleMiddle;
hr = pDSNotify->SetNotificationPositions(1, &dsbNotify2);
pDSNotify->Release();
return TRUE;
}