[Android] Audio Decoding Issues Discussion

Hello @dumganhar,
Thanks for the pointer, I did modified the JNI as per the requirements, but still got errors from CCFileUtils-android by tracing back to logs i came to the conclusion that cocos2d-x is now trying to read data from OBB files due to introduction of OBB-File extension support from 3.12(AFAIR). I am a little lost as i have no idea what files were modified to implement OBB support. A pointer here would be much of an help.

Regards
Ajay

Hello,

I’m new with cocos2d-x and currently porting my iOS game. Where I can read documentation about this new AudioEngine? Sample code example? Anything? What I’ve found is only this http://cocos2d-x.org/docs/programmers-guide/audio/index.html

Also, I’m looking for pitch option for sounds and music, is it available?

If you don’t use OBB feature provided by Google Play, you could just disable it since it wasn’t supported in V3.10.

static int fdGetter(const std::string& url, off_t* start, off_t* length)
{
    int fd = -1;
//    if (cocos2d::FileUtilsAndroid::getObbFile() != nullptr)
//    {
//        fd = getObbAssetFileDescriptorJNI(url.c_str(), start, length);
//    } 
//    else
    {
        auto asset = AAssetManager_open(cocos2d::FileUtilsAndroid::getAssetManager(), url.c_str(), AASSET_MODE_UNKNOWN);
        // open asset as file descriptor
        fd = AAsset_openFileDescriptor(asset, start, length);
        AAsset_close(asset);
    }

    if (fd <= 0)
    {
        ALOGE("Failed to open file descriptor for '%s'", url.c_str());
    }

    return fd;
};

It seems that the audio documentation is outdated for a long time. I didn’t find New AudioEngine docs too.
You could just visit the interfaces in AudioEngine.h and find the sample code in cpp-tests/NewAudioEngineTest .

Probably, it will be in v3.15. :slight_smile:

Look at this post: PreloadEffect very slow loading

There’s something wrong with waves.

Ok, and what about pitch?

Is it blocking main thread while loading files? In my game taking some real example I have a scene with several oggs. I don’t have any loading screen, just going there. Usually it was half a second lag before scene loaded, but now it’s much longer. I found out that just preloading isn’t harmful, but if you’d play sound before it’s loaded it’ll freeze game for 1-2 seconds.
In simple audio engine there were a code when after loading sample it checked if it should be played and then it was played.
Can we do something about it?

Just loading 19 oggs (344kb): 0.091s
Loading the same 19 oggs and calling play on the first one before it actually loaded (just after calling preload): 2.143s and app is frozen in these 2 seconds.
I know I can add listener and play sound after it loaded, but in my case it requires a lot of effort to achieve. I don’t know why it’s extending loading so drastically and freezes app at the same time.

while(0) loop in AudioEngine::play2d may be responsible for this.

The do { } while(0) exits the ‘loop’ instantly as soon as it hits the while(0) statement. The only way it loops is if the condition is true, for instance, if it was while(1), which is impossible in this case since the condition is false.

The reason the do{} while(0) is there has nothing to do with looping, but as a way to stop processing the code inside the brackets if it hits any “break;” statement. You will notice a number of “break” statements inside the do { } while(0) of the play2d function.

1 Like

Replied in that thread.

