diff --git a/CMakeLists.txt b/CMakeLists.txt index fc3b6d7..73dc94a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.18.1) +cmake_minimum_required(VERSION 3.16.3) project("ViPER4Android Reworked") @@ -67,4 +67,5 @@ add_library( ${FILES}) find_library(log-lib log) + target_link_libraries(v4afx_r ${log-lib}) diff --git a/src/cpp/constants.h b/src/cpp/constants.h index f37280c..1aed833 100644 --- a/src/cpp/constants.h +++ b/src/cpp/constants.h @@ -5,19 +5,15 @@ #pragma once #ifdef ANDROID_TOOLCHAIN -#include #include #else -#define __android_log_write(...) do {} while (0) -#define __android_log_print(...) do {} while (0) -#define ANDROID_LOG_INFO 1 -#include +#include #endif +#include "log.h" // TODO: Remove this dependency + #define STR_HELPER(x) #x #define STR(x) STR_HELPER(x) #define VERSION_STRING STR(VERSION_MAJOR) "." STR(VERSION_MINOR) "." STR(VERSION_REVISION) "." STR(VERSION_BUILD) -#define DEFAULT_SAMPLERATE 44100 -#define v4a_print(status, message) __android_log_write(status, "ViPER4Android_Reworked", message) -#define v4a_printf(status, format, ...) __android_log_print(status, "ViPER4Android_Reworked", format, __VA_ARGS__) \ No newline at end of file +#define DEFAULT_SAMPLERATE 44100 \ No newline at end of file diff --git a/src/cpp/log.h b/src/cpp/log.h new file mode 100644 index 0000000..205c123 --- /dev/null +++ b/src/cpp/log.h @@ -0,0 +1,12 @@ +#pragma once + +#ifdef ANDROID_TOOLCHAIN +#include +#else +#define __android_log_write(...) do {} while (0) +#define __android_log_print(...) do {} while (0) +#define ANDROID_LOG_INFO 1 +#endif + +#define v4a_print(status, message) __android_log_write(status, "ViPER4Android_Reworked", message) +#define v4a_printf(status, format, ...) __android_log_print(status, "ViPER4Android_Reworked", format, __VA_ARGS__) \ No newline at end of file diff --git a/src/cpp/viper.cpp b/src/cpp/viper.cpp index b126287..0f70fd4 100644 --- a/src/cpp/viper.cpp +++ b/src/cpp/viper.cpp @@ -1,110 +1,168 @@ #include -#include #include "Effect.h" #include "ProcessUnit_FX.h" #include "constants.h" +#include "log.h" static effect_descriptor_t viper_descriptor = { // Identical type/uuid to original ViPER4Android .type = {0x00000000, 0x0000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, .uuid = {0x41d3c987, 0xe6cf, 0x11e3, 0xa88a, { 0x11, 0xab, 0xa5, 0xd5, 0xc5, 0x1b } }, - .apiVersion = 0x20000, - .flags = 0xf010, - .cpuLoad = 0x08, - .memoryUsage = 0x01, + .apiVersion = EFFECT_CONTROL_API_VERSION, + .flags = EFFECT_FLAG_OUTPUT_BOTH | EFFECT_FLAG_INPUT_BOTH | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_TYPE_INSERT, + .cpuLoad = 8, // In 0.1 MIPS units as estimated on an ARM9E core (ARMv5TE) with 0 WS + .memoryUsage = 1, // In KB and includes only dynamically allocated memory }; extern "C" { - typedef struct { - const struct effect_interface_s* interface; - Effect* effect; - effect_descriptor_t* descriptor; - } handle; + struct ViperContext { + const struct effect_interface_s *interface; + ProcessUnit_FX *effect; + effect_descriptor_t *descriptor; + }; - static int32_t generic_process(effect_handle_t self, audio_buffer_t *in, audio_buffer_t *out) { - auto e = (handle *) self; - return e->effect->process(in, out); - } - static int32_t generic_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) { - auto e = (handle *) self; - return e->effect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData); - } - static int32_t generic_getDescriptor(effect_handle_t self, effect_descriptor_t *pDescriptor) { - auto e = (handle *) self; - strcpy(viper_descriptor.name, "ViPER4Android Reworked [" VERSION_STRING "]"); - strcpy(viper_descriptor.implementor, "ViPER.WYF, Martmists, Iscle"); + static int32_t viper_process(effect_handle_t self, audio_buffer_t *in, audio_buffer_t *out) { + auto pContext = (ViperContext *) self; + + if (pContext == nullptr) { + v4a_printf(ANDROID_LOG_ERROR, "viper_process(), Error [pContext = NULL]"); + return -EINVAL; + } + + if (in == nullptr) { + v4a_printf(ANDROID_LOG_ERROR, "viper_process(), Error [in = NULL]"); + return -EINVAL; + } + + if (out == nullptr) { + v4a_printf(ANDROID_LOG_ERROR, "viper_process(), Error [out = NULL]"); + return -EINVAL; + } + + return pContext->effect->process(in, out); + } + + static int32_t viper_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) { + auto pContext = (ViperContext *) self; + + if (pContext == nullptr) { + v4a_printf(ANDROID_LOG_ERROR, "viper_command(), Error [pContext = NULL]"); + return -EINVAL; + } + + return pContext->effect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData); + } + + static int32_t viper_get_descriptor(effect_handle_t self, effect_descriptor_t *pDescriptor) { + auto *pContext = (ViperContext *) self; + + if (pContext == nullptr) { + v4a_printf(ANDROID_LOG_ERROR, "viper_get_descriptor(), Error [pContext = NULL]"); + return -EINVAL; + } + + if (pDescriptor == nullptr) { + v4a_print(ANDROID_LOG_ERROR, "viper_get_descriptor(), Error [pDescriptor = NULL]"); + return -EINVAL; + } + + *pDescriptor = *pContext->descriptor; - memcpy(pDescriptor, e->descriptor, sizeof(effect_descriptor_t)); return 0; } const effect_interface_s viper_interface = { - .process = generic_process, - .command = generic_command, - .get_descriptor = generic_getDescriptor, - .process_reverse = nullptr + .process = viper_process, + .command = viper_command, + .get_descriptor = viper_get_descriptor }; - int32_t EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pEffect) { - v4a_print(ANDROID_LOG_INFO,"Enter EffectCreate()"); - if (memcmp(uuid, &viper_descriptor.uuid, sizeof(effect_uuid_t)) == 0) { - // UUID matches - v4a_printf(ANDROID_LOG_INFO, "EffectCreate(), uuid = %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, uuid->clockSeq, uuid->node[0], uuid->node[1], uuid->node[2], uuid->node[3], uuid->node[4], uuid->node[5]); + int32_t viper_effect_create(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle) { + v4a_print(ANDROID_LOG_INFO, "Enter viper_effect_create()"); - strcpy(viper_descriptor.name, "ViPER4Android Reworked [" VERSION_STRING "]"); - strcpy(viper_descriptor.implementor, "ViPER.WYF, Martmists, Iscle"); + if (uuid == nullptr) { + v4a_printf(ANDROID_LOG_ERROR, "viper_effect_create(), Error [uuid = NULL]"); + return -EINVAL; + } - v4a_print(ANDROID_LOG_INFO, "EffectCreate(), v4a standard effect (normal), Constructing ProcessUnit_FX"); + if (pHandle == nullptr) { + v4a_printf(ANDROID_LOG_ERROR, "viper_effect_create(), Error [pHandle = NULL]"); + return -EINVAL; + } - auto ptr = (handle*)calloc(1, sizeof(handle)); - ptr->interface = &viper_interface; - ptr->effect = new ProcessUnit_FX(); - ptr->descriptor = &viper_descriptor; + if (memcmp(uuid, &viper_descriptor.uuid, sizeof(effect_uuid_t)) != 0) { + v4a_print(ANDROID_LOG_ERROR, "viper_effect_create(), Error [effect not found]"); + return -EINVAL; + } - v4a_print(ANDROID_LOG_INFO, "Creating ViPER4Android Reworked [" VERSION_STRING "]"); - *pEffect = (effect_handle_t)ptr; - } else { + v4a_printf(ANDROID_LOG_INFO, "viper_effect_create(), uuid = %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, uuid->clockSeq, uuid->node[0], uuid->node[1], uuid->node[2], uuid->node[3], uuid->node[4], uuid->node[5]); + v4a_print(ANDROID_LOG_INFO, "viper_effect_create(), v4a standard effect (normal), Constructing ProcessUnit_FX"); + + auto *pContext = new ViperContext; + pContext->interface = &viper_interface; + pContext->effect = new ProcessUnit_FX(); + pContext->descriptor = &viper_descriptor; + + v4a_print(ANDROID_LOG_INFO, "Creating ViPER4Android Reworked [" VERSION_STRING "]"); + *pHandle = (effect_handle_t) pContext; - v4a_print(ANDROID_LOG_ERROR, "EffectCreate(), Error [effect not found]"); - return -ENOENT; - } return 0; } - int32_t EffectRelease(effect_handle_t ei) { - v4a_print(ANDROID_LOG_INFO, "EffectRelease(), Deconstructing ProcessUnit"); + int32_t viper_effect_release(effect_handle_t handle) { + auto *pContext = (ViperContext *) handle; + + v4a_print(ANDROID_LOG_INFO, "Enter viper_effect_release()"); + + if (pContext == nullptr) { + v4a_printf(ANDROID_LOG_ERROR, "viper_effect_release(), Error [pContext = NULL]"); + return -EINVAL; + } + + v4a_print(ANDROID_LOG_INFO, "viper_effect_release(), Deconstructing ProcessUnit"); + + if (pContext->effect != nullptr) { + delete pContext->effect; + pContext->effect = nullptr; + } + delete pContext; - auto ptr = (handle*)ei; - delete ptr->effect; - free(ptr); return 0; } - int32_t EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { - v4a_print(ANDROID_LOG_INFO, "Enter EffectGetDescriptor()"); + int32_t viper_effect_get_descriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { + v4a_print(ANDROID_LOG_INFO, "Enter viper_effect_get_descriptor()"); - if (memcmp(uuid, &viper_descriptor.uuid, sizeof(effect_uuid_t)) == 0) { - v4a_printf(ANDROID_LOG_INFO, "EffectGetDescriptor(), uuid = %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, uuid->clockSeq, uuid->node[0], uuid->node[1], uuid->node[2], uuid->node[3], uuid->node[4], uuid->node[5]); + if (uuid == nullptr) { + v4a_printf(ANDROID_LOG_ERROR, "viper_effect_get_descriptor(), Error [uuid = NULL]"); + return -EINVAL; + } - strcpy(viper_descriptor.name, "ViPER4Android Reworked [" VERSION_STRING "]"); - strcpy(viper_descriptor.implementor, "ViPER.WYF, Martmists, Iscle"); + if (pDescriptor == nullptr) { + v4a_printf(ANDROID_LOG_ERROR, "viper_effect_get_descriptor(), Error [pDescriptor = NULL]"); + return -EINVAL; + } + + if (memcmp(uuid, &viper_descriptor.uuid, sizeof(effect_uuid_t)) != 0) { + v4a_print(ANDROID_LOG_ERROR, "viper_effect_get_descriptor(), Error [effect not found]"); + return -EINVAL; + } + + v4a_printf(ANDROID_LOG_INFO, "viper_effect_get_descriptor(), uuid = %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, uuid->clockSeq, uuid->node[0], uuid->node[1], uuid->node[2], uuid->node[3], uuid->node[4], uuid->node[5]); + + *pDescriptor = viper_descriptor; - memcpy(pDescriptor, &viper_descriptor, sizeof(effect_descriptor_t)); - } else { - v4a_print(ANDROID_LOG_ERROR, "EffectGetDescriptor(), Error [effect not found]"); - return -EINVAL; - } return 0; } audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { .tag = AUDIO_EFFECT_LIBRARY_TAG, - .version = 0x30000, + .version = EFFECT_LIBRARY_API_VERSION, .name = "ViPER4Android FX Reworked", .implementor = "ViPER.WYF, Martmists, Iscle", - .create_effect = EffectCreate, - .release_effect = EffectRelease, - .get_descriptor = EffectGetDescriptor, + .create_effect = viper_effect_create, + .release_effect = viper_effect_release, + .get_descriptor = viper_effect_get_descriptor, }; } diff --git a/src/include/essential.h b/src/include/essential.h index b4b0da5..17875e8 100644 --- a/src/include/essential.h +++ b/src/include/essential.h @@ -1,3 +1,5 @@ +// Source: https://android.googlesource.com/platform/system/media/+/master/audio/include/system + typedef struct effect_uuid_s { uint32_t timeLow;