From ca652cefeeb8e2ab56952caf17d0f09abc4dbe27 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 3 Sep 2014 18:18:47 +0800 Subject: [PATCH 01/32] New audio engine API[2d] --- cocos/audio/include/AudioEngine.h | 289 ++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 cocos/audio/include/AudioEngine.h diff --git a/cocos/audio/include/AudioEngine.h b/cocos/audio/include/AudioEngine.h new file mode 100644 index 0000000000..b05c1a1472 --- /dev/null +++ b/cocos/audio/include/AudioEngine.h @@ -0,0 +1,289 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS +#ifndef __AUDIO_ENGINE_H_ +#define __AUDIO_ENGINE_H_ + +#include +#include + +#include "2d/CCNode.h" +#include "Export.h" + +#ifdef ERROR +#undef ERROR +#endif // ERROR + +NS_CC_BEGIN + +class AudioEngine; +class AudioEngineImpl; + +class EXPORT_DLL AudioProfile +{ +public: + unsigned int maxInstances; + + /* minimum delay in between sounds */ + double minDelay; + + /*the following property only take effect on 3d audio */ + float minRange; + float maxRange; + +private: + AudioProfile() + : minDelay(0.0) + , maxInstances(0) + , lastPlayTime(0.0) + { + + } + + std::list audioIDs; + + double lastPlayTime; + + friend class AudioEngine; + friend class AudioEngineImpl; +}; + +/** + @class AudioEngine + @brief + @note + */ + +class EXPORT_DLL AudioEngine +{ +public: + enum class AudioState + { + INITIAL, + PLAYING, + PAUSED + }; + + static const int INVAILD_AUDIO_ID; + + static const float TIME_UNKNOWN; + + /** Returns a shared instance of the AudioEngine */ + static AudioEngine* getInstance(); + + /** + * Release the shared Audio Engine object + @warning It must be called before the application exit + */ + static void destroyInstance(); + + /** Create an audio profile + * + */ + virtual AudioProfile* createProfile(const std::string& name,int maxInstance = 0,double minDelay = 0.0f,float minRange = 0.0f,float maxRange = 1.0f); + + /** Get an audio profile + * + */ + virtual AudioProfile* getProfile(const std::string& name); + + /** Setup default profiles for audio instances + * @param profile a profile return by createProfile/getProfile function + */ + virtual void setDefaultProfile(AudioProfile* profile); + + /** Gets the default profile of audio instances + * @return the default profile of audio instances + */ + virtual AudioProfile* getDefaultProfile() const; + + /** Play 2d sound + * @param filePath The path of an audio file + * @param loop Whether audio instance loop or not + * @param volume volume value (range from 0.0 to 1.0) + * @param profile a profile return by createProfile/getProfile function + * @return an audio ID. It allows you to dynamically change the behavior of an audio instance on the fly. + */ + virtual int play2d(const std::string& filePath, bool loop = false, float volume = 1.0f, AudioProfile *profile = nullptr); + + /** Sets whether an audio instance loop or not. + @param audioID an audioID returned by the play2d function + @param loop Whether audio instance loop or not + */ + virtual void setLoop(int audioID, bool loop); + + /** Checks whether an audio instance is loop. + * @param audioID an audioID returned by the play2d function + * @return Whether or not an audio instance is loop. + */ + virtual bool isLoop(int audioID) const; + + /** Sets volume for an audio instance. + * @param audioID an audioID returned by the play2d function + * @param volume volume value (range from 0.0 to 1.0) + */ + virtual void setVolume(int audioID, float volume); + + /** Gets the volume value of an audio instance. + * @param audioID an audioID returned by the play2d function + * @return volume value (range from 0.0 to 1.0) + */ + virtual float getVolume(int audioID) const; + + /** Pause an audio instance. + * @param audioID an audioID returned by the play2d function + */ + virtual void pause(int audioID); + + /** Pause all playing audio instances */ + virtual void pauseAll(); + + /** Resume an audio instance. + * @param audioID an audioID returned by the play2d function + */ + virtual void resume(int audioID); + + /** Resume all suspended audio instances */ + virtual void resumeAll(); + + /** Stop an audio instance. + * @param audioID an audioID returned by the play2d function + */ + virtual void stop(int audioID); + + /** Stop all audio instances */ + virtual void stopAll(); + + /** Sets the current playback position of an audio instance. + * @param audioID an audioID returned by the play2d function + * @return + */ + virtual bool setCurrentTime(int audioID, float time); + + /** Gets the current playback position of an audio instance. + * @param audioID an audioID returned by the play2d function + * @return the current playback position of an audio instance + */ + virtual float getCurrentTime(int audioID); + + /** Gets the duration of an audio instance. + * @param audioID an audioID returned by the play2d function + * @return the duration of an audio instance + */ + virtual float getDuration(int audioID); + + /** Returns the state of an audio instance. + * @param audioID an audioID returned by the play2d function + * @return the status of an audio instance + */ + virtual AudioState getState(int audioID) const; + + /** Register a callback to be invoked when an audio instance has completed playing. + * @param audioID an audioID returned by the play2d function + * @param callback + */ + virtual void setFinishCallback(int audioID, const std::function& callback); + + virtual unsigned int getMaxAudioInstance(); + + virtual bool setMaxAudioInstance(unsigned int maxInstances); + + /** Uncache the audio data from internal buffer. + * AudioEngine cache audio data on ios platform + * @warning This can lead to stop related audio first. + * @param filePath The path of an audio file + */ + void uncache(const std::string& filePath); + + /** Uncache all audio data from internal buffer. + * @warning All audio will be stopped first. + * @param + */ + void uncacheAll(); + + /** Setup profiles for an audio instance. + * @param audioID an audioID returned by the play2d function + * @param profile a profile for audio instance + */ + virtual void setProfile(int audioID, AudioProfile* profile); + + /** Gets the profiles of audio instance. + * @param audioID an audioID returned by the play2d function + * @return the profile of audio instance + */ + virtual AudioProfile* getProfile(int audioID); + +protected: + AudioEngine(); + virtual ~AudioEngine(); + + // + void remove(int audioID); + + virtual bool init(); + + class AudioInfo + { + public: + AudioInfo() + : profile(nullptr) + , duration(TIME_UNKNOWN) + , state(AudioState::INITIAL) + { + + } + + const std::string* filePath; + AudioProfile* profile; + + float volume; + bool loop; + float duration; + AudioState state; + + bool is3dAudio; + }; + + //audioID,audioAttribute + std::unordered_map _audioInfos; + + //audio file path,audio IDs + std::unordered_map> _audioIDs; + + //profileName,AudioProfile + std::unordered_map _audioProfiles; + + int _maxInstances; + + AudioProfile* _defaultProfile; + + AudioEngineImpl* _audioEngineImpl; + + friend class AudioEngineImpl; +}; + +NS_CC_END + +#endif // __AUDIO_ENGINE_H_ +#endif From fc9a0f9be95622a8c87ebf28e29e44ec9f1b444b Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 3 Sep 2014 18:19:21 +0800 Subject: [PATCH 02/32] Implement logical codes of new audio engine on IOS. --- cocos/audio/AudioEngine.cpp | 443 +++++++++++++++++++++++++ cocos/audio/ios/AudioCache.h | 97 ++++++ cocos/audio/ios/AudioCache.mm | 234 +++++++++++++ cocos/audio/ios/AudioEngine-inl.h | 97 ++++++ cocos/audio/ios/AudioEngine-inl.mm | 505 +++++++++++++++++++++++++++++ cocos/audio/ios/AudioPlayer.h | 78 +++++ cocos/audio/ios/AudioPlayer.mm | 263 +++++++++++++++ 7 files changed, 1717 insertions(+) create mode 100644 cocos/audio/AudioEngine.cpp create mode 100644 cocos/audio/ios/AudioCache.h create mode 100644 cocos/audio/ios/AudioCache.mm create mode 100644 cocos/audio/ios/AudioEngine-inl.h create mode 100644 cocos/audio/ios/AudioEngine-inl.mm create mode 100644 cocos/audio/ios/AudioPlayer.h create mode 100644 cocos/audio/ios/AudioPlayer.mm diff --git a/cocos/audio/AudioEngine.cpp b/cocos/audio/AudioEngine.cpp new file mode 100644 index 0000000000..02c611644c --- /dev/null +++ b/cocos/audio/AudioEngine.cpp @@ -0,0 +1,443 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS + +#include "audio/include/AudioEngine.h" +#include "platform/CCFileUtils.h" +#include "base/ccUtils.h" + +#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID +#include "android/AudioEngine-inl.h" +#elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS +#include "ios/AudioEngine-inl.h" +#endif + +static cocos2d::AudioEngine *s_sharedAudioEngine = nullptr; + +#define TIME_DELAY_PRECISION 0.0001 + +using namespace cocos2d; + +const int AudioEngine::INVAILD_AUDIO_ID = -1; +const float AudioEngine::TIME_UNKNOWN = -1.0f; + +AudioEngine* AudioEngine::getInstance() +{ + if (!s_sharedAudioEngine) + { + s_sharedAudioEngine = new (std::nothrow) AudioEngine(); + CCASSERT(s_sharedAudioEngine, "FATAL: Not enough memory"); + + if(!s_sharedAudioEngine->init()){ + delete s_sharedAudioEngine; + s_sharedAudioEngine = nullptr; + } + } + + return s_sharedAudioEngine; +} + +void AudioEngine::destroyInstance() +{ + delete s_sharedAudioEngine; + s_sharedAudioEngine = nullptr; +} + +AudioEngine::AudioEngine() + : _maxInstances(kMaxSources) +{ + _audioEngineImpl = new (std::nothrow) AudioEngineImpl(this); + + _audioProfiles["audioengine_defaultProfile"] = new AudioProfile; + _defaultProfile = _audioProfiles["audioengine_defaultProfile"]; +} + +AudioEngine::~AudioEngine() +{ + for (auto it = _audioProfiles.begin(); it != _audioProfiles.end(); ++it) { + delete it->second; + } + _audioProfiles.clear(); + + delete _audioEngineImpl; +} + +bool AudioEngine::init() +{ + return _audioEngineImpl->init(); +} + +int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, AudioProfile *profile) +{ + int ret = AudioEngine::INVAILD_AUDIO_ID; + if ( !FileUtils::getInstance()->isFileExist(filePath)){ + return ret; + } + + do { + auto targetProfile = profile; + if (!targetProfile) { + targetProfile = _defaultProfile; + } + + if (_audioInfos.size() >= _maxInstances || (targetProfile->maxInstances != 0 && targetProfile->audioIDs.size() >= targetProfile->maxInstances)) { + log("Fail to play %s cause by limited max instance",filePath.c_str()); + break; + } + + if (targetProfile->minDelay > TIME_DELAY_PRECISION) { + auto currTime = utils::gettime(); + if (targetProfile->lastPlayTime > TIME_DELAY_PRECISION && currTime - targetProfile->lastPlayTime <= targetProfile->minDelay) { + log("Fail to play %s cause by limited minimum delay",filePath.c_str()); + break; + } + } + + if (volume < 0.0f) { + volume = 0.0f; + } + else if (volume > 1.0f){ + volume = 1.0f; + } + + ret = _audioEngineImpl->play2d(filePath, loop, volume, targetProfile); + if (ret != INVAILD_AUDIO_ID) + { + _audioIDs[filePath].push_back(ret); + auto it = _audioIDs.find(filePath); + + auto& audioRef = _audioInfos[ret]; + audioRef.volume = volume; + audioRef.loop = loop; + audioRef.is3dAudio = false; + audioRef.filePath = &it->first; + audioRef.profile = targetProfile; + //audioRef.state = AudioEngine::AudioState::PLAYING; + } + } while (0); + + return ret; +} + +void AudioEngine::setLoop(int audioID, bool loop) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end() && it->second.loop != loop){ + _audioEngineImpl->setLoop(audioID, loop); + it->second.loop = loop; + } +} + +void AudioEngine::setVolume(int audioID, float volume) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end()){ + if (volume < 0.0f) { + volume = 0.0f; + } + else if (volume > 1.0f){ + volume = 1.0f; + } + _audioEngineImpl->setVolume(audioID, volume); + it->second.volume = volume; + } +} + +void AudioEngine::pause(int audioID) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end() && it->second.state == AudioState::PLAYING){ + _audioEngineImpl->pause(audioID); + it->second.state = AudioState::PAUSED; + } +} + +void AudioEngine::pauseAll() +{ + auto itEnd = _audioInfos.end(); + for (auto it = _audioInfos.begin(); it != itEnd; ++it) + { + if (it->second.state == AudioState::PLAYING) + { + _audioEngineImpl->pause(it->first); + it->second.state = AudioState::PAUSED; + } + } +} + +void AudioEngine::resume(int audioID) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end() && it->second.state == AudioState::PAUSED){ + _audioEngineImpl->resume(audioID); + it->second.state = AudioState::PLAYING; + } +} + +void AudioEngine::resumeAll() +{ + auto itEnd = _audioInfos.end(); + for (auto it = _audioInfos.begin(); it != itEnd; ++it) + { + if (it->second.state == AudioState::PAUSED) + { + _audioEngineImpl->resume(it->first); + it->second.state = AudioState::PLAYING; + } + } +} + +void AudioEngine::stop(int audioID) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end()){ + _audioEngineImpl->stop(audioID); + + if (it->second.profile) { + it->second.profile->audioIDs.remove(audioID); + } + _audioIDs[*it->second.filePath].remove(audioID); + _audioInfos.erase(audioID); + } +} + +void AudioEngine::remove(int audioID) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end()){ + if (it->second.profile) { + it->second.profile->audioIDs.remove(audioID); + } + _audioIDs[*it->second.filePath].remove(audioID); + _audioInfos.erase(audioID); + } +} + +void AudioEngine::stopAll() +{ + _audioEngineImpl->stopAll(); + auto itEnd = _audioInfos.end(); + for (auto it = _audioInfos.begin(); it != itEnd; ++it) + { + if (it->second.profile){ + it->second.profile->audioIDs.remove(it->first); + } + } + _audioIDs.clear(); + _audioInfos.clear(); +} + +void AudioEngine::uncache(const std::string &filePath) +{ + if(_audioIDs.find(filePath) != _audioIDs.end()){ + auto itEnd = _audioIDs[filePath].end(); + int audioID; + for (auto it = _audioIDs[filePath].begin() ; it != itEnd; ++it) { + audioID = *it; + _audioEngineImpl->stop(audioID); + + auto& info = _audioInfos[audioID]; + if (info.profile) { + info.profile->audioIDs.remove(audioID); + } + _audioInfos.erase(audioID); + } + _audioEngineImpl->uncache(filePath); + _audioIDs.erase(filePath); + } +} + +void AudioEngine::uncacheAll() +{ + stopAll(); + _audioEngineImpl->uncacheAll(); +} + +float AudioEngine::getDuration(int audioID) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end() && it->second.state != AudioState::INITIAL) + { + if (it->second.duration == TIME_UNKNOWN) + { + it->second.duration = _audioEngineImpl->getDuration(audioID); + } + return it->second.duration; + } + + return TIME_UNKNOWN; +} + +bool AudioEngine::setCurrentTime(int audioID, float time) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end() && it->second.state != AudioState::INITIAL){ + return _audioEngineImpl->setCurrentTime(audioID, time); + } + + return false; +} + +float AudioEngine::getCurrentTime(int audioID) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end() && it->second.state != AudioState::INITIAL){ + return _audioEngineImpl->getCurrentTime(audioID); + } + return 0.0f; +} + +void AudioEngine::setFinishCallback(int audioID, const std::function &callback) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end()){ + _audioEngineImpl->setFinishCallback(audioID, callback); + } +} + +bool AudioEngine::setMaxAudioInstance(unsigned int maxInstances) +{ + if (maxInstances <= kMaxSources) { + _maxInstances = maxInstances; + return true; + } + + return false; +} + +void AudioEngine::setDefaultProfile(AudioProfile *profile) +{ + if (_defaultProfile != profile && _defaultProfile) { + auto itEnd = _defaultProfile->audioIDs.end(); + for (auto it = _defaultProfile->audioIDs.begin() ; it != itEnd; ++it) { + _audioInfos[*it].profile = profile; + profile->audioIDs.push_back(*it); + } + _defaultProfile->audioIDs.clear(); + } + + _defaultProfile = profile; +} + +void AudioEngine::setProfile(int audioID, AudioProfile *profile) +{ + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end()) + { + if (it->second.profile) { + it->second.profile->audioIDs.remove(audioID); + } + + it->second.profile = profile; + if (profile) { + profile->audioIDs.push_back(audioID); + } + } +} + +AudioProfile* AudioEngine::createProfile(const std::string &name, int maxInstances, double minDelay, float minRange, float maxRange) +{ + if (_audioProfiles.find(name) == _audioProfiles.end()) { + _audioProfiles[name] = new AudioProfile; + } + auto profile = _audioProfiles[name]; + + profile->maxInstances = maxInstances; + profile->minDelay = minDelay; + profile->minRange = minRange; + profile->maxRange = maxRange; + + return profile; +} + +AudioProfile* AudioEngine::getProfile(const std::string &name) +{ + auto it = _audioProfiles.find(name); + if (it != _audioProfiles.end()) { + return it->second; + } else { + log("AudioEngine::getProfile-->profile:%s not found", name.c_str()); + return nullptr; + } +} + +bool AudioEngine::isLoop(int audioID) const +{ + auto tmpIterator = _audioInfos.find(audioID); + if (tmpIterator != _audioInfos.end()) + { + return tmpIterator->second.loop; + } + + log("AudioEngine::isLoop-->The audio instance %d is non-existent", audioID); + return false; +} + +float AudioEngine::getVolume(int audioID) const +{ + auto tmpIterator = _audioInfos.find(audioID); + if (tmpIterator != _audioInfos.end()) + { + return tmpIterator->second.volume; + } + + log("AudioEngine::getVolume-->The audio instance %d is non-existent", audioID); + return 0.0f; +} + +AudioEngine::AudioState AudioEngine::getState(int audioID) const +{ + auto tmpIterator = _audioInfos.find(audioID); + if (tmpIterator != _audioInfos.end()) + { + return tmpIterator->second.state; + } + + log("AudioEngine::getState-->The audio instance %d is non-existent", audioID); + return AudioState::INITIAL; +} + +AudioProfile* AudioEngine::getProfile(int audioID) +{ + auto tmpIterator = _audioInfos.find(audioID); + if (tmpIterator != _audioInfos.end()) + { + return tmpIterator->second.profile; + } + + log("AudioEngine::getProfile-->The audio instance %d is non-existent", audioID); + return nullptr; +} + +AudioProfile* AudioEngine::getDefaultProfile() const +{ + return _defaultProfile; +} + +unsigned int AudioEngine::getMaxAudioInstance() +{ + return _maxInstances; +} + +#endif diff --git a/cocos/audio/ios/AudioCache.h b/cocos/audio/ios/AudioCache.h new file mode 100644 index 0000000000..c72000c647 --- /dev/null +++ b/cocos/audio/ios/AudioCache.h @@ -0,0 +1,97 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS + +#ifndef __AUDIO_CACHE_H_ +#define __AUDIO_CACHE_H_ + +#import +#import + +#include +#include +#include + +#include "base/CCPlatformMacros.h" + +#define QUEUEBUFFER_NUM 3 + +NS_CC_BEGIN + +class AudioEngineImpl; +class AudioPlayer; + +class AudioCache{ +public: + AudioCache(); + ~AudioCache(); + + void addCallbacks(const std::function &callback); + +private: + + void readDataThread(); + + void invokingCallbacks(); + + //pcm data related stuff + ALsizei _dataSize; + ALenum _format; + ALsizei _sampleRate; + float _duration; + int _bytesPerFrame; + AudioStreamBasicDescription outputFormat; + + /*Cache related stuff; + * Cache pcm data when sizeInBytes less than PCMDATA_CACHEMAXSIZE + */ + ALuint _alBufferId; + char* _pcmData; + SInt64 _bytesOfRead; + + /*Queue buffer related stuff + * Streaming in openal when sizeInBytes greater then PCMDATA_CACHEMAXSIZE + */ + char* _queBuffers[QUEUEBUFFER_NUM]; + UInt32 _queBufferFrames; + UInt32 _queBufferBytes; + + bool _alBufferReady; + std::mutex _callbackMutex; + + std::vector< std::function > _callbacks; + std::mutex _readThreadMutex; + + bool _release; + std::string _fileFullPath; + + friend class AudioEngineImpl; + friend class AudioPlayer; +} ; + +NS_CC_END + +#endif // __AUDIO_CACHE_H_ +#endif + diff --git a/cocos/audio/ios/AudioCache.mm b/cocos/audio/ios/AudioCache.mm new file mode 100644 index 0000000000..3ae7253e26 --- /dev/null +++ b/cocos/audio/ios/AudioCache.mm @@ -0,0 +1,234 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#include "AudioCache.h" +#include +#import +#import + +#define PCMDATA_CACHEMAXSIZE 1048576//1MB + +typedef ALvoid AL_APIENTRY (*alBufferDataStaticProcPtr) (const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq); +ALvoid alBufferDataStaticProc(const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq) +{ + static alBufferDataStaticProcPtr proc = NULL; + + if (proc == NULL) { + proc = (alBufferDataStaticProcPtr) alcGetProcAddress(NULL, (const ALCchar*) "alBufferDataStatic"); + } + + if (proc) + proc(bid, format, data, size, freq); + + return; +} +using namespace cocos2d; + +AudioCache::AudioCache() +: _pcmData(nullptr) +, _dataSize(0) +, _bytesOfRead(0) +, _release(false) +, _queBufferFrames(0) +, _queBufferBytes(0) +, _alBufferReady(false) +{ + +} + +AudioCache::~AudioCache() +{ + _release = true; + if(_pcmData){ + if (_alBufferReady) { + alDeleteBuffers(1, &_alBufferId); + } + _readThreadMutex.lock(); + _readThreadMutex.unlock(); + free(_pcmData); + } + + if (_queBufferFrames > 0) { + for (int index = 0; index < QUEUEBUFFER_NUM; ++index) { + free(_queBuffers[index]); + } + } +} + +void AudioCache::readDataThread() +{ + _readThreadMutex.lock(); + + AudioStreamBasicDescription theFileFormat; + UInt32 thePropertySize = sizeof(theFileFormat); + + SInt64 theFileLengthInFrames; + SInt64 readInFrames; + SInt64 dataSize; + SInt64 frames; + AudioBufferList theDataBuffer; + ExtAudioFileRef extRef = nullptr; + + auto fileURL = (CFURLRef)[[NSURL fileURLWithPath:[NSString stringWithCString:_fileFullPath.c_str() encoding:[NSString defaultCStringEncoding]]] retain]; + + auto error = ExtAudioFileOpenURL(fileURL, &extRef); + if(error) { + printf("readDataThread: ExtAudioFileOpenURL FAILED, Error = %d\n", error); + goto ExitThread; + } + + // Get the audio data format + error = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat); + if(error) { + printf("readDataThread: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %d\n", (int)error); + goto ExitThread; + } + if (theFileFormat.mChannelsPerFrame > 2) { + printf("readDataThread: Unsupported Format, channel count is greater than stereo\n"); + goto ExitThread; + } + + // Set the client format to 16 bit signed integer (native-endian) data + // Maintain the channel count and sample rate of the original source format + outputFormat.mSampleRate = theFileFormat.mSampleRate; + outputFormat.mChannelsPerFrame = theFileFormat.mChannelsPerFrame; + + _bytesPerFrame = 2 * outputFormat.mChannelsPerFrame; + outputFormat.mFormatID = kAudioFormatLinearPCM; + outputFormat.mBytesPerPacket = _bytesPerFrame; + outputFormat.mFramesPerPacket = 1; + outputFormat.mBytesPerFrame = _bytesPerFrame; + outputFormat.mBitsPerChannel = 16; + outputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; + + error = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(outputFormat), &outputFormat); + if(error) { + printf("readDataThread: ExtAudioFileSetProperty FAILED, Error = %d\n", (int)error); + goto ExitThread; + } + + // Get the total frame count + thePropertySize = sizeof(theFileLengthInFrames); + error = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames); + if(error) { printf("initOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %d\n", (int)error); goto ExitThread; } + + _dataSize = (ALsizei)(theFileLengthInFrames * outputFormat.mBytesPerFrame); + _format = (outputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; + _sampleRate = (ALsizei)outputFormat.mSampleRate; + _duration = 1.0f * theFileLengthInFrames / outputFormat.mSampleRate; + + if (_dataSize <= PCMDATA_CACHEMAXSIZE) { + _pcmData = (char*)malloc(_dataSize); + alGenBuffers(1, &_alBufferId); + auto alError = alGetError(); + if (alError != AL_NO_ERROR) { + printf("error attaching audio to buffer: %x\n", alError); goto ExitThread; + } + alBufferDataStaticProc(_alBufferId, _format, _pcmData, _dataSize, _sampleRate); + + readInFrames = theFileFormat.mSampleRate * 0.6; + dataSize = outputFormat.mBytesPerFrame * readInFrames; + if (dataSize > _dataSize) { + dataSize = _dataSize; + readInFrames = theFileLengthInFrames; + } + theDataBuffer.mNumberBuffers = 1; + theDataBuffer.mBuffers[0].mDataByteSize = (UInt32)dataSize; + theDataBuffer.mBuffers[0].mNumberChannels = outputFormat.mChannelsPerFrame; + + theDataBuffer.mBuffers[0].mData = _pcmData; + frames = readInFrames; + ExtAudioFileRead(extRef, (UInt32*)&frames, &theDataBuffer); + _alBufferReady = true; + _bytesOfRead += dataSize; + invokingCallbacks(); + + while (!_release && _bytesOfRead + dataSize < _dataSize) { + theDataBuffer.mBuffers[0].mData = _pcmData + _bytesOfRead; + frames = readInFrames; + ExtAudioFileRead(extRef, (UInt32*)&frames, &theDataBuffer); + _bytesOfRead += dataSize; + } + + dataSize = _dataSize - _bytesOfRead; + if (dataSize > 0) { + theDataBuffer.mBuffers[0].mDataByteSize = (UInt32)dataSize; + theDataBuffer.mBuffers[0].mData = _pcmData + _bytesOfRead; + frames = readInFrames; + ExtAudioFileRead(extRef, (UInt32*)&frames, &theDataBuffer); + } + + _bytesOfRead = _dataSize; + } + else{ + _queBufferFrames = theFileFormat.mSampleRate * 0.2; + _queBufferBytes = _queBufferFrames * outputFormat.mBytesPerFrame; + + theDataBuffer.mNumberBuffers = QUEUEBUFFER_NUM; + for (int index = 0; index < QUEUEBUFFER_NUM; ++index) { + _queBuffers[index] = (char*)malloc(_queBufferBytes); + + theDataBuffer.mBuffers[index].mDataByteSize = _queBufferBytes; + theDataBuffer.mBuffers[index].mNumberChannels = outputFormat.mChannelsPerFrame; + theDataBuffer.mBuffers[index].mData = _queBuffers[index]; + } + + frames = _queBufferFrames * QUEUEBUFFER_NUM; + ExtAudioFileRead(extRef, (UInt32*)&frames, &theDataBuffer); + } + +ExitThread: + CFRelease(fileURL); + if (extRef) ExtAudioFileDispose(extRef); + + _readThreadMutex.unlock(); + if (_queBufferFrames > 0) { + _alBufferReady = true; + invokingCallbacks(); + } + else { + invokingCallbacks(); + } +} + +void AudioCache::invokingCallbacks() +{ + _callbackMutex.lock(); + auto count = _callbacks.size(); + for (size_t index = 0; index < count; ++index) { + _callbacks[index](); + } + _callbacks.clear(); + _callbackMutex.unlock(); +} + +void AudioCache::addCallbacks(const std::function &callback) +{ + _callbackMutex.lock(); + if (_alBufferReady) { + callback(); + } else { + _callbacks.push_back(callback); + } + _callbackMutex.unlock(); +} diff --git a/cocos/audio/ios/AudioEngine-inl.h b/cocos/audio/ios/AudioEngine-inl.h new file mode 100644 index 0000000000..8a6e4b846e --- /dev/null +++ b/cocos/audio/ios/AudioEngine-inl.h @@ -0,0 +1,97 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS + +#ifndef __AUDIO_ENGINE_INL_H_ +#define __AUDIO_ENGINE_INL_H_ + +#include + +#include "base/CCRef.h" +#include "AudioCache.h" +#include "AudioPlayer.h" + +NS_CC_BEGIN +class AudioEngine; +class AudioProfile; + +#define kMaxSources 32 + +class AudioEngineThreadPool; + +class AudioEngineImpl : public cocos2d::Ref +{ +public: + AudioEngineImpl(AudioEngine* audioEngine); + ~AudioEngineImpl(); + + bool init(); + int play2d(const std::string &fileFullPath ,bool loop ,float volume, AudioProfile* profile); + void setVolume(int audioID,float volume); + void setLoop(int audioID, bool loop); + bool pause(int audioID); + bool resume(int audioID); + bool stop(int audioID); + void stopAll(); + float getDuration(int audioID); + float getCurrentTime(int audioID); + bool setCurrentTime(int audioID, float time); + void setFinishCallback(int audioID, const std::function &callback); + + void uncache(const std::string& filePath); + void uncacheAll(); + + void update(float dt); + +private: + void _play2d(AudioCache *cache, int audioID); + + AudioEngineThreadPool* _threadPool; + AudioEngine* _audioEngine; + + ALuint _alSources[kMaxSources]; + + //source,used + std::unordered_map _alSourceUsed; + + //filePath,bufferInfo + std::unordered_map _audioCaches; + + //audioID,AudioInfo + std::unordered_map _audioPlayers; + + std::mutex _threadMutex; + + std::vector _removeCaches; + std::vector _removeAudioIDs; + + bool _lazyInitLoop; + + int nextAudioID; + +}; +NS_CC_END +#endif // __AUDIO_ENGINE_INL_H_ +#endif + diff --git a/cocos/audio/ios/AudioEngine-inl.mm b/cocos/audio/ios/AudioEngine-inl.mm new file mode 100644 index 0000000000..32b3b74f45 --- /dev/null +++ b/cocos/audio/ios/AudioEngine-inl.mm @@ -0,0 +1,505 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#include "AudioEngine-inl.h" +#include "audio/include/AudioEngine.h" + +#import +#include "platform/CCFileUtils.h" +#include "base/CCDirector.h" +#include "base/CCScheduler.h" +#include "base/ccUtils.h" + +using namespace cocos2d; + +static ALCdevice *s_ALDevice = nullptr; +static ALCcontext *s_ALContext = nullptr; + +static void AudioInterrupionListenerCallback(void* user_data, UInt32 interruption_state) +{ + if(kAudioSessionBeginInterruption == interruption_state){ + alcMakeContextCurrent(nullptr); + } + else if (kAudioSessionEndInterruption == interruption_state){ + AudioSessionSetActive(true); + alcMakeContextCurrent(s_ALContext); + } +} + +namespace cocos2d { + class AudioEngineThreadPool + { + public: + AudioEngineThreadPool() + : _running(true) + , _numThread(6) + { + _threads.reserve(_numThread); + _tasks.reserve(_numThread); + + for (int index = 0; index < _numThread; ++index) { + _tasks.push_back(nullptr); + _threads.push_back( std::thread( std::bind(&AudioEngineThreadPool::threadFunc,this,index) ) ); + } + } + + void addTask(const std::function &task){ + _taskMutex.lock(); + int targetIndex = -1; + for (int index = 0; index < _numThread; ++index) { + if (_tasks[index] == nullptr) { + targetIndex = index; + _tasks[index] = task; + break; + } + } + if (targetIndex == -1) { + _tasks.push_back(task); + _threads.push_back( std::thread( std::bind(&AudioEngineThreadPool::threadFunc,this,_numThread) ) ); + + _numThread++; + } + _taskMutex.unlock(); + + _sleepCondition.notify_all(); + } + + void stop() + { + _running = false; + _sleepCondition.notify_all(); + + for (int index = 0; index < _numThread; ++index) { + _threads[index].join(); + } + } + + private: + bool _running; + std::vector _threads; + std::vector< std::function > _tasks; + + void threadFunc(int index) + { + while (_running) { + std::function task = nullptr; + _taskMutex.lock(); + task = _tasks[index]; + _taskMutex.unlock(); + + if (nullptr == task) + { + // Wait for http request tasks from main thread + std::unique_lock lk(_sleepMutex); + _sleepCondition.wait(lk); + continue; + } + + task(); + + _taskMutex.lock(); + _tasks[index] = nullptr; + _taskMutex.unlock(); + } + } + + int _numThread; + + std::mutex _taskMutex; + std::mutex _sleepMutex; + std::condition_variable _sleepCondition; + + }; +} + +AudioEngineImpl::AudioEngineImpl(AudioEngine* audioEngine) +: _audioEngine(audioEngine) +, _lazyInitLoop(true) +, nextAudioID(0) +, _threadPool(nullptr) +{ + +} + +AudioEngineImpl::~AudioEngineImpl() +{ + if (s_ALContext) { + alDeleteSources(kMaxSources, _alSources); + + _audioCaches.clear(); + + alcDestroyContext(s_ALContext); + } + if (s_ALDevice) { + alcCloseDevice(s_ALDevice); + } + if (_threadPool) { + _threadPool->stop(); + delete _threadPool; + } +} + +bool AudioEngineImpl::init() +{ + //set up the audio session + AudioSessionInitialize(nullptr, nullptr, AudioInterrupionListenerCallback, nullptr); + + bool ret = false; + do{ + s_ALDevice = alcOpenDevice(nullptr); + + if (s_ALDevice) { + auto alError = alGetError(); + s_ALContext = alcCreateContext(s_ALDevice, nullptr); + alcMakeContextCurrent(s_ALContext); + + alGenSources(kMaxSources, _alSources); + alError = alGetError(); + if(alError != AL_NO_ERROR) + { + printf("Error generating sources! %x\n", alError); + break; + } + + for (int i = 0; i < kMaxSources; ++i) { + _alSourceUsed[_alSources[i]] = false; + } + + _threadPool = new (std::nothrow) AudioEngineThreadPool(); + ret = true; + } + }while (false); + + return ret; +} + +int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume, AudioProfile* profile) +{ + if (s_ALDevice == nullptr) { + return AudioEngine::INVAILD_AUDIO_ID; + } + + bool sourceFlag = false; + ALuint alSource = 0; + for (int i = 0; i < kMaxSources; ++i) { + alSource = _alSources[i]; + + if ( !_alSourceUsed[alSource]) { + sourceFlag = true; + break; + } + } + if(!sourceFlag){ + return AudioEngine::INVAILD_AUDIO_ID; + } + + AudioCache* audioCache = nullptr; + auto it = _audioCaches.find(filePath); + if (it == _audioCaches.end()) { + audioCache = &_audioCaches[filePath]; + audioCache->_fileFullPath = FileUtils::getInstance()->fullPathForFilename(filePath); + + _threadPool->addTask(std::bind(&AudioCache::readDataThread, audioCache)); + } + else { + audioCache = &it->second; + } + + auto player = &_audioPlayers[nextAudioID]; + player->_alSource = alSource; + player->_loop = loop; + player->_volume = volume; + audioCache->addCallbacks(std::bind(&AudioEngineImpl::_play2d,this,audioCache,nextAudioID)); + + _alSourceUsed[alSource] = true; + + if (profile) { + profile->lastPlayTime = utils::gettime(); + profile->audioIDs.push_back(nextAudioID); + } + + if (_lazyInitLoop) { + _lazyInitLoop = false; + + auto scheduler = cocos2d::Director::getInstance()->getScheduler(); + scheduler->schedule(schedule_selector(AudioEngineImpl::update), this, 0.05f, false); + } + + return nextAudioID++; +} + +void AudioEngineImpl::_play2d(AudioCache *cache, int audioID) +{ + if(cache->_alBufferReady){ + auto playerIt = _audioPlayers.find(audioID); + if (playerIt != _audioPlayers.end()) { + if (playerIt->second.play2d(cache)) { + _audioEngine->_audioInfos[audioID].state = AudioEngine::AudioState::PLAYING; + } + else{ + _threadMutex.lock(); + _removeAudioIDs.push_back(audioID); + _threadMutex.unlock(); + } + } + } + else { + _threadMutex.lock(); + _removeCaches.push_back(cache); + _removeAudioIDs.push_back(audioID); + _threadMutex.unlock(); + } +} + +void AudioEngineImpl::setVolume(int audioID,float volume) +{ + auto& player = _audioPlayers[audioID]; + player._volume = volume; + + if (player._ready) { + alSourcef(_audioPlayers[audioID]._alSource, AL_GAIN, volume); + + auto error = alGetError(); + if (error != AL_NO_ERROR) { + printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + } + } +} + +void AudioEngineImpl::setLoop(int audioID, bool loop) +{ + auto& player = _audioPlayers[audioID]; + + if (player._ready) { + if (player._largeFile) { + player.setLoop(loop); + } else { + if (loop) { + alSourcei(player._alSource, AL_LOOPING, AL_TRUE); + } else { + alSourcei(player._alSource, AL_LOOPING, AL_FALSE); + } + + auto error = alGetError(); + if (error != AL_NO_ERROR) { + printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + } + } + } + else { + player._loop = loop; + } +} + +bool AudioEngineImpl::pause(int audioID) +{ + bool ret = true; + alSourcePause(_audioPlayers[audioID]._alSource); + + auto error = alGetError(); + if (error != AL_NO_ERROR) { + ret = false; + printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + } + + return ret; +} + +bool AudioEngineImpl::resume(int audioID) +{ + bool ret = true; + alSourcePlay(_audioPlayers[audioID]._alSource); + + auto error = alGetError(); + if (error != AL_NO_ERROR) { + ret = false; + printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + } + + return ret; +} + +bool AudioEngineImpl::stop(int audioID) +{ + bool ret = true; + auto& player = _audioPlayers[audioID]; + if (player._ready) { + alSourceStop(player._alSource); + + auto error = alGetError(); + if (error != AL_NO_ERROR) { + ret = false; + printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + } + } + + alSourcei(player._alSource, AL_BUFFER, NULL); + + _alSourceUsed[player._alSource] = false; + _audioPlayers.erase(audioID); + + return ret; +} + +void AudioEngineImpl::stopAll() +{ + for(int index = 0; index < kMaxSources; ++index) + { + alSourceStop(_alSources[index]); + alSourcei(_alSources[index], AL_BUFFER, NULL); + _alSourceUsed[_alSources[index]] = false; + } + + _audioPlayers.clear(); +} + +float AudioEngineImpl::getDuration(int audioID) +{ + auto& player = _audioPlayers[audioID]; + if(player._ready){ + return player._audioCache->_duration; + } else { + return AudioEngine::TIME_UNKNOWN; + } +} + +float AudioEngineImpl::getCurrentTime(int audioID) +{ + float ret = 0.0f; + auto& player = _audioPlayers[audioID]; + if(player._ready){ + if (player._largeFile) { + ret = player.getTime(); + } else { + alGetSourcef(player._alSource, AL_SEC_OFFSET, &ret); + + auto error = alGetError(); + if (error != AL_NO_ERROR) { + printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + } + } + } + + return ret; +} + +bool AudioEngineImpl::setCurrentTime(int audioID, float time) +{ + bool ret = false; + auto& player = _audioPlayers[audioID]; + + do { + if (!player._ready) { + break; + } + + if (player._largeFile) { + //ret = player.setTime(time); + break; + } + else { + if (player._audioCache->_bytesOfRead != player._audioCache->_dataSize && + (time * player._audioCache->_sampleRate * player._audioCache->_bytesPerFrame) > player._audioCache->_bytesOfRead) { + printf("setCurrentTime fail for audio %d",audioID); + break; + } + + alSourcef(player._alSource, AL_SEC_OFFSET, time); + + auto error = alGetError(); + if (error != AL_NO_ERROR) { + printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + } + ret = true; + } + } while (0); + + return ret; +} + +void AudioEngineImpl::setFinishCallback(int audioID, const std::function &callback) +{ + _audioPlayers[audioID]._finishCallbak = callback; +} + +void AudioEngineImpl::update(float dt) +{ + ALint sourceState; + int audioID; + + if (_threadMutex.try_lock()) { + size_t removeAudioCount = _removeAudioIDs.size(); + for (size_t index = 0; index < removeAudioCount; ++index) { + audioID = _removeAudioIDs[index]; + auto playerIt = _audioPlayers.find(audioID); + if (playerIt != _audioPlayers.end()) { + _alSourceUsed[playerIt->second._alSource] = false; + _audioPlayers.erase(audioID); + _audioEngine->remove(audioID); + } + } + size_t removeCacheCount = _removeCaches.size(); + for (size_t index = 0; index < removeCacheCount; ++index) { + auto itEnd = _audioCaches.end(); + for (auto it = _audioCaches.begin(); it != itEnd; ++it) { + if (&it->second == _removeCaches[index]) { + _audioCaches.erase(it); + break; + } + } + } + _threadMutex.unlock(); + } + + for (auto it = _audioPlayers.begin(); it != _audioPlayers.end(); ) { + audioID = it->first; + auto& player = it->second; + alGetSourcei(player._alSource, AL_SOURCE_STATE, &sourceState); + + if (player._ready && sourceState == AL_STOPPED) { + _alSourceUsed[player._alSource] = false; + auto& audioInfo = _audioEngine->_audioInfos[audioID]; + if (player._finishCallbak) { + player._finishCallbak(audioID, *audioInfo.filePath); + } + + _audioEngine->remove(audioID); + + it = _audioPlayers.erase(it); + } + else{ + ++it; + } + } +} + +void AudioEngineImpl::uncache(const std::string &filePath) +{ + auto fileFullPath = FileUtils::getInstance()->fullPathForFilename(filePath); + _audioCaches.erase(fileFullPath); +} + +void AudioEngineImpl::uncacheAll() +{ + _audioCaches.clear(); +} diff --git a/cocos/audio/ios/AudioPlayer.h b/cocos/audio/ios/AudioPlayer.h new file mode 100644 index 0000000000..6cea716150 --- /dev/null +++ b/cocos/audio/ios/AudioPlayer.h @@ -0,0 +1,78 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS + +#ifndef __AUDIO_PLAYER_H_ +#define __AUDIO_PLAYER_H_ + +#import +#include +#include +#include "base/CCPlatformMacros.h" + +NS_CC_BEGIN +class AudioCache; +class AudioEngineImpl; + +class AudioPlayer +{ +public: + AudioPlayer(); + ~AudioPlayer(); + + //queue buffer related stuff + bool setTime(float time); + float getTime() { return _currTime;} + bool setLoop(bool loop); + +private: + void rotateBufferThread(int offsetFrame); + bool play2d(AudioCache* cache); + + AudioCache* _audioCache; + + float _volume; + bool _loop; + std::function _finishCallbak; + + bool _ready; + ALuint _alSource; + + //play by circular buffer + bool _largeFile; + ALuint _bufferIds[3]; + int _bufferIndex; + int _frameIndex; + float _currTime; + std::mutex _rotateBufferMtx; + std::timed_mutex _timeMtx; + + bool _release; + + friend class AudioEngineImpl; +}; +NS_CC_END +#endif // __AUDIO_PLAYER_H_ +#endif + diff --git a/cocos/audio/ios/AudioPlayer.mm b/cocos/audio/ios/AudioPlayer.mm new file mode 100644 index 0000000000..fb540c0c68 --- /dev/null +++ b/cocos/audio/ios/AudioPlayer.mm @@ -0,0 +1,263 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#include "AudioPlayer.h" +#include "AudioCache.h" +#include "platform/CCFileUtils.h" +#import + +using namespace cocos2d; + +AudioPlayer::AudioPlayer() +: _release(false) +, _largeFile(false) +, _currTime(0.0f) +, _finishCallbak(nullptr) +, _ready(false) +, _audioCache(nullptr) +{ + +} + +AudioPlayer::~AudioPlayer() +{ + _release = true; + if (_audioCache && _audioCache->_queBufferFrames > 0) { + _timeMtx.unlock(); + _rotateBufferMtx.lock(); + _rotateBufferMtx.unlock(); + alDeleteBuffers(3, _bufferIds); + } +} + +bool AudioPlayer::play2d(AudioCache* cache) +{ + bool ret = true; + if (!cache->_alBufferReady) { + return false; + } + _audioCache = cache; + + alSourcei(_alSource, AL_BUFFER, NULL); + alSourcef(_alSource, AL_PITCH, 1.0f); + alSourcef(_alSource, AL_GAIN, _volume); + + if (_audioCache->_queBufferFrames == 0) { + if (_loop) { + alSourcei(_alSource, AL_LOOPING, AL_TRUE); + } + else { + alSourcei(_alSource, AL_LOOPING, AL_FALSE); + } + alSourcei(_alSource, AL_BUFFER, _audioCache->_alBufferId); + + } else { + _largeFile = true; + + auto alError = alGetError(); + alGenBuffers(3, _bufferIds); + alError = alGetError(); + if (alError == AL_NO_ERROR) { + for (int index = 0; index < QUEUEBUFFER_NUM; ++index) { + alBufferData(_bufferIds[index], _audioCache->_format, _audioCache->_queBuffers[index], _audioCache->_queBufferBytes, _audioCache->_sampleRate); + } + alSourcei(_alSource, AL_BUFFER, NULL); + alSourceQueueBuffers(_alSource, QUEUEBUFFER_NUM, _bufferIds); + + _timeMtx.lock(); + auto rotateThread = std::thread(&AudioPlayer::rotateBufferThread,this, _audioCache->_queBufferFrames * QUEUEBUFFER_NUM + 1); + rotateThread.detach(); + } + else { + printf("error:%s, error code:%x", __PRETTY_FUNCTION__,alError); + ret = false; + } + } + + alSourcePlay(_alSource); + _ready = true; + auto alError = alGetError(); + + if (alError != AL_NO_ERROR) { + ret = false; + printf("error:%s, error code:%x\n", __PRETTY_FUNCTION__,alError); + } + + return ret; +} + +void AudioPlayer::rotateBufferThread(int offsetFrame) +{ + _rotateBufferMtx.lock(); + printf("%s start\n",__func__); + + ALint sourceState; + ALint bufferProcessed = 0; + ExtAudioFileRef extRef = nullptr; + + auto fileURL = (CFURLRef)[[NSURL fileURLWithPath:[NSString stringWithCString:_audioCache->_fileFullPath.c_str() encoding:[NSString defaultCStringEncoding]]] retain]; + char* tmpBuffer = (char*)malloc(_audioCache->_queBufferBytes); + auto frames = _audioCache->_queBufferFrames; + + auto error = ExtAudioFileOpenURL(fileURL, &extRef); + if(error) { + printf("rotateBufferThread: ExtAudioFileOpenURL FAILED, Error = %d\n", error); + goto ExitBufferThread; + } + + error = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(_audioCache->outputFormat), &_audioCache->outputFormat); + AudioBufferList theDataBuffer; + theDataBuffer.mNumberBuffers = 1; + theDataBuffer.mBuffers[0].mData = tmpBuffer; + theDataBuffer.mBuffers[0].mDataByteSize = _audioCache->_queBufferBytes; + theDataBuffer.mBuffers[0].mNumberChannels = _audioCache->outputFormat.mChannelsPerFrame; + + if (offsetFrame != 0) { + ExtAudioFileSeek(extRef, offsetFrame); + } + + while (!_release) { + alGetSourcei(_alSource, AL_SOURCE_STATE, &sourceState); + if (sourceState == AL_PLAYING) { + alGetSourcei(_alSource, AL_BUFFERS_PROCESSED, &bufferProcessed); + while (bufferProcessed > 0) { + bufferProcessed--; + + _currTime += 0.2f; + if (_currTime > _audioCache->_duration) { + if (_loop) { + _currTime = 0.0f; + } else { + _currTime = _audioCache->_duration; + } + } + + frames = _audioCache->_queBufferFrames; + ExtAudioFileRead(extRef, (UInt32*)&frames, &theDataBuffer); + if (frames <= 0) { + if (_loop) { + ExtAudioFileSeek(extRef, 0); + frames = _audioCache->_queBufferFrames; + theDataBuffer.mBuffers[0].mDataByteSize = _audioCache->_queBufferBytes; + ExtAudioFileRead(extRef, (UInt32*)&frames, &theDataBuffer); + } else { + break; + } + } + + ALuint bid; + alSourceUnqueueBuffers(_alSource, 1, &bid); + alBufferData(bid, _audioCache->_format, tmpBuffer, frames * _audioCache->outputFormat.mBytesPerFrame, _audioCache->_sampleRate); + alSourceQueueBuffers(_alSource, 1, &bid); + } + } + + _timeMtx.try_lock_for(std::chrono::milliseconds(100)); + } + +ExitBufferThread: + CFRelease(fileURL); + // Dispose the ExtAudioFileRef, it is no longer needed + if (extRef){ + ExtAudioFileDispose(extRef); + } + free(tmpBuffer); + _rotateBufferMtx.unlock(); + printf("%s end\n",__func__); +} + +bool AudioPlayer::setLoop(bool loop) +{ + if (!_release ) { + _loop = loop; + if (_rotateBufferMtx.try_lock() && loop) { + _rotateBufferMtx.unlock(); + + auto rotateThread = std::thread(&AudioPlayer::rotateBufferThread,this, 0); + rotateThread.detach(); + } + + return true; + } + + return false; +} + +bool AudioPlayer::setTime(float time) +{ + return false; + + if (!_release && time >= 0.0f && time < _audioCache->_duration) { + _release = true; + _timeMtx.unlock(); + _rotateBufferMtx.lock(); + _rotateBufferMtx.unlock(); + + _currTime = time; + alSourcei(_alSource, AL_BUFFER, NULL); + + ExtAudioFileRef extRef = nullptr; + AudioBufferList theDataBuffer; + char* bufferData[QUEUEBUFFER_NUM]; + + auto fileURL = (CFURLRef)[[NSURL fileURLWithPath:[NSString stringWithCString:_audioCache->_fileFullPath.c_str() encoding:[NSString defaultCStringEncoding]]] retain]; + auto error = ExtAudioFileOpenURL(fileURL, &extRef); + error = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(_audioCache->outputFormat), &_audioCache->outputFormat); + + theDataBuffer.mNumberBuffers = QUEUEBUFFER_NUM; + for (int index = 0; index < QUEUEBUFFER_NUM; ++index) { + bufferData[index] = (char*)malloc(_audioCache->_queBufferBytes); + + theDataBuffer.mBuffers[index].mDataByteSize = _audioCache->_queBufferBytes; + theDataBuffer.mBuffers[index].mNumberChannels = _audioCache->outputFormat.mChannelsPerFrame; + theDataBuffer.mBuffers[index].mData = bufferData[index]; + } + + int offsetFrames = time * _audioCache->outputFormat.mSampleRate; + if (offsetFrames != 0) { + error = ExtAudioFileSeek(extRef, offsetFrames); + } + + UInt32 frames = _audioCache->_queBufferFrames * QUEUEBUFFER_NUM; + ExtAudioFileRead(extRef, (UInt32*)&frames, &theDataBuffer); + + for (int index = 0; index < theDataBuffer.mNumberBuffers; ++index) { + alBufferData(_bufferIds[index], _audioCache->_format, bufferData[index], theDataBuffer.mBuffers[index].mDataByteSize, _audioCache->_sampleRate); + free(bufferData[index]); + } + alSourceQueueBuffers(_alSource, theDataBuffer.mNumberBuffers, _bufferIds); + + ExitSetTime: + CFRelease(fileURL); + // Dispose the ExtAudioFileRef, it is no longer needed + if (extRef){ + ExtAudioFileDispose(extRef); + } + + auto rotateThread = std::thread(&AudioPlayer::rotateBufferThread,this, offsetFrames + QUEUEBUFFER_NUM * _audioCache->_queBufferFrames+ 1); + rotateThread.detach(); + + return true; + } + return false; +} From d5c023740f6ef6b5f68a6e8c051869df832b16e7 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 3 Sep 2014 18:19:47 +0800 Subject: [PATCH 03/32] Implement logical codes of new audio engine on android. --- cocos/Android.mk | 1 + cocos/audio/android/Android.mk | 20 ++ cocos/audio/android/AudioEngine-inl.cpp | 371 ++++++++++++++++++++++++ cocos/audio/android/AudioEngine-inl.h | 111 +++++++ 4 files changed, 503 insertions(+) create mode 100644 cocos/audio/android/AudioEngine-inl.cpp create mode 100644 cocos/audio/android/AudioEngine-inl.h diff --git a/cocos/Android.mk b/cocos/Android.mk index 94c14a9824..0969f5be76 100644 --- a/cocos/Android.mk +++ b/cocos/Android.mk @@ -237,6 +237,7 @@ LOCAL_MODULE := cocos2dx_static LOCAL_MODULE_FILENAME := libcocos2d LOCAL_STATIC_LIBRARIES := cocostudio_static +LOCAL_STATIC_LIBRARIES += audioengine_static LOCAL_STATIC_LIBRARIES += cocos3d_static LOCAL_STATIC_LIBRARIES += cocosbuilder_static LOCAL_STATIC_LIBRARIES += spine_static diff --git a/cocos/audio/android/Android.mk b/cocos/audio/android/Android.mk index 3854fa79d7..bbd7725d9d 100644 --- a/cocos/audio/android/Android.mk +++ b/cocos/audio/android/Android.mk @@ -16,3 +16,23 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include \ $(LOCAL_PATH)/../../platform/android include $(BUILD_STATIC_LIBRARY) + +#new audio engine +include $(CLEAR_VARS) + +LOCAL_MODULE := audioengine_static + +LOCAL_MODULE_FILENAME := libaudioengine + +LOCAL_SRC_FILES := AudioEngine-inl.cpp \ + ../AudioEngine.cpp + +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include + +LOCAL_EXPORT_LDLIBS := -lOpenSLES + +LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include \ + $(LOCAL_PATH)/../.. \ + $(LOCAL_PATH)/../../platform/android + +include $(BUILD_STATIC_LIBRARY) diff --git a/cocos/audio/android/AudioEngine-inl.cpp b/cocos/audio/android/AudioEngine-inl.cpp new file mode 100644 index 0000000000..2a8de0a7f3 --- /dev/null +++ b/cocos/audio/android/AudioEngine-inl.cpp @@ -0,0 +1,371 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID +#include "AudioEngine-inl.h" + +#include +// for native asset manager +#include +#include +#include + +#include "audio/include/AudioEngine.h" +#include "base/CCDirector.h" +#include "platform/android/CCFileUtilsAndroid.h" + +#include "platform/android/jni/JniHelper.h" +#include +#include + +#define MIN_VOLUME_MILLIBEL -7000 +#define RANGE_VOLUME_MILLIBEL 7000 + +using namespace cocos2d; + +void PlayOverEvent(SLPlayItf caller, void* context, SLuint32 playEvent) +{ + if (context && playEvent == SL_PLAYEVENT_HEADATEND) + { + AudioEngineImpl* engineImpl = (AudioEngineImpl*)context; + engineImpl->playerFinishCallback(caller,playEvent); + } +} + +AudioPlayer::AudioPlayer() + : _fdPlayerObject(nullptr) + , _finishCallback(nullptr) + , _duration(0.0f) +{ + +} + +AudioPlayer::~AudioPlayer() +{ + if (_fdPlayerObject) + { + (*_fdPlayerObject)->Destroy(_fdPlayerObject); + _fdPlayerObject = nullptr; + } +} + +bool AudioPlayer::init(SLEngineItf engineEngine, SLObjectItf outputMixObject,const std::string& fileFullPath, float volume, bool loop) +{ + bool ret = false; + + do + { + SLDataSource audioSrc; + + SLDataLocator_AndroidFD loc_fd; + SLDataLocator_URI loc_uri; + + SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED}; + audioSrc.pFormat = &format_mime; + + if (fileFullPath[0] != '/'){ + std::string relativePath = ""; + + size_t position = fileFullPath.find("assets/"); + if (0 == position) { + // "assets/" is at the beginning of the path and we don't want it + relativePath += fileFullPath.substr(strlen("assets/")); + } else { + relativePath += fileFullPath; + } + + auto asset = AAssetManager_open(cocos2d::FileUtilsAndroid::getAssetManager(), relativePath.c_str(), AASSET_MODE_UNKNOWN); + + // open asset as file descriptor + off_t start, length; + int fd = AAsset_openFileDescriptor(asset, &start, &length); + assert(0 <= fd); + AAsset_close(asset); + + // configure audio source + loc_fd = {SL_DATALOCATOR_ANDROIDFD, fd, start, length}; + + audioSrc.pLocator = &loc_fd; + } + else{ + loc_uri = {SL_DATALOCATOR_URI , (SLchar*)fileFullPath.c_str()}; + audioSrc.pLocator = &loc_uri; + } + + // configure audio sink + SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject}; + SLDataSink audioSnk = {&loc_outmix, NULL}; + + // create audio player + const SLInterfaceID ids[3] = {SL_IID_SEEK, SL_IID_PREFETCHSTATUS, SL_IID_VOLUME}; + const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; + auto result = (*engineEngine)->CreateAudioPlayer(engineEngine, &_fdPlayerObject, &audioSrc, &audioSnk, 3, ids, req); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + // realize the player + result = (*_fdPlayerObject)->Realize(_fdPlayerObject, SL_BOOLEAN_FALSE); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + // get the play interface + result = (*_fdPlayerObject)->GetInterface(_fdPlayerObject, SL_IID_PLAY, &_fdPlayerPlay); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + // get the seek interface + result = (*_fdPlayerObject)->GetInterface(_fdPlayerObject, SL_IID_SEEK, &_fdPlayerSeek); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + // get the volume interface + result = (*_fdPlayerObject)->GetInterface(_fdPlayerObject, SL_IID_VOLUME, &_fdPlayerVolume); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + if (loop){ + (*_fdPlayerSeek)->SetLoop(_fdPlayerSeek, SL_BOOLEAN_TRUE, 0, SL_TIME_UNKNOWN); + } + + (*_fdPlayerVolume)->SetVolumeLevel(_fdPlayerVolume, MIN_VOLUME_MILLIBEL + RANGE_VOLUME_MILLIBEL * volume); + + result = (*_fdPlayerPlay)->SetPlayState(_fdPlayerPlay, SL_PLAYSTATE_PLAYING); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + ret = true; + } while (0); + + return ret; +} + +//==================================================== +AudioEngineImpl::AudioEngineImpl(AudioEngine* audioEngine) + : _audioEngine(audioEngine) + , nextAudioID(0) + , _engineObject(nullptr) + , _engineEngine(nullptr) + , _outputMixObject(nullptr) +{ + +} + +AudioEngineImpl::~AudioEngineImpl() +{ + if (_outputMixObject) + { + (*_outputMixObject)->Destroy(_outputMixObject); + } + if (_engineObject) + { + (*_engineObject)->Destroy(_engineObject); + } +} + +bool AudioEngineImpl::init() +{ + bool ret = false; + do{ + // create engine + auto result = slCreateEngine(&_engineObject, 0, nullptr, 0, nullptr, nullptr); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + // realize the engine + result = (*_engineObject)->Realize(_engineObject, SL_BOOLEAN_FALSE); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + // get the engine interface, which is needed in order to create other objects + result = (*_engineObject)->GetInterface(_engineObject, SL_IID_ENGINE, &_engineEngine); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + // create output mix + const SLInterfaceID outputMixIIDs[] = {}; + const SLboolean outputMixReqs[] = {}; + result = (*_engineEngine)->CreateOutputMix(_engineEngine, &_outputMixObject, 0, outputMixIIDs, outputMixReqs); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + // realize the output mix + result = (*_outputMixObject)->Realize(_outputMixObject, SL_BOOLEAN_FALSE); + if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + + ret = true; + }while (false); + + return ret; +} + +int AudioEngineImpl::play2d(const std::string &fileFullPath ,bool loop ,float volume, AudioProfile* profile) +{ + auto audioId = AudioEngine::INVAILD_AUDIO_ID; + + do + { + if (_engineEngine == nullptr) + break; + + auto& player = _audioPlayers[nextAudioID]; + auto initPlayer = player.init( _engineEngine, _outputMixObject, fileFullPath, volume, loop); + if (!initPlayer){ + _audioPlayers.erase(nextAudioID); + log("%s,%d message:create player for %s fail", __func__, __LINE__, fileFullPath.c_str()); + break; + } + + audioId = nextAudioID++; + player._audioID = audioId; + + (*(player._fdPlayerPlay))->RegisterCallback(player._fdPlayerPlay, PlayOverEvent, (void*)this); + (*(player._fdPlayerPlay))->SetCallbackEventsMask(player._fdPlayerPlay, SL_PLAYEVENT_HEADATEND); + + if (profile) { + profile->lastPlayTime = utils::gettime(); + profile->audioIDs.push_back(audioId); + } + + _audioEngine->_audioInfos[audioId].state = AudioEngine::AudioState::PLAYING; + } while (0); + + return audioId; +} + +void AudioEngineImpl::playerFinishCallback(SLPlayItf caller, SLuint32 playEvent) +{ + auto itend = _audioPlayers.end(); + for (auto iter = _audioPlayers.begin(); iter != itend; ++iter) + { + if (iter->second._fdPlayerPlay == caller) + { + if (iter->second._finishCallback) + { + iter->second._finishCallback(iter->second._audioID, *_audioEngine->_audioInfos[iter->second._audioID].filePath); + } + _audioEngine->stop(iter->second._audioID); + break; + } + } +} + +void AudioEngineImpl::setVolume(int audioID,float volume) +{ + auto& player = _audioPlayers[audioID]; + auto result = (*player._fdPlayerVolume)->SetVolumeLevel(player._fdPlayerVolume, MIN_VOLUME_MILLIBEL + RANGE_VOLUME_MILLIBEL * volume); + if(SL_RESULT_SUCCESS != result){ + log("%s error:%lu",__func__, result); + } +} + +void AudioEngineImpl::setLoop(int audioID, bool loop) +{ + auto& player = _audioPlayers[audioID]; + SLboolean loopEnabled = SL_BOOLEAN_TRUE; + if (!loop){ + loopEnabled = SL_BOOLEAN_FALSE; + } + (*player._fdPlayerSeek)->SetLoop(player._fdPlayerSeek, loopEnabled, 0, SL_TIME_UNKNOWN); +} + +void AudioEngineImpl::pause(int audioID) +{ + auto& player = _audioPlayers[audioID]; + auto result = (*player._fdPlayerPlay)->SetPlayState(player._fdPlayerPlay, SL_PLAYSTATE_PAUSED); + if(SL_RESULT_SUCCESS != result){ + log("%s error:%lu",__func__, result); + } +} + +void AudioEngineImpl::resume(int audioID) +{ + auto& player = _audioPlayers[audioID]; + auto result = (*player._fdPlayerPlay)->SetPlayState(player._fdPlayerPlay, SL_PLAYSTATE_PLAYING); + if(SL_RESULT_SUCCESS != result){ + log("%s error:%lu",__func__, result); + } +} + +void AudioEngineImpl::stop(int audioID) +{ + auto& player = _audioPlayers[audioID]; + auto result = (*player._fdPlayerPlay)->SetPlayState(player._fdPlayerPlay, SL_PLAYSTATE_STOPPED); + if(SL_RESULT_SUCCESS != result){ + log("%s error:%lu",__func__, result); + } + + _audioPlayers.erase(audioID); +} + +void AudioEngineImpl::stopAll() +{ + auto itEnd = _audioPlayers.end(); + for (auto it = _audioPlayers.begin(); it != itEnd; ++it) + { + auto result = (*it->second._fdPlayerPlay)->SetPlayState(it->second._fdPlayerPlay, SL_PLAYSTATE_STOPPED); + } + _audioPlayers.clear(); +} + +float AudioEngineImpl::getDuration(int audioID) +{ + SLmillisecond duration; + auto& player = _audioPlayers[audioID]; + auto result = (*player._fdPlayerPlay)->GetDuration(player._fdPlayerPlay, &duration); + if (duration == SL_TIME_UNKNOWN){ + return AudioEngine::TIME_UNKNOWN; + } + else{ + player._duration = duration / 1000.0; + + if (player._duration <= 0) + { + return AudioEngine::TIME_UNKNOWN; + } + + return player._duration; + } +} + +float AudioEngineImpl::getCurrentTime(int audioID) +{ + SLmillisecond currPos; + auto& player = _audioPlayers[audioID]; + (*player._fdPlayerPlay)->GetPosition(player._fdPlayerPlay, &currPos); + + if (currPos > player._duration){ + float pos = currPos/1000.0f; + return fmod(pos, player._duration); + } + else { + return currPos / 1000.0f; + } +} + +bool AudioEngineImpl::setCurrentTime(int audioID, float time) +{ + auto& player = _audioPlayers[audioID]; + SLmillisecond pos = 1000 * time; + auto result = (*player._fdPlayerSeek)->SetPosition(player._fdPlayerSeek, pos, SL_SEEKMODE_ACCURATE); + if(SL_RESULT_SUCCESS != result){ + return false; + } + return true; +} + +void AudioEngineImpl::setFinishCallback(int audioID, const std::function &callback) +{ + _audioPlayers[audioID]._finishCallback = callback; +} + +#endif diff --git a/cocos/audio/android/AudioEngine-inl.h b/cocos/audio/android/AudioEngine-inl.h new file mode 100644 index 0000000000..2decd98fce --- /dev/null +++ b/cocos/audio/android/AudioEngine-inl.h @@ -0,0 +1,111 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID + +#ifndef __AUDIO_ENGINE_INL_H_ +#define __AUDIO_ENGINE_INL_H_ + +#include +#include +#include +#include +#include "base/ccUtils.h" + +#define kMaxSources 24 + +#define LOG_FUN log("error: %s,%d",__func__,__LINE__); + +NS_CC_BEGIN + +class AudioEngineImpl; + +class AudioPlayer +{ +public: + AudioPlayer(); + ~AudioPlayer(); + + bool init(SLEngineItf engineEngine, SLObjectItf outputMixObject,const std::string& fileFullPath, float volume, bool loop); + +private: + + SLObjectItf _fdPlayerObject; + SLPlayItf _fdPlayerPlay; + SLSeekItf _fdPlayerSeek; + SLVolumeItf _fdPlayerVolume; + + float _duration; + int _audioID; + + std::function _finishCallback; + + friend class AudioEngineImpl; +}; + +class AudioEngine; +class AudioProfile; +class AudioEngineImpl +{ +public: + AudioEngineImpl(AudioEngine* audioEngine); + ~AudioEngineImpl(); + + bool init(); + int play2d(const std::string &fileFullPath ,bool loop ,float volume, AudioProfile* profile); + void setVolume(int audioID,float volume); + void setLoop(int audioID, bool loop); + void pause(int audioID); + void resume(int audioID); + void stop(int audioID); + void stopAll(); + float getDuration(int audioID); + float getCurrentTime(int audioID); + bool setCurrentTime(int audioID, float time); + void setFinishCallback(int audioID, const std::function &callback); + + void playerFinishCallback(SLPlayItf caller, SLuint32 playEvent); + + void uncache(const std::string& filePath){} + void uncacheAll(){} +private: + AudioEngine* _audioEngine; + + // engine interfaces + SLObjectItf _engineObject; + SLEngineItf _engineEngine; + + // output mix interfaces + SLObjectItf _outputMixObject; + + //audioID,AudioInfo + std::unordered_map _audioPlayers; + + int nextAudioID; +}; + +#endif // __AUDIO_ENGINE_INL_H_ + +NS_CC_END + +#endif From a352a10d385f3dcfba3d4bca9eef299253c95c1b Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 3 Sep 2014 18:20:31 +0800 Subject: [PATCH 04/32] Add test case for new audio engine. --- tests/cpp-tests/Android.mk | 1 + .../NewAudioEngineTest/NewAudioEngineTest.cpp | 718 ++++++++++++++++++ .../NewAudioEngineTest/NewAudioEngineTest.h | 153 ++++ tests/cpp-tests/Classes/controller.cpp | 3 + tests/cpp-tests/Classes/tests.h | 3 + 5 files changed, 878 insertions(+) create mode 100644 tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp create mode 100644 tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.h diff --git a/tests/cpp-tests/Android.mk b/tests/cpp-tests/Android.mk index dba250329b..19b2adf941 100644 --- a/tests/cpp-tests/Android.mk +++ b/tests/cpp-tests/Android.mk @@ -38,6 +38,7 @@ Classes/ChipmunkTest/ChipmunkTest.cpp \ Classes/ClickAndMoveTest/ClickAndMoveTest.cpp \ Classes/ClippingNodeTest/ClippingNodeTest.cpp \ Classes/CocosDenshionTest/CocosDenshionTest.cpp \ +Classes/NewAudioEngineTest/NewAudioEngineTest.cpp \ Classes/ConfigurationTest/ConfigurationTest.cpp \ Classes/ConsoleTest/ConsoleTest.cpp \ Classes/CurlTest/CurlTest.cpp \ diff --git a/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp b/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp new file mode 100644 index 0000000000..d4d4ea91fe --- /dev/null +++ b/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp @@ -0,0 +1,718 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS +#include "NewAudioEngineTest.h" +#include "ui/CocosGUI.h" + +using namespace cocos2d::ui; + +namespace { + +std::function createFunctions[] = +{ + CL(AudioControlTest), + CL(PlaySimultaneouslyTest), + CL(AudioProfileTest), + CL(InvalidAudioFileTest), + CL(LargeAudioFileTest) +}; + +unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]); + +int s_sceneIdx = -1; +Layer* createTest(int index) +{ + auto layer = (createFunctions[index])();; + return layer; +} + +Layer* nextAction() +{ + s_sceneIdx++; + s_sceneIdx = s_sceneIdx % TEST_CASE_COUNT; + + return createTest(s_sceneIdx); +} + +Layer* backAction() +{ + s_sceneIdx--; + if( s_sceneIdx < 0 ) + s_sceneIdx = TEST_CASE_COUNT -1; + + return createTest(s_sceneIdx); +} + +Layer* restartAction() +{ + return createTest(s_sceneIdx); +} + + class TextButton : public cocos2d::Label + { + public: + + static TextButton *create(const std::string& text, const std::function &onTriggered) + { + auto ret = new (std::nothrow) TextButton(); + + TTFConfig ttfconfig("fonts/arial.ttf",25); + if (ret && ret->setTTFConfig(ttfconfig)) { + ret->setString(text); + ret->_onTriggered = onTriggered; + + ret->autorelease(); + + return ret; + } + + delete ret; + return nullptr; + } + + void setEnabled(bool enabled) + { + _enabled = enabled; + if(_enabled){ + this->setColor(Color3B::WHITE); + } + else { + this->setColor(Color3B::GRAY); + } + } + + private: + TextButton() + : _enabled(true) + , _onTriggered(nullptr) + { + auto listener = EventListenerTouchOneByOne::create(); + listener->setSwallowTouches(true); + + listener->onTouchBegan = CC_CALLBACK_2(TextButton::onTouchBegan, this); + listener->onTouchEnded = CC_CALLBACK_2(TextButton::onTouchEnded, this); + listener->onTouchCancelled = CC_CALLBACK_2(TextButton::onTouchCancelled, this); + + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); + + } + + bool touchHits(Touch *touch) + { + auto hitPos = this->convertToNodeSpace(touch->getLocation()); + if (hitPos.x >= 0 && hitPos.y >= 0 && hitPos.x <= _contentSize.width && hitPos.y <= _contentSize.height) { + return true; + } + return false; + } + + bool onTouchBegan(Touch *touch, Event *event) + { + auto hits = touchHits(touch); + if (hits){ + scaleButtonTo(0.95f); + } + return hits; + } + + void onTouchEnded(Touch *touch, Event *event) + { + if(_enabled) { + auto hits = touchHits(touch); + if (hits && _onTriggered){ + _onTriggered(this); + } + } + + scaleButtonTo(1); + } + + void onTouchCancelled(Touch *touch, Event *event) + { + scaleButtonTo(1); + } + + void scaleButtonTo(float scale) + { + auto action = ScaleTo::create(0.05f, scale); + action->setTag(10000); + stopActionByTag(10000); + runAction(action); + } + + std::function _onTriggered; + + bool _enabled; + }; + + class SliderEx : public ui::Slider + { + public: + enum class TouchEvent + { + DOWN, + MOVE, + UP, + CANCEL + }; + typedef std::function ccSliderExCallback; + + static SliderEx* create(){ + auto ret = new (std::nothrow) SliderEx(); + if (ret && ret->init()) + { + ret->_callback = nullptr; + ret->loadBarTexture("cocosui/sliderTrack.png"); + ret->loadSlidBallTextures("cocosui/sliderThumb.png", "cocosui/sliderThumb.png", ""); + ret->loadProgressBarTexture("cocosui/sliderProgress.png"); + + ret->autorelease(); + + return ret; + } + CC_SAFE_DELETE(ret); + return ret; + } + + void setCallBack(const ccSliderExCallback& callback){ + _callback = callback; + } + + void setRatio(float ratio) { + if (ratio > 1.0f){ + ratio = 1.0f; + } + else if (ratio < 0.0f){ + ratio = 0.0f; + } + + _ratio = ratio; + _percent = 100 * _ratio; + + float dis = _barLength * _ratio; + _slidBallRenderer->setPosition(Vec2(dis, _contentSize.height / 2.0f)); + if (_scale9Enabled){ + _progressBarRenderer->setPreferredSize(Size(dis,_progressBarTextureSize.height)); + } + else + { + auto spriteRenderer = _progressBarRenderer->getSprite(); + + if (nullptr != spriteRenderer) { + Rect rect = spriteRenderer->getTextureRect(); + rect.size.width = _progressBarTextureSize.width * _ratio; + spriteRenderer->setTextureRect(rect, spriteRenderer->isTextureRectRotated(), rect.size); + } + } + } + + virtual bool onTouchBegan(Touch *touch, Event *unusedEvent) override{ + auto ret = Slider::onTouchBegan(touch, unusedEvent); + if(ret && _callback){ + _touchEvent = TouchEvent::DOWN; + Vec2 nsp = convertToNodeSpace(_touchBeganPosition); + _ratio = nsp.x / _barLength; + if(_ratio < 0.0f) + _ratio = 0.0f; + else if(_ratio > 1.0f) + _ratio = 1.0f; + _callback(this,_ratio,_touchEvent); + } + return ret; + } + + virtual void onTouchMoved(Touch *touch, Event *unusedEvent) override{ + _touchEvent = TouchEvent::MOVE; + Slider::onTouchMoved(touch, unusedEvent); + Vec2 nsp = convertToNodeSpace(_touchMovePosition); + _ratio = nsp.x / _barLength; + if(_ratio < 0.0f) + _ratio = 0.0f; + else if(_ratio > 1.0f) + _ratio = 1.0f; + if(_callback){ + _callback(this,_ratio,_touchEvent); + } + } + + virtual void onTouchEnded(Touch *touch, Event *unusedEvent) override{ + _touchEvent = TouchEvent::UP; + Slider::onTouchEnded(touch, unusedEvent); + Vec2 nsp = convertToNodeSpace(_touchEndPosition); + _ratio = nsp.x / _barLength; + if(_ratio < 0.0f) + _ratio = 0.0f; + else if(_ratio > 1.0f) + _ratio = 1.0f; + if(_callback){ + _callback(this,_ratio,_touchEvent); + } + } + + virtual void onTouchCancelled(Touch *touch, Event *unusedEvent) override{ + _touchEvent = TouchEvent::CANCEL; + Slider::onTouchCancelled(touch, unusedEvent); + + if(_callback){ + _callback(this,_ratio,_touchEvent); + } + } + + private: + TouchEvent _touchEvent; + float _ratio; + ccSliderExCallback _callback; + }; +} + +void AudioEngineTestScene::runThisTest() +{ + auto engine = AudioEngine::getInstance(); + CCASSERT(engine,"Fail to get instance of AudioEngine!"); + + s_sceneIdx = -1; + auto layer = nextAction(); + addChild(layer); + + Director::getInstance()->replaceScene(this); +} + +void AudioEngineTestDemo::backCallback(Ref* sender) +{ + AudioEngine::getInstance()->stopAll(); + auto scene = new AudioEngineTestScene(); + auto layer = backAction(); + + scene->addChild(layer); + Director::getInstance()->replaceScene(scene); + scene->release(); +} + +void AudioEngineTestDemo::nextCallback(Ref* sender) +{ + AudioEngine::getInstance()->stopAll(); + auto scene = new AudioEngineTestScene(); + auto layer = nextAction(); + + scene->addChild(layer); + Director::getInstance()->replaceScene(scene); + scene->release(); +} + +void AudioEngineTestDemo::restartCallback(Ref* sender) +{ + AudioEngine::getInstance()->stopAll(); + auto scene = new AudioEngineTestScene(); + auto layer = restartAction(); + + scene->addChild(layer); + Director::getInstance()->replaceScene(scene); + scene->release(); +} + +std::string AudioEngineTestDemo::title() const +{ + return "New Audio Engine Test"; +} + +// AudioControlTest +bool AudioControlTest::init() +{ + auto ret = AudioEngineTestDemo::init(); + _audioID = AudioEngine::INVAILD_AUDIO_ID; + _loopEnabled = false; + _volume = 1.0f; + _duration = AudioEngine::TIME_UNKNOWN; + _timeRatio = 0.0f; + _updateTimeSlider = true; + + std::string fontFilePath = "fonts/arial.ttf"; + + auto& layerSize = this->getContentSize(); + + auto playItem = TextButton::create("play", [&](TextButton* button){ + if (_audioID == AudioEngine::INVAILD_AUDIO_ID) { + auto engine = AudioEngine::getInstance(); + _audioID = engine->play2d("background.mp3", _loopEnabled, _volume); + + if(_audioID != AudioEngine::INVAILD_AUDIO_ID) { + button->setEnabled(false); + engine->setFinishCallback(_audioID, [&](int id, const std::string& filePath){ + _audioID = AudioEngine::INVAILD_AUDIO_ID; + ((TextButton*)_playItem)->setEnabled(true); + + _timeRatio = 0.0f; + ((SliderEx*)_timeSlider)->setRatio(_timeRatio); + }); + } + } + }); + _playItem = playItem; + playItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.7f); + addChild(playItem); + + auto stopItem = TextButton::create("stop", [&](TextButton* button){ + if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { + AudioEngine::getInstance()->stop(_audioID); + + _audioID = AudioEngine::INVAILD_AUDIO_ID; + ((TextButton*)_playItem)->setEnabled(true); + } + }); + stopItem->setPosition(layerSize.width * 0.7f,layerSize.height * 0.7f); + addChild(stopItem); + + auto pauseItem = TextButton::create("pause", [&](TextButton* button){ + if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { + AudioEngine::getInstance()->pause(_audioID); + } + }); + pauseItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.6f); + addChild(pauseItem); + + auto resumeItem = TextButton::create("resume", [&](TextButton* button){ + if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { + AudioEngine::getInstance()->resume(_audioID); + } + }); + resumeItem->setPosition(layerSize.width * 0.7f,layerSize.height * 0.6f); + addChild(resumeItem); + + auto loopItem = TextButton::create("enable-loop", [&](TextButton* button){ + _loopEnabled = !_loopEnabled; + + if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { + AudioEngine::getInstance()->setLoop(_audioID, _loopEnabled); + } + if(_loopEnabled){ + button->setString("disable-loop"); + } + else { + button->setString("enable-loop"); + } + }); + loopItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.5f); + addChild(loopItem); + + auto uncacheItem = TextButton::create("uncache", [&](TextButton* button){ + AudioEngine::getInstance()->uncache("background.mp3"); + + _audioID = AudioEngine::INVAILD_AUDIO_ID; + ((TextButton*)_playItem)->setEnabled(true); + }); + uncacheItem->setPosition(layerSize.width * 0.7f,layerSize.height * 0.5f); + addChild(uncacheItem); + + auto volumeSlider = SliderEx::create(); + volumeSlider->setPercent(100); + volumeSlider->setCallBack([&](SliderEx* sender,float ratio,SliderEx::TouchEvent event){ + _volume = ratio; + log("_volume:%f,event:%d",_volume,event); + if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { + AudioEngine::getInstance()->setVolume(_audioID, _volume); + } + }); + volumeSlider->setPosition(Vec2(layerSize.width * 0.5f,layerSize.height * 0.35f)); + addChild(volumeSlider); + + auto timeSlider = SliderEx::create(); + timeSlider->setCallBack([&](SliderEx* sender,float ratio,SliderEx::TouchEvent event){ + switch(event){ + case SliderEx::TouchEvent::MOVE: + case SliderEx::TouchEvent::DOWN: + _updateTimeSlider = false; + break; + case SliderEx::TouchEvent::UP: + if (_audioID != AudioEngine::INVAILD_AUDIO_ID && _duration != AudioEngine::TIME_UNKNOWN) { + AudioEngine::getInstance()->setCurrentTime(_audioID,_duration * ratio); + } + case SliderEx::TouchEvent::CANCEL: + _updateTimeSlider = true; + break; + } + }); + timeSlider->setPosition(Vec2(layerSize.width * 0.5f,layerSize.height * 0.25f)); + addChild(timeSlider); + _timeSlider = timeSlider; + + auto& volumeSliderPos = volumeSlider->getPosition(); + auto& sliderSize = volumeSlider->getContentSize(); + auto volumeLabel = Label::createWithTTF("volume: ", fontFilePath, 20); + volumeLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT); + volumeLabel->setPosition(volumeSliderPos.x - sliderSize.width / 2, volumeSliderPos.y); + addChild(volumeLabel); + + auto& timeSliderPos = timeSlider->getPosition(); + auto timeLabel = Label::createWithTTF("time: ", fontFilePath, 20); + timeLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT); + timeLabel->setPosition(timeSliderPos.x - sliderSize.width / 2, timeSliderPos.y); + addChild(timeLabel); + + this->schedule(schedule_selector(AudioControlTest::update), 0.1f); + + return ret; +} + +void AudioControlTest::update(float dt) +{ + if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { + if(_duration == AudioEngine::TIME_UNKNOWN){ + _duration = AudioEngine::getInstance()->getDuration(_audioID); + } + if(_duration != AudioEngine::TIME_UNKNOWN){ + auto time = AudioEngine::getInstance()->getCurrentTime(_audioID); + _timeRatio = time / _duration; + if(_updateTimeSlider){ + ((SliderEx*)_timeSlider)->setRatio(_timeRatio); + } + } + } +} + +AudioControlTest::~AudioControlTest() +{ +} + +std::string AudioControlTest::title() const +{ + return "audio control test"; +} + +// PlaySimultaneouslyTest +bool PlaySimultaneouslyTest::init() +{ + auto ret = AudioEngineTestDemo::init(); + + char text[30]; + int tmp = 81; + for(int index = 0; index < TEST_COUNT; ++index){ + sprintf(text,"SoundEffectsFX009/FX0%d.mp3",tmp + index); + //sprintf(text,"audio2/1 (%d).mp3",1 + index); + _files[index] = text; + } + _playingcount = 0; + + auto playItem = TextButton::create("play-10-audio", [&](TextButton* button){ + auto engine = AudioEngine::getInstance(); + int audioId; + _playingcount = 0; + button->setEnabled(false); + auto startTime = utils::gettime(); + for(int index = 0; index < TEST_COUNT; ++index){ + audioId = engine->play2d(_files[index]); + if(audioId != AudioEngine::INVAILD_AUDIO_ID){ + _playingcount += 1; + + engine->setFinishCallback(audioId, [&](int id, const std::string& filePath){ + _playingcount -= 1; + if(_playingcount <= 0){ + ((TextButton*)_playItem)->setEnabled(true); + } + }); + } + else { + log("%s,%d,Fail to play file:%s",__FILE__,__LINE__ ,_files[index].c_str()); + } + } + log("diff time:%lf",utils::gettime() - startTime); + }); + playItem->setNormalizedPosition(Vec2(0.5f,0.5f)); + this->addChild(playItem); + _playItem = playItem; + + return ret; +} + +PlaySimultaneouslyTest::~PlaySimultaneouslyTest() +{ +} + +std::string PlaySimultaneouslyTest::title() const +{ + return "Simultaneously play multiple audio"; +} + +// AudioProfileTest +bool AudioProfileTest::init() +{ + auto ret = AudioEngineTestDemo::init(); + + char text[30]; + _files[0] = "background.mp3"; +#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS + _files[1] = "background.caf"; +#else + _files[1] = "background.ogg"; +#endif + _files[2] = "background.wav"; + _files[3] = "pew-pew-lei.wav"; + + std::string fontFilePath = "fonts/arial.ttf"; + _minDelay = 1.0f; + _time = 0.0f; + auto audioEngine = AudioEngine::getInstance(); + _profile = audioEngine->createProfile("MyProfile1",3,_minDelay); + + Vec2 pos(0.5f,0.7f); + + for(int index = 0; index < FILE_COUNT; ++index){ + sprintf(text,"play %s",_files[index].c_str()); + + auto playItem = TextButton::create(text, [&](TextButton* button){ + auto engine = AudioEngine::getInstance(); + int index = button->getTag(); + auto id = engine->play2d(_files[index], false, 1.0f, _profile); + if(id != AudioEngine::INVAILD_AUDIO_ID){ + _time = _minDelay; + _audioCount += 1; + char show[30]; + sprintf(show,"audio count:%d",_audioCount); + _showLabel->setString(show); + + engine->setFinishCallback(id, [&](int id, const std::string& filePath){ + _audioCount -= 1; + char show[30]; + sprintf(show,"audio count:%d",_audioCount); + _showLabel->setString(show); + }); + } + + }); + playItem->setTag(index); + playItem->setNormalizedPosition(pos); + this->addChild(playItem); + pos.y -= 0.1f; + + } + + Vec2 origin = Director::getInstance()->getVisibleOrigin(); + Size size = Director::getInstance()->getVisibleSize(); + + auto profileInfoLabel = Label::createWithTTF("AudioProfile Info:\n max instance:3 \n minimum delay:1.0", fontFilePath, 12); + profileInfoLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT); + profileInfoLabel->setPosition(Vec2(origin.x, origin.y + size.height * 0.65f)); + addChild(profileInfoLabel); + + _audioCount = 0; + _showLabel = Label::createWithTTF("audio count:0", fontFilePath, 12); + _showLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT); + _showLabel->setPosition(Vec2(origin.x, origin.y + size.height * 0.5f)); + addChild(_showLabel); + + auto timeSlider = SliderEx::create(); + timeSlider->setEnabled(false); + timeSlider->setNormalizedPosition(pos); + addChild(timeSlider); + _timeSlider = timeSlider; + + this->schedule(schedule_selector(AudioControlTest::update), 0.05f); + + return ret; +} + +void AudioProfileTest::update(float dt) +{ + if(_time > 0.0f) + { + _time -= dt; + ((SliderEx*)_timeSlider)->setRatio(_time / _minDelay); + } +} + +AudioProfileTest::~AudioProfileTest() +{ +} + +std::string AudioProfileTest::title() const +{ + return "AudioProfileTest"; +} + +std::string AudioProfileTest::subtitle() const +{ + return "See the console."; +} + +// InvalidAudioFileTest +bool InvalidAudioFileTest::init() +{ + auto ret = AudioEngineTestDemo::init(); + + auto playItem = TextButton::create("play unsupported media type", [&](TextButton* button){ +#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS + AudioEngine::getInstance()->play2d("background.ogg"); +#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID + AudioEngine::getInstance()->play2d("background.caf"); +#endif + }); + playItem->setNormalizedPosition(Vec2(0.5f, 0.6f)); + this->addChild(playItem); + + auto playItem2 = TextButton::create("play not-existent file", [&](TextButton* button){ + AudioEngine::getInstance()->play2d("NotExistFile.mp3"); + }); + playItem2->setNormalizedPosition(Vec2(0.5f, 0.4f)); + this->addChild(playItem2); + + return ret; +} + +InvalidAudioFileTest::~InvalidAudioFileTest() +{ +} + +std::string InvalidAudioFileTest::title() const +{ + return "Test invalid audio file"; +} + +std::string InvalidAudioFileTest::subtitle() const +{ + return "Not crash,please see the console."; +} + +// LargeAudioFileTest +bool LargeAudioFileTest::init() +{ + auto ret = AudioEngineTestDemo::init(); + + auto playItem = TextButton::create("play large audio file", [&](TextButton* button){ + AudioEngine::getInstance()->play2d("NotExistFile.mp3"); + }); + playItem->setNormalizedPosition(Vec2::ANCHOR_MIDDLE); + this->addChild(playItem); + + return ret; +} + +LargeAudioFileTest::~LargeAudioFileTest() +{ +} + +std::string LargeAudioFileTest::title() const +{ + return "Test large audio file"; +} + +#endif diff --git a/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.h b/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.h new file mode 100644 index 0000000000..21bdf62fe7 --- /dev/null +++ b/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.h @@ -0,0 +1,153 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + 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. + ****************************************************************************/ +#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS +#ifndef __NEWAUDIOENGINE_TEST_H_ +#define __NEWAUDIOENGINE_TEST_H_ + +#include "cocos2d.h" +#include "../testBasic.h" +#include "../BaseTest.h" + +#include "audio/include/AudioEngine.h" + +using namespace cocos2d; + +class AudioEngineTestScene : public TestScene +{ +public: + virtual void runThisTest(); +}; + +class AudioEngineTestDemo : public BaseTest +{ +public: + virtual std::string title() const override; + void backCallback(Ref* sender); + void nextCallback(Ref* sender); + void restartCallback(Ref* sender); + +}; + +class AudioControlTest : public AudioEngineTestDemo +{ +public: + CREATE_FUNC(AudioControlTest); + + virtual ~AudioControlTest(); + + virtual bool init(); + + virtual void update(float dt); + + virtual std::string title() const override; + +private: + int _audioID; + bool _loopEnabled; + float _volume; + float _duration; + float _timeRatio; + + void* _playItem; + void* _timeSlider; + bool _updateTimeSlider; +}; + +class PlaySimultaneouslyTest : public AudioEngineTestDemo +{ +public: + CREATE_FUNC(PlaySimultaneouslyTest); + + virtual ~PlaySimultaneouslyTest(); + + virtual bool init(); + + virtual std::string title() const override; +private: + static const int TEST_COUNT = 10; + std::string _files[TEST_COUNT]; + + void* _playItem; + int _playingcount; +}; + +class AudioProfileTest : public AudioEngineTestDemo +{ +public: + CREATE_FUNC(AudioProfileTest); + + virtual ~AudioProfileTest(); + + virtual bool init(); + + virtual std::string title() const override; + virtual std::string subtitle() const override; + + virtual void update(float dt); + +private: + static const int FILE_COUNT = 4; + std::string _files[FILE_COUNT]; + AudioProfile* _profile; + + int _audioCount; + Label* _showLabel; + float _time; + float _minDelay; + void* _timeSlider; +}; + +class InvalidAudioFileTest : public AudioEngineTestDemo +{ +public: + CREATE_FUNC(InvalidAudioFileTest); + + virtual ~InvalidAudioFileTest(); + + virtual bool init(); + + virtual std::string title() const override; + virtual std::string subtitle() const override; + +private: + +}; + +class LargeAudioFileTest : public AudioEngineTestDemo +{ +public: + CREATE_FUNC(LargeAudioFileTest); + + virtual ~LargeAudioFileTest(); + + virtual bool init(); + + virtual std::string title() const override; + +private: + +}; + +#endif /* defined(__NEWAUDIOENGINE_TEST_H_) */ +#endif diff --git a/tests/cpp-tests/Classes/controller.cpp b/tests/cpp-tests/Classes/controller.cpp index e677a5cecc..795557869a 100644 --- a/tests/cpp-tests/Classes/controller.cpp +++ b/tests/cpp-tests/Classes/controller.cpp @@ -39,6 +39,9 @@ Controller g_aTestNames[] = { { "Actions - Ease", [](){return new ActionsEaseTestScene();} }, { "Actions - Progress", [](){return new ProgressActionsTestScene(); } }, { "Audio - CocosDenshion", []() { return new CocosDenshionTestScene(); } }, +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) + { "Audio - NewAudioEngine", []() { return new AudioEngineTestScene(); } }, +#endif { "Box2d - Basic", []() { return new Box2DTestScene(); } }, { "Box2d - TestBed", []() { return new Box2dTestBedScene(); } }, { "Bugs", []() { return new BugsTestScene(); } }, diff --git a/tests/cpp-tests/Classes/tests.h b/tests/cpp-tests/Classes/tests.h index 5f0f139b23..deba2e9465 100644 --- a/tests/cpp-tests/Classes/tests.h +++ b/tests/cpp-tests/Classes/tests.h @@ -37,6 +37,9 @@ #include "PerformanceTest/PerformanceTest.h" #include "ZwoptexTest/ZwoptexTest.h" #include "CocosDenshionTest/CocosDenshionTest.h" +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) +#include "NewAudioEngineTest/NewAudioEngineTest.h" +#endif #if (CC_TARGET_PLATFORM != CC_PLATFORM_EMSCRIPEN) #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE) // bada don't support libcurl From 6b4b5ed943588e60a50142cb992887a5ea63935e Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Fri, 5 Sep 2014 11:13:51 +0800 Subject: [PATCH 05/32] Refactoring API: 1.Remove Singleton Pattern 2.Make AudioProfile clear. --- cocos/audio/AudioEngine.cpp | 227 ++++++++---------- cocos/audio/android/AudioEngine-inl.cpp | 31 ++- cocos/audio/android/AudioEngine-inl.h | 7 +- cocos/audio/include/AudioEngine.h | 133 +++++----- .../NewAudioEngineTest/NewAudioEngineTest.cpp | 56 +++-- .../NewAudioEngineTest/NewAudioEngineTest.h | 2 +- 6 files changed, 197 insertions(+), 259 deletions(-) diff --git a/cocos/audio/AudioEngine.cpp b/cocos/audio/AudioEngine.cpp index 02c611644c..bb94580e16 100644 --- a/cocos/audio/AudioEngine.cpp +++ b/cocos/audio/AudioEngine.cpp @@ -33,8 +33,6 @@ #include "ios/AudioEngine-inl.h" #endif -static cocos2d::AudioEngine *s_sharedAudioEngine = nullptr; - #define TIME_DELAY_PRECISION 0.0001 using namespace cocos2d; @@ -42,76 +40,78 @@ using namespace cocos2d; const int AudioEngine::INVAILD_AUDIO_ID = -1; const float AudioEngine::TIME_UNKNOWN = -1.0f; -AudioEngine* AudioEngine::getInstance() -{ - if (!s_sharedAudioEngine) - { - s_sharedAudioEngine = new (std::nothrow) AudioEngine(); - CCASSERT(s_sharedAudioEngine, "FATAL: Not enough memory"); +//audio file path,audio IDs +std::unordered_map> AudioEngine::_audioIDs; +//profileName,ProfileManage +std::unordered_map AudioEngine::_profileManages; +int AudioEngine::_maxInstances = kMaxSources; +AudioEngine::ProfileManage* AudioEngine::_defaultProfileManage; +std::unordered_map AudioEngine::_audioInfos; +AudioEngineImpl* AudioEngine::_audioEngineImpl = nullptr; - if(!s_sharedAudioEngine->init()){ - delete s_sharedAudioEngine; - s_sharedAudioEngine = nullptr; +void AudioEngine::end() +{ + delete _audioEngineImpl; + _audioEngineImpl = nullptr; + + delete _defaultProfileManage; + _defaultProfileManage = nullptr; +} + +bool AudioEngine::lazyInit() +{ + if (_audioEngineImpl == nullptr) + { + _audioEngineImpl = new (std::nothrow) AudioEngineImpl(); + if(!_audioEngineImpl || !_audioEngineImpl->init() ){ + return false; } } - return s_sharedAudioEngine; + return true; } -void AudioEngine::destroyInstance() -{ - delete s_sharedAudioEngine; - s_sharedAudioEngine = nullptr; -} - -AudioEngine::AudioEngine() - : _maxInstances(kMaxSources) -{ - _audioEngineImpl = new (std::nothrow) AudioEngineImpl(this); - - _audioProfiles["audioengine_defaultProfile"] = new AudioProfile; - _defaultProfile = _audioProfiles["audioengine_defaultProfile"]; -} - -AudioEngine::~AudioEngine() -{ - for (auto it = _audioProfiles.begin(); it != _audioProfiles.end(); ++it) { - delete it->second; - } - _audioProfiles.clear(); - - delete _audioEngineImpl; -} - -bool AudioEngine::init() -{ - return _audioEngineImpl->init(); -} - -int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, AudioProfile *profile) +int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, const AudioProfile *profile) { int ret = AudioEngine::INVAILD_AUDIO_ID; - if ( !FileUtils::getInstance()->isFileExist(filePath)){ - return ret; - } do { - auto targetProfile = profile; - if (!targetProfile) { - targetProfile = _defaultProfile; + if (_audioEngineImpl == nullptr) + { + _audioEngineImpl = new (std::nothrow) AudioEngineImpl(); + if(!_audioEngineImpl || !_audioEngineImpl->init() ){ + break; + } } - if (_audioInfos.size() >= _maxInstances || (targetProfile->maxInstances != 0 && targetProfile->audioIDs.size() >= targetProfile->maxInstances)) { - log("Fail to play %s cause by limited max instance",filePath.c_str()); + if ( !FileUtils::getInstance()->isFileExist(filePath)){ break; } - if (targetProfile->minDelay > TIME_DELAY_PRECISION) { - auto currTime = utils::gettime(); - if (targetProfile->lastPlayTime > TIME_DELAY_PRECISION && currTime - targetProfile->lastPlayTime <= targetProfile->minDelay) { - log("Fail to play %s cause by limited minimum delay",filePath.c_str()); - break; - } + ProfileManage* manage = _defaultProfileManage; + if (profile && profile != &manage->profile){ + CC_ASSERT(!profile->name.empty()); + manage = &_profileManages[profile->name]; + manage->profile = *profile; + } + + if (_audioInfos.size() >= _maxInstances) { + log("Fail to play %s cause by limited max instance of AudioEngine",filePath.c_str()); + break; + } + if (manage) + { + if(manage->profile.maxInstances != 0 && manage->audioIDs.size() >= manage->profile.maxInstances){ + log("Fail to play %s cause by limited max instance of AudioProfile",filePath.c_str()); + break; + } + if (manage->profile.minDelay > TIME_DELAY_PRECISION) { + auto currTime = utils::gettime(); + if (manage->lastPlayTime > TIME_DELAY_PRECISION && currTime - manage->lastPlayTime <= manage->profile.minDelay) { + log("Fail to play %s cause by limited minimum delay",filePath.c_str()); + break; + } + } } if (volume < 0.0f) { @@ -121,7 +121,7 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, Au volume = 1.0f; } - ret = _audioEngineImpl->play2d(filePath, loop, volume, targetProfile); + ret = _audioEngineImpl->play2d(filePath, loop, volume); if (ret != INVAILD_AUDIO_ID) { _audioIDs[filePath].push_back(ret); @@ -132,8 +132,10 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, Au audioRef.loop = loop; audioRef.is3dAudio = false; audioRef.filePath = &it->first; - audioRef.profile = targetProfile; - //audioRef.state = AudioEngine::AudioState::PLAYING; + + manage->lastPlayTime = utils::gettime(); + manage->audioIDs.push_back(ret); + audioRef.profileManage = manage; } } while (0); @@ -214,8 +216,8 @@ void AudioEngine::stop(int audioID) if (it != _audioInfos.end()){ _audioEngineImpl->stop(audioID); - if (it->second.profile) { - it->second.profile->audioIDs.remove(audioID); + if (it->second.profileManage) { + it->second.profileManage->audioIDs.remove(audioID); } _audioIDs[*it->second.filePath].remove(audioID); _audioInfos.erase(audioID); @@ -226,8 +228,8 @@ void AudioEngine::remove(int audioID) { auto it = _audioInfos.find(audioID); if (it != _audioInfos.end()){ - if (it->second.profile) { - it->second.profile->audioIDs.remove(audioID); + if (it->second.profileManage) { + it->second.profileManage->audioIDs.remove(audioID); } _audioIDs[*it->second.filePath].remove(audioID); _audioInfos.erase(audioID); @@ -240,8 +242,8 @@ void AudioEngine::stopAll() auto itEnd = _audioInfos.end(); for (auto it = _audioInfos.begin(); it != itEnd; ++it) { - if (it->second.profile){ - it->second.profile->audioIDs.remove(it->first); + if (it->second.profileManage){ + it->second.profileManage->audioIDs.remove(it->first); } } _audioIDs.clear(); @@ -255,11 +257,12 @@ void AudioEngine::uncache(const std::string &filePath) int audioID; for (auto it = _audioIDs[filePath].begin() ; it != itEnd; ++it) { audioID = *it; + log("uncache id:%d", audioID); _audioEngineImpl->stop(audioID); auto& info = _audioInfos[audioID]; - if (info.profile) { - info.profile->audioIDs.remove(audioID); + if (info.profileManage) { + info.profileManage->audioIDs.remove(audioID); } _audioInfos.erase(audioID); } @@ -326,63 +329,7 @@ bool AudioEngine::setMaxAudioInstance(unsigned int maxInstances) return false; } -void AudioEngine::setDefaultProfile(AudioProfile *profile) -{ - if (_defaultProfile != profile && _defaultProfile) { - auto itEnd = _defaultProfile->audioIDs.end(); - for (auto it = _defaultProfile->audioIDs.begin() ; it != itEnd; ++it) { - _audioInfos[*it].profile = profile; - profile->audioIDs.push_back(*it); - } - _defaultProfile->audioIDs.clear(); - } - - _defaultProfile = profile; -} - -void AudioEngine::setProfile(int audioID, AudioProfile *profile) -{ - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end()) - { - if (it->second.profile) { - it->second.profile->audioIDs.remove(audioID); - } - - it->second.profile = profile; - if (profile) { - profile->audioIDs.push_back(audioID); - } - } -} - -AudioProfile* AudioEngine::createProfile(const std::string &name, int maxInstances, double minDelay, float minRange, float maxRange) -{ - if (_audioProfiles.find(name) == _audioProfiles.end()) { - _audioProfiles[name] = new AudioProfile; - } - auto profile = _audioProfiles[name]; - - profile->maxInstances = maxInstances; - profile->minDelay = minDelay; - profile->minRange = minRange; - profile->maxRange = maxRange; - - return profile; -} - -AudioProfile* AudioEngine::getProfile(const std::string &name) -{ - auto it = _audioProfiles.find(name); - if (it != _audioProfiles.end()) { - return it->second; - } else { - log("AudioEngine::getProfile-->profile:%s not found", name.c_str()); - return nullptr; - } -} - -bool AudioEngine::isLoop(int audioID) const +bool AudioEngine::isLoop(int audioID) { auto tmpIterator = _audioInfos.find(audioID); if (tmpIterator != _audioInfos.end()) @@ -394,7 +341,7 @@ bool AudioEngine::isLoop(int audioID) const return false; } -float AudioEngine::getVolume(int audioID) const +float AudioEngine::getVolume(int audioID) { auto tmpIterator = _audioInfos.find(audioID); if (tmpIterator != _audioInfos.end()) @@ -406,7 +353,7 @@ float AudioEngine::getVolume(int audioID) const return 0.0f; } -AudioEngine::AudioState AudioEngine::getState(int audioID) const +AudioEngine::AudioState AudioEngine::getState(int audioID) { auto tmpIterator = _audioInfos.find(audioID); if (tmpIterator != _audioInfos.end()) @@ -420,19 +367,35 @@ AudioEngine::AudioState AudioEngine::getState(int audioID) const AudioProfile* AudioEngine::getProfile(int audioID) { - auto tmpIterator = _audioInfos.find(audioID); - if (tmpIterator != _audioInfos.end()) + auto it = _audioInfos.find(audioID); + if (it != _audioInfos.end()) { - return tmpIterator->second.profile; + return &it->second.profileManage->profile; } log("AudioEngine::getProfile-->The audio instance %d is non-existent", audioID); return nullptr; } -AudioProfile* AudioEngine::getDefaultProfile() const +AudioProfile* AudioEngine::getDefaultProfile() { - return _defaultProfile; + if (_defaultProfileManage == nullptr) + { + _defaultProfileManage = new (std::nothrow) ProfileManage(); + } + + return &_defaultProfileManage->profile; +} + +AudioProfile* AudioEngine::getProfile(const std::string &name) +{ + auto it = _profileManages.find(name); + if (it != _profileManages.end()) { + return &it->second.profile; + } else { + log("AudioEngine::getProfile-->profile:%s not found", name.c_str()); + return nullptr; + } } unsigned int AudioEngine::getMaxAudioInstance() diff --git a/cocos/audio/android/AudioEngine-inl.cpp b/cocos/audio/android/AudioEngine-inl.cpp index 2a8de0a7f3..1b5158b1c4 100644 --- a/cocos/audio/android/AudioEngine-inl.cpp +++ b/cocos/audio/android/AudioEngine-inl.cpp @@ -99,7 +99,10 @@ bool AudioPlayer::init(SLEngineItf engineEngine, SLObjectItf outputMixObject,con // open asset as file descriptor off_t start, length; int fd = AAsset_openFileDescriptor(asset, &start, &length); - assert(0 <= fd); + if (fd <= 0){ + AAsset_close(asset); + break; + } AAsset_close(asset); // configure audio source @@ -154,9 +157,8 @@ bool AudioPlayer::init(SLEngineItf engineEngine, SLObjectItf outputMixObject,con } //==================================================== -AudioEngineImpl::AudioEngineImpl(AudioEngine* audioEngine) - : _audioEngine(audioEngine) - , nextAudioID(0) +AudioEngineImpl::AudioEngineImpl() + : nextAudioID(0) , _engineObject(nullptr) , _engineEngine(nullptr) , _outputMixObject(nullptr) @@ -208,7 +210,7 @@ bool AudioEngineImpl::init() return ret; } -int AudioEngineImpl::play2d(const std::string &fileFullPath ,bool loop ,float volume, AudioProfile* profile) +int AudioEngineImpl::play2d(const std::string &fileFullPath ,bool loop ,float volume) { auto audioId = AudioEngine::INVAILD_AUDIO_ID; @@ -231,12 +233,7 @@ int AudioEngineImpl::play2d(const std::string &fileFullPath ,bool loop ,float vo (*(player._fdPlayerPlay))->RegisterCallback(player._fdPlayerPlay, PlayOverEvent, (void*)this); (*(player._fdPlayerPlay))->SetCallbackEventsMask(player._fdPlayerPlay, SL_PLAYEVENT_HEADATEND); - if (profile) { - profile->lastPlayTime = utils::gettime(); - profile->audioIDs.push_back(audioId); - } - - _audioEngine->_audioInfos[audioId].state = AudioEngine::AudioState::PLAYING; + AudioEngine::_audioInfos[audioId].state = AudioEngine::AudioState::PLAYING; } while (0); return audioId; @@ -251,9 +248,9 @@ void AudioEngineImpl::playerFinishCallback(SLPlayItf caller, SLuint32 playEvent) { if (iter->second._finishCallback) { - iter->second._finishCallback(iter->second._audioID, *_audioEngine->_audioInfos[iter->second._audioID].filePath); + iter->second._finishCallback(iter->second._audioID, *AudioEngine::_audioInfos[iter->second._audioID].filePath); } - _audioEngine->stop(iter->second._audioID); + AudioEngine::stop(iter->second._audioID); break; } } @@ -264,7 +261,7 @@ void AudioEngineImpl::setVolume(int audioID,float volume) auto& player = _audioPlayers[audioID]; auto result = (*player._fdPlayerVolume)->SetVolumeLevel(player._fdPlayerVolume, MIN_VOLUME_MILLIBEL + RANGE_VOLUME_MILLIBEL * volume); if(SL_RESULT_SUCCESS != result){ - log("%s error:%lu",__func__, result); + log("%s error:%u",__func__, result); } } @@ -283,7 +280,7 @@ void AudioEngineImpl::pause(int audioID) auto& player = _audioPlayers[audioID]; auto result = (*player._fdPlayerPlay)->SetPlayState(player._fdPlayerPlay, SL_PLAYSTATE_PAUSED); if(SL_RESULT_SUCCESS != result){ - log("%s error:%lu",__func__, result); + log("%s error:%u",__func__, result); } } @@ -292,7 +289,7 @@ void AudioEngineImpl::resume(int audioID) auto& player = _audioPlayers[audioID]; auto result = (*player._fdPlayerPlay)->SetPlayState(player._fdPlayerPlay, SL_PLAYSTATE_PLAYING); if(SL_RESULT_SUCCESS != result){ - log("%s error:%lu",__func__, result); + log("%s error:%u",__func__, result); } } @@ -301,7 +298,7 @@ void AudioEngineImpl::stop(int audioID) auto& player = _audioPlayers[audioID]; auto result = (*player._fdPlayerPlay)->SetPlayState(player._fdPlayerPlay, SL_PLAYSTATE_STOPPED); if(SL_RESULT_SUCCESS != result){ - log("%s error:%lu",__func__, result); + log("%s error:%u",__func__, result); } _audioPlayers.erase(audioID); diff --git a/cocos/audio/android/AudioEngine-inl.h b/cocos/audio/android/AudioEngine-inl.h index 2decd98fce..8444d12c7c 100644 --- a/cocos/audio/android/AudioEngine-inl.h +++ b/cocos/audio/android/AudioEngine-inl.h @@ -63,16 +63,14 @@ private: friend class AudioEngineImpl; }; -class AudioEngine; -class AudioProfile; class AudioEngineImpl { public: - AudioEngineImpl(AudioEngine* audioEngine); + AudioEngineImpl(); ~AudioEngineImpl(); bool init(); - int play2d(const std::string &fileFullPath ,bool loop ,float volume, AudioProfile* profile); + int play2d(const std::string &fileFullPath ,bool loop ,float volume); void setVolume(int audioID,float volume); void setLoop(int audioID, bool loop); void pause(int audioID); @@ -89,7 +87,6 @@ public: void uncache(const std::string& filePath){} void uncacheAll(){} private: - AudioEngine* _audioEngine; // engine interfaces SLObjectItf _engineObject; diff --git a/cocos/audio/include/AudioEngine.h b/cocos/audio/include/AudioEngine.h index b05c1a1472..4250239c7a 100644 --- a/cocos/audio/include/AudioEngine.h +++ b/cocos/audio/include/AudioEngine.h @@ -37,12 +37,12 @@ NS_CC_BEGIN -class AudioEngine; -class AudioEngineImpl; - class EXPORT_DLL AudioProfile { public: + //name can't be empty + std::string name; + unsigned int maxInstances; /* minimum delay in between sounds */ @@ -52,23 +52,16 @@ public: float minRange; float maxRange; -private: AudioProfile() : minDelay(0.0) , maxInstances(0) - , lastPlayTime(0.0) { } - - std::list audioIDs; - - double lastPlayTime; - - friend class AudioEngine; - friend class AudioEngineImpl; }; +class AudioEngineImpl; + /** @class AudioEngine @brief @@ -89,34 +82,17 @@ public: static const float TIME_UNKNOWN; - /** Returns a shared instance of the AudioEngine */ - static AudioEngine* getInstance(); - + static bool lazyInit(); /** * Release the shared Audio Engine object @warning It must be called before the application exit */ - static void destroyInstance(); - - /** Create an audio profile - * - */ - virtual AudioProfile* createProfile(const std::string& name,int maxInstance = 0,double minDelay = 0.0f,float minRange = 0.0f,float maxRange = 1.0f); - - /** Get an audio profile - * - */ - virtual AudioProfile* getProfile(const std::string& name); - - /** Setup default profiles for audio instances - * @param profile a profile return by createProfile/getProfile function - */ - virtual void setDefaultProfile(AudioProfile* profile); + static void end(); /** Gets the default profile of audio instances * @return the default profile of audio instances */ - virtual AudioProfile* getDefaultProfile() const; + static AudioProfile* getDefaultProfile(); /** Play 2d sound * @param filePath The path of an audio file @@ -125,129 +101,136 @@ public: * @param profile a profile return by createProfile/getProfile function * @return an audio ID. It allows you to dynamically change the behavior of an audio instance on the fly. */ - virtual int play2d(const std::string& filePath, bool loop = false, float volume = 1.0f, AudioProfile *profile = nullptr); + static int play2d(const std::string& filePath, bool loop = false, float volume = 1.0f, const AudioProfile *profile = nullptr); /** Sets whether an audio instance loop or not. @param audioID an audioID returned by the play2d function @param loop Whether audio instance loop or not */ - virtual void setLoop(int audioID, bool loop); + static void setLoop(int audioID, bool loop); /** Checks whether an audio instance is loop. * @param audioID an audioID returned by the play2d function * @return Whether or not an audio instance is loop. */ - virtual bool isLoop(int audioID) const; + static bool isLoop(int audioID); /** Sets volume for an audio instance. * @param audioID an audioID returned by the play2d function * @param volume volume value (range from 0.0 to 1.0) */ - virtual void setVolume(int audioID, float volume); + static void setVolume(int audioID, float volume); /** Gets the volume value of an audio instance. * @param audioID an audioID returned by the play2d function * @return volume value (range from 0.0 to 1.0) */ - virtual float getVolume(int audioID) const; + static float getVolume(int audioID); /** Pause an audio instance. * @param audioID an audioID returned by the play2d function */ - virtual void pause(int audioID); + static void pause(int audioID); /** Pause all playing audio instances */ - virtual void pauseAll(); + static void pauseAll(); /** Resume an audio instance. * @param audioID an audioID returned by the play2d function */ - virtual void resume(int audioID); + static void resume(int audioID); /** Resume all suspended audio instances */ - virtual void resumeAll(); + static void resumeAll(); /** Stop an audio instance. * @param audioID an audioID returned by the play2d function */ - virtual void stop(int audioID); + static void stop(int audioID); /** Stop all audio instances */ - virtual void stopAll(); + static void stopAll(); /** Sets the current playback position of an audio instance. * @param audioID an audioID returned by the play2d function * @return */ - virtual bool setCurrentTime(int audioID, float time); + static bool setCurrentTime(int audioID, float time); /** Gets the current playback position of an audio instance. * @param audioID an audioID returned by the play2d function * @return the current playback position of an audio instance */ - virtual float getCurrentTime(int audioID); + static float getCurrentTime(int audioID); /** Gets the duration of an audio instance. * @param audioID an audioID returned by the play2d function * @return the duration of an audio instance */ - virtual float getDuration(int audioID); + static float getDuration(int audioID); /** Returns the state of an audio instance. * @param audioID an audioID returned by the play2d function * @return the status of an audio instance */ - virtual AudioState getState(int audioID) const; + static AudioState getState(int audioID); /** Register a callback to be invoked when an audio instance has completed playing. * @param audioID an audioID returned by the play2d function * @param callback */ - virtual void setFinishCallback(int audioID, const std::function& callback); + static void setFinishCallback(int audioID, const std::function& callback); - virtual unsigned int getMaxAudioInstance(); + static unsigned int getMaxAudioInstance(); - virtual bool setMaxAudioInstance(unsigned int maxInstances); + static bool setMaxAudioInstance(unsigned int maxInstances); /** Uncache the audio data from internal buffer. * AudioEngine cache audio data on ios platform * @warning This can lead to stop related audio first. * @param filePath The path of an audio file */ - void uncache(const std::string& filePath); + static void uncache(const std::string& filePath); /** Uncache all audio data from internal buffer. * @warning All audio will be stopped first. * @param */ - void uncacheAll(); - - /** Setup profiles for an audio instance. - * @param audioID an audioID returned by the play2d function - * @param profile a profile for audio instance - */ - virtual void setProfile(int audioID, AudioProfile* profile); + static void uncacheAll(); /** Gets the profiles of audio instance. * @param audioID an audioID returned by the play2d function * @return the profile of audio instance */ - virtual AudioProfile* getProfile(int audioID); + static AudioProfile* getProfile(int audioID); + + static AudioProfile* getProfile(const std::string &name); protected: - AudioEngine(); - virtual ~AudioEngine(); - // - void remove(int audioID); - - virtual bool init(); + static void remove(int audioID); + class ProfileManage + { + public: + AudioProfile profile; + + ProfileManage() + : lastPlayTime(0.0) + { + + } + + std::list audioIDs; + + double lastPlayTime; + }; + class AudioInfo { public: AudioInfo() - : profile(nullptr) + : profileManage(nullptr) , duration(TIME_UNKNOWN) , state(AudioState::INITIAL) { @@ -255,7 +238,7 @@ protected: } const std::string* filePath; - AudioProfile* profile; + ProfileManage* profileManage; float volume; bool loop; @@ -264,21 +247,21 @@ protected: bool is3dAudio; }; - + //audioID,audioAttribute - std::unordered_map _audioInfos; + static std::unordered_map _audioInfos; //audio file path,audio IDs - std::unordered_map> _audioIDs; + static std::unordered_map> _audioIDs; - //profileName,AudioProfile - std::unordered_map _audioProfiles; + //profileName,ProfileManage + static std::unordered_map _profileManages; - int _maxInstances; + static int _maxInstances; - AudioProfile* _defaultProfile; + static ProfileManage* _defaultProfileManage; - AudioEngineImpl* _audioEngineImpl; + static AudioEngineImpl* _audioEngineImpl; friend class AudioEngineImpl; }; diff --git a/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp b/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp index d4d4ea91fe..00179be6e2 100644 --- a/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp +++ b/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp @@ -288,8 +288,7 @@ Layer* restartAction() void AudioEngineTestScene::runThisTest() { - auto engine = AudioEngine::getInstance(); - CCASSERT(engine,"Fail to get instance of AudioEngine!"); + CCASSERT(AudioEngine::lazyInit(),"Fail to initialize AudioEngine!"); s_sceneIdx = -1; auto layer = nextAction(); @@ -300,7 +299,7 @@ void AudioEngineTestScene::runThisTest() void AudioEngineTestDemo::backCallback(Ref* sender) { - AudioEngine::getInstance()->stopAll(); + AudioEngine::stopAll(); auto scene = new AudioEngineTestScene(); auto layer = backAction(); @@ -311,7 +310,7 @@ void AudioEngineTestDemo::backCallback(Ref* sender) void AudioEngineTestDemo::nextCallback(Ref* sender) { - AudioEngine::getInstance()->stopAll(); + AudioEngine::stopAll(); auto scene = new AudioEngineTestScene(); auto layer = nextAction(); @@ -322,7 +321,7 @@ void AudioEngineTestDemo::nextCallback(Ref* sender) void AudioEngineTestDemo::restartCallback(Ref* sender) { - AudioEngine::getInstance()->stopAll(); + AudioEngine::stopAll(); auto scene = new AudioEngineTestScene(); auto layer = restartAction(); @@ -353,12 +352,11 @@ bool AudioControlTest::init() auto playItem = TextButton::create("play", [&](TextButton* button){ if (_audioID == AudioEngine::INVAILD_AUDIO_ID) { - auto engine = AudioEngine::getInstance(); - _audioID = engine->play2d("background.mp3", _loopEnabled, _volume); + _audioID = AudioEngine::play2d("background.mp3", _loopEnabled, _volume); if(_audioID != AudioEngine::INVAILD_AUDIO_ID) { button->setEnabled(false); - engine->setFinishCallback(_audioID, [&](int id, const std::string& filePath){ + AudioEngine::setFinishCallback(_audioID, [&](int id, const std::string& filePath){ _audioID = AudioEngine::INVAILD_AUDIO_ID; ((TextButton*)_playItem)->setEnabled(true); @@ -374,7 +372,7 @@ bool AudioControlTest::init() auto stopItem = TextButton::create("stop", [&](TextButton* button){ if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { - AudioEngine::getInstance()->stop(_audioID); + AudioEngine::stop(_audioID); _audioID = AudioEngine::INVAILD_AUDIO_ID; ((TextButton*)_playItem)->setEnabled(true); @@ -385,7 +383,7 @@ bool AudioControlTest::init() auto pauseItem = TextButton::create("pause", [&](TextButton* button){ if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { - AudioEngine::getInstance()->pause(_audioID); + AudioEngine::pause(_audioID); } }); pauseItem->setPosition(layerSize.width * 0.3f,layerSize.height * 0.6f); @@ -393,7 +391,7 @@ bool AudioControlTest::init() auto resumeItem = TextButton::create("resume", [&](TextButton* button){ if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { - AudioEngine::getInstance()->resume(_audioID); + AudioEngine::resume(_audioID); } }); resumeItem->setPosition(layerSize.width * 0.7f,layerSize.height * 0.6f); @@ -403,7 +401,7 @@ bool AudioControlTest::init() _loopEnabled = !_loopEnabled; if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { - AudioEngine::getInstance()->setLoop(_audioID, _loopEnabled); + AudioEngine::setLoop(_audioID, _loopEnabled); } if(_loopEnabled){ button->setString("disable-loop"); @@ -416,7 +414,7 @@ bool AudioControlTest::init() addChild(loopItem); auto uncacheItem = TextButton::create("uncache", [&](TextButton* button){ - AudioEngine::getInstance()->uncache("background.mp3"); + AudioEngine::uncache("background.mp3"); _audioID = AudioEngine::INVAILD_AUDIO_ID; ((TextButton*)_playItem)->setEnabled(true); @@ -430,7 +428,7 @@ bool AudioControlTest::init() _volume = ratio; log("_volume:%f,event:%d",_volume,event); if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { - AudioEngine::getInstance()->setVolume(_audioID, _volume); + AudioEngine::setVolume(_audioID, _volume); } }); volumeSlider->setPosition(Vec2(layerSize.width * 0.5f,layerSize.height * 0.35f)); @@ -445,7 +443,7 @@ bool AudioControlTest::init() break; case SliderEx::TouchEvent::UP: if (_audioID != AudioEngine::INVAILD_AUDIO_ID && _duration != AudioEngine::TIME_UNKNOWN) { - AudioEngine::getInstance()->setCurrentTime(_audioID,_duration * ratio); + AudioEngine::setCurrentTime(_audioID,_duration * ratio); } case SliderEx::TouchEvent::CANCEL: _updateTimeSlider = true; @@ -478,10 +476,10 @@ void AudioControlTest::update(float dt) { if (_audioID != AudioEngine::INVAILD_AUDIO_ID ) { if(_duration == AudioEngine::TIME_UNKNOWN){ - _duration = AudioEngine::getInstance()->getDuration(_audioID); + _duration = AudioEngine::getDuration(_audioID); } if(_duration != AudioEngine::TIME_UNKNOWN){ - auto time = AudioEngine::getInstance()->getCurrentTime(_audioID); + auto time = AudioEngine::getCurrentTime(_audioID); _timeRatio = time / _duration; if(_updateTimeSlider){ ((SliderEx*)_timeSlider)->setRatio(_timeRatio); @@ -514,17 +512,16 @@ bool PlaySimultaneouslyTest::init() _playingcount = 0; auto playItem = TextButton::create("play-10-audio", [&](TextButton* button){ - auto engine = AudioEngine::getInstance(); int audioId; _playingcount = 0; button->setEnabled(false); auto startTime = utils::gettime(); for(int index = 0; index < TEST_COUNT; ++index){ - audioId = engine->play2d(_files[index]); + audioId = AudioEngine::play2d(_files[index]); if(audioId != AudioEngine::INVAILD_AUDIO_ID){ _playingcount += 1; - engine->setFinishCallback(audioId, [&](int id, const std::string& filePath){ + AudioEngine::setFinishCallback(audioId, [&](int id, const std::string& filePath){ _playingcount -= 1; if(_playingcount <= 0){ ((TextButton*)_playItem)->setEnabled(true); @@ -571,8 +568,10 @@ bool AudioProfileTest::init() std::string fontFilePath = "fonts/arial.ttf"; _minDelay = 1.0f; _time = 0.0f; - auto audioEngine = AudioEngine::getInstance(); - _profile = audioEngine->createProfile("MyProfile1",3,_minDelay); + + _audioProfile.name = "AudioProfileTest"; + _audioProfile.maxInstances = 3; + _audioProfile.minDelay = 1.0; Vec2 pos(0.5f,0.7f); @@ -580,9 +579,8 @@ bool AudioProfileTest::init() sprintf(text,"play %s",_files[index].c_str()); auto playItem = TextButton::create(text, [&](TextButton* button){ - auto engine = AudioEngine::getInstance(); int index = button->getTag(); - auto id = engine->play2d(_files[index], false, 1.0f, _profile); + auto id = AudioEngine::play2d(_files[index], false, 1.0f, &_audioProfile); if(id != AudioEngine::INVAILD_AUDIO_ID){ _time = _minDelay; _audioCount += 1; @@ -590,7 +588,7 @@ bool AudioProfileTest::init() sprintf(show,"audio count:%d",_audioCount); _showLabel->setString(show); - engine->setFinishCallback(id, [&](int id, const std::string& filePath){ + AudioEngine::setFinishCallback(id, [&](int id, const std::string& filePath){ _audioCount -= 1; char show[30]; sprintf(show,"audio count:%d",_audioCount); @@ -661,16 +659,16 @@ bool InvalidAudioFileTest::init() auto playItem = TextButton::create("play unsupported media type", [&](TextButton* button){ #if CC_TARGET_PLATFORM == CC_PLATFORM_IOS - AudioEngine::getInstance()->play2d("background.ogg"); + AudioEngine::play2d("background.ogg"); #elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID - AudioEngine::getInstance()->play2d("background.caf"); + AudioEngine::play2d("background.caf"); #endif }); playItem->setNormalizedPosition(Vec2(0.5f, 0.6f)); this->addChild(playItem); auto playItem2 = TextButton::create("play not-existent file", [&](TextButton* button){ - AudioEngine::getInstance()->play2d("NotExistFile.mp3"); + AudioEngine::play2d("NotExistFile.mp3"); }); playItem2->setNormalizedPosition(Vec2(0.5f, 0.4f)); this->addChild(playItem2); @@ -698,7 +696,7 @@ bool LargeAudioFileTest::init() auto ret = AudioEngineTestDemo::init(); auto playItem = TextButton::create("play large audio file", [&](TextButton* button){ - AudioEngine::getInstance()->play2d("NotExistFile.mp3"); + AudioEngine::play2d("NotExistFile.mp3"); }); playItem->setNormalizedPosition(Vec2::ANCHOR_MIDDLE); this->addChild(playItem); diff --git a/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.h b/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.h index 21bdf62fe7..e4c2133b6a 100644 --- a/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.h +++ b/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.h @@ -109,7 +109,7 @@ public: private: static const int FILE_COUNT = 4; std::string _files[FILE_COUNT]; - AudioProfile* _profile; + AudioProfile _audioProfile; int _audioCount; Label* _showLabel; From 1d900940ab70964d60da06bc517a09bf3ab8f6c1 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Fri, 5 Sep 2014 14:34:30 +0800 Subject: [PATCH 06/32] Refactoring API: 1.Remove Singleton Pattern 2.Make AudioProfile clear. --- cocos/audio/AudioEngine.cpp | 6 ++++-- cocos/audio/ios/AudioEngine-inl.h | 6 ++---- cocos/audio/ios/AudioEngine-inl.mm | 20 +++++++------------- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/cocos/audio/AudioEngine.cpp b/cocos/audio/AudioEngine.cpp index bb94580e16..daa977063a 100644 --- a/cocos/audio/AudioEngine.cpp +++ b/cocos/audio/AudioEngine.cpp @@ -133,8 +133,10 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, co audioRef.is3dAudio = false; audioRef.filePath = &it->first; - manage->lastPlayTime = utils::gettime(); - manage->audioIDs.push_back(ret); + if (manage) { + manage->lastPlayTime = utils::gettime(); + manage->audioIDs.push_back(ret); + } audioRef.profileManage = manage; } } while (0); diff --git a/cocos/audio/ios/AudioEngine-inl.h b/cocos/audio/ios/AudioEngine-inl.h index 8a6e4b846e..835367a06f 100644 --- a/cocos/audio/ios/AudioEngine-inl.h +++ b/cocos/audio/ios/AudioEngine-inl.h @@ -33,7 +33,6 @@ #include "AudioPlayer.h" NS_CC_BEGIN -class AudioEngine; class AudioProfile; #define kMaxSources 32 @@ -43,11 +42,11 @@ class AudioEngineThreadPool; class AudioEngineImpl : public cocos2d::Ref { public: - AudioEngineImpl(AudioEngine* audioEngine); + AudioEngineImpl(); ~AudioEngineImpl(); bool init(); - int play2d(const std::string &fileFullPath ,bool loop ,float volume, AudioProfile* profile); + int play2d(const std::string &fileFullPath ,bool loop ,float volume); void setVolume(int audioID,float volume); void setLoop(int audioID, bool loop); bool pause(int audioID); @@ -68,7 +67,6 @@ private: void _play2d(AudioCache *cache, int audioID); AudioEngineThreadPool* _threadPool; - AudioEngine* _audioEngine; ALuint _alSources[kMaxSources]; diff --git a/cocos/audio/ios/AudioEngine-inl.mm b/cocos/audio/ios/AudioEngine-inl.mm index 32b3b74f45..2c4769d567 100644 --- a/cocos/audio/ios/AudioEngine-inl.mm +++ b/cocos/audio/ios/AudioEngine-inl.mm @@ -132,9 +132,8 @@ namespace cocos2d { }; } -AudioEngineImpl::AudioEngineImpl(AudioEngine* audioEngine) -: _audioEngine(audioEngine) -, _lazyInitLoop(true) +AudioEngineImpl::AudioEngineImpl() +: _lazyInitLoop(true) , nextAudioID(0) , _threadPool(nullptr) { @@ -193,7 +192,7 @@ bool AudioEngineImpl::init() return ret; } -int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume, AudioProfile* profile) +int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume) { if (s_ALDevice == nullptr) { return AudioEngine::INVAILD_AUDIO_ID; @@ -233,11 +232,6 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume _alSourceUsed[alSource] = true; - if (profile) { - profile->lastPlayTime = utils::gettime(); - profile->audioIDs.push_back(nextAudioID); - } - if (_lazyInitLoop) { _lazyInitLoop = false; @@ -254,7 +248,7 @@ void AudioEngineImpl::_play2d(AudioCache *cache, int audioID) auto playerIt = _audioPlayers.find(audioID); if (playerIt != _audioPlayers.end()) { if (playerIt->second.play2d(cache)) { - _audioEngine->_audioInfos[audioID].state = AudioEngine::AudioState::PLAYING; + AudioEngine::_audioInfos[audioID].state = AudioEngine::AudioState::PLAYING; } else{ _threadMutex.lock(); @@ -455,7 +449,7 @@ void AudioEngineImpl::update(float dt) if (playerIt != _audioPlayers.end()) { _alSourceUsed[playerIt->second._alSource] = false; _audioPlayers.erase(audioID); - _audioEngine->remove(audioID); + AudioEngine::remove(audioID); } } size_t removeCacheCount = _removeCaches.size(); @@ -478,12 +472,12 @@ void AudioEngineImpl::update(float dt) if (player._ready && sourceState == AL_STOPPED) { _alSourceUsed[player._alSource] = false; - auto& audioInfo = _audioEngine->_audioInfos[audioID]; + auto& audioInfo = AudioEngine::_audioInfos[audioID]; if (player._finishCallbak) { player._finishCallbak(audioID, *audioInfo.filePath); } - _audioEngine->remove(audioID); + AudioEngine::remove(audioID); it = _audioPlayers.erase(it); } From 0cfb8c6469f75202bec2c14801aa68963901a97c Mon Sep 17 00:00:00 2001 From: DENPEN Date: Fri, 5 Sep 2014 20:49:15 +0900 Subject: [PATCH 07/32] fix ScrollView bug I Fixed a bug that scroll view hidden picks up the touch events. --- extensions/GUI/CCScrollView/CCScrollView.cpp | 15 ++++++++++++++- extensions/GUI/CCScrollView/CCScrollView.h | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/extensions/GUI/CCScrollView/CCScrollView.cpp b/extensions/GUI/CCScrollView/CCScrollView.cpp index e97d2672be..68181bd899 100644 --- a/extensions/GUI/CCScrollView/CCScrollView.cpp +++ b/extensions/GUI/CCScrollView/CCScrollView.cpp @@ -343,6 +343,19 @@ void ScrollView::setContainer(Node * pContainer) this->setViewSize(this->_viewSize); } +bool ScrollView::hasVisibleParents() const +{ + auto parent = this->getParent(); + for( auto c = parent; c != nullptr; c = c->getParent() ) + { + if( !c->isVisible() ) + { + return false; + } + } + return true; +} + void ScrollView::relocateContainer(bool animated) { Vec2 oldPoint, min, max; @@ -625,7 +638,7 @@ void ScrollView::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t bool ScrollView::onTouchBegan(Touch* touch, Event* event) { - if (!this->isVisible()) + if (!this->isVisible() || !this->hasVisibleParents()) { return false; } diff --git a/extensions/GUI/CCScrollView/CCScrollView.h b/extensions/GUI/CCScrollView/CCScrollView.h index 72695df5c7..36f94d39f8 100644 --- a/extensions/GUI/CCScrollView/CCScrollView.h +++ b/extensions/GUI/CCScrollView/CCScrollView.h @@ -256,6 +256,8 @@ public: * CCActionTweenDelegate */ void updateTweenAction(float value, const std::string& key); + + bool hasVisibleParents() const; protected: /** * Relocates the container at the proper offset, in bounds of max/min offsets. From 66070868f754ec4f7cdd8ec91aacdfdbcc4223fc Mon Sep 17 00:00:00 2001 From: sunzhuoshi Date: Mon, 8 Sep 2014 20:58:59 +0800 Subject: [PATCH 08/32] Added Math SSE implementation on x86 --- cocos/math/Mat4.cpp | 38 ++++++++-- cocos/math/Mat4.h | 11 +++ cocos/math/MathUtil.h | 25 +++++- cocos/math/MathUtilSSE.inl | 152 +++++++++++++++++++++++++++++++++++++ cocos/math/Vec4.h | 18 ++++- 5 files changed, 235 insertions(+), 9 deletions(-) create mode 100644 cocos/math/MathUtilSSE.inl diff --git a/cocos/math/Mat4.cpp b/cocos/math/Mat4.cpp index ff598d3da8..1e3dc5a972 100644 --- a/cocos/math/Mat4.cpp +++ b/cocos/math/Mat4.cpp @@ -414,8 +414,11 @@ void Mat4::add(float scalar) void Mat4::add(float scalar, Mat4* dst) { GP_ASSERT(dst); - +#ifdef __SSE__ + MathUtil::addMatrix(col, scalar, dst->col); +#else MathUtil::addMatrix(m, scalar, dst->m); +#endif } void Mat4::add(const Mat4& mat) @@ -426,8 +429,11 @@ void Mat4::add(const Mat4& mat) void Mat4::add(const Mat4& m1, const Mat4& m2, Mat4* dst) { GP_ASSERT(dst); - +#ifdef __SSE__ + MathUtil::addMatrix(m1.col, m2.col, dst->col); +#else MathUtil::addMatrix(m1.m, m2.m, dst->m); +#endif } bool Mat4::decompose(Vec3* scale, Quaternion* rotation, Vec3* translation) const @@ -700,8 +706,11 @@ void Mat4::multiply(float scalar, Mat4* dst) const void Mat4::multiply(const Mat4& m, float scalar, Mat4* dst) { GP_ASSERT(dst); - +#ifdef __SSE__ + MathUtil::multiplyMatrix(m.col, scalar, dst->col); +#else MathUtil::multiplyMatrix(m.m, scalar, dst->m); +#endif } void Mat4::multiply(const Mat4& mat) @@ -712,13 +721,20 @@ void Mat4::multiply(const Mat4& mat) void Mat4::multiply(const Mat4& m1, const Mat4& m2, Mat4* dst) { GP_ASSERT(dst); - +#ifdef __SSE__ + MathUtil::multiplyMatrix(m1.col, m2.col, dst->col); +#else MathUtil::multiplyMatrix(m1.m, m2.m, dst->m); +#endif } void Mat4::negate() { +#ifdef __SSE__ + MathUtil::negateMatrix(col, col); +#else MathUtil::negateMatrix(m, m); +#endif } Mat4 Mat4::getNegated() const @@ -870,8 +886,11 @@ void Mat4::subtract(const Mat4& mat) void Mat4::subtract(const Mat4& m1, const Mat4& m2, Mat4* dst) { GP_ASSERT(dst); - +#ifdef __SSE__ + MathUtil::subtractMatrix(m1.col, m2.col, dst->col); +#else MathUtil::subtractMatrix(m1.m, m2.m, dst->m); +#endif } void Mat4::transformPoint(Vec3* point) const @@ -912,8 +931,11 @@ void Mat4::transformVector(Vec4* vector) const void Mat4::transformVector(const Vec4& vector, Vec4* dst) const { GP_ASSERT(dst); - +#ifdef __SSE__ + MathUtil::transformVec4(col, vector.v, dst->v); +#else MathUtil::transformVec4(m, (const float*) &vector, (float*)dst); +#endif } void Mat4::translate(float x, float y, float z) @@ -940,7 +962,11 @@ void Mat4::translate(const Vec3& t, Mat4* dst) const void Mat4::transpose() { +#ifdef __SSE__ + MathUtil::transposeMatrix(col, col); +#else MathUtil::transposeMatrix(m, m); +#endif } Mat4 Mat4::getTransposed() const diff --git a/cocos/math/Mat4.h b/cocos/math/Mat4.h index 53b4b64da1..7616221943 100644 --- a/cocos/math/Mat4.h +++ b/cocos/math/Mat4.h @@ -24,6 +24,10 @@ #include "math/Vec3.h" #include "math/Vec4.h" +#ifdef __SSE__ +#include +#endif + NS_CC_MATH_BEGIN //class Plane; @@ -77,7 +81,14 @@ public: /** * Stores the columns of this 4x4 matrix. * */ +#ifdef __SSE__ + union { + __m128 col[4]; + float m[16]; + }; +#else float m[16]; +#endif /** * Constructs a matrix initialized to the identity matrix: diff --git a/cocos/math/MathUtil.h b/cocos/math/MathUtil.h index da5fe3c830..acf6ab0b42 100644 --- a/cocos/math/MathUtil.h +++ b/cocos/math/MathUtil.h @@ -21,6 +21,10 @@ #ifndef MATHUTIL_H_ #define MATHUTIL_H_ +#ifdef __SSE__ +#include +#endif + #include "CCMathBase.h" NS_CC_MATH_BEGIN @@ -67,7 +71,23 @@ public: static void smooth(float* x, float target, float elapsedTime, float riseTime, float fallTime); private: - +#ifdef __SSE__ + inline static void addMatrix(const __m128 m[4], float scalar, __m128 dst[4]); + + inline static void addMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]); + + inline static void subtractMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]); + + inline static void multiplyMatrix(const __m128 m[4], float scalar, __m128 dst[4]); + + inline static void multiplyMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]); + + inline static void negateMatrix(const __m128 m[4], __m128 dst[4]); + + inline static void transposeMatrix(const __m128 m[4], __m128 dst[4]); + + inline static void transformVec4(const __m128 m[4], const __m128& v, __m128& dst); +#endif inline static void addMatrix(const float* m, float scalar, float* dst); inline static void addMatrix(const float* m1, const float* m2, float* dst); @@ -99,6 +119,9 @@ NS_CC_MATH_END #include "MathUtilNeon.inl" #else #include "MathUtil.inl" +#if defined(__SSE__) +#include "MathUtilSSE.inl" +#endif #endif #endif diff --git a/cocos/math/MathUtilSSE.inl b/cocos/math/MathUtilSSE.inl new file mode 100644 index 0000000000..b701bb51ca --- /dev/null +++ b/cocos/math/MathUtilSSE.inl @@ -0,0 +1,152 @@ +NS_CC_MATH_BEGIN + +inline void MathUtil::addMatrix(const __m128 m[4], float scalar, __m128 dst[4]) +{ + __m128 s = _mm_set1_ps(scalar); + dst[0] = _mm_add_ps(m[0], s); + dst[1] = _mm_add_ps(m[1], s); + dst[2] = _mm_add_ps(m[2], s); + dst[3] = _mm_add_ps(m[3], s); +} + +inline void MathUtil::addMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]) +{ + dst[0] = _mm_add_ps(m1[0], m2[0]); + dst[1] = _mm_add_ps(m1[1], m2[1]); + dst[2] = _mm_add_ps(m1[2], m2[2]); + dst[3] = _mm_add_ps(m1[3], m2[3]); +} + +inline void MathUtil::subtractMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]) +{ + dst[0] = _mm_sub_ps(m1[0], m2[0]); + dst[1] = _mm_sub_ps(m1[1], m2[1]); + dst[2] = _mm_sub_ps(m1[2], m2[2]); + dst[3] = _mm_sub_ps(m1[3], m2[3]); +} + +inline void MathUtil::multiplyMatrix(const __m128 m[4], float scalar, __m128 dst[4]) +{ + __m128 s = _mm_set1_ps(scalar); + dst[0] = _mm_mul_ps(m[0], s); + dst[1] = _mm_mul_ps(m[1], s); + dst[2] = _mm_mul_ps(m[2], s); + dst[3] = _mm_mul_ps(m[3], s); +} + +inline void MathUtil::multiplyMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]) +{ + __m128 dst0, dst1, dst2, dst3; + { + __m128 e0 = _mm_shuffle_ps(m2[0], m2[0], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(m2[0], m2[0], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(m2[0], m2[0], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(m2[0], m2[0], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 v0 = _mm_mul_ps(m1[0], e0); + __m128 v1 = _mm_mul_ps(m1[1], e1); + __m128 v2 = _mm_mul_ps(m1[2], e2); + __m128 v3 = _mm_mul_ps(m1[3], e3); + + __m128 a0 = _mm_add_ps(v0, v1); + __m128 a1 = _mm_add_ps(v2, v3); + __m128 a2 = _mm_add_ps(a0, a1); + + dst0 = a2; + } + + { + __m128 e0 = _mm_shuffle_ps(m2[1], m2[1], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(m2[1], m2[1], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(m2[1], m2[1], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(m2[1], m2[1], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 v0 = _mm_mul_ps(m1[0], e0); + __m128 v1 = _mm_mul_ps(m1[1], e1); + __m128 v2 = _mm_mul_ps(m1[2], e2); + __m128 v3 = _mm_mul_ps(m1[3], e3); + + __m128 a0 = _mm_add_ps(v0, v1); + __m128 a1 = _mm_add_ps(v2, v3); + __m128 a2 = _mm_add_ps(a0, a1); + + dst1 = a2; + } + + { + __m128 e0 = _mm_shuffle_ps(m2[2], m2[2], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(m2[2], m2[2], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(m2[2], m2[2], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(m2[2], m2[2], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 v0 = _mm_mul_ps(m1[0], e0); + __m128 v1 = _mm_mul_ps(m1[1], e1); + __m128 v2 = _mm_mul_ps(m1[2], e2); + __m128 v3 = _mm_mul_ps(m1[3], e3); + + __m128 a0 = _mm_add_ps(v0, v1); + __m128 a1 = _mm_add_ps(v2, v3); + __m128 a2 = _mm_add_ps(a0, a1); + + dst2 = a2; + } + + { + __m128 e0 = _mm_shuffle_ps(m2[3], m2[3], _MM_SHUFFLE(0, 0, 0, 0)); + __m128 e1 = _mm_shuffle_ps(m2[3], m2[3], _MM_SHUFFLE(1, 1, 1, 1)); + __m128 e2 = _mm_shuffle_ps(m2[3], m2[3], _MM_SHUFFLE(2, 2, 2, 2)); + __m128 e3 = _mm_shuffle_ps(m2[3], m2[3], _MM_SHUFFLE(3, 3, 3, 3)); + + __m128 v0 = _mm_mul_ps(m1[0], e0); + __m128 v1 = _mm_mul_ps(m1[1], e1); + __m128 v2 = _mm_mul_ps(m1[2], e2); + __m128 v3 = _mm_mul_ps(m1[3], e3); + + __m128 a0 = _mm_add_ps(v0, v1); + __m128 a1 = _mm_add_ps(v2, v3); + __m128 a2 = _mm_add_ps(a0, a1); + + dst3 = a2; + } + dst[0] = dst0; + dst[1] = dst1; + dst[2] = dst2; + dst[3] = dst3; +} + +inline void MathUtil::negateMatrix(const __m128 m[4], __m128 dst[4]) +{ + __m128 z = _mm_setzero_ps(); + dst[0] = _mm_sub_ps(z, m[0]); + dst[1] = _mm_sub_ps(z, m[1]); + dst[2] = _mm_sub_ps(z, m[2]); + dst[3] = _mm_sub_ps(z, m[3]); +} + +inline void MathUtil::transposeMatrix(const __m128 m[4], __m128 dst[4]) +{ + __m128 tmp0 = _mm_shuffle_ps(m[0], m[1], 0x44); + __m128 tmp2 = _mm_shuffle_ps(m[0], m[1], 0xEE); + __m128 tmp1 = _mm_shuffle_ps(m[2], m[3], 0x44); + __m128 tmp3 = _mm_shuffle_ps(m[2], m[3], 0xEE); + + dst[0] = _mm_shuffle_ps(tmp0, tmp1, 0x88); + dst[1] = _mm_shuffle_ps(tmp0, tmp1, 0xDD); + dst[2] = _mm_shuffle_ps(tmp2, tmp3, 0x88); + dst[3] = _mm_shuffle_ps(tmp2, tmp3, 0xDD); +} + +inline void MathUtil::transformVec4(const __m128 m[4], const __m128& v, __m128& dst) +{ + __m128 col1 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 col2 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); + __m128 col3 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2)); + __m128 col4 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3)); + + dst = _mm_add_ps( + _mm_add_ps(_mm_mul_ps(m[0], col1), _mm_mul_ps(m[1], col2)), + _mm_add_ps(_mm_mul_ps(m[2], col3), _mm_mul_ps(m[3], col4)) + ); +} + +NS_CC_MATH_END diff --git a/cocos/math/Vec4.h b/cocos/math/Vec4.h index d6399fb339..712f60fd4f 100644 --- a/cocos/math/Vec4.h +++ b/cocos/math/Vec4.h @@ -21,6 +21,10 @@ #ifndef MATH_VEC4_H #define MATH_VEC4_H +#ifdef __SSE__ +#include +#endif + #include "math/CCMathBase.h" NS_CC_MATH_BEGIN @@ -33,7 +37,17 @@ class Mat4; class CC_DLL Vec4 { public: - +#ifdef __SSE__ + union { + struct { + float x; + float y; + float z; + float w; + }; + __m128 v; + }; +#else /** * The x-coordinate. */ @@ -53,7 +67,7 @@ public: * The w-coordinate. */ float w; - +#endif /** * Constructs a new vector initialized to all zeros. */ From 66979891746e8cef3b03bf17bee545e827bd3670 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Tue, 9 Sep 2014 10:48:07 +0800 Subject: [PATCH 09/32] Update test case of AudioEngine. --- .../Classes/NewAudioEngineTest/NewAudioEngineTest.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp b/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp index 00179be6e2..ae82703326 100644 --- a/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp +++ b/tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp @@ -502,16 +502,15 @@ bool PlaySimultaneouslyTest::init() { auto ret = AudioEngineTestDemo::init(); - char text[30]; + char text[36]; int tmp = 81; for(int index = 0; index < TEST_COUNT; ++index){ - sprintf(text,"SoundEffectsFX009/FX0%d.mp3",tmp + index); - //sprintf(text,"audio2/1 (%d).mp3",1 + index); + sprintf(text,"audio/SoundEffectsFX009/FX0%d.mp3",tmp + index); _files[index] = text; } _playingcount = 0; - auto playItem = TextButton::create("play-10-audio", [&](TextButton* button){ + auto playItem = TextButton::create("play-simultaneously", [&](TextButton* button){ int audioId; _playingcount = 0; button->setEnabled(false); @@ -668,7 +667,7 @@ bool InvalidAudioFileTest::init() this->addChild(playItem); auto playItem2 = TextButton::create("play not-existent file", [&](TextButton* button){ - AudioEngine::play2d("NotExistFile.mp3"); + AudioEngine::play2d("not-existent file.mp3"); }); playItem2->setNormalizedPosition(Vec2(0.5f, 0.4f)); this->addChild(playItem2); @@ -696,7 +695,7 @@ bool LargeAudioFileTest::init() auto ret = AudioEngineTestDemo::init(); auto playItem = TextButton::create("play large audio file", [&](TextButton* button){ - AudioEngine::play2d("NotExistFile.mp3"); + AudioEngine::play2d("audio/Chee Lai(Arise).mp3"); }); playItem->setNormalizedPosition(Vec2::ANCHOR_MIDDLE); this->addChild(playItem); From f2b7bd62d599ac3de354e237fc3d5e380f30a8af Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Tue, 9 Sep 2014 11:41:17 +0800 Subject: [PATCH 10/32] update Xcode project for audio engine --- build/cocos2d_libs.xcodeproj/project.pbxproj | 32 +++++++++++++++++++ build/cocos2d_tests.xcodeproj/project.pbxproj | 18 +++++++++++ cocos/audio/AudioEngine.cpp | 2 +- cocos/audio/include/AudioEngine.h | 17 +++++----- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index 6f0291e781..ea909f23eb 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -1377,6 +1377,14 @@ 299CF1FC19A434BC00C378C1 /* ccRandom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299CF1F919A434BC00C378C1 /* ccRandom.cpp */; }; 299CF1FD19A434BC00C378C1 /* ccRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 299CF1FA19A434BC00C378C1 /* ccRandom.h */; }; 299CF1FE19A434BC00C378C1 /* ccRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 299CF1FA19A434BC00C378C1 /* ccRandom.h */; }; + 3E2BDABE19BEA28E0055CDCD /* AudioEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDABD19BEA28E0055CDCD /* AudioEngine.h */; }; + 3E2BDAC519BEA29F0055CDCD /* AudioCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDABF19BEA29F0055CDCD /* AudioCache.h */; }; + 3E2BDAC619BEA29F0055CDCD /* AudioCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDAC019BEA29F0055CDCD /* AudioCache.mm */; }; + 3E2BDAC719BEA29F0055CDCD /* AudioEngine-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDAC119BEA29F0055CDCD /* AudioEngine-inl.h */; }; + 3E2BDAC819BEA29F0055CDCD /* AudioEngine-inl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDAC219BEA29F0055CDCD /* AudioEngine-inl.mm */; }; + 3E2BDAC919BEA29F0055CDCD /* AudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDAC319BEA29F0055CDCD /* AudioPlayer.h */; }; + 3E2BDACA19BEA29F0055CDCD /* AudioPlayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDAC419BEA29F0055CDCD /* AudioPlayer.mm */; }; + 3E2BDACC19BEA2AB0055CDCD /* AudioEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDACB19BEA2AB0055CDCD /* AudioEngine.cpp */; }; 3E6176681960F89B00DE83F5 /* CCController-iOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176551960F89B00DE83F5 /* CCController-iOS.mm */; }; 3E6176691960F89B00DE83F5 /* CCController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176561960F89B00DE83F5 /* CCController.h */; }; 3E6176741960F89B00DE83F5 /* CCEventController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176611960F89B00DE83F5 /* CCEventController.cpp */; }; @@ -2366,6 +2374,14 @@ 37936A3C1869B76800E974DD /* reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reader.h; sourceTree = ""; }; 37936A3D1869B76800E974DD /* stringbuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stringbuffer.h; sourceTree = ""; }; 37936A3E1869B76800E974DD /* writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = writer.h; sourceTree = ""; }; + 3E2BDABD19BEA28E0055CDCD /* AudioEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioEngine.h; sourceTree = ""; }; + 3E2BDABF19BEA29F0055CDCD /* AudioCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioCache.h; sourceTree = ""; }; + 3E2BDAC019BEA29F0055CDCD /* AudioCache.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AudioCache.mm; sourceTree = ""; }; + 3E2BDAC119BEA29F0055CDCD /* AudioEngine-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AudioEngine-inl.h"; sourceTree = ""; }; + 3E2BDAC219BEA29F0055CDCD /* AudioEngine-inl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "AudioEngine-inl.mm"; sourceTree = ""; }; + 3E2BDAC319BEA29F0055CDCD /* AudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioPlayer.h; sourceTree = ""; }; + 3E2BDAC419BEA29F0055CDCD /* AudioPlayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AudioPlayer.mm; sourceTree = ""; }; + 3E2BDACB19BEA2AB0055CDCD /* AudioEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioEngine.cpp; sourceTree = ""; }; 3E6176551960F89B00DE83F5 /* CCController-iOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "CCController-iOS.mm"; path = "../base/CCController-iOS.mm"; sourceTree = ""; }; 3E6176561960F89B00DE83F5 /* CCController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCController.h; path = ../base/CCController.h; sourceTree = ""; }; 3E6176611960F89B00DE83F5 /* CCEventController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCEventController.cpp; path = ../base/CCEventController.cpp; sourceTree = ""; }; @@ -4105,6 +4121,7 @@ 46A15FD01807A56F005B8026 /* audio */ = { isa = PBXGroup; children = ( + 3E2BDACB19BEA2AB0055CDCD /* AudioEngine.cpp */, 46A15FE01807A56F005B8026 /* include */, 46A15FE31807A56F005B8026 /* ios */, 46A15FF31807A56F005B8026 /* mac */, @@ -4116,6 +4133,7 @@ 46A15FE01807A56F005B8026 /* include */ = { isa = PBXGroup; children = ( + 3E2BDABD19BEA28E0055CDCD /* AudioEngine.h */, 46A15FE11807A56F005B8026 /* Export.h */, 46A15FE21807A56F005B8026 /* SimpleAudioEngine.h */, ); @@ -4125,6 +4143,12 @@ 46A15FE31807A56F005B8026 /* ios */ = { isa = PBXGroup; children = ( + 3E2BDABF19BEA29F0055CDCD /* AudioCache.h */, + 3E2BDAC019BEA29F0055CDCD /* AudioCache.mm */, + 3E2BDAC119BEA29F0055CDCD /* AudioEngine-inl.h */, + 3E2BDAC219BEA29F0055CDCD /* AudioEngine-inl.mm */, + 3E2BDAC319BEA29F0055CDCD /* AudioPlayer.h */, + 3E2BDAC419BEA29F0055CDCD /* AudioPlayer.mm */, 46A15FE41807A56F005B8026 /* CDAudioManager.h */, 46A15FE51807A56F005B8026 /* CDAudioManager.m */, 46A15FE61807A56F005B8026 /* CDConfig.h */, @@ -5545,6 +5569,7 @@ B37510861823ACA100B3BA6A /* CCPhysicsWorldInfo_chipmunk.h in Headers */, 15AE1BC019AADFF000C27E9E /* WebSocket.h in Headers */, 1A570080180BC5A10088DEC7 /* CCActionInterval.h in Headers */, + 3E2BDABE19BEA28E0055CDCD /* AudioEngine.h in Headers */, 15AE192D19AAD35100C27E9E /* CCActionFrame.h in Headers */, 15AE192F19AAD35100C27E9E /* CCActionFrameEasing.h in Headers */, 1A570084180BC5A10088DEC7 /* CCActionManager.h in Headers */, @@ -5553,6 +5578,7 @@ 1A570088180BC5A10088DEC7 /* CCActionPageTurn3D.h in Headers */, 15AE1B9319AADA9A00C27E9E /* UIHelper.h in Headers */, 50ABBD9E1925AB4100A911A9 /* ccGLStateCache.h in Headers */, + 3E2BDAC719BEA29F0055CDCD /* AudioEngine-inl.h in Headers */, 15AE1B9619AADA9A00C27E9E /* CocosGUI.h in Headers */, 1A57008C180BC5A10088DEC7 /* CCActionProgressTimer.h in Headers */, 1A570090180BC5A10088DEC7 /* CCActionTiledGrid.h in Headers */, @@ -5578,6 +5604,7 @@ 1A570111180BC8EE0088DEC7 /* CCDrawingPrimitives.h in Headers */, 50ABBE381925AB6F00A911A9 /* CCConsole.h in Headers */, 50ABBE8A1925AB6F00A911A9 /* CCMap.h in Headers */, + 3E2BDAC519BEA29F0055CDCD /* AudioCache.h in Headers */, 503DD8E61926736A00CD74DD /* CCEAGLView.h in Headers */, 50ABBE4C1925AB6F00A911A9 /* CCEventAcceleration.h in Headers */, 50ABBD571925AB0000A911A9 /* TransformUtils.h in Headers */, @@ -5608,6 +5635,7 @@ 15AE1AAD19AAD40300C27E9E /* b2WorldCallbacks.h in Headers */, 1A5701A4180BCB590088DEC7 /* CCFontAtlas.h in Headers */, 15AE1C0219AAE01E00C27E9E /* CCScrollView.h in Headers */, + 3E2BDAC919BEA29F0055CDCD /* AudioPlayer.h in Headers */, 15AE1AFF19AAD42500C27E9E /* cpPinJoint.h in Headers */, 1A5701A8180BCB590088DEC7 /* CCFontAtlasCache.h in Headers */, 15AE1A4C19AAD3D500C27E9E /* b2EdgeShape.h in Headers */, @@ -6572,10 +6600,12 @@ B37510851823ACA100B3BA6A /* CCPhysicsWorldInfo_chipmunk.cpp in Sources */, 15AE1BB919AADFF000C27E9E /* HttpClient.cpp in Sources */, 15AE1B4319AAD43700C27E9E /* cpSpaceHash.c in Sources */, + 3E2BDACC19BEA2AB0055CDCD /* AudioEngine.cpp in Sources */, 15AE1A1D19AAD3A700C27E9E /* SlotData.cpp in Sources */, 50ABBD551925AB0000A911A9 /* TransformUtils.cpp in Sources */, 292DB14419B4574100A80320 /* UIEditBoxImplAndroid.cpp in Sources */, 15AE193619AAD35100C27E9E /* CCArmature.cpp in Sources */, + 3E2BDACA19BEA29F0055CDCD /* AudioPlayer.mm in Sources */, 1A57007A180BC5A10088DEC7 /* CCActionInstant.cpp in Sources */, 15AE1AC419AAD40300C27E9E /* b2FrictionJoint.cpp in Sources */, 15AE1BEC19AAE01E00C27E9E /* CCControlColourPicker.cpp in Sources */, @@ -6714,6 +6744,7 @@ 15AE1A3A19AAD3D500C27E9E /* b2BroadPhase.cpp in Sources */, 15AE19B619AAD39700C27E9E /* TextBMFontReader.cpp in Sources */, 15AE1BFD19AAE01E00C27E9E /* CCInvocation.cpp in Sources */, + 3E2BDAC619BEA29F0055CDCD /* AudioCache.mm in Sources */, B24AA98A195A675C007B4522 /* CCFastTMXTiledMap.cpp in Sources */, 15AE18CE19AAD33D00C27E9E /* CCNodeLoader.cpp in Sources */, 29394CF719B01DBA00D2DE1A /* UIWebViewImpl_iOS.mm in Sources */, @@ -6747,6 +6778,7 @@ 50ABBE321925AB6F00A911A9 /* CCConfiguration.cpp in Sources */, 15AE1A9F19AAD40300C27E9E /* b2Timer.cpp in Sources */, 15AE1AD419AAD40300C27E9E /* b2WeldJoint.cpp in Sources */, + 3E2BDAC819BEA29F0055CDCD /* AudioEngine-inl.mm in Sources */, 1A5702C9180BCE370088DEC7 /* CCTextFieldTTF.cpp in Sources */, 15AE1A0519AAD3A700C27E9E /* Bone.cpp in Sources */, 15AE1B3D19AAD43700C27E9E /* cpCollision.c in Sources */, diff --git a/build/cocos2d_tests.xcodeproj/project.pbxproj b/build/cocos2d_tests.xcodeproj/project.pbxproj index dec67dde2c..1bfef6f5d6 100644 --- a/build/cocos2d_tests.xcodeproj/project.pbxproj +++ b/build/cocos2d_tests.xcodeproj/project.pbxproj @@ -871,6 +871,8 @@ 38FA2E74194AEBE100FF2BE4 /* ActionTimelineTestScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 38FA2E71194AEBE100FF2BE4 /* ActionTimelineTestScene.cpp */; }; 38FA2E76194AECF800FF2BE4 /* ActionTimeline in Resources */ = {isa = PBXBuildFile; fileRef = 38FA2E75194AECF800FF2BE4 /* ActionTimeline */; }; 38FA2E77194AECF800FF2BE4 /* ActionTimeline in Resources */ = {isa = PBXBuildFile; fileRef = 38FA2E75194AECF800FF2BE4 /* ActionTimeline */; }; + 3E2BDAD019BEA3410055CDCD /* NewAudioEngineTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDACE19BEA3410055CDCD /* NewAudioEngineTest.cpp */; }; + 3E2BDAD219BEA3E20055CDCD /* audio in Resources */ = {isa = PBXBuildFile; fileRef = 3E2BDAD119BEA3E20055CDCD /* audio */; }; 3E6177221960FAED00DE83F5 /* libcocos2d iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 46A15FBE1807A4F9005B8026 /* libcocos2d iOS.a */; }; 3E6177241960FAED00DE83F5 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D60AE43317F7FFE100757E4B /* CoreMotion.framework */; }; 3E6177251960FAED00DE83F5 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 15C6482E165F399D007D4F18 /* libz.dylib */; }; @@ -2892,6 +2894,9 @@ 38FA2E71194AEBE100FF2BE4 /* ActionTimelineTestScene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActionTimelineTestScene.cpp; sourceTree = ""; }; 38FA2E72194AEBE100FF2BE4 /* ActionTimelineTestScene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActionTimelineTestScene.h; sourceTree = ""; }; 38FA2E75194AECF800FF2BE4 /* ActionTimeline */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ActionTimeline; path = "../tests/cpp-tests/Resources/ActionTimeline"; sourceTree = ""; }; + 3E2BDACE19BEA3410055CDCD /* NewAudioEngineTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewAudioEngineTest.cpp; sourceTree = ""; }; + 3E2BDACF19BEA3410055CDCD /* NewAudioEngineTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewAudioEngineTest.h; sourceTree = ""; }; + 3E2BDAD119BEA3E20055CDCD /* audio */ = {isa = PBXFileReference; lastKnownFileType = folder; name = audio; path = "../tests/cpp-tests/Resources/audio"; sourceTree = ""; }; 3E6176B71960FA6300DE83F5 /* AppDelegate.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AppDelegate.cpp; sourceTree = ""; }; 3E6176B81960FA6300DE83F5 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 3E6176B91960FA6300DE83F5 /* AppMacros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppMacros.h; sourceTree = ""; }; @@ -5422,6 +5427,7 @@ 1AC3592418CECF0A00F37B72 /* Classes */ = { isa = PBXGroup; children = ( + 3E2BDACD19BEA3410055CDCD /* NewAudioEngineTest */, 3E9E75CB199324A8005B7047 /* Camera3DTest */, 1AC3592818CECF0A00F37B72 /* ActionManagerTest */, 1AC3592B18CECF0A00F37B72 /* ActionsEaseTest */, @@ -6445,6 +6451,7 @@ 1AC35CA818CED83500F37B72 /* Resources */ = { isa = PBXGroup; children = ( + 3E2BDAD119BEA3E20055CDCD /* audio */, 38FA2E75194AECF800FF2BE4 /* ActionTimeline */, B2507B6A192589AF00FA4972 /* Shaders3D */, 3E92EA841921A7720094CD21 /* Sprite3DTest */, @@ -7026,6 +7033,15 @@ path = CocoStudioActionTimelineTest; sourceTree = ""; }; + 3E2BDACD19BEA3410055CDCD /* NewAudioEngineTest */ = { + isa = PBXGroup; + children = ( + 3E2BDACE19BEA3410055CDCD /* NewAudioEngineTest.cpp */, + 3E2BDACF19BEA3410055CDCD /* NewAudioEngineTest.h */, + ); + path = NewAudioEngineTest; + sourceTree = ""; + }; 3E6176B51960FA6300DE83F5 /* game-controller-test */ = { isa = PBXGroup; children = ( @@ -7814,6 +7830,7 @@ 1AC35CD518CED84500F37B72 /* ccb in Resources */, 1AC35CE118CED84500F37B72 /* configs in Resources */, 1AC35CE918CED84500F37B72 /* extensions in Resources */, + 3E2BDAD219BEA3E20055CDCD /* audio in Resources */, C08689C318D370C90093E810 /* background.caf in Resources */, 1AC35C9518CECF1400F37B72 /* Icon-72.png in Resources */, 1AC35D0B18CED84500F37B72 /* zwoptex in Resources */, @@ -8204,6 +8221,7 @@ 1AC35B4418CECF0C00F37B72 /* Bug-624.cpp in Sources */, 1AC35BF818CECF0C00F37B72 /* SocketIOTest.cpp in Sources */, 1AC35C5018CECF0C00F37B72 /* SpriteTest.cpp in Sources */, + 3E2BDAD019BEA3410055CDCD /* NewAudioEngineTest.cpp in Sources */, 1AC35C0418CECF0C00F37B72 /* FileUtilsTest.cpp in Sources */, 1AC35B5C18CECF0C00F37B72 /* CurlTest.cpp in Sources */, 1AC35C0018CECF0C00F37B72 /* CustomTableViewCell.cpp in Sources */, diff --git a/cocos/audio/AudioEngine.cpp b/cocos/audio/AudioEngine.cpp index daa977063a..98821d46a4 100644 --- a/cocos/audio/AudioEngine.cpp +++ b/cocos/audio/AudioEngine.cpp @@ -364,7 +364,7 @@ AudioEngine::AudioState AudioEngine::getState(int audioID) } log("AudioEngine::getState-->The audio instance %d is non-existent", audioID); - return AudioState::INITIAL; + return AudioState::ERROR; } AudioProfile* AudioEngine::getProfile(int audioID) diff --git a/cocos/audio/include/AudioEngine.h b/cocos/audio/include/AudioEngine.h index 4250239c7a..77da61dba3 100644 --- a/cocos/audio/include/AudioEngine.h +++ b/cocos/audio/include/AudioEngine.h @@ -47,10 +47,6 @@ public: /* minimum delay in between sounds */ double minDelay; - - /*the following property only take effect on 3d audio */ - float minRange; - float maxRange; AudioProfile() : minDelay(0.0) @@ -73,6 +69,7 @@ class EXPORT_DLL AudioEngine public: enum class AudioState { + ERROR = -1, INITIAL, PLAYING, PAUSED @@ -84,7 +81,7 @@ public: static bool lazyInit(); /** - * Release the shared Audio Engine object + * Release related objects @warning It must be called before the application exit */ static void end(); @@ -98,7 +95,7 @@ public: * @param filePath The path of an audio file * @param loop Whether audio instance loop or not * @param volume volume value (range from 0.0 to 1.0) - * @param profile a profile return by createProfile/getProfile function + * @param profile a profile for audio instance * @return an audio ID. It allows you to dynamically change the behavior of an audio instance on the fly. */ static int play2d(const std::string& filePath, bool loop = false, float volume = 1.0f, const AudioProfile *profile = nullptr); @@ -198,12 +195,16 @@ public: */ static void uncacheAll(); - /** Gets the profiles of audio instance. + /** Gets the audio profile by id of audio instance. * @param audioID an audioID returned by the play2d function - * @return the profile of audio instance + * @return the audio profile */ static AudioProfile* getProfile(int audioID); + /** Gets the audio profile by name. + * @param name name of audio profile + * @return the audio profile + */ static AudioProfile* getProfile(const std::string &name); protected: From 3a433b2cd6ae7d469f73100f1aad7750a9e110e1 Mon Sep 17 00:00:00 2001 From: samuele3hu Date: Tue, 9 Sep 2014 16:26:06 +0800 Subject: [PATCH 11/32] Update bindings-generator submodule --- tools/bindings-generator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/bindings-generator b/tools/bindings-generator index c1db553615..a8496d540c 160000 --- a/tools/bindings-generator +++ b/tools/bindings-generator @@ -1 +1 @@ -Subproject commit c1db553615789a1545d495d0d0fd6f620547f99d +Subproject commit a8496d540c174236bec0d5a33457340571699f19 From 3151c54879e27b97fa0d2ef85b7330509ebe4d7b Mon Sep 17 00:00:00 2001 From: samuele3hu Date: Tue, 9 Sep 2014 19:08:01 +0800 Subject: [PATCH 12/32] Update macro define limited --- cocos/math/Mat4.cpp | 16 ++++++++-------- cocos/math/Mat4.h | 4 ++-- cocos/math/MathUtil.h | 4 ++-- cocos/math/MathUtilSSE.inl | 4 ++-- cocos/math/Vec4.h | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cocos/math/Mat4.cpp b/cocos/math/Mat4.cpp index 1e3dc5a972..0062888a87 100644 --- a/cocos/math/Mat4.cpp +++ b/cocos/math/Mat4.cpp @@ -414,7 +414,7 @@ void Mat4::add(float scalar) void Mat4::add(float scalar, Mat4* dst) { GP_ASSERT(dst); -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) MathUtil::addMatrix(col, scalar, dst->col); #else MathUtil::addMatrix(m, scalar, dst->m); @@ -429,7 +429,7 @@ void Mat4::add(const Mat4& mat) void Mat4::add(const Mat4& m1, const Mat4& m2, Mat4* dst) { GP_ASSERT(dst); -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) MathUtil::addMatrix(m1.col, m2.col, dst->col); #else MathUtil::addMatrix(m1.m, m2.m, dst->m); @@ -706,7 +706,7 @@ void Mat4::multiply(float scalar, Mat4* dst) const void Mat4::multiply(const Mat4& m, float scalar, Mat4* dst) { GP_ASSERT(dst); -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) MathUtil::multiplyMatrix(m.col, scalar, dst->col); #else MathUtil::multiplyMatrix(m.m, scalar, dst->m); @@ -721,7 +721,7 @@ void Mat4::multiply(const Mat4& mat) void Mat4::multiply(const Mat4& m1, const Mat4& m2, Mat4* dst) { GP_ASSERT(dst); -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) MathUtil::multiplyMatrix(m1.col, m2.col, dst->col); #else MathUtil::multiplyMatrix(m1.m, m2.m, dst->m); @@ -730,7 +730,7 @@ void Mat4::multiply(const Mat4& m1, const Mat4& m2, Mat4* dst) void Mat4::negate() { -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) MathUtil::negateMatrix(col, col); #else MathUtil::negateMatrix(m, m); @@ -886,7 +886,7 @@ void Mat4::subtract(const Mat4& mat) void Mat4::subtract(const Mat4& m1, const Mat4& m2, Mat4* dst) { GP_ASSERT(dst); -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) MathUtil::subtractMatrix(m1.col, m2.col, dst->col); #else MathUtil::subtractMatrix(m1.m, m2.m, dst->m); @@ -931,7 +931,7 @@ void Mat4::transformVector(Vec4* vector) const void Mat4::transformVector(const Vec4& vector, Vec4* dst) const { GP_ASSERT(dst); -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) MathUtil::transformVec4(col, vector.v, dst->v); #else MathUtil::transformVec4(m, (const float*) &vector, (float*)dst); @@ -962,7 +962,7 @@ void Mat4::translate(const Vec3& t, Mat4* dst) const void Mat4::transpose() { -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) MathUtil::transposeMatrix(col, col); #else MathUtil::transposeMatrix(m, m); diff --git a/cocos/math/Mat4.h b/cocos/math/Mat4.h index 7616221943..3b6438dcd1 100644 --- a/cocos/math/Mat4.h +++ b/cocos/math/Mat4.h @@ -24,7 +24,7 @@ #include "math/Vec3.h" #include "math/Vec4.h" -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) #include #endif @@ -81,7 +81,7 @@ public: /** * Stores the columns of this 4x4 matrix. * */ -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) union { __m128 col[4]; float m[16]; diff --git a/cocos/math/MathUtil.h b/cocos/math/MathUtil.h index acf6ab0b42..ada14e70c0 100644 --- a/cocos/math/MathUtil.h +++ b/cocos/math/MathUtil.h @@ -21,7 +21,7 @@ #ifndef MATHUTIL_H_ #define MATHUTIL_H_ -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) #include #endif @@ -71,7 +71,7 @@ public: static void smooth(float* x, float target, float elapsedTime, float riseTime, float fallTime); private: -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) inline static void addMatrix(const __m128 m[4], float scalar, __m128 dst[4]); inline static void addMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]); diff --git a/cocos/math/MathUtilSSE.inl b/cocos/math/MathUtilSSE.inl index b701bb51ca..e701d2cdbd 100644 --- a/cocos/math/MathUtilSSE.inl +++ b/cocos/math/MathUtilSSE.inl @@ -1,5 +1,5 @@ NS_CC_MATH_BEGIN - +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) inline void MathUtil::addMatrix(const __m128 m[4], float scalar, __m128 dst[4]) { __m128 s = _mm_set1_ps(scalar); @@ -148,5 +148,5 @@ inline void MathUtil::transformVec4(const __m128 m[4], const __m128& v, __m128& _mm_add_ps(_mm_mul_ps(m[2], col3), _mm_mul_ps(m[3], col4)) ); } - +#endif NS_CC_MATH_END diff --git a/cocos/math/Vec4.h b/cocos/math/Vec4.h index 712f60fd4f..cf5f2fe16b 100644 --- a/cocos/math/Vec4.h +++ b/cocos/math/Vec4.h @@ -21,7 +21,7 @@ #ifndef MATH_VEC4_H #define MATH_VEC4_H -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) #include #endif @@ -37,7 +37,7 @@ class Mat4; class CC_DLL Vec4 { public: -#ifdef __SSE__ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) union { struct { float x; From 8c0f8e1eb654c05e5600e6be2ff68a5d914712ca Mon Sep 17 00:00:00 2001 From: samuele3hu Date: Tue, 9 Sep 2014 23:01:37 +0800 Subject: [PATCH 13/32] Reset marco limited to `#ifdef __SSE__` --- cocos/math/Mat4.cpp | 16 ++++++++-------- cocos/math/Mat4.h | 4 ++-- cocos/math/MathUtil.h | 4 ++-- cocos/math/MathUtilSSE.inl | 4 ++-- cocos/math/Vec4.h | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cocos/math/Mat4.cpp b/cocos/math/Mat4.cpp index 0062888a87..1e3dc5a972 100644 --- a/cocos/math/Mat4.cpp +++ b/cocos/math/Mat4.cpp @@ -414,7 +414,7 @@ void Mat4::add(float scalar) void Mat4::add(float scalar, Mat4* dst) { GP_ASSERT(dst); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ MathUtil::addMatrix(col, scalar, dst->col); #else MathUtil::addMatrix(m, scalar, dst->m); @@ -429,7 +429,7 @@ void Mat4::add(const Mat4& mat) void Mat4::add(const Mat4& m1, const Mat4& m2, Mat4* dst) { GP_ASSERT(dst); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ MathUtil::addMatrix(m1.col, m2.col, dst->col); #else MathUtil::addMatrix(m1.m, m2.m, dst->m); @@ -706,7 +706,7 @@ void Mat4::multiply(float scalar, Mat4* dst) const void Mat4::multiply(const Mat4& m, float scalar, Mat4* dst) { GP_ASSERT(dst); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ MathUtil::multiplyMatrix(m.col, scalar, dst->col); #else MathUtil::multiplyMatrix(m.m, scalar, dst->m); @@ -721,7 +721,7 @@ void Mat4::multiply(const Mat4& mat) void Mat4::multiply(const Mat4& m1, const Mat4& m2, Mat4* dst) { GP_ASSERT(dst); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ MathUtil::multiplyMatrix(m1.col, m2.col, dst->col); #else MathUtil::multiplyMatrix(m1.m, m2.m, dst->m); @@ -730,7 +730,7 @@ void Mat4::multiply(const Mat4& m1, const Mat4& m2, Mat4* dst) void Mat4::negate() { -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ MathUtil::negateMatrix(col, col); #else MathUtil::negateMatrix(m, m); @@ -886,7 +886,7 @@ void Mat4::subtract(const Mat4& mat) void Mat4::subtract(const Mat4& m1, const Mat4& m2, Mat4* dst) { GP_ASSERT(dst); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ MathUtil::subtractMatrix(m1.col, m2.col, dst->col); #else MathUtil::subtractMatrix(m1.m, m2.m, dst->m); @@ -931,7 +931,7 @@ void Mat4::transformVector(Vec4* vector) const void Mat4::transformVector(const Vec4& vector, Vec4* dst) const { GP_ASSERT(dst); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ MathUtil::transformVec4(col, vector.v, dst->v); #else MathUtil::transformVec4(m, (const float*) &vector, (float*)dst); @@ -962,7 +962,7 @@ void Mat4::translate(const Vec3& t, Mat4* dst) const void Mat4::transpose() { -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ MathUtil::transposeMatrix(col, col); #else MathUtil::transposeMatrix(m, m); diff --git a/cocos/math/Mat4.h b/cocos/math/Mat4.h index 3b6438dcd1..7616221943 100644 --- a/cocos/math/Mat4.h +++ b/cocos/math/Mat4.h @@ -24,7 +24,7 @@ #include "math/Vec3.h" #include "math/Vec4.h" -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ #include #endif @@ -81,7 +81,7 @@ public: /** * Stores the columns of this 4x4 matrix. * */ -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ union { __m128 col[4]; float m[16]; diff --git a/cocos/math/MathUtil.h b/cocos/math/MathUtil.h index ada14e70c0..acf6ab0b42 100644 --- a/cocos/math/MathUtil.h +++ b/cocos/math/MathUtil.h @@ -21,7 +21,7 @@ #ifndef MATHUTIL_H_ #define MATHUTIL_H_ -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ #include #endif @@ -71,7 +71,7 @@ public: static void smooth(float* x, float target, float elapsedTime, float riseTime, float fallTime); private: -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ inline static void addMatrix(const __m128 m[4], float scalar, __m128 dst[4]); inline static void addMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]); diff --git a/cocos/math/MathUtilSSE.inl b/cocos/math/MathUtilSSE.inl index e701d2cdbd..b701bb51ca 100644 --- a/cocos/math/MathUtilSSE.inl +++ b/cocos/math/MathUtilSSE.inl @@ -1,5 +1,5 @@ NS_CC_MATH_BEGIN -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) + inline void MathUtil::addMatrix(const __m128 m[4], float scalar, __m128 dst[4]) { __m128 s = _mm_set1_ps(scalar); @@ -148,5 +148,5 @@ inline void MathUtil::transformVec4(const __m128 m[4], const __m128& v, __m128& _mm_add_ps(_mm_mul_ps(m[2], col3), _mm_mul_ps(m[3], col4)) ); } -#endif + NS_CC_MATH_END diff --git a/cocos/math/Vec4.h b/cocos/math/Vec4.h index cf5f2fe16b..712f60fd4f 100644 --- a/cocos/math/Vec4.h +++ b/cocos/math/Vec4.h @@ -21,7 +21,7 @@ #ifndef MATH_VEC4_H #define MATH_VEC4_H -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ #include #endif @@ -37,7 +37,7 @@ class Mat4; class CC_DLL Vec4 { public: -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) && defined (__SSE__) +#ifdef __SSE__ union { struct { float x; From daeb51e5480fb3aab150bab605dc2db36de326bd Mon Sep 17 00:00:00 2001 From: samuele3hu Date: Tue, 9 Sep 2014 23:02:06 +0800 Subject: [PATCH 14/32] Update cocos2d.ini --- tools/tolua/cocos2dx.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/tolua/cocos2dx.ini b/tools/tolua/cocos2dx.ini index d6894e123b..c84570383f 100644 --- a/tools/tolua/cocos2dx.ini +++ b/tools/tolua/cocos2dx.ini @@ -11,7 +11,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -D__STRICT_ANSI__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android cocos_flags = -DANDROID From e45a4ff1bd11292d356bb657152b9d7b6a6faab4 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 10 Sep 2014 13:47:17 +0800 Subject: [PATCH 15/32] 1.Fix name of variables. 2.Fix control of volume on android. --- cocos/audio/AudioEngine.cpp | 146 +++++++++++------------- cocos/audio/android/AudioEngine-inl.cpp | 36 +++--- cocos/audio/include/AudioEngine.h | 14 +-- cocos/audio/ios/AudioEngine-inl.mm | 6 +- 4 files changed, 92 insertions(+), 110 deletions(-) diff --git a/cocos/audio/AudioEngine.cpp b/cocos/audio/AudioEngine.cpp index 98821d46a4..d485bd6695 100644 --- a/cocos/audio/AudioEngine.cpp +++ b/cocos/audio/AudioEngine.cpp @@ -41,12 +41,12 @@ const int AudioEngine::INVAILD_AUDIO_ID = -1; const float AudioEngine::TIME_UNKNOWN = -1.0f; //audio file path,audio IDs -std::unordered_map> AudioEngine::_audioIDs; +std::unordered_map> AudioEngine::_audioPathIDMap; //profileName,ProfileManage -std::unordered_map AudioEngine::_profileManages; +std::unordered_map AudioEngine::_audioPathProfileManageMap; int AudioEngine::_maxInstances = kMaxSources; AudioEngine::ProfileManage* AudioEngine::_defaultProfileManage; -std::unordered_map AudioEngine::_audioInfos; +std::unordered_map AudioEngine::_audioIDInfoMap; AudioEngineImpl* AudioEngine::_audioEngineImpl = nullptr; void AudioEngine::end() @@ -76,12 +76,8 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, co int ret = AudioEngine::INVAILD_AUDIO_ID; do { - if (_audioEngineImpl == nullptr) - { - _audioEngineImpl = new (std::nothrow) AudioEngineImpl(); - if(!_audioEngineImpl || !_audioEngineImpl->init() ){ - break; - } + if ( !lazyInit() ){ + break; } if ( !FileUtils::getInstance()->isFileExist(filePath)){ @@ -91,11 +87,11 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, co ProfileManage* manage = _defaultProfileManage; if (profile && profile != &manage->profile){ CC_ASSERT(!profile->name.empty()); - manage = &_profileManages[profile->name]; + manage = &_audioPathProfileManageMap[profile->name]; manage->profile = *profile; } - if (_audioInfos.size() >= _maxInstances) { + if (_audioIDInfoMap.size() >= _maxInstances) { log("Fail to play %s cause by limited max instance of AudioEngine",filePath.c_str()); break; } @@ -124,10 +120,10 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, co ret = _audioEngineImpl->play2d(filePath, loop, volume); if (ret != INVAILD_AUDIO_ID) { - _audioIDs[filePath].push_back(ret); - auto it = _audioIDs.find(filePath); + _audioPathIDMap[filePath].push_back(ret); + auto it = _audioPathIDMap.find(filePath); - auto& audioRef = _audioInfos[ret]; + auto& audioRef = _audioIDInfoMap[ret]; audioRef.volume = volume; audioRef.loop = loop; audioRef.is3dAudio = false; @@ -146,8 +142,8 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, co void AudioEngine::setLoop(int audioID, bool loop) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end() && it->second.loop != loop){ + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end() && it->second.loop != loop){ _audioEngineImpl->setLoop(audioID, loop); it->second.loop = loop; } @@ -155,8 +151,8 @@ void AudioEngine::setLoop(int audioID, bool loop) void AudioEngine::setVolume(int audioID, float volume) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end()){ + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end() && it->second.volume != volume){ if (volume < 0.0f) { volume = 0.0f; } @@ -170,8 +166,8 @@ void AudioEngine::setVolume(int audioID, float volume) void AudioEngine::pause(int audioID) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end() && it->second.state == AudioState::PLAYING){ + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end() && it->second.state == AudioState::PLAYING){ _audioEngineImpl->pause(audioID); it->second.state = AudioState::PAUSED; } @@ -179,8 +175,8 @@ void AudioEngine::pause(int audioID) void AudioEngine::pauseAll() { - auto itEnd = _audioInfos.end(); - for (auto it = _audioInfos.begin(); it != itEnd; ++it) + auto itEnd = _audioIDInfoMap.end(); + for (auto it = _audioIDInfoMap.begin(); it != itEnd; ++it) { if (it->second.state == AudioState::PLAYING) { @@ -192,8 +188,8 @@ void AudioEngine::pauseAll() void AudioEngine::resume(int audioID) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end() && it->second.state == AudioState::PAUSED){ + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end() && it->second.state == AudioState::PAUSED){ _audioEngineImpl->resume(audioID); it->second.state = AudioState::PLAYING; } @@ -201,8 +197,8 @@ void AudioEngine::resume(int audioID) void AudioEngine::resumeAll() { - auto itEnd = _audioInfos.end(); - for (auto it = _audioInfos.begin(); it != itEnd; ++it) + auto itEnd = _audioIDInfoMap.end(); + for (auto it = _audioIDInfoMap.begin(); it != itEnd; ++it) { if (it->second.state == AudioState::PAUSED) { @@ -214,62 +210,58 @@ void AudioEngine::resumeAll() void AudioEngine::stop(int audioID) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end()){ + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end()){ _audioEngineImpl->stop(audioID); - if (it->second.profileManage) { - it->second.profileManage->audioIDs.remove(audioID); - } - _audioIDs[*it->second.filePath].remove(audioID); - _audioInfos.erase(audioID); + remove(audioID); } } void AudioEngine::remove(int audioID) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end()){ + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end()){ if (it->second.profileManage) { it->second.profileManage->audioIDs.remove(audioID); } - _audioIDs[*it->second.filePath].remove(audioID); - _audioInfos.erase(audioID); + _audioPathIDMap[*it->second.filePath].remove(audioID); + _audioIDInfoMap.erase(audioID); } } void AudioEngine::stopAll() { _audioEngineImpl->stopAll(); - auto itEnd = _audioInfos.end(); - for (auto it = _audioInfos.begin(); it != itEnd; ++it) + auto itEnd = _audioIDInfoMap.end(); + for (auto it = _audioIDInfoMap.begin(); it != itEnd; ++it) { if (it->second.profileManage){ it->second.profileManage->audioIDs.remove(it->first); } } - _audioIDs.clear(); - _audioInfos.clear(); + _audioPathIDMap.clear(); + _audioIDInfoMap.clear(); } void AudioEngine::uncache(const std::string &filePath) { - if(_audioIDs.find(filePath) != _audioIDs.end()){ - auto itEnd = _audioIDs[filePath].end(); - int audioID; - for (auto it = _audioIDs[filePath].begin() ; it != itEnd; ++it) { - audioID = *it; - log("uncache id:%d", audioID); + if(_audioPathIDMap.find(filePath) != _audioPathIDMap.end()){ + auto itEnd = _audioPathIDMap[filePath].end(); + for (auto it = _audioPathIDMap[filePath].begin() ; it != itEnd; ++it) { + auto audioID = *it; _audioEngineImpl->stop(audioID); - auto& info = _audioInfos[audioID]; - if (info.profileManage) { - info.profileManage->audioIDs.remove(audioID); + auto itInfo = _audioIDInfoMap.find(audioID); + if (itInfo != _audioIDInfoMap.end()){ + if (itInfo->second.profileManage) { + itInfo->second.profileManage->audioIDs.remove(audioID); + } + _audioIDInfoMap.erase(audioID); } - _audioInfos.erase(audioID); } _audioEngineImpl->uncache(filePath); - _audioIDs.erase(filePath); + _audioPathIDMap.erase(filePath); } } @@ -281,8 +273,8 @@ void AudioEngine::uncacheAll() float AudioEngine::getDuration(int audioID) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end() && it->second.state != AudioState::INITIAL) + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end() && it->second.state != AudioState::INITIALZING) { if (it->second.duration == TIME_UNKNOWN) { @@ -296,8 +288,8 @@ float AudioEngine::getDuration(int audioID) bool AudioEngine::setCurrentTime(int audioID, float time) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end() && it->second.state != AudioState::INITIAL){ + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end() && it->second.state != AudioState::INITIALZING){ return _audioEngineImpl->setCurrentTime(audioID, time); } @@ -306,8 +298,8 @@ bool AudioEngine::setCurrentTime(int audioID, float time) float AudioEngine::getCurrentTime(int audioID) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end() && it->second.state != AudioState::INITIAL){ + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end() && it->second.state != AudioState::INITIALZING){ return _audioEngineImpl->getCurrentTime(audioID); } return 0.0f; @@ -315,15 +307,15 @@ float AudioEngine::getCurrentTime(int audioID) void AudioEngine::setFinishCallback(int audioID, const std::function &callback) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end()){ + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end()){ _audioEngineImpl->setFinishCallback(audioID, callback); } } -bool AudioEngine::setMaxAudioInstance(unsigned int maxInstances) +bool AudioEngine::setMaxAudioInstance(int maxInstances) { - if (maxInstances <= kMaxSources) { + if (maxInstances > 0 && maxInstances <= kMaxSources) { _maxInstances = maxInstances; return true; } @@ -333,8 +325,8 @@ bool AudioEngine::setMaxAudioInstance(unsigned int maxInstances) bool AudioEngine::isLoop(int audioID) { - auto tmpIterator = _audioInfos.find(audioID); - if (tmpIterator != _audioInfos.end()) + auto tmpIterator = _audioIDInfoMap.find(audioID); + if (tmpIterator != _audioIDInfoMap.end()) { return tmpIterator->second.loop; } @@ -345,8 +337,8 @@ bool AudioEngine::isLoop(int audioID) float AudioEngine::getVolume(int audioID) { - auto tmpIterator = _audioInfos.find(audioID); - if (tmpIterator != _audioInfos.end()) + auto tmpIterator = _audioIDInfoMap.find(audioID); + if (tmpIterator != _audioIDInfoMap.end()) { return tmpIterator->second.volume; } @@ -357,25 +349,23 @@ float AudioEngine::getVolume(int audioID) AudioEngine::AudioState AudioEngine::getState(int audioID) { - auto tmpIterator = _audioInfos.find(audioID); - if (tmpIterator != _audioInfos.end()) + auto tmpIterator = _audioIDInfoMap.find(audioID); + if (tmpIterator != _audioIDInfoMap.end()) { return tmpIterator->second.state; } - - log("AudioEngine::getState-->The audio instance %d is non-existent", audioID); + return AudioState::ERROR; } AudioProfile* AudioEngine::getProfile(int audioID) { - auto it = _audioInfos.find(audioID); - if (it != _audioInfos.end()) + auto it = _audioIDInfoMap.find(audioID); + if (it != _audioIDInfoMap.end()) { return &it->second.profileManage->profile; } - log("AudioEngine::getProfile-->The audio instance %d is non-existent", audioID); return nullptr; } @@ -391,18 +381,12 @@ AudioProfile* AudioEngine::getDefaultProfile() AudioProfile* AudioEngine::getProfile(const std::string &name) { - auto it = _profileManages.find(name); - if (it != _profileManages.end()) { + auto it = _audioPathProfileManageMap.find(name); + if (it != _audioPathProfileManageMap.end()) { return &it->second.profile; } else { - log("AudioEngine::getProfile-->profile:%s not found", name.c_str()); return nullptr; } } -unsigned int AudioEngine::getMaxAudioInstance() -{ - return _maxInstances; -} - #endif diff --git a/cocos/audio/android/AudioEngine-inl.cpp b/cocos/audio/android/AudioEngine-inl.cpp index 1b5158b1c4..2314b36192 100644 --- a/cocos/audio/android/AudioEngine-inl.cpp +++ b/cocos/audio/android/AudioEngine-inl.cpp @@ -38,9 +38,6 @@ #include #include -#define MIN_VOLUME_MILLIBEL -7000 -#define RANGE_VOLUME_MILLIBEL 7000 - using namespace cocos2d; void PlayOverEvent(SLPlayItf caller, void* context, SLuint32 playEvent) @@ -145,7 +142,11 @@ bool AudioPlayer::init(SLEngineItf engineEngine, SLObjectItf outputMixObject,con (*_fdPlayerSeek)->SetLoop(_fdPlayerSeek, SL_BOOLEAN_TRUE, 0, SL_TIME_UNKNOWN); } - (*_fdPlayerVolume)->SetVolumeLevel(_fdPlayerVolume, MIN_VOLUME_MILLIBEL + RANGE_VOLUME_MILLIBEL * volume); + int dbVolume = 2000 * log10(volume); + if(dbVolume < SL_MILLIBEL_MIN){ + dbVolume = SL_MILLIBEL_MIN; + } + (*_fdPlayerVolume)->SetVolumeLevel(_fdPlayerVolume, dbVolume); result = (*_fdPlayerPlay)->SetPlayState(_fdPlayerPlay, SL_PLAYSTATE_PLAYING); if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } @@ -233,7 +234,7 @@ int AudioEngineImpl::play2d(const std::string &fileFullPath ,bool loop ,float vo (*(player._fdPlayerPlay))->RegisterCallback(player._fdPlayerPlay, PlayOverEvent, (void*)this); (*(player._fdPlayerPlay))->SetCallbackEventsMask(player._fdPlayerPlay, SL_PLAYEVENT_HEADATEND); - AudioEngine::_audioInfos[audioId].state = AudioEngine::AudioState::PLAYING; + AudioEngine::_audioIDInfoMap[audioId].state = AudioEngine::AudioState::PLAYING; } while (0); return audioId; @@ -248,7 +249,7 @@ void AudioEngineImpl::playerFinishCallback(SLPlayItf caller, SLuint32 playEvent) { if (iter->second._finishCallback) { - iter->second._finishCallback(iter->second._audioID, *AudioEngine::_audioInfos[iter->second._audioID].filePath); + iter->second._finishCallback(iter->second._audioID, *AudioEngine::_audioIDInfoMap[iter->second._audioID].filePath); } AudioEngine::stop(iter->second._audioID); break; @@ -259,9 +260,13 @@ void AudioEngineImpl::playerFinishCallback(SLPlayItf caller, SLuint32 playEvent) void AudioEngineImpl::setVolume(int audioID,float volume) { auto& player = _audioPlayers[audioID]; - auto result = (*player._fdPlayerVolume)->SetVolumeLevel(player._fdPlayerVolume, MIN_VOLUME_MILLIBEL + RANGE_VOLUME_MILLIBEL * volume); + int dbVolume = 2000 * log10(volume); + if(dbVolume < SL_MILLIBEL_MIN){ + dbVolume = SL_MILLIBEL_MIN; + } + auto result = (*player._fdPlayerVolume)->SetVolumeLevel(player._fdPlayerVolume, dbVolume); if(SL_RESULT_SUCCESS != result){ - log("%s error:%u",__func__, result); + log("%s error:%lu",__func__, result); } } @@ -280,7 +285,7 @@ void AudioEngineImpl::pause(int audioID) auto& player = _audioPlayers[audioID]; auto result = (*player._fdPlayerPlay)->SetPlayState(player._fdPlayerPlay, SL_PLAYSTATE_PAUSED); if(SL_RESULT_SUCCESS != result){ - log("%s error:%u",__func__, result); + log("%s error:%lu",__func__, result); } } @@ -289,7 +294,7 @@ void AudioEngineImpl::resume(int audioID) auto& player = _audioPlayers[audioID]; auto result = (*player._fdPlayerPlay)->SetPlayState(player._fdPlayerPlay, SL_PLAYSTATE_PLAYING); if(SL_RESULT_SUCCESS != result){ - log("%s error:%u",__func__, result); + log("%s error:%lu",__func__, result); } } @@ -298,7 +303,7 @@ void AudioEngineImpl::stop(int audioID) auto& player = _audioPlayers[audioID]; auto result = (*player._fdPlayerPlay)->SetPlayState(player._fdPlayerPlay, SL_PLAYSTATE_STOPPED); if(SL_RESULT_SUCCESS != result){ - log("%s error:%u",__func__, result); + log("%s error:%lu",__func__, result); } _audioPlayers.erase(audioID); @@ -339,14 +344,7 @@ float AudioEngineImpl::getCurrentTime(int audioID) SLmillisecond currPos; auto& player = _audioPlayers[audioID]; (*player._fdPlayerPlay)->GetPosition(player._fdPlayerPlay, &currPos); - - if (currPos > player._duration){ - float pos = currPos/1000.0f; - return fmod(pos, player._duration); - } - else { - return currPos / 1000.0f; - } + return currPos / 1000.0f; } bool AudioEngineImpl::setCurrentTime(int audioID, float time) diff --git a/cocos/audio/include/AudioEngine.h b/cocos/audio/include/AudioEngine.h index 77da61dba3..d4442a562d 100644 --- a/cocos/audio/include/AudioEngine.h +++ b/cocos/audio/include/AudioEngine.h @@ -70,7 +70,7 @@ public: enum class AudioState { ERROR = -1, - INITIAL, + INITIALZING, PLAYING, PAUSED }; @@ -178,9 +178,9 @@ public: */ static void setFinishCallback(int audioID, const std::function& callback); - static unsigned int getMaxAudioInstance(); + static int getMaxAudioInstance() {return _maxInstances;} - static bool setMaxAudioInstance(unsigned int maxInstances); + static bool setMaxAudioInstance(int maxInstances); /** Uncache the audio data from internal buffer. * AudioEngine cache audio data on ios platform @@ -233,7 +233,7 @@ protected: AudioInfo() : profileManage(nullptr) , duration(TIME_UNKNOWN) - , state(AudioState::INITIAL) + , state(AudioState::INITIALZING) { } @@ -250,13 +250,13 @@ protected: }; //audioID,audioAttribute - static std::unordered_map _audioInfos; + static std::unordered_map _audioIDInfoMap; //audio file path,audio IDs - static std::unordered_map> _audioIDs; + static std::unordered_map> _audioPathIDMap; //profileName,ProfileManage - static std::unordered_map _profileManages; + static std::unordered_map _audioPathProfileManageMap; static int _maxInstances; diff --git a/cocos/audio/ios/AudioEngine-inl.mm b/cocos/audio/ios/AudioEngine-inl.mm index 2c4769d567..22a5d6fa00 100644 --- a/cocos/audio/ios/AudioEngine-inl.mm +++ b/cocos/audio/ios/AudioEngine-inl.mm @@ -248,7 +248,7 @@ void AudioEngineImpl::_play2d(AudioCache *cache, int audioID) auto playerIt = _audioPlayers.find(audioID); if (playerIt != _audioPlayers.end()) { if (playerIt->second.play2d(cache)) { - AudioEngine::_audioInfos[audioID].state = AudioEngine::AudioState::PLAYING; + AudioEngine::_audioIDInfoMap[audioID].state = AudioEngine::AudioState::PLAYING; } else{ _threadMutex.lock(); @@ -408,7 +408,7 @@ bool AudioEngineImpl::setCurrentTime(int audioID, float time) } if (player._largeFile) { - //ret = player.setTime(time); + ret = player.setTime(time); break; } else { @@ -472,7 +472,7 @@ void AudioEngineImpl::update(float dt) if (player._ready && sourceState == AL_STOPPED) { _alSourceUsed[player._alSource] = false; - auto& audioInfo = AudioEngine::_audioInfos[audioID]; + auto& audioInfo = AudioEngine::_audioIDInfoMap[audioID]; if (player._finishCallbak) { player._finishCallbak(audioID, *audioInfo.filePath); } From e588b371bdfc77fd35352c18b4a197a2760d6d81 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 10 Sep 2014 14:09:42 +0800 Subject: [PATCH 16/32] Replace with 'struct' for AudioInfo/ProfileHelper. --- cocos/audio/AudioEngine.cpp | 49 ++++++++++++++++--------------- cocos/audio/include/AudioEngine.h | 42 +++++++++++++------------- cocos/audio/ios/AudioEngine-inl.h | 1 - 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/cocos/audio/AudioEngine.cpp b/cocos/audio/AudioEngine.cpp index d485bd6695..28a3a74114 100644 --- a/cocos/audio/AudioEngine.cpp +++ b/cocos/audio/AudioEngine.cpp @@ -42,10 +42,10 @@ const float AudioEngine::TIME_UNKNOWN = -1.0f; //audio file path,audio IDs std::unordered_map> AudioEngine::_audioPathIDMap; -//profileName,ProfileManage -std::unordered_map AudioEngine::_audioPathProfileManageMap; +//profileName,ProfileHelper +std::unordered_map AudioEngine::_audioPathProfileHelperMap; int AudioEngine::_maxInstances = kMaxSources; -AudioEngine::ProfileManage* AudioEngine::_defaultProfileManage; +AudioEngine::ProfileHelper* AudioEngine::_defaultProfileHelper; std::unordered_map AudioEngine::_audioIDInfoMap; AudioEngineImpl* AudioEngine::_audioEngineImpl = nullptr; @@ -54,8 +54,8 @@ void AudioEngine::end() delete _audioEngineImpl; _audioEngineImpl = nullptr; - delete _defaultProfileManage; - _defaultProfileManage = nullptr; + delete _defaultProfileHelper; + _defaultProfileHelper = nullptr; } bool AudioEngine::lazyInit() @@ -84,10 +84,10 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, co break; } - ProfileManage* manage = _defaultProfileManage; + ProfileHelper* manage = _defaultProfileHelper; if (profile && profile != &manage->profile){ CC_ASSERT(!profile->name.empty()); - manage = &_audioPathProfileManageMap[profile->name]; + manage = &_audioPathProfileHelperMap[profile->name]; manage->profile = *profile; } @@ -133,7 +133,7 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, co manage->lastPlayTime = utils::gettime(); manage->audioIDs.push_back(ret); } - audioRef.profileManage = manage; + audioRef.profileHelper = manage; } } while (0); @@ -152,15 +152,18 @@ void AudioEngine::setLoop(int audioID, bool loop) void AudioEngine::setVolume(int audioID, float volume) { auto it = _audioIDInfoMap.find(audioID); - if (it != _audioIDInfoMap.end() && it->second.volume != volume){ + if (it != _audioIDInfoMap.end()){ if (volume < 0.0f) { volume = 0.0f; } else if (volume > 1.0f){ volume = 1.0f; } - _audioEngineImpl->setVolume(audioID, volume); - it->second.volume = volume; + + if (it->second.volume != volume){ + _audioEngineImpl->setVolume(audioID, volume); + it->second.volume = volume; + } } } @@ -222,8 +225,8 @@ void AudioEngine::remove(int audioID) { auto it = _audioIDInfoMap.find(audioID); if (it != _audioIDInfoMap.end()){ - if (it->second.profileManage) { - it->second.profileManage->audioIDs.remove(audioID); + if (it->second.profileHelper) { + it->second.profileHelper->audioIDs.remove(audioID); } _audioPathIDMap[*it->second.filePath].remove(audioID); _audioIDInfoMap.erase(audioID); @@ -236,8 +239,8 @@ void AudioEngine::stopAll() auto itEnd = _audioIDInfoMap.end(); for (auto it = _audioIDInfoMap.begin(); it != itEnd; ++it) { - if (it->second.profileManage){ - it->second.profileManage->audioIDs.remove(it->first); + if (it->second.profileHelper){ + it->second.profileHelper->audioIDs.remove(it->first); } } _audioPathIDMap.clear(); @@ -254,8 +257,8 @@ void AudioEngine::uncache(const std::string &filePath) auto itInfo = _audioIDInfoMap.find(audioID); if (itInfo != _audioIDInfoMap.end()){ - if (itInfo->second.profileManage) { - itInfo->second.profileManage->audioIDs.remove(audioID); + if (itInfo->second.profileHelper) { + itInfo->second.profileHelper->audioIDs.remove(audioID); } _audioIDInfoMap.erase(audioID); } @@ -363,7 +366,7 @@ AudioProfile* AudioEngine::getProfile(int audioID) auto it = _audioIDInfoMap.find(audioID); if (it != _audioIDInfoMap.end()) { - return &it->second.profileManage->profile; + return &it->second.profileHelper->profile; } return nullptr; @@ -371,18 +374,18 @@ AudioProfile* AudioEngine::getProfile(int audioID) AudioProfile* AudioEngine::getDefaultProfile() { - if (_defaultProfileManage == nullptr) + if (_defaultProfileHelper == nullptr) { - _defaultProfileManage = new (std::nothrow) ProfileManage(); + _defaultProfileHelper = new (std::nothrow) ProfileHelper(); } - return &_defaultProfileManage->profile; + return &_defaultProfileHelper->profile; } AudioProfile* AudioEngine::getProfile(const std::string &name) { - auto it = _audioPathProfileManageMap.find(name); - if (it != _audioPathProfileManageMap.end()) { + auto it = _audioPathProfileHelperMap.find(name); + if (it != _audioPathProfileHelperMap.end()) { return &it->second.profile; } else { return nullptr; diff --git a/cocos/audio/include/AudioEngine.h b/cocos/audio/include/AudioEngine.h index d4442a562d..a3663b0868 100644 --- a/cocos/audio/include/AudioEngine.h +++ b/cocos/audio/include/AudioEngine.h @@ -211,35 +211,25 @@ protected: static void remove(int audioID); - class ProfileManage + struct ProfileHelper { - public: AudioProfile profile; - ProfileManage() - : lastPlayTime(0.0) - { - - } - std::list audioIDs; double lastPlayTime; - }; - class AudioInfo - { - public: - AudioInfo() - : profileManage(nullptr) - , duration(TIME_UNKNOWN) - , state(AudioState::INITIALZING) + ProfileHelper() + : lastPlayTime(0.0) { - + } - + }; + + struct AudioInfo + { const std::string* filePath; - ProfileManage* profileManage; + ProfileHelper* profileHelper; float volume; bool loop; @@ -247,6 +237,14 @@ protected: AudioState state; bool is3dAudio; + + AudioInfo() + : profileHelper(nullptr) + , duration(TIME_UNKNOWN) + , state(AudioState::INITIALZING) + { + + } }; //audioID,audioAttribute @@ -255,12 +253,12 @@ protected: //audio file path,audio IDs static std::unordered_map> _audioPathIDMap; - //profileName,ProfileManage - static std::unordered_map _audioPathProfileManageMap; + //profileName,ProfileHelper + static std::unordered_map _audioPathProfileHelperMap; static int _maxInstances; - static ProfileManage* _defaultProfileManage; + static ProfileHelper* _defaultProfileHelper; static AudioEngineImpl* _audioEngineImpl; diff --git a/cocos/audio/ios/AudioEngine-inl.h b/cocos/audio/ios/AudioEngine-inl.h index 835367a06f..5421389948 100644 --- a/cocos/audio/ios/AudioEngine-inl.h +++ b/cocos/audio/ios/AudioEngine-inl.h @@ -33,7 +33,6 @@ #include "AudioPlayer.h" NS_CC_BEGIN -class AudioProfile; #define kMaxSources 32 From 51879a7e394b88907970a9fcb6476cdd7ada1ee5 Mon Sep 17 00:00:00 2001 From: samuele3hu Date: Wed, 10 Sep 2014 14:18:21 +0800 Subject: [PATCH 17/32] Update lua bindings ini config files --- tools/tolua/cocos2dx.ini | 2 +- tools/tolua/cocos2dx_3d.ini | 2 +- tools/tolua/cocos2dx_cocosbuilder.ini | 2 +- tools/tolua/cocos2dx_cocosdenshion.ini | 2 +- tools/tolua/cocos2dx_controller.ini | 2 +- tools/tolua/cocos2dx_experimental.ini | 2 +- tools/tolua/cocos2dx_experimental_video.ini | 2 +- tools/tolua/cocos2dx_extension.ini | 2 +- tools/tolua/cocos2dx_physics.ini | 2 +- tools/tolua/cocos2dx_spine.ini | 2 +- tools/tolua/cocos2dx_studio.ini | 2 +- tools/tolua/cocos2dx_ui.ini | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/tolua/cocos2dx.ini b/tools/tolua/cocos2dx.ini index c84570383f..f2769ce810 100644 --- a/tools/tolua/cocos2dx.ini +++ b/tools/tolua/cocos2dx.ini @@ -11,7 +11,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 -D__STRICT_ANSI__ +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android cocos_flags = -DANDROID diff --git a/tools/tolua/cocos2dx_3d.ini b/tools/tolua/cocos2dx_3d.ini index a043f994f9..e218da343a 100644 --- a/tools/tolua/cocos2dx_3d.ini +++ b/tools/tolua/cocos2dx_3d.ini @@ -11,7 +11,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android cocos_flags = -DANDROID diff --git a/tools/tolua/cocos2dx_cocosbuilder.ini b/tools/tolua/cocos2dx_cocosbuilder.ini index 40a7de384b..410fdeb5a5 100644 --- a/tools/tolua/cocos2dx_cocosbuilder.ini +++ b/tools/tolua/cocos2dx_cocosbuilder.ini @@ -11,7 +11,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android diff --git a/tools/tolua/cocos2dx_cocosdenshion.ini b/tools/tolua/cocos2dx_cocosdenshion.ini index b032989626..6e337f3b84 100644 --- a/tools/tolua/cocos2dx_cocosdenshion.ini +++ b/tools/tolua/cocos2dx_cocosdenshion.ini @@ -11,7 +11,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android diff --git a/tools/tolua/cocos2dx_controller.ini b/tools/tolua/cocos2dx_controller.ini index d80733b677..aed359d313 100644 --- a/tools/tolua/cocos2dx_controller.ini +++ b/tools/tolua/cocos2dx_controller.ini @@ -13,7 +13,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/platform/android cocos_flags = -DANDROID diff --git a/tools/tolua/cocos2dx_experimental.ini b/tools/tolua/cocos2dx_experimental.ini index 97d890abf1..3ab59b7e59 100644 --- a/tools/tolua/cocos2dx_experimental.ini +++ b/tools/tolua/cocos2dx_experimental.ini @@ -11,7 +11,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android diff --git a/tools/tolua/cocos2dx_experimental_video.ini b/tools/tolua/cocos2dx_experimental_video.ini index e0c343b56e..3f92bf13d7 100644 --- a/tools/tolua/cocos2dx_experimental_video.ini +++ b/tools/tolua/cocos2dx_experimental_video.ini @@ -13,7 +13,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android diff --git a/tools/tolua/cocos2dx_extension.ini b/tools/tolua/cocos2dx_extension.ini index 3b474c792f..162ebddd02 100644 --- a/tools/tolua/cocos2dx_extension.ini +++ b/tools/tolua/cocos2dx_extension.ini @@ -11,7 +11,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android diff --git a/tools/tolua/cocos2dx_physics.ini b/tools/tolua/cocos2dx_physics.ini index dca3e11f6f..c5042f1dde 100644 --- a/tools/tolua/cocos2dx_physics.ini +++ b/tools/tolua/cocos2dx_physics.ini @@ -13,7 +13,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android diff --git a/tools/tolua/cocos2dx_spine.ini b/tools/tolua/cocos2dx_spine.ini index 9ab910e8a2..b43c0ca4e3 100644 --- a/tools/tolua/cocos2dx_spine.ini +++ b/tools/tolua/cocos2dx_spine.ini @@ -11,7 +11,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android diff --git a/tools/tolua/cocos2dx_studio.ini b/tools/tolua/cocos2dx_studio.ini index a25e3b67b9..5aaf483758 100644 --- a/tools/tolua/cocos2dx_studio.ini +++ b/tools/tolua/cocos2dx_studio.ini @@ -14,7 +14,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s/external -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android diff --git a/tools/tolua/cocos2dx_ui.ini b/tools/tolua/cocos2dx_ui.ini index 1852a16b97..90258ae875 100644 --- a/tools/tolua/cocos2dx_ui.ini +++ b/tools/tolua/cocos2dx_ui.ini @@ -14,7 +14,7 @@ android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include android_flags = -D_SIZE_T_DEFINED_ clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include -clang_flags = -nostdinc -x c++ -std=c++11 +clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android From 61b316e12f8b021bdf7090b0399aaa33a2d1a515 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 10 Sep 2014 14:46:21 +0800 Subject: [PATCH 18/32] Update the reference of submodule cocos2d-console --- tools/cocos2d-console | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cocos2d-console b/tools/cocos2d-console index 305f090f26..0fd9899d87 160000 --- a/tools/cocos2d-console +++ b/tools/cocos2d-console @@ -1 +1 @@ -Subproject commit 305f090f260a0b8766c3fd09a3d4d2072910bfd9 +Subproject commit 0fd9899d8797dad6fd68d99b5dc41a5548219a97 From 1d43c6ec82c73453cf83c180e2e479ba5f55bf3e Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 10 Sep 2014 17:12:46 +0800 Subject: [PATCH 19/32] Fix name of variables and coding style. --- cocos/audio/AudioEngine.cpp | 4 +-- cocos/audio/android/AudioEngine-inl.cpp | 32 +++++++++--------- cocos/audio/android/AudioEngine-inl.h | 6 ++-- cocos/audio/ios/AudioCache.h | 2 +- cocos/audio/ios/AudioCache.mm | 37 +++++++++++---------- cocos/audio/ios/AudioEngine-inl.h | 10 +++--- cocos/audio/ios/AudioEngine-inl.mm | 44 ++++++++++++++----------- cocos/audio/ios/AudioPlayer.h | 2 +- 8 files changed, 73 insertions(+), 64 deletions(-) diff --git a/cocos/audio/AudioEngine.cpp b/cocos/audio/AudioEngine.cpp index 28a3a74114..03579936bf 100644 --- a/cocos/audio/AudioEngine.cpp +++ b/cocos/audio/AudioEngine.cpp @@ -44,7 +44,7 @@ const float AudioEngine::TIME_UNKNOWN = -1.0f; std::unordered_map> AudioEngine::_audioPathIDMap; //profileName,ProfileHelper std::unordered_map AudioEngine::_audioPathProfileHelperMap; -int AudioEngine::_maxInstances = kMaxSources; +int AudioEngine::_maxInstances = MAX_AUDIOINSTANCES; AudioEngine::ProfileHelper* AudioEngine::_defaultProfileHelper; std::unordered_map AudioEngine::_audioIDInfoMap; AudioEngineImpl* AudioEngine::_audioEngineImpl = nullptr; @@ -318,7 +318,7 @@ void AudioEngine::setFinishCallback(int audioID, const std::function 0 && maxInstances <= kMaxSources) { + if (maxInstances > 0 && maxInstances <= MAX_AUDIOINSTANCES) { _maxInstances = maxInstances; return true; } diff --git a/cocos/audio/android/AudioEngine-inl.cpp b/cocos/audio/android/AudioEngine-inl.cpp index 2314b36192..69389ab05e 100644 --- a/cocos/audio/android/AudioEngine-inl.cpp +++ b/cocos/audio/android/AudioEngine-inl.cpp @@ -32,7 +32,7 @@ #include "audio/include/AudioEngine.h" #include "base/CCDirector.h" -#include "platform/android/CCFileUtilsAndroid.h" +#include "platform/android/CCFileUtils-android.h" #include "platform/android/jni/JniHelper.h" #include @@ -120,23 +120,23 @@ bool AudioPlayer::init(SLEngineItf engineEngine, SLObjectItf outputMixObject,con const SLInterfaceID ids[3] = {SL_IID_SEEK, SL_IID_PREFETCHSTATUS, SL_IID_VOLUME}; const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; auto result = (*engineEngine)->CreateAudioPlayer(engineEngine, &_fdPlayerObject, &audioSrc, &audioSnk, 3, ids, req); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("create audio player fail"); break; } // realize the player result = (*_fdPlayerObject)->Realize(_fdPlayerObject, SL_BOOLEAN_FALSE); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("realize the player fail"); break; } // get the play interface result = (*_fdPlayerObject)->GetInterface(_fdPlayerObject, SL_IID_PLAY, &_fdPlayerPlay); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("get the play interface fail"); break; } // get the seek interface result = (*_fdPlayerObject)->GetInterface(_fdPlayerObject, SL_IID_SEEK, &_fdPlayerSeek); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("get the seek interface fail"); break; } // get the volume interface result = (*_fdPlayerObject)->GetInterface(_fdPlayerObject, SL_IID_VOLUME, &_fdPlayerVolume); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("get the volume interface fail"); break; } if (loop){ (*_fdPlayerSeek)->SetLoop(_fdPlayerSeek, SL_BOOLEAN_TRUE, 0, SL_TIME_UNKNOWN); @@ -149,7 +149,7 @@ bool AudioPlayer::init(SLEngineItf engineEngine, SLObjectItf outputMixObject,con (*_fdPlayerVolume)->SetVolumeLevel(_fdPlayerVolume, dbVolume); result = (*_fdPlayerPlay)->SetPlayState(_fdPlayerPlay, SL_PLAYSTATE_PLAYING); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("SetPlayState fail"); break; } ret = true; } while (0); @@ -159,7 +159,7 @@ bool AudioPlayer::init(SLEngineItf engineEngine, SLObjectItf outputMixObject,con //==================================================== AudioEngineImpl::AudioEngineImpl() - : nextAudioID(0) + : currentAudioID(0) , _engineObject(nullptr) , _engineEngine(nullptr) , _outputMixObject(nullptr) @@ -185,25 +185,25 @@ bool AudioEngineImpl::init() do{ // create engine auto result = slCreateEngine(&_engineObject, 0, nullptr, 0, nullptr, nullptr); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("create opensl engine fail"); break; } // realize the engine result = (*_engineObject)->Realize(_engineObject, SL_BOOLEAN_FALSE); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("realize the engine fail"); break; } // get the engine interface, which is needed in order to create other objects result = (*_engineObject)->GetInterface(_engineObject, SL_IID_ENGINE, &_engineEngine); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("get the engine interface fail"); break; } // create output mix const SLInterfaceID outputMixIIDs[] = {}; const SLboolean outputMixReqs[] = {}; result = (*_engineEngine)->CreateOutputMix(_engineEngine, &_outputMixObject, 0, outputMixIIDs, outputMixReqs); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("create output mix fail"); break; } // realize the output mix result = (*_outputMixObject)->Realize(_outputMixObject, SL_BOOLEAN_FALSE); - if(SL_RESULT_SUCCESS != result){ LOG_FUN break; } + if(SL_RESULT_SUCCESS != result){ ERRORLOG("realize the output mix fail"); break; } ret = true; }while (false); @@ -220,15 +220,15 @@ int AudioEngineImpl::play2d(const std::string &fileFullPath ,bool loop ,float vo if (_engineEngine == nullptr) break; - auto& player = _audioPlayers[nextAudioID]; + auto& player = _audioPlayers[currentAudioID]; auto initPlayer = player.init( _engineEngine, _outputMixObject, fileFullPath, volume, loop); if (!initPlayer){ - _audioPlayers.erase(nextAudioID); + _audioPlayers.erase(currentAudioID); log("%s,%d message:create player for %s fail", __func__, __LINE__, fileFullPath.c_str()); break; } - audioId = nextAudioID++; + audioId = currentAudioID++; player._audioID = audioId; (*(player._fdPlayerPlay))->RegisterCallback(player._fdPlayerPlay, PlayOverEvent, (void*)this); diff --git a/cocos/audio/android/AudioEngine-inl.h b/cocos/audio/android/AudioEngine-inl.h index 8444d12c7c..bf9f7a7773 100644 --- a/cocos/audio/android/AudioEngine-inl.h +++ b/cocos/audio/android/AudioEngine-inl.h @@ -32,9 +32,9 @@ #include #include "base/ccUtils.h" -#define kMaxSources 24 +#define MAX_AUDIOINSTANCES 24 -#define LOG_FUN log("error: %s,%d",__func__,__LINE__); +#define ERRORLOG(msg) log("fun:%s,line:%d,msg:%s",__func__,__LINE__,#msg) NS_CC_BEGIN @@ -98,7 +98,7 @@ private: //audioID,AudioInfo std::unordered_map _audioPlayers; - int nextAudioID; + int currentAudioID; }; #endif // __AUDIO_ENGINE_INL_H_ diff --git a/cocos/audio/ios/AudioCache.h b/cocos/audio/ios/AudioCache.h index c72000c647..4ba29807d6 100644 --- a/cocos/audio/ios/AudioCache.h +++ b/cocos/audio/ios/AudioCache.h @@ -33,7 +33,7 @@ #include #include -#include "base/CCPlatformMacros.h" +#include "CCPlatformMacros.h" #define QUEUEBUFFER_NUM 3 diff --git a/cocos/audio/ios/AudioCache.mm b/cocos/audio/ios/AudioCache.mm index 3ae7253e26..6f9fbbd384 100644 --- a/cocos/audio/ios/AudioCache.mm +++ b/cocos/audio/ios/AudioCache.mm @@ -26,19 +26,20 @@ #import #import -#define PCMDATA_CACHEMAXSIZE 1048576//1MB +#define PCMDATA_CACHEMAXSIZE 1048576 typedef ALvoid AL_APIENTRY (*alBufferDataStaticProcPtr) (const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq); -ALvoid alBufferDataStaticProc(const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq) +static ALvoid alBufferDataStaticProc(const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq) { static alBufferDataStaticProcPtr proc = NULL; - if (proc == NULL) { + if (proc == NULL){ proc = (alBufferDataStaticProcPtr) alcGetProcAddress(NULL, (const ALCchar*) "alBufferDataStatic"); } - if (proc) + if (proc){ proc(bid, format, data, size, freq); + } return; } @@ -60,9 +61,9 @@ AudioCache::~AudioCache() { _release = true; if(_pcmData){ - if (_alBufferReady) { + if (_alBufferReady) alDeleteBuffers(1, &_alBufferId); - } + _readThreadMutex.lock(); _readThreadMutex.unlock(); free(_pcmData); @@ -79,8 +80,8 @@ void AudioCache::readDataThread() { _readThreadMutex.lock(); - AudioStreamBasicDescription theFileFormat; - UInt32 thePropertySize = sizeof(theFileFormat); + AudioStreamBasicDescription theFileFormat; + UInt32 thePropertySize = sizeof(theFileFormat); SInt64 theFileLengthInFrames; SInt64 readInFrames; @@ -130,7 +131,10 @@ void AudioCache::readDataThread() // Get the total frame count thePropertySize = sizeof(theFileLengthInFrames); error = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames); - if(error) { printf("initOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %d\n", (int)error); goto ExitThread; } + if(error) { + printf("initOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %d\n", (int)error); + goto ExitThread; + } _dataSize = (ALsizei)(theFileLengthInFrames * outputFormat.mBytesPerFrame); _format = (outputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; @@ -142,7 +146,8 @@ void AudioCache::readDataThread() alGenBuffers(1, &_alBufferId); auto alError = alGetError(); if (alError != AL_NO_ERROR) { - printf("error attaching audio to buffer: %x\n", alError); goto ExitThread; + printf("error attaching audio to buffer: %x\n", alError); + goto ExitThread; } alBufferDataStaticProc(_alBufferId, _format, _pcmData, _dataSize, _sampleRate); @@ -199,16 +204,14 @@ void AudioCache::readDataThread() ExitThread: CFRelease(fileURL); - if (extRef) ExtAudioFileDispose(extRef); + if (extRef) + ExtAudioFileDispose(extRef); _readThreadMutex.unlock(); - if (_queBufferFrames > 0) { + if (_queBufferFrames > 0) _alBufferReady = true; - invokingCallbacks(); - } - else { - invokingCallbacks(); - } + + invokingCallbacks(); } void AudioCache::invokingCallbacks() diff --git a/cocos/audio/ios/AudioEngine-inl.h b/cocos/audio/ios/AudioEngine-inl.h index 5421389948..1f67978435 100644 --- a/cocos/audio/ios/AudioEngine-inl.h +++ b/cocos/audio/ios/AudioEngine-inl.h @@ -34,7 +34,7 @@ NS_CC_BEGIN -#define kMaxSources 32 +#define MAX_AUDIOINSTANCES 32 class AudioEngineThreadPool; @@ -67,7 +67,7 @@ private: AudioEngineThreadPool* _threadPool; - ALuint _alSources[kMaxSources]; + ALuint _alSources[MAX_AUDIOINSTANCES]; //source,used std::unordered_map _alSourceUsed; @@ -80,12 +80,12 @@ private: std::mutex _threadMutex; - std::vector _removeCaches; - std::vector _removeAudioIDs; + std::vector _toRemoveCaches; + std::vector _toRemoveAudioIDs; bool _lazyInitLoop; - int nextAudioID; + int _currentAudioID; }; NS_CC_END diff --git a/cocos/audio/ios/AudioEngine-inl.mm b/cocos/audio/ios/AudioEngine-inl.mm index 22a5d6fa00..a23c81a1fe 100644 --- a/cocos/audio/ios/AudioEngine-inl.mm +++ b/cocos/audio/ios/AudioEngine-inl.mm @@ -84,7 +84,7 @@ namespace cocos2d { _sleepCondition.notify_all(); } - void stop() + void destroy() { _running = false; _sleepCondition.notify_all(); @@ -109,7 +109,6 @@ namespace cocos2d { if (nullptr == task) { - // Wait for http request tasks from main thread std::unique_lock lk(_sleepMutex); _sleepCondition.wait(lk); continue; @@ -134,7 +133,7 @@ namespace cocos2d { AudioEngineImpl::AudioEngineImpl() : _lazyInitLoop(true) -, nextAudioID(0) +, _currentAudioID(0) , _threadPool(nullptr) { @@ -143,7 +142,7 @@ AudioEngineImpl::AudioEngineImpl() AudioEngineImpl::~AudioEngineImpl() { if (s_ALContext) { - alDeleteSources(kMaxSources, _alSources); + alDeleteSources(MAX_AUDIOINSTANCES, _alSources); _audioCaches.clear(); @@ -153,7 +152,7 @@ AudioEngineImpl::~AudioEngineImpl() alcCloseDevice(s_ALDevice); } if (_threadPool) { - _threadPool->stop(); + _threadPool->destroy(); delete _threadPool; } } @@ -172,7 +171,7 @@ bool AudioEngineImpl::init() s_ALContext = alcCreateContext(s_ALDevice, nullptr); alcMakeContextCurrent(s_ALContext); - alGenSources(kMaxSources, _alSources); + alGenSources(MAX_AUDIOINSTANCES, _alSources); alError = alGetError(); if(alError != AL_NO_ERROR) { @@ -180,7 +179,7 @@ bool AudioEngineImpl::init() break; } - for (int i = 0; i < kMaxSources; ++i) { + for (int i = 0; i < MAX_AUDIOINSTANCES; ++i) { _alSourceUsed[_alSources[i]] = false; } @@ -200,7 +199,7 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume bool sourceFlag = false; ALuint alSource = 0; - for (int i = 0; i < kMaxSources; ++i) { + for (int i = 0; i < MAX_AUDIOINSTANCES; ++i) { alSource = _alSources[i]; if ( !_alSourceUsed[alSource]) { @@ -224,11 +223,11 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume audioCache = &it->second; } - auto player = &_audioPlayers[nextAudioID]; + auto player = &_audioPlayers[_currentAudioID]; player->_alSource = alSource; player->_loop = loop; player->_volume = volume; - audioCache->addCallbacks(std::bind(&AudioEngineImpl::_play2d,this,audioCache,nextAudioID)); + audioCache->addCallbacks(std::bind(&AudioEngineImpl::_play2d,this,audioCache,_currentAudioID)); _alSourceUsed[alSource] = true; @@ -239,7 +238,7 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume scheduler->schedule(schedule_selector(AudioEngineImpl::update), this, 0.05f, false); } - return nextAudioID++; + return _currentAudioID++; } void AudioEngineImpl::_play2d(AudioCache *cache, int audioID) @@ -252,15 +251,15 @@ void AudioEngineImpl::_play2d(AudioCache *cache, int audioID) } else{ _threadMutex.lock(); - _removeAudioIDs.push_back(audioID); + _toRemoveAudioIDs.push_back(audioID); _threadMutex.unlock(); } } } else { _threadMutex.lock(); - _removeCaches.push_back(cache); - _removeAudioIDs.push_back(audioID); + _toRemoveCaches.push_back(cache); + _toRemoveAudioIDs.push_back(audioID); _threadMutex.unlock(); } } @@ -357,7 +356,7 @@ bool AudioEngineImpl::stop(int audioID) void AudioEngineImpl::stopAll() { - for(int index = 0; index < kMaxSources; ++index) + for(int index = 0; index < MAX_AUDIOINSTANCES; ++index) { alSourceStop(_alSources[index]); alSourcei(_alSources[index], AL_BUFFER, NULL); @@ -442,9 +441,9 @@ void AudioEngineImpl::update(float dt) int audioID; if (_threadMutex.try_lock()) { - size_t removeAudioCount = _removeAudioIDs.size(); + size_t removeAudioCount = _toRemoveAudioIDs.size(); for (size_t index = 0; index < removeAudioCount; ++index) { - audioID = _removeAudioIDs[index]; + audioID = _toRemoveAudioIDs[index]; auto playerIt = _audioPlayers.find(audioID); if (playerIt != _audioPlayers.end()) { _alSourceUsed[playerIt->second._alSource] = false; @@ -452,11 +451,11 @@ void AudioEngineImpl::update(float dt) AudioEngine::remove(audioID); } } - size_t removeCacheCount = _removeCaches.size(); + size_t removeCacheCount = _toRemoveCaches.size(); for (size_t index = 0; index < removeCacheCount; ++index) { auto itEnd = _audioCaches.end(); for (auto it = _audioCaches.begin(); it != itEnd; ++it) { - if (&it->second == _removeCaches[index]) { + if (&it->second == _toRemoveCaches[index]) { _audioCaches.erase(it); break; } @@ -485,6 +484,13 @@ void AudioEngineImpl::update(float dt) ++it; } } + + if(_audioPlayers.empty()){ + _lazyInitLoop = true; + + auto scheduler = cocos2d::Director::getInstance()->getScheduler(); + scheduler->unschedule(schedule_selector(AudioEngineImpl::update), this); + } } void AudioEngineImpl::uncache(const std::string &filePath) diff --git a/cocos/audio/ios/AudioPlayer.h b/cocos/audio/ios/AudioPlayer.h index 6cea716150..8903578aca 100644 --- a/cocos/audio/ios/AudioPlayer.h +++ b/cocos/audio/ios/AudioPlayer.h @@ -29,7 +29,7 @@ #import #include #include -#include "base/CCPlatformMacros.h" +#include "CCPlatformMacros.h" NS_CC_BEGIN class AudioCache; From 336c85e88ebf2a54a611282019d5769692f62407 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 10 Sep 2014 17:13:51 +0800 Subject: [PATCH 20/32] update project for audio engine on IOS. --- build/cocos2d_libs.xcodeproj/project.pbxproj | 32 ++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index a518e62b73..3ccc0a806b 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -1267,6 +1267,14 @@ 299CF1FC19A434BC00C378C1 /* ccRandom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 299CF1F919A434BC00C378C1 /* ccRandom.cpp */; }; 299CF1FD19A434BC00C378C1 /* ccRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 299CF1FA19A434BC00C378C1 /* ccRandom.h */; }; 299CF1FE19A434BC00C378C1 /* ccRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 299CF1FA19A434BC00C378C1 /* ccRandom.h */; }; + 3E2BDADE19C030ED0055CDCD /* AudioEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDADD19C030ED0055CDCD /* AudioEngine.h */; }; + 3E2BDAE519C0329B0055CDCD /* AudioCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDADF19C0329B0055CDCD /* AudioCache.h */; }; + 3E2BDAE619C0329B0055CDCD /* AudioCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDAE019C0329B0055CDCD /* AudioCache.mm */; }; + 3E2BDAE719C0329B0055CDCD /* AudioEngine-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDAE119C0329B0055CDCD /* AudioEngine-inl.h */; }; + 3E2BDAE819C0329B0055CDCD /* AudioEngine-inl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDAE219C0329B0055CDCD /* AudioEngine-inl.mm */; }; + 3E2BDAE919C0329B0055CDCD /* AudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E2BDAE319C0329B0055CDCD /* AudioPlayer.h */; }; + 3E2BDAEA19C0329B0055CDCD /* AudioPlayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDAE419C0329B0055CDCD /* AudioPlayer.mm */; }; + 3E2BDAEC19C0436F0055CDCD /* AudioEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E2BDAEB19C0436F0055CDCD /* AudioEngine.cpp */; }; 3E6176681960F89B00DE83F5 /* CCController-iOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176551960F89B00DE83F5 /* CCController-iOS.mm */; }; 3E6176691960F89B00DE83F5 /* CCController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176561960F89B00DE83F5 /* CCController.h */; }; 3E6176741960F89B00DE83F5 /* CCEventController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E6176611960F89B00DE83F5 /* CCEventController.cpp */; }; @@ -2278,6 +2286,14 @@ 37936A3C1869B76800E974DD /* reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reader.h; sourceTree = ""; }; 37936A3D1869B76800E974DD /* stringbuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stringbuffer.h; sourceTree = ""; }; 37936A3E1869B76800E974DD /* writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = writer.h; sourceTree = ""; }; + 3E2BDADD19C030ED0055CDCD /* AudioEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioEngine.h; sourceTree = ""; }; + 3E2BDADF19C0329B0055CDCD /* AudioCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioCache.h; sourceTree = ""; }; + 3E2BDAE019C0329B0055CDCD /* AudioCache.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AudioCache.mm; sourceTree = ""; }; + 3E2BDAE119C0329B0055CDCD /* AudioEngine-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AudioEngine-inl.h"; sourceTree = ""; }; + 3E2BDAE219C0329B0055CDCD /* AudioEngine-inl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "AudioEngine-inl.mm"; sourceTree = ""; }; + 3E2BDAE319C0329B0055CDCD /* AudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioPlayer.h; sourceTree = ""; }; + 3E2BDAE419C0329B0055CDCD /* AudioPlayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AudioPlayer.mm; sourceTree = ""; }; + 3E2BDAEB19C0436F0055CDCD /* AudioEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioEngine.cpp; sourceTree = ""; }; 3E6176551960F89B00DE83F5 /* CCController-iOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "CCController-iOS.mm"; path = "../base/CCController-iOS.mm"; sourceTree = ""; }; 3E6176561960F89B00DE83F5 /* CCController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCController.h; path = ../base/CCController.h; sourceTree = ""; }; 3E6176611960F89B00DE83F5 /* CCEventController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCEventController.cpp; path = ../base/CCEventController.cpp; sourceTree = ""; }; @@ -3990,6 +4006,7 @@ 46A15FD01807A56F005B8026 /* audio */ = { isa = PBXGroup; children = ( + 3E2BDAEB19C0436F0055CDCD /* AudioEngine.cpp */, 46A15FE01807A56F005B8026 /* include */, 46A15FE31807A56F005B8026 /* ios */, 46A15FF31807A56F005B8026 /* mac */, @@ -4001,6 +4018,7 @@ 46A15FE01807A56F005B8026 /* include */ = { isa = PBXGroup; children = ( + 3E2BDADD19C030ED0055CDCD /* AudioEngine.h */, 46A15FE11807A56F005B8026 /* Export.h */, 46A15FE21807A56F005B8026 /* SimpleAudioEngine.h */, ); @@ -4010,6 +4028,12 @@ 46A15FE31807A56F005B8026 /* ios */ = { isa = PBXGroup; children = ( + 3E2BDADF19C0329B0055CDCD /* AudioCache.h */, + 3E2BDAE019C0329B0055CDCD /* AudioCache.mm */, + 3E2BDAE119C0329B0055CDCD /* AudioEngine-inl.h */, + 3E2BDAE219C0329B0055CDCD /* AudioEngine-inl.mm */, + 3E2BDAE319C0329B0055CDCD /* AudioPlayer.h */, + 3E2BDAE419C0329B0055CDCD /* AudioPlayer.mm */, 46A15FE41807A56F005B8026 /* CDAudioManager.h */, 46A15FE51807A56F005B8026 /* CDAudioManager.m */, 46A15FE61807A56F005B8026 /* CDConfig.h */, @@ -5368,6 +5392,7 @@ 1A5701A0180BCB590088DEC7 /* CCFont.h in Headers */, 292DB14819B4574100A80320 /* UIEditBoxImpl-ios.h in Headers */, 15AE1A0819AAD3A700C27E9E /* BoneData.h in Headers */, + 3E2BDADE19C030ED0055CDCD /* AudioEngine.h in Headers */, 50ABBD9A1925AB4100A911A9 /* CCGLProgramStateCache.h in Headers */, 15AE181D19AAD2F700C27E9E /* CCBundle3D.h in Headers */, 15AE192519AAD35100C27E9E /* CocoLoader.h in Headers */, @@ -5420,6 +5445,7 @@ 5034CA22191D591100CE6051 /* ccShader_PositionTextureColorAlphaTest.frag in Headers */, 15AE1B8E19AADA9A00C27E9E /* UIDeprecated.h in Headers */, 15AE1A3919AAD3D500C27E9E /* Box2D.h in Headers */, + 3E2BDAE519C0329B0055CDCD /* AudioCache.h in Headers */, 50ABBECE1925AB6F00A911A9 /* s3tc.h in Headers */, 50643BE519BFCF1800EF68ED /* CCPlatformMacros.h in Headers */, 15AE1BFA19AAE01E00C27E9E /* CCControlSwitch.h in Headers */, @@ -5513,6 +5539,7 @@ 15AE1BAE19AADFDF00C27E9E /* UILayoutParameter.h in Headers */, 15AE18C819AAD33D00C27E9E /* CCMenuItemImageLoader.h in Headers */, 15AE18D119AAD33D00C27E9E /* CCNodeLoaderLibrary.h in Headers */, + 3E2BDAE719C0329B0055CDCD /* AudioEngine-inl.h in Headers */, 15AE1AC319AAD40300C27E9E /* b2DistanceJoint.h in Headers */, 50ABBE741925AB6F00A911A9 /* CCEventListenerMouse.h in Headers */, 1A5702CB180BCE370088DEC7 /* CCTextFieldTTF.h in Headers */, @@ -5546,6 +5573,7 @@ B375107F1823ACA100B3BA6A /* CCPhysicsContactInfo_chipmunk.h in Headers */, 15AE180719AAD2F700C27E9E /* 3dExport.h in Headers */, 15AE1A2019AAD3A700C27E9E /* spine-cocos2dx.h in Headers */, + 3E2BDAE919C0329B0055CDCD /* AudioPlayer.h in Headers */, 15AE185D19AAD31200C27E9E /* CocosDenshion.h in Headers */, 15AE194319AAD35100C27E9E /* CCColliderDetector.h in Headers */, 15AE1BC419AADFFB00C27E9E /* ExtensionMacros.h in Headers */, @@ -6202,6 +6230,7 @@ 50ABBDA01925AB4100A911A9 /* CCGroupCommand.cpp in Sources */, 46A171031807CECB005B8026 /* CCPhysicsShape.cpp in Sources */, 50ABC0161926664800A911A9 /* CCImage.cpp in Sources */, + 3E2BDAE819C0329B0055CDCD /* AudioEngine-inl.mm in Sources */, 1A01C6A518F58F7500EFE3A6 /* CCNotificationCenter.cpp in Sources */, 292DB14E19B4574100A80320 /* UIEditBoxImpl-mac.mm in Sources */, 15AE1BFB19AAE01E00C27E9E /* CCControlUtils.cpp in Sources */, @@ -6230,6 +6259,7 @@ B257B44F1989D5E800D9A687 /* CCPrimitive.cpp in Sources */, 50ABBE281925AB6F00A911A9 /* CCAutoreleasePool.cpp in Sources */, 15AE18D519AAD33D00C27E9E /* CCScale9SpriteLoader.cpp in Sources */, + 3E2BDAEA19C0329B0055CDCD /* AudioPlayer.mm in Sources */, 15AE192919AAD35100C27E9E /* TriggerMng.cpp in Sources */, 15AE185E19AAD31200C27E9E /* CocosDenshion.m in Sources */, 46A170FE1807CECB005B8026 /* CCPhysicsContact.cpp in Sources */, @@ -6546,6 +6576,7 @@ 3E6176761960F89B00DE83F5 /* CCEventListenerController.cpp in Sources */, 15AE1AC219AAD40300C27E9E /* b2DistanceJoint.cpp in Sources */, 503DD8E71926736A00CD74DD /* CCEAGLView-ios.mm in Sources */, + 3E2BDAEC19C0436F0055CDCD /* AudioEngine.cpp in Sources */, 50ABBDA41925AB4100A911A9 /* CCQuadCommand.cpp in Sources */, 15AE18C319AAD33D00C27E9E /* CCLayerGradientLoader.cpp in Sources */, 15AE197919AAD35700C27E9E /* CCActionTimelineCache.cpp in Sources */, @@ -6572,6 +6603,7 @@ 15AE18CC19AAD33D00C27E9E /* CCNode+CCBRelativePositioning.cpp in Sources */, 50ABBD5D1925AB0000A911A9 /* Vec3.cpp in Sources */, 50ABC0121926664800A911A9 /* CCGLView.cpp in Sources */, + 3E2BDAE619C0329B0055CDCD /* AudioCache.mm in Sources */, 50ABC0021926664800A911A9 /* CCLock-apple.cpp in Sources */, 50ABBEBC1925AB6F00A911A9 /* ccUtils.cpp in Sources */, 15AE1A4719AAD3D500C27E9E /* b2ChainShape.cpp in Sources */, From 26142e1300bf75e1614c960f1d7cd79fdbe17183 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Wed, 10 Sep 2014 17:49:26 +0800 Subject: [PATCH 21/32] fix compile error on android. --- cocos/Android.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cocos/Android.mk b/cocos/Android.mk index 08873fb606..0b3dfa85c7 100644 --- a/cocos/Android.mk +++ b/cocos/Android.mk @@ -187,7 +187,7 @@ physics/chipmunk/CCPhysicsWorldInfo_chipmunk.cpp \ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \ $(LOCAL_PATH)/. \ - $(LOCAL_PATH)/platform/android \ + $(LOCAL_PATH)/platform \ $(LOCAL_PATH)/base \ $(LOCAL_PATH)/../external/tinyxml2 \ $(LOCAL_PATH)/../external/unzip \ @@ -197,7 +197,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \ LOCAL_C_INCLUDES := $(LOCAL_PATH) \ $(LOCAL_PATH)/. \ - $(LOCAL_PATH)/platform/android \ + $(LOCAL_PATH)/platform \ $(LOCAL_PATH)/../external \ $(LOCAL_PATH)/../external/tinyxml2 \ $(LOCAL_PATH)/../external/unzip \ From 11dcc37d4d42276f82f4d4d96bdab732d9181214 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Wed, 10 Sep 2014 09:51:56 -0700 Subject: [PATCH 22/32] Fixes cmakefile for mac --- cocos/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/CMakeLists.txt b/cocos/CMakeLists.txt index e1d889b96c..d4ced21da2 100644 --- a/cocos/CMakeLists.txt +++ b/cocos/CMakeLists.txt @@ -296,7 +296,7 @@ if(MACOSX) ${COCOS2D_BASE_SRC} ui/UIEditBox/UIEditBoxImpl-ios.mm ui/UIEditBox/UIEditBoxImpl-mac.mm - base/CCUserDefault.mm + base/CCUserDefault-apple.mm ) endif() From e46fa14be9af9ba52e8f0243da032db30412c860 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Wed, 10 Sep 2014 12:01:35 -0700 Subject: [PATCH 23/32] Fixes Xcode 6 warnings --- build/cocos2d_libs.xcodeproj/project.pbxproj | 10 +++------- build/cocos2d_tests.xcodeproj/project.pbxproj | 10 +--------- .../cocos2d_lua_bindings.xcodeproj/project.pbxproj | 6 +++--- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index a518e62b73..a10ddb016d 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -5749,7 +5749,7 @@ 1551A336158F2AB200E66CFE /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0500; + LastUpgradeCheck = 0600; ORGANIZATIONNAME = ""; }; buildConfigurationList = 1551A339158F2AB200E66CFE /* Build configuration list for PBXProject "cocos2d_libs" */; @@ -6610,7 +6610,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_BOOL_CONVERSION = YES; @@ -6648,7 +6647,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_BOOL_CONVERSION = YES; @@ -6683,7 +6681,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - ARCHS = "$(ARCHS_STANDARD)"; + COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = a; EXECUTABLE_PREFIX = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -6717,7 +6715,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - ARCHS = "$(ARCHS_STANDARD)"; + COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = a; EXECUTABLE_PREFIX = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; @@ -6752,7 +6750,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - ARCHS = "$(ARCHS_STANDARD)"; EXECUTABLE_PREFIX = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "../cocos/cocos2d-prefix.pch"; @@ -6784,7 +6781,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - ARCHS = "$(ARCHS_STANDARD)"; EXECUTABLE_PREFIX = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; diff --git a/build/cocos2d_tests.xcodeproj/project.pbxproj b/build/cocos2d_tests.xcodeproj/project.pbxproj index dec67dde2c..1a0d03b575 100644 --- a/build/cocos2d_tests.xcodeproj/project.pbxproj +++ b/build/cocos2d_tests.xcodeproj/project.pbxproj @@ -7319,7 +7319,7 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0510; + LastUpgradeCheck = 0600; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "cocos2d_tests" */; compatibilityVersion = "Xcode 3.2"; @@ -8557,7 +8557,6 @@ 1A0EE2B018CDF6DA004CD58F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD)"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", @@ -8572,7 +8571,6 @@ 1A0EE2B118CDF6DA004CD58F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD)"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", @@ -8588,7 +8586,6 @@ 1A0EE31218CDF733004CD58F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD)"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", CC_TARGET_OS_MAC, @@ -8608,7 +8605,6 @@ 1A0EE31318CDF733004CD58F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD)"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", CC_TARGET_OS_MAC, @@ -8703,7 +8699,6 @@ 1ABCA2B318CD91520087CE3A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD)"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", CC_TARGET_OS_MAC, @@ -8723,7 +8718,6 @@ 1ABCA2B418CD91520087CE3A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD)"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", CC_TARGET_OS_MAC, @@ -8785,7 +8779,6 @@ 1D6058940D05DD3E006BFB54 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD)"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", CC_TARGET_OS_MAC, @@ -8799,7 +8792,6 @@ 1D6058950D05DD3E006BFB54 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD)"; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", CC_TARGET_OS_MAC, diff --git a/cocos/scripting/lua-bindings/proj.ios_mac/cocos2d_lua_bindings.xcodeproj/project.pbxproj b/cocos/scripting/lua-bindings/proj.ios_mac/cocos2d_lua_bindings.xcodeproj/project.pbxproj index 260b98b268..05f642556d 100644 --- a/cocos/scripting/lua-bindings/proj.ios_mac/cocos2d_lua_bindings.xcodeproj/project.pbxproj +++ b/cocos/scripting/lua-bindings/proj.ios_mac/cocos2d_lua_bindings.xcodeproj/project.pbxproj @@ -871,7 +871,7 @@ 1551A336158F2AB200E66CFE /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0510; + LastUpgradeCheck = 0600; ORGANIZATIONNAME = ""; }; buildConfigurationList = 1551A339158F2AB200E66CFE /* Build configuration list for PBXProject "cocos2d_lua_bindings" */; @@ -1107,7 +1107,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_PREFIX = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ""; @@ -1129,7 +1129,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_PREFIX = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; From 7ca0203fdf86652aac68b874f2a3cb93ae143bcf Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Wed, 10 Sep 2014 16:26:32 -0700 Subject: [PATCH 24/32] Project Name is Cocos2d-X not Cocos2dX --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fcc2753a1..2550a3d7b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ # ****************************************************************************/ cmake_minimum_required(VERSION 2.8) -project (Cocos2dx) +project (Cocos2d-X) # The version number set(COCOS2D_X_VERSION 3.3.0) From 518fd7ab6fb5d0d7de9d512abc68813da4aa2045 Mon Sep 17 00:00:00 2001 From: Dhilan007 Date: Thu, 11 Sep 2014 10:53:01 +0800 Subject: [PATCH 25/32] Optimized seek for large file and log output on IOS. --- cocos/audio/ios/AudioCache.h | 7 +- cocos/audio/ios/AudioCache.mm | 38 ++++----- cocos/audio/ios/AudioEngine-inl.mm | 24 +++--- cocos/audio/ios/AudioPlayer.h | 12 ++- cocos/audio/ios/AudioPlayer.mm | 121 +++++++++-------------------- 5 files changed, 77 insertions(+), 125 deletions(-) diff --git a/cocos/audio/ios/AudioCache.h b/cocos/audio/ios/AudioCache.h index 4ba29807d6..603350e507 100644 --- a/cocos/audio/ios/AudioCache.h +++ b/cocos/audio/ios/AudioCache.h @@ -36,6 +36,7 @@ #include "CCPlatformMacros.h" #define QUEUEBUFFER_NUM 3 +#define QUEUEBUFFER_TIME_STEP 0.1 NS_CC_BEGIN @@ -51,7 +52,7 @@ public: private: - void readDataThread(); + void readDataTask(); void invokingCallbacks(); @@ -81,9 +82,9 @@ private: std::mutex _callbackMutex; std::vector< std::function > _callbacks; - std::mutex _readThreadMutex; + std::mutex _readDataTaskMutex; - bool _release; + bool _exitReadDataTask; std::string _fileFullPath; friend class AudioEngineImpl; diff --git a/cocos/audio/ios/AudioCache.mm b/cocos/audio/ios/AudioCache.mm index 6f9fbbd384..33fae2fb40 100644 --- a/cocos/audio/ios/AudioCache.mm +++ b/cocos/audio/ios/AudioCache.mm @@ -49,7 +49,7 @@ AudioCache::AudioCache() : _pcmData(nullptr) , _dataSize(0) , _bytesOfRead(0) -, _release(false) +, _exitReadDataTask(false) , _queBufferFrames(0) , _queBufferBytes(0) , _alBufferReady(false) @@ -59,13 +59,15 @@ AudioCache::AudioCache() AudioCache::~AudioCache() { - _release = true; + _exitReadDataTask = true; if(_pcmData){ - if (_alBufferReady) + if (_alBufferReady){ alDeleteBuffers(1, &_alBufferId); + } + //wait for the 'readDataTask' task to exit + _readDataTaskMutex.lock(); + _readDataTaskMutex.unlock(); - _readThreadMutex.lock(); - _readThreadMutex.unlock(); free(_pcmData); } @@ -76,9 +78,9 @@ AudioCache::~AudioCache() } } -void AudioCache::readDataThread() +void AudioCache::readDataTask() { - _readThreadMutex.lock(); + _readDataTaskMutex.lock(); AudioStreamBasicDescription theFileFormat; UInt32 thePropertySize = sizeof(theFileFormat); @@ -94,18 +96,18 @@ void AudioCache::readDataThread() auto error = ExtAudioFileOpenURL(fileURL, &extRef); if(error) { - printf("readDataThread: ExtAudioFileOpenURL FAILED, Error = %d\n", error); + printf("%s: ExtAudioFileOpenURL FAILED, Error = %d\n", __PRETTY_FUNCTION__, error); goto ExitThread; } // Get the audio data format error = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat); if(error) { - printf("readDataThread: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %d\n", (int)error); + printf("%s: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %d\n", __PRETTY_FUNCTION__, error); goto ExitThread; } if (theFileFormat.mChannelsPerFrame > 2) { - printf("readDataThread: Unsupported Format, channel count is greater than stereo\n"); + printf("%s: Unsupported Format, channel count is greater than stereo\n",__PRETTY_FUNCTION__); goto ExitThread; } @@ -124,7 +126,7 @@ void AudioCache::readDataThread() error = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(outputFormat), &outputFormat); if(error) { - printf("readDataThread: ExtAudioFileSetProperty FAILED, Error = %d\n", (int)error); + printf("%s: ExtAudioFileSetProperty FAILED, Error = %d\n", __PRETTY_FUNCTION__, error); goto ExitThread; } @@ -132,7 +134,7 @@ void AudioCache::readDataThread() thePropertySize = sizeof(theFileLengthInFrames); error = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames); if(error) { - printf("initOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %d\n", (int)error); + printf("%s: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %d\n", __PRETTY_FUNCTION__, error); goto ExitThread; } @@ -146,12 +148,12 @@ void AudioCache::readDataThread() alGenBuffers(1, &_alBufferId); auto alError = alGetError(); if (alError != AL_NO_ERROR) { - printf("error attaching audio to buffer: %x\n", alError); + printf("%s: attaching audio to buffer fail: %x\n", __PRETTY_FUNCTION__, alError); goto ExitThread; } alBufferDataStaticProc(_alBufferId, _format, _pcmData, _dataSize, _sampleRate); - readInFrames = theFileFormat.mSampleRate * 0.6; + readInFrames = theFileFormat.mSampleRate * QUEUEBUFFER_TIME_STEP * QUEUEBUFFER_NUM; dataSize = outputFormat.mBytesPerFrame * readInFrames; if (dataSize > _dataSize) { dataSize = _dataSize; @@ -168,7 +170,7 @@ void AudioCache::readDataThread() _bytesOfRead += dataSize; invokingCallbacks(); - while (!_release && _bytesOfRead + dataSize < _dataSize) { + while (!_exitReadDataTask && _bytesOfRead + dataSize < _dataSize) { theDataBuffer.mBuffers[0].mData = _pcmData + _bytesOfRead; frames = readInFrames; ExtAudioFileRead(extRef, (UInt32*)&frames, &theDataBuffer); @@ -176,7 +178,7 @@ void AudioCache::readDataThread() } dataSize = _dataSize - _bytesOfRead; - if (dataSize > 0) { + if (!_exitReadDataTask && dataSize > 0) { theDataBuffer.mBuffers[0].mDataByteSize = (UInt32)dataSize; theDataBuffer.mBuffers[0].mData = _pcmData + _bytesOfRead; frames = readInFrames; @@ -186,7 +188,7 @@ void AudioCache::readDataThread() _bytesOfRead = _dataSize; } else{ - _queBufferFrames = theFileFormat.mSampleRate * 0.2; + _queBufferFrames = theFileFormat.mSampleRate * QUEUEBUFFER_TIME_STEP; _queBufferBytes = _queBufferFrames * outputFormat.mBytesPerFrame; theDataBuffer.mNumberBuffers = QUEUEBUFFER_NUM; @@ -207,7 +209,7 @@ ExitThread: if (extRef) ExtAudioFileDispose(extRef); - _readThreadMutex.unlock(); + _readDataTaskMutex.unlock(); if (_queBufferFrames > 0) _alBufferReady = true; diff --git a/cocos/audio/ios/AudioEngine-inl.mm b/cocos/audio/ios/AudioEngine-inl.mm index a23c81a1fe..e81ade8588 100644 --- a/cocos/audio/ios/AudioEngine-inl.mm +++ b/cocos/audio/ios/AudioEngine-inl.mm @@ -175,7 +175,7 @@ bool AudioEngineImpl::init() alError = alGetError(); if(alError != AL_NO_ERROR) { - printf("Error generating sources! %x\n", alError); + printf("%s:generating sources fail! error = %x\n", __PRETTY_FUNCTION__, alError); break; } @@ -217,7 +217,7 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume audioCache = &_audioCaches[filePath]; audioCache->_fileFullPath = FileUtils::getInstance()->fullPathForFilename(filePath); - _threadPool->addTask(std::bind(&AudioCache::readDataThread, audioCache)); + _threadPool->addTask(std::bind(&AudioCache::readDataTask, audioCache)); } else { audioCache = &it->second; @@ -274,7 +274,7 @@ void AudioEngineImpl::setVolume(int audioID,float volume) auto error = alGetError(); if (error != AL_NO_ERROR) { - printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + printf("%s: audio id = %d, error = %x\n", __PRETTY_FUNCTION__,audioID,error); } } } @@ -284,7 +284,7 @@ void AudioEngineImpl::setLoop(int audioID, bool loop) auto& player = _audioPlayers[audioID]; if (player._ready) { - if (player._largeFile) { + if (player._streamingSource) { player.setLoop(loop); } else { if (loop) { @@ -295,7 +295,7 @@ void AudioEngineImpl::setLoop(int audioID, bool loop) auto error = alGetError(); if (error != AL_NO_ERROR) { - printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + printf("%s: audio id = %d, error = %x\n", __PRETTY_FUNCTION__,audioID,error); } } } @@ -312,7 +312,7 @@ bool AudioEngineImpl::pause(int audioID) auto error = alGetError(); if (error != AL_NO_ERROR) { ret = false; - printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + printf("%s: audio id = %d, error = %x\n", __PRETTY_FUNCTION__,audioID,error); } return ret; @@ -326,7 +326,7 @@ bool AudioEngineImpl::resume(int audioID) auto error = alGetError(); if (error != AL_NO_ERROR) { ret = false; - printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + printf("%s: audio id = %d, error = %x\n", __PRETTY_FUNCTION__,audioID,error); } return ret; @@ -342,7 +342,7 @@ bool AudioEngineImpl::stop(int audioID) auto error = alGetError(); if (error != AL_NO_ERROR) { ret = false; - printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + printf("%s: audio id = %d, error = %x\n", __PRETTY_FUNCTION__,audioID,error); } } @@ -381,7 +381,7 @@ float AudioEngineImpl::getCurrentTime(int audioID) float ret = 0.0f; auto& player = _audioPlayers[audioID]; if(player._ready){ - if (player._largeFile) { + if (player._streamingSource) { ret = player.getTime(); } else { alGetSourcef(player._alSource, AL_SEC_OFFSET, &ret); @@ -406,14 +406,14 @@ bool AudioEngineImpl::setCurrentTime(int audioID, float time) break; } - if (player._largeFile) { + if (player._streamingSource) { ret = player.setTime(time); break; } else { if (player._audioCache->_bytesOfRead != player._audioCache->_dataSize && (time * player._audioCache->_sampleRate * player._audioCache->_bytesPerFrame) > player._audioCache->_bytesOfRead) { - printf("setCurrentTime fail for audio %d",audioID); + printf("%s: audio id = %d\n", __PRETTY_FUNCTION__,audioID); break; } @@ -421,7 +421,7 @@ bool AudioEngineImpl::setCurrentTime(int audioID, float time) auto error = alGetError(); if (error != AL_NO_ERROR) { - printf("%s, audio id:%d,error code:%x", __PRETTY_FUNCTION__,audioID,error); + printf("%s: audio id = %d, error = %x\n", __PRETTY_FUNCTION__,audioID,error); } ret = true; } diff --git a/cocos/audio/ios/AudioPlayer.h b/cocos/audio/ios/AudioPlayer.h index 8903578aca..76d9e3ad31 100644 --- a/cocos/audio/ios/AudioPlayer.h +++ b/cocos/audio/ios/AudioPlayer.h @@ -60,15 +60,13 @@ private: ALuint _alSource; //play by circular buffer - bool _largeFile; - ALuint _bufferIds[3]; - int _bufferIndex; - int _frameIndex; float _currTime; - std::mutex _rotateBufferMtx; + bool _streamingSource; + ALuint _bufferIds[3]; + std::thread _rotateBufferThread; std::timed_mutex _timeMtx; - - bool _release; + bool _exitThread; + bool _timeDirty; friend class AudioEngineImpl; }; diff --git a/cocos/audio/ios/AudioPlayer.mm b/cocos/audio/ios/AudioPlayer.mm index fb540c0c68..c7d93216d4 100644 --- a/cocos/audio/ios/AudioPlayer.mm +++ b/cocos/audio/ios/AudioPlayer.mm @@ -29,8 +29,9 @@ using namespace cocos2d; AudioPlayer::AudioPlayer() -: _release(false) -, _largeFile(false) +: _exitThread(false) +, _timeDirty(false) +, _streamingSource(false) , _currTime(0.0f) , _finishCallbak(nullptr) , _ready(false) @@ -41,18 +42,18 @@ AudioPlayer::AudioPlayer() AudioPlayer::~AudioPlayer() { - _release = true; + _exitThread = true; if (_audioCache && _audioCache->_queBufferFrames > 0) { _timeMtx.unlock(); - _rotateBufferMtx.lock(); - _rotateBufferMtx.unlock(); + if (_rotateBufferThread.joinable()) { + _rotateBufferThread.join(); + } alDeleteBuffers(3, _bufferIds); } } bool AudioPlayer::play2d(AudioCache* cache) { - bool ret = true; if (!cache->_alBufferReady) { return false; } @@ -72,7 +73,7 @@ bool AudioPlayer::play2d(AudioCache* cache) alSourcei(_alSource, AL_BUFFER, _audioCache->_alBufferId); } else { - _largeFile = true; + _streamingSource = true; auto alError = alGetError(); alGenBuffers(3, _bufferIds); @@ -85,12 +86,11 @@ bool AudioPlayer::play2d(AudioCache* cache) alSourceQueueBuffers(_alSource, QUEUEBUFFER_NUM, _bufferIds); _timeMtx.lock(); - auto rotateThread = std::thread(&AudioPlayer::rotateBufferThread,this, _audioCache->_queBufferFrames * QUEUEBUFFER_NUM + 1); - rotateThread.detach(); + _rotateBufferThread = std::thread(&AudioPlayer::rotateBufferThread,this, _audioCache->_queBufferFrames * QUEUEBUFFER_NUM + 1); } else { - printf("error:%s, error code:%x", __PRETTY_FUNCTION__,alError); - ret = false; + printf("%s:alGenBuffers error code:%x", __PRETTY_FUNCTION__,alError); + return false; } } @@ -99,17 +99,16 @@ bool AudioPlayer::play2d(AudioCache* cache) auto alError = alGetError(); if (alError != AL_NO_ERROR) { - ret = false; - printf("error:%s, error code:%x\n", __PRETTY_FUNCTION__,alError); + printf("%s:alSourcePlay error code:%x\n", __PRETTY_FUNCTION__,alError); + return false; } - return ret; + return true; } void AudioPlayer::rotateBufferThread(int offsetFrame) { - _rotateBufferMtx.lock(); - printf("%s start\n",__func__); + printf("%s start\n",__PRETTY_FUNCTION__); ALint sourceState; ALint bufferProcessed = 0; @@ -121,7 +120,7 @@ void AudioPlayer::rotateBufferThread(int offsetFrame) auto error = ExtAudioFileOpenURL(fileURL, &extRef); if(error) { - printf("rotateBufferThread: ExtAudioFileOpenURL FAILED, Error = %d\n", error); + printf("%s: ExtAudioFileOpenURL FAILED, Error = %d\n", __PRETTY_FUNCTION__, error); goto ExitBufferThread; } @@ -136,19 +135,25 @@ void AudioPlayer::rotateBufferThread(int offsetFrame) ExtAudioFileSeek(extRef, offsetFrame); } - while (!_release) { + while (!_exitThread) { alGetSourcei(_alSource, AL_SOURCE_STATE, &sourceState); if (sourceState == AL_PLAYING) { alGetSourcei(_alSource, AL_BUFFERS_PROCESSED, &bufferProcessed); while (bufferProcessed > 0) { bufferProcessed--; - - _currTime += 0.2f; - if (_currTime > _audioCache->_duration) { - if (_loop) { - _currTime = 0.0f; - } else { - _currTime = _audioCache->_duration; + if (_timeDirty) { + _timeDirty = false; + offsetFrame = _currTime * _audioCache->outputFormat.mSampleRate; + ExtAudioFileSeek(extRef, offsetFrame); + } + else { + _currTime += QUEUEBUFFER_TIME_STEP; + if (_currTime > _audioCache->_duration) { + if (_loop) { + _currTime = 0.0f; + } else { + _currTime = _audioCache->_duration; + } } } @@ -161,6 +166,7 @@ void AudioPlayer::rotateBufferThread(int offsetFrame) theDataBuffer.mBuffers[0].mDataByteSize = _audioCache->_queBufferBytes; ExtAudioFileRead(extRef, (UInt32*)&frames, &theDataBuffer); } else { + _exitThread = true; break; } } @@ -172,7 +178,7 @@ void AudioPlayer::rotateBufferThread(int offsetFrame) } } - _timeMtx.try_lock_for(std::chrono::milliseconds(100)); + _timeMtx.try_lock_for(std::chrono::milliseconds(50)); } ExitBufferThread: @@ -182,21 +188,13 @@ ExitBufferThread: ExtAudioFileDispose(extRef); } free(tmpBuffer); - _rotateBufferMtx.unlock(); - printf("%s end\n",__func__); + printf("%s: end\n",__PRETTY_FUNCTION__); } bool AudioPlayer::setLoop(bool loop) { - if (!_release ) { + if (!_exitThread ) { _loop = loop; - if (_rotateBufferMtx.try_lock() && loop) { - _rotateBufferMtx.unlock(); - - auto rotateThread = std::thread(&AudioPlayer::rotateBufferThread,this, 0); - rotateThread.detach(); - } - return true; } @@ -205,57 +203,10 @@ bool AudioPlayer::setLoop(bool loop) bool AudioPlayer::setTime(float time) { - return false; - - if (!_release && time >= 0.0f && time < _audioCache->_duration) { - _release = true; - _timeMtx.unlock(); - _rotateBufferMtx.lock(); - _rotateBufferMtx.unlock(); + if (!_exitThread && time >= 0.0f && time < _audioCache->_duration) { _currTime = time; - alSourcei(_alSource, AL_BUFFER, NULL); - - ExtAudioFileRef extRef = nullptr; - AudioBufferList theDataBuffer; - char* bufferData[QUEUEBUFFER_NUM]; - - auto fileURL = (CFURLRef)[[NSURL fileURLWithPath:[NSString stringWithCString:_audioCache->_fileFullPath.c_str() encoding:[NSString defaultCStringEncoding]]] retain]; - auto error = ExtAudioFileOpenURL(fileURL, &extRef); - error = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(_audioCache->outputFormat), &_audioCache->outputFormat); - - theDataBuffer.mNumberBuffers = QUEUEBUFFER_NUM; - for (int index = 0; index < QUEUEBUFFER_NUM; ++index) { - bufferData[index] = (char*)malloc(_audioCache->_queBufferBytes); - - theDataBuffer.mBuffers[index].mDataByteSize = _audioCache->_queBufferBytes; - theDataBuffer.mBuffers[index].mNumberChannels = _audioCache->outputFormat.mChannelsPerFrame; - theDataBuffer.mBuffers[index].mData = bufferData[index]; - } - - int offsetFrames = time * _audioCache->outputFormat.mSampleRate; - if (offsetFrames != 0) { - error = ExtAudioFileSeek(extRef, offsetFrames); - } - - UInt32 frames = _audioCache->_queBufferFrames * QUEUEBUFFER_NUM; - ExtAudioFileRead(extRef, (UInt32*)&frames, &theDataBuffer); - - for (int index = 0; index < theDataBuffer.mNumberBuffers; ++index) { - alBufferData(_bufferIds[index], _audioCache->_format, bufferData[index], theDataBuffer.mBuffers[index].mDataByteSize, _audioCache->_sampleRate); - free(bufferData[index]); - } - alSourceQueueBuffers(_alSource, theDataBuffer.mNumberBuffers, _bufferIds); - - ExitSetTime: - CFRelease(fileURL); - // Dispose the ExtAudioFileRef, it is no longer needed - if (extRef){ - ExtAudioFileDispose(extRef); - } - - auto rotateThread = std::thread(&AudioPlayer::rotateBufferThread,this, offsetFrames + QUEUEBUFFER_NUM * _audioCache->_queBufferFrames+ 1); - rotateThread.detach(); + _timeDirty = true; return true; } From 1945c4f31ef86c9abfad617ac6d4f03a3bb45c6d Mon Sep 17 00:00:00 2001 From: andyque Date: Thu, 11 Sep 2014 14:45:55 +0800 Subject: [PATCH 26/32] fix compile error --- cocos/2d/cocos2d_headers.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/2d/cocos2d_headers.props b/cocos/2d/cocos2d_headers.props index aaaefd1c7d..06da521592 100644 --- a/cocos/2d/cocos2d_headers.props +++ b/cocos/2d/cocos2d_headers.props @@ -7,7 +7,7 @@ - $(EngineRoot)cocos;$(EngineRoot)cocos\platform\win32;$(EngineRoot)cocos\platform\desktop;$(EngineRoot)external\glfw3\include\win32;$(EngineRoot)external\win32-specific\gles\include\OGLES + $(EngineRoot)cocos;$(EngineRoot)cocos\platform;$(EngineRoot)cocos\platform\desktop;$(EngineRoot)external\glfw3\include\win32;$(EngineRoot)external\win32-specific\gles\include\OGLES _VARIADIC_MAX=10;%(PreprocessorDefinitions) From 11005a6ce977f2af3d3d9337a254b8462a69d713 Mon Sep 17 00:00:00 2001 From: CocosRobot Date: Thu, 11 Sep 2014 06:48:54 +0000 Subject: [PATCH 27/32] [AUTO][ci skip]: updating cocos2dx_files.json --- templates/cocos2dx_files.json | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/cocos2dx_files.json b/templates/cocos2dx_files.json index d7ce573238..b6c10fe734 100644 --- a/templates/cocos2dx_files.json +++ b/templates/cocos2dx_files.json @@ -662,6 +662,7 @@ "cocos/math/MathUtil.h", "cocos/math/MathUtil.inl", "cocos/math/MathUtilNeon.inl", + "cocos/math/MathUtilSSE.inl", "cocos/math/Quaternion.cpp", "cocos/math/Quaternion.h", "cocos/math/Quaternion.inl", From 561ec7ea7bcdf5579cbb443df302694ba1c3b5e6 Mon Sep 17 00:00:00 2001 From: minggo Date: Thu, 11 Sep 2014 15:09:12 +0800 Subject: [PATCH 28/32] [ci skip] --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index 10cfacd141..135b64cca9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -997,6 +997,9 @@ Developers: jagd Added setSubsteps() and getSubsteps() in PhysicsWorld + + denpen + Fixed a bug that scroll view hidden picks up the touch events. Retired Core Developers: WenSheng Yang From 04d4df54c01d158930b147dfd8ff9d6e27a9c49c Mon Sep 17 00:00:00 2001 From: minggo Date: Thu, 11 Sep 2014 15:10:45 +0800 Subject: [PATCH 29/32] [ci skip] --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index d64df950a5..a96b28b486 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,7 @@ cocos2d-x-3.3?? ?? [FIX] Node: create unneeded temple `Vec2` object in `setPosition(int, int)`, `setPositionX()` and `setPositionY()` [FIX] Node: skew effect is wrong [FIX] Node: setNormalizedPosition can not take effect if parent position is not changed + [FIX] External: ScrollView: scroll view hidden picks up the touch events [FIX] TextureAtlas: may crash if only drawing part of it cocos2d-x-3.3alpha0 Aug.28 2014 From 434d4fbfdd87ab410bb9fcf926ee6b0296b08cac Mon Sep 17 00:00:00 2001 From: CocosRobot Date: Thu, 11 Sep 2014 07:11:40 +0000 Subject: [PATCH 30/32] [AUTO]: updating luabinding automatically --- .../auto/lua_cocos2dx_extension_auto.cpp | 45 +++++++++++++++++++ .../auto/lua_cocos2dx_extension_auto.hpp | 1 + 2 files changed, 46 insertions(+) diff --git a/cocos/scripting/lua-bindings/auto/lua_cocos2dx_extension_auto.cpp b/cocos/scripting/lua-bindings/auto/lua_cocos2dx_extension_auto.cpp index 6958a28aa3..1f1c29dacd 100644 --- a/cocos/scripting/lua-bindings/auto/lua_cocos2dx_extension_auto.cpp +++ b/cocos/scripting/lua-bindings/auto/lua_cocos2dx_extension_auto.cpp @@ -8511,6 +8511,50 @@ int lua_cocos2dx_extension_ScrollView_setMaxScale(lua_State* tolua_S) return 0; } +int lua_cocos2dx_extension_ScrollView_hasVisibleParents(lua_State* tolua_S) +{ + int argc = 0; + cocos2d::extension::ScrollView* cobj = nullptr; + bool ok = true; + +#if COCOS2D_DEBUG >= 1 + tolua_Error tolua_err; +#endif + + +#if COCOS2D_DEBUG >= 1 + if (!tolua_isusertype(tolua_S,1,"cc.ScrollView",0,&tolua_err)) goto tolua_lerror; +#endif + + cobj = (cocos2d::extension::ScrollView*)tolua_tousertype(tolua_S,1,0); + +#if COCOS2D_DEBUG >= 1 + if (!cobj) + { + tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_extension_ScrollView_hasVisibleParents'", nullptr); + return 0; + } +#endif + + argc = lua_gettop(tolua_S)-1; + if (argc == 0) + { + if(!ok) + return 0; + bool ret = cobj->hasVisibleParents(); + tolua_pushboolean(tolua_S,(bool)ret); + return 1; + } + CCLOG("%s has wrong number of arguments: %d, was expecting %d \n", "cc.ScrollView:hasVisibleParents",argc, 0); + return 0; + +#if COCOS2D_DEBUG >= 1 + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_extension_ScrollView_hasVisibleParents'.",&tolua_err); +#endif + + return 0; +} int lua_cocos2dx_extension_ScrollView_getDirection(lua_State* tolua_S) { int argc = 0; @@ -9937,6 +9981,7 @@ int lua_register_cocos2dx_extension_ScrollView(lua_State* tolua_S) tolua_function(tolua_S,"setZoomScaleInDuration",lua_cocos2dx_extension_ScrollView_setZoomScaleInDuration); tolua_function(tolua_S,"updateTweenAction",lua_cocos2dx_extension_ScrollView_updateTweenAction); tolua_function(tolua_S,"setMaxScale",lua_cocos2dx_extension_ScrollView_setMaxScale); + tolua_function(tolua_S,"hasVisibleParents",lua_cocos2dx_extension_ScrollView_hasVisibleParents); tolua_function(tolua_S,"getDirection",lua_cocos2dx_extension_ScrollView_getDirection); tolua_function(tolua_S,"getContainer",lua_cocos2dx_extension_ScrollView_getContainer); tolua_function(tolua_S,"setMinScale",lua_cocos2dx_extension_ScrollView_setMinScale); diff --git a/cocos/scripting/lua-bindings/auto/lua_cocos2dx_extension_auto.hpp b/cocos/scripting/lua-bindings/auto/lua_cocos2dx_extension_auto.hpp index cbd41e6a6b..483cbe013a 100644 --- a/cocos/scripting/lua-bindings/auto/lua_cocos2dx_extension_auto.hpp +++ b/cocos/scripting/lua-bindings/auto/lua_cocos2dx_extension_auto.hpp @@ -262,6 +262,7 @@ int register_all_cocos2dx_extension(lua_State* tolua_S); + #endif // __cocos2dx_extension_h__ From 4106596f9da7b02528e46e143910aacaa3bbf279 Mon Sep 17 00:00:00 2001 From: minggo Date: Thu, 11 Sep 2014 15:24:22 +0800 Subject: [PATCH 31/32] [ci skip] --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index a96b28b486..84aed66e37 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ cocos2d-x-3.3?? ?? [NEW] ActionManager: added removeAllActionsByTag() + [NEW] Audio: added new audio system for iOS and Android [NEW] GLViewProtocol: added getAllTouches() [NEW] Node: added stopAllActionsByTag() [NEW] PhysicsWorld: add setSubsteps() and getSubsteps() From 67ad24e7c13703a5a6c8305a342cd1a4b59a8bb6 Mon Sep 17 00:00:00 2001 From: andyque Date: Thu, 11 Sep 2014 15:44:31 +0800 Subject: [PATCH 32/32] remove orderOfArrival = 0 --- cocos/2d/CCNodeGrid.cpp | 5 +++-- cocos/2d/CCProtectedNode.cpp | 5 +++-- cocos/2d/CCRenderTexture.cpp | 4 +++- cocos/editor-support/cocostudio/CCArmature.cpp | 5 +++-- cocos/editor-support/cocostudio/CCBatchNode.cpp | 5 +++-- cocos/ui/UIScale9Sprite.cpp | 5 +++-- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/cocos/2d/CCNodeGrid.cpp b/cocos/2d/CCNodeGrid.cpp index eb42030199..2153b9dca2 100644 --- a/cocos/2d/CCNodeGrid.cpp +++ b/cocos/2d/CCNodeGrid.cpp @@ -150,8 +150,9 @@ void NodeGrid::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t p this->draw(renderer, _modelViewTransform, dirty); } - // reset for next frame - _orderOfArrival = 0; + // FIX ME: Why need to set _orderOfArrival to 0?? + // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920 + // setOrderOfArrival(0); if(_nodeGrid && _nodeGrid->isActive()) { diff --git a/cocos/2d/CCProtectedNode.cpp b/cocos/2d/CCProtectedNode.cpp index d65ca6a7b5..3a8259b48d 100644 --- a/cocos/2d/CCProtectedNode.cpp +++ b/cocos/2d/CCProtectedNode.cpp @@ -330,8 +330,9 @@ void ProtectedNode::visit(Renderer* renderer, const Mat4 &parentTransform, uint3 for(auto it=_children.cbegin()+i; it != _children.cend(); ++it) (*it)->visit(renderer, _modelViewTransform, flags); - // reset for next frame - _orderOfArrival = 0; + // FIX ME: Why need to set _orderOfArrival to 0?? + // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920 + // setOrderOfArrival(0); director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); } diff --git a/cocos/2d/CCRenderTexture.cpp b/cocos/2d/CCRenderTexture.cpp index 13fed5a85e..201cf0cfc1 100644 --- a/cocos/2d/CCRenderTexture.cpp +++ b/cocos/2d/CCRenderTexture.cpp @@ -403,7 +403,9 @@ void RenderTexture::visit(Renderer *renderer, const Mat4 &parentTransform, uint3 director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); - _orderOfArrival = 0; + // FIX ME: Why need to set _orderOfArrival to 0?? + // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920 + // setOrderOfArrival(0); } bool RenderTexture::saveToFile(const std::string& filename, bool isRGBA, std::function callback) diff --git a/cocos/editor-support/cocostudio/CCArmature.cpp b/cocos/editor-support/cocostudio/CCArmature.cpp index a005e23127..62517e1604 100644 --- a/cocos/editor-support/cocostudio/CCArmature.cpp +++ b/cocos/editor-support/cocostudio/CCArmature.cpp @@ -486,8 +486,9 @@ void Armature::visit(cocos2d::Renderer *renderer, const Mat4 &parentTransform, u sortAllChildren(); draw(renderer, _modelViewTransform, flags); - // reset for next frame - _orderOfArrival = 0; + // FIX ME: Why need to set _orderOfArrival to 0?? + // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920 + // setOrderOfArrival(0); director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); } diff --git a/cocos/editor-support/cocostudio/CCBatchNode.cpp b/cocos/editor-support/cocostudio/CCBatchNode.cpp index c8128748f3..19d339d6c7 100644 --- a/cocos/editor-support/cocostudio/CCBatchNode.cpp +++ b/cocos/editor-support/cocostudio/CCBatchNode.cpp @@ -124,8 +124,9 @@ void BatchNode::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t sortAllChildren(); draw(renderer, _modelViewTransform, flags); - // reset for next frame - _orderOfArrival = 0; + // FIX ME: Why need to set _orderOfArrival to 0?? + // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920 + // setOrderOfArrival(0); director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); } diff --git a/cocos/ui/UIScale9Sprite.cpp b/cocos/ui/UIScale9Sprite.cpp index 13f6f2f92d..f5e61c659e 100644 --- a/cocos/ui/UIScale9Sprite.cpp +++ b/cocos/ui/UIScale9Sprite.cpp @@ -814,8 +814,9 @@ y+=ytranslate; \ for(auto it=_children.cbegin()+i; it != _children.cend(); ++it) (*it)->visit(renderer, _modelViewTransform, flags); - // reset for next frame - _orderOfArrival = 0; + // FIX ME: Why need to set _orderOfArrival to 0?? + // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920 + // setOrderOfArrival(0); director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);