@anon98020523, pitch is not supported in AudioEngine currently.
But there is some Pull Requests (https://github.com/cocos2d/cocos2d-x/pull/13662, https://github.com/cocos2d/cocos2d-x/pull/16728) which make it available probably.

It’s possible to support pitch on those platforms which use OpenAL for playing audio.
But it will take some work to make it work on AudioEngine implementation of Android since Android uses an AudioMixer in engine side rather than using which in system to get best performance.

Actually, I tested 101 ogg files loading at the same time, and it only waste a little time for loading.
2 seconds it a bit more for just loading 19 ogg files.

Keep in mind that AudioEngine::preload is called doesn’t mean that preload is finished, AudioEngine::preload is an asynchronous interface, it will be returned very fast.

If you wanna get better experience for your game, it’s better to wait the preload to finish then play audio.

I understand it and I know preload is asynchronous.
Thing is playing any sound before it loaded shoudn’t so drastically increase loading time.
Let me show you a little function:

void HelloWorld::preloadSounds(Ref* ref, ui::Widget::TouchEventType touchEventType) {
    if(touchEventType != ui::Widget::TouchEventType::ENDED) return;
    if(loaded > 0) return;
    CCLOG("Started preloading!");
    milliseconds startMiliseconds = duration_cast< milliseconds >(
            system_clock::now().time_since_epoch()
    );
    for(int i = 0; i < files.size(); i++){
        std::string filename = files.at(i) + "." + extension;
        const int j = i;
        cocos2d::experimental::AudioEngine::preload(filename, [&, filename, startMiliseconds, j](bool success){
            CCLOG("%s done loading. Result: %s", filename.c_str(), success ? "success" : "failure");
            loaded++;
            if(loaded == files.size()){
                CCLOG("All done!");
                milliseconds endMiliseconds = duration_cast< milliseconds >(
                        system_clock::now().time_since_epoch()
                );
                milliseconds diff = endMiliseconds - startMiliseconds;
                CCLOG("loading took: %lld ms", diff.count());
            }
        });
    }
}

Loading took prints about 91ms on my device.
But let’s add one more thing here:

void HelloWorld::preloadSounds(Ref* ref, ui::Widget::TouchEventType touchEventType) {
    if(touchEventType != ui::Widget::TouchEventType::ENDED) return;
    if(loaded > 0) return;
    CCLOG("Started preloading!");
    milliseconds startMiliseconds = duration_cast< milliseconds >(
            system_clock::now().time_since_epoch()
    );
    for(int i = 0; i < files.size(); i++){
        std::string filename = files.at(i) + "." + extension;
        const int j = i;
        cocos2d::experimental::AudioEngine::preload(filename, [&, filename, startMiliseconds, j](bool success){
            CCLOG("%s done loading. Result: %s", filename.c_str(), success ? "success" : "failure");
            loaded++;
            if(loaded == files.size()){
                CCLOG("All done!");
                milliseconds endMiliseconds = duration_cast< milliseconds >(
                        system_clock::now().time_since_epoch()
                );
                milliseconds diff = endMiliseconds - startMiliseconds;
                CCLOG("loading took: %lld ms", diff.count());
            }
        });
        if(i == 0){
            cocos2d::experimental::AudioEngine::play2d(filename);
        }
    }
}

First sound is played before it loaded.
And then game freezes for a while and loading took prints 2143ms!

That time shouldn’t be that long, it should be more or less the same! It should play this sound after loading.

That wasn’t working like that while using SimpleAudioEngine. It took longer to load, but game wasn’t freezing.

I play tons of sounds in tons of screens in different situations and it’s hard to find all the ones which are played on the beginning - leave one and game is freezing hard.

Sorry about that while loop, it was confusing.

Thanks for the good work @dumganhar .

Is the new patch stable enough to update my game in Google Play? I got some dudes reporting bad reviews because the game got stuck due to sound problems in Android 7. Cocos version is 3.7, let’s see if the new patch can be introduced in this version

We have merged the patch to Cocos Creator yet, and no complain of audio any more. Probably, you could have a try and do some tests.

Sorry about that it could be used without easy modification in v3.7. You could check the different between v3.12 and v3.13 to find out what have been changed in audio module. Then, it will be easier for you to apply the patch into v3.7. Otherwise, you probably need to upgrade your engine to v3.14 (latest version).

@piotrros, yes, if your test code is all right, I guess there is something wrong inside AudioEngine.
Could you send me a demo for reproducing the issue you reported? Thanks.

Of course I can. Here it is:
PreloadBug.zip (9.0 MB)

Got to modify JNIHelper class introducing new methods, but it’s building fine for now (builds take about 15 mins to compile). I will post here my results