Android OpenSL ES 在初始化时崩溃
Android OpenSL ES crashes while initialization
所以我坚持将 Polycode 移植到 Android。
我正在尝试通过 OpenSL ES 实现音频接口。我阅读了一些文章,尝试尽可能多地从 android ndk 示例等中复制,但没有任何效果 - 可靠地 - 对我来说......
我使用的是最新的 Android Studio (2.1.1),因此是最新的 NDK (12RC1)。对于测试,我使用我的 Fairphone 2(API 级别 21)和模拟器(Nexus 5 API 级别 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 之前,是否需要等待初始化?
目前我正在从 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 是我用于测试的)
欢迎任何帮助甚至提示!
好的,所以我尝试在创建本机 Window 后初始化 OpenSL - 这似乎有效。所以我猜这是一个线程问题。
我认为它不需要在本机 window 创建之后,但必须在 "ANativeActivity_onCreate" 完成之后。
所以我坚持将 Polycode 移植到 Android。
我正在尝试通过 OpenSL ES 实现音频接口。我阅读了一些文章,尝试尽可能多地从 android ndk 示例等中复制,但没有任何效果 - 可靠地 - 对我来说......
我使用的是最新的 Android Studio (2.1.1),因此是最新的 NDK (12RC1)。对于测试,我使用我的 Fairphone 2(API 级别 21)和模拟器(Nexus 5 API 级别 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 之前,是否需要等待初始化?
目前我正在从 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 是我用于测试的)
欢迎任何帮助甚至提示!
好的,所以我尝试在创建本机 Window 后初始化 OpenSL - 这似乎有效。所以我猜这是一个线程问题。
我认为它不需要在本机 window 创建之后,但必须在 "ANativeActivity_onCreate" 完成之后。