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; 
}