axmol/CocosDenshion/bada/SimpleAudioEngine.cpp

426 lines
9.6 KiB
C++
Raw Normal View History

#include "SimpleAudioEngine.h"
#include "MyAudioOutListener.h"
#include <FBase.h>
#include <FMedia.h>
#include <FSystem.h>
#include <string>
#include <map>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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
typedef map<unsigned int, MyAudioOutEventListener*> EffectList;
typedef pair<unsigned int ,MyAudioOutEventListener*> 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 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 void unloadEffectAll()
{
for (EffectList::iterator it = s_List.begin(); it != s_List.end(); ++it)
{
delete it->second;
}
s_List.clear();
}
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 )
{
AppLog("OnPlayerOpened");
}
/**
* Notifies that the Player has reached the end of the clip.
*
*/
2011-09-28 22:53:51 +08:00
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()
*/
2011-09-28 22:53:51 +08:00
virtual void OnPlayerSeekCompleted( result r )
{
AppLog("OnPlayerSeekCompleted");
}
/**
* 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)
{
AppLog("OnPlayerBuffering");
}
/**
* 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 )
{
AppLog("OnPlayerErrorOccurred");
}
/**
* 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)
{
//Insert your code here
AppLog("OnPlayerInterrupted");
if (s_pBackPlayer->GetState() == PLAYER_STATE_PLAYING)
s_pBackPlayer->Pause();
}
/**
* Notifies that the interrupting Player has been released.
*
*/
2011-09-28 22:53:51 +08:00
virtual void OnPlayerReleased(void)
{
//Insert your code here
AppLog("OnPlayerReleased");
if (s_pBackPlayer->GetState() != PLAYER_STATE_PLAYING)
s_pBackPlayer->Play();
}
};
static MyPlayerEventListener s_playerListener;
SimpleAudioEngine::SimpleAudioEngine()
{
}
SimpleAudioEngine::~SimpleAudioEngine()
{
AppLog("destroy SimpleAudioEngine");
unloadEffectAll();
if( s_pBackPlayer )
{
PlayerState nowState = s_pBackPlayer->GetState();
if( nowState == PLAYER_STATE_PLAYING || nowState == PLAYER_STATE_PAUSED )
{
s_pBackPlayer->Stop();
s_pBackPlayer->Close();
}else if(nowState == PLAYER_STATE_OPENED || nowState == PLAYER_STATE_ENDOFCLIP || nowState == PLAYER_STATE_STOPPED )
{
s_pBackPlayer->Close();
}
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::setResourcePath(const char *pszResourcePath)
{
s_strResourcePath = pszResourcePath;
}
void SimpleAudioEngine::preloadBackgroundMusic(const char* pszFilePath)
{
}
void SimpleAudioEngine::playBackgroundMusic(const char* pszFilePath, bool bLoop)
{
if (s_pBackPlayer)
{
PlayerState nowState = s_pBackPlayer->GetState();
if( nowState == PLAYER_STATE_PLAYING || nowState == PLAYER_STATE_PAUSED )
{
s_pBackPlayer->Stop();
s_pBackPlayer->Close();
}else if(nowState == PLAYER_STATE_OPENED || nowState == PLAYER_STATE_ENDOFCLIP || nowState == PLAYER_STATE_STOPPED )
{
s_pBackPlayer->Close();
}
}
else
{
s_pBackPlayer = new Player();
result r = s_pBackPlayer->Construct(s_playerListener, null);
AppLog("player construct return %d", r);
}
setBackgroundMusicVolume(s_fBackgroundMusicVolume);
string strFilePath = s_strResourcePath+pszFilePath;
// OpenFile must use synchronous param, for after that it will playing.
result r = s_pBackPlayer->OpenFile(strFilePath.c_str(), false);
if (IsFailed(r))
{
AppLog("Openfile fails\n");
}
else
{
s_pBackPlayer->SetLooping(bLoop);
}
2011-09-28 22:53:51 +08:00
if (s_fBackgroundMusicVolume > 0.0f)
{
r = s_pBackPlayer->Play();
}
}
void SimpleAudioEngine::stopBackgroundMusic(bool bReleaseData)
{
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_pBackPlayer->Pause();
}
}
void SimpleAudioEngine::resumeBackgroundMusic()
{
2011-09-28 22:53:51 +08:00
if (s_pBackPlayer && PLAYER_STATE_PLAYING != s_pBackPlayer->GetState())
{
s_pBackPlayer->Play();
}
}
void SimpleAudioEngine::rewindBackgroundMusic()
{
if (s_pBackPlayer)
{
s_pBackPlayer->SeekTo(0);
if (PLAYER_STATE_PLAYING != s_pBackPlayer->GetState())
{
s_pBackPlayer->Play();
}
}
}
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));
}
2011-09-28 22:53:51 +08:00
AppLog("volume = %f", volume);
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*/)
{
string strFilePath = s_strResourcePath+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));
p->second->play();
}
return nRet;
}
void SimpleAudioEngine::stopEffect(unsigned int nSoundId)
{
MyAudioOutEventListener*& pListener = s_List[nSoundId];
if (pListener != null)
{
pListener->stop();
}
}
void SimpleAudioEngine::preloadEffect(const char* pszFilePath)
{
int nRet = 0;
do
{
BREAK_IF(! pszFilePath);
string strFilePath = s_strResourcePath+pszFilePath;
nRet = _Hash(strFilePath.c_str());
BREAK_IF(s_List.end() != s_List.find(nRet));
if (s_List.size() >= 64)
{
unloadEffectAll();
}
MyAudioOutEventListener* pListener = new MyAudioOutEventListener();
pListener->Construct(strFilePath.c_str());
s_List.insert(Effect(nRet, pListener));
} while (0);
}
void SimpleAudioEngine::unloadEffect(const char* pszFilePath)
{
string strFilePath = s_strResourcePath+pszFilePath;
unsigned int nSoundId = _Hash(strFilePath.c_str());
MyAudioOutEventListener*& pListener = s_List[nSoundId];
delete pListener;
s_List.erase(nSoundId);
}
} // end of namespace CocosDenshion