mirror of
https://github.com/azahar-emu/soundtouch
synced 2025-11-07 07:30:02 +01:00
- OpenMP parallel processing disabled by default; can be enabled in compile-time
- Android: Workaround for threading issue to enable OpenMP parallel processing in Android
This commit is contained in:
parent
92973bc18e
commit
d44723ea57
@ -85,8 +85,8 @@ AC_ARG_ENABLE(integer-samples,
|
|||||||
|
|
||||||
AC_ARG_ENABLE(openmp,
|
AC_ARG_ENABLE(openmp,
|
||||||
[AC_HELP_STRING([--enable-openmp],
|
[AC_HELP_STRING([--enable-openmp],
|
||||||
[use parallel multicore calculation through OpenMP [default=yes]])],,
|
[use parallel multicore calculation through OpenMP [default=no]])],,
|
||||||
[enable_openmp=yes])
|
[enable_openmp=no])
|
||||||
|
|
||||||
# Let the user enable/disable the x86 optimizations.
|
# Let the user enable/disable the x86 optimizations.
|
||||||
# Useful when compiling on non-x86 architectures.
|
# Useful when compiling on non-x86 architectures.
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="src" path="src"/>
|
|
||||||
<classpathentry kind="src" path="gen"/>
|
|
||||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
<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.LIBRARIES"/>
|
||||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
<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"/>
|
<classpathentry kind="output" path="bin/classes"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|||||||
@ -36,10 +36,16 @@ LOCAL_SHARED_LIBRARIES += -lgcc
|
|||||||
LOCAL_LDLIBS += -llog
|
LOCAL_LDLIBS += -llog
|
||||||
# for native asset manager
|
# for native asset manager
|
||||||
#LOCAL_LDLIBS += -landroid
|
#LOCAL_LDLIBS += -landroid
|
||||||
# don't export all symbols
|
|
||||||
#
|
# Custom Flags:
|
||||||
# in ARM-only environment could add "-marm" switch to force arm instruction set instead
|
# -fvisibility=hidden : don't export all symbols
|
||||||
# of thumb for improved calculation performance.
|
# -fopenmp : enable these flags to allow using OpenMP for parallel computation
|
||||||
LOCAL_CFLAGS += -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections
|
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)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|||||||
@ -6,4 +6,5 @@
|
|||||||
APP_ABI := all #armeabi-v7a armeabi
|
APP_ABI := all #armeabi-v7a armeabi
|
||||||
APP_OPTIM := release
|
APP_OPTIM := release
|
||||||
APP_STL := stlport_static
|
APP_STL := stlport_static
|
||||||
APP_CPPFLAGS := -fexceptions
|
APP_CPPFLAGS := -fexceptions # -D SOUNDTOUCH_DISABLE_X86_OPTIMIZATIONS
|
||||||
|
|
||||||
|
|||||||
@ -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
|
// Processes the sound file
|
||||||
static void _processFile(SoundTouch *pSoundTouch, const char *inFileName, const char *outFileName)
|
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
|
// Call example SoundTouch routine
|
||||||
verStr = SoundTouch::getVersionString();
|
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 version as string
|
||||||
return env->NewStringUTF(verStr);
|
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);
|
LOGV("JNI process file %s", inputFile);
|
||||||
|
|
||||||
|
/// gomp_tls storage bug workaround - see comments in _init_threading() function!
|
||||||
|
if (_init_threading(true)) return -1;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_processFile(ptr, inputFile, outputFile);
|
_processFile(ptr, inputFile, outputFile);
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ems="5"
|
android:ems="5"
|
||||||
android:inputType="numberDecimal"
|
android:inputType="text"
|
||||||
android:text="100" >
|
android:text="100" >
|
||||||
</EditText>
|
</EditText>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
@ -46,8 +46,8 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ems="5"
|
android:ems="5"
|
||||||
android:inputType="numberSigned"
|
android:inputType="text"
|
||||||
android:text="0" >
|
android:text="-0.318" >
|
||||||
</EditText>
|
</EditText>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableLayout>
|
</TableLayout>
|
||||||
|
|||||||
@ -146,11 +146,10 @@ public class ExampleActivity extends Activity implements OnClickListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Processing routine
|
|
||||||
@Override
|
/// Function that does the SoundTouch processing
|
||||||
protected Long doInBackground(Parameters... aparams)
|
public final long doSoundTouchProcessing(Parameters params)
|
||||||
{
|
{
|
||||||
Parameters params = aparams[0];
|
|
||||||
|
|
||||||
SoundTouch st = new SoundTouch();
|
SoundTouch st = new SoundTouch();
|
||||||
st.setTempo(params.tempo);
|
st.setTempo(params.tempo);
|
||||||
@ -178,6 +177,15 @@ public class ExampleActivity extends Activity implements OnClickListener
|
|||||||
return 0L;
|
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();
|
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.execute(params);
|
||||||
|
// task.doSoundTouchProcessing(params); // this would run processing in main thread
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception exp)
|
catch (Exception exp)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user