Can not create more than 13 openSLES players on Nexus.
it will fail at Realizing openSLES player. here is the error log:
it only occurred on Android 7. Is this a problem peculiar to the Nexus Devices?
Or I am doing something wrong with creating players.
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);
}