229 lines
No EOL
6.3 KiB
C++
229 lines
No EOL
6.3 KiB
C++
#include "StdAfx.h"
|
|
#include "EtSoundChannelGroup.h"
|
|
#include "EtSoundChannel.h"
|
|
#include "SundriesFunc.h"
|
|
#include "EtSoundEngine.h"
|
|
#include "fmod.hpp"
|
|
|
|
#ifdef _DEBUG
|
|
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
|
#endif
|
|
|
|
|
|
CEtSoundChannelGroup::CEtSoundChannelGroup( CEtSoundEngine *pEngine, const char *szName, int nIndex )
|
|
{
|
|
m_szName = szName;
|
|
m_nIndex = nIndex;
|
|
m_nChannelRefCount = 0;
|
|
m_pGroup = NULL;
|
|
m_pEngine = pEngine;
|
|
m_fTargetVolume = 0.f;
|
|
m_fCurrentVolume = 0.f;
|
|
m_fCurrentDelta = 0.f;
|
|
|
|
CEtSoundEngine::s_FMODFuncLock.Lock();
|
|
FMOD_API_CHECK( m_pEngine->GetFMODSystem()->createChannelGroup( szName, &m_pGroup ) );
|
|
FMOD_API_CHECK( m_pGroup->getVolume( &m_fTargetVolume ) );
|
|
CEtSoundEngine::s_FMODFuncLock.UnLock();
|
|
m_fCurrentVolume = m_fTargetVolume;
|
|
m_fVolumeDelta = 0.f;
|
|
|
|
m_fMasterVolume = 1.f;
|
|
}
|
|
|
|
CEtSoundChannelGroup::~CEtSoundChannelGroup()
|
|
{
|
|
RemoveAllChannel();
|
|
if( m_pGroup ) {
|
|
CEtSoundEngine::s_FMODFuncLock.Lock();
|
|
FMOD_API_CHECK( m_pGroup->release() ); // 이곳에서 가끔 크래쉬... WinAmp 에서 Output Device 를
|
|
// DirectSound 로 세팅하는 경우 종종 충돌이 생기는듯....
|
|
CEtSoundEngine::s_FMODFuncLock.UnLock();
|
|
|
|
m_pGroup = NULL;
|
|
}
|
|
}
|
|
|
|
const char *CEtSoundChannelGroup::GetName()
|
|
{
|
|
return m_szName.c_str();
|
|
}
|
|
|
|
int CEtSoundChannelGroup::GetIndex()
|
|
{
|
|
return m_nIndex;
|
|
}
|
|
|
|
EtSoundChannelHandle CEtSoundChannelGroup::InsertChannel( int nSoundIndex, FMOD::Channel *pChannel )
|
|
{
|
|
ScopeLock<CSyncLock> Lock(m_InsertLock);
|
|
EtSoundChannelHandle hChannel = (new CEtSoundChannel( m_nChannelRefCount, nSoundIndex, this ))->GetMySmartPtr();
|
|
hChannel->SetChannel( pChannel );
|
|
m_hVecChannelList.push_back( hChannel );
|
|
m_nChannelRefCount++;
|
|
|
|
hChannel->SetCallback( ChannelStopCallbackFunc );
|
|
return hChannel;
|
|
}
|
|
|
|
void CEtSoundChannelGroup::RemoveChannel( int nChannelIndex )
|
|
{
|
|
ScopeLock<CSyncLock> Lock(m_InsertLock);
|
|
for( DWORD i=0; i<m_hVecChannelList.size(); i++ ) {
|
|
if( !m_hVecChannelList[i] ) {
|
|
m_hVecChannelList.erase( m_hVecChannelList.begin() + i );
|
|
i--;
|
|
continue;
|
|
}
|
|
if( m_hVecChannelList[i]->GetIndex() == nChannelIndex ) {
|
|
SAFE_RELEASE_SPTR( m_hVecChannelList[i] );
|
|
m_hVecChannelList.erase( m_hVecChannelList.begin() + i );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CEtSoundChannelGroup::RemoveAllChannel()
|
|
{
|
|
CEtSoundEngine::s_FMODFuncLock.Lock();
|
|
m_pGroup->stop();
|
|
CEtSoundEngine::s_FMODFuncLock.UnLock();
|
|
SAFE_RELEASE_SPTRVEC( m_hVecChannelList );
|
|
}
|
|
|
|
EtSoundChannelHandle CEtSoundChannelGroup::GetChannel( int nChannelIndex )
|
|
{
|
|
for( DWORD i=0; i<m_hVecChannelList.size(); i++ ) {
|
|
if( m_hVecChannelList[i]->GetIndex() == nChannelIndex ) return m_hVecChannelList[i];
|
|
}
|
|
return CEtSoundChannel::Identity();
|
|
}
|
|
|
|
void CEtSoundChannelGroup::Process( float fDelta )
|
|
{
|
|
if( m_fCurrentDelta > 0.f ) {
|
|
m_fCurrentDelta -= fDelta;
|
|
if( m_fCurrentDelta <= 0.f ) m_fCurrentDelta = 0.f;
|
|
float fRatio = 1.f - ( 1.f / m_fVolumeDelta * m_fCurrentDelta );
|
|
float fVolume = m_fCurrentVolume + ( ( m_fTargetVolume - m_fCurrentVolume ) * fRatio );
|
|
CEtSoundEngine::s_FMODFuncLock.Lock();
|
|
FMOD_API_CHECK( m_pGroup->setVolume( fVolume * ( IsMute() ? 0.f : m_fMasterVolume ) ) );
|
|
CEtSoundEngine::s_FMODFuncLock.UnLock();
|
|
}
|
|
}
|
|
|
|
FMOD_RESULT F_CALLBACK CEtSoundChannelGroup::ChannelStopCallbackFunc( FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, void *commanddata1, void *commanddata2 )
|
|
{
|
|
#pragma warning(disable:4312)
|
|
if( type == FMOD_CHANNEL_CALLBACKTYPE_END ) {
|
|
void *pUserData;
|
|
FMOD_API_CHECK( ((FMOD::Channel *)channel)->getUserData( &pUserData ) );
|
|
int nIndex = *(int*)pUserData;
|
|
|
|
EtSoundChannelHandle hChannel = CEtSoundChannel::GetSmartPtr( nIndex );
|
|
|
|
if( hChannel && hChannel->GetGroup() ) {
|
|
hChannel->SetRollOff( 0 );
|
|
hChannel->SetChannel( NULL );
|
|
hChannel->GetGroup()->RemoveChannel( hChannel->GetIndex() );
|
|
}
|
|
return FMOD_OK;
|
|
}
|
|
return FMOD_OK;
|
|
#pragma warning(default:4312)
|
|
}
|
|
|
|
void CEtSoundChannelGroup::SetVolume( float fValue, float fDelta )
|
|
{
|
|
CEtSoundEngine::s_FMODFuncLock.Lock();
|
|
FMOD_API_CHECK( m_pGroup->getVolume( &m_fCurrentVolume ) );
|
|
CEtSoundEngine::s_FMODFuncLock.UnLock();
|
|
m_fCurrentVolume *= ( m_fMasterVolume <= 0.f ) ? 0.f : ( 1.f / m_fMasterVolume );
|
|
m_fCurrentDelta = fDelta;
|
|
m_fVolumeDelta = fDelta;
|
|
m_fTargetVolume = fValue;
|
|
if( fDelta == 0.f ) {
|
|
CEtSoundEngine::s_FMODFuncLock.Lock();
|
|
FMOD_API_CHECK( m_pGroup->setVolume( fValue * ( IsMute() ? 0.f : m_fMasterVolume ) ) );
|
|
CEtSoundEngine::s_FMODFuncLock.UnLock();
|
|
}
|
|
}
|
|
|
|
float CEtSoundChannelGroup::GetVolume()
|
|
{
|
|
return m_fTargetVolume;
|
|
}
|
|
|
|
void CEtSoundChannelGroup::CheckSoundIndexAndRemoveChannel( int nSoundIndex )
|
|
{
|
|
ScopeLock<CSyncLock> Lock(m_InsertLock);
|
|
for( DWORD i=0; i<m_hVecChannelList.size(); i++ ) {
|
|
if( m_hVecChannelList[i]->GetSoundIndex() == nSoundIndex ) {
|
|
SAFE_RELEASE_SPTR( m_hVecChannelList[i] );
|
|
m_hVecChannelList.erase( m_hVecChannelList.begin() + i );
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CEtSoundChannelGroup::Pause()
|
|
{
|
|
ScopeLock<CSyncLock> Lock( CEtSoundEngine::s_FMODFuncLock );
|
|
FMOD_API_CHECK( m_pGroup->setPaused( true ) );
|
|
}
|
|
|
|
void CEtSoundChannelGroup::Resume()
|
|
{
|
|
ScopeLock<CSyncLock> Lock( CEtSoundEngine::s_FMODFuncLock );
|
|
FMOD_API_CHECK( m_pGroup->setPaused( false ));
|
|
}
|
|
|
|
void CEtSoundChannelGroup::Stop()
|
|
{
|
|
ScopeLock<CSyncLock> Lock( CEtSoundEngine::s_FMODFuncLock );
|
|
FMOD_API_CHECK( m_pGroup->stop());
|
|
}
|
|
|
|
void CEtSoundChannelGroup::Play()
|
|
{
|
|
ScopeLock<CSyncLock> Lock( CEtSoundEngine::s_FMODFuncLock );
|
|
FMOD_API_CHECK( m_pGroup->setPaused( false ));
|
|
}
|
|
|
|
void CEtSoundChannelGroup::SetMute( bool bMute )
|
|
{
|
|
ScopeLock<CSyncLock> Lock( CEtSoundEngine::s_FMODFuncLock );
|
|
FMOD_API_CHECK( m_pGroup->setMute( bMute ));
|
|
if( bMute ) {
|
|
FMOD_API_CHECK( m_pGroup->setVolume( 0.f ));
|
|
}
|
|
else FMOD_API_CHECK( m_pGroup->setVolume( m_fTargetVolume * m_fMasterVolume ));
|
|
}
|
|
|
|
bool CEtSoundChannelGroup::IsMute()
|
|
{
|
|
ScopeLock<CSyncLock> Lock( CEtSoundEngine::s_FMODFuncLock );
|
|
bool bMute;
|
|
FMOD_API_CHECK( m_pGroup->getMute( &bMute ));
|
|
return bMute;
|
|
}
|
|
|
|
void CEtSoundChannelGroup::SetMasterVolume( float fValue )
|
|
{
|
|
m_fMasterVolume = fValue;
|
|
|
|
CEtSoundEngine::s_FMODFuncLock.Lock();
|
|
if( IsMute() ) {
|
|
FMOD_API_CHECK( m_pGroup->setVolume( 0.f ));
|
|
}
|
|
else FMOD_API_CHECK( m_pGroup->setVolume( m_fTargetVolume * m_fMasterVolume ));
|
|
CEtSoundEngine::s_FMODFuncLock.UnLock();
|
|
// FMOD_API_CHECK( m_pGroup->setVolume( m_fTargetVolume * m_fMasterVolume ));
|
|
}
|
|
|
|
float CEtSoundChannelGroup::GetMasterVolume()
|
|
{
|
|
return m_fMasterVolume;
|
|
} |