Files
Client/GameTools/SoundLib/MusicBuffer.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.5 KiB
C++

#include "MusicBuffer.h"
#include "DirectMusic.h"
#include <dmusicc.h>
#include <dmusici.h>
#include <string>
/////////////////////////////////////////////////////////////////////////////////////////
//
#define NULL 0
#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; } }
/////////////////////////////////////////////////////////////////////////////////////////
//
CMusicBuffer::CMusicBuffer()
: m_pSegment( NULL )
, m_pAudioPath( NULL )
, m_pDS3DBuffer( NULL )
, m_p3DBufferParam( NULL )
, m_pDMusic( &CDirectMusic::GetInstance() )
, m_pstrFilename( new string )
{
}
/////////////////////////////////////////////////////////////////////////////////////////
//
CMusicBuffer::~CMusicBuffer()
{
Destroy();
delete m_pstrFilename;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CMusicBuffer::Create( const char * szFilename, bool b3D )
{
if( m_pSegment )
Destroy();
m_pSegment = NULL;
*m_pstrFilename = szFilename;
//DirectMusic은 WideString만 받기 때문에 변환.
WCHAR wstrFilename[256];
int len = strlen( szFilename );
MultiByteToWideChar( CP_ACP, 0, szFilename, -1, wstrFilename, len );
wstrFilename[len] = L'\0';
IDirectMusicLoader8 * pLoader = IsWaveFile( szFilename ) ? m_pDMusic->GetWavLoader() : m_pDMusic->GetOggLoader();
IDirectMusicPerformance8 * pPerformance = m_pDMusic->GetPerformance();
if( pLoader == NULL || pPerformance == NULL )
SNDError( "DirectMusic이 초기화 되지 않은 상태로 MusicBuffer를 생성하려 시도했습니다." );
//로드
HRESULT hr = pLoader->LoadObjectFromFile( CLSID_DirectMusicSegment,
IID_IDirectMusicSegment8,
wstrFilename,
(LPVOID*) &m_pSegment );
if( FAILED( hr ) )
SNDError( "DirectMusic LoadObjectFromFile Failed!! ErrorCode : 0x%x", hr );
if( b3D )
{
hr = pPerformance->CreateStandardAudioPath( DMUS_APATH_DYNAMIC_3D, 64, TRUE, &m_pAudioPath );
if( FAILED( hr ) )
SNDError( "DirectMusic CreateStandardAudioPath(3D Audiopath) Failed!! ErrorCode : 0x%x", hr );
hr = m_pAudioPath->GetObjectInPath( DMUS_PCHANNEL_ALL, DMUS_PATH_BUFFER, 0, GUID_NULL, 0, IID_IDirectSound3DBuffer,
(LPVOID*) &m_pDS3DBuffer );
if( FAILED( hr ) )
SNDError( "DirectMusic GetObjectInPath(DirectSound3DBuffer) Failed!!" );
m_p3DBufferParam = new DS3DBUFFER;
m_p3DBufferParam->dwSize = sizeof( DS3DBUFFER );
m_pDS3DBuffer->GetAllParameters( m_p3DBufferParam );
}
else
{
IUnknown* pConfig = NULL;
hr = m_pSegment->GetAudioPathConfig( &pConfig );
if( SUCCEEDED( hr ) )
{
pPerformance->CreateAudioPath( pConfig, TRUE, &m_pAudioPath );
SAFE_RELEASE( pConfig );
}
}
Download();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CMusicBuffer::Destroy()
{
if( m_pSegment )
{
if( m_pDMusic )
{
StopAll();
m_pDMusic = &CDirectMusic::GetInstance();
IDirectMusicLoader8 * pWavLoader = m_pDMusic->GetWavLoader();
IDirectMusicLoader8 * pOggLoader = m_pDMusic->GetOggLoader();
IDirectMusicPerformance8 * pPerformance = m_pDMusic->GetPerformance();
if( pWavLoader )
{
if( pWavLoader->ReleaseObjectByUnknown( m_pSegment ) == S_FALSE )
pOggLoader->ReleaseObjectByUnknown( m_pSegment );
}
if( m_pAudioPath )
m_pSegment->Unload( m_pAudioPath );
else if( pPerformance )
m_pSegment->Unload( pPerformance );
}
delete m_p3DBufferParam;
SAFE_RELEASE( m_pDS3DBuffer );
SAFE_RELEASE( m_pAudioPath );
SAFE_RELEASE( m_pSegment );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
int CMusicBuffer::Play( bool bLoop )
{
if( m_pSegment == NULL )
return -1;
m_pSegment->SetRepeats( bLoop ? DMUS_SEG_REPEAT_INFINITE : 0 );
IDirectMusicPerformance8 * pPerformance = m_pDMusic->GetPerformance();
HRESULT hr = pPerformance->PlaySegmentEx( m_pSegment,
0,
NULL,
DMUS_SEGF_SECONDARY,
0,
0,
NULL,
m_pAudioPath );
if( FAILED( hr ) )
SNDError( "DirectMusic PlaySegment Failed!! ErrorCode : 0x%x", hr );
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CMusicBuffer::Play( DWORD dwIndex, bool bLoop )
{
Play( bLoop );
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CMusicBuffer::Stop( unsigned )
{
IDirectMusicPerformance8 * pPerformance = m_pDMusic->GetPerformance();
if( m_pSegment == NULL || pPerformance == NULL )
return;
HRESULT hr = pPerformance->Stop( m_pSegment, NULL, 0, 0 );
if( FAILED( hr ) )
SNDError( "DirectMusic Stop Failed!! ErrorCode : 0x%x", hr );
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CMusicBuffer::StopAll()
{
Stop( 0 );
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CMusicBuffer::Reset( unsigned index )
{
Stop( index );
if( m_pSegment )
m_pSegment->SetStartPoint( 0 );
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CMusicBuffer::ResetAll()
{
Reset( 0 );
}
/////////////////////////////////////////////////////////////////////////////////////////
//
bool CMusicBuffer::IsAllPlaying()
{
return IsPlaying( 0 );
}
/////////////////////////////////////////////////////////////////////////////////////////
//
bool CMusicBuffer::IsAllFree()
{
return !IsPlaying( 0 );
}
/////////////////////////////////////////////////////////////////////////////////////////
//
bool CMusicBuffer::IsPlaying( unsigned )
{
IDirectMusicPerformance8 * pPerformance = m_pDMusic->GetPerformance();
if( m_pSegment == NULL || pPerformance == NULL )
return false;
return pPerformance->IsPlaying( m_pSegment, NULL ) == S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CMusicBuffer::Download()
{
HRESULT hr;
if( m_pAudioPath )
hr = m_pSegment->Download( m_pAudioPath );
else
hr = m_pSegment->Download( m_pDMusic->GetPerformance() );
if( FAILED( hr ) )
SNDError( "DirectMusic Download Segment Failed!! ErrorCode : 0x%x", hr );
}
/////////////////////////////////////////////////////////////////////////////////////////
//
DWORD CMusicBuffer::GetMemoryUse()
{
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
bool CMusicBuffer::IsSameFile( const char * szFilename )
{
return *m_pstrFilename == szFilename;
}
/////////////////////////////////////////////////////////////////////////////////////////
//
const char * CMusicBuffer::GetFilename()
{
return m_pstrFilename->c_str();
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CMusicBuffer::SetPosition( DWORD dwIndex, D3DVALUE x, D3DVALUE y, D3DVALUE z )
{
if( m_pDS3DBuffer )
{
HRESULT hr = m_pDS3DBuffer->SetPosition( x, y, z, DS3D_IMMEDIATE );
if( FAILED( hr ) )
SNDError( "MusicBuffer SetPosition Failed!!" );
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//
void CMusicBuffer::SetDistance( DWORD dwIndex, D3DVALUE minDistance, D3DVALUE maxDistance )
{
if( m_pDS3DBuffer )
{
m_pDS3DBuffer->SetMinDistance( minDistance, DS3D_IMMEDIATE );
m_pDS3DBuffer->SetMaxDistance( maxDistance, DS3D_IMMEDIATE );
}
}
/////////////////////////////////////////////////////////////////////////////////////////