Beispiel #1
0
void SimpleAudioEngine::stopAllEffects()
{
	for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
	{
		it->second->Stop();
	}
}
	void parseEffects()
	{
		Parser parser(false, true);
		parser.readStream(filesystem::FilePackageManager::getInstance().getFile(fileName));

		ParserGroup &global = parser.getGlobals();
		int groupAmount = global.getSubGroupAmount();

		for(int i = 0; i < groupAmount; ++i)
		{
			const std::string &name = global.getSubGroupName(i);
			const ParserGroup &group = global.getSubGroup(i);
			const ParserGroup &textures = group.getSubGroup("textures");

			if(name.empty())
				continue;

			effects.push_back(parseEffectProperties(name, group));
			Effect &effect = effects[effects.size() - 1];

			int lineCount = textures.getLineCount();
			for(int j = 0; j < lineCount; ++j)
			{
				const string &texture = textures.getLine(j);
				addSpawner(effect, manager, texture, storm);
			}

			if(lineCount == 0)
			{
				Logger::getInstance()->warning("Decal effect with no textures defined");
				Logger::getInstance()->warning(name.c_str());
			}
		}
	}
void SimpleAudioEngine::playPreloadedEffect(int nSoundId)
{
	EffectList::iterator p = s_List.find(nSoundId);
	if (p != s_List.end())
	{
		p->second.Rewind();
	}
}
void SimpleAudioEngine::stopEffect(unsigned int nSoundId)
{
	EffectList::iterator p = s_List.find(nSoundId);
	if (p != s_List.end())
	{
		p->second.Stop();
	}
}
	int getId(const string &name) const
	{
		EffectList::const_iterator it = effects.begin();
		for(; it != effects.end(); ++it)
		{
			if(it->name == name)
				return it - effects.begin();
		}

		return -1;
	}
unsigned int SimpleAudioEngine::playEffect(const char* pszFilePath)
{
    unsigned int nRet = _Hash(pszFilePath);

	preloadEffect(pszFilePath);

    EffectList::iterator p = s_List.find(nRet);
    if (p != s_List.end())
    {
        p->second.Rewind();
    }

	return nRet;
}
Beispiel #7
0
SimpleAudioEngine::~SimpleAudioEngine()
{
	for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
	{
		it->second->Stop();
		delete it->second;
	}

	s_List.clear();

	closeMediaPlayer(s_pBackPlayer);
	delete s_pBackPlayer;
	s_pBackPlayer = NULL;
}
void QBSoundMac::unloadEffect(const char* filename)
{
	QBSoundLocker locker(&mMutex,"unloadEffect");
  if (filename) {
    unsigned int nRet = _Hash(filename);

    EffectList::iterator p = effectTrack.find(nRet);
    if (p != effectTrack.end())
    {
      delete p->second;
      p->second = NULL;
      effectTrack.erase(nRet);
    }
  }
}
	void spawn(DecalIdentifier &identifier, int id, const VC3 &position, const QUAT &rotation, const COL &light, bool inBuilding)
	{
		assert(id >= 0 && id < int(effects.size()));

		Effect &effect = effects[id];
		if(effect.spawners.empty())
			return;

		float size = effect.sizeMin;
		float sizeDelta = effect.sizeMax - effect.sizeMin;
		size += (rand() / float(RAND_MAX)) * sizeDelta;

		int spawnerIndex = rand() % effect.spawners.size();

		DecalSpawner &spawner = *effect.spawners[spawnerIndex];
		spawner.setSize(VC2(size, size));

		if(!effect.randomRotation)
			spawner.spawnDecal(identifier, position, rotation, light, inBuilding);
		else
		{
			float angle = rand() % 6000 / 1000.f;
			QUAT r;
			r.MakeFromAngles(0, 0, angle);
			r = r * rotation;

			spawner.spawnDecal(identifier, position, r, light, inBuilding);
		}
	}
