Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/alexmarsev/soundtouch.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroparviai <oparviai@f3a24b6a-cf45-0410-b55a-8c22e2698227>2015-05-15 13:22:36 +0300
committeroparviai <oparviai@f3a24b6a-cf45-0410-b55a-8c22e2698227>2015-05-15 13:22:36 +0300
commit7655c8ba36657be51509aa05a5b9b1a1ca245ebb (patch)
tree2e713898e6301a06694fb20f8e1e8329924ae823
parent2816202b12d5eee8d29a1b31e924bb393a2e3bc3 (diff)
- OpenMP parallel processing disabled by default; can be enabled in compile-time
- Android: Workaround for threading issue to enable OpenMP parallel processing in Android
-rw-r--r--configure.ac4
-rw-r--r--source/Android-lib/.classpath4
-rw-r--r--source/Android-lib/jni/Android.mk16
-rw-r--r--source/Android-lib/jni/Application.mk3
-rw-r--r--source/Android-lib/jni/soundtouch-jni.cpp62
-rw-r--r--source/Android-lib/res/layout/activity_example.xml6
-rw-r--r--source/Android-lib/src/net/surina/ExampleActivity.java19
7 files changed, 96 insertions, 18 deletions
diff --git a/configure.ac b/configure.ac
index e399dc5..aaa4028 100644
--- a/configure.ac
+++ b/configure.ac
@@ -85,8 +85,8 @@ AC_ARG_ENABLE(integer-samples,
AC_ARG_ENABLE(openmp,
[AC_HELP_STRING([--enable-openmp],
- [use parallel multicore calculation through OpenMP [default=yes]])],,
- [enable_openmp=yes])
+ [use parallel multicore calculation through OpenMP [default=no]])],,
+ [enable_openmp=no])
# Let the user enable/disable the x86 optimizations.
# Useful when compiling on non-x86 architectures.
diff --git a/source/Android-lib/.classpath b/source/Android-lib/.classpath
index 7bc01d9..5176974 100644
--- a/source/Android-lib/.classpath
+++ b/source/Android-lib/.classpath
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
diff --git a/source/Android-lib/jni/Android.mk b/source/Android-lib/jni/Android.mk
index ef5cfef..98fbbf7 100644
--- a/source/Android-lib/jni/Android.mk
+++ b/source/Android-lib/jni/Android.mk
@@ -36,10 +36,16 @@ LOCAL_SHARED_LIBRARIES += -lgcc
LOCAL_LDLIBS += -llog
# for native asset manager
#LOCAL_LDLIBS += -landroid
-# don't export all symbols
-#
-# in ARM-only environment could add "-marm" switch to force arm instruction set instead
-# of thumb for improved calculation performance.
-LOCAL_CFLAGS += -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections
+
+# Custom Flags:
+# -fvisibility=hidden : don't export all symbols
+# -fopenmp : enable these flags to allow using OpenMP for parallel computation
+LOCAL_CFLAGS += -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections #-fopenmp
+
+#LOCAL_LDFLAGS += -fopenmp
+
+
+# Use ARM instruction set instead of Thumb for improved calculation performance in ARM CPUs
+LOCAL_ARM_MODE := arm
include $(BUILD_SHARED_LIBRARY)
diff --git a/source/Android-lib/jni/Application.mk b/source/Android-lib/jni/Application.mk
index 68ef2d0..9875799 100644
--- a/source/Android-lib/jni/Application.mk
+++ b/source/Android-lib/jni/Application.mk
@@ -6,4 +6,5 @@
APP_ABI := all #armeabi-v7a armeabi
APP_OPTIM := release
APP_STL := stlport_static
-APP_CPPFLAGS := -fexceptions \ No newline at end of file
+APP_CPPFLAGS := -fexceptions # -D SOUNDTOUCH_DISABLE_X86_OPTIMIZATIONS
+
diff --git a/source/Android-lib/jni/soundtouch-jni.cpp b/source/Android-lib/jni/soundtouch-jni.cpp
index 15fb446..7922bb3 100644
--- a/source/Android-lib/jni/soundtouch-jni.cpp
+++ b/source/Android-lib/jni/soundtouch-jni.cpp
@@ -46,6 +46,54 @@ static void _setErrmsg(const char *msg)
}
+#ifdef _OPENMP
+
+#include <pthread.h>
+extern pthread_key_t gomp_tls_key;
+static void * _p_gomp_tls = NULL;
+
+/// Function to initialize threading for OpenMP.
+///
+/// This is a workaround for bug in Android NDK v10 regarding OpenMP: OpenMP works only if
+/// called from the Android App main thread because in the main thread the gomp_tls storage is
+/// properly set, however, Android does not properly initialize gomp_tls storage for other threads.
+/// Thus if OpenMP routines are invoked from some other thread than the main thread,
+/// the OpenMP routine will crash the application due to NULL pointer access on uninitialized storage.
+///
+/// This workaround stores the gomp_tls storage from main thread, and copies to other threads.
+/// In order this to work, the Application main thread needws to call at least "getVersionString"
+/// routine.
+static int _init_threading(bool warn)
+{
+ void *ptr = pthread_getspecific(gomp_tls_key);
+ LOGV("JNI thread-specific TLS storage %ld", (long)ptr);
+ if (ptr == NULL)
+ {
+ LOGV("JNI set missing TLS storage to %ld", (long)_p_gomp_tls);
+ pthread_setspecific(gomp_tls_key, _p_gomp_tls);
+ }
+ else
+ {
+ LOGV("JNI store this TLS storage");
+ _p_gomp_tls = ptr;
+ }
+ // Where critical, show warning if storage still not properly initialized
+ if ((warn) && (_p_gomp_tls == NULL))
+ {
+ _setErrmsg("Error - OpenMP threading not properly initialized: Call SoundTouch.getVersionString() from the App main thread!");
+ return -1;
+ }
+ return 0;
+}
+
+#else
+static int _init_threading(bool warn)
+{
+ // do nothing if not OpenMP build
+ return 0;
+}
+#endif
+
// Processes the sound file
static void _processFile(SoundTouch *pSoundTouch, const char *inFileName, const char *outFileName)
@@ -118,6 +166,17 @@ extern "C" DLL_PUBLIC jstring Java_net_surina_soundtouch_SoundTouch_getVersionSt
// Call example SoundTouch routine
verStr = SoundTouch::getVersionString();
+ /// gomp_tls storage bug workaround - see comments in _init_threading() function!
+ _init_threading(false);
+
+ int threads = 0;
+ #pragma omp parallel
+ {
+ #pragma omp atomic
+ threads ++;
+ }
+ LOGV("JNI thread count %d", threads);
+
// return version as string
return env->NewStringUTF(verStr);
}
@@ -176,6 +235,9 @@ extern "C" DLL_PUBLIC int Java_net_surina_soundtouch_SoundTouch_processFile(JNIE
LOGV("JNI process file %s", inputFile);
+ /// gomp_tls storage bug workaround - see comments in _init_threading() function!
+ if (_init_threading(true)) return -1;
+
try
{
_processFile(ptr, inputFile, outputFile);
diff --git a/source/Android-lib/res/layout/activity_example.xml b/source/Android-lib/res/layout/activity_example.xml
index b333511..c71c77d 100644
--- a/source/Android-lib/res/layout/activity_example.xml
+++ b/source/Android-lib/res/layout/activity_example.xml
@@ -25,7 +25,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="5"
- android:inputType="numberDecimal"
+ android:inputType="text"
android:text="100" >
</EditText>
</TableRow>
@@ -46,8 +46,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="5"
- android:inputType="numberSigned"
- android:text="0" >
+ android:inputType="text"
+ android:text="-0.318" >
</EditText>
</TableRow>
</TableLayout>
diff --git a/source/Android-lib/src/net/surina/ExampleActivity.java b/source/Android-lib/src/net/surina/ExampleActivity.java
index 465cb9d..1aae8d8 100644
--- a/source/Android-lib/src/net/surina/ExampleActivity.java
+++ b/source/Android-lib/src/net/surina/ExampleActivity.java
@@ -146,11 +146,10 @@ public class ExampleActivity extends Activity implements OnClickListener
}
- /// Processing routine
- @Override
- protected Long doInBackground(Parameters... aparams)
+
+ /// Function that does the SoundTouch processing
+ public final long doSoundTouchProcessing(Parameters params)
{
- Parameters params = aparams[0];
SoundTouch st = new SoundTouch();
st.setTempo(params.tempo);
@@ -177,6 +176,15 @@ public class ExampleActivity extends Activity implements OnClickListener
}
return 0L;
}
+
+
+
+ /// Overloaded function that get called by the system to perform the background processing
+ @Override
+ protected Long doInBackground(Parameters... aparams)
+ {
+ return doSoundTouchProcessing(aparams[0]);
+ }
}
@@ -202,8 +210,9 @@ public class ExampleActivity extends Activity implements OnClickListener
Toast.makeText(this, "Starting to process file " + params.inFileName + "...", Toast.LENGTH_SHORT).show();
- // start processing task in background
+ // start SoundTouch processing in a background thread
task.execute(params);
+// task.doSoundTouchProcessing(params); // this would run processing in main thread
}
catch (Exception exp)