Skip to content

Commit 82c187f

Browse files
committed
Merge commit 'refs/pull/18383/head' of https://github.com/cocos2d/cocos2d-x into scgamex-v3
# Conflicts: # cocos/audio/AudioEngine.cpp
2 parents 8090172 + c1d69b0 commit 82c187f

File tree

4 files changed

+87
-6
lines changed

4 files changed

+87
-6
lines changed

cocos/audio/AudioEngine.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, fl
209209
// Steve: added check for null profileHelper
210210
if (profile && (!profileHelper || profile != &profileHelper->profile))
211211
{
212+
#warning FIXME: may want to comment out assert for release? (though it should by default in release build)
213+
CC_ASSERT(!profile->name.empty()); // NOTE: may cause issues that were previously ignored, but should probably resolve them
212214
CCLOGINFO("profile = %p, profileHelper = %p, profile->name = %s", profile, profileHelper, profile->name.c_str());
213215
profileHelper = &_audioPathProfileHelperMap[profile->name];
214216
profileHelper->profile = *profile;
@@ -220,8 +222,25 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, fl
220222
// TODO: consider this PR - https://github.com/cocos2d/cocos2d-x/pull/18383
221223
// - to allow play by removing oldest instance
222224
if (_audioIDInfoMap.size() >= _maxInstances) {
223-
CCLOGERROR("Fail to play %s cause by limited max instance of AudioEngine",filePath.c_str());
224-
break;
225+
double oldestTimestamp = std::numeric_limits<double>::max();
226+
int oldestId = INVALID_AUDIO_ID;
227+
std::string ofilePath;
228+
for(auto it = _audioIDInfoMap.begin(); it != _audioIDInfoMap.end(); ++it){
229+
if(it->second.timestamp < oldestTimestamp && !it->second.loop){
230+
oldestId = it->first;
231+
oldestTimestamp = it->second.timestamp;
232+
ofilePath = *it->second.filePath;
233+
}
234+
}
235+
236+
if(oldestId == INVALID_AUDIO_ID){
237+
CCLOG("Fail to play %s cause by limited max instance of AudioEngine", filePath.c_str());
238+
break;
239+
}
240+
241+
CCLOG("Max instance limit of AudioEngine exceeded. Stopping the oldest sound with id: %d and path: %s", oldestId, ofilePath.c_str());
242+
243+
AudioEngine::stop(oldestId);
225244
}
226245

227246
if (profileHelper)
@@ -256,6 +275,7 @@ int AudioEngine::play2d(const std::string& filePath, bool loop, float volume, fl
256275
audioRef.volume = volume;
257276
audioRef.loop = loop;
258277
audioRef.filePath = &it->first;
278+
audioRef.timestamp = utils::gettime();
259279

260280
if (profileHelper) {
261281
profileHelper->lastPlayTime = utils::gettime();
@@ -375,6 +395,7 @@ void AudioEngine::stopAll()
375395
void AudioEngine::uncache(const std::string &filePath)
376396
{
377397
if(!_audioEngineImpl){
398+
// TODO: any reason we should assert this instead? Why would it ever be null?
378399
return;
379400
}
380401
auto audioIDsIter = _audioPathIDMap.find(filePath);

cocos/audio/include/AudioEngine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ class EXPORT_DLL AudioEngine
335335
bool loop;
336336
float duration;
337337
AudioState state;
338+
double timestamp;
338339

339340
AudioInfo();
340341
~AudioInfo();

tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.cpp

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ using namespace cocos2d::experimental;
3232

3333
AudioEngineTests::AudioEngineTests()
3434
{
35+
ADD_TEST_CASE(AudioIssueMaxInstanceTest);
3536
ADD_TEST_CASE(AudioIssue11143Test);
3637
ADD_TEST_CASE(AudioControlTest);
3738
ADD_TEST_CASE(AudioLoadTest);
@@ -651,12 +652,59 @@ std::string LargeAudioFileTest::title() const
651652
return "Test large audio file";
652653
}
653654

654-
bool AudioIssue11143Test::init()
655+
bool AudioIssueMaxInstanceTest::init()
655656
{
656657
if (AudioEngineTestDemo::init())
657658
{
658659
auto& layerSize = this->getContentSize();
660+
661+
auto playItem = TextButton::create("play", [](TextButton* button){
662+
float diff = 0.05f;
663+
664+
AudioEngine::play2d("background.wav", true);
665+
666+
for(int i = 0; i < 200; i++){
667+
float delay = diff * (i + 1);
668+
int j = i % 10 + 81;
669+
670+
char buff1[255];
671+
snprintf(buff1, sizeof(buff1), "k%d", i);
672+
std::string key = buff1;
673+
674+
char buff2[255];
675+
snprintf(buff2, sizeof(buff2), "audio/SoundEffectsFX009/FX0%d.mp3", j);
676+
std::string path = buff2;
677+
678+
button->scheduleOnce([path](float dt){
679+
AudioEngine::play2d(path);
680+
}, delay, key);
681+
}
682+
});
683+
playItem->setPosition(layerSize.width * 0.5f, layerSize.height * 0.5f);
684+
addChild(playItem);
685+
686+
return true;
687+
}
688+
689+
return false;
690+
}
659691

692+
std::string AudioIssueMaxInstanceTest::title() const
693+
{
694+
return "Max instance exceeded issue test";
695+
}
696+
697+
std::string AudioIssueMaxInstanceTest::subtitle() const
698+
{
699+
return "There shouldn't be any blank break in sound.\nBackground music shouldn't stop.";
700+
}
701+
702+
bool AudioIssue11143Test::init()
703+
{
704+
if (AudioEngineTestDemo::init())
705+
{
706+
auto& layerSize = this->getContentSize();
707+
660708
auto playItem = TextButton::create("play", [](TextButton* button){
661709
AudioEngine::play2d("audio/SoundEffectsFX009/FX082.mp3", true);
662710
AudioEngine::stopAll();
@@ -668,14 +716,14 @@ bool AudioIssue11143Test::init()
668716
AudioEngine::stop(audioId);
669717
AudioEngine::play2d("audio/SoundEffectsFX009/FX083.mp3");
670718
}, 0.3f, key);
671-
719+
672720
});
673721
playItem->setPosition(layerSize.width * 0.5f, layerSize.height * 0.5f);
674722
addChild(playItem);
675-
723+
676724
return true;
677725
}
678-
726+
679727
return false;
680728
}
681729

tests/cpp-tests/Classes/NewAudioEngineTest/NewAudioEngineTest.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,17 @@ class AudioLoadTest : public AudioEngineTestDemo
160160
virtual std::string title() const override;
161161
};
162162

163+
class AudioIssueMaxInstanceTest : public AudioEngineTestDemo
164+
{
165+
public:
166+
CREATE_FUNC(AudioIssueMaxInstanceTest);
167+
168+
virtual bool init() override;
169+
170+
virtual std::string title() const override;
171+
virtual std::string subtitle() const override;
172+
};
173+
163174
class AudioIssue11143Test : public AudioEngineTestDemo
164175
{
165176
public:

0 commit comments

Comments
 (0)