2016-05-12 7 views
1

ab, so dass ich mit der Portierung Polycode auf Android stecken bin.
Ich versuche eine Audio-Schnittstelle über OpenSL ES zu implementieren. Ich lese einige Artikel, versuchte so viel wie möglich von den android ndk Beispielen zu kopieren und so weiter, aber nichts funktionierte - zuverlässig - für mich ..Android OpenSL ES stürzt während der Initialisierung

Ich benutze das neueste Android Studio (2.1.1) und daher das Neueste NDK (12 RC1). Für Tests verwende ich mein Fairphone 2 (API Level 21) und den Emulator (Nexus 5 API Level 23).

Die App stürzt in der Regel beim Aufruf CreateAudioPlayer ab, manchmal bei der Realisierung des Spielerobjekts, manchmal unter SetPlayState. Aber es passiert auch, dass die vollständige Initialisierung einfach funktioniert. Dies ist geräteunabhängig.

Auf meinem Fairphone erhalte ich diese Warnungen, wenn das Spielerobjekt zu realisieren:

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 

Mein init-Code wie folgt aussieht:

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); 

Was ich frage mich, über sich selbst: Gibt es etwas, ich muss warten auf Initialisierung, bevor ich OpenSL initialisieren kann?
Im Moment initialisiere ich OpenSL von Thread gestartet in onCreate. OnCreate wartet immer noch auf den Abschluss.

Oder vermisse ich eine Android-Konfiguration oder die Erlaubnis, OpenSL zu verwenden? Oder stimmt irgendwas mit meinem Code nicht?

Für vollständigen Code sehen: https://github.com/fodinabor/Polycode/tree/OpenSL/src/core/PolyOpenSLAudioInterface.cpp
und https://github.com/fodinabor/Polycode/tree/OpenSL/include/polycode/core/PolyOpenSLAudioInterface.h

Projekte Android Studios sind in: https://github.com/fodinabor/Polycode/tree/OpenSL/build/android (die TemplateApp ist, was für Tests Ich verwende)

Jede Hilfe oder sogar Tipps sind willkommen !

Antwort

1

Okay, also habe ich versucht, OpenSL zu initialisieren, nachdem das Native Window erstellt wurde - und das scheint zu funktionieren. Also ich denke, es war ein Threading-Problem.

Ich glaube nicht, dass es sein muss, nachdem natives Fenster erstellt wird, aber es muss sein, nachdem "ANativeActivity_onCreate" beendet ist.

Verwandte Themen