diff --git a/Main/libjamesdsp/jni/Android.mk b/Main/libjamesdsp/jni/Android.mk.disabled similarity index 100% rename from Main/libjamesdsp/jni/Android.mk rename to Main/libjamesdsp/jni/Android.mk.disabled diff --git a/Main/libjamesdsp/jni/jamesdsp/Android.bp b/Main/libjamesdsp/jni/jamesdsp/Android.bp new file mode 100644 index 0000000..86c61b8 --- /dev/null +++ b/Main/libjamesdsp/jni/jamesdsp/Android.bp @@ -0,0 +1,175 @@ +filegroup { + name: "jdspCommonFile", + srcs: [ + "cpthread.c", + "jdsp_impl.c", + "jdsp/generalDSP/spectralInterpolatorFloat.c", + "jdsp/generalDSP/ArbFIRGen.c", + "jdsp/Effects/eel2/numericSys/codelet.c", + "jdsp/generalDSP/digitalFilters.c", + "jdsp/Effects/eel2/numericSys/FFTConvolver.c", + "jdsp/generalDSP/TwoStageFFTConvolver.c", + "jdsp/generalDSP/interpolation.c", + "jdsp/generalDSP/generalProg.c", + "jdsp/Effects/vdc.c", + "jdsp/Effects/vacuumTube.c", + "jdsp/Effects/stereoEnhancement.c", + "jdsp/Effects/reverb.c", + "jdsp/Effects/liveprogWrapper.c", + "jdsp/Effects/multimodalEQ.c", + "jdsp/Effects/dynamic.c", + "jdsp/Effects/dbb.c", + "jdsp/Effects/convolver1D.c", + "jdsp/Effects/crossfeed.c", + "jdsp/Effects/bs2b.c", + "jdsp/Effects/arbEqConv.c", + "jdsp/Effects/eel2/numericSys/libsamplerate/samplerate.c", + "jdsp/Effects/eel2/numericSys/libsamplerate/src_sinc.c", + "jdsp/Effects/eel2/numericSys/libsamplerate/src_linear.c", + "jdsp/Effects/eel2/numericSys/FilterDesign/generalFdesign.c", + "jdsp/Effects/eel2/numericSys/FilterDesign/cos_fib_paraunitary.c", + "jdsp/Effects/eel2/numericSys/FilterDesign/polyphaseFilterbank.c", + "jdsp/Effects/eel2/numericSys/FilterDesign/polyphaseASRC.c", + "jdsp/Effects/eel2/numericSys/FilterDesign/eqnerror.c", + "jdsp/Effects/eel2/numericSys/FilterDesign/firls.c", + "jdsp/Effects/eel2/numericSys/SolveLinearSystem/inv.c", + "jdsp/Effects/eel2/numericSys/SolveLinearSystem/pinv.c", + "jdsp/Effects/eel2/numericSys/SolveLinearSystem/mldivide.c", + "jdsp/Effects/eel2/numericSys/SolveLinearSystem/mrdivide.c", + "jdsp/Effects/eel2/numericSys/SolveLinearSystem/qr_fact.c", + "jdsp/Effects/eel2/numericSys/solvopt.c", + "jdsp/Effects/eel2/numericSys/cpoly.c", + "jdsp/Effects/eel2/numericSys/MersenneTwister.c", + "jdsp/Effects/eel2/numericSys/quadprog.c", + "jdsp/Effects/eel2/numericSys/HPFloat/atox.c", + "jdsp/Effects/eel2/numericSys/HPFloat/constant.c", + "jdsp/Effects/eel2/numericSys/HPFloat/cxaop.c", + "jdsp/Effects/eel2/numericSys/HPFloat/cxbasic.c", + "jdsp/Effects/eel2/numericSys/HPFloat/cxconstant.c", + "jdsp/Effects/eel2/numericSys/HPFloat/cxconvf.c", + "jdsp/Effects/eel2/numericSys/HPFloat/cxexp.c", + "jdsp/Effects/eel2/numericSys/HPFloat/cxhypb.c", + "jdsp/Effects/eel2/numericSys/HPFloat/cxidiv.c", + "jdsp/Effects/eel2/numericSys/HPFloat/cxpow.c", + "jdsp/Effects/eel2/numericSys/HPFloat/cxprcmp.c", + "jdsp/Effects/eel2/numericSys/HPFloat/cxtrig.c", + "jdsp/Effects/eel2/numericSys/HPFloat/hpaconf.c", + "jdsp/Effects/eel2/numericSys/HPFloat/prcxpr.c", + "jdsp/Effects/eel2/numericSys/HPFloat/print.c", + "jdsp/Effects/eel2/numericSys/HPFloat/prxpr.c", + "jdsp/Effects/eel2/numericSys/HPFloat/sfmod.c", + "jdsp/Effects/eel2/numericSys/HPFloat/shift.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xadd.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xchcof.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xdiv.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xevtch.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xexp.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xfmod.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xfrac.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xhypb.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xivhypb.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xivtrg.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xlog.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xmul.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xneg.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xprcmp.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xpwr.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xsigerr.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xsqrt.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xtodbl.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xtoflt.c", + "jdsp/Effects/eel2/numericSys/HPFloat/xtrig.c", + "jdsp/Effects/eel2/s_str.c", + "jdsp/Effects/eel2/fft.c", + "jdsp/Effects/eel2/nseel-compiler.c", + "jdsp/Effects/eel2/nseel-ram.c", + "jdsp/Effects/eel2/y.tab.c", + "jdsp/binaryBlobs.c", + "jdsp/jdspController.c", + ], +} + +cc_defaults { + name: "jdspDefaults", + cflags: [ + "-Wall", + "-Wextra", + "-Ofast", + "-ftree-vectorize", + "-ffunction-sections", + "-fdata-sections", + "-g", + "-DAOSP_SOONG_BUILD", + "-DJAMESDSP_REFERENCE_IMPL", + "-DNDEBUG", + ], + header_libs: [ + "liblog_headers", + "libhardware_headers", + ], + lto: { + // TODO: full was removed in https://android-review.googlesource.com/c/platform/build/soong/+/2609595 + thin: true, + }, +} + +cc_library_static { + name: "libjamesdspimpl", + vendor: true, + defaults: [ + "jdspDefaults", + ], + srcs: [ + ":jdspCommonFile", + ], +} + +cc_defaults { + name: "jdspEffectDefaults", + defaults: [ + "jdspDefaults", + ], + whole_static_libs: [ + "libjamesdspimpl" + ], + shared_libs: [ + "liblog", + ], + cflags: [ + "-DBACKEND_NDK", + ], +} + +cc_library_shared { + name: "libjamesdsp", + vendor: true, + relative_install_path: "soundfx", + defaults: [ + "jdspEffectDefaults", + ], + srcs: [ + "jamesdsp.c", + ], + cflags: [ + "-fvisibility=hidden", + ], +} + +cc_library_shared { + name: "libjamesdspaidl", + vendor: true, + relative_install_path: "soundfx", + defaults: [ + "aidlaudioeffectservice_defaults", + "jdspEffectDefaults", + ], + srcs: [ + "jamesdsp_aidl.cpp", + // AOSP + ":effectCommonFile", + ], + static_libs: [ + "libaudio_aidl_conversion_common_ndk", + "libstagefright_foundation", + ], +} diff --git a/Main/libjamesdsp/jni/jamesdsp/Android.mk b/Main/libjamesdsp/jni/jamesdsp/Android.mk.disabled similarity index 99% rename from Main/libjamesdsp/jni/jamesdsp/Android.mk rename to Main/libjamesdsp/jni/jamesdsp/Android.mk.disabled index 1e0c5e2..0e8c6b8 100644 --- a/Main/libjamesdsp/jni/jamesdsp/Android.mk +++ b/Main/libjamesdsp/jni/jamesdsp/Android.mk.disabled @@ -4,6 +4,7 @@ LOCAL_MODULE := libjamesdsp LOCAL_PRELINK_MODULE := false LOCAL_SRC_FILES := \ cpthread.c \ + jdsp_impl.c \ jdsp/generalDSP/spectralInterpolatorFloat.c \ jdsp/generalDSP/ArbFIRGen.c \ jdsp/Effects/eel2/numericSys/codelet.c \ @@ -104,4 +105,4 @@ LOCAL_CPPFLAGS += -ffunction-sections -fdata-sections -Ofast -ftree-vectorize -f LOCAL_CFLAGS += -ffunction-sections -fdata-sections -Ofast -ftree-vectorize -fvisibility=hidden -DJAMESDSP_REFERENCE_IMPL #-DDEBUG -g endif LOCAL_LDFLAGS += -Wl,--gc-sections,--exclude-libs,ALL -include $(BUILD_SHARED_LIBRARY) \ No newline at end of file +include $(BUILD_SHARED_LIBRARY) diff --git a/Main/libjamesdsp/jni/jamesdsp/jamesdsp.c b/Main/libjamesdsp/jni/jamesdsp/jamesdsp.c index 67d7213..a9e665f 100644 --- a/Main/libjamesdsp/jni/jamesdsp/jamesdsp.c +++ b/Main/libjamesdsp/jni/jamesdsp/jamesdsp.c @@ -4,812 +4,16 @@ #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG,__VA_ARGS__) -#include "MemoryUsage.h" #endif -#include -#include + +#ifdef AOSP_SOONG_BUILD +#include +#else #include "essential.h" -// Effect section -#include "jdsp/jdsp_header.h" -typedef struct -{ - unsigned long long initializeForFirst; - int32_t engineImpulseResponseHash; - int32_t hashSlot[4]; - int mEnable; - JamesDSPLib jdsp; - float mSamplingRate; - int formatFloatModeInt32Mode; - char *stringEq; - float *tempImpulseIncoming; - float drcAtkRel[4]; - float boostingCon; - int bbMaxGain; - // Variables - int numTime2Send, samplesInc, stringIndex; - int16_t impChannels; - int32_t impulseLengthActual, convolverNeedRefresh; -} EffectDSPMain; -typedef struct -{ - int32_t status; - uint32_t psize; - uint32_t vsize; - int32_t cmd; - int32_t data; -} reply1x4_1x4_t; -void EffectDSPMainConstructor(EffectDSPMain *dspmain) -{ - dspmain->initializeForFirst = 0; - dspmain->tempImpulseIncoming = 0; - dspmain->stringEq = 0; - dspmain->boostingCon = 3; - dspmain->bbMaxGain = 0; - dspmain->numTime2Send = 0; - dspmain->samplesInc = 0; - dspmain->stringIndex = 0; - JamesDSPInit(&dspmain->jdsp, 128, 48000.0f); -} -void EffectDSPMainDestructor(EffectDSPMain *dspmain) -{ - JamesDSPFree(&dspmain->jdsp); - if (dspmain->tempImpulseIncoming) - free(dspmain->tempImpulseIncoming); - if (dspmain->stringEq) - free(dspmain->stringEq); -#ifdef DEBUG - LOGI("Buffer freed"); -#endif -} -int32_t configure(EffectDSPMain *dspmain, void* pCmdData, effect_buffer_access_e* mAccessMode) -{ - effect_config_t *cfg = (effect_config_t*)pCmdData; - buffer_config_t in = cfg->inputCfg; - buffer_config_t out = cfg->outputCfg; - /* Check that we aren't asked to do resampling. Note that audioflinger - * always provides full setup info at initial configure time. */ -#ifdef DEBUG - LOGI("Sample rate of In: %u and out: %u", in.samplingRate, out.samplingRate); -#endif - if ((in.mask & EFFECT_CONFIG_SMP_RATE) && (out.mask & EFFECT_CONFIG_SMP_RATE)) - { - if (out.samplingRate != in.samplingRate) - { -#ifdef DEBUG - LOGW("In/out sample rate doesn't match"); -#endif - return -EINVAL; - } - dspmain->mSamplingRate = (float)in.samplingRate; - } - if (in.mask & EFFECT_CONFIG_CHANNELS && out.mask & EFFECT_CONFIG_CHANNELS) - { - if (in.channels != AUDIO_CHANNEL_OUT_STEREO) - { -#ifdef DEBUG - LOGE("Input is non stereo signal. It's channel count is %u", in.channels); -#endif - return -EINVAL; - } - if (out.channels != AUDIO_CHANNEL_OUT_STEREO) - { -#ifdef DEBUG - LOGE("Output is non stereo signal. It's channel count is %u", out.channels); -#endif - return -EINVAL; - } - } - else - { -#ifdef DEBUG - LOGE("In/out channel mask doesn't match"); -#endif - } - if (in.mask & EFFECT_CONFIG_FORMAT) - { - if (in.format == AUDIO_FORMAT_PCM_FLOAT) - dspmain->formatFloatModeInt32Mode = 1; - else if (in.format == AUDIO_FORMAT_PCM_32_BIT) - dspmain->formatFloatModeInt32Mode = 2; - else if (in.format == AUDIO_FORMAT_PCM_24_BIT_PACKED) - dspmain->formatFloatModeInt32Mode = 3; - else if (in.format == AUDIO_FORMAT_PCM_8_24_BIT) - dspmain->formatFloatModeInt32Mode = 4; - else if (in.format == AUDIO_FORMAT_PCM_16_BIT) - dspmain->formatFloatModeInt32Mode = 0; - } - if (out.mask & EFFECT_CONFIG_FORMAT) - { - if (out.format == AUDIO_FORMAT_PCM_FLOAT) - dspmain->formatFloatModeInt32Mode = 1; - else if (out.format == AUDIO_FORMAT_PCM_32_BIT) - dspmain->formatFloatModeInt32Mode = 2; - else if (out.format == AUDIO_FORMAT_PCM_24_BIT_PACKED) - dspmain->formatFloatModeInt32Mode = 3; - else if (out.format == AUDIO_FORMAT_PCM_8_24_BIT) - dspmain->formatFloatModeInt32Mode = 4; - else if (out.format == AUDIO_FORMAT_PCM_16_BIT) - dspmain->formatFloatModeInt32Mode = 0; - } -#ifdef DEBUG - LOGW("I/O FMT = { %u, %u }", in.format, out.format); -#endif - if (out.mask & EFFECT_CONFIG_ACC_MODE) - *mAccessMode = (effect_buffer_access_e) out.accessMode; - return 0; -} -int32_t EffectDSPMainCommand(EffectDSPMain *dspmain, uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize, void* pReplyData) -{ -#ifdef DEBUG -// LOGI("Memory used: %f Mb", (float)getCurrentRSS() / 1024.0 / 1024.0); -#endif - if (cmdCode == EFFECT_CMD_SET_CONFIG) - { - effect_buffer_access_e mAccessMode; - int32_t *replyData = (int32_t *)pReplyData; - int32_t ret = configure(dspmain, pCmdData, &mAccessMode); - if (ret != 0) - { - *replyData = ret; - return 0; - } - // Set sample rate - JamesDSPSetSampleRate(&dspmain->jdsp, dspmain->mSamplingRate, 0); - *replyData = 0; - return 0; - } - if (cmdCode == EFFECT_CMD_GET_PARAM) - { - effect_param_t *cep = (effect_param_t *)pCmdData; - if (cep->psize == 4 && cep->vsize == 4) - { - int32_t cmd = ((int32_t *)cep)[3]; - if (cmd == 19998) - { - reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; - replyData->status = 0; - replyData->psize = 4; - replyData->vsize = 4; - replyData->cmd = 19998; - replyData->data = (int32_t)dspmain->initializeForFirst++; - *replySize = sizeof(reply1x4_1x4_t); - return 0; - } - if (cmd == 19999) - { - reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; - replyData->status = 0; - replyData->psize = 4; - replyData->vsize = 4; - replyData->cmd = 19999; - replyData->data = (int32_t)dspmain->jdsp.blockSize; - *replySize = sizeof(reply1x4_1x4_t); - return 0; - } - else if (cmd == 20000) - { - reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; - replyData->status = 0; - replyData->psize = 4; - replyData->vsize = 4; - replyData->cmd = 20000; - replyData->data = (int32_t)dspmain->jdsp.blockSizeMax; - *replySize = sizeof(reply1x4_1x4_t); - return 0; - } - else if (cmd == 20001) - { - reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; - replyData->status = 0; - replyData->psize = 4; - replyData->vsize = 4; - replyData->cmd = 20001; - replyData->data = (int32_t)dspmain->jdsp.fs; - *replySize = sizeof(reply1x4_1x4_t); - return 0; - } - else if (cmd == 20002) - { - reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; - replyData->status = 0; - replyData->psize = 4; - replyData->vsize = 4; - replyData->cmd = 20002; - replyData->data = (int32_t)getpid(); - *replySize = sizeof(reply1x4_1x4_t); - return 0; - } - else if (cmd == 30000) - { - reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; - replyData->status = 0; - replyData->psize = 4; - replyData->vsize = 4; - replyData->cmd = 30000; - replyData->data = dspmain->hashSlot[0]; - *replySize = sizeof(reply1x4_1x4_t); - return 0; - } - else if (cmd == 30001) - { - reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; - replyData->status = 0; - replyData->psize = 4; - replyData->vsize = 4; - replyData->cmd = 30001; - replyData->data = dspmain->hashSlot[1]; - *replySize = sizeof(reply1x4_1x4_t); - return 0; - } - else if (cmd == 30002) - { - reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; - replyData->status = 0; - replyData->psize = 4; - replyData->vsize = 4; - replyData->cmd = 30002; - replyData->data = dspmain->hashSlot[2]; - *replySize = sizeof(reply1x4_1x4_t); - return 0; - } - else if (cmd == 30003) - { - reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; - replyData->status = 0; - replyData->psize = 4; - replyData->vsize = 4; - replyData->cmd = 30003; - replyData->data = dspmain->hashSlot[3]; - *replySize = sizeof(reply1x4_1x4_t); - return 0; - } - } - } - if (cmdCode == EFFECT_CMD_SET_PARAM) - { - effect_param_t *cep = (effect_param_t *)pCmdData; - int32_t *replyData = (int32_t *)pReplyData; - if (cep->psize == 4 && cep->vsize == 2) - { - int32_t cmd = ((int32_t *)cep)[3]; - if (cmd == 128) - { - int reverbMode = (int)((int16_t *)cep)[8]; - Reverb_SetParam(&dspmain->jdsp, reverbMode); -#ifdef DEBUG - LOGI("Reverb mode: %d", reverbMode); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 137) - { - float agress = ((int16_t *)cep)[8] / 100.0f; - StereoEnhancementSetParam(&dspmain->jdsp, agress); -#ifdef DEBUG - LOGE("Stereo widen ag: %1.7f", agress); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 188) - { - int16_t nMode = ((int16_t *)cep)[8]; - if (nMode < 0) - nMode = 0; - if (nMode > 5) - nMode = 5; - CrossfeedChangeMode(&dspmain->jdsp, nMode); -#ifdef DEBUG - LOGI("Crossfeed mode: %d", nMode); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 150) - { - float tubedrive = ((int16_t *)cep)[8] / 1000.0f; -#ifdef DEBUG - LOGI("Tube drive: %1.7f", tubedrive); -#endif - VacuumTubeSetGain(&dspmain->jdsp, tubedrive); - *replyData = 0; - return 0; - } - else if (cmd == 1200) - { - int16_t compressorEnabled = ((int16_t *)cep)[8]; - if (!compressorEnabled) - CompressorDisable(&dspmain->jdsp); - else - CompressorEnable(&dspmain->jdsp, 1); -#ifdef DEBUG - LOGE("Compressor enabled: %d", compressorEnabled); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 1201) - { - int16_t bassBoostEnabled = ((int16_t *)cep)[8]; - if (!bassBoostEnabled) - BassBoostDisable(&dspmain->jdsp); - else - BassBoostEnable(&dspmain->jdsp); -#ifdef DEBUG - LOGE("Bass boost enabled: %d", bassBoostEnabled); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 112) - { - float maxg = ((int16_t *)cep)[8]; -#ifdef DEBUG - LOGE("Bass boost max gain: %f", maxg); -#endif - BassBoostSetParam(&dspmain->jdsp, maxg); - *replyData = 0; - return 0; - } - else if (cmd == 1202) - { - int16_t equalizerEnabled = ((int16_t *)cep)[8]; - if (!equalizerEnabled) - MultimodalEqualizerDisable(&dspmain->jdsp); - else - MultimodalEqualizerEnable(&dspmain->jdsp, 1); -#ifdef DEBUG - LOGE("FIR equalizer enabled: %d", equalizerEnabled); -#endif - // Enable EQ - *replyData = 0; - return 0; - } - else if (cmd == 1203) - { - int16_t reverbEnabled = ((int16_t *)cep)[8]; - if (!reverbEnabled) - ReverbDisable(&dspmain->jdsp); - else - ReverbEnable(&dspmain->jdsp); -#ifdef DEBUG - LOGE("Reverb enabled: %d", reverbEnabled); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 1204) - { - int16_t stereoWidenEnabled = ((int16_t *)cep)[8]; - if (!stereoWidenEnabled) - StereoEnhancementDisable(&dspmain->jdsp); - else - StereoEnhancementEnable(&dspmain->jdsp); -#ifdef DEBUG - LOGE("Stereo widen enabled: %d", stereoWidenEnabled); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 1205) - { - int16_t convolverEnabled = ((int16_t *)cep)[8]; -#ifdef DEBUG - LOGE("Convolver enabled: %d", convolverEnabled); -#endif - if (!convolverEnabled) - Convolver1DDisable(&dspmain->jdsp); - else - Convolver1DEnable(&dspmain->jdsp); - *replyData = 0; - return 0; - } - else if (cmd == 1206) - { - int16_t analogueModelEnable = ((int16_t *)cep)[8]; - if (!analogueModelEnable) - VacuumTubeDisable(&dspmain->jdsp); - else - VacuumTubeEnable(&dspmain->jdsp); -#ifdef DEBUG - LOGE("Analogue modelling enabled: %d", analogueModelEnable); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 1208) - { - int16_t bs2bEnabled = ((int16_t *)cep)[8]; - if (!bs2bEnabled) - CrossfeedDisable(&dspmain->jdsp); - else - CrossfeedEnable(&dspmain->jdsp, 1); -#ifdef DEBUG - LOGE("Crossfeed enabled: %d", bs2bEnabled); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 1210) - { - int16_t arbitraryResponseEnabled = ((int16_t *)cep)[8]; - if (!arbitraryResponseEnabled) - ArbitraryResponseEqualizerDisable(&dspmain->jdsp); - else - ArbitraryResponseEqualizerEnable(&dspmain->jdsp, 1); -#ifdef DEBUG - LOGE("Arbitrary response eq enabled: %d", arbitraryResponseEnabled); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 1212) - { - int16_t viperddcEnabled = ((int16_t *)cep)[8]; - int errCode = 0; - if (!viperddcEnabled) - DDCDisable(&dspmain->jdsp); - else - errCode = DDCEnable(&dspmain->jdsp, 1); -#ifdef DEBUG - LOGE("viperddcEnabled: %d, success?: %d", viperddcEnabled, errCode); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 1213) - { - int16_t EELEnabled = ((int16_t *)cep)[8]; - if (!EELEnabled) - LiveProgDisable(&dspmain->jdsp); - else - LiveProgEnable(&dspmain->jdsp); -#ifdef DEBUG - LOGE("Liveprog enabled: %d", EELEnabled); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 10004) - { - // Load impulse -#ifdef DEBUG - if (dspmain->samplesInc == dspmain->numTime2Send) - LOGI("Buffer slices complete, chs: %d, impLen: %d", dspmain->impChannels, dspmain->impulseLengthActual); - else - LOGI("Ops! Buffer slices got %d missing holes", dspmain->numTime2Send - dspmain->samplesInc); -#endif - dspmain->samplesInc = 0; - int success = Convolver1DLoadImpulseResponse(&dspmain->jdsp, dspmain->tempImpulseIncoming, dspmain->impChannels, dspmain->impulseLengthActual, 1); - union - { - int32_t raw; - float f; - } fltInt; - int32_t crc = 0xFFFFFFFF; - for (unsigned int i = 0; i < dspmain->impulseLengthActual * dspmain->impChannels; i++) - { - fltInt.f = dspmain->tempImpulseIncoming[i]; - crc = crc ^ fltInt.raw; - for (int j = 7; j >= 0; j--) - { - int32_t mask = -(crc & 1); - crc = (crc >> 1) ^ (0xEDB88320 & mask); - } - } - dspmain->engineImpulseResponseHash = ~crc; - free(dspmain->tempImpulseIncoming); - dspmain->tempImpulseIncoming = 0; -#ifdef DEBUG - LOGI("FFT convolver errCode: %d", success); -#endif - *replyData = 0; - return 0; - } - else if (cmd == 10006) - { - dspmain->stringIndex = 0; - if (dspmain->stringEq) - { -#ifdef DEBUG - LOGI("%s", dspmain->stringEq); -#endif - ArbitraryResponseEqualizerStringParser(&dspmain->jdsp, dspmain->stringEq); - free(dspmain->stringEq); - dspmain->stringEq = 0; -#ifdef DEBUG - LOGI("Arbitrary response initialized"); -#endif - } - *replyData = 0; - return 0; - } - else if (cmd == 10009) - { - dspmain->stringIndex = 0; - if (dspmain->stringEq) - { -#ifdef DEBUG - LOGI("%s", dspmain->stringEq); -#endif - // Initialize DDC - DDCStringParser(&dspmain->jdsp, dspmain->stringEq); - free(dspmain->stringEq); - dspmain->stringEq = 0; -#ifdef DEBUG - LOGI("DDC initialized"); -#endif - } - *replyData = 0; - return 0; - } - else if (cmd == 10010) - { - dspmain->stringIndex = 0; - if (dspmain->stringEq) - { -#ifdef DEBUG - LOGI("%s", dspmain->stringEq); #endif - // Initialize EEL - int errorCode = LiveProgStringParser(&dspmain->jdsp, dspmain->stringEq); - free(dspmain->stringEq); - dspmain->stringEq = 0; -#ifdef DEBUG - LOGI("Live prog error message: %s", checkErrorCode(errorCode)); -#endif - } - *replyData = 0; - return 0; - } - } - if (cep->psize == 4 && cep->vsize == 4) - { - int32_t cmd = ((int32_t *)cep)[3]; - if (cmd == 25000) - { - dspmain->hashSlot[0] = ((int32_t*)cep)[4]; -#ifdef DEBUG - LOGI("ArbEq hash: %d", dspmain->hashSlot[0]); -#endif - *replyData = 0; - return 0; - } - if (cmd == 25001) - { - dspmain->hashSlot[0 + 1] = ((int32_t*)cep)[4]; -#ifdef DEBUG - LOGI("DDC hash: %d", dspmain->hashSlot[0 + 1]); -#endif - *replyData = 0; - return 0; - } - if (cmd == 25002) - { - dspmain->hashSlot[0 + 2] = ((int32_t*)cep)[4]; -#ifdef DEBUG - LOGI("LiveProg hash: %d", dspmain->hashSlot[0 + 2]); -#endif - *replyData = 0; - return 0; - } - if (cmd == 25003) - { - dspmain->hashSlot[0 + 3] = ((int32_t*)cep)[4]; -#ifdef DEBUG - LOGI("Convolver app hash: %d, engine hash: %d", dspmain->hashSlot[0 + 3], dspmain->engineImpulseResponseHash); -#endif - *replyData = 0; - return 0; - } - } - if (cep->psize == 4 && cep->vsize == 12) - { - int32_t cmd = ((int32_t *)cep)[3]; - if (cmd == 1500) - { - double limThreshold = (double)((float*)cep)[4]; - double limRelease = (double)((float*)cep)[5]; - double postgain = (double)((float*)cep)[6]; - if (limThreshold > -0.09) - limThreshold = -0.09; - if (limRelease < 0.15) - limRelease = 0.15; - if (postgain > 15.0) - postgain = 15.0; - if (postgain < -15.0) - postgain = -15.0; - JLimiterSetCoefficients(&dspmain->jdsp, limThreshold, limRelease); - JamesDSPSetPostGain(&dspmain->jdsp, postgain); -#ifdef DEBUG - LOGE("limThreshold: %f, limRelease: %f, postgain: %f", limThreshold, limRelease, postgain); -#endif - *replyData = 0; - return 0; - } - } - if (cep->psize == 4 && cep->vsize == 68) - { - int32_t cmd = ((int32_t *)cep)[3]; - if (cmd == 115) - { - float timeconstant = ((float*)cep)[4 + 0]; - int granularity = (int)roundf(((float*)cep)[4 + 1]); - int tfresolution = (int)roundf(((float*)cep)[4 + 2]); - float *ptrFreqAxis = &((float*)cep)[4 + 3]; - float *ptrGainAxis = ptrFreqAxis + 7; - double param[14]; - for (int i = 0; i < 7; i++) - { - param[i] = (double)ptrFreqAxis[i]; - param[i + 7] = (double)ptrGainAxis[i]; - } -#ifdef DEBUG - LOGI("Compander timeconstant = %1.8f", timeconstant); - LOGI("Compander granularity = %d", granularity); - LOGI("Compander tfresolution = %d", tfresolution); - LOGI("Compander axis: "); - for (int i = 0; i < 7; i++) - LOGI("%1.7lf %1.7lf; ", param[i], param[i + 7]); -#endif - CompressorSetParam(&dspmain->jdsp, timeconstant, granularity, tfresolution, 0); - CompressorSetGain(&dspmain->jdsp, param, param + 7, 1); - *replyData = 0; - return 0; - } - } - if (cep->psize == 4 && cep->vsize == 128) - { - int32_t cmd = ((int32_t *)cep)[3]; - if (cmd == 116) - { - int filtertype = roundf(((float*)cep)[4 + 0]); - int interpolationMode = (((float*)cep)[4 + 1]) < 0.0f ? 0 : 1; - float *ptrFreqAxis = &((float*)cep)[4 + 2]; - float *ptrGainAxis = ptrFreqAxis + 15; - double param[30]; - for (int i = 0; i < 15; i++) - { - param[i] = (double)ptrFreqAxis[i]; - param[i + 15] = (double)ptrGainAxis[i]; - } -#ifdef DEBUG - if (filtertype == 0) - LOGI("filtertype: FIR Minimum phase"); - else if (filtertype == 1) - LOGI("filtertype: IIR 4 order"); - else if (filtertype == 2) - LOGI("filtertype: IIR 6 order"); - else if (filtertype == 3) - LOGI("filtertype: IIR 8 order"); - else if (filtertype == 4) - LOGI("filtertype: IIR 10 order"); - else - LOGI("filtertype: IIR 12 order"); - LOGI("Eq axis: "); - for (int i = 0; i < 15; i++) - LOGI("%1.7lf %1.7lf; ", param[i], param[i + 15]); -#endif - MultimodalEqualizerAxisInterpolation(&dspmain->jdsp, interpolationMode, filtertype, param, param + 15); - *replyData = 0; - return 0; - } - } - if (cep->psize == 4 && cep->vsize == 8) - { - int32_t cmd = ((int32_t *)cep)[3]; - if (cmd == 8888) // Implemented - { - int32_t times = ((int32_t *)cep)[4]; - int32_t sizePerBuffer = ((int32_t *)cep)[5]; - int stringLength = times * sizePerBuffer; -#ifdef DEBUG - LOGI("Allocate %d string length", stringLength); -#endif - dspmain->stringEq = (char*)calloc(stringLength, sizeof(char)); - *replyData = 0; - return 0; - } - } - if (cep->psize == 4 && cep->vsize == 16) - { - int32_t cmd = ((int32_t *)cep)[3]; - if (cmd == 9999) // Implemented - { - dspmain->impChannels = ((int32_t *)cep)[5]; - dspmain->impulseLengthActual = ((int32_t *)cep)[4] / dspmain->impChannels; - float convGaindB = (float)((int32_t *)cep)[6] / 262144.0f; - if (convGaindB > 50.0f) - convGaindB = 50.0f; - dspmain->numTime2Send = ((int32_t *)cep)[7]; - dspmain->tempImpulseIncoming = (float*)calloc(4096 * dspmain->impChannels * dspmain->numTime2Send, sizeof(float)); - *replyData = 0; - return 0; - } - } - if (cep->psize == 4 && cep->vsize == 16384) - { - int32_t cmd = ((int32_t *)cep)[3]; - if (cmd == 12000) // Implemented - { - memcpy(dspmain->tempImpulseIncoming + (dspmain->samplesInc++ * 4096), ((float*)cep) + 4, 4096 * sizeof(float)); - *replyData = 0; - return 0; - } - } - if (cep->psize == 4 && cep->vsize == 256) - { - int32_t cmd = ((int32_t *)cep)[3]; - if (cmd == 12001) // Implemented - { - memcpy(dspmain->stringEq + (dspmain->stringIndex++ * 256), ((char*)cep) + 16, 256 * sizeof(char)); - *replyData = 0; - return 0; - } - } - return -1; - } - switch (cmdCode) - { - case EFFECT_CMD_ENABLE: - case EFFECT_CMD_DISABLE: - { - dspmain->mEnable = cmdCode == EFFECT_CMD_ENABLE; - int32_t *replyData = (int32_t *) pReplyData; - *replyData = 0; - break; - } - case EFFECT_CMD_INIT: - case EFFECT_CMD_SET_CONFIG: - case EFFECT_CMD_SET_PARAM: - case EFFECT_CMD_SET_PARAM_COMMIT: - { - int32_t *replyData = (int32_t *) pReplyData; - *replyData = 0; - break; - } - case EFFECT_CMD_RESET: - case EFFECT_CMD_SET_PARAM_DEFERRED: - case EFFECT_CMD_SET_DEVICE: - case EFFECT_CMD_SET_AUDIO_MODE: - break; - case EFFECT_CMD_GET_PARAM: - { - effect_param_t *rep = (effect_param_t *) pReplyData; - rep->status = -EINVAL; - rep->psize = 0; - rep->vsize = 0; - *replySize = 12; - break; - } - } - return 0; -} -int32_t EffectDSPMainProcess(EffectDSPMain *dspmain, audio_buffer_t *in, audio_buffer_t *out) -{ - size_t actualFrameCount = in->frameCount; - switch (dspmain->formatFloatModeInt32Mode) - { - case 0: - dspmain->jdsp.processInt16Multiplexd(&dspmain->jdsp, in->s16, out->s16, actualFrameCount); - break; - case 1: - dspmain->jdsp.processFloatMultiplexd(&dspmain->jdsp, in->f32, out->f32, actualFrameCount); - break; - case 2: - dspmain->jdsp.processInt32Multiplexd(&dspmain->jdsp, in->s32, out->s32, actualFrameCount); - break; - case 3: - dspmain->jdsp.processInt24PackedMultiplexd(&dspmain->jdsp, (uint8_t*)in->raw, (uint8_t*)out->raw, actualFrameCount); - break; - case 4: - dspmain->jdsp.processInt8_24Multiplexd(&dspmain->jdsp, in->s32, out->s32, actualFrameCount); - break; - } - return dspmain->mEnable ? 0 : -ENODATA; -} +#include "jdsp_impl.h" + // Effect section end static effect_descriptor_t jamesdsp_descriptor = { @@ -822,20 +26,7 @@ static effect_descriptor_t jamesdsp_descriptor = "JamesDSP v4.01", "James Fung" }; -__attribute__((constructor)) static void initialize(void) -{ - JamesDSPGlobalMemoryAllocation(); -#ifdef DEBUG - LOGI("Initialization: DLL loaded"); -#endif -} -__attribute__((destructor)) static void destruction(void) -{ - JamesDSPGlobalMemoryDeallocation(); -#ifdef DEBUG - LOGI("Initialization: DLL unloaded"); -#endif -} + // Library mandatory methods struct effect_module_s { diff --git a/Main/libjamesdsp/jni/jamesdsp/jamesdsp_aidl.cpp b/Main/libjamesdsp/jni/jamesdsp/jamesdsp_aidl.cpp new file mode 100644 index 0000000..7ad0b80 --- /dev/null +++ b/Main/libjamesdsp/jni/jamesdsp/jamesdsp_aidl.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * 2025 anonymix007 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#define LOG_TAG "JamesDSP_AIDL" +#include + +#include +#include +#include +#include + +#include "jamesdsp_aidl.h" + +using aidl::android::hardware::audio::effect::Descriptor; +using aidl::android::hardware::audio::effect::DefaultExtension; +using aidl::android::hardware::audio::effect::JamesDSPAIDL; +using aidl::android::hardware::audio::effect::getEffectTypeUuidCustom; +using aidl::android::hardware::audio::effect::getEffectImplUuidJDSP; +using aidl::android::hardware::audio::effect::getEffectUuidNull; +using aidl::android::hardware::audio::effect::IEffect; +using aidl::android::hardware::audio::effect::State; +using aidl::android::hardware::audio::effect::VendorExtension; +using aidl::android::media::audio::common::AudioUuid; + +extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid, + std::shared_ptr* instanceSpp) { + if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidJDSP()) { + LOG(ERROR) << __func__ << "uuid not supported"; + return EX_ILLEGAL_ARGUMENT; + } + if (instanceSpp) { + *instanceSpp = ndk::SharedRefBase::make(); + LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created"; + return EX_NONE; + } else { + LOG(ERROR) << __func__ << " invalid input parameter!"; + return EX_ILLEGAL_ARGUMENT; + } +} + +extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) { + if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidJDSP()) { + LOG(ERROR) << __func__ << "uuid not supported"; + return EX_ILLEGAL_ARGUMENT; + } + *_aidl_return = JamesDSPAIDL::kDesc; + return EX_NONE; +} + +namespace aidl::android::hardware::audio::effect { + +#if __aarch64__ == 1 +const std::string JamesDSPAIDL::kEffectName = "James Audio DSP arm64"; +#elif __ARM_ARCH_7A__ == 1 +const std::string JamesDSPAIDL::kEffectName = "James Audio DSP arm32"; +#elif __i386__ == 1 +const std::string JamesDSPAIDL::kEffectName = "James Audio DSP x86"; +#elif __x86_64__ == 1 +const std::string JamesDSPAIDL::kEffectName = "James Audio DSP x64"; +#endif + +const Descriptor JamesDSPAIDL::kDesc = {.common = {.id = {.type = getEffectTypeUuidCustom(), + .uuid = getEffectImplUuidJDSP()}, + .flags = {.type = Flags::Type::INSERT, + .insert = Flags::Insert::LAST, + .volume = Flags::Volume::CTRL}, + .name = JamesDSPAIDL::kEffectName, + .implementor = "James Fung"}}; + +ndk::ScopedAStatus JamesDSPAIDL::getDescriptor(Descriptor* _aidl_return) { + LOG(DEBUG) << __func__ << kDesc.toString(); + *_aidl_return = kDesc; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus JamesDSPAIDL::setParameterSpecific(const Parameter::Specific& specific) { + RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext"); + RETURN_IF(Parameter::Specific::vendorEffect != specific.getTag(), EX_ILLEGAL_ARGUMENT, "EffectNotSupported"); + auto& vendorEffect = specific.get(); + std::optional defaultExt; + RETURN_IF(STATUS_OK != vendorEffect.extension.getParcelable(&defaultExt), EX_ILLEGAL_ARGUMENT, "getParcelableFailed"); + RETURN_IF(!defaultExt.has_value(), EX_ILLEGAL_ARGUMENT, "parcelableNull"); + +#ifdef AIDL_DEBUG + LOG(DEBUG) << __func__ << ": defaultExt: " << defaultExt->toString(); +#endif + + int32_t ret = 0; + uint32_t ret_size = sizeof(ret); + RETURN_IF(mContext->handleCommand(EFFECT_CMD_SET_PARAM, defaultExt->bytes.size(), defaultExt->bytes.data(), &ret_size, &ret) != 0, EX_ILLEGAL_ARGUMENT, "handleCommandFailed"); + RETURN_IF(ret != 0, EX_ILLEGAL_ARGUMENT, "handleCommandInternalFailed"); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus JamesDSPAIDL::getParameterSpecific(const Parameter::Id& id, + Parameter::Specific* specific) { + RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext"); + RETURN_IF(Parameter::Id::vendorEffectTag != id.getTag(), EX_ILLEGAL_ARGUMENT, "wrongIdTag"); + auto extensionId = id.get(); + std::optional defaultIdExt; + RETURN_IF(STATUS_OK != extensionId.extension.getParcelable(&defaultIdExt), EX_ILLEGAL_ARGUMENT, "getIdParcelableFailed"); + RETURN_IF(!defaultIdExt.has_value(), EX_ILLEGAL_ARGUMENT, "parcelableIdNull"); + +#ifdef AIDL_DEBUG + LOG(DEBUG) << __func__ << ": defaultIdExt: " << defaultIdExt->toString(); +#endif + + VendorExtension extension; + DefaultExtension defaultExt; + defaultExt.bytes.resize(sizeof(effect_param_t) + 2 * sizeof(int32_t)); + uint32_t data_size = defaultExt.bytes.size(); + RETURN_IF(mContext->handleCommand(EFFECT_CMD_GET_PARAM, defaultIdExt->bytes.size(), defaultIdExt->bytes.data(), &data_size, defaultExt.bytes.data()) != 0, EX_ILLEGAL_ARGUMENT, "handleCommandFailed"); + assert(data_size <= defaultExt.bytes.size()); + defaultExt.bytes.resize(data_size); + +#ifdef AIDL_DEBUG + LOG(DEBUG) << __func__ << ": defaultExt: " << defaultExt.toString(); +#endif + + RETURN_IF(STATUS_OK != extension.extension.setParcelable(defaultExt), EX_ILLEGAL_ARGUMENT, "setParcelableFailed"); + specific->set(extension); + return ndk::ScopedAStatus::ok(); +} + +static inline std::string buffer_config_to_string(const buffer_config_t &conf) { + std::ostringstream stream_out; + stream_out << "rate: " << conf.samplingRate << ", channels: " << conf.channels << ", format: " << (int) conf.format; + return stream_out.str(); +} + +std::shared_ptr JamesDSPAIDL::createContext(const Parameter::Common& common) { + if (mContext) { + LOG(DEBUG) << __func__ << " context already exists"; + } else { + mContext = std::make_shared(1 /* statusFmqDepth */, common); + int32_t ret = 0; + uint32_t ret_size = sizeof(ret); + int32_t status = mContext->handleCommand(EFFECT_CMD_INIT, 0, NULL, &ret_size, &ret); + if (status < 0) { + LOG(ERROR) << __func__ << ": JamesDSPAIDLContext::handleCommand INIT failed: " << status; + mContext = nullptr; + return mContext; + } + if (ret < 0) { + LOG(ERROR) << __func__ << ": JamesDSPAIDLContext::handleCommand INIT failed (internal): " << ret; + mContext = nullptr; + return mContext; + } + ret = 0; + ret_size = sizeof(ret); + effect_config_t conf; + + if (!aidl2legacy_ParameterCommon_effect_config_t(common, conf)) { + LOG(ERROR) << __func__ << ": JamesDSPAIDL::createContext: aidl2legacy_ParameterCommon_effect_config_t failed"; + mContext = nullptr; + return mContext; + } + + LOG(INFO) << __func__ << ": AIDL input config: " << common.input.toString(); + LOG(INFO) << __func__ << ": AIDL output config: " << common.output.toString(); + LOG(INFO) << __func__ << ": Legacy input config: " << buffer_config_to_string(conf.inputCfg); + LOG(INFO) << __func__ << ": Legacy output config: " << buffer_config_to_string(conf.outputCfg); + + status = mContext->handleCommand(EFFECT_CMD_SET_CONFIG, sizeof(conf), &conf, &ret_size, &ret); + if (status < 0) { + LOG(ERROR) << __func__ << ": JamesDSPAIDLContext::handleCommand SET CONFIG failed: " << status; + mContext = nullptr; + return mContext; + } + if (ret < 0) { + LOG(ERROR) << __func__ << ": JamesDSPAIDLContext::handleCommand SET CONFIG failed (internal): " << ret; + mContext = nullptr; + return mContext; + } + } + + return mContext; +} + +ndk::ScopedAStatus JamesDSPAIDL::commandImpl(CommandId command) { + RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext"); + int32_t ret = 0; + uint32_t ret_size = sizeof(ret); + switch (command) { + case CommandId::START: + RETURN_IF(mContext->handleCommand(EFFECT_CMD_ENABLE, 0, NULL, &ret_size, &ret) != 0, EX_ILLEGAL_ARGUMENT, "handleCommandFailed"); + RETURN_IF(ret != 0, EX_ILLEGAL_ARGUMENT, "handleCommandInternalFailed"); + break; + case CommandId::STOP: + RETURN_IF(mContext->handleCommand(EFFECT_CMD_DISABLE, 0, NULL, &ret_size, &ret) != 0, EX_ILLEGAL_ARGUMENT, "handleCommandFailed"); + RETURN_IF(ret != 0, EX_ILLEGAL_ARGUMENT, "handleCommandInternalFailed"); + break; + case CommandId::RESET: + mImplContext->resetBuffer(); + break; + default: + break; + } + return ndk::ScopedAStatus::ok(); +} + +RetCode JamesDSPAIDL::releaseContext() { + if (mContext) { + int32_t ret = 0; + uint32_t ret_size = sizeof(ret); + int32_t status = mContext->handleCommand(EFFECT_CMD_RESET, 0, NULL, &ret_size, &ret); + if (status < 0) { + LOG(ERROR) << __func__ << ": JamesDSPAIDLContext::handleCommand RESET failed: " << status; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + if (ret < 0) { + LOG(ERROR) << __func__ << ": JamesDSPAIDLContext::handleCommand RESET failed (internal): " << ret; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + mContext.reset(); + } + return RetCode::SUCCESS; +} + +// Processing method running in EffectWorker thread. +IEffect::Status JamesDSPAIDL::effectProcessImpl(float* in_, float* out_, int samples) { + size_t frames = static_cast(samples) / 2; + audio_buffer_t in{frames, {in_}}, out{frames, {out_}}; + +#ifdef AIDL_DEBUG + LOG(DEBUG) << __func__ << ": in " << in_ << ", out " << out_ << ", samples " << samples; +#endif + int32_t ret = mContext->process(&in, &out); +#ifdef AIDL_DEBUG + LOG(DEBUG) << __func__ << ": mContext->process: " << ret; +#endif + + switch(ret) { + case 0: + return {STATUS_OK, samples, samples}; + case -ENODATA: + return {STATUS_NOT_ENOUGH_DATA, 0, 0}; + default: + return {STATUS_INVALID_OPERATION, 0, 0}; + } +} + +} // namespace aidl::android::hardware::audio::effect diff --git a/Main/libjamesdsp/jni/jamesdsp/jamesdsp_aidl.h b/Main/libjamesdsp/jni/jamesdsp/jamesdsp_aidl.h new file mode 100644 index 0000000..b505b6b --- /dev/null +++ b/Main/libjamesdsp/jni/jamesdsp/jamesdsp_aidl.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * 2025 anonymix007 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +#include "effect-impl/EffectImpl.h" + +#include "jdsp_impl.h" + +namespace aidl::android::hardware::audio::effect { + +static inline bool aidl2legacy_ParameterCommon_effect_config_t(const Parameter::Common& common, effect_config_t &conf) { + // FIXME: This shouldn't be false + auto tmp = ::aidl::android::aidl2legacy_AudioConfig_buffer_config_t(common.input, false); + if (tmp.ok()) { + conf.inputCfg = tmp.value(); + } else { + return false; + } + + tmp = ::aidl::android::aidl2legacy_AudioConfig_buffer_config_t(common.output, false); + if (tmp.ok()) { + conf.outputCfg = tmp.value(); + } else {; + return false; + } + + return true; +} + +class JamesDSPAIDLContext final : public EffectContext { + public: + JamesDSPAIDLContext(int statusDepth, const Parameter::Common& common) + : EffectContext(statusDepth, common), + e(std::make_unique()) { + LOG(DEBUG) << __func__; + EffectDSPMainConstructor(e.get()); + } + ~JamesDSPAIDLContext() { + LOG(DEBUG) << __func__; + EffectDSPMainDestructor(e.get()); + } + + RetCode setCommon(const Parameter::Common& common) override { + if (auto ret = EffectContext::setCommon(common); ret != RetCode::SUCCESS) { + return ret; + } + + int32_t ret = 0; + uint32_t ret_size = sizeof(ret); + effect_config_t conf; + + if (!aidl2legacy_ParameterCommon_effect_config_t(common, conf)) { + LOG(ERROR) << __func__ << ": JamesDSPAIDL::createContext: aidl2legacy_ParameterCommon_effect_config_t failed"; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + + int32_t status = handleCommand(EFFECT_CMD_SET_CONFIG, sizeof(conf), &conf, &ret_size, &ret); + if (status < 0) { + LOG(ERROR) << __func__ << ": JamesDSPAIDLContext::handleCommand SET CONFIG failed: " << status; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + if (ret < 0) { + LOG(ERROR) << __func__ << ": JamesDSPAIDLContext::handleCommand SET CONFIG failed (internal): " << ret; + return RetCode::ERROR_ILLEGAL_PARAMETER; + } + return RetCode::SUCCESS; + } + + + int32_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize, void* pReplyData) { + return EffectDSPMainCommand(e.get(), cmdCode, cmdSize, pCmdData, replySize, pReplyData); + } + + int32_t process(audio_buffer_t *in, audio_buffer_t *out) { + return EffectDSPMainProcess(e.get(), in, out); + } + +private: + std::unique_ptr e; +}; + +class JamesDSPAIDL final : public EffectImpl { + public: + static const std::string kEffectName; + static const Capability kEqCap; + static const Descriptor kDesc; + + JamesDSPAIDL() { LOG(DEBUG) << __func__; } + ~JamesDSPAIDL() { + cleanUp(); + LOG(DEBUG) << __func__; + } + + ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override; + ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) + REQUIRES(mImplMutex) override; + ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, Parameter::Specific* specific) + REQUIRES(mImplMutex) override; + + std::shared_ptr createContext(const Parameter::Common& common) + REQUIRES(mImplMutex) override; + ndk::ScopedAStatus commandImpl(CommandId id) REQUIRES(mImplMutex); + + RetCode releaseContext() REQUIRES(mImplMutex) override; + + IEffect::Status effectProcessImpl(float* in, float* out, int samples) + REQUIRES(mImplMutex) override; + std::string getEffectName() override { return kEffectName; } + + private: + std::shared_ptr mContext; +}; + + +constexpr char kEffectTypeUuidCustom[] = "f98765f4-c321-5de6-9a45-123459495ab2"; +inline const AudioUuid& getEffectTypeUuidCustom() { + static const ::android::base::NoDestructor uuid(stringToUuid(kEffectTypeUuidCustom)); + return *uuid; +} + +constexpr char kEffectImplUuidJDSP[] = "f27317f4-c984-4de6-9a90-545759495bf2"; +inline const AudioUuid& getEffectImplUuidJDSP() { + static const ::android::base::NoDestructor uuid(stringToUuid(kEffectImplUuidJDSP)); + return *uuid; +} + +} // namespace aidl::android::hardware::audio::effect diff --git a/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/crossfeed.c b/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/crossfeed.c index 588f338..9b5cc71 100644 --- a/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/crossfeed.c +++ b/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/crossfeed.c @@ -61,7 +61,7 @@ void CrossfeedEnable(JamesDSPLib *jdsp, char enable) jdsp->advXF.convLong_S_S = (FFTConvolver2x4x2 *)malloc(sizeof(FFTConvolver2x4x2)); FFTConvolver2x4x2Init(jdsp->advXF.convLong_S_S); FFTConvolver2x4x2LoadImpulseResponse(jdsp->advXF.convLong_S_S, (unsigned int)jdsp->blockSize, jdsp->hrtfblobsResampled[0], jdsp->hrtfblobsResampled[1], jdsp->hrtfblobsResampled[2], jdsp->hrtfblobsResampled[3], jdsp->frameLenSVirResampled); - jdsp->advXF.process = CrossfeedProcessFFTConvolver2x4x2; + jdsp->advXF.process = (void *) CrossfeedProcessFFTConvolver2x4x2; } else { @@ -69,7 +69,7 @@ void CrossfeedEnable(JamesDSPLib *jdsp, char enable) jdsp->advXF.convLong_T_S = (TwoStageFFTConvolver2x4x2 *)malloc(sizeof(TwoStageFFTConvolver2x4x2)); TwoStageFFTConvolver2x4x2Init(jdsp->advXF.convLong_T_S); TwoStageFFTConvolver2x4x2LoadImpulseResponse(jdsp->advXF.convLong_T_S, (unsigned int)jdsp->blockSize, seg2Len, jdsp->hrtfblobsResampled[0], jdsp->hrtfblobsResampled[1], jdsp->hrtfblobsResampled[2], jdsp->hrtfblobsResampled[3], jdsp->frameLenSVirResampled); - jdsp->advXF.process = CrossfeedProcessTwoStageFFTConvolver2x4x2; + jdsp->advXF.process = (void *) CrossfeedProcessTwoStageFFTConvolver2x4x2; } jdsp->crossfeedForceRefresh = 0; } @@ -120,4 +120,4 @@ void CrossfeedProcess(JamesDSPLib *jdsp, size_t n) FFTConvolver2x4x2Process(jdsp->advXF.conv[jdsp->advXF.mode - 2], jdsp->tmpBuffer[0], jdsp->tmpBuffer[1], jdsp->tmpBuffer[0], jdsp->tmpBuffer[1], (unsigned int)n); else jdsp->advXF.process(jdsp, (unsigned int)n); -} \ No newline at end of file +} diff --git a/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/eel2/nseel-compiler.c b/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/eel2/nseel-compiler.c index 33b8f42..cf3e114 100644 --- a/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/eel2/nseel-compiler.c +++ b/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/eel2/nseel-compiler.c @@ -1646,7 +1646,7 @@ static float NSEEL_CGEN_CALL eel_mean(float *blocks, float *start, float *lengt ---------------------------------------------------------------------------*/ float kth_smallest(float a[], int n, int k) { - register i, j, l, m; + register int i, j, l, m; register float x; l = 0; m = n - 1; @@ -8185,4 +8185,4 @@ opcodeRec *nseel_translate(compileContext *ctx, const char *tmp, size_t tmplen) return nseel_createCompiledValue(ctx, (float)rv); } return nseel_createCompiledValue(ctx, (float)atof(tmp)); -} \ No newline at end of file +} diff --git a/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/eel2/numericSys/FilterDesign/polyphaseFilterbank.c b/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/eel2/numericSys/FilterDesign/polyphaseFilterbank.c index 72db1ca..df4e642 100644 --- a/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/eel2/numericSys/FilterDesign/polyphaseFilterbank.c +++ b/Main/libjamesdsp/jni/jamesdsp/jdsp/Effects/eel2/numericSys/FilterDesign/polyphaseFilterbank.c @@ -48,6 +48,7 @@ double getOptimalDF(unsigned int N, unsigned int m) return 0.51554 * exp(-0.38706 * N) + 0.060656 * exp(-0.025357 * N); else if (m == 6) return 0.51908 * exp(-0.40187 * N) + 0.057579 * exp(-0.027425 * N); + else return 0; /* TODO: assert(!"Unreachable"); */ } } else @@ -437,4 +438,4 @@ void synthesisWarpedPFBStereo(WarpedPFB *pfb1, WarpedPFB *pfb2, float *y1, float } *y1 = R1_b * pfb1->postGain; *y2 = R1_b_x2 * pfb1->postGain; -} \ No newline at end of file +} diff --git a/Main/libjamesdsp/jni/jamesdsp/jdsp/jdspController.c b/Main/libjamesdsp/jni/jamesdsp/jdsp/jdspController.c index 8ae4fae..55901a6 100644 --- a/Main/libjamesdsp/jni/jamesdsp/jdsp/jdspController.c +++ b/Main/libjamesdsp/jni/jamesdsp/jdsp/jdspController.c @@ -3,6 +3,10 @@ #include #include #include +#ifndef _WIN32 +#include +#include +#endif #include #include "Effects/eel2/dr_flac.h" #include "Effects/eel2/ns-eel.h" @@ -1238,4 +1242,4 @@ void JamesDSPFree(JamesDSPLib *jdsp) FreeIntegerASRCHandler(&jdsp->asrc[1]); } jdsp_unlock(jdsp); -} \ No newline at end of file +} diff --git a/Main/libjamesdsp/jni/jamesdsp/jdsp_impl.c b/Main/libjamesdsp/jni/jamesdsp/jdsp_impl.c new file mode 100644 index 0000000..cb60c80 --- /dev/null +++ b/Main/libjamesdsp/jni/jamesdsp/jdsp_impl.c @@ -0,0 +1,810 @@ +#ifdef DEBUG +#define TAG "EffectDSPMain" +#include +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__) +#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG,__VA_ARGS__) +#include "MemoryUsage.h" +#endif + +#include "jdsp_impl.h" + +typedef struct +{ + int32_t status; + uint32_t psize; + uint32_t vsize; + int32_t cmd; + int32_t data; +} reply1x4_1x4_t; + +void EffectDSPMainConstructor(EffectDSPMain *dspmain) +{ + dspmain->initializeForFirst = 0; + dspmain->tempImpulseIncoming = 0; + dspmain->stringEq = 0; + dspmain->boostingCon = 3; + dspmain->bbMaxGain = 0; + dspmain->numTime2Send = 0; + dspmain->samplesInc = 0; + dspmain->stringIndex = 0; + JamesDSPInit(&dspmain->jdsp, 128, 48000.0f); +} + +void EffectDSPMainDestructor(EffectDSPMain *dspmain) +{ + JamesDSPFree(&dspmain->jdsp); + if (dspmain->tempImpulseIncoming) + free(dspmain->tempImpulseIncoming); + if (dspmain->stringEq) + free(dspmain->stringEq); +#ifdef DEBUG + LOGI("Buffer freed"); +#endif +} + +static int32_t configure(EffectDSPMain *dspmain, void* pCmdData, effect_buffer_access_e* mAccessMode) +{ + effect_config_t *cfg = (effect_config_t*)pCmdData; + buffer_config_t in = cfg->inputCfg; + buffer_config_t out = cfg->outputCfg; + /* Check that we aren't asked to do resampling. Note that audioflinger + * always provides full setup info at initial configure time. */ +#ifdef DEBUG + LOGI("Sample rate of In: %u and out: %u", in.samplingRate, out.samplingRate); +#endif + if ((in.mask & EFFECT_CONFIG_SMP_RATE) && (out.mask & EFFECT_CONFIG_SMP_RATE)) + { + if (out.samplingRate != in.samplingRate) + { +#ifdef DEBUG + LOGW("In/out sample rate doesn't match"); +#endif + return -EINVAL; + } + dspmain->mSamplingRate = (float)in.samplingRate; + } + if (in.mask & EFFECT_CONFIG_CHANNELS && out.mask & EFFECT_CONFIG_CHANNELS) + { + if (in.channels != AUDIO_CHANNEL_OUT_STEREO) + { +#ifdef DEBUG + LOGE("Input is non stereo signal. It's channel count is %u", in.channels); +#endif + return -EINVAL; + } + if (out.channels != AUDIO_CHANNEL_OUT_STEREO) + { +#ifdef DEBUG + LOGE("Output is non stereo signal. It's channel count is %u", out.channels); +#endif + return -EINVAL; + } + } + else + { +#ifdef DEBUG + LOGE("In/out channel mask doesn't match"); +#endif + } + if (in.mask & EFFECT_CONFIG_FORMAT) + { + if (in.format == AUDIO_FORMAT_PCM_FLOAT) + dspmain->formatFloatModeInt32Mode = 1; + else if (in.format == AUDIO_FORMAT_PCM_32_BIT) + dspmain->formatFloatModeInt32Mode = 2; + else if (in.format == AUDIO_FORMAT_PCM_24_BIT_PACKED) + dspmain->formatFloatModeInt32Mode = 3; + else if (in.format == AUDIO_FORMAT_PCM_8_24_BIT) + dspmain->formatFloatModeInt32Mode = 4; + else if (in.format == AUDIO_FORMAT_PCM_16_BIT) + dspmain->formatFloatModeInt32Mode = 0; + } + if (out.mask & EFFECT_CONFIG_FORMAT) + { + if (out.format == AUDIO_FORMAT_PCM_FLOAT) + dspmain->formatFloatModeInt32Mode = 1; + else if (out.format == AUDIO_FORMAT_PCM_32_BIT) + dspmain->formatFloatModeInt32Mode = 2; + else if (out.format == AUDIO_FORMAT_PCM_24_BIT_PACKED) + dspmain->formatFloatModeInt32Mode = 3; + else if (out.format == AUDIO_FORMAT_PCM_8_24_BIT) + dspmain->formatFloatModeInt32Mode = 4; + else if (out.format == AUDIO_FORMAT_PCM_16_BIT) + dspmain->formatFloatModeInt32Mode = 0; + } +#ifdef DEBUG + LOGW("I/O FMT = { %u, %u }", in.format, out.format); +#endif + if (out.mask & EFFECT_CONFIG_ACC_MODE) + *mAccessMode = (effect_buffer_access_e) out.accessMode; + return 0; +} + +int32_t EffectDSPMainCommand(EffectDSPMain *dspmain, uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize, void* pReplyData) +{ +#ifdef DEBUG +// LOGI("Memory used: %f Mb", (float)getCurrentRSS() / 1024.0 / 1024.0); +#endif + if (cmdCode == EFFECT_CMD_SET_CONFIG) + { + effect_buffer_access_e mAccessMode; + int32_t *replyData = (int32_t *)pReplyData; + int32_t ret = configure(dspmain, pCmdData, &mAccessMode); + if (ret != 0) + { + *replyData = ret; + return 0; + } + // Set sample rate + JamesDSPSetSampleRate(&dspmain->jdsp, dspmain->mSamplingRate, 0); + *replyData = 0; + return 0; + } + if (cmdCode == EFFECT_CMD_GET_PARAM) + { + effect_param_t *cep = (effect_param_t *)pCmdData; + if (cep->psize == 4 && cep->vsize == 4) + { + int32_t cmd = ((int32_t *)cep)[3]; + if (cmd == 19998) + { + reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; + replyData->status = 0; + replyData->psize = 4; + replyData->vsize = 4; + replyData->cmd = 19998; + replyData->data = (int32_t)dspmain->initializeForFirst++; + *replySize = sizeof(reply1x4_1x4_t); + return 0; + } + if (cmd == 19999) + { + reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; + replyData->status = 0; + replyData->psize = 4; + replyData->vsize = 4; + replyData->cmd = 19999; + replyData->data = (int32_t)dspmain->jdsp.blockSize; + *replySize = sizeof(reply1x4_1x4_t); + return 0; + } + else if (cmd == 20000) + { + reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; + replyData->status = 0; + replyData->psize = 4; + replyData->vsize = 4; + replyData->cmd = 20000; + replyData->data = (int32_t)dspmain->jdsp.blockSizeMax; + *replySize = sizeof(reply1x4_1x4_t); + return 0; + } + else if (cmd == 20001) + { + reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; + replyData->status = 0; + replyData->psize = 4; + replyData->vsize = 4; + replyData->cmd = 20001; + replyData->data = (int32_t)dspmain->jdsp.fs; + *replySize = sizeof(reply1x4_1x4_t); + return 0; + } + else if (cmd == 20002) + { + reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; + replyData->status = 0; + replyData->psize = 4; + replyData->vsize = 4; + replyData->cmd = 20002; + replyData->data = (int32_t)getpid(); + *replySize = sizeof(reply1x4_1x4_t); + return 0; + } + else if (cmd == 30000) + { + reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; + replyData->status = 0; + replyData->psize = 4; + replyData->vsize = 4; + replyData->cmd = 30000; + replyData->data = dspmain->hashSlot[0]; + *replySize = sizeof(reply1x4_1x4_t); + return 0; + } + else if (cmd == 30001) + { + reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; + replyData->status = 0; + replyData->psize = 4; + replyData->vsize = 4; + replyData->cmd = 30001; + replyData->data = dspmain->hashSlot[1]; + *replySize = sizeof(reply1x4_1x4_t); + return 0; + } + else if (cmd == 30002) + { + reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; + replyData->status = 0; + replyData->psize = 4; + replyData->vsize = 4; + replyData->cmd = 30002; + replyData->data = dspmain->hashSlot[2]; + *replySize = sizeof(reply1x4_1x4_t); + return 0; + } + else if (cmd == 30003) + { + reply1x4_1x4_t *replyData = (reply1x4_1x4_t *)pReplyData; + replyData->status = 0; + replyData->psize = 4; + replyData->vsize = 4; + replyData->cmd = 30003; + replyData->data = dspmain->hashSlot[3]; + *replySize = sizeof(reply1x4_1x4_t); + return 0; + } + } + } + if (cmdCode == EFFECT_CMD_SET_PARAM) + { + effect_param_t *cep = (effect_param_t *)pCmdData; + int32_t *replyData = (int32_t *)pReplyData; + if (cep->psize == 4 && cep->vsize == 2) + { + int32_t cmd = ((int32_t *)cep)[3]; + if (cmd == 128) + { + int reverbMode = (int)((int16_t *)cep)[8]; + Reverb_SetParam(&dspmain->jdsp, reverbMode); +#ifdef DEBUG + LOGI("Reverb mode: %d", reverbMode); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 137) + { + float agress = ((int16_t *)cep)[8] / 100.0f; + StereoEnhancementSetParam(&dspmain->jdsp, agress); +#ifdef DEBUG + LOGE("Stereo widen ag: %1.7f", agress); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 188) + { + int16_t nMode = ((int16_t *)cep)[8]; + if (nMode < 0) + nMode = 0; + if (nMode > 5) + nMode = 5; + CrossfeedChangeMode(&dspmain->jdsp, nMode); +#ifdef DEBUG + LOGI("Crossfeed mode: %d", nMode); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 150) + { + float tubedrive = ((int16_t *)cep)[8] / 1000.0f; +#ifdef DEBUG + LOGI("Tube drive: %1.7f", tubedrive); +#endif + VacuumTubeSetGain(&dspmain->jdsp, tubedrive); + *replyData = 0; + return 0; + } + else if (cmd == 1200) + { + int16_t compressorEnabled = ((int16_t *)cep)[8]; + if (!compressorEnabled) + CompressorDisable(&dspmain->jdsp); + else + CompressorEnable(&dspmain->jdsp, 1); +#ifdef DEBUG + LOGE("Compressor enabled: %d", compressorEnabled); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 1201) + { + int16_t bassBoostEnabled = ((int16_t *)cep)[8]; + if (!bassBoostEnabled) + BassBoostDisable(&dspmain->jdsp); + else + BassBoostEnable(&dspmain->jdsp); +#ifdef DEBUG + LOGE("Bass boost enabled: %d", bassBoostEnabled); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 112) + { + float maxg = ((int16_t *)cep)[8]; +#ifdef DEBUG + LOGE("Bass boost max gain: %f", maxg); +#endif + BassBoostSetParam(&dspmain->jdsp, maxg); + *replyData = 0; + return 0; + } + else if (cmd == 1202) + { + int16_t equalizerEnabled = ((int16_t *)cep)[8]; + if (!equalizerEnabled) + MultimodalEqualizerDisable(&dspmain->jdsp); + else + MultimodalEqualizerEnable(&dspmain->jdsp, 1); +#ifdef DEBUG + LOGE("FIR equalizer enabled: %d", equalizerEnabled); +#endif + // Enable EQ + *replyData = 0; + return 0; + } + else if (cmd == 1203) + { + int16_t reverbEnabled = ((int16_t *)cep)[8]; + if (!reverbEnabled) + ReverbDisable(&dspmain->jdsp); + else + ReverbEnable(&dspmain->jdsp); +#ifdef DEBUG + LOGE("Reverb enabled: %d", reverbEnabled); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 1204) + { + int16_t stereoWidenEnabled = ((int16_t *)cep)[8]; + if (!stereoWidenEnabled) + StereoEnhancementDisable(&dspmain->jdsp); + else + StereoEnhancementEnable(&dspmain->jdsp); +#ifdef DEBUG + LOGE("Stereo widen enabled: %d", stereoWidenEnabled); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 1205) + { + int16_t convolverEnabled = ((int16_t *)cep)[8]; +#ifdef DEBUG + LOGE("Convolver enabled: %d", convolverEnabled); +#endif + if (!convolverEnabled) + Convolver1DDisable(&dspmain->jdsp); + else + Convolver1DEnable(&dspmain->jdsp); + *replyData = 0; + return 0; + } + else if (cmd == 1206) + { + int16_t analogueModelEnable = ((int16_t *)cep)[8]; + if (!analogueModelEnable) + VacuumTubeDisable(&dspmain->jdsp); + else + VacuumTubeEnable(&dspmain->jdsp); +#ifdef DEBUG + LOGE("Analogue modelling enabled: %d", analogueModelEnable); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 1208) + { + int16_t bs2bEnabled = ((int16_t *)cep)[8]; + if (!bs2bEnabled) + CrossfeedDisable(&dspmain->jdsp); + else + CrossfeedEnable(&dspmain->jdsp, 1); +#ifdef DEBUG + LOGE("Crossfeed enabled: %d", bs2bEnabled); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 1210) + { + int16_t arbitraryResponseEnabled = ((int16_t *)cep)[8]; + if (!arbitraryResponseEnabled) + ArbitraryResponseEqualizerDisable(&dspmain->jdsp); + else + ArbitraryResponseEqualizerEnable(&dspmain->jdsp, 1); +#ifdef DEBUG + LOGE("Arbitrary response eq enabled: %d", arbitraryResponseEnabled); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 1212) + { + int16_t viperddcEnabled = ((int16_t *)cep)[8]; + int errCode = 0; + if (!viperddcEnabled) + DDCDisable(&dspmain->jdsp); + else + errCode = DDCEnable(&dspmain->jdsp, 1); +#ifdef DEBUG + LOGE("viperddcEnabled: %d, success?: %d", viperddcEnabled, errCode); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 1213) + { + int16_t EELEnabled = ((int16_t *)cep)[8]; + if (!EELEnabled) + LiveProgDisable(&dspmain->jdsp); + else + LiveProgEnable(&dspmain->jdsp); +#ifdef DEBUG + LOGE("Liveprog enabled: %d", EELEnabled); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 10004) + { + // Load impulse +#ifdef DEBUG + if (dspmain->samplesInc == dspmain->numTime2Send) + LOGI("Buffer slices complete, chs: %d, impLen: %d", dspmain->impChannels, dspmain->impulseLengthActual); + else + LOGI("Ops! Buffer slices got %d missing holes", dspmain->numTime2Send - dspmain->samplesInc); +#endif + dspmain->samplesInc = 0; + int success = Convolver1DLoadImpulseResponse(&dspmain->jdsp, dspmain->tempImpulseIncoming, dspmain->impChannels, dspmain->impulseLengthActual, 1); + union + { + int32_t raw; + float f; + } fltInt; + int32_t crc = 0xFFFFFFFF; + for (unsigned int i = 0; i < dspmain->impulseLengthActual * dspmain->impChannels; i++) + { + fltInt.f = dspmain->tempImpulseIncoming[i]; + crc = crc ^ fltInt.raw; + for (int j = 7; j >= 0; j--) + { + int32_t mask = -(crc & 1); + crc = (crc >> 1) ^ (0xEDB88320 & mask); + } + } + dspmain->engineImpulseResponseHash = ~crc; + free(dspmain->tempImpulseIncoming); + dspmain->tempImpulseIncoming = 0; +#ifdef DEBUG + LOGI("FFT convolver errCode: %d", success); +#endif + *replyData = 0; + return 0; + } + else if (cmd == 10006) + { + dspmain->stringIndex = 0; + if (dspmain->stringEq) + { +#ifdef DEBUG + LOGI("%s", dspmain->stringEq); +#endif + ArbitraryResponseEqualizerStringParser(&dspmain->jdsp, dspmain->stringEq); + free(dspmain->stringEq); + dspmain->stringEq = 0; +#ifdef DEBUG + LOGI("Arbitrary response initialized"); +#endif + } + *replyData = 0; + return 0; + } + else if (cmd == 10009) + { + dspmain->stringIndex = 0; + if (dspmain->stringEq) + { +#ifdef DEBUG + LOGI("%s", dspmain->stringEq); +#endif + // Initialize DDC + DDCStringParser(&dspmain->jdsp, dspmain->stringEq); + free(dspmain->stringEq); + dspmain->stringEq = 0; +#ifdef DEBUG + LOGI("DDC initialized"); +#endif + } + *replyData = 0; + return 0; + } + else if (cmd == 10010) + { + dspmain->stringIndex = 0; + if (dspmain->stringEq) + { +#ifdef DEBUG + LOGI("%s", dspmain->stringEq); +#endif + // Initialize EEL + int errorCode = LiveProgStringParser(&dspmain->jdsp, dspmain->stringEq); + free(dspmain->stringEq); + dspmain->stringEq = 0; +#ifdef DEBUG + LOGI("Live prog error message: %s", checkErrorCode(errorCode)); +#endif + } + *replyData = 0; + return 0; + } + } + if (cep->psize == 4 && cep->vsize == 4) + { + int32_t cmd = ((int32_t *)cep)[3]; + if (cmd == 25000) + { + dspmain->hashSlot[0] = ((int32_t*)cep)[4]; +#ifdef DEBUG + LOGI("ArbEq hash: %d", dspmain->hashSlot[0]); +#endif + *replyData = 0; + return 0; + } + if (cmd == 25001) + { + dspmain->hashSlot[0 + 1] = ((int32_t*)cep)[4]; +#ifdef DEBUG + LOGI("DDC hash: %d", dspmain->hashSlot[0 + 1]); +#endif + *replyData = 0; + return 0; + } + if (cmd == 25002) + { + dspmain->hashSlot[0 + 2] = ((int32_t*)cep)[4]; +#ifdef DEBUG + LOGI("LiveProg hash: %d", dspmain->hashSlot[0 + 2]); +#endif + *replyData = 0; + return 0; + } + if (cmd == 25003) + { + dspmain->hashSlot[0 + 3] = ((int32_t*)cep)[4]; +#ifdef DEBUG + LOGI("Convolver app hash: %d, engine hash: %d", dspmain->hashSlot[0 + 3], dspmain->engineImpulseResponseHash); +#endif + *replyData = 0; + return 0; + } + } + if (cep->psize == 4 && cep->vsize == 12) + { + int32_t cmd = ((int32_t *)cep)[3]; + if (cmd == 1500) + { + double limThreshold = (double)((float*)cep)[4]; + double limRelease = (double)((float*)cep)[5]; + double postgain = (double)((float*)cep)[6]; + if (limThreshold > -0.09) + limThreshold = -0.09; + if (limRelease < 0.15) + limRelease = 0.15; + if (postgain > 15.0) + postgain = 15.0; + if (postgain < -15.0) + postgain = -15.0; + JLimiterSetCoefficients(&dspmain->jdsp, limThreshold, limRelease); + JamesDSPSetPostGain(&dspmain->jdsp, postgain); +#ifdef DEBUG + LOGE("limThreshold: %f, limRelease: %f, postgain: %f", limThreshold, limRelease, postgain); +#endif + *replyData = 0; + return 0; + } + } + if (cep->psize == 4 && cep->vsize == 68) + { + int32_t cmd = ((int32_t *)cep)[3]; + if (cmd == 115) + { + float timeconstant = ((float*)cep)[4 + 0]; + int granularity = (int)roundf(((float*)cep)[4 + 1]); + int tfresolution = (int)roundf(((float*)cep)[4 + 2]); + float *ptrFreqAxis = &((float*)cep)[4 + 3]; + float *ptrGainAxis = ptrFreqAxis + 7; + double param[14]; + for (int i = 0; i < 7; i++) + { + param[i] = (double)ptrFreqAxis[i]; + param[i + 7] = (double)ptrGainAxis[i]; + } +#ifdef DEBUG + LOGI("Compander timeconstant = %1.8f", timeconstant); + LOGI("Compander granularity = %d", granularity); + LOGI("Compander tfresolution = %d", tfresolution); + LOGI("Compander axis: "); + for (int i = 0; i < 7; i++) + LOGI("%1.7lf %1.7lf; ", param[i], param[i + 7]); +#endif + CompressorSetParam(&dspmain->jdsp, timeconstant, granularity, tfresolution, 0); + CompressorSetGain(&dspmain->jdsp, param, param + 7, 1); + *replyData = 0; + return 0; + } + } + if (cep->psize == 4 && cep->vsize == 128) + { + int32_t cmd = ((int32_t *)cep)[3]; + if (cmd == 116) + { + int filtertype = roundf(((float*)cep)[4 + 0]); + int interpolationMode = (((float*)cep)[4 + 1]) < 0.0f ? 0 : 1; + float *ptrFreqAxis = &((float*)cep)[4 + 2]; + float *ptrGainAxis = ptrFreqAxis + 15; + double param[30]; + for (int i = 0; i < 15; i++) + { + param[i] = (double)ptrFreqAxis[i]; + param[i + 15] = (double)ptrGainAxis[i]; + } +#ifdef DEBUG + if (filtertype == 0) + LOGI("filtertype: FIR Minimum phase"); + else if (filtertype == 1) + LOGI("filtertype: IIR 4 order"); + else if (filtertype == 2) + LOGI("filtertype: IIR 6 order"); + else if (filtertype == 3) + LOGI("filtertype: IIR 8 order"); + else if (filtertype == 4) + LOGI("filtertype: IIR 10 order"); + else + LOGI("filtertype: IIR 12 order"); + LOGI("Eq axis: "); + for (int i = 0; i < 15; i++) + LOGI("%1.7lf %1.7lf; ", param[i], param[i + 15]); +#endif + MultimodalEqualizerAxisInterpolation(&dspmain->jdsp, interpolationMode, filtertype, param, param + 15); + *replyData = 0; + return 0; + } + } + if (cep->psize == 4 && cep->vsize == 8) + { + int32_t cmd = ((int32_t *)cep)[3]; + if (cmd == 8888) // Implemented + { + int32_t times = ((int32_t *)cep)[4]; + int32_t sizePerBuffer = ((int32_t *)cep)[5]; + int stringLength = times * sizePerBuffer; +#ifdef DEBUG + LOGI("Allocate %d string length", stringLength); +#endif + dspmain->stringEq = (char*)calloc(stringLength, sizeof(char)); + *replyData = 0; + return 0; + } + } + if (cep->psize == 4 && cep->vsize == 16) + { + int32_t cmd = ((int32_t *)cep)[3]; + if (cmd == 9999) // Implemented + { + dspmain->impChannels = ((int32_t *)cep)[5]; + dspmain->impulseLengthActual = ((int32_t *)cep)[4] / dspmain->impChannels; + float convGaindB = (float)((int32_t *)cep)[6] / 262144.0f; + if (convGaindB > 50.0f) + convGaindB = 50.0f; + dspmain->numTime2Send = ((int32_t *)cep)[7]; + dspmain->tempImpulseIncoming = (float*)calloc(4096 * dspmain->impChannels * dspmain->numTime2Send, sizeof(float)); + *replyData = 0; + return 0; + } + } + if (cep->psize == 4 && cep->vsize == 16384) + { + int32_t cmd = ((int32_t *)cep)[3]; + if (cmd == 12000) // Implemented + { + memcpy(dspmain->tempImpulseIncoming + (dspmain->samplesInc++ * 4096), ((float*)cep) + 4, 4096 * sizeof(float)); + *replyData = 0; + return 0; + } + } + if (cep->psize == 4 && cep->vsize == 256) + { + int32_t cmd = ((int32_t *)cep)[3]; + if (cmd == 12001) // Implemented + { + memcpy(dspmain->stringEq + (dspmain->stringIndex++ * 256), ((char*)cep) + 16, 256 * sizeof(char)); + *replyData = 0; + return 0; + } + } + return -1; + } + switch (cmdCode) + { + case EFFECT_CMD_ENABLE: + case EFFECT_CMD_DISABLE: + { + dspmain->mEnable = cmdCode == EFFECT_CMD_ENABLE; + int32_t *replyData = (int32_t *) pReplyData; + *replyData = 0; + break; + } + case EFFECT_CMD_INIT: + case EFFECT_CMD_SET_CONFIG: + case EFFECT_CMD_SET_PARAM: + case EFFECT_CMD_SET_PARAM_COMMIT: + { + int32_t *replyData = (int32_t *) pReplyData; + *replyData = 0; + break; + } + case EFFECT_CMD_RESET: + case EFFECT_CMD_SET_PARAM_DEFERRED: + case EFFECT_CMD_SET_DEVICE: + case EFFECT_CMD_SET_AUDIO_MODE: + break; + case EFFECT_CMD_GET_PARAM: + { + effect_param_t *rep = (effect_param_t *) pReplyData; + rep->status = -EINVAL; + rep->psize = 0; + rep->vsize = 0; + *replySize = 12; + break; + } + } + return 0; +} + +int32_t EffectDSPMainProcess(EffectDSPMain *dspmain, audio_buffer_t *in, audio_buffer_t *out) +{ + size_t actualFrameCount = in->frameCount; + switch (dspmain->formatFloatModeInt32Mode) + { + case 0: + dspmain->jdsp.processInt16Multiplexd(&dspmain->jdsp, in->s16, out->s16, actualFrameCount); + break; + case 1: + dspmain->jdsp.processFloatMultiplexd(&dspmain->jdsp, in->f32, out->f32, actualFrameCount); + break; + case 2: + dspmain->jdsp.processInt32Multiplexd(&dspmain->jdsp, in->s32, out->s32, actualFrameCount); + break; + case 3: + dspmain->jdsp.processInt24PackedMultiplexd(&dspmain->jdsp, (uint8_t*)in->raw, (uint8_t*)out->raw, actualFrameCount); + break; + case 4: + dspmain->jdsp.processInt8_24Multiplexd(&dspmain->jdsp, in->s32, out->s32, actualFrameCount); + break; + } + return dspmain->mEnable ? 0 : -ENODATA; +} + +__attribute__((constructor)) static void initialize(void) +{ + JamesDSPGlobalMemoryAllocation(); +#ifdef DEBUG + LOGI("Initialization: DLL loaded"); +#endif +} +__attribute__((destructor)) static void destruction(void) +{ + JamesDSPGlobalMemoryDeallocation(); +#ifdef DEBUG + LOGI("Initialization: DLL unloaded"); +#endif +} diff --git a/Main/libjamesdsp/jni/jamesdsp/jdsp_impl.h b/Main/libjamesdsp/jni/jamesdsp/jdsp_impl.h new file mode 100644 index 0000000..a6062e4 --- /dev/null +++ b/Main/libjamesdsp/jni/jamesdsp/jdsp_impl.h @@ -0,0 +1,50 @@ +#ifndef _JDSP_IMPL_H_ +#define _JDSP_IMPL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#ifdef AOSP_SOONG_BUILD +#include +#else +#include "essential.h" +#endif + +#include "jdsp/jdsp_header.h" + +typedef struct +{ + unsigned long long initializeForFirst; + int32_t engineImpulseResponseHash; + int32_t hashSlot[4]; + int mEnable; + JamesDSPLib jdsp; + float mSamplingRate; + int formatFloatModeInt32Mode; + char *stringEq; + float *tempImpulseIncoming; + float drcAtkRel[4]; + float boostingCon; + int bbMaxGain; + // Variables + int numTime2Send, samplesInc, stringIndex; + int16_t impChannels; + int32_t impulseLengthActual, convolverNeedRefresh; +} EffectDSPMain; + +void EffectDSPMainConstructor(EffectDSPMain *dspmain); +void EffectDSPMainDestructor(EffectDSPMain *dspmain); +int32_t EffectDSPMainCommand(EffectDSPMain *dspmain, uint32_t cmdCode, uint32_t cmdSize, void* pCmdData, uint32_t* replySize, void* pReplyData); +int32_t EffectDSPMainProcess(EffectDSPMain *dspmain, audio_buffer_t *in, audio_buffer_t *out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Tutorials/jni/Android.mk b/Tutorials/jni/Android.mk.disabled similarity index 100% rename from Tutorials/jni/Android.mk rename to Tutorials/jni/Android.mk.disabled diff --git a/VeryOldOpen_source_edition/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/Android.mk b/VeryOldOpen_source_edition/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/Android.mk.disabled similarity index 100% rename from VeryOldOpen_source_edition/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/Android.mk rename to VeryOldOpen_source_edition/Audio_Engine/eclipse_libjamesdsp_free_bp/jni/Android.mk.disabled diff --git a/VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/Android.mk b/VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/Android.mk.disabled similarity index 100% rename from VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/Android.mk rename to VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/Android.mk.disabled diff --git a/VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/FLAC/Android.mk b/VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/FLAC/Android.mk.disabled similarity index 100% rename from VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/FLAC/Android.mk rename to VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/FLAC/Android.mk.disabled diff --git a/VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/libsamplerate/Android.mk b/VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/libsamplerate/Android.mk.disabled similarity index 100% rename from VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/libsamplerate/Android.mk rename to VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/libsamplerate/Android.mk.disabled diff --git a/VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/libsndfile/Android.mk b/VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/libsndfile/Android.mk.disabled similarity index 100% rename from VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/libsndfile/Android.mk rename to VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/libsndfile/Android.mk.disabled diff --git a/VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/main/Android.mk b/VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/main/Android.mk.disabled similarity index 100% rename from VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/main/Android.mk rename to VeryOldOpen_source_edition/DSPManager_Free_BitPerfect/jni/main/Android.mk.disabled