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
|
#endif
|
||||||
|
|
|
@ -281,6 +281,12 @@ public:
|
||||||
*/
|
*/
|
||||||
static AudioProfile* getProfile(const std::string &profileName);
|
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:
|
protected:
|
||||||
|
|
||||||
static void remove(int audioID);
|
static void remove(int audioID);
|
||||||
|
|
|
@ -47,15 +47,18 @@ static ALCdevice *s_ALDevice = nullptr;
|
||||||
static ALCcontext *s_ALContext = nullptr;
|
static ALCcontext *s_ALContext = nullptr;
|
||||||
static bool MPG123_LAZYINIT = true;
|
static bool MPG123_LAZYINIT = true;
|
||||||
|
|
||||||
|
static AudioEngineThreadPool* s_threadPool = nullptr;
|
||||||
|
|
||||||
namespace cocos2d {
|
namespace cocos2d {
|
||||||
namespace experimental {
|
namespace experimental {
|
||||||
class AudioEngineThreadPool
|
class AudioEngineThreadPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AudioEngineThreadPool()
|
AudioEngineThreadPool()
|
||||||
: _running(true)
|
: _numThread(6)
|
||||||
, _numThread(6)
|
|
||||||
{
|
{
|
||||||
|
s_threadPool = this;
|
||||||
|
|
||||||
_threads.reserve(_numThread);
|
_threads.reserve(_numThread);
|
||||||
_tasks.reserve(_numThread);
|
_tasks.reserve(_numThread);
|
||||||
|
|
||||||
|
@ -88,21 +91,17 @@ namespace cocos2d {
|
||||||
|
|
||||||
void destroy()
|
void destroy()
|
||||||
{
|
{
|
||||||
_running = false;
|
std::unique_lock<std::mutex> lk(_sleepMutex);
|
||||||
_sleepCondition.notify_all();
|
_sleepCondition.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
for (int index = 0; index < _numThread; ++index) {
|
|
||||||
_threads[index].join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
bool _running;
|
|
||||||
std::vector<std::thread> _threads;
|
std::vector<std::thread> _threads;
|
||||||
std::vector< std::function<void ()> > _tasks;
|
std::vector< std::function<void ()> > _tasks;
|
||||||
|
|
||||||
void threadFunc(int index)
|
void threadFunc(int index)
|
||||||
{
|
{
|
||||||
while (_running) {
|
while (s_threadPool == this) {
|
||||||
std::function<void ()> task = nullptr;
|
std::function<void ()> task = nullptr;
|
||||||
_taskMutex.lock();
|
_taskMutex.lock();
|
||||||
task = _tasks[index];
|
task = _tasks[index];
|
||||||
|
@ -194,6 +193,54 @@ bool AudioEngineImpl::init()
|
||||||
return ret;
|
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)
|
int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume)
|
||||||
{
|
{
|
||||||
bool availableSourceExist = false;
|
bool availableSourceExist = false;
|
||||||
|
@ -209,50 +256,12 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume
|
||||||
return AudioEngine::INVALID_AUDIO_ID;
|
return AudioEngine::INVALID_AUDIO_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioCache* audioCache = nullptr;
|
AudioCache* audioCache = preload(filePath);
|
||||||
auto it = _audioCaches.find(filePath);
|
if (audioCache == nullptr)
|
||||||
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;
|
return AudioEngine::INVALID_AUDIO_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
audioCache->_fileFullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
|
||||||
_threadPool->addTask(std::bind(&AudioCache::readDataTask, audioCache));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
audioCache = &it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto player = &_audioPlayers[_currentAudioID];
|
auto player = &_audioPlayers[_currentAudioID];
|
||||||
player->_alSource = alSource;
|
player->_alSource = alSource;
|
||||||
player->_loop = loop;
|
player->_loop = loop;
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
|
|
||||||
void uncache(const std::string& filePath);
|
void uncache(const std::string& filePath);
|
||||||
void uncacheAll();
|
void uncacheAll();
|
||||||
|
AudioCache* preload(const std::string& filePath);
|
||||||
|
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
|
||||||
|
|
|
@ -142,38 +142,34 @@ bool AudioEngineImpl::init()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioEngineImpl::play2d(const std::string &filePath, bool loop, float volume)
|
AudioCache* AudioEngineImpl::preload(const std::string& filePath)
|
||||||
{
|
{
|
||||||
AudioCache* audioCache = nullptr;
|
AudioCache* audioCache = nullptr;
|
||||||
|
do
|
||||||
|
{
|
||||||
auto it = _audioCaches.find(filePath);
|
auto it = _audioCaches.find(filePath);
|
||||||
if (it == _audioCaches.end()) {
|
if (it == _audioCaches.end()) {
|
||||||
audioCache = &_audioCaches[filePath];
|
FileFormat fileFormat = FileFormat::UNKNOWN;
|
||||||
|
|
||||||
auto ext = filePath.substr(filePath.rfind('.'));
|
auto ext = filePath.substr(filePath.rfind('.'));
|
||||||
transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||||
|
|
||||||
bool eraseCache = true;
|
|
||||||
|
|
||||||
if (ext.compare(".wav") == 0){
|
if (ext.compare(".wav") == 0){
|
||||||
audioCache->_fileFormat = FileFormat::WAV;
|
fileFormat = FileFormat::WAV;
|
||||||
eraseCache = false;
|
|
||||||
}
|
}
|
||||||
else if (ext.compare(".ogg") == 0){
|
else if (ext.compare(".ogg") == 0){
|
||||||
audioCache->_fileFormat = FileFormat::OGG;
|
fileFormat = FileFormat::OGG;
|
||||||
eraseCache = false;
|
|
||||||
}
|
}
|
||||||
else if (ext.compare(".mp3") == 0){
|
else if (ext.compare(".mp3") == 0){
|
||||||
audioCache->_fileFormat = FileFormat::MP3;
|
fileFormat = FileFormat::MP3;
|
||||||
eraseCache = false;
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
log("unsupported media type:%s\n", ext.c_str());
|
log("unsupported media type:%s\n", ext.c_str());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eraseCache){
|
audioCache = &_audioCaches[filePath];
|
||||||
_audioCaches.erase(filePath);
|
audioCache->_fileFormat = fileFormat;
|
||||||
return AudioEngine::INVALID_AUDIO_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
||||||
audioCache->_fileFullPath = fullPath;
|
audioCache->_fileFullPath = fullPath;
|
||||||
|
@ -182,6 +178,18 @@ int AudioEngineImpl::play2d(const std::string &filePath, bool loop, float volume
|
||||||
else {
|
else {
|
||||||
audioCache = &it->second;
|
audioCache = &it->second;
|
||||||
}
|
}
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
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];
|
auto player = &_audioPlayers[_currentAudioID];
|
||||||
player->_loop = loop;
|
player->_loop = loop;
|
||||||
|
|
|
@ -58,6 +58,7 @@ NS_CC_BEGIN
|
||||||
void setFinishCallback(int audioID, const std::function<void(int, const std::string &)> &callback);
|
void setFinishCallback(int audioID, const std::function<void(int, const std::string &)> &callback);
|
||||||
void uncache(const std::string& filePath);
|
void uncache(const std::string& filePath);
|
||||||
void uncacheAll();
|
void uncacheAll();
|
||||||
|
AudioCache* preload(const std::string& filePath);
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -303,7 +303,7 @@ bool AudioControlTest::init()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_playItem = playItem;
|
_playItem = playItem;
|
||||||
playItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.7f);
|
playItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.8f);
|
||||||
addChild(playItem);
|
addChild(playItem);
|
||||||
|
|
||||||
auto stopItem = TextButton::create("stop", [&](TextButton* button){
|
auto stopItem = TextButton::create("stop", [&](TextButton* button){
|
||||||
|
@ -314,7 +314,7 @@ bool AudioControlTest::init()
|
||||||
((TextButton*)_playItem)->setEnabled(true);
|
((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);
|
addChild(stopItem);
|
||||||
|
|
||||||
auto pauseItem = TextButton::create("pause", [&](TextButton* button){
|
auto pauseItem = TextButton::create("pause", [&](TextButton* button){
|
||||||
|
@ -322,7 +322,7 @@ bool AudioControlTest::init()
|
||||||
AudioEngine::pause(_audioID);
|
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);
|
addChild(pauseItem);
|
||||||
|
|
||||||
auto resumeItem = TextButton::create("resume", [&](TextButton* button){
|
auto resumeItem = TextButton::create("resume", [&](TextButton* button){
|
||||||
|
@ -330,7 +330,7 @@ bool AudioControlTest::init()
|
||||||
AudioEngine::resume(_audioID);
|
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);
|
addChild(resumeItem);
|
||||||
|
|
||||||
auto loopItem = TextButton::create("enable-loop", [&](TextButton* button){
|
auto loopItem = TextButton::create("enable-loop", [&](TextButton* button){
|
||||||
|
@ -346,16 +346,22 @@ bool AudioControlTest::init()
|
||||||
button->setString("enable-loop");
|
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);
|
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){
|
auto uncacheItem = TextButton::create("uncache", [&](TextButton* button){
|
||||||
AudioEngine::uncache("background.mp3");
|
AudioEngine::uncache("background.mp3");
|
||||||
|
|
||||||
_audioID = AudioEngine::INVALID_AUDIO_ID;
|
_audioID = AudioEngine::INVALID_AUDIO_ID;
|
||||||
((TextButton*)_playItem)->setEnabled(true);
|
((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);
|
addChild(uncacheItem);
|
||||||
|
|
||||||
auto volumeSlider = SliderEx::create();
|
auto volumeSlider = SliderEx::create();
|
||||||
|
|
Loading…
Reference in New Issue