[Android 7][Nexus]Can not create more than 13 openSLES players

383 views
Skip to first unread message

ryu...@cri-mw.co.jp

unread,
May 23, 2017, 11:35:50 AM5/23/17
to android-ndk
Can not create more than 13 openSLES players on Nexus.
I tried on Nexus 5x and Nexus 9, When I am going to create the 14th player, 
it will fail at Realizing openSLES player. here is the error log:

05-23 16:09:09.288: E/AudioFlinger(239): no more track names available
05-23 16:09:09.288: E/AudioFlinger(239): createTrack_l() initCheck failed -12; no control block?
05-23 16:09:09.288: E/AudioTrack(3863): AudioFlinger could not create track, status: -12
05-23 16:09:09.289: E/libOpenSLES(3863): AudioTrack::initCheck status 4294967284
05-23 16:09:09.289: W/libOpenSLES(3863): Leaving Object::Realize (SL_RESULT_CONTENT_UNSUPPORTED)
05-23 16:09:09.289: W/libOpenSLES(3863): --------- beginning of crash

it only occurred on Android 7. Is this a problem peculiar to the Nexus Devices?
Or I am doing something wrong with creating players.

Here is my code to create openSLES engine:
Nothing changed from the android-ndk native-audio sample

void Java_com_example_nativeaudio_NativeAudio_createEngine(JNIEnv* env, jclass clazz)
{
SLresult result;

// create engine
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
assert(SL_RESULT_SUCCESS == result);
(void)result;

// realize the engine
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void)result;

// get the engine interface, which is needed in order to create other objects
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
assert(SL_RESULT_SUCCESS == result);
(void)result;

// create output mix, with environmental reverb specified as a non-required interface
const SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
const SLboolean req[1] = {SL_BOOLEAN_FALSE};
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
assert(SL_RESULT_SUCCESS == result);
(void)result;

// realize the output mix
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void)result;

result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
&outputMixEnvironmentalReverb);
if (SL_RESULT_SUCCESS == result) {
result = (*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(
outputMixEnvironmentalReverb, &reverbSettings);
(void)result;
}
// ignore unsuccessful result codes for environmental reverb, as it is optional for this example
}





Here is my code to create multiple openSLES players:

struct VoicePlayerTag{
SLObjectItf bqPlayerObject;
SLPlayItf bqPlayerPlay;
SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
SLVolumeItf bqPlayerVolume;
SLuint32 numChannels;
SLuint32 samplesPerSec;
SLmillisecond minisecPlayed;

short *Data;
int DataSize;

int queueNum;
int queueIndex;
int queueSize;

int playFlag;
int loopFlag;

long samplePlayed;
};

#define NUM_MULTI_PLAYER 20
static VoicePlayerHn VP_44_1_N[NUM_MULTI_PLAYER] = {};

void Batch_Setup_Player_44_1(VoicePlayerHn VP){
VP->Data = (short *) se_stereo_44_1kHz;
VP->DataSize = sizeof(se_stereo_44_1kHz);
VP->queueSize = 4096;
VP->numChannels = 2;
VP->samplesPerSec = SL_SAMPLINGRATE_44_1;
SL_Player_Init(VP);
SL_Player_Create(VP);
}

void SL_Player_Create(VoicePlayerHn VP){
SLresult result;
SLDataFormat_PCM format_pcm;
// configure audio source
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, (SLuint32)VP->queueNum};
format_pcm.formatType = SL_DATAFORMAT_PCM;
format_pcm.numChannels = VP->numChannels;
format_pcm.samplesPerSec = VP->samplesPerSec;
format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
format_pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
if (format_pcm.numChannels == 1){
format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
}else if(format_pcm.numChannels == 2){
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
}
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};

const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(
engineEngine,
&VP->bqPlayerObject,
&audioSrc,
&audioSnk,
2,
ids,
req);
assert(SL_RESULT_SUCCESS == result);
(void)result;

// realize the player
result = (*VP->bqPlayerObject)->Realize(VP->bqPlayerObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void)result;

// get the play interface
result = (*VP->bqPlayerObject)->GetInterface(VP->bqPlayerObject, SL_IID_PLAY, &VP->bqPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
(void)result;

// get the buffer queue interface
result = (*VP->bqPlayerObject)->GetInterface(VP->bqPlayerObject, SL_IID_BUFFERQUEUE,
&VP->bqPlayerBufferQueue);
assert(SL_RESULT_SUCCESS == result);
(void)result;

// register callback on the buffer queue
# if 0
result = (*VP->bqPlayerBufferQueue)->RegisterCallback(VP->bqPlayerBufferQueue, vPlayerCallback, VP);
assert(SL_RESULT_SUCCESS == result);
(void)result;
#endif
// get the volume interface
result = (*VP->bqPlayerObject)->GetInterface(VP->bqPlayerObject, SL_IID_VOLUME, &VP->bqPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
(void)result;
}

for(int i=0;i<NUM_MULTI_PLAYER;i++){
VP_44_1_N[i] = (VoicePlayerHn) malloc(sizeof(struct VoicePlayerTag));
Batch_Setup_Player_44_1(VP_44_1_N[i]);
DBG_LOG("Player %d created",i);
}

Glenn Kasten

unread,
May 23, 2017, 11:46:28 AM5/23/17
to android-ndk
See https://android.googlesource.com/platform/frameworks/av/+/ad7dd9610b6fafa81baf69607f4ac669da88182a
You may want to consider implementing a simple mixer in your application,
so that you don't need so many audio tracks.

Phil Burk

unread,
May 23, 2017, 11:51:20 AM5/23/17
to android-ndk
Hello,


On Tuesday, May 23, 2017 at 8:35:50 AM UTC-7, ryu...@cri-mw.co.jp wrote:
Can not create more than 13 openSLES players on Nexus.
05-23 16:09:09.288: E/AudioFlinger(239): no more track names available

The Audio server has a limited number of tracks.

The intention is that an app would only open one player for each device that it needed. So if it needed to play audio over the speakers and over  a USB device then it could open two players.

There is no reason to open multiple players for a single device. If you need to play multiple sounds on one device just mix your sounds and then send the mix to your one player.  This approach is also more portable. And it give you better control over the mix.
 
it only occurred on Android 7. Is this a problem peculiar to the Nexus Devices?

The same recommendation applies to all Android devices.

Phil Burk

ryu...@cri-mw.co.jp

unread,
May 24, 2017, 10:36:57 AM5/24/17
to android-ndk
According to Android NDK, The maximum number of players that can be created should be 32.
I can create that number of players on other devices like Galaxy S6.
So I wonder if this is a problem peculiar to the Nexus Devices.

mic _

unread,
May 24, 2017, 10:45:39 AM5/24/17
to andro...@googlegroups.com
The commit that Glenn linked to contains the lines

+    // 14 tracks max per client allows for 2 misbehaving application leaving 4 available tracks.
+    static const uint32_t kMaxTracksPerUid = 14;

Your Galaxy S6 probably runs an Android version that doesn't contain this change.

/Michael

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk+unsubscribe@googlegroups.com.
To post to this group, send email to andro...@googlegroups.com.
Visit this group at https://groups.google.com/group/android-ndk.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/66262bcb-d0cf-4e4e-be82-7ec825d194e4%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

ryu...@cri-mw.co.jp

unread,
Jun 8, 2017, 5:40:02 AM6/8/17
to android-ndk
Understood.
Thanks a lot for your reply
Reply all
Reply to author
Forward
0 new messages