Files
Client/GameTools/SoundLib/DirectMusic.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

313 lines
7.6 KiB
C++

#include "DirectMusic.h"
#include <dmusicc.h>
#include <dmusici.h>
#include <set>
#include "MusicBuffer.h"
#include "DMusic_OggLoader.h"
/////////////////////////////////////////////////////////////////////////////////////////
//
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
/////////////////////////////////////////////////////////////////////////////////////////
//
CDirectMusic & CDirectMusic::GetInstance()
{
static CDirectMusic dmusic;
return dmusic;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
CDirectMusic::CDirectMusic()
: m_pWavLoader( NULL )
, m_pOggLoader( NULL )
, m_pPerformance( NULL )
, m_bCOMInitialized( false )
, m_pDSListener( NULL )
, m_pMusicBuffers( new MUSICBUFFERS )
{
if( !m_bCOMInitialized )
{
CoInitialize( NULL );
m_bCOMInitialized = true;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
CDirectMusic::~CDirectMusic()
{
Destroy();
if( m_bCOMInitialized )
{
CoUninitialize();
m_bCOMInitialized = false;
}
delete m_pMusicBuffers;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::Create( HWND hWnd, DWORD dwPChannels )
{
if( m_pWavLoader || m_pOggLoader || m_pPerformance )
return;
//Wav 로더 생성
HRESULT hr = CoCreateInstance( CLSID_DirectMusicLoader,
NULL,
CLSCTX_INPROC,
IID_IDirectMusicLoader8,
(void**)&m_pWavLoader );
if( FAILED( hr ) )
SNDError( "DirectMusic WavLoader Creation Error!! ErrorCode : 0x%x", hr );
//Ogg 로더 생성
CDMusic_OggLoader * pOggLoader = new CDMusic_OggLoader;
m_pOggLoader = pOggLoader;
hr = pOggLoader->Init();
if( FAILED( hr ) )
SNDError( "DirectMusic OggLoader Creation Error!! ErrorCode : 0x%x", hr );
//퍼포먼스 생성
hr = CoCreateInstance( CLSID_DirectMusicPerformance,
NULL,
CLSCTX_INPROC,
IID_IDirectMusicPerformance8,
(void**)&m_pPerformance );
if( FAILED( hr ) )
SNDError( "DirectMusic Performance Creation Error!! ErrorCode : 0x%x", hr );
hr = m_pPerformance->InitAudio( NULL,
NULL,
hWnd,
DMUS_APATH_DYNAMIC_STEREO,
dwPChannels,
DMUS_AUDIOF_ALL,
NULL );
if( FAILED( hr ) )
SNDError( "InitAudio Failed!! ErrorCode : 0x%x", hr );
Get3DListener();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::Get3DListener()
{
//3D Listener 얻어옴.
IDirectMusicAudioPath * p3DAudioPath;
HRESULT hr = m_pPerformance->CreateStandardAudioPath( DMUS_APATH_DYNAMIC_3D, 64, TRUE, &p3DAudioPath );
if( FAILED( hr ) )
SNDError( "DirectMusic CreateStandardAudioPath(3D AudioPath) Failed!! ErrorCode : 0x%x", hr );
hr = p3DAudioPath->GetObjectInPath( 0, DMUS_PATH_PRIMARY_BUFFER, 0, GUID_NULL, 0, IID_IDirectSound3DListener,
(void**)&m_pDSListener );
if( FAILED( hr ) )
SNDError( "DirectMusic GetObjectInPath(Primary Buffer) Failed!! ErrorCode : 0x%x", hr );
p3DAudioPath->Release();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::Destroy()
{
ClearMusicBuffers();
SAFE_RELEASE( m_pWavLoader );
CDMusic_OggLoader * pOggLoader = (CDMusic_OggLoader*)m_pOggLoader;
pOggLoader->UnInit();
SAFE_RELEASE( m_pOggLoader );
SAFE_RELEASE( m_pDSListener );
if( m_pPerformance )
{
m_pPerformance->Stop( NULL, NULL, 0, 0 ); //플레이 되고 있는 음악이 있으면 멈춤.
m_pPerformance->CloseDown();
SAFE_RELEASE( m_pPerformance );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::SetSearchDirectory( const char * szPath )
{
if( m_pWavLoader == NULL )
return;
//DirectMusic은 WideString만 받음.
WCHAR wstrPath[256];
int len = strlen( szPath );
MultiByteToWideChar( CP_ACP, 0, szPath, -1, wstrPath, len );
HRESULT hr = m_pWavLoader->SetSearchDirectory( GUID_DirectMusicAllTypes, wstrPath, FALSE );
if( FAILED( hr ) )
SNDError( "DirectMusic WavLoader SetSearchDirectory Failed!! ErrorCode : 0x%x", hr );
hr = m_pOggLoader->SetSearchDirectory( GUID_DirectMusicAllTypes, wstrPath, FALSE );
if( FAILED( hr ) )
SNDError( "DirectMusic OggLoader SetSearchDirectory Failed!! ErrorCode : 0x%x", hr );
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::CollectGarbage()
{
if( m_pWavLoader )
m_pWavLoader->CollectGarbage();
if( m_pOggLoader )
m_pOggLoader->CollectGarbage();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::SetDoppler( D3DVALUE distance, D3DVALUE doppler )
{
if( m_pDSListener )
{
m_pDSListener->SetDistanceFactor( distance, DS3D_IMMEDIATE );
m_pDSListener->SetDopplerFactor( doppler, DS3D_IMMEDIATE );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::SetRolloff( D3DVALUE rolloff )
{
if( m_pDSListener )
{
m_pDSListener->SetRolloffFactor( rolloff, DS3D_IMMEDIATE );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::Set3DOrientation( D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront
, D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop )
{
if( m_pDSListener )
{
m_pDSListener->SetOrientation( xFront, yFront, zFront, xTop, yTop, zTop, DS3D_IMMEDIATE );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::SetVelocity( D3DVALUE x, D3DVALUE y, D3DVALUE z )
{
if( m_pDSListener )
{
m_pDSListener->SetVelocity( x, y, z, DS3D_IMMEDIATE );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::SetPosition( D3DVALUE x, D3DVALUE y, D3DVALUE z )
{
if( m_pDSListener )
{
m_pDSListener->SetPosition( x, y, z, DS3D_IMMEDIATE );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
inline CMusicBuffer * NewMusicBuffer()
{
return new CMusicBuffer;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
inline void DeleteMusicBuffer( CMusicBuffer * pBuf )
{
delete pBuf;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::ClearMusicBuffers()
{
MUSICBUFFERS::iterator it, it_end;
it = m_pMusicBuffers->begin();
it_end = m_pMusicBuffers->end();
for( ; it != it_end; it++ )
{
::DeleteMusicBuffer( *it );
}
m_pMusicBuffers->clear();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
CMusicBuffer & CDirectMusic::NewMusicBuffer()
{
typedef MUSICBUFFERS::iterator iterator;
CMusicBuffer * pNewBuf = ::NewMusicBuffer();
pair <iterator, bool> r = m_pMusicBuffers->insert( pNewBuf );
if( r.second == false )
{
SNDError_Debug( "NewMusicBuffer Failed!!" );
}
return *pNewBuf;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CDirectMusic::DeleteMusicBuffer( CMusicBuffer & musicBuffer )
{
size_t nErased = m_pMusicBuffers->erase( &musicBuffer );
if( nErased == 0 )
{
SNDError_Debug( "DeleteMusicBuffer Failed!! 지정된 버퍼를 컨테이너에서 찾을 수 없습니다." );
}
else
{
::DeleteMusicBuffer( &musicBuffer );
}
}
/////////////////////////////////////////////////////////////////////////////////////////