Android OpenSL ES аварийно завершает работу при инициализации

поэтому я застрял с переносом Polycode на Android.
Я пытаюсь реализовать аудиоинтерфейс через OpenSL ES. Я читал некоторые статьи, пытался скопировать как можно больше из примеров Android ndk и так далее, но ничего не работало - надежно - для меня.

Я использую последнюю версию Android Studio (2.1.1) и, следовательно, последнюю версию NDK (12RC1). Для тестов я использую свой Fairphone 2 (уровень API 21) и эмулятор (уровень API Nexus 5 23).

Приложение обычно падает при вызове CreateAudioPlayer, иногда при реализации объекта игрока, иногда при SetPlayState. Но бывает и так, что просто работает полная инициализация. Это не зависит от устройства.

На моем Fairphone я получаю эти предупреждения при реализации объекта игрока:

org.polycode.templateapp D/AudioTrack: TrackOffload: AudioTrack Offload disabled by property, returning false
org.polycode.templateapp W/AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by client

Мой код инициализации выглядит так:

SLresult lRes;

const SLInterfaceID lEngineMixIIDs[]={SL_IID_ENGINE};
const SLboolean lEngineMixReqs[]={SL_BOOLEAN_TRUE};
const SLuint32 lOutputMixIIDCount=0;
const SLInterfaceID lOutputMixIIDs[]={};
const SLboolean lOutputMixReqs[]={};

lRes = slCreateEngine(&mEngineObj, 0, NULL, 1, lEngineMixIIDs, lEngineMixReqs);
lRes = (*mEngineObj)->Realize(mEngineObj,SL_BOOLEAN_FALSE);
lRes = (*mEngineObj)->GetInterface(mEngineObj, SL_IID_ENGINE, &mEngine);

lRes=(*mEngine)->CreateOutputMix(mEngine, &mOutputMixObj,lOutputMixIIDCount,lOutputMixIIDs, lOutputMixReqs);
lRes=(*mOutputMixObj)->Realize(mOutputMixObj, SL_BOOLEAN_FALSE);

SLDataLocator_AndroidSimpleBufferQueue lDataLocatorIn;
lDataLocatorIn.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
lDataLocatorIn.numBuffers = 1;

SLDataFormat_PCM lDataFormat;
lDataFormat.formatType = SL_DATAFORMAT_PCM;
lDataFormat.numChannels = 1; // Mono sound.
lDataFormat.samplesPerSec = SL_SAMPLINGRATE_44_1;
lDataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
lDataFormat.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
lDataFormat.channelMask = SL_SPEAKER_FRONT_CENTER;
lDataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;

SLDataSource lDataSource;
lDataSource.pLocator = &lDataLocatorIn;
lDataSource.pFormat = &lDataFormat;

SLDataLocator_OutputMix lDataLocatorOut;
lDataLocatorOut.locatorType = SL_DATALOCATOR_OUTPUTMIX;
lDataLocatorOut.outputMix = mOutputMixObj;

SLDataSink lDataSink;
lDataSink.pLocator = &lDataLocatorOut;
lDataSink.pFormat = NULL;

const SLuint32 lSoundPlayerIIDCount = 2;
const SLInterfaceID lSoundPlayerIIDs[3] = { SL_IID_PLAY, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME };
const SLboolean lSoundPlayerReqs[3] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };

lRes = (*mEngine)->CreateAudioPlayer(mEngine, &mPlayerObj, &lDataSource, &lDataSink, lSoundPlayerIIDCount, lSoundPlayerIIDs, lSoundPlayerReqs);
lRes = (*mPlayerObj)->Realize(mPlayerObj, SL_BOOLEAN_FALSE);

lRes = (*mPlayerObj)->GetInterface(mPlayerObj, SL_IID_PLAY, &mPlayer);
lRes = (*mPlayerObj)->GetInterface(mPlayerObj, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &mPlayerQueue);

lRes = (*mPlayerQueue)->RegisterCallback(mPlayerQueue, OpenSLAudioInterface::queueCallback, this);

lRes = (*mPlayer)->SetPlayState(mPlayer, SL_PLAYSTATE_PLAYING);

Что меня интересовало: есть ли что-то, что мне нужно дождаться инициализации, прежде чем я смогу начать инициализацию OpenSL?
В данный момент я инициализирую OpenSL из потока, запущенного в onCreate. onCreate все еще ожидает завершения.

Или мне не хватает какой-либо конфигурации Android или разрешения на использование OpenSL? Или что-то не так с моим кодом?

Полный код см. по адресу: https://github.com/fodinabor/Polycode/tree/OpenSL/src/core/PolyOpenSLAudioInterface.cpp
и https://github.com/fodinabor/Polycode/tree/OpenSL/include/polycode/core/PolyOpenSLAudioInterface.h

Проекты Android Studio находятся по адресу: https://github.com/fodinabor/Polycode/tree/OpenSL/build/android (для тестов я использую TemplateApp)

Любая помощь или даже советы приветствуются!


person fodinabor    schedule 12.05.2016    source источник


Ответы (1)


Хорошо, поэтому я попытался инициализировать OpenSL после создания собственного окна - и это, похоже, работает. Так что я думаю, что это была проблема с потоками.

Я не думаю, что это должно быть после создания собственного окна, но это должно быть после завершения «ANativeActivity_onCreate».

person fodinabor    schedule 13.05.2016