AudioEngine:support preload for audio[WIN32/WINRT 8.1/WP8.1]

This commit is contained in:
WenhaiLin 2015-07-08 10:48:20 +08:00
parent 1b9b741068
commit b395ef06d8
7 changed files with 137 additions and 92 deletions

View File

@ -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

View File

@ -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);

View File

@ -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,50 +256,12 @@ 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);
AudioCache* audioCache = preload(filePath);
if (audioCache == nullptr)
{
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];
player->_alSource = alSource;
player->_loop = loop;

View File

@ -61,6 +61,7 @@ public:
void uncache(const std::string& filePath);
void uncacheAll();
AudioCache* preload(const std::string& filePath);
void update(float dt);

View File

@ -142,38 +142,34 @@ 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;
do
{
auto it = _audioCaches.find(filePath);
if (it == _audioCaches.end()) {
audioCache = &_audioCaches[filePath];
FileFormat fileFormat = FileFormat::UNKNOWN;
auto ext = filePath.substr(filePath.rfind('.'));
transform(ext.begin(), ext.end(), ext.begin(), tolower);
bool eraseCache = true;
if (ext.compare(".wav") == 0){
audioCache->_fileFormat = FileFormat::WAV;
eraseCache = false;
fileFormat = FileFormat::WAV;
}
else if (ext.compare(".ogg") == 0){
audioCache->_fileFormat = FileFormat::OGG;
eraseCache = false;
fileFormat = FileFormat::OGG;
}
else if (ext.compare(".mp3") == 0){
audioCache->_fileFormat = FileFormat::MP3;
eraseCache = false;
fileFormat = FileFormat::MP3;
}
else{
log("unsupported media type:%s\n", ext.c_str());
break;
}
if (eraseCache){
_audioCaches.erase(filePath);
return AudioEngine::INVALID_AUDIO_ID;
}
audioCache = &_audioCaches[filePath];
audioCache->_fileFormat = fileFormat;
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
audioCache->_fileFullPath = fullPath;
@ -182,6 +178,18 @@ int AudioEngineImpl::play2d(const std::string &filePath, bool loop, float volume
else {
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];
player->_loop = loop;

View File

@ -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:

View File

@ -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,7 +330,7 @@ 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){
@ -346,16 +346,22 @@ bool AudioControlTest::init()
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();