diff --git a/android/app-android.cpp b/android/app-android.cpp index 7968abc568..b3b93eb6db 100644 --- a/android/app-android.cpp +++ b/android/app-android.cpp @@ -93,7 +93,7 @@ extern "C" jboolean Java_com_turboviking_libnative_NativeApp_isLandscape(JNIEnv extern "C" void Java_com_turboviking_libnative_NativeApp_init (JNIEnv *env, jclass, jint xxres, jint yyres, jstring apkpath, - jstring dataDir, jstring externalDir, jstring jinstallID, jboolean juseNativeAudio) { + jstring dataDir, jstring externalDir, jstring libraryDir, jstring jinstallID, jboolean juseNativeAudio) { jniEnvUI = env; pixel_xres = xxres; pixel_yres = yyres; @@ -123,6 +123,9 @@ extern "C" void Java_com_turboviking_libnative_NativeApp_init str = env->GetStringUTFChars(dataDir, &isCopy); std::string user_data_path = std::string(str) + "/"; + str = env->GetStringUTFChars(libraryDir, &isCopy); + std::string library_path = std::string(str) + "/"; + str = env->GetStringUTFChars(jinstallID, &isCopy); std::string installID = std::string(str); @@ -133,13 +136,21 @@ extern "C" void Java_com_turboviking_libnative_NativeApp_init NativeGetAppInfo(&app_name, &app_nice_name, &landscape); const char *argv[2] = {app_name.c_str(), 0}; NativeInit(1, argv, user_data_path.c_str(), installID.c_str()); + + if (use_native_audio) { + AndroidAudio_Init(&NativeMix, library_path); + } } extern "C" void Java_com_turboviking_libnative_NativeApp_shutdown (JNIEnv *, jclass) { ILOG("NativeShutdown."); - if (renderer_inited) { + if (use_native_audio) { + AndroidAudio_Shutdown(); + } + if (renderer_inited) { NativeShutdownGraphics(); + renderer_inited = false; } NativeShutdown(); ILOG("VFSShutdown."); diff --git a/android/native-audio-so.cpp b/android/native-audio-so.cpp index 4c4eeed270..11c0e58613 100644 --- a/android/native-audio-so.cpp +++ b/android/native-audio-so.cpp @@ -31,6 +31,8 @@ #include #include +#include "../base/logging.h" + // engine interfaces static SLObjectItf engineObject = NULL; static SLEngineItf engineEngine; @@ -57,6 +59,7 @@ static unsigned nextSize; // synthesize a mono sawtooth wave and place it into a buffer (called automatically on load) __attribute__((constructor)) static void onDlOpen(void) { + ILOG("Buffer callback"); unsigned int i; for (i = 0; i < SAWTOOTH_FRAMES; ++i) { sawtoothBuffer[i] = 32768 - ((i % 100) * 660); @@ -98,9 +101,7 @@ extern "C" bool OpenSLWrap_Init() assert(SL_RESULT_SUCCESS == result); // create output mix, with environmental reverb specified as a non-required interface - const SLInterfaceID ids1[1] = {SL_IID_ENVIRONMENTALREVERB}; - const SLboolean req1[1] = {SL_BOOLEAN_FALSE}; - result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids1, req1); + result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0); assert(SL_RESULT_SUCCESS == result); // realize the output mix @@ -130,10 +131,10 @@ extern "C" bool OpenSLWrap_Init() SLDataSink audioSnk = {&loc_outmix, NULL}; // create audio player - const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME}; - const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; + const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME}; + const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, - 3, ids, req); + 2, ids, req); assert(SL_RESULT_SUCCESS == result); // realize the player @@ -161,12 +162,10 @@ extern "C" bool OpenSLWrap_Init() result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING); assert(SL_RESULT_SUCCESS == result); - if (nextBuffer) { - SLresult result; - result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize); - if (SL_RESULT_SUCCESS != result) { - return false; - } + // Enqueue a first buffer. + result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, sawtoothBuffer, sizeof(sawtoothBuffer)); + if (SL_RESULT_SUCCESS != result) { + return false; } return true; } diff --git a/android/native_audio.cpp b/android/native_audio.cpp index 2b99a9dc25..7a1a774113 100644 --- a/android/native_audio.cpp +++ b/android/native_audio.cpp @@ -1,18 +1,21 @@ #include +#include #include "base/logging.h" #include "android/native_audio.h" #include "android/native-audio-so.h" static void *so; + static OpenSLWrap_Init_T init_func; static OpenSLWrap_Shutdown_T shutdown_func; -bool AndroidAudio_Init(AndroidAudioCallback cb) { +bool AndroidAudio_Init(AndroidAudioCallback cb, std::string libraryDir) { ILOG("Loading native audio library..."); - so = dlopen("libnative_audio.so", RTLD_NOW); + std::string so_filename = libraryDir + "/libnative_audio.so"; + so = dlopen(so_filename.c_str(), RTLD_LAZY); if (!so) { - ELOG("Failed to find native audio library"); + ELOG("Failed to find native audio library: %i: %s ", errno, dlerror()); return false; } init_func = (OpenSLWrap_Init_T)dlsym(so, "OpenSLWrap_Init"); @@ -24,7 +27,6 @@ bool AndroidAudio_Init(AndroidAudioCallback cb) { return init_retval; } - void AndroidAudio_Shutdown() { ILOG("Calling OpenSLWrap_Shutdown_T..."); shutdown_func(); diff --git a/android/native_audio.h b/android/native_audio.h index af6ec235f7..e9a230addf 100644 --- a/android/native_audio.h +++ b/android/native_audio.h @@ -1,12 +1,12 @@ #pragma once #include "native-audio-so.h" - +#include // This is the file you should include from your program. It dynamically loads // the native_audio.so shared object and sets up the function pointers. // Do not call this if you have detected that the android version is below // 2.2, as it will fail miserably. -bool AndroidAudio_Init(AndroidAudioCallback cb); +bool AndroidAudio_Init(AndroidAudioCallback cb, std::string libraryDir); void AndroidAudio_Shutdown(); diff --git a/android/src/com/turboviking/libnative/NativeActivity.java b/android/src/com/turboviking/libnative/NativeActivity.java index ef68757bb0..2f1b906ec9 100644 --- a/android/src/com/turboviking/libnative/NativeActivity.java +++ b/android/src/com/turboviking/libnative/NativeActivity.java @@ -3,6 +3,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; +import java.lang.reflect.Field; import java.util.UUID; import javax.microedition.khronos.egl.EGLConfig; @@ -93,6 +94,24 @@ public class NativeActivity extends Activity { public static String installID; + String getApplicationLibraryDir(ApplicationInfo application) { + String libdir = null; + try { + // Starting from Android 2.3, nativeLibraryDir is available: + Field field = ApplicationInfo.class.getField("nativeLibraryDir"); + libdir = (String) field.get(application); + } catch (SecurityException e1) { + } catch (NoSuchFieldException e1) { + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } + if (libdir == null) { + // Fallback for Android < 2.3: + libdir = application.dataDir + "/lib"; + } + return libdir; + } + @Override public void onCreate(Bundle savedInstanceState) { if (NativeApp.isLandscape()) { @@ -113,6 +132,7 @@ public class NativeActivity extends Activity { e.printStackTrace(); throw new RuntimeException("Unable to locate assets, aborting..."); } + String libraryDir = getApplicationLibraryDir(appInfo); File sdcard = Environment.getExternalStorageDirectory(); Display display = ((WindowManager)this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); int scrPixelFormat = display.getPixelFormat(); @@ -123,7 +143,7 @@ public class NativeActivity extends Activity { String dataDir = this.getFilesDir().getAbsolutePath(); String apkFilePath = appInfo.sourceDir; NativeApp.sendMessage("Message from Java", "Hot Coffee"); - NativeApp.init(scrWidth, scrHeight, apkFilePath, dataDir, externalStorageDir, installID, useOpenSL); + NativeApp.init(scrWidth, scrHeight, apkFilePath, dataDir, externalStorageDir, libraryDir, installID, useOpenSL); // Keep the screen bright - very annoying if it goes dark when tilting away Window window = this.getWindow(); diff --git a/android/src/com/turboviking/libnative/NativeApp.java b/android/src/com/turboviking/libnative/NativeApp.java index b1809c76e2..5af6937e6f 100644 --- a/android/src/com/turboviking/libnative/NativeApp.java +++ b/android/src/com/turboviking/libnative/NativeApp.java @@ -4,7 +4,7 @@ public class NativeApp { public static native boolean isLandscape(); public static native void init( int xxres, int yyres, String apkPath, - String dataDir, String externalDir, String installID, boolean useOpenSL); + String dataDir, String externalDir, String libraryDir, String installID, boolean useOpenSL); public static native void shutdown(); public static native void keyDown(int key);