[FMOD Studio lowlevel api, Android] system->getNumDrivers() failing

FMOD Studio version 1.06.05
Android ARM, Lollipop, Samsung Galaxy S5

Running a NativeActivity with a simple class wrapper to call System.loadLibrary(“fmodL”)
and invoke org.fmod.FMOD.init()

library loads successfully, org.fmod.FMOD.init() succeeds

In native code (after library successfully loaded and initialized)
FMOD::Debug_Initialize succeeds
FMOD::System_Create succeeds
system->getVersion() succeeds

system->getNumDrivers() returns FMOD_ERR_PLUGIN_MISSING

from the error log:
I/fmod (32589): [ERR] FMOD_OS_Output_GetDefault : JavaVM::GetEnv returned -2.

FMOD source file/line number for the error is
…/android/src/fmod_os_output.cpp(52)

The native code is getting invoked from the main application thread that the NativeActivity is running on.

It doesn’t seem like I’m doing anything crazy here but it’s not working.

Is there an initialization step I’m missing or something?

This application was working fine with FModEX. I upgraded to pick up the ARM64 support and have been having problems getting back to a running state since.

additional data point: calling system->setOutput to avoid the check for default output type lets the app get further along before failing but the log indicates the underlying issues are related to the JVM failing to provide environment info.

log excerpt:
D/BEngine ( 2253): SoundDevice.cpp(54): TRACE: fmod shared lib version: 00010605
D/BEngine ( 2253): SoundDevice.cpp(83): TRACE: 1 sound drivers available.
I/fmod ( 2253): [ERR] OutputOpenSL::getDriverInfo : JavaVM::GetEnv returned -2.
D/BEngine ( 2253): SoundDevice.cpp(99): TRACE: Using device Android audio output
I/fmod ( 2253): [ERR] AndroidAssetFile::registerLib : JavaVM::GetEnv returned -2.
I/fmod ( 2253): [ERR] OutputOpenSL::init : JavaVM::GetEnv returned -2.
W/BEngine ( 2253): SoundDevice.cpp(121): FMOD error: An error occurred that wasn’t supposed to. Contact support. (28)

After a great deal of spelunking on the web & the error logs + some experimentation, a solution has been found.

It turns out that error -2 as returned from JavaVM::GetEnv() is JNI_EDETACHED.
Because native code launched via android.app.NativeActivity actually executes in a separate thread from the main activity thread and JavaVM methods can’t be safely invoked across multiple threads you need to use JavaVM::AttachCurrentThread()/JavaVM::DetachCurrentthread() to lock/unlock the VM for access off the main thread.

It is possible to detect the JNI_EDETACHED error in GetEnv() and use AttachCurrentThread() as a fallback case:

This does not appear to be happening in FMOD’s use of JNI. The answer was just to do something like this:

JNIEnv* pEnv = nullptr;
android_app->activity->vm->AttachCurrentThread( &pEnv, nullptr );
myFMODSetupFunc();
android_app->activity->vm->DetachCurrentThread();

Please note FMOD will make JNI calls during runtime too, so it would be wise to keep the native thread attached to the Java VM. We plan to better document the attached VM requirement but have been reluctant to automatically attach user threads without their knowledge.

This post was a life saver for me. I’ve been wrestling with this problem for the last 2 days :slight_smile:

Mathew, please do document this, and an example that builds on top of NDK’s native activity sample would be super useful.

I’ll bump the priority on this task, thanks for your feedback.