2024-12-21 10:04:04 +08:00
|
|
|
|
#include "StdAfx.h"
|
|
|
|
|
|
#include "EtSoundEngine.h"
|
|
|
|
|
|
#include "EtSoundChannelGroup.h"
|
|
|
|
|
|
#include "EtSoundChannel.h"
|
|
|
|
|
|
#include "SundriesFunc.h"
|
|
|
|
|
|
#include "EtLoader.h"
|
|
|
|
|
|
#include <process.h>
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
|
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
CEtSoundEngine *CEtSoundEngine::s_pCurrentCallbackPtr = NULL;
|
|
|
|
|
|
CSyncLock CEtSoundEngine::s_FMODFuncLock;
|
|
|
|
|
|
bool CEtSoundEngine::s_bFMODFuncLock = false;
|
|
|
|
|
|
CSyncLock CEtSoundEngine::s_ChannelLock;
|
|
|
|
|
|
bool CEtSoundEngine::s_bChannelLock = false;
|
|
|
|
|
|
|
|
|
|
|
|
CEtSoundEngine::CEtSoundEngine()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pSystem = NULL;
|
|
|
|
|
|
m_nSoundRefCount = 0;
|
|
|
|
|
|
m_bEnable = true;
|
|
|
|
|
|
m_dwMainThreadID = 0;
|
|
|
|
|
|
m_nTotalSoundSize = 0;
|
|
|
|
|
|
|
|
|
|
|
|
s_pCurrentCallbackPtr = this;
|
|
|
|
|
|
|
|
|
|
|
|
m_fMaxVolumeRate = 0.6f; // #28730 <20><>ü<EFBFBD><C3BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ҹ<EFBFBD> ũ<><C5A9><EFBFBD>ؼ<EFBFBD> 60%<25><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CEtSoundEngine::~CEtSoundEngine()
|
|
|
|
|
|
{
|
|
|
|
|
|
Finalize();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CEtSoundEngine::Initialize( OutputTypeEnum Type )
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(s_FMODFuncLock);
|
|
|
|
|
|
m_dwMainThreadID = GetCurrentThreadId();
|
|
|
|
|
|
FMOD_RESULT Result;
|
|
|
|
|
|
Result = FMOD::System_Create( &m_pSystem );
|
|
|
|
|
|
if( Result != FMOD_OK ) return false;
|
|
|
|
|
|
unsigned int nVersion;
|
|
|
|
|
|
Result = m_pSystem->getVersion( &nVersion );
|
|
|
|
|
|
if( Result != FMOD_OK ) return false;
|
|
|
|
|
|
if( nVersion < FMOD_VERSION ) {
|
|
|
|
|
|
char szStr[256];
|
|
|
|
|
|
sprintf_s( szStr, "You are using an old version of FMOD %08x. This program requires %08x", nVersion, FMOD_VERSION );
|
|
|
|
|
|
MessageBox( NULL, szStr, "Error", MB_OK );
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
int nNumDriver;
|
|
|
|
|
|
int nNumChannel = 0;
|
|
|
|
|
|
Result = m_pSystem->getNumDrivers( &nNumDriver );
|
|
|
|
|
|
if( nNumDriver == 0 ) {
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->setOutput( FMOD_OUTPUTTYPE_NOSOUND ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>Ŀ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
FMOD_SPEAKERMODE SpeakerMode;
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->getDriverCaps( 0, NULL, NULL, NULL, &SpeakerMode ));
|
|
|
|
|
|
Result = m_pSystem->setSpeakerMode( SpeakerMode );
|
|
|
|
|
|
if( Result != FMOD_OK ) {
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->setSpeakerMode( FMOD_SPEAKERMODE_STEREO ));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
FMOD_OUTPUTTYPE OutputType = FMOD_OUTPUTTYPE_AUTODETECT;
|
|
|
|
|
|
switch( Type ) {
|
|
|
|
|
|
case AutoDetected: OutputType = FMOD_OUTPUTTYPE_AUTODETECT; break;
|
|
|
|
|
|
case DirectSound: OutputType = FMOD_OUTPUTTYPE_DSOUND; break;
|
|
|
|
|
|
case WindowsMM: OutputType = FMOD_OUTPUTTYPE_WINMM; break;
|
|
|
|
|
|
case OpenAL: OutputType = FMOD_OUTPUTTYPE_OPENAL; break;
|
|
|
|
|
|
case WASAPI: OutputType = FMOD_OUTPUTTYPE_WASAPI; break;
|
|
|
|
|
|
}
|
|
|
|
|
|
Result = m_pSystem->setOutput( OutputType );
|
|
|
|
|
|
if( Result != FMOD_OK ) {
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->setOutput( FMOD_OUTPUTTYPE_AUTODETECT ));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ü<><C3BC> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
int n2DChannel, n3DChannel, nTotalChannel;
|
|
|
|
|
|
Result = m_pSystem->getHardwareChannels( &n2DChannel, &n3DChannel, &nTotalChannel );
|
|
|
|
|
|
Result = m_pSystem->setHardwareChannels( n2DChannel, n2DChannel, n3DChannel, n3DChannel );
|
|
|
|
|
|
Result = m_pSystem->setSoftwareChannels( 64 );
|
|
|
|
|
|
nNumChannel = n2DChannel + 64;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Result = m_pSystem->init( nNumChannel, FMOD_INIT_NORMAL, NULL );
|
|
|
|
|
|
if( Type == WASAPI ) {
|
|
|
|
|
|
if( Result == FMOD_ERR_OUTPUT_INIT ) {
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->setOutput( FMOD_OUTPUTTYPE_NOSOUND ) );
|
|
|
|
|
|
Result = m_pSystem->init( nNumChannel, FMOD_INIT_NORMAL, NULL ); // <20>̷<EFBFBD> <20><>Ȳ<EFBFBD><C8B2> <20>ȳ<EFBFBD><C8B3><EFBFBD><EFBFBD><EFBFBD> <20>ϴ¹<CFB4><C2B9><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..?
|
|
|
|
|
|
}
|
|
|
|
|
|
else if( Result != FMOD_OK ) {
|
|
|
|
|
|
FMOD_API_CHECK( Result );
|
|
|
|
|
|
FMOD_SPEAKERMODE SpeakerMode;
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->getDriverCaps( 0, NULL, NULL, NULL, &SpeakerMode ));
|
|
|
|
|
|
Result = m_pSystem->setSpeakerMode( SpeakerMode );
|
|
|
|
|
|
Result = m_pSystem->init( nNumChannel, FMOD_INIT_WASAPI_EXCLUSIVE, NULL ); // WASAPI <20><><EFBFBD>нÿ<D0BD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>õ<EFBFBD><C3B5>غ<EFBFBD><D8BA><EFBFBD>. (<28>ܺ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FMOD_API_CHECK( Result );
|
|
|
|
|
|
|
|
|
|
|
|
if( Result != FMOD_OK ) { // <20><EFBFBD><D7B7><EFBFBD> <20>ȵǴ<C8B5> <20><><EFBFBD>쿣 NoSound<6E><64> <20><><EFBFBD>ش<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD>Ҷ<EFBFBD> ũ<><C5A9><EFBFBD><EFBFBD> <20><><EFBFBD>°<EFBFBD> <20><><EFBFBD><EFBFBD>.
|
|
|
|
|
|
m_pSystem->setOutput( FMOD_OUTPUTTYPE_NOSOUND );
|
|
|
|
|
|
Result = m_pSystem->init( nNumChannel, FMOD_INIT_NORMAL, NULL );
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3D Setting
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->set3DSettings( 1.f, 100.f, 1.f ));
|
|
|
|
|
|
|
|
|
|
|
|
CreateChannelGroup( "NULL" );
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CEtSoundEngine::ReInitialize()
|
|
|
|
|
|
{
|
|
|
|
|
|
Finalize();
|
|
|
|
|
|
return Initialize();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::LockFMODFunc()
|
|
|
|
|
|
{
|
|
|
|
|
|
s_FMODFuncLock.Lock();
|
|
|
|
|
|
s_bFMODFuncLock = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::UnLockFMODFunc()
|
|
|
|
|
|
{
|
|
|
|
|
|
s_FMODFuncLock.UnLock();
|
|
|
|
|
|
s_bFMODFuncLock = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::UnLockExceptionFMODFunc()
|
|
|
|
|
|
{
|
|
|
|
|
|
if( s_bFMODFuncLock ) UnLockFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::LockChannel()
|
|
|
|
|
|
{
|
|
|
|
|
|
s_ChannelLock.Lock();
|
|
|
|
|
|
s_bChannelLock = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::UnLockChannel()
|
|
|
|
|
|
{
|
|
|
|
|
|
s_ChannelLock.UnLock();
|
|
|
|
|
|
s_bChannelLock = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::UnLockExceptionChannel()
|
|
|
|
|
|
{
|
|
|
|
|
|
if( s_bChannelLock ) UnLockChannel();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CEtSoundEngine::_Finalize()
|
|
|
|
|
|
{
|
|
|
|
|
|
if( m_pSystem == NULL ) return true;
|
|
|
|
|
|
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(m_LoadLock);
|
|
|
|
|
|
LockChannel();
|
|
|
|
|
|
|
|
|
|
|
|
m_dwMainThreadID = 0;
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ ) {
|
|
|
|
|
|
m_pVecChannelGroupList[i]->RemoveAllChannel();
|
|
|
|
|
|
}
|
|
|
|
|
|
Process(0.f);
|
|
|
|
|
|
|
|
|
|
|
|
SAFE_DELETE_PVEC( m_pVecChannelGroupList );
|
|
|
|
|
|
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecSoundList.size(); i++ ) {
|
|
|
|
|
|
if( m_pVecSoundList[i]->szFileName.empty() ) continue;
|
|
|
|
|
|
SAFE_DELETE( m_pVecSoundList[i] );
|
|
|
|
|
|
m_pVecSoundList.erase( m_pVecSoundList.begin() + i );
|
|
|
|
|
|
i--;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LockFMODFunc();
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->close() );
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->release() );
|
|
|
|
|
|
UnLockFMODFunc();
|
|
|
|
|
|
m_pSystem = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
bool CEtSoundEngine::Finalize()
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
_Finalize();
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::Process( float fDelta )
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
_Process( fDelta );
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::_Process( float fDelta )
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(m_LoadLock);
|
|
|
|
|
|
if ( !m_bEnable ) return;
|
|
|
|
|
|
if( !m_pSystem ) return;
|
|
|
|
|
|
|
|
|
|
|
|
s_FMODFuncLock.Lock();
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->update());
|
|
|
|
|
|
s_FMODFuncLock.UnLock();
|
|
|
|
|
|
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ ) {
|
|
|
|
|
|
m_pVecChannelGroupList[i]->Process( fDelta );
|
|
|
|
|
|
}
|
|
|
|
|
|
ProcessRemoveSoundQueue();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CEtSoundEngine::CreateChannelGroup( const char *szChannelName, int nChannelIndex )
|
|
|
|
|
|
{
|
|
|
|
|
|
LockChannel();
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ ) {
|
|
|
|
|
|
if( strcmp( m_pVecChannelGroupList[i]->GetName(), szChannelName ) == NULL ) {
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
if( m_pVecChannelGroupList[i]->GetIndex() == nChannelIndex ) {
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
int nRefCount = 0;
|
|
|
|
|
|
while(1) {
|
|
|
|
|
|
bool bExistChannel = false;
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ ) {
|
|
|
|
|
|
if( m_pVecChannelGroupList[i]->GetIndex() == nRefCount ) {
|
|
|
|
|
|
bExistChannel = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if( bExistChannel == false ) break;
|
|
|
|
|
|
|
|
|
|
|
|
nRefCount++;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( nChannelIndex == -1 ) nChannelIndex = nRefCount;
|
|
|
|
|
|
|
|
|
|
|
|
CEtSoundChannelGroup *pChannel = new CEtSoundChannelGroup( this, szChannelName, nChannelIndex );
|
|
|
|
|
|
|
|
|
|
|
|
m_pVecChannelGroupList.push_back( pChannel );
|
|
|
|
|
|
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
return nChannelIndex;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::RemoveChannelGroup( const char *szChannelName )
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(s_ChannelLock);
|
|
|
|
|
|
CEtSoundChannelGroup *pChannel = NULL;
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ ) {
|
|
|
|
|
|
if( strcmp( m_pVecChannelGroupList[i]->GetName(), szChannelName ) == NULL ) {
|
|
|
|
|
|
SAFE_DELETE( m_pVecChannelGroupList[i] );
|
|
|
|
|
|
m_pVecChannelGroupList.erase( m_pVecChannelGroupList.begin() + i );
|
|
|
|
|
|
// pChannel = m_pVecChannelGroupList[i];
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// if( pChannel == NULL ) return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CEtSoundChannelGroup *CEtSoundEngine::GetChannelGroup( const char *szChannelName )
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(s_ChannelLock);
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ ) {
|
|
|
|
|
|
if( strcmp( m_pVecChannelGroupList[i]->GetName(), szChannelName ) == NULL ) return m_pVecChannelGroupList[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CEtSoundChannelGroup *CEtSoundEngine::GetChannelGroup( int nChannelIndex )
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(s_ChannelLock);
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ ) {
|
|
|
|
|
|
if( m_pVecChannelGroupList[i]->GetIndex() == nChannelIndex ) return m_pVecChannelGroupList[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CEtSoundEngine::LoadSound( const char *szFileName, bool b3DSound, bool bStream )
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
return _LoadSound( szFileName, b3DSound, bStream );
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
int CEtSoundEngine::_LoadSound( const char *szFileName, bool b3DSound, bool bStream )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( !szFileName ) return -1;
|
|
|
|
|
|
m_LoadLock.Lock();
|
|
|
|
|
|
std::pair< MapSearchIter, MapSearchIter > range = m_szMapSearch.equal_range( szFileName );
|
|
|
|
|
|
for ( MapSearchIter itSearch = range.first; itSearch != range.second; ++itSearch ) {
|
|
|
|
|
|
if( itSearch->second->b3D == b3DSound ) {
|
|
|
|
|
|
itSearch->second->nRefCount++;
|
|
|
|
|
|
m_LoadLock.UnLock();
|
|
|
|
|
|
return itSearch->second->nIndex;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
m_LoadLock.UnLock();
|
|
|
|
|
|
|
|
|
|
|
|
bool bValid = false;
|
|
|
|
|
|
CResMngStream Stream( szFileName );
|
|
|
|
|
|
if( Stream.IsValid() == false ) return -1;
|
|
|
|
|
|
|
|
|
|
|
|
SoundStruct *pStruct = new SoundStruct;
|
|
|
|
|
|
pStruct->szFileName = szFileName;
|
|
|
|
|
|
m_LoadLock.Lock();
|
|
|
|
|
|
pStruct->nIndex = m_nSoundRefCount++;
|
|
|
|
|
|
m_LoadLock.UnLock();
|
|
|
|
|
|
pStruct->nRefCount = 1;
|
|
|
|
|
|
pStruct->b3D = b3DSound;
|
|
|
|
|
|
pStruct->nSize = Stream.Size();
|
|
|
|
|
|
|
|
|
|
|
|
pStruct->pData = new char[Stream.Size()];
|
|
|
|
|
|
Stream.Read( pStruct->pData, Stream.Size() );
|
|
|
|
|
|
|
|
|
|
|
|
FMOD_RESULT Result;
|
|
|
|
|
|
FMOD_MODE Mode;
|
|
|
|
|
|
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
|
|
|
|
|
if( b3DSound ) Mode = FMOD_3D | FMOD_OPENMEMORY | FMOD_CREATECOMPRESSEDSAMPLE | FMOD_SOFTWARE;
|
|
|
|
|
|
else Mode = FMOD_DEFAULT | FMOD_OPENMEMORY | FMOD_CREATECOMPRESSEDSAMPLE | FMOD_SOFTWARE;
|
|
|
|
|
|
#else
|
|
|
|
|
|
if( b3DSound ) Mode = FMOD_3D | FMOD_OPENMEMORY;
|
|
|
|
|
|
else Mode = FMOD_DEFAULT | FMOD_OPENMEMORY;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
FMOD_CREATESOUNDEXINFO Info;
|
|
|
|
|
|
memset( &Info, 0, sizeof(FMOD_CREATESOUNDEXINFO) );
|
|
|
|
|
|
Info.length = Stream.Size();
|
|
|
|
|
|
Info.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
|
|
|
|
|
|
|
|
|
|
|
|
// <20>̺κ<CCBA> <20><><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD><EFBFBD><EFBFBD><EEBAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FMOD <20><> thread <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȵȰ<C8B5><C8B0><EFBFBD><EFBFBD><EFBFBD> <20>ϴ<EFBFBD> <20>Ӵϴ<D3B4>. ( <20><><EFBFBD>Ⱑ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ɸ<EFBFBD><C9B8>ϴ<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. )
|
|
|
|
|
|
if( bStream ) {
|
|
|
|
|
|
s_FMODFuncLock.Lock();
|
|
|
|
|
|
Result = m_pSystem->createStream( pStruct->pData, Mode, &Info, &pStruct->pSound );
|
|
|
|
|
|
s_FMODFuncLock.UnLock();
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
s_FMODFuncLock.Lock();
|
|
|
|
|
|
Result = m_pSystem->createSound( pStruct->pData, Mode, &Info, &pStruct->pSound );
|
|
|
|
|
|
s_FMODFuncLock.UnLock();
|
|
|
|
|
|
SAFE_DELETEA( pStruct->pData );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( Result != FMOD_OK ) {
|
|
|
|
|
|
SAFE_DELETE( pStruct );
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
pStruct->pSound->getFormat( &pStruct->Type, &pStruct->Format, &pStruct->nChannel, &pStruct->nBit );
|
|
|
|
|
|
m_nTotalSoundSize += pStruct->nSize;
|
|
|
|
|
|
#ifdef PRE_FIX_CLIENT_MEMOPTIMIZE
|
|
|
|
|
|
if( pStruct->Type == FMOD_SOUND_TYPE_MPEG ) {
|
|
|
|
|
|
s_FMODFuncLock.Lock();
|
|
|
|
|
|
pStruct->pSound->getMode( &Mode );
|
|
|
|
|
|
Mode &= ~( FMOD_CREATECOMPRESSEDSAMPLE | FMOD_SOFTWARE );
|
|
|
|
|
|
Result = pStruct->pSound->setMode( Mode );
|
|
|
|
|
|
s_FMODFuncLock.UnLock();
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
m_LoadLock.Lock();
|
|
|
|
|
|
m_pVecSoundList.push_back( pStruct );
|
|
|
|
|
|
m_nMapSearch.insert( make_pair( pStruct->nIndex, pStruct ) );
|
|
|
|
|
|
m_szMapSearch.insert( make_pair( pStruct->szFileName, pStruct ) );
|
|
|
|
|
|
m_LoadLock.UnLock();
|
|
|
|
|
|
|
|
|
|
|
|
return pStruct->nIndex;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::RemoveSound( int nSoundIndex )
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
return _RemoveSound( nSoundIndex );
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::_RemoveSound( int nSoundIndex )
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(m_LoadLock);
|
|
|
|
|
|
|
|
|
|
|
|
std::map<int, SoundStruct *>::iterator it = m_nMapSearch.find( nSoundIndex );
|
|
|
|
|
|
if( it != m_nMapSearch.end() ) {
|
|
|
|
|
|
it->second->nRefCount--;
|
|
|
|
|
|
if( it->second->nRefCount <= 0 ) {
|
|
|
|
|
|
if( m_dwMainThreadID != GetCurrentThreadId() ) {
|
|
|
|
|
|
if( std::find( m_nVecRemoveSoundQueue.begin(), m_nVecRemoveSoundQueue.end(), nSoundIndex ) == m_nVecRemoveSoundQueue.end() ) {
|
|
|
|
|
|
m_nVecRemoveSoundQueue.push_back( nSoundIndex );
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::pair< MapSearchIter, MapSearchIter > range = m_szMapSearch.equal_range( it->second->szFileName );
|
|
|
|
|
|
for ( MapSearchIter itSearch = range.first; itSearch != range.second; ++itSearch ) {
|
|
|
|
|
|
if( itSearch->second == it->second ) {
|
|
|
|
|
|
m_szMapSearch.erase( itSearch );
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
m_nMapSearch.erase( it );
|
|
|
|
|
|
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecSoundList.size(); i++ ) {
|
|
|
|
|
|
if( m_pVecSoundList[i]->nIndex == nSoundIndex ) {
|
|
|
|
|
|
m_pVecSoundList[i]->nRefCount--;
|
|
|
|
|
|
if( m_pVecSoundList[i]->nRefCount <= 0 ) {
|
|
|
|
|
|
SoundStruct *pStruct = m_pVecSoundList[i];
|
|
|
|
|
|
m_nTotalSoundSize -= pStruct->nSize;
|
|
|
|
|
|
SAFE_DELETE( pStruct );
|
|
|
|
|
|
m_pVecSoundList.erase( m_pVecSoundList.begin() + i );
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ ) {
|
|
|
|
|
|
CEtSoundChannelGroup *pGroup = m_pVecChannelGroupList[i];
|
|
|
|
|
|
pGroup->CheckSoundIndexAndRemoveChannel( nSoundIndex );
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::ProcessRemoveSoundQueue()
|
|
|
|
|
|
{
|
|
|
|
|
|
for( DWORD i=0; i<m_nVecRemoveSoundQueue.size(); i++ ) {
|
|
|
|
|
|
SoundStruct *pStruct = FindSoundStruct( m_nVecRemoveSoundQueue[i] );
|
|
|
|
|
|
if( !pStruct ) continue;
|
|
|
|
|
|
if( pStruct->nRefCount > 0 ) continue;
|
|
|
|
|
|
RemoveSound( m_nVecRemoveSoundQueue[i] );
|
|
|
|
|
|
}
|
|
|
|
|
|
m_nVecRemoveSoundQueue.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::GetCPUUsage( float &fDSP, float &fStream, float &fUpdate, float &fTotal )
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(s_FMODFuncLock);
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->getCPUUsage( &fDSP, &fStream, NULL, &fUpdate, &fTotal ));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CEtSoundEngine::GetUsingChannelCount()
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(s_FMODFuncLock);
|
|
|
|
|
|
int nCount = 0;
|
|
|
|
|
|
m_pSystem->getChannelsPlaying( &nCount );
|
|
|
|
|
|
return nCount;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EtSoundChannelHandle CEtSoundEngine::PlaySound__( const char *szGroupName, int nSoundIndex, bool bLoop, bool bPause, bool b3DSound )
|
|
|
|
|
|
{
|
|
|
|
|
|
return PlaySound(szGroupName, nSoundIndex, bLoop, bPause, b3DSound);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EtSoundChannelHandle CEtSoundEngine::PlaySound( const char *szGroupName, int nSoundIndex, bool bLoop, bool bPause, bool b3DSound )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( m_dwMainThreadID != GetCurrentThreadId() ) return CEtSoundChannel::Identity();
|
|
|
|
|
|
if ( !m_bEnable )
|
|
|
|
|
|
{
|
|
|
|
|
|
return CEtSoundChannel::Identity();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CEtSoundChannelGroup *pGroup = NULL;
|
|
|
|
|
|
if( szGroupName == NULL ) pGroup = GetChannelGroup( "NULL" );
|
|
|
|
|
|
else pGroup = GetChannelGroup( szGroupName );
|
|
|
|
|
|
if( pGroup == NULL ) return CEtSoundChannel::Identity();
|
|
|
|
|
|
SoundStruct *pStruct = FindSoundStruct( nSoundIndex );
|
|
|
|
|
|
if( pStruct == NULL ) return CEtSoundChannel::Identity();
|
|
|
|
|
|
if( pStruct->pSound == NULL ) return CEtSoundChannel::Identity();
|
|
|
|
|
|
if( pStruct->szFileName.empty() ) return CEtSoundChannel::Identity();
|
|
|
|
|
|
FMOD::Channel *pChannel;
|
|
|
|
|
|
|
|
|
|
|
|
FMOD_RESULT Result;
|
|
|
|
|
|
s_FMODFuncLock.Lock();
|
|
|
|
|
|
Result = m_pSystem->playSound( FMOD_CHANNEL_FREE, pStruct->pSound, bPause, &pChannel );
|
|
|
|
|
|
s_FMODFuncLock.UnLock();
|
|
|
|
|
|
if( Result != FMOD_OK ) return CEtSoundChannel::Identity();
|
|
|
|
|
|
|
|
|
|
|
|
s_FMODFuncLock.Lock();
|
|
|
|
|
|
FMOD_API_CHECK( pChannel->setChannelGroup( pGroup->GetGroup() ));
|
|
|
|
|
|
s_FMODFuncLock.UnLock();
|
|
|
|
|
|
|
|
|
|
|
|
FMOD_MODE Mode = 0;
|
|
|
|
|
|
if( bLoop ) Mode |= FMOD_LOOP_NORMAL;
|
|
|
|
|
|
else Mode |= FMOD_LOOP_OFF;
|
|
|
|
|
|
|
|
|
|
|
|
if (pStruct->b3D && b3DSound)
|
|
|
|
|
|
Mode |= FMOD_3D;
|
|
|
|
|
|
else
|
|
|
|
|
|
Mode |= FMOD_2D;
|
|
|
|
|
|
|
|
|
|
|
|
s_FMODFuncLock.Lock();
|
|
|
|
|
|
FMOD_API_CHECK( pChannel->setMode( Mode ));
|
|
|
|
|
|
FMOD_API_CHECK( pChannel->setLoopCount( ( bLoop == true ) ? -1 : 0 ));
|
|
|
|
|
|
// SetVolume <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ChannelGroup <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> Volume<6D><65><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
|
|
|
|
|
float fVolume = pGroup->GetVolume();
|
|
|
|
|
|
FMOD_API_CHECK( pChannel->setVolume( fVolume ));
|
|
|
|
|
|
if( bLoop ) {
|
|
|
|
|
|
pChannel->setPriority(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
s_FMODFuncLock.UnLock();
|
|
|
|
|
|
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock2(s_ChannelLock);
|
|
|
|
|
|
return pGroup->InsertChannel( nSoundIndex, pChannel );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CEtSoundEngine::SoundStruct *CEtSoundEngine::FindSoundStruct( const char *szFileName )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( !szFileName ) return NULL;
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(m_LoadLock);
|
|
|
|
|
|
std::multimap<std::string, SoundStruct *>::iterator it = m_szMapSearch.find( szFileName );
|
|
|
|
|
|
if( it != m_szMapSearch.end() ) {
|
|
|
|
|
|
return it->second;
|
|
|
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CEtSoundEngine::SoundStruct *CEtSoundEngine::FindSoundStruct( int nIndex )
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(m_LoadLock);
|
|
|
|
|
|
std::map<int, SoundStruct *>::iterator it = m_nMapSearch.find( nIndex );
|
|
|
|
|
|
if( it != m_nMapSearch.end() ) {
|
|
|
|
|
|
return it->second;
|
|
|
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::RemoveChannel( EtSoundChannelHandle hChannel )
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(s_ChannelLock);
|
|
|
|
|
|
if( hChannel )
|
|
|
|
|
|
hChannel->GetGroup()->RemoveChannel( hChannel->GetIndex() );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::AddSoundRef( int nIndex )
|
|
|
|
|
|
{
|
|
|
|
|
|
ScopeLock<CSyncLock> Lock(m_LoadLock);
|
|
|
|
|
|
SoundStruct *pStruct = FindSoundStruct( nIndex );
|
|
|
|
|
|
if( pStruct ) pStruct->nRefCount++;
|
|
|
|
|
|
}
|
|
|
|
|
|
void CEtSoundEngine::SetListener( EtVector3 &vPos, EtVector3 &vLook, EtVector3 &vUp )
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
return _SetListener( vPos, vLook, vUp );
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EtVector3 CEtSoundEngine::GetListenerPos()
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
return _GetListenerPos();
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
return EtVector3( 0.f, 0.f, 0.f );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::_SetListener( EtVector3 &vPos, EtVector3 &vLook, EtVector3 &vUp )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( !m_pSystem ) return;
|
|
|
|
|
|
FMOD_VECTOR vPosF = { vPos.x, vPos.y, vPos.z };
|
|
|
|
|
|
FMOD_VECTOR vLookF = { vLook.x, vLook.y, vLook.z };
|
|
|
|
|
|
FMOD_VECTOR vUpF = { vUp.x, vUp.y, vUp.z };
|
|
|
|
|
|
// s_FMODFuncLock.Lock();
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->set3DListenerAttributes( 0, &vPosF, NULL, &vLookF, &vUpF ));
|
|
|
|
|
|
// s_FMODFuncLock.UnLock();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EtVector3 CEtSoundEngine::_GetListenerPos()
|
|
|
|
|
|
{
|
|
|
|
|
|
if( !m_pSystem ) return EtVector3( 0.f, 0.f, 0.f );
|
|
|
|
|
|
|
|
|
|
|
|
FMOD_VECTOR vPos;
|
|
|
|
|
|
// s_FMODFuncLock.Lock();
|
|
|
|
|
|
FMOD_API_CHECK( m_pSystem->get3DListenerAttributes( 0, &vPos, NULL, NULL, NULL ));
|
|
|
|
|
|
// s_FMODFuncLock.UnLock();
|
|
|
|
|
|
|
|
|
|
|
|
return EtVector3( vPos.x, vPos.y, vPos.z );
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::FadeVolume( const char *szGroupName, float fVolume, float fDelta, bool bPauseResume )
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
return _FadeVolume( szGroupName, fVolume, fDelta, bPauseResume );
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void CEtSoundEngine::SetVolume( const char *szGroupName, float fVolume )
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
return _SetVolume( szGroupName, fVolume );
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::_FadeVolume( const char *szGroupName, float fVolume, float fDelta, bool bPauseResume )
|
|
|
|
|
|
{
|
|
|
|
|
|
LockChannel();
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ ) {
|
|
|
|
|
|
if( szGroupName && strcmp( m_pVecChannelGroupList[i]->GetName(), szGroupName ) != NULL ) continue;
|
|
|
|
|
|
m_pVecChannelGroupList[i]->SetVolume( fVolume, fDelta );
|
|
|
|
|
|
if( bPauseResume == true ) m_pVecChannelGroupList[i]->Pause();
|
|
|
|
|
|
else m_pVecChannelGroupList[i]->Resume();
|
|
|
|
|
|
}
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::_SetVolume( const char *szGroupName, float fVolume )
|
|
|
|
|
|
{
|
|
|
|
|
|
LockChannel();
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( strcmp( m_pVecChannelGroupList[i]->GetName(), szGroupName ) != NULL )
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
m_pVecChannelGroupList[i]->SetVolume( fVolume );
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float CEtSoundEngine::GetVolume( const char *szGroupName )
|
|
|
|
|
|
{
|
|
|
|
|
|
LockChannel();
|
|
|
|
|
|
float fValue = 0.f;
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( strcmp( m_pVecChannelGroupList[i]->GetName(), szGroupName ) != NULL )
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
fValue = m_pVecChannelGroupList[i]->GetVolume();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
return fValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::SetMute( const char *szGroupName, bool bMute )
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
return _SetMute( szGroupName, bMute );
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CEtSoundEngine::IsMute( const char *szGroupName )
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
return _IsMute( szGroupName );
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::_SetMute( const char *szGroupName, bool bMute )
|
|
|
|
|
|
{
|
|
|
|
|
|
LockChannel();
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( strcmp( m_pVecChannelGroupList[i]->GetName(), szGroupName ) != NULL )
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
m_pVecChannelGroupList[i]->SetMute( bMute );
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CEtSoundEngine::_IsMute( const char *szGroupName )
|
|
|
|
|
|
{
|
|
|
|
|
|
LockChannel();
|
|
|
|
|
|
bool bResult = false;
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( strcmp( m_pVecChannelGroupList[i]->GetName(), szGroupName ) != NULL )
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
bResult = m_pVecChannelGroupList[i]->IsMute();
|
|
|
|
|
|
}
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::SetMasterVolume( const char *szGroupName, float fVolume )
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
return _SetMasterVolume( szGroupName, fVolume );
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float CEtSoundEngine::GetMasterVolume( const char *szGroupName )
|
|
|
|
|
|
{
|
|
|
|
|
|
__try {
|
|
|
|
|
|
return _GetMasterVolume( szGroupName );
|
|
|
|
|
|
}
|
|
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
|
|
UnLockExceptionFMODFunc();
|
|
|
|
|
|
}
|
|
|
|
|
|
return 0.f;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CEtSoundEngine::_SetMasterVolume( const char *szGroupName, float fVolume )
|
|
|
|
|
|
{
|
|
|
|
|
|
LockChannel();
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( strcmp( m_pVecChannelGroupList[i]->GetName(), szGroupName ) != NULL )
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
m_pVecChannelGroupList[i]->SetMasterVolume( fVolume * m_fMaxVolumeRate );
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float CEtSoundEngine::_GetMasterVolume( const char *szGroupName )
|
|
|
|
|
|
{
|
|
|
|
|
|
LockChannel();
|
|
|
|
|
|
float fValue = 0.f;
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecChannelGroupList.size(); i++ )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( strcmp( m_pVecChannelGroupList[i]->GetName(), szGroupName ) != NULL )
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
fValue = m_pVecChannelGroupList[i]->GetMasterVolume() / m_fMaxVolumeRate;
|
|
|
|
|
|
}
|
|
|
|
|
|
UnLockChannel();
|
|
|
|
|
|
|
|
|
|
|
|
return fValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CEtSoundEngine::GetSoundTypeCount( FMOD_SOUND_TYPE Type )
|
|
|
|
|
|
{
|
|
|
|
|
|
int nCount = 0;
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecSoundList.size(); i++ ) {
|
|
|
|
|
|
if( m_pVecSoundList[i]->Type == Type ) nCount++;
|
|
|
|
|
|
}
|
|
|
|
|
|
return nCount;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CEtSoundEngine::GetSoundFormatCount( FMOD_SOUND_FORMAT Format )
|
|
|
|
|
|
{
|
|
|
|
|
|
int nCount = 0;
|
|
|
|
|
|
for( DWORD i=0; i<m_pVecSoundList.size(); i++ ) {
|
|
|
|
|
|
if( m_pVecSoundList[i]->Format == Format ) nCount++;
|
|
|
|
|
|
}
|
|
|
|
|
|
return nCount;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CEtSoundEngine::SoundStruct *CEtSoundEngine::GetSoundStruct( int nIndex )
|
|
|
|
|
|
{
|
|
|
|
|
|
if( nIndex < 0 || nIndex >= (int)m_pVecSoundList.size() ) return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
return m_pVecSoundList[nIndex];
|
|
|
|
|
|
}
|