📄 csound.cpp
字号:
// 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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -