Skip to content

Commit

Permalink
refactor: more efficient JNI interface
Browse files Browse the repository at this point in the history
  • Loading branch information
timschneeb committed Aug 2, 2023
1 parent 3c48d8f commit 059b8c3
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 42 deletions.
57 changes: 33 additions & 24 deletions app/src/main/cpp/libjamesdsp-wrapper/JamesDspWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,39 +187,45 @@ Java_me_timschneeberger_rootlessjamesdsp_interop_JamesDspWrapper_isHandleValid(J
}

extern "C"
JNIEXPORT jshortArray JNICALL
Java_me_timschneeberger_rootlessjamesdsp_interop_JamesDspWrapper_processInt16(JNIEnv *env, jobject obj, jlong self, jshortArray inputObj)
JNIEXPORT void JNICALL
Java_me_timschneeberger_rootlessjamesdsp_interop_JamesDspWrapper_processInt16(JNIEnv *env, jobject obj, jlong self, jshortArray inputObj, jshortArray outputObj, jint offset, jint size)
{
// Return inputObj if DECLARE failed
DECLARE_DSP(inputObj)
DECLARE_DSP_V

auto inputLength = env->GetArrayLength(inputObj);
auto outputObj = env->NewShortArray(inputLength);
jsize inputLength;
if(size < 0)
inputLength = env->GetArrayLength(inputObj);
else
inputLength = size;
if(offset < 0)
offset = 0;

auto input = env->GetShortArrayElements(inputObj, nullptr);
auto output = env->GetShortArrayElements(outputObj, nullptr);
dsp->processInt16Multiplexd(dsp, input, output, inputLength / 2);
dsp->processInt16Multiplexd(dsp, input + offset, output, inputLength / 2);
env->ReleaseShortArrayElements(inputObj, input, JNI_ABORT);
env->ReleaseShortArrayElements(outputObj, output, 0);
return outputObj;
}

extern "C"
JNIEXPORT jintArray JNICALL
Java_me_timschneeberger_rootlessjamesdsp_interop_JamesDspWrapper_processInt32(JNIEnv *env, jobject obj, jlong self, jintArray inputObj)
JNIEXPORT void JNICALL
Java_me_timschneeberger_rootlessjamesdsp_interop_JamesDspWrapper_processInt32(JNIEnv *env, jobject obj, jlong self, jintArray inputObj, jintArray outputObj, jint offset, jint size)
{
// Return inputObj if DECLARE failed
DECLARE_DSP(inputObj)
DECLARE_DSP_V

auto inputLength = env->GetArrayLength(inputObj);
auto outputObj = env->NewIntArray(inputLength);
jsize inputLength;
if(size < 0)
inputLength = env->GetArrayLength(inputObj);
else
inputLength = size;
if(offset < 0)
offset = 0;

auto input = env->GetIntArrayElements(inputObj, nullptr);
auto output = env->GetIntArrayElements(outputObj, nullptr);
dsp->processInt32Multiplexd(dsp, input, output, inputLength / 2);
dsp->processInt32Multiplexd(dsp, input + offset, output, inputLength / 2);
env->ReleaseIntArrayElements(inputObj, input, JNI_ABORT);
env->ReleaseIntArrayElements(outputObj, output, 0);
return outputObj;
}

extern "C"
Expand Down Expand Up @@ -261,23 +267,26 @@ Java_me_timschneeberger_rootlessjamesdsp_interop_JamesDspWrapper_processInt8U24(
}

extern "C"
JNIEXPORT jfloatArray JNICALL
Java_me_timschneeberger_rootlessjamesdsp_interop_JamesDspWrapper_processFloat(JNIEnv *env, jobject obj, jlong self, jfloatArray inputObj)
JNIEXPORT void JNICALL
Java_me_timschneeberger_rootlessjamesdsp_interop_JamesDspWrapper_processFloat(JNIEnv *env, jobject obj, jlong self, jfloatArray inputObj, jfloatArray outputObj, jint offset, jint size)
{
// Return inputObj if DECLARE failed
DECLARE_DSP(inputObj)
DECLARE_DSP_V

auto inputLength = env->GetArrayLength(inputObj);
auto outputObj = env->NewFloatArray(inputLength);
jsize inputLength;
if(size < 0)
inputLength = env->GetArrayLength(inputObj);
else
inputLength = size;
if(offset < 0)
offset = 0;

auto input = env->GetFloatArrayElements(inputObj, nullptr);
auto output = env->GetFloatArrayElements(outputObj, nullptr);

dsp->processFloatMultiplexd(dsp, input, output, inputLength / 2);
dsp->processFloatMultiplexd(dsp, input + offset, output, inputLength / 2);

env->ReleaseFloatArrayElements(inputObj, input, JNI_ABORT);
env->ReleaseFloatArrayElements(outputObj, output, 0);
return outputObj;
}

extern "C" JNIEXPORT jboolean JNICALL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.sh
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.showYesNoAlert
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.toast
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.unregisterLocalReceiver
import me.timschneeberger.rootlessjamesdsp.utils.isPlugin
import me.timschneeberger.rootlessjamesdsp.utils.isRoot
import me.timschneeberger.rootlessjamesdsp.utils.isRootless
import timber.log.Timber
Expand Down Expand Up @@ -249,8 +250,12 @@ class LiveprogEditorActivity : BaseActivity() {
}

// If service down or in case of root, if engine disabled, show warning message
// TODO: plugin mode -> is activeServices zero?
if(BaseAudioProcessorService.activeServices <= 0 || (!isRootless() && prefsApp.get<Boolean>(R.string.key_powered_on))) {
if(
// Root/Rootless: if no services are active
(!isPlugin() && BaseAudioProcessorService.activeServices <= 0) ||
// Root/Plugin: if power button off
(!isRootless() && prefsApp.get<Boolean>(R.string.key_powered_on))
) {
this.showAlert(R.string.editor_engine_down_title, R.string.editor_engine_down)
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.se
import timber.log.Timber
import java.util.Timer
import kotlin.concurrent.schedule
import kotlin.reflect.jvm.internal.impl.renderer.ClassifierNamePolicy.SHORT

class JamesDspLocalEngine(context: Context, callbacks: JamesDspWrapper.JamesDspCallbacks? = null) : JamesDspBaseEngine(context, callbacks) {
var handle: JamesDspHandle = JamesDspWrapper.alloc(callbacks ?: DummyCallbacks())
Expand All @@ -33,34 +34,52 @@ class JamesDspLocalEngine(context: Context, callbacks: JamesDspWrapper.JamesDspC
}

// Processing
fun processInt16(input: ShortArray): ShortArray
fun processInt16(input: ShortArray, output: ShortArray, offset: Int = -1, length: Int = -1)
{
if(!enabled || handle == 0L)
{
return input
if(offset < 0 && length < 0) {
input.copyInto(output)
}
else {
input.copyInto(output, 0, offset, offset + length)
}
}
else {
JamesDspWrapper.processInt16(handle, input, output, offset, length)
}

return JamesDspWrapper.processInt16(handle, input)
}

fun processInt32(input: IntArray): IntArray
fun processInt32(input: IntArray, output: IntArray, offset: Int = -1, length: Int = -1)
{
if(!enabled || handle == 0L)
{
return input
if(offset < 0 && length < 0) {
input.copyInto(output)
}
else {
input.copyInto(output, 0, offset, offset + length)
}
}
else {
JamesDspWrapper.processInt32(handle, input, output, offset, length)
}

return JamesDspWrapper.processInt32(handle, input)
}

fun processFloat(input: FloatArray): FloatArray
fun processFloat(input: FloatArray, output: FloatArray, offset: Int = -1, length: Int = -1)
{
if(!enabled || handle == 0L)
{
return input
if(offset < 0 && length < 0) {
input.copyInto(output)
}
else {
input.copyInto(output, 0, offset, offset + length)
}
}
else {
JamesDspWrapper.processFloat(handle, input, output, offset, length)
}

return JamesDspWrapper.processFloat(handle, input)
}

// Effect config
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ object JamesDspWrapper {
external fun isHandleValid(self: JamesDspHandle): Boolean

// Processing (interleaved)
external fun processInt16(self: JamesDspHandle, input: ShortArray): ShortArray
external fun processInt16(self: JamesDspHandle, input: ShortArray, output: ShortArray, offset: Int = -1, length: Int = -1)
external fun processInt8U24(self: JamesDspHandle, input: IntArray): IntArray
external fun processInt24Packed(self: JamesDspHandle, input: BooleanArray): BooleanArray

external fun processInt32(self: JamesDspHandle, input: IntArray): IntArray
external fun processFloat(self: JamesDspHandle, input: FloatArray): FloatArray
external fun processInt32(self: JamesDspHandle, input: IntArray, output: IntArray, offset: Int = -1, length: Int = -1)
external fun processFloat(self: JamesDspHandle, input: FloatArray, output: FloatArray, offset: Int = -1, length: Int = -1)

// Engine config
external fun setSamplingRate(self: JamesDspHandle, sampleRate: Float, forceRefresh: Boolean)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package me.timschneeberger.rootlessjamesdsp.flavor

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import me.timschneeberger.rootlessjamesdsp.R
import me.timschneeberger.rootlessjamesdsp.interop.JamesDspLocalEngine
import me.timschneeberger.rootlessjamesdsp.interop.ProcessorMessageHandler
import me.timschneeberger.rootlessjamesdsp.utils.Constants
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.registerLocalReceiver
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.unregisterLocalReceiver
import me.timschneeberger.rootlessjamesdsp.utils.preferences.Preferences
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject

abstract class JamesDspBasePlugin : KoinComponent, AutoCloseable {
protected val context: Context by inject()

// Engine
protected val engine = JamesDspLocalEngine(context, ProcessorMessageHandler())

// Preferences
protected val preferences: Preferences.App by inject()
private val onPreferenceChanged = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
when(key) {
context.getString(R.string.key_powered_on) -> {
engine.enabled = preferences.get<Boolean>(R.string.key_powered_on)
}
}
}

// General purpose broadcast receiver
private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
Constants.ACTION_SAMPLE_RATE_UPDATED -> engine.syncWithPreferences(arrayOf(Constants.PREF_CONVOLVER))
Constants.ACTION_PREFERENCES_UPDATED -> engine.syncWithPreferences()
Constants.ACTION_SERVICE_RELOAD_LIVEPROG -> engine.syncWithPreferences(arrayOf(Constants.PREF_LIVEPROG))
}
}
}

init {
preferences.registerOnSharedPreferenceChangeListener(onPreferenceChanged)
// Setup general-purpose broadcast receiver
context.registerLocalReceiver(broadcastReceiver, IntentFilter().apply {
addAction(Constants.ACTION_PREFERENCES_UPDATED)
addAction(Constants.ACTION_SAMPLE_RATE_UPDATED)
addAction(Constants.ACTION_SERVICE_RELOAD_LIVEPROG)
addAction(Constants.ACTION_SERVICE_HARD_REBOOT_CORE)
addAction(Constants.ACTION_SERVICE_SOFT_REBOOT_CORE)
})
context.registerReceiver(broadcastReceiver, IntentFilter())
engine.enabled = preferences.get<Boolean>(R.string.key_powered_on)
engine.syncWithPreferences()
}

override fun close() {
context.unregisterLocalReceiver(broadcastReceiver)
preferences.unregisterOnSharedPreferenceChangeListener(onPreferenceChanged)
engine.close()
}
}

0 comments on commit 059b8c3

Please sign in to comment.