Beispiel #10
0
void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
{
	int nRet = 0;
	CCAudioOut* pEffectPlayer = NULL;
	do
	{
		BREAK_IF(! pszFilePath);

		string strFilePath = fullPathFromRelativePath(pszFilePath);

		nRet = _Hash(strFilePath.c_str());

		BREAK_IF(s_List.end() != s_List.find(nRet));

		//AppLog("not find effect, create it...");
		if (s_List.size() >= 64)
		{
			// get the first effect, and remove it form list
			//AppLog("effect preload more than 64, delete the first effect");
			pEffectPlayer = s_List.begin()->second;
			pEffectPlayer->Finalize();
			s_List.erase(s_List.begin()->first);
		}
		if (pEffectPlayer == NULL)
			pEffectPlayer = new CCAudioOut;
		pEffectPlayer->Initialize(strFilePath.c_str());

		s_List.insert(Effect(nRet, pEffectPlayer));

	} while (0);
}
void QBSoundMac::preloadEffect(const char* filename)
{
	QBSoundLocker locker(&mMutex,"preloadEffect");
  do {
    if (filename==NULL) break;
  
    unsigned int nRet = _Hash(filename);
    
    if (effectTrack.end() != effectTrack.find(nRet)) break;
    
    effectTrack.insert(make_pair(nRet,new EffectBuffer()));
    EffectBuffer* buffer = effectTrack[nRet];
    
    if (buffer->load(filename)!=0) {
      effectTrack.erase(nRet);
    }

  } while (0);
}
void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
{
	int nRet = 0;
	do 
	{
		BREAK_IF(! pszFilePath);

		nRet = _Hash(pszFilePath);

		BREAK_IF(s_List.end() != s_List.find(nRet));

		s_List.insert(Effect(nRet, MciPlayer()));
		MciPlayer& player = s_List[nRet];
		player.Open(_FullPath(pszFilePath), nRet);

		BREAK_IF(nRet == player.GetSoundID());

		s_List.erase(nRet);
		nRet = 0;
	} while (0);
}
Beispiel #13
0
// for sound effects
unsigned int SimpleAudioEngine::playEffect(const char* pszFilePath, bool bLoop/* = false*/)
{
	result r = E_FAILURE;
	string strFilePath = fullPathFromRelativePath(pszFilePath);
	unsigned int nRet = _Hash(strFilePath.c_str());

	preloadEffect(pszFilePath);

	EffectList::iterator p = s_List.find(nRet);
	if (p != s_List.end())
	{
		p->second->SetVolume((int) (s_fEffectsVolume * 99));
		int volume = p->second->GetVolume();

    	if (s_fEffectsVolume > 0.0f && volume == 0)
    	{
    		p->second->SetVolume(1);
    	}

	    if (AUDIOOUT_STATE_PLAYING == p->second->GetState())
		{
            return nRet; // Stop waste a lot of time, so just return.
	    	//r = p->second->Stop();
		}

	    if (s_fEffectsVolume > 0.0f)
	    {
	    	r = p->second->Play(bLoop);
	    }

    	if (IsFailed(r))
    	{
    		AppLog("play effect fails, error code = %d", r);
    	}
	}
	return nRet;
}
void QBSoundMac::stopAll()
{
	QBSoundLocker locker(&mMutex,"stopAll");
#ifdef __USE_OGG_VORBIS__
  {
    PlayerList::iterator it = streamTrack.begin();
    while(it != streamTrack.end()) {
      delete (*it).second;
      ++it;
    }
    streamTrack.clear();
  }
  {
    EffectList::iterator it = effectTrack.begin();
    while(it != effectTrack.end())
    {
      delete (*it).second;
      ++it;
    }
    effectTrack.clear();
  }
#endif
	return QBSound::stopAll();
}
unsigned int QBSoundMac::playEffect(const char* filename,bool bLoop,float pitch, float pan, float gain)
{
	QBSoundLocker locker(&mMutex,"playEffect");
  if (filename) {
    unsigned int nRet = _Hash(filename);
  
    do {
      if (filename==NULL) break;
    
      unsigned int nRet = _Hash(filename);
      
      if (effectTrack.end() != effectTrack.find(nRet)) break;
      
      effectTrack.insert(make_pair(nRet,new EffectBuffer()));
      EffectBuffer* buffer = effectTrack[nRet];
      
      if (buffer->load(filename)!=0) {
        effectTrack.erase(nRet);
      }

    } while (0);

    EffectList::iterator p = effectTrack.find(nRet);
    if (p != effectTrack.end())
    {
      EffectBuffer* effect = p->second;
      findPlayer(soundID)->setVolume(gain);
      findPlayer(soundID)->play((unsigned char*)effect->pcmbuffer,effect->pcmsize);
      soundID ++;
      if (soundID > 9999) soundID = 1;
    }

    return soundID;
  }
  return 0;
}
Beispiel #16
0
 void load(ESMReader &esm)
 {
   esm.getHNT(data, "ENDT", 16);
   effects.load(esm);
 }
