Files
Client/GameTools/SoundLib/DirectSound.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

278 lines
7.2 KiB
C++

#include "DirectSound.h"
#include "SoundObject.h"
#include <dsound.h>
#include <vector>
#include <assert.h>
/////////////////////////////////////////////////////////////////////////////////////////
// 전역 변수
bool g_b3DSound = false; //SoundLib전체에 대한 3DSound여부를 결정함.
/////////////////////////////////////////////////////////////////////////////////////////
//
CDirectSound & CDirectSound::GetInstance()
{
static CDirectSound DSound;
return DSound;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
CDirectSound::CDirectSound()
: m_pDSound( NULL )
, m_p3DListener( NULL )
, m_pSoundBufferList( new SOUNDBUFFERLIST )
, m_bDSoundCreated( false )
{
}
/////////////////////////////////////////////////////////////////////////////////////////
//
CDirectSound::~CDirectSound()
{
Destroy();
delete m_pSoundBufferList;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::Create( IDirectSound8 * pDSound )
{
Destroy();
m_pDSound = pDSound;
m_bDSoundCreated = false;
Enable3DSound();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::Create( HWND hWnd,
DWORD dwCoopLevel,
DWORD dwPrimaryChannels,
DWORD dwPrimaryFreq,
DWORD dwPrimaryBitRate )
{
if( m_pDSound )
return;
HRESULT hr;
// Create IDirectSound using the primary sound device
if( FAILED( hr = DirectSoundCreate8( NULL, &m_pDSound, NULL ) ) )
SNDError( "DirectSoundCreate8 Error!! ErrorCode : 0x%x", hr );
// Set DirectSound coop level
if( FAILED( hr = m_pDSound->SetCooperativeLevel( hWnd, dwCoopLevel ) ) )
SNDError( "SetCooperativeLevel(DirectSound) Error!! ErrorCode : 0x%x", hr );
SetPrimaryBufferFormat( dwPrimaryChannels, dwPrimaryFreq, dwPrimaryBitRate );
m_bDSoundCreated = true;
Enable3DSound();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::Destroy()
{
for( SOUNDBUFFERLIST::iterator i = m_pSoundBufferList->begin(); i != m_pSoundBufferList->end(); i++ )
{
delete *i;
}
m_pSoundBufferList->clear();
if( m_p3DListener )
{
m_p3DListener->Release();
m_p3DListener = NULL;
}
if( m_pDSound )
{
if( m_bDSoundCreated )
m_pDSound->Release();
m_pDSound = NULL;
}
m_bDSoundCreated = false;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::Enable3DSound()
{
if( g_b3DSound == false )
{
g_b3DSound = true;
m_p3DListener = Get3DListenerInterface();
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::SetPrimaryBufferFormat( DWORD dwPrimaryChannels,
DWORD dwPrimaryFreq,
DWORD dwPrimaryBitRate )
{
HRESULT hr;
LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;
assert( m_pDSound != NULL );
// Get the primary buffer
DSBUFFERDESC dsbd;
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
dsbd.dwBufferBytes = 0;
dsbd.lpwfxFormat = NULL;
if( FAILED( hr = m_pDSound->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) )
SNDError( "CreateSoundBuffer(Primary) Failed!! ErrorCode : 0x%x", hr );
WAVEFORMATEX wfx;
ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = (WORD) dwPrimaryChannels;
wfx.nSamplesPerSec = dwPrimaryFreq;
wfx.wBitsPerSample = (WORD) dwPrimaryBitRate;
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) )
SNDError( "SetFormat(DirectSound) Error!! ErrorCode : 0x%x", hr );
if( pDSBPrimary )
pDSBPrimary->Release();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
IDirectSound3DListener * CDirectSound::Get3DListenerInterface()
{
DSBUFFERDESC dsbdesc;
ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;
HRESULT hr = m_pDSound->CreateSoundBuffer( &dsbdesc, &pDSBPrimary, NULL );
if( FAILED( hr ) )
{
return NULL;
// SNDError( "CreateSoundBuffer Error!! ErrorCode : 0x%x", hr );
}
LPDIRECTSOUND3DLISTENER8 pDSListener = NULL;
if( FAILED( hr = pDSBPrimary->QueryInterface( IID_IDirectSound3DListener8, (void**)&pDSListener ) ) )
{
if( pDSBPrimary )
pDSBPrimary->Release();
SNDError( "QueryInterface IDirectSound3DListener Failed!! ErrorCode : 0x%x", hr );
}
if( pDSBPrimary )
pDSBPrimary->Release();
return pDSListener;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::SetDoppler( D3DVALUE distance, D3DVALUE doppler )
{
if( m_p3DListener )
{
HRESULT hr = m_p3DListener->SetDistanceFactor( distance, DS3D_IMMEDIATE );
if( FAILED( hr ) )
SNDError( "SetDistanceFactor (DS3DListener) Failed!! ErrorCode : 0x%x", hr );
if( FAILED( hr = m_p3DListener->SetDopplerFactor( doppler, DS3D_IMMEDIATE ) ) )
SNDError( "SetDopplerFactor (DS3DListener) Failed!! ErrorCode : 0x%x", hr );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::SetRolloff( D3DVALUE rolloff )
{
if( m_p3DListener )
{
HRESULT hr;
if( FAILED( hr = m_p3DListener->SetRolloffFactor( rolloff, DS3D_IMMEDIATE ) ) )
SNDError( "SetRolloffFactor (DS3DListener) Failed!! ErrorCode : 0x%x", hr );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::Set3DOrientation( D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront
, D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop )
{
if( m_p3DListener )
{
HRESULT hr = m_p3DListener->SetOrientation( xFront, yFront, zFront, xTop, yTop, zTop, DS3D_IMMEDIATE );
if( FAILED( hr ) )
SNDError( "SetOrientation (DS3DListener) Failed!! ErrorCode : 0x%x", hr );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::SetVelocity( D3DVALUE x, D3DVALUE y, D3DVALUE z )
{
if( m_p3DListener )
{
HRESULT hr = m_p3DListener->SetVelocity( x, y, z, DS3D_IMMEDIATE );
if( FAILED( hr ) )
SNDError( "SetVelocity (DS3DListener) Failed!! ErrorCode : 0x%x", hr );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::SetPosition( D3DVALUE x, D3DVALUE y, D3DVALUE z )
{
if( m_p3DListener )
{
HRESULT hr = m_p3DListener->SetPosition( x, y, z, DS3D_IMMEDIATE );
if( FAILED( hr ) )
SNDError( "SetPosition (DS3DListener) Failed!! ErrorCode : 0x%x", hr );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectSound::RegisterSoundBuffer( ISoundObject * pBuf )
{
m_pSoundBufferList->push_back( pBuf );
}
/////////////////////////////////////////////////////////////////////////////////////////