cSound.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:7k
- // CMAIN LIB - APPLICATION AND DIRECT WRAPPER
- //
- // Written by Mauricio Teichmann Ritter
- //
- // Copyright (C) 2002, Brazil. All rights reserved.
- //
- //
- // cSound.cpp: implementation of the cSound class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "cSound.h"
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- cSound::cSound()
- {
- m_bIsPlaying = FALSE;
- m_sFileName = NULL;
- m_pWaveFile = NULL;
- m_pSoundBuffer = NULL;
- m_p3DInterface = NULL;
- }
- cSound::~cSound()
- {
- if(m_sFileName)
- free(m_sFileName);
- if(m_pWaveFile)
- delete m_pWaveFile;
- if(m_pSoundBuffer)
- {
- Stop();
- m_pSoundBuffer->Release();
- m_pSoundBuffer = NULL;
- }
- }
- HRESULT cSound::Create(LPTSTR lpszFileName, DWORD dwCreationFlags, GUID guid3DAlgorithm)
- {
- Destroy();
- HRESULT hr;
- HRESULT hrRet = S_OK;
- DWORD dwDSBufferSize = NULL;
- cSoundInterface pSoundInterface;
- /* if(MAKEINTRESOURCE(lpszFileName))
- {
- m_sFileName = (char*)malloc(strlen(lpszFileName)+1);
- strcpy(m_sFileName, lpszFileName);
- }
- else
- {
- m_sFileName = lpszFileName;
- }*/
- if( lpszFileName == NULL )
- return E_INVALIDARG;
- m_pWaveFile = new cWavFile();
- if( m_pWaveFile == NULL )
- {
- hr = E_OUTOFMEMORY;
- goto LFail;
- }
- if(m_pWaveFile->Open( lpszFileName, NULL, WAVEFILE_READ ) != 0)
- {
- DXTRACE_MSG("Didn磘 find resource!");
- }
- if( m_pWaveFile->GetSize() == 0 )
- {
- // Wave is blank, so don't create it.
- hr = E_FAIL;
- goto LFail;
- }
- // Make the DirectSound buffer the same size as the wav file
- dwDSBufferSize = m_pWaveFile->GetSize();
- m_dwDSBufferSize = dwDSBufferSize;
- // Create the direct sound buffer, and only request the flags needed
- // since each requires some overhead and limits if the buffer can
- // be hardware accelerated
- DSBUFFERDESC dsbd;
- ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
- dsbd.dwSize = sizeof(DSBUFFERDESC);
- dsbd.dwFlags = dwCreationFlags;
- dsbd.dwBufferBytes = dwDSBufferSize;
- dsbd.guid3DAlgorithm = guid3DAlgorithm;
- dsbd.lpwfxFormat = m_pWaveFile->m_pwfx;
- // DirectSound is only guarenteed to play PCM data. Other
- // formats may or may not work depending the sound card driver.
- hr = pSoundInterface.GetDirectSound()->CreateSoundBuffer( &dsbd, &m_pSoundBuffer, NULL );
- // Be sure to return this error code if it occurs so the
- // callers knows this happened.
- if( hr == DS_NO_VIRTUALIZATION )
- hrRet = DS_NO_VIRTUALIZATION;
-
- if( FAILED(hr) )
- {
- // DSERR_BUFFERTOOSMALL will be returned if the buffer is
- // less than DSBSIZE_FX_MIN (100ms) and the buffer is created
- // with DSBCAPS_CTRLFX.
- if( hr != DSERR_BUFFERTOOSMALL )
- DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr );
-
- goto LFail;
- }
- // Make sure we have focus, and we didn't just switch in from
- // an app which had a DirectSound device
- if( FAILED( hr = RestoreBuffer( NULL ) ) )
- return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
- FillBuffer();
- return S_OK;
- LFail:
- // Cleanup
- return hr;
- }
- HRESULT cSound::Play(DWORD dwPriority, DWORD dwFlags)
- {
- BOOL bRestored;
- HRESULT hRet;
- DWORD dwStatus;
- hRet = m_pSoundBuffer->GetStatus(&dwStatus);
- if(hRet != 0)
- return -1;
- if( !(dwStatus & DSBSTATUS_PLAYING) )
- m_bIsPlaying = FALSE;
- if(m_bIsPlaying == TRUE)
- return S_OK;
- RestoreBuffer(&bRestored);
- if(bRestored)
- FillBuffer();
- // else
- // DXTRACE_MSG("BUFFER NOT RESTORED");
- // DXTRACE_MSG("START PLAY");
- m_pSoundBuffer->Play(0, dwPriority, dwFlags);
- m_bIsPlaying = TRUE;
- return S_OK;
- }
- HRESULT cSound::RestoreBuffer(BOOL *bRestored)
- {
- HRESULT hr;
- if( m_pSoundBuffer == NULL )
- return CO_E_NOTINITIALIZED;
- if( bRestored )
- *bRestored = FALSE;
- DWORD dwStatus;
- if( FAILED( hr = m_pSoundBuffer->GetStatus( &dwStatus ) ) )
- return DXTRACE_ERR( TEXT("GetStatus"), hr );
- if( dwStatus & DSBSTATUS_BUFFERLOST )
- {
- // Since the app could have just been activated, then DirectSound
- // may not be giving us control yet, so restoring the buffer may fail.
- // If it does, sleep until DirectSound gives us control.
- do
- {
- hr = m_pSoundBuffer->Restore();
- if( hr == DSERR_BUFFERLOST )
- Sleep( 10 );
- }
- while( hr != DS_OK );
- if( bRestored != NULL )
- *bRestored = TRUE;
- return S_OK;
- }
- else
- {
- return S_FALSE;
- }
- }
- LPDIRECTSOUND3DBUFFER cSound::Get3DInterface()
- {
- if(!m_p3DInterface)
- {
- m_pSoundBuffer->QueryInterface( IID_IDirectSound3DBuffer,
- (VOID**)&m_p3DInterface );
- }
- return m_p3DInterface;
- }
- HRESULT cSound::Stop(BOOL bOverride)
- {
- if(bOverride)
- {
- if(m_bIsPlaying == FALSE)
- return S_OK;
- }
- // DXTRACE_MSG("SOUND STOPPED");
-
- m_pSoundBuffer->Stop();
- m_bIsPlaying = FALSE;
- return S_OK;
- }
- HRESULT cSound::FillBuffer()
- {
- HRESULT hr;
- VOID* pDSLockedBuffer = NULL; // Pointer to locked buffer memory
- DWORD dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer
- DWORD dwWavDataRead = 0; // Amount of data read from the wav file
- // Lock the buffer down
- if( FAILED( hr = m_pSoundBuffer->Lock( 0, m_dwDSBufferSize,
- &pDSLockedBuffer, &dwDSLockedBufferSize,
- NULL, NULL, 0L ) ) )
- return DXTRACE_ERR( TEXT("Lock"), hr );
- // Reset the wave file to the beginning
- m_pWaveFile->ResetFile();
- if( FAILED( hr = m_pWaveFile->Read( (BYTE*) pDSLockedBuffer,
- dwDSLockedBufferSize,
- &dwWavDataRead ) ) )
- return DXTRACE_ERR( TEXT("Read"), hr );
- if( dwWavDataRead == 0 )
- {
- // Wav is blank, so just fill with silence
- FillMemory( (BYTE*) pDSLockedBuffer,
- dwDSLockedBufferSize,
- (BYTE)(m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
- }
- // Unlock the buffer, we don't need it anymore.
- m_pSoundBuffer->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
- return 0;
- }
- void cSound::SetPosition(float fX, float fY, float fZ)
- {
- Get3DInterface()->SetPosition(fX, fY, fZ, DS3D_IMMEDIATE);
- }
- void cSound::SetVelocity(float fX, float fY, float fZ)
- {
- Get3DInterface()->SetVelocity(fX, fY, fZ, DS3D_IMMEDIATE);
- }
- void cSound::Destroy()
- {
- if(m_sFileName)
- free(m_sFileName);
- if(m_pWaveFile)
- delete m_pWaveFile;
- if(m_p3DInterface)
- {
- m_p3DInterface->Release();
- m_p3DInterface = NULL;
- }
- if(m_pSoundBuffer)
- {
- Stop();
- m_pSoundBuffer->Release();
- m_pSoundBuffer = NULL;
- }
- }