Skip to content

Commit

Permalink
Robust Java to C engine data buffer commit
Browse files Browse the repository at this point in the history
  • Loading branch information
james34602 committed Sep 9, 2023
1 parent 45e8ea9 commit be98515
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 123 deletions.
20 changes: 0 additions & 20 deletions Main/DSPManager/DSPManagerNonFree.iml

This file was deleted.

27 changes: 23 additions & 4 deletions Main/DSPManager/jni/main/JdspImpResToolbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,35 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdint.h>
#include "interpolation.h"
void channel_splitFloat(float *buffer, unsigned int num_frames, float **chan_buffers, unsigned int num_channels)
{
unsigned int i, samples = num_frames * num_channels;
for (i = 0; i < samples; i++)
chan_buffers[i % num_channels][i / num_channels] = buffer[i];
}
void channel_joinFloat(float **chan_buffers, unsigned int num_channels, float *buffer, unsigned int num_frames)
int32_t channel_joinFloat(float **chan_buffers, unsigned int num_channels, float *buffer, unsigned int num_frames)
{
unsigned int i, samples = num_frames * num_channels;
union
{
int32_t raw;
float f;
} fltInt;
int32_t crc = 0xFFFFFFFF;
for (i = 0; i < samples; i++)
{
buffer[i] = chan_buffers[i % num_channels][i / num_channels];
fltInt.f = buffer[i];
crc = crc ^ fltInt.raw;
for (int j = 7; j >= 0; j--)
{
int32_t mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
}
return ~crc;
}
unsigned long upper_power_of_two(unsigned long v)
{
Expand Down Expand Up @@ -433,6 +450,7 @@ JNIEXPORT jfloatArray JNICALL Java_james_dsp_activity_JdspImpResToolbox_ReadImpu
splittedBuffer[i] = (float*)malloc(frameCount * sizeof(float));
}
channel_splitFloat(pFrameBuffer, frameCount, splittedBuffer, channels);
int32_t crc32;
if (convMode > 0)
{
free(pFrameBuffer);
Expand Down Expand Up @@ -502,7 +520,7 @@ JNIEXPORT jfloatArray JNICALL Java_james_dsp_activity_JdspImpResToolbox_ReadImpu
unsigned int totalFrames = xLen * channels;
frameCount = xLen;
pFrameBuffer = (float*)malloc(totalFrames * sizeof(float));
channel_joinFloat(outPtr, channels, pFrameBuffer, xLen);
crc32 = channel_joinFloat(outPtr, channels, pFrameBuffer, xLen);
}
else
{
Expand All @@ -512,15 +530,16 @@ JNIEXPORT jfloatArray JNICALL Java_james_dsp_activity_JdspImpResToolbox_ReadImpu
for (int j = 0; j < javaAdvSetPtr[i + 2] - 1; j++)
splittedBuffer[i][j] = 0.0f;
}
channel_joinFloat(splittedBuffer, channels, pFrameBuffer, frameCount);
crc32 = channel_joinFloat(splittedBuffer, channels, pFrameBuffer, frameCount);
}
for (i = 0; i < channels; i++)
free(splittedBuffer[i]);
(*env)->ReleaseIntArrayElements(env, jadvParam, javaAdvSetPtr, 0);
jint *javaBasicInfoPtr = (jint*) (*env)->GetIntArrayElements(env, jImpInfo, 0);
javaBasicInfoPtr[0] = (int)channels;
javaBasicInfoPtr[1] = (int)frameCount;
(*env)->SetIntArrayRegion(env, jImpInfo, 0, 2, javaBasicInfoPtr);
javaBasicInfoPtr[2] = crc32;
(*env)->SetIntArrayRegion(env, jImpInfo, 0, 3, javaBasicInfoPtr);
jfloatArray outbuf;
int frameCountTotal = channels * frameCount;
size_t bufferSize = frameCountTotal * sizeof(float);
Expand Down
177 changes: 86 additions & 91 deletions Main/DSPManager/src/james/dsp/service/HeadsetService.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ private void setParameterShort(AudioEffect audioEffect, int parameter, short val
throw new RuntimeException(e);
}
}
private int getParameter(AudioEffect audioEffect, int parameter)
private int getParameterInt(AudioEffect audioEffect, int parameter)
{
try
{
Expand Down Expand Up @@ -311,20 +311,12 @@ public HeadsetService getService()
/**
* Receive new broadcast intents for adding DSP to session
*/
private String oldeqText = "";
private String oldEELProgramName = "";
private String oldVDCName = "";
private String oldImpulseName = "";
private int[] oldImpSet = new int[6];
private int oldConvMode = 0;
private float prelimthreshold = 0;
private float prelimrelease = 0;
private float prepostgain = 0;
public static JDSPModule JamesDSPGbEf;
private SharedPreferences preferencesMode;
public static int dspModuleSamplingRate = 0;
public static String ddcString = "";
public static String eelProgString = "";

final static public float[] mergeFloatArray(final float[] ...arrays)
{
Expand All @@ -342,6 +334,21 @@ final static public float[] mergeFloatArray(final float[] ...arrays)
}
return res;
}
final static public int HashString(final String str)
{
byte[] btAry = str.getBytes();
int crc = 0xFFFFFFFF;
for (int i = 0; i < btAry.length; i++)
{
crc = crc ^ btAry[i];
for (int j = 7; j >= 0; j--)
{
int mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
}
return ~crc;
}

private final BroadcastReceiver mAudioSessionReceiver = new BroadcastReceiver()
{
Expand Down Expand Up @@ -652,7 +659,7 @@ protected void updateDsp(boolean notify, boolean updateConvolver)
{
String pid = "";
if (JamesDSPGbEf != null)
pid = " PID:" + JamesDSPGbEf.getParameter(JamesDSPGbEf.JamesDSP, 20002);
pid = " PID:" + JamesDSPGbEf.getParameterInt(JamesDSPGbEf.JamesDSP, 20002);
if (mode == "bluetooth")
foregroundPersistent(getString(R.string.bluetooth_title) + pid);
else if (mode == "headset")
Expand Down Expand Up @@ -690,6 +697,7 @@ else if (mode == "headset")

private void updateDsp(SharedPreferences preferences, JDSPModule session, boolean updateMajor, int sessionId)
{
Log.e("HeadsetService", "sessionId = " + sessionId);
boolean masterSwitch = preferences.getBoolean("dsp.masterswitch.enable", false);
session.JamesDSP.setEnabled(masterSwitch); // Master switch
if (masterSwitch)
Expand All @@ -705,14 +713,14 @@ private void updateDsp(SharedPreferences preferences, JDSPModule session, boolea
int analogModelEnabled = preferences.getBoolean("dsp.analogmodelling.enable", false) ? 1 : 0;
int viperddcEnabled = preferences.getBoolean("dsp.ddc.enable", false) ? 1 : 0;
int liveProgEnabled = preferences.getBoolean("dsp.liveprog.enable", false) ? 1 : 0;
int numberOfParameterCommitted = session.getParameter(session.JamesDSP, 19998);
int numberOfParameterCommitted = session.getParameterInt(session.JamesDSP, 19998);
// Log.i(DSPManager.TAG, "Commited: " + numberOfParameterCommitted);
int dspBufferLen = session.getParameter(session.JamesDSP, 19999);
int dspAllocatedBlockLen = session.getParameter(session.JamesDSP, 20000);
dspModuleSamplingRate = session.getParameter(session.JamesDSP, 20001);
int dspBufferLen = session.getParameterInt(session.JamesDSP, 19999);
int dspAllocatedBlockLen = session.getParameterInt(session.JamesDSP, 20000);
dspModuleSamplingRate = session.getParameterInt(session.JamesDSP, 20001);
if (dspModuleSamplingRate == 0)
{
if (session.getParameter(session.JamesDSP, 20002) == 0)
if (session.getParameterInt(session.JamesDSP, 20002) == 0)
{
Toast.makeText(HeadsetService.this, R.string.dspneedreboot, Toast.LENGTH_LONG).show();
Log.e("HeadsetService", "Get PID failed from engine");
Expand Down Expand Up @@ -801,23 +809,23 @@ private void updateDsp(SharedPreferences preferences, JDSPModule session, boolea
session.setParameterFloatArray(session.JamesDSP, 116, sendAry);
}
session.setParameterShort(session.JamesDSP, 1202, (short)equalizerEnabled); // Equalizer switch
boolean updateNow = true;
if (stringEqEnabled == 1 && updateMajor)
{
String eqText = preferences.getString("dsp.streq.stringp", "GraphicEQ: 0.0 0.0; ");
if(oldeqText.equals(eqText) && numberOfParameterCommitted != 0)
updateNow = false;
if (updateNow)
{
oldeqText = eqText;
int previousHash = session.getParameterInt(session.JamesDSP, 30000);
int hashID = HashString(eqText);
Log.e(DSPManager.TAG, "ArbEq hash before: " + previousHash + ", current: " + hashID);
if (previousHash != hashID)
{
int arraySize2Send = 256;
int stringLength = eqText.length();
int numTime2Send = (int)Math.ceil((double)stringLength / arraySize2Send); // Number of times that have to send
session.setParameterIntArray(session.JamesDSP, 8888, new int[]{ numTime2Send, arraySize2Send }); // Send buffer info for module to allocate memory
for (int i = 0; i < numTime2Send; i++)
session.setParameterCharArray(session.JamesDSP, 12001, eqText.substring(arraySize2Send * i, Math.min(arraySize2Send * i + arraySize2Send, stringLength))); // Commit buffer
session.setParameterShort(session.JamesDSP, 10006, (short)1); // Notify send array completed and generate filter in native side
}
session.setParameterInt(session.JamesDSP, 25000, hashID); // Commit hashID to engine
}
}
session.setParameterShort(session.JamesDSP, 1210, (short)stringEqEnabled); // String equalizer switch
if (reverbEnabled == 1 && updateMajor)
Expand All @@ -832,79 +840,74 @@ private void updateDsp(SharedPreferences preferences, JDSPModule session, boolea
if (analogModelEnabled == 1 && updateMajor)
session.setParameterShort(session.JamesDSP, 150, (short) (Float.valueOf(preferences.getString("dsp.analogmodelling.tubedrive", "2"))*1000));
session.setParameterShort(session.JamesDSP, 1206, (short)analogModelEnabled); // Analog modelling switch
updateNow = true;
if (viperddcEnabled == 1 && updateMajor)
{
String ddcFilePath = preferences.getString("dsp.ddc.files", "");
if(oldVDCName.equals(ddcFilePath) && numberOfParameterCommitted != 0)
updateNow = false;
if (updateNow)
{
oldVDCName = ddcFilePath;
StringBuilder contentBuilder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(ddcFilePath)))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null)
contentBuilder.append(sCurrentLine).append("\n");
}
catch (IOException e)
{
e.printStackTrace();
}
int arraySize2Send = 256;
ddcString = contentBuilder.toString();
if(ddcString != null && !ddcString.isEmpty())
{
StringBuilder contentBuilder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(ddcFilePath)))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null)
contentBuilder.append(sCurrentLine).append("\n");
}
catch (IOException e)
{
e.printStackTrace();
}
int arraySize2Send = 256;
String ddcString = contentBuilder.toString();
if(ddcString != null && !ddcString.isEmpty())
{
int previousHash = session.getParameterInt(session.JamesDSP, 30001);
int hashID = HashString(ddcString);
Log.e(DSPManager.TAG, "DDC hash before: " + previousHash + ", current: " + hashID);
if (previousHash != hashID)
{
int stringLength = ddcString.length();
int numTime2Send = (int)Math.ceil((double)stringLength / arraySize2Send); // Number of times that have to send
session.setParameterIntArray(session.JamesDSP, 8888, new int[]{ numTime2Send, arraySize2Send }); // Send buffer info for module to allocate memory
for (int i = 0; i < numTime2Send; i++)
session.setParameterCharArray(session.JamesDSP, 12001, ddcString.substring(arraySize2Send * i, Math.min(arraySize2Send * i + arraySize2Send, stringLength))); // Commit buffer
session.setParameterShort(session.JamesDSP, 10009, (short)1); // Notify send array completed and generate filter in native side
}
}
session.setParameterInt(session.JamesDSP, 25001, hashID); // Commit hashID to engine
}
}
}
else
oldVDCName = "";
session.setParameterShort(session.JamesDSP, 1212, (short)viperddcEnabled); // VDC switch
updateNow = true;
if (liveProgEnabled == 1 && updateMajor)
{
String eelFilePath = preferences.getString("dsp.liveprog.files", "");
if(oldEELProgramName.equals(eelFilePath) && numberOfParameterCommitted != 0)
updateNow = false;
if (updateNow)
{
oldEELProgramName = eelFilePath;
StringBuilder contentBuilder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(eelFilePath)))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null)
contentBuilder.append(sCurrentLine).append("\n");
}
catch (IOException e)
{
e.printStackTrace();
}
int arraySize2Send = 256;
eelProgString = contentBuilder.toString();
if(eelProgString != null && !eelProgString.isEmpty())
{
StringBuilder contentBuilder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(eelFilePath)))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null)
contentBuilder.append(sCurrentLine).append("\n");
}
catch (IOException e)
{
e.printStackTrace();
}
int arraySize2Send = 256;
String eelProgString = contentBuilder.toString();
if(eelProgString != null && !eelProgString.isEmpty())
{
int previousHash = session.getParameterInt(session.JamesDSP, 30002);
int hashID = HashString(eelProgString);
Log.e(DSPManager.TAG, "LiveProg hash before: " + previousHash + ", current: " + hashID);
if (previousHash != hashID)
{
int stringLength = eelProgString.length();
int numTime2Send = (int)Math.ceil((double)stringLength / arraySize2Send); // Number of times that have to send
session.setParameterIntArray(session.JamesDSP, 8888, new int[]{ numTime2Send, arraySize2Send }); // Send buffer info for module to allocate memory
for (int i = 0; i < numTime2Send; i++)
session.setParameterCharArray(session.JamesDSP, 12001, eelProgString.substring(arraySize2Send * i, Math.min(arraySize2Send * i + arraySize2Send, stringLength))); // Commit buffer
session.setParameterShort(session.JamesDSP, 10010, (short)1); // Notify send array completed and generate filter in native side
}
}
session.setParameterInt(session.JamesDSP, 25002, hashID); // Commit hashID to engine
}
}
}
else
oldEELProgramName = "";
session.setParameterShort(session.JamesDSP, 1213, (short)liveProgEnabled); // LiveProg switch
updateNow = true;
if (convolverEnabled == 1 && updateMajor)
{
String mConvIRFilePath = preferences.getString("dsp.convolver.files", "");
Expand All @@ -918,18 +921,15 @@ private void updateDsp(SharedPreferences preferences, JDSPModule session, boolea
advSetting[i] = Integer.valueOf(advConv[i]);
//Log.e(DSPManager.TAG, "Advance settings: " + Arrays.toString(advSetting));// Debug
}
if(oldImpulseName.equals(mConvIRFilePath) && numberOfParameterCommitted != 0 && oldConvMode == convMode && Arrays.equals(oldImpSet, advSetting))
updateNow = false;
if (updateNow)
{
oldImpulseName = mConvIRFilePath;
oldConvMode = convMode;
oldImpSet = advSetting.clone();
String mConvIRFileName = mConvIRFilePath.replace(DSPManager.impulseResponsePath, "");
int[] impinfo = new int[3];
//Log.e(DSPManager.TAG, "Conv mode: " + convMode);// Debug
float[] impulseResponse = JdspImpResToolbox.ReadImpulseResponseToFloat(mConvIRFilePath, dspModuleSamplingRate, impinfo, convMode, advSetting);
int previousHash = session.getParameterInt(session.JamesDSP, 30003);
Log.e(DSPManager.TAG, "Convolver hash before: " + previousHash + ", current: " + impinfo[2]);
if (previousHash != impinfo[2])
{
session.setParameterShort(session.JamesDSP, 1205, (short)0);
String mConvIRFileName = mConvIRFilePath.replace(DSPManager.impulseResponsePath, "");
int[] impinfo = new int[2];
//Log.e(DSPManager.TAG, "Conv mode: " + convMode);// Debug
float[] impulseResponse = JdspImpResToolbox.ReadImpulseResponseToFloat(mConvIRFilePath, dspModuleSamplingRate, impinfo, convMode, advSetting);
//Log.e(DSPManager.TAG, "Channels: " + impinfo[0] + ", frameCount: " + impinfo[1]);// Debug
if (impinfo[1] == 0)
{
Expand All @@ -952,6 +952,7 @@ private void updateDsp(SharedPreferences preferences, JDSPModule session, boolea
session.setParameterFloatArray(session.JamesDSP, 12000, sendArray); // Commit buffer
}
session.setParameterShort(session.JamesDSP, 10004, (short)1); // Notify send array completed and resize array in native side
session.setParameterInt(session.JamesDSP, 25003, impinfo[2]); // Commit hashID to engine
if (DSPManager.devMsgDisplay)
{
Toast.makeText(HeadsetService.this, getString(R.string.basicinfo, dspBufferLen, dspAllocatedBlockLen), Toast.LENGTH_SHORT).show();
Expand All @@ -963,13 +964,7 @@ else if (impinfo[0] == 4)
Toast.makeText(HeadsetService.this, getString(R.string.convolversuccess, mConvIRFileName, getString(R.string.fullstereo_conv), impinfo[1], (int)impulseCutted / 4), Toast.LENGTH_SHORT).show();
}
}
}
}
else
{
oldImpulseName = "";
oldConvMode = 0;
Arrays.fill(oldImpSet, 0);
}
}
session.setParameterShort(session.JamesDSP, 1205, (short)convolverEnabled); // Convolver switch
}
Expand Down
Loading

0 comments on commit be98515

Please sign in to comment.