namespace CocosDenshion {

typedef map<unsigned int, MciPlayer> EffectList;
typedef pair<unsigned int ,MciPlayer> Effect;

static SimpleAudioEngine s_SharedEngine;
static EffectList	s_List;
static MciPlayer	s_Music;
static char			s_szRootPath[MAX_PATH];
static DWORD		s_dwRootLen;
static char			s_szFullPath[MAX_PATH];


static const char * _FullPath(const char * szPath);
static unsigned int _Hash(const char *key);

#define BREAK_IF(cond)  if (cond) break;

SimpleAudioEngine::SimpleAudioEngine()
{
}

SimpleAudioEngine::~SimpleAudioEngine()
{
}

SimpleAudioEngine* SimpleAudioEngine::sharedEngine()
{
    return &s_SharedEngine;
}

void SimpleAudioEngine::end()
{
	return;
}

void SimpleAudioEngine::setResource(const char* pszResPath, const char* pszZipFileName)
{
}

//////////////////////////////////////////////////////////////////////////
// BackgroundMusic
//////////////////////////////////////////////////////////////////////////

void SimpleAudioEngine::playBackgroundMusic(const char* pszFilePath, bool bLoop)
{
	if (! pszFilePath)
	{
		return;
	}

	s_Music.Open(_FullPath(pszFilePath), _Hash(pszFilePath));
	s_Music.Play((bLoop) ? -1 : 1);
}

void SimpleAudioEngine::stopBackgroundMusic(bool bReleaseData)
{
    if (bReleaseData)
    {
        s_Music.Close();
    }
    else
    {
        s_Music.Stop();
    }
}

void SimpleAudioEngine::pauseBackgroundMusic()
{
	s_Music.Pause();
}

void SimpleAudioEngine::resumeBackgroundMusic()
{
	s_Music.Resume();
}

void SimpleAudioEngine::rewindBackgroundMusic()
{
	s_Music.Rewind();
}

bool SimpleAudioEngine::willPlayBackgroundMusic()
{
    return false;
}

bool SimpleAudioEngine::isBackgroundMusicPlaying()
{
	return s_Music.IsPlaying();
}

//////////////////////////////////////////////////////////////////////////
// effect function
//////////////////////////////////////////////////////////////////////////

unsigned int SimpleAudioEngine::playEffect(const char* pszFilePath)
{
    unsigned int nRet = _Hash(pszFilePath);

	preloadEffect(pszFilePath);

    EffectList::iterator p = s_List.find(nRet);
    if (p != s_List.end())
    {
        p->second.Rewind();
    }

	return nRet;
}

void SimpleAudioEngine::stopEffect(unsigned int nSoundId)
{
	EffectList::iterator p = s_List.find(nSoundId);
	if (p != s_List.end())
	{
		p->second.Stop();
	}
}

void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
{
	int nRet = 0;
	do 
	{
		BREAK_IF(! pszFilePath);

		nRet = _Hash(pszFilePath);

		BREAK_IF(s_List.end() != s_List.find(nRet));

		s_List.insert(Effect(nRet, MciPlayer()));
		MciPlayer& player = s_List[nRet];
		player.Open(_FullPath(pszFilePath), nRet);

		BREAK_IF(nRet == player.GetSoundID());

		s_List.erase(nRet);
		nRet = 0;
	} while (0);
}

void SimpleAudioEngine::preloadBackgroundMusic(const char* pszFilePath)
{

}

void SimpleAudioEngine::unloadEffect(const char* pszFilePath)
{
    unsigned int nID = _Hash(pszFilePath);
	s_List.erase(nID);
}

void SimpleAudioEngine::unloadEffectAll()
{
	s_List.clear();
}

//////////////////////////////////////////////////////////////////////////
// volume interface
//////////////////////////////////////////////////////////////////////////

int SimpleAudioEngine::getBackgroundMusicVolume()
{
	return 100;
}

void SimpleAudioEngine::setBackgroundMusicVolume(int volume)
{
}

int SimpleAudioEngine::getEffectsVolume()
{
	return 100;
}

void SimpleAudioEngine::setEffectsVolume(int volume)
{
}

//////////////////////////////////////////////////////////////////////////
// static function
//////////////////////////////////////////////////////////////////////////

const char * _FullPath(const char * szPath)
{
	if (! s_szRootPath[0])
	{
		s_dwRootLen = GetModuleFileName(NULL, s_szRootPath, sizeof(s_szRootPath));
		while (--s_dwRootLen)
		{
			if ('\\' == s_szRootPath[s_dwRootLen])
			{
				s_szRootPath[s_dwRootLen + 1] = 0;
				strcpy_s(s_szFullPath, sizeof(s_szFullPath), s_szRootPath);
				++s_dwRootLen;
				break;
			}
		}
	}

	if (0 != szPath[0] && ':' != szPath[1])
	{
		strcpy_s(s_szFullPath + s_dwRootLen, sizeof(s_szFullPath) - s_dwRootLen, szPath);
		return s_szFullPath;
	}
	else
	{
		return szPath;
	}
}

unsigned int _Hash(const char *key)
{
	unsigned int len = strlen(key);
	const char *end=key+len;
	unsigned int hash;

	for (hash = 0; key < end; key++)
	{
		hash *= 16777619;
		hash ^= (unsigned int) (unsigned char) toupper(*key);
	}
	return (hash);
}

} // end of namespace CocosDenshion
void SimpleAudioEngine::unloadEffectAll()
{
	s_List.clear();
}
void SimpleAudioEngine::unloadEffect(const char* pszFilePath)
{
    unsigned int nID = _Hash(pszFilePath);
	s_List.erase(nID);
}
void SimpleAudioEngine::unloadEffect(int nSoundId)
{
	s_List.erase(nSoundId);
}
Beispiel #21
0
namespace CocosDenshion {

#define MAX_BUFFER_SIZE	2520 // 840 byte

typedef map<unsigned int, CCAudioOut*> EffectList;
typedef pair<unsigned int ,CCAudioOut*> Effect;


static SimpleAudioEngine *s_pSharedAudioEngine = NULL;
static Player       *s_pBackPlayer       = NULL;
static EffectList	s_List;
static float   s_fBackgroundMusicVolume = 1.0f;
static float   s_fEffectsVolume = 1.0f;
static bool    s_bWillPlayBackgroundMusic = false;
static bool    s_bBackgroundMusicPaused = false;
static string s_strResourcePath = "/Res/";

static unsigned int _Hash(const char *key)
{
	unsigned int len = strlen(key);
	const char *end=key+len;
	unsigned int hash;

	for (hash = 0; key < end; key++)
	{
		hash *= 16777619;
		hash ^= (unsigned int) (unsigned char) toupper(*key);
	}
	return (hash);
}

static string fullPathFromRelativePath(const char *pszRelativePath)
{
	string strRet="";
	int len = strlen(pszRelativePath);
	if (pszRelativePath == NULL || len <= 0)
	{
		return strRet;
	}

    if (len > 1 && pszRelativePath[0] == '/')
    {
    	strRet = pszRelativePath;
    }
    else
    {
    	strRet = s_strResourcePath;
    	strRet += pszRelativePath;
    }
	return strRet;
}

class MyPlayerEventListener :
	public IPlayerEventListener
{

public:

	/**
	*	Notifies that audio/video content was opened asynchronously.
	*
	* 	@param[in]	r	The cause of the error
	*	@exception	 E_SUCCESS							The method was successful.
	*	@exception	 E_SYSTEM							A system error occurred.
	*	@exception	 E_CONNECTION_FAILED				Network connection failed.
	* 	@exception	 E_UNSUPPORTED_FORMAT				The specified format is not supported.
	* 	@exception	 E_UNSUPPORTED_CODEC				The specified codec is not supported.
	*	@exception	 E_OUT_OF_MEMORY					Insufficient memory.
	*	@see		Player::OpenFile(), Player::OpenUrl(), Player::OpenBuffer()
	*/
	virtual void OnPlayerOpened( result r )
	{
		AppLog("OnPlayerOpened result = %d", r);
	}

	/**
	*	Notifies that the Player has reached the end of the clip.
	*
	*/
	virtual void OnPlayerEndOfClip(void)
	{
		AppLog("OnPlayerEndOfClip");
	}

	/**
	*	Notifies that the position of the audio/video content was moved asynchronously.
	*
	*	@exception	 E_SUCCESS		The method was successful.
	*	@exception	 E_SYSTEM		A system error occurred.
	*	@see		Player::SeekTo()
	*/

	virtual void OnPlayerSeekCompleted( result r )
	{
		AppLog("OnPlayerSeekCompleted result = %d", r);
	}


	/**
	*	Notifies that streaming data is being buffered.
	*
	*	@param[in]	percent		The percentage of buffering completed
	*	@see		Player::OpenUrl()
	*/
	virtual void OnPlayerBuffering(int percent)
	{
		AppLog("OnPlayerBuffering percent = %d%", percent);
	}

	/**
	*	Notifies that an error has occurred while the Player is working.
	*
	*	@param[in]	r		A player error reason of type ::PlayerErrorReason
	*	@remark		While playing streaming media, the player might throw an error like ::PLAYER_ERROR_CONNECTION_LOST @n
	*				::PLAYER_ERROR_STREAMING_TIMEOUT, ::PLAYER_ERROR_TRANSPORT or ::PLAYER_ERROR_SERVER. @n
	*				If the content includes invalid data, ::PLAYER_ERROR_INVALID_DATA may occur.
	*	@see	PlayerErrorReason
	*/
	virtual void OnPlayerErrorOccurred( PlayerErrorReason r )
	{
		AppLog("OnPlayerErrorOccurred PlayerErrorReason = %d", r);
	}


	/**
	 *	Notifies that the Player is being interrupted by a task of higher priority than Player.
	 *
	 */
	virtual void OnPlayerInterrupted(void)
	{
		AppLog("OnPlayerInterrupted");
		//Insert your code here
		if (s_pBackPlayer->GetState() == PLAYER_STATE_PLAYING)
			s_pBackPlayer->Pause();
	}

	/**
	 *	Notifies that the interrupting Player has been released.
	 *
	 */
	virtual void OnPlayerReleased(void)
	{
		AppLog("OnPlayerReleased");
		//Insert your code here
		if (s_pBackPlayer->GetState() != PLAYER_STATE_PLAYING)
			s_pBackPlayer->Play();
	}

};

static 	MyPlayerEventListener s_playerListener;

static void closeMediaPlayer(Player*& pPlayer)
{
	if (pPlayer != NULL)
	{
		PlayerState nowState = pPlayer->GetState();
		if( nowState == PLAYER_STATE_PLAYING || nowState == PLAYER_STATE_PAUSED )
		{
			pPlayer->Stop();
			pPlayer->Close();
		}
		else if(nowState == PLAYER_STATE_OPENED || nowState == PLAYER_STATE_ENDOFCLIP || nowState == PLAYER_STATE_STOPPED )
		{
			pPlayer->Close();
		}
	}
}

static bool openMediaPlayer(Player*& pPlayer, const char* pszFilePath)
{
	bool bRet = false;
	result r = E_FAILURE;

	do
	{
		closeMediaPlayer(pPlayer);

		if (pPlayer == NULL)
		{
			pPlayer = new Player();
			r = pPlayer->Construct(s_playerListener, null);
			if (IsFailed(r))
			{
				AppLog("player construct fails, pszFilePath = %s", pszFilePath);
				delete pPlayer;
				pPlayer = NULL;
				break;
			}
		}

		string strFilePath = fullPathFromRelativePath(pszFilePath);
		// OpenFile must use synchronous param, for after that it will playing.
		r = pPlayer->OpenFile(strFilePath.c_str(), false);
		if (IsFailed(r))
		{
			AppLog("Open (%s) fails\n", strFilePath.c_str());
			delete pPlayer;
			pPlayer = NULL;
			break;
		}
		else
		{
			bRet = true;
		}
	}
	while (0);

	SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(s_fBackgroundMusicVolume);

	return bRet;
}

SimpleAudioEngine::SimpleAudioEngine()
{

}

SimpleAudioEngine::~SimpleAudioEngine()
{
	for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
	{
		it->second->Stop();
		delete it->second;
	}

	s_List.clear();

	closeMediaPlayer(s_pBackPlayer);
	delete s_pBackPlayer;
	s_pBackPlayer = NULL;
}

SimpleAudioEngine* SimpleAudioEngine::sharedEngine()
{
    if (s_pSharedAudioEngine == NULL)
    {
        s_pSharedAudioEngine = new SimpleAudioEngine;
    }
    
    return s_pSharedAudioEngine;
}

void SimpleAudioEngine::end()
{
	if (s_pSharedAudioEngine)
	{
		delete s_pSharedAudioEngine;
		s_pSharedAudioEngine = NULL;
	}
}

void SimpleAudioEngine::setResource(const char* pszZipFileName)
{

}

void SimpleAudioEngine::preloadBackgroundMusic(const char* pszFilePath)
{
	openMediaPlayer(s_pBackPlayer, pszFilePath);
}

void SimpleAudioEngine::playBackgroundMusic(const char* pszFilePath, bool bLoop)
{
	result r = E_FAILURE;
	bool bRet = false;
	bRet = openMediaPlayer(s_pBackPlayer, pszFilePath);

    if (bRet)
    {
    	s_pBackPlayer->SetLooping(bLoop);
    	r = s_pBackPlayer->Play();
    }
}

void SimpleAudioEngine::stopBackgroundMusic(bool bReleaseData)
{
	s_bBackgroundMusicPaused = false;
    if (s_pBackPlayer && PLAYER_STATE_PLAYING == s_pBackPlayer->GetState())
    {
        s_pBackPlayer->Stop();
    }
}

void SimpleAudioEngine::pauseBackgroundMusic()
{
    if (s_pBackPlayer && PLAYER_STATE_PLAYING == s_pBackPlayer->GetState())
    {
    	s_bBackgroundMusicPaused = true;
        s_pBackPlayer->Pause();
    }
}

void SimpleAudioEngine::resumeBackgroundMusic()
{
    if (s_pBackPlayer && s_bBackgroundMusicPaused && PLAYER_STATE_PLAYING != s_pBackPlayer->GetState())
    {
    	s_bBackgroundMusicPaused = false;
        s_pBackPlayer->Play();
    }
}

void SimpleAudioEngine::rewindBackgroundMusic()
{
	stopBackgroundMusic();
    if (s_pBackPlayer)
    {
        if (PLAYER_STATE_PLAYING != s_pBackPlayer->GetState())
        {
         	result r = s_pBackPlayer->Play();
         	if (IsFailed(r))
         	{
         		AppLog("ERROR: %s", GetErrorMessage(r));
         	}
        }
    }
}

bool SimpleAudioEngine::willPlayBackgroundMusic()
{
    return s_bWillPlayBackgroundMusic;
}

bool SimpleAudioEngine::isBackgroundMusicPlaying()
{
    bool bRet = false;

    if (s_pBackPlayer)
    {
        if (s_pBackPlayer->GetState() == PLAYER_STATE_PLAYING)
        {
        	bRet = true;
        }
    }

    return bRet;
}

// properties
float SimpleAudioEngine::getBackgroundMusicVolume()
{
    return s_fBackgroundMusicVolume;
}

void SimpleAudioEngine::setBackgroundMusicVolume(float volume)
{
    if (volume > 1.0f)
    {
        volume = 1.0f;
    }
    else if (volume < 0.0f)
    {
        volume = 0.0f;
    }

    if (s_pBackPlayer)
    {
    	s_pBackPlayer->SetVolume((int) (volume * 99));
    	if (volume > 0.0f && s_pBackPlayer->GetVolume() == 0)
    	{
    		s_pBackPlayer->SetVolume(1);
    	}
    }
    s_fBackgroundMusicVolume = volume;
}

float SimpleAudioEngine::getEffectsVolume()
{
    return s_fEffectsVolume;
}

void SimpleAudioEngine::setEffectsVolume(float volume)
{
    if (volume > 1.0f)
    {
        volume = 1.0f;
    }
    else if (volume < 0.0f)
    {
        volume = 0.0f;
    }

    s_fEffectsVolume = volume;
}

// for sound effects
unsigned int SimpleAudioEngine::playEffect(const char* pszFilePath, bool bLoop/* = false*/)
{
	result r = E_FAILURE;
	string strFilePath = fullPathFromRelativePath(pszFilePath);
	unsigned int nRet = _Hash(strFilePath.c_str());

	preloadEffect(pszFilePath);

	EffectList::iterator p = s_List.find(nRet);
	if (p != s_List.end())
	{
		p->second->SetVolume((int) (s_fEffectsVolume * 99));
		int volume = p->second->GetVolume();

    	if (s_fEffectsVolume > 0.0f && volume == 0)
    	{
    		p->second->SetVolume(1);
    	}

	    if (AUDIOOUT_STATE_PLAYING == p->second->GetState())
		{
            return nRet; // Stop waste a lot of time, so just return.
	    	//r = p->second->Stop();
		}

	    if (s_fEffectsVolume > 0.0f)
	    {
	    	r = p->second->Play(bLoop);
	    }

    	if (IsFailed(r))
    	{
    		AppLog("play effect fails, error code = %d", r);
    	}
	}
	return nRet;
}

void SimpleAudioEngine::stopEffect(unsigned int nSoundId)
{
	CCAudioOut*& pPlayer = s_List[nSoundId];
	if (pPlayer != NULL)
	{
		pPlayer->Stop();
	}
}

void SimpleAudioEngine::pauseEffect(unsigned int nSoundId)
{
	CCAudioOut*& pPlayer = s_List[nSoundId];
	if (pPlayer != NULL)
	{
		pPlayer->Pause();
	}
}

void SimpleAudioEngine::pauseAllEffects()
{
	for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
	{
		it->second->Pause();
	}
}

void SimpleAudioEngine::resumeEffect(unsigned int nSoundId)
{
	CCAudioOut*& pPlayer = s_List[nSoundId];
	if (pPlayer != NULL)
	{
		pPlayer->Resume();
	}
}

void SimpleAudioEngine::resumeAllEffects()
{
	for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
	{
		it->second->Resume();
	}
}

void SimpleAudioEngine::stopAllEffects()
{
	for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
	{
		it->second->Stop();
	}
}

void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
{
	int nRet = 0;
	CCAudioOut* pEffectPlayer = NULL;
	do
	{
		BREAK_IF(! pszFilePath);

		string strFilePath = fullPathFromRelativePath(pszFilePath);

		nRet = _Hash(strFilePath.c_str());

		BREAK_IF(s_List.end() != s_List.find(nRet));

		//AppLog("not find effect, create it...");
		if (s_List.size() >= 64)
		{
			// get the first effect, and remove it form list
			//AppLog("effect preload more than 64, delete the first effect");
			pEffectPlayer = s_List.begin()->second;
			pEffectPlayer->Finalize();
			s_List.erase(s_List.begin()->first);
		}
		if (pEffectPlayer == NULL)
			pEffectPlayer = new CCAudioOut;
		pEffectPlayer->Initialize(strFilePath.c_str());

		s_List.insert(Effect(nRet, pEffectPlayer));

	} while (0);
}

void SimpleAudioEngine::unloadEffect(const char* pszFilePath)
{
	string strFilePath = fullPathFromRelativePath(pszFilePath);
	unsigned int nSoundId = _Hash(strFilePath.c_str());
	CCAudioOut*& pPlayer = s_List[nSoundId];
	pPlayer->Stop();
}

} // end of namespace CocosDenshion
	float getMaxSize(int id) const
	{
		assert(id >= 0 && id < int(effects.size()));
		return effects[id].sizeMax;
	}