2016-05-12 108 views
1

因此我坚持将Polycode移植到Android。
我想通过OpenSL ES实现音频接口。我阅读了一些文章,试图从android ndk例子中尽可能地复制等,但没有任何工作 - 可靠 - 对我来说。Android OpenSL ES在初始化时崩溃

我使用最新的Android Studio(2.1.1),因此最新NDK(12RC1)。对于我使用我的Fairphone 2(API级别21)和仿真器(Nexus 5 API级别23)的测试。

该应用程序通常会在调用CreateAudioPlayer时崩溃,有时在实现播放器对象时,有时在SetPlayState。但它也发生了完整的初始化工作。这是独立于设备的。

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

什么我想知道:有什么我必须

在我Fairphone我意识到玩家对象时得到这些警告等到我可以开始初始化OpenSL之前进行初始化?
目前我正在从onCreate中启动的线程初始化OpenSL。 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是我使用的是什么测试)

任何帮助,甚至技巧都欢迎!

回答

1

好吧,所以我试图在创建本机窗口后初始化OpenSL - 这似乎是工作。所以我想这是一个线程问题。

我不认为它需要在本机窗口创建后,但它必须在“ANativeActivity_onCreate”完成后。