Question

I'm having a problem with OpenSL ES on Android. I'm using OpenSL to play sound effects. Currently I'm creating a new player each time I play a sound. (I know this isn't terribly efficient, but it's "good enough" for the time being.)

After a while of playback, I start to get these errors:

E/libOpenSLES(25131): Too many objects
W/libOpenSLES(25131): Leaving Engine::CreateAudioPlayer (SL_RESULT_MEMORY_FAILURE)

I'm tracking my create/destroy pattern and I never go above 4 outstanding objects at any given time, well below the system limit of 32. Of course, this is assuming that the Destroy is properly working.

My only guess right now is that I'm doing something incorrectly when I clean up the player objects. One possible issue is that the Destroy is often called in the context of the player callback (basically destroying the player after it's finished playing), although I can't find any reference suggesting this is a problem. Are there any other cleanup steps I should be taking besides "Destroy"-ing the player object? Do the Interfaces need to be cleaned up somehow as well?

-- Added --

After more testing, it happens consistently after the 30th player is created (there is an engine and a mix too, so that brings the total to 32 objects). So I must not be destroying the object properly. Here's the code--I'd love to know what's going wrong:

SLuint32 playerState = 0;

SLresult result = (*pPlayerObject)->GetState(pPlayerObject, &playerState);

return_if_fail(result);

if (playerState == SL_OBJECT_STATE_REALIZED)
{
    (*pPlayerObject)->AbortAsyncOperation(pPlayerObject);
    (*pPlayerObject)->Destroy(pPlayerObject);
}
else
{
    __android_log_print(1, LOG_TAG, "Player object in unexpected state (%d)", playerState);
    return 1002;
}
Was it helpful?

Solution

  1. if (playerState == SL_OBJECT_STATE_REALIZED)

    is not needed. Try to do it always.

  2. AbortAsyncOperation is called in Destroy => not needed.

  3. So try just (*pPlayerObject)->Destroy(pPlayerObject); it should be enough.

Edit: I tested, and found solution. You cannot call Destroy() from player callback. Should make "destroy" list and destroy it somewhere else, for example, in main thread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top