#include "SoundManager.h" #include "DirectSound.h" #include "StreamBuffer.h" #include "StreamHandler.h" #include "DirectMusic.h" #include "MusicBuffer.h" #include "SoundObj_None.h" #include #include #include #include #include #include #include #include #pragma comment( lib, "winmm.lib" ) //#define REPORT_SOUNDMANAGER ///////////////////////////////////////////////////////////////////////////////////////// // struct CompareResource : public less< CSoundManager::Resource * > { bool operator()( const CSoundManager::Resource * pLhs, const CSoundManager::Resource * pRhs ) const { DWORD eval_Left = pLhs->used * ( pLhs->time / 60000 ); //»ç¿ë Ƚ¼ö ÇÑ ¹ø ´õ ¸¹Àº °Í°ú »ç¿ë ÁßÁöÇÑ ½Ã°£ÀÌ 1ºÐ ´ÊÀº °ÍÀÇ È¿°ú°¡ °°´Ù. DWORD eval_Right = pRhs->used * ( pRhs->time / 60000 ); return ( eval_Left < eval_Right ); } }; ///////////////////////////////////////////////////////////////////////////////////////// // CSoundManager & CSoundManager::GetInstance() { static CSoundManager SndManager; return SndManager; } ///////////////////////////////////////////////////////////////////////////////////////// // CSoundManager::CSoundManager() : m_DSound( CDirectSound::GetInstance() ) , m_DMusic( CDirectMusic::GetInstance() ) , m_bDSoundEnable( false ) , m_bDMusicEnable( false ) // , m_pStreamUpdater( new CStreamUpdater ) , m_pResources( new RESOURCES ) , ReportFunc( NULL ) { m_pComparer = new CompareResource; m_pUsingList = new RESLIST( *m_pComparer ); m_pUnuseList = new RESLIST( *m_pComparer ); m_pDeletedList = new RESLIST( *m_pComparer ); } ///////////////////////////////////////////////////////////////////////////////////////// // CSoundManager::~CSoundManager() { Destroy(); // delete m_pStreamUpdater; delete m_pComparer; delete m_pResources; delete m_pUsingList; delete m_pUnuseList; delete m_pDeletedList; } ///////////////////////////////////////////////////////////////////////////////////////// // void CSoundManager::Create( HWND hWnd, DWORD dwCoopLevel ) { Destroy(); try { m_bDSoundEnable = true; m_DSound.Create( hWnd, dwCoopLevel ); } catch( std::exception & ) { //DirectSound ÃʱâÈ­¿¡ ½ÇÆÐÇϸé DSound¸¦ Disable »óÅ·Π¼¼ÆÃ m_bDSoundEnable = false; } try { m_bDMusicEnable = true; m_DMusic.Create( hWnd ); } catch( std::exception & e ) { //DirectMusic ÃʱâÈ­¿¡ ½ÇÆÐÇϸé DMusicÀ» Disable »óÅ·Π¼¼ÆÃ MessageBox( NULL, "¾Ë¸²!! DirectMusicÀÇ ÃʱâÈ­¿¡ ½ÇÆÐÇÏ¿© BGMÀÌ Ãâ·ÂµÇÁö ¾ÊÀ» °ÍÀÔ´Ï´Ù.", e.what(), MB_OK ); m_bDMusicEnable = false; } // m_pStreamUpdater->Create(); } ///////////////////////////////////////////////////////////////////////////////////////// // void CSoundManager::Destroy() { // m_pStreamUpdater->Destroy(); for( RESOURCES::iterator it = m_pResources->begin(); it != m_pResources->end(); it++ ) { if( it->second ) { if( it->second->pSndBuf ) { if( it->second->pSndBuf->GetType() == SNDOBJTYPE_MUSICBUFFER ) { m_DMusic.DeleteMusicBuffer( *((CMusicBuffer*)it->second->pSndBuf) ); } else { delete it->second->pSndBuf; } it->second->pSndBuf = NULL; } delete it->second; it->second = NULL; } } m_pResources->clear(); } ///////////////////////////////////////////////////////////////////////////////////////// // CDirectSound & CSoundManager::GetDirectSound() { return m_DSound; } ///////////////////////////////////////////////////////////////////////////////////////// // ISoundObject & CSoundManager::GetBuffer( const char * szFilename, bool b3DSound, bool bStream, int nBuf, DWORD dwAddFlag ) { typedef RESOURCES::iterator RES_ITER; typedef RESLIST::iterator LIST_ITER; //¸ÕÀú Resources¿¡¼­ ÁÖ¾îÁø À̸§À¸·Î µÈ ¹öÆÛ°¡ ÀÖ´ÂÁö ã´Â´Ù. RES_ITER it = m_pResources->find( szFilename ); if( it == m_pResources->end() ) { //¾øÀ¸¸é Resources¿¡ »õ·Î Ãß°¡Çϰí, using list¿¡µµ Ãß°¡ÇÑ ´ÙÀ½ ¹öÆÛ¸¦ ¸®ÅÏÇÑ´Ù. Resource & res = AddResource( szFilename, b3DSound, bStream, nBuf, dwAddFlag ); Caching(); return *res.pSndBuf; } else { //ÀÖÀ¸¸é using ¸®½ºÆ®·Î ¿Å±â°í, »ç¿ë ºóµµ º¯¼ö¸¦ Áõ°¡½ÃŲ´Ù. Resource & res = *(it->second); MoveResourceTo( res, m_pUsingList ); res.used++; if( res.pSndBuf == NULL ) { CreateSoundBuffer( res, szFilename, b3DSound, bStream, nBuf, dwAddFlag ); } Caching(); return *res.pSndBuf; } } ///////////////////////////////////////////////////////////////////////////////////////// // void CSoundManager::Update() { // m_pStreamUpdater->Update(); } ///////////////////////////////////////////////////////////////////////////////////////// // CSoundManager::RESLIST * CSoundManager::GetListOfState( eState state ) { RESLIST * pList = m_pUsingList; switch( state ) { case STATE_UNUSE: pList = m_pUnuseList; break; case STATE_DELETED: pList = m_pDeletedList; break; } return pList; } ///////////////////////////////////////////////////////////////////////////////////////// // CSoundManager::eState CSoundManager::GetStateOfList( RESLIST * pList ) { if( pList == m_pUsingList ) return STATE_USING; else if( pList == m_pUnuseList ) return STATE_UNUSE; else if( pList == m_pDeletedList ) return STATE_DELETED; else assert( false ); return STATE_USING; } ///////////////////////////////////////////////////////////////////////////////////////// // void CSoundManager::CreateSoundBuffer( Resource & res, const char * szFilename, bool b3DSound, bool bStream, int nBuf, DWORD dwAddFlag ) { if( bStream ) { if( m_bDMusicEnable ) { CMusicBuffer * p = &m_DMusic.NewMusicBuffer(); p->Create( szFilename, b3DSound ); res.pSndBuf = p; // CStreamBuffer * p = new CStreamBuffer(); // p->Create( m_DSound.GetDS(), szFilename, b3DSound, nBuf, dwAddFlag ); // m_pStreamUpdater->Add( *p ); } else { res.pSndBuf = new CSoundObj_None; } } else { if( m_bDSoundEnable ) { CSoundBuffer * p = new CSoundBuffer(); p->Create( m_DSound.GetDS(), szFilename, b3DSound, nBuf, dwAddFlag ); res.pSndBuf = p; } else { res.pSndBuf = new CSoundObj_None; } } res.state = STATE_USING; res.time = timeGetTime(); //-------¸®Æ÷Æ®---------------// #ifdef REPORT_SOUNDMANAGER char szBuffer[1024]; sprintf( szBuffer, "**%s »ý¼ºµÊ ==> %s ==> %d ¸¸Å­ÀÇ ¸Þ¸ð¸® »ç¿ë. [[ÇöÀç ¸Þ¸ð¸®:%d]]\r\n", ( bStream ? "½ºÆ®¸²¹öÆÛ" : "½ºÅÂÆ½¹öÆÛ" ), szFilename, res.pSndBuf->GetMemoryUse(), m_dwCurrentByte ); if( ReportFunc ) ReportFunc( szBuffer ); #endif //----------------------------// } ///////////////////////////////////////////////////////////////////////////////////////// // CSoundManager::Resource & CSoundManager::AddResource( const char * szFilename, bool b3DSound, bool bStream, int nBuf, DWORD dwAddFlag ) { typedef RESOURCES::iterator RES_ITER; typedef RESLIST::iterator LIST_ITER; Resource * data = new Resource; data->used = 0; CreateSoundBuffer( *data, szFilename, b3DSound, bStream, nBuf, dwAddFlag ); pair result = m_pResources->insert( RESOURCES::value_type( szFilename, data ) ); assert( result.second == true ); pair result2 = m_pUsingList->insert( data ); assert( result2.second == true ); return *data; } ///////////////////////////////////////////////////////////////////////////////////////// // void CSoundManager::MoveResourceTo( Resource & res, RESLIST * pDest ) { typedef RESLIST::iterator LIST_ITER; RESLIST * pList = GetListOfState( res.state ); LIST_ITER it_res = pList->find( &res ); if( it_res != pList->end() ) { pList->erase( it_res ); pDest->insert( &res ); } res.state = GetStateOfList( pDest ); res.time = timeGetTime(); /* if( res.pSndBuf ) { if( res.pSndBuf->GetEventNotify() != 0 ) { if( res.pSndBuf->GetType() == SNDOBJTYPE_STREAMBUFFER ) { m_pStreamUpdater->Remove( *((CStreamBuffer*)res.pSndBuf) ); } } }*/ } ///////////////////////////////////////////////////////////////////////////////////////// // void CSoundManager::Caching() { typedef RESLIST::iterator LIST_ITER; DWORD curTime = timeGetTime(); //using ¸®½ºÆ®¸¦ ¸ðµÎ µ¹¸ç, PlayÁßÀÎÁö °Ë»çÇÑ´Ù. for( LIST_ITER it = m_pUsingList->begin(); it != m_pUsingList->end(); it++ ) { Resource & res = **it; if( res.pSndBuf->IsAllFree() ) { if( curTime - res.time > 5000 ) { //PlayÁßÀÌ ¾Æ´Ñ °ÍÁß¿¡¼­ 5Ãʰ¡ Áö³­ °ÍµéÀº ½Ã°£À» ±â·ÏÇØµÎ°í, unusing ¸®½ºÆ®¿¡ Ãß°¡ÇÑ´Ù. res.time = timeGetTime(); LIST_ITER it2 = it; it2++; MoveResourceTo( res, m_pUnuseList ); it = it2; //UsingList¿¡¼­ »èÁ¦µÈ °ÍÀÌ ÀÖÀ¸¹Ç·Î itÀÇ À§Ä¡°¡ Á¦´ë·Î µÇµµ·Ï ÇÔ. } } } //Unused list´Â 10°³ ÀÌÇϱîÁö¸¸ Çã¿ëÇÑ´Ù. while( m_pUnuseList->size() > 10 ) { unsigned ss = m_pUnuseList->size(); Resource * pRes = *(m_pUnuseList->begin()); MoveResourceTo( *pRes, m_pDeletedList ); if( pRes->pSndBuf->GetType() == SNDOBJTYPE_MUSICBUFFER ) { m_DMusic.DeleteMusicBuffer( *((CMusicBuffer*)pRes->pSndBuf) ); } else { delete pRes->pSndBuf; } pRes->pSndBuf = NULL; //--------¸®Æ÷Æ®--------------// #ifdef REPORT_SOUNDMANAGER char szBuffer[1024]; sprintf( szBuffer, "**¹öÆÛÆó±âµÊ ==> %s ==> [[ÇöÀç ¸Þ¸ð¸®:%d]]\r\n", it2->first.c_str(), m_dwCurrentByte ); if( ReportFunc ) ReportFunc( szBuffer ); #endif } } /////////////////////////////////////////////////////////////////////////////////////////