mirror of https://github.com/axmolengine/axmol.git
AudioEngine:support preload for audio[WIN32/WINRT 8.1/WP8.1]
This commit is contained in:
parent
1b9b741068
commit
b395ef06d8
|
@ -415,4 +415,18 @@ AudioProfile* AudioEngine::getProfile(const std::string &name)
|
|||
}
|
||||
}
|
||||
|
||||
void AudioEngine::preload(const std::string& filePath)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if (_audioEngineImpl)
|
||||
{
|
||||
if (!FileUtils::getInstance()->isFileExist(filePath)){
|
||||
return;
|
||||
}
|
||||
|
||||
_audioEngineImpl->preload(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -281,6 +281,12 @@ public:
|
|||
*/
|
||||
static AudioProfile* getProfile(const std::string &profileName);
|
||||
|
||||
/**
|
||||
* Preload audio file.
|
||||
* @param filePath The file path of an audio.
|
||||
*/
|
||||
static void preload(const std::string& filePath);
|
||||
|
||||
protected:
|
||||
|
||||
static void remove(int audioID);
|
||||
|
|
|
@ -47,15 +47,18 @@ static ALCdevice *s_ALDevice = nullptr;
|
|||
static ALCcontext *s_ALContext = nullptr;
|
||||
static bool MPG123_LAZYINIT = true;
|
||||
|
||||
static AudioEngineThreadPool* s_threadPool = nullptr;
|
||||
|
||||
namespace cocos2d {
|
||||
namespace experimental {
|
||||
class AudioEngineThreadPool
|
||||
{
|
||||
public:
|
||||
AudioEngineThreadPool()
|
||||
: _running(true)
|
||||
, _numThread(6)
|
||||
: _numThread(6)
|
||||
{
|
||||
s_threadPool = this;
|
||||
|
||||
_threads.reserve(_numThread);
|
||||
_tasks.reserve(_numThread);
|
||||
|
||||
|
@ -88,21 +91,17 @@ namespace cocos2d {
|
|||
|
||||
void destroy()
|
||||
{
|
||||
_running = false;
|
||||
std::unique_lock<std::mutex> lk(_sleepMutex);
|
||||
_sleepCondition.notify_all();
|
||||
|
||||
for (int index = 0; index < _numThread; ++index) {
|
||||
_threads[index].join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool _running;
|
||||
std::vector<std::thread> _threads;
|
||||
std::vector< std::function<void ()> > _tasks;
|
||||
|
||||
void threadFunc(int index)
|
||||
{
|
||||
while (_running) {
|
||||
while (s_threadPool == this) {
|
||||
std::function<void ()> task = nullptr;
|
||||
_taskMutex.lock();
|
||||
task = _tasks[index];
|
||||
|
@ -194,6 +193,54 @@ bool AudioEngineImpl::init()
|
|||
return ret;
|
||||
}
|
||||
|
||||
AudioCache* AudioEngineImpl::preload(const std::string& filePath)
|
||||
{
|
||||
AudioCache* audioCache = nullptr;
|
||||
|
||||
do
|
||||
{
|
||||
auto it = _audioCaches.find(filePath);
|
||||
if (it != _audioCaches.end())
|
||||
{
|
||||
audioCache = &it->second;
|
||||
break;
|
||||
}
|
||||
|
||||
auto ext = strchr(filePath.c_str(), '.');
|
||||
AudioCache::FileFormat fileFormat = AudioCache::FileFormat::UNKNOWN;
|
||||
|
||||
if (_stricmp(ext, ".ogg") == 0){
|
||||
fileFormat = AudioCache::FileFormat::OGG;
|
||||
}
|
||||
else if (_stricmp(ext, ".mp3") == 0){
|
||||
fileFormat = AudioCache::FileFormat::MP3;
|
||||
|
||||
if (MPG123_LAZYINIT){
|
||||
auto error = mpg123_init();
|
||||
if (error == MPG123_OK){
|
||||
MPG123_LAZYINIT = false;
|
||||
}
|
||||
else{
|
||||
log("Basic setup goes wrong: %s", mpg123_plain_strerror(error));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
log("unsupported media type:%s\n", ext);
|
||||
break;
|
||||
}
|
||||
|
||||
audioCache = &_audioCaches[filePath];
|
||||
audioCache->_fileFormat = fileFormat;
|
||||
|
||||
audioCache->_fileFullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||
_threadPool->addTask(std::bind(&AudioCache::readDataTask, audioCache));
|
||||
} while (false);
|
||||
|
||||
return audioCache;
|
||||
}
|
||||
|
||||
int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume)
|
||||
{
|
||||
bool availableSourceExist = false;
|
||||
|
@ -209,48 +256,10 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume
|
|||
return AudioEngine::INVALID_AUDIO_ID;
|
||||
}
|
||||
|
||||
AudioCache* audioCache = nullptr;
|
||||
auto it = _audioCaches.find(filePath);
|
||||
if (it == _audioCaches.end()) {
|
||||
audioCache = &_audioCaches[filePath];
|
||||
auto ext = strchr(filePath.c_str(), '.');
|
||||
bool eraseCache = true;
|
||||
|
||||
if (_stricmp(ext, ".ogg") == 0){
|
||||
audioCache->_fileFormat = AudioCache::FileFormat::OGG;
|
||||
eraseCache = false;
|
||||
}
|
||||
else if (_stricmp(ext, ".mp3") == 0){
|
||||
audioCache->_fileFormat = AudioCache::FileFormat::MP3;
|
||||
|
||||
if (MPG123_LAZYINIT){
|
||||
auto error = mpg123_init();
|
||||
if(error == MPG123_OK){
|
||||
MPG123_LAZYINIT = false;
|
||||
eraseCache = false;
|
||||
}
|
||||
else{
|
||||
log("Basic setup goes wrong: %s", mpg123_plain_strerror(error));
|
||||
}
|
||||
}
|
||||
else{
|
||||
eraseCache = false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
log("unsupported media type:%s\n", ext);
|
||||
}
|
||||
|
||||
if (eraseCache){
|
||||
_audioCaches.erase(filePath);
|
||||
return AudioEngine::INVALID_AUDIO_ID;
|
||||
}
|
||||
|
||||
audioCache->_fileFullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||
_threadPool->addTask(std::bind(&AudioCache::readDataTask, audioCache));
|
||||
}
|
||||
else {
|
||||
audioCache = &it->second;
|
||||
AudioCache* audioCache = preload(filePath);
|
||||
if (audioCache == nullptr)
|
||||
{
|
||||
return AudioEngine::INVALID_AUDIO_ID;
|
||||
}
|
||||
|
||||
auto player = &_audioPlayers[_currentAudioID];
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
|
||||
void uncache(const std::string& filePath);
|
||||
void uncacheAll();
|
||||
AudioCache* preload(const std::string& filePath);
|
||||
|
||||
void update(float dt);
|
||||
|
||||
|
|
|
@ -142,45 +142,53 @@ bool AudioEngineImpl::init()
|
|||
return ret;
|
||||
}
|
||||
|
||||
int AudioEngineImpl::play2d(const std::string &filePath, bool loop, float volume)
|
||||
AudioCache* AudioEngineImpl::preload(const std::string& filePath)
|
||||
{
|
||||
AudioCache* audioCache = nullptr;
|
||||
auto it = _audioCaches.find(filePath);
|
||||
if (it == _audioCaches.end()) {
|
||||
audioCache = &_audioCaches[filePath];
|
||||
do
|
||||
{
|
||||
auto it = _audioCaches.find(filePath);
|
||||
if (it == _audioCaches.end()) {
|
||||
FileFormat fileFormat = FileFormat::UNKNOWN;
|
||||
|
||||
auto ext = filePath.substr(filePath.rfind('.'));
|
||||
transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||
auto ext = filePath.substr(filePath.rfind('.'));
|
||||
transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||
|
||||
bool eraseCache = true;
|
||||
if (ext.compare(".wav") == 0){
|
||||
fileFormat = FileFormat::WAV;
|
||||
}
|
||||
else if (ext.compare(".ogg") == 0){
|
||||
fileFormat = FileFormat::OGG;
|
||||
}
|
||||
else if (ext.compare(".mp3") == 0){
|
||||
fileFormat = FileFormat::MP3;
|
||||
}
|
||||
else{
|
||||
log("unsupported media type:%s\n", ext.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
if (ext.compare(".wav") == 0){
|
||||
audioCache->_fileFormat = FileFormat::WAV;
|
||||
eraseCache = false;
|
||||
}
|
||||
else if (ext.compare(".ogg") == 0){
|
||||
audioCache->_fileFormat = FileFormat::OGG;
|
||||
eraseCache = false;
|
||||
}
|
||||
else if (ext.compare(".mp3") == 0){
|
||||
audioCache->_fileFormat = FileFormat::MP3;
|
||||
eraseCache = false;
|
||||
}
|
||||
else{
|
||||
log("unsupported media type:%s\n", ext.c_str());
|
||||
}
|
||||
audioCache = &_audioCaches[filePath];
|
||||
audioCache->_fileFormat = fileFormat;
|
||||
|
||||
if (eraseCache){
|
||||
_audioCaches.erase(filePath);
|
||||
return AudioEngine::INVALID_AUDIO_ID;
|
||||
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||
audioCache->_fileFullPath = fullPath;
|
||||
_threadPool->addTask(std::bind(&AudioCache::readDataTask, audioCache));
|
||||
}
|
||||
else {
|
||||
audioCache = &it->second;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||
audioCache->_fileFullPath = fullPath;
|
||||
_threadPool->addTask(std::bind(&AudioCache::readDataTask, audioCache));
|
||||
}
|
||||
else {
|
||||
audioCache = &it->second;
|
||||
return audioCache;
|
||||
}
|
||||
|
||||
int AudioEngineImpl::play2d(const std::string &filePath, bool loop, float volume)
|
||||
{
|
||||
auto audioCache = preload(filePath);
|
||||
if (audioCache == nullptr)
|
||||
{
|
||||
return AudioEngine::INVALID_AUDIO_ID;
|
||||
}
|
||||
|
||||
auto player = &_audioPlayers[_currentAudioID];
|
||||
|
|
|
@ -58,6 +58,7 @@ NS_CC_BEGIN
|
|||
void setFinishCallback(int audioID, const std::function<void(int, const std::string &)> &callback);
|
||||
void uncache(const std::string& filePath);
|
||||
void uncacheAll();
|
||||
AudioCache* preload(const std::string& filePath);
|
||||
void update(float dt);
|
||||
|
||||
private:
|
||||
|
|
|
@ -303,7 +303,7 @@ bool AudioControlTest::init()
|
|||
}
|
||||
});
|
||||
_playItem = playItem;
|
||||
playItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.7f);
|
||||
playItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.8f);
|
||||
addChild(playItem);
|
||||
|
||||
auto stopItem = TextButton::create("stop", [&](TextButton* button){
|
||||
|
@ -314,7 +314,7 @@ bool AudioControlTest::init()
|
|||
((TextButton*)_playItem)->setEnabled(true);
|
||||
}
|
||||
});
|
||||
stopItem->setPosition(layerSize.width * 0.7f,layerSize.height * 0.7f);
|
||||
stopItem->setPosition(layerSize.width * 0.7f,layerSize.height * 0.8f);
|
||||
addChild(stopItem);
|
||||
|
||||
auto pauseItem = TextButton::create("pause", [&](TextButton* button){
|
||||
|
@ -322,7 +322,7 @@ bool AudioControlTest::init()
|
|||
AudioEngine::pause(_audioID);
|
||||
}
|
||||
});
|
||||
pauseItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.6f);
|
||||
pauseItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.7f);
|
||||
addChild(pauseItem);
|
||||
|
||||
auto resumeItem = TextButton::create("resume", [&](TextButton* button){
|
||||
|
@ -330,32 +330,38 @@ bool AudioControlTest::init()
|
|||
AudioEngine::resume(_audioID);
|
||||
}
|
||||
});
|
||||
resumeItem->setPosition(layerSize.width * 0.7f,layerSize.height * 0.6f);
|
||||
resumeItem->setPosition(layerSize.width * 0.7f,layerSize.height * 0.7f);
|
||||
addChild(resumeItem);
|
||||
|
||||
auto loopItem = TextButton::create("enable-loop", [&](TextButton* button){
|
||||
_loopEnabled = !_loopEnabled;
|
||||
|
||||
if (_audioID != AudioEngine::INVALID_AUDIO_ID ) {
|
||||
|
||||
if (_audioID != AudioEngine::INVALID_AUDIO_ID) {
|
||||
AudioEngine::setLoop(_audioID, _loopEnabled);
|
||||
}
|
||||
if(_loopEnabled){
|
||||
if (_loopEnabled){
|
||||
button->setString("disable-loop");
|
||||
}
|
||||
else {
|
||||
button->setString("enable-loop");
|
||||
}
|
||||
});
|
||||
loopItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.5f);
|
||||
loopItem->setPosition(layerSize.width * 0.5f, layerSize.height * 0.5f);
|
||||
addChild(loopItem);
|
||||
|
||||
auto preloadItem = TextButton::create("preload", [&](TextButton* button){
|
||||
AudioEngine::preload("background.mp3");
|
||||
});
|
||||
preloadItem->setPosition(layerSize.width * 0.3f, layerSize.height * 0.6f);
|
||||
addChild(preloadItem);
|
||||
|
||||
auto uncacheItem = TextButton::create("uncache", [&](TextButton* button){
|
||||
AudioEngine::uncache("background.mp3");
|
||||
|
||||
_audioID = AudioEngine::INVALID_AUDIO_ID;
|
||||
((TextButton*)_playItem)->setEnabled(true);
|
||||
});
|
||||
uncacheItem->setPosition(layerSize.width * 0.7f,layerSize.height * 0.5f);
|
||||
uncacheItem->setPosition(layerSize.width * 0.7f,layerSize.height * 0.6f);
|
||||
addChild(uncacheItem);
|
||||
|
||||
auto volumeSlider = SliderEx::create();
|
||||
|
|
Loading…
Reference in New Issue