2011-11-28 18:05:38 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2010 cocos2d-x.org
|
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
2011-09-19 17:53:45 +08:00
|
|
|
#include "SimpleAudioEngine.h"
|
2011-10-18 18:10:53 +08:00
|
|
|
#include "CCAudioOut.h"
|
2011-09-19 17:53:45 +08:00
|
|
|
#include <FBase.h>
|
|
|
|
#include <FMedia.h>
|
|
|
|
#include <FSystem.h>
|
2011-09-29 22:53:38 +08:00
|
|
|
#include <string>
|
2011-09-19 17:53:45 +08:00
|
|
|
#include <map>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2011-12-31 18:08:41 +08:00
|
|
|
#include <math.h>
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace Osp::Media;
|
|
|
|
using namespace Osp::System;
|
|
|
|
using namespace Osp::Base::Runtime;
|
|
|
|
using namespace Osp::Base::Collection;
|
|
|
|
|
|
|
|
#define BREAK_IF(cond) if (cond) break;
|
|
|
|
|
|
|
|
namespace CocosDenshion {
|
|
|
|
|
|
|
|
#define MAX_BUFFER_SIZE 2520 // 840 byte
|
|
|
|
|
2011-10-18 18:10:53 +08:00
|
|
|
typedef map<unsigned int, CCAudioOut*> EffectList;
|
|
|
|
typedef pair<unsigned int ,CCAudioOut*> Effect;
|
2011-10-14 09:20:03 +08:00
|
|
|
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
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;
|
2011-11-28 16:09:01 +08:00
|
|
|
static bool s_bBackgroundMusicPaused = false;
|
2011-11-07 14:19:46 +08:00
|
|
|
static string s_strResourcePath = "/Res/";
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2011-11-07 18:18:10 +08:00
|
|
|
static string fullPathFromRelativePath(const char *pszRelativePath)
|
|
|
|
{
|
|
|
|
string strRet="";
|
|
|
|
int len = strlen(pszRelativePath);
|
|
|
|
if (pszRelativePath == NULL || len <= 0)
|
2011-11-28 16:09:01 +08:00
|
|
|
{
|
|
|
|
return strRet;
|
|
|
|
}
|
2011-11-07 18:18:10 +08:00
|
|
|
|
|
|
|
if (len > 1 && pszRelativePath[0] == '/')
|
|
|
|
{
|
|
|
|
strRet = pszRelativePath;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strRet = s_strResourcePath;
|
|
|
|
strRet += pszRelativePath;
|
|
|
|
}
|
|
|
|
return strRet;
|
|
|
|
}
|
|
|
|
|
2011-09-19 17:53:45 +08:00
|
|
|
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()
|
|
|
|
*/
|
2011-09-28 22:53:51 +08:00
|
|
|
virtual void OnPlayerOpened( result r )
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
AppLog("OnPlayerOpened result = %d", r);
|
2011-09-28 22:53:51 +08:00
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Notifies that the Player has reached the end of the clip.
|
|
|
|
*
|
|
|
|
*/
|
2011-09-28 22:53:51 +08:00
|
|
|
virtual void OnPlayerEndOfClip(void)
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
AppLog("OnPlayerEndOfClip");
|
2011-09-28 22:53:51 +08:00
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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()
|
|
|
|
*/
|
|
|
|
|
2011-09-28 22:53:51 +08:00
|
|
|
virtual void OnPlayerSeekCompleted( result r )
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
AppLog("OnPlayerSeekCompleted result = %d", r);
|
2011-09-28 22:53:51 +08:00
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notifies that streaming data is being buffered.
|
|
|
|
*
|
|
|
|
* @param[in] percent The percentage of buffering completed
|
|
|
|
* @see Player::OpenUrl()
|
|
|
|
*/
|
2011-09-28 22:53:51 +08:00
|
|
|
virtual void OnPlayerBuffering(int percent)
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
AppLog("OnPlayerBuffering percent = %d%", percent);
|
2011-09-28 22:53:51 +08:00
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2011-09-28 22:53:51 +08:00
|
|
|
virtual void OnPlayerErrorOccurred( PlayerErrorReason r )
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
AppLog("OnPlayerErrorOccurred PlayerErrorReason = %d", r);
|
2011-09-28 22:53:51 +08:00
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notifies that the Player is being interrupted by a task of higher priority than Player.
|
|
|
|
*
|
|
|
|
*/
|
2011-09-28 22:53:51 +08:00
|
|
|
virtual void OnPlayerInterrupted(void)
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
AppLog("OnPlayerInterrupted");
|
2011-09-28 22:53:51 +08:00
|
|
|
//Insert your code here
|
|
|
|
if (s_pBackPlayer->GetState() == PLAYER_STATE_PLAYING)
|
|
|
|
s_pBackPlayer->Pause();
|
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Notifies that the interrupting Player has been released.
|
|
|
|
*
|
|
|
|
*/
|
2011-09-28 22:53:51 +08:00
|
|
|
virtual void OnPlayerReleased(void)
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
AppLog("OnPlayerReleased");
|
2011-09-28 22:53:51 +08:00
|
|
|
//Insert your code here
|
|
|
|
if (s_pBackPlayer->GetState() != PLAYER_STATE_PLAYING)
|
|
|
|
s_pBackPlayer->Play();
|
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
static MyPlayerEventListener s_playerListener;
|
|
|
|
|
2011-10-14 09:20:03 +08:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-28 18:05:38 +08:00
|
|
|
static bool openMediaPlayer(Player*& pPlayer, const char* pszFilePath)
|
2011-10-14 09:20:03 +08:00
|
|
|
{
|
|
|
|
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))
|
|
|
|
{
|
2011-11-28 16:09:01 +08:00
|
|
|
AppLog("player construct fails, pszFilePath = %s", pszFilePath);
|
2011-10-14 09:20:03 +08:00
|
|
|
delete pPlayer;
|
|
|
|
pPlayer = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-07 18:18:10 +08:00
|
|
|
string strFilePath = fullPathFromRelativePath(pszFilePath);
|
2011-10-14 09:20:03 +08:00
|
|
|
// OpenFile must use synchronous param, for after that it will playing.
|
|
|
|
r = pPlayer->OpenFile(strFilePath.c_str(), false);
|
|
|
|
if (IsFailed(r))
|
|
|
|
{
|
2011-11-28 16:09:01 +08:00
|
|
|
AppLog("Open (%s) fails\n", strFilePath.c_str());
|
2011-10-14 09:20:03 +08:00
|
|
|
delete pPlayer;
|
|
|
|
pPlayer = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bRet = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (0);
|
|
|
|
|
2011-11-28 18:05:38 +08:00
|
|
|
SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(s_fBackgroundMusicVolume);
|
|
|
|
|
2011-10-14 09:20:03 +08:00
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
2011-09-19 17:53:45 +08:00
|
|
|
SimpleAudioEngine::SimpleAudioEngine()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
SimpleAudioEngine::~SimpleAudioEngine()
|
|
|
|
{
|
2011-10-14 09:20:03 +08:00
|
|
|
for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
|
2011-09-19 17:53:45 +08:00
|
|
|
{
|
2011-11-28 16:09:01 +08:00
|
|
|
it->second->Stop();
|
2011-10-14 09:20:03 +08:00
|
|
|
delete it->second;
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
2011-10-14 09:20:03 +08:00
|
|
|
|
|
|
|
s_List.clear();
|
|
|
|
|
|
|
|
closeMediaPlayer(s_pBackPlayer);
|
|
|
|
delete s_pBackPlayer;
|
|
|
|
s_pBackPlayer = NULL;
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-29 22:53:38 +08:00
|
|
|
void SimpleAudioEngine::setResource(const char* pszZipFileName)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-09-19 17:53:45 +08:00
|
|
|
void SimpleAudioEngine::preloadBackgroundMusic(const char* pszFilePath)
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
openMediaPlayer(s_pBackPlayer, pszFilePath);
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::playBackgroundMusic(const char* pszFilePath, bool bLoop)
|
|
|
|
{
|
2011-10-14 09:20:03 +08:00
|
|
|
result r = E_FAILURE;
|
|
|
|
bool bRet = false;
|
2011-11-28 18:05:38 +08:00
|
|
|
bRet = openMediaPlayer(s_pBackPlayer, pszFilePath);
|
2011-09-19 17:53:45 +08:00
|
|
|
|
2011-10-29 14:47:13 +08:00
|
|
|
if (bRet)
|
2011-09-28 22:53:51 +08:00
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
s_pBackPlayer->SetLooping(bLoop);
|
2011-09-28 22:53:51 +08:00
|
|
|
r = s_pBackPlayer->Play();
|
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::stopBackgroundMusic(bool bReleaseData)
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
s_bBackgroundMusicPaused = false;
|
2011-12-31 17:44:45 +08:00
|
|
|
if (s_pBackPlayer != NULL && PLAYER_STATE_PLAYING == s_pBackPlayer->GetState())
|
2011-09-19 17:53:45 +08:00
|
|
|
{
|
|
|
|
s_pBackPlayer->Stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::pauseBackgroundMusic()
|
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
if (s_pBackPlayer != NULL && PLAYER_STATE_PLAYING == s_pBackPlayer->GetState())
|
2011-09-19 17:53:45 +08:00
|
|
|
{
|
2011-11-28 16:09:01 +08:00
|
|
|
s_bBackgroundMusicPaused = true;
|
2011-09-19 17:53:45 +08:00
|
|
|
s_pBackPlayer->Pause();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::resumeBackgroundMusic()
|
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
if (s_pBackPlayer != NULL && s_bBackgroundMusicPaused && PLAYER_STATE_PLAYING != s_pBackPlayer->GetState())
|
2011-09-19 17:53:45 +08:00
|
|
|
{
|
2011-11-28 16:09:01 +08:00
|
|
|
s_bBackgroundMusicPaused = false;
|
2011-09-19 17:53:45 +08:00
|
|
|
s_pBackPlayer->Play();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::rewindBackgroundMusic()
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
stopBackgroundMusic();
|
2011-12-31 17:44:45 +08:00
|
|
|
if (s_pBackPlayer != NULL)
|
2011-09-19 17:53:45 +08:00
|
|
|
{
|
|
|
|
if (PLAYER_STATE_PLAYING != s_pBackPlayer->GetState())
|
|
|
|
{
|
2011-11-28 18:05:38 +08:00
|
|
|
result r = s_pBackPlayer->Play();
|
|
|
|
if (IsFailed(r))
|
|
|
|
{
|
|
|
|
AppLog("ERROR: %s", GetErrorMessage(r));
|
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SimpleAudioEngine::willPlayBackgroundMusic()
|
|
|
|
{
|
|
|
|
return s_bWillPlayBackgroundMusic;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SimpleAudioEngine::isBackgroundMusicPlaying()
|
|
|
|
{
|
|
|
|
bool bRet = false;
|
|
|
|
|
2011-12-31 17:44:45 +08:00
|
|
|
if (s_pBackPlayer != NULL && s_pBackPlayer->GetState() == PLAYER_STATE_PLAYING)
|
2011-09-19 17:53:45 +08:00
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
bRet = true;
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-12-31 17:44:45 +08:00
|
|
|
if (s_pBackPlayer != NULL)
|
2011-09-19 17:53:45 +08:00
|
|
|
{
|
2012-01-11 17:24:46 +08:00
|
|
|
s_pBackPlayer->SetVolume(ceil(volume*99));
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-12-31 17:53:01 +08:00
|
|
|
EffectList::iterator it;
|
|
|
|
for (it = s_List.begin(); it != s_List.end(); ++it)
|
|
|
|
{
|
|
|
|
if (it->second != NULL)
|
|
|
|
{
|
2012-01-11 17:24:46 +08:00
|
|
|
it->second->SetVolume(ceil(volume*99));
|
2011-12-31 17:53:01 +08:00
|
|
|
}
|
|
|
|
}
|
2011-12-31 18:08:41 +08:00
|
|
|
s_fEffectsVolume = volume;
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// for sound effects
|
2011-09-20 12:39:44 +08:00
|
|
|
unsigned int SimpleAudioEngine::playEffect(const char* pszFilePath, bool bLoop/* = false*/)
|
2011-09-19 17:53:45 +08:00
|
|
|
{
|
2011-10-14 09:20:03 +08:00
|
|
|
result r = E_FAILURE;
|
2011-11-07 18:18:10 +08:00
|
|
|
string strFilePath = fullPathFromRelativePath(pszFilePath);
|
2011-09-29 22:53:38 +08:00
|
|
|
unsigned int nRet = _Hash(strFilePath.c_str());
|
2011-11-28 16:09:01 +08:00
|
|
|
|
2011-09-19 17:53:45 +08:00
|
|
|
preloadEffect(pszFilePath);
|
|
|
|
|
|
|
|
EffectList::iterator p = s_List.find(nRet);
|
|
|
|
if (p != s_List.end())
|
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
if (NULL == p->second)
|
|
|
|
{
|
|
|
|
AppLog("CCAudioOut instance must not be NULL, id = %d", p->first);
|
|
|
|
return 0;
|
|
|
|
}
|
2012-01-11 17:24:46 +08:00
|
|
|
p->second->SetVolume(ceil(s_fEffectsVolume * 99));
|
2011-10-14 16:03:06 +08:00
|
|
|
|
2011-10-18 18:10:53 +08:00
|
|
|
if (AUDIOOUT_STATE_PLAYING == p->second->GetState())
|
2011-10-14 09:20:03 +08:00
|
|
|
{
|
2011-11-28 16:09:01 +08:00
|
|
|
return nRet; // Stop waste a lot of time, so just return.
|
2011-11-29 09:27:44 +08:00
|
|
|
//r = p->second->Stop();
|
2011-10-14 09:20:03 +08:00
|
|
|
}
|
|
|
|
|
2011-10-20 13:49:01 +08:00
|
|
|
if (s_fEffectsVolume > 0.0f)
|
|
|
|
{
|
2011-11-28 16:09:01 +08:00
|
|
|
r = p->second->Play(bLoop);
|
2011-10-20 13:49:01 +08:00
|
|
|
}
|
2011-10-18 18:10:53 +08:00
|
|
|
|
2011-10-14 09:20:03 +08:00
|
|
|
if (IsFailed(r))
|
|
|
|
{
|
2011-11-28 16:09:01 +08:00
|
|
|
AppLog("play effect fails, error code = %d", r);
|
2011-10-14 09:20:03 +08:00
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
|
|
|
return nRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::stopEffect(unsigned int nSoundId)
|
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
EffectList::iterator it = s_List.find(nSoundId);
|
|
|
|
if (it != s_List.end())
|
2011-09-19 17:53:45 +08:00
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
if (it->second != NULL)
|
|
|
|
{
|
|
|
|
it->second->Stop();
|
|
|
|
}
|
2011-11-28 16:09:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::pauseEffect(unsigned int nSoundId)
|
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
EffectList::iterator it = s_List.find(nSoundId);
|
|
|
|
if (it != s_List.end())
|
2011-11-28 16:09:01 +08:00
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
if (it->second != NULL)
|
|
|
|
{
|
|
|
|
it->second->Pause();
|
|
|
|
}
|
2011-11-28 16:09:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::pauseAllEffects()
|
|
|
|
{
|
|
|
|
for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
|
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
if (it->second != NULL)
|
|
|
|
{
|
|
|
|
it->second->Pause();
|
|
|
|
}
|
2011-11-28 16:09:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::resumeEffect(unsigned int nSoundId)
|
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
EffectList::iterator it = s_List.find(nSoundId);
|
|
|
|
if (it != s_List.end())
|
2011-11-28 16:09:01 +08:00
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
if (it->second != NULL)
|
|
|
|
{
|
|
|
|
it->second->Resume();
|
|
|
|
}
|
2011-11-28 16:09:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::resumeAllEffects()
|
|
|
|
{
|
|
|
|
for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
|
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
if (it->second != NULL)
|
|
|
|
{
|
|
|
|
it->second->Resume();
|
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-29 14:47:13 +08:00
|
|
|
void SimpleAudioEngine::stopAllEffects()
|
|
|
|
{
|
|
|
|
for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
|
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
if (it->second != NULL)
|
|
|
|
{
|
|
|
|
it->second->Stop();
|
|
|
|
}
|
2011-10-29 14:47:13 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-19 17:53:45 +08:00
|
|
|
void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
|
|
|
|
{
|
|
|
|
int nRet = 0;
|
2011-10-18 18:10:53 +08:00
|
|
|
CCAudioOut* pEffectPlayer = NULL;
|
2011-09-19 17:53:45 +08:00
|
|
|
do
|
|
|
|
{
|
|
|
|
BREAK_IF(! pszFilePath);
|
|
|
|
|
2011-11-07 18:18:10 +08:00
|
|
|
string strFilePath = fullPathFromRelativePath(pszFilePath);
|
2011-09-29 22:53:38 +08:00
|
|
|
|
|
|
|
nRet = _Hash(strFilePath.c_str());
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
BREAK_IF(s_List.end() != s_List.find(nRet));
|
|
|
|
|
2011-11-13 00:57:54 +08:00
|
|
|
//AppLog("not find effect, create it...");
|
2011-10-18 18:10:53 +08:00
|
|
|
if (s_List.size() >= 64)
|
2011-09-19 17:53:45 +08:00
|
|
|
{
|
2011-10-14 09:20:03 +08:00
|
|
|
// get the first effect, and remove it form list
|
2011-12-31 17:44:45 +08:00
|
|
|
AppLog("effect preload more than 64, delete the first effect");
|
2011-10-14 09:20:03 +08:00
|
|
|
pEffectPlayer = s_List.begin()->second;
|
2011-10-18 18:10:53 +08:00
|
|
|
pEffectPlayer->Finalize();
|
2011-12-31 17:44:45 +08:00
|
|
|
s_List.erase(s_List.begin());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NULL == pEffectPlayer)
|
|
|
|
{
|
|
|
|
pEffectPlayer = new CCAudioOut();
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
2011-12-31 17:44:45 +08:00
|
|
|
|
2011-10-18 18:10:53 +08:00
|
|
|
pEffectPlayer->Initialize(strFilePath.c_str());
|
2011-11-28 16:09:01 +08:00
|
|
|
|
|
|
|
s_List.insert(Effect(nRet, pEffectPlayer));
|
2011-09-19 17:53:45 +08:00
|
|
|
|
|
|
|
} while (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleAudioEngine::unloadEffect(const char* pszFilePath)
|
|
|
|
{
|
2011-11-07 18:18:10 +08:00
|
|
|
string strFilePath = fullPathFromRelativePath(pszFilePath);
|
2011-12-29 14:54:18 +08:00
|
|
|
unsigned int nID = _Hash(strFilePath.c_str());
|
|
|
|
EffectList::iterator p = s_List.find(nID);
|
|
|
|
if (p != s_List.end())
|
|
|
|
{
|
2011-12-31 17:44:45 +08:00
|
|
|
if (p->second != NULL)
|
|
|
|
{
|
|
|
|
delete p->second;
|
|
|
|
p->second = NULL;
|
|
|
|
AppLog("delete CCAudioOut, id = %d", nID);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AppLog("CCAudioOut instance is NULL, id = %d", nID);
|
|
|
|
}
|
|
|
|
s_List.erase(p);
|
2011-12-29 14:54:18 +08:00
|
|
|
}
|
2011-09-19 17:53:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
} // end of namespace CocosDenshion
|