mirror of
https://github.com/AndroidAudioMods/ViPERFX_RE.git
synced 2025-06-08 02:29:40 +08:00
Implement effect offloading to Hexagon DSP
This commit is contained in:
parent
bdf5053968
commit
e2a6a406a2
6
.gitignore
vendored
6
.gitignore
vendored
@ -24,6 +24,8 @@ build.ninja
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
android_*/
|
||||
hexagon_*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
@ -147,3 +149,7 @@ local.properties
|
||||
.gradle/
|
||||
build/
|
||||
.cxx/
|
||||
|
||||
### Misc
|
||||
LOGS/
|
||||
*-hexagon/
|
||||
|
@ -7,19 +7,17 @@ set(CMAKE_CXX_COMPILER_VERSION 20)
|
||||
#add_compile_definitions(ANDROID_ARM_NEON=true)
|
||||
#add_compile_definitions(ANDROID_PLATFORM=android-24)
|
||||
|
||||
project("ViPER4Android")
|
||||
project("ViPER4Android" C CXX ASM)
|
||||
enable_language(ASM)
|
||||
add_compile_definitions(VIPER_VERSION=20240314)
|
||||
|
||||
# FFTS
|
||||
#add_subdirectory(src/viper/ffts)
|
||||
|
||||
# ViPERFX
|
||||
include_directories(src/include)
|
||||
|
||||
set(FILES
|
||||
# Main
|
||||
src/viper/ViPER.cpp
|
||||
src/ViPER4Android.cpp
|
||||
src/ViperContext.cpp
|
||||
|
||||
# Effects
|
||||
@ -70,16 +68,66 @@ set(FILES
|
||||
src/viper/utils/TimeConstDelay.cpp
|
||||
src/viper/utils/WaveBuffer.cpp)
|
||||
|
||||
add_library(
|
||||
# Sets the name of the library.
|
||||
v4a_re
|
||||
if(HEXAGON_SDK_ROOT)
|
||||
include(${HEXAGON_SDK_ROOT}/build/cmake/hexagon_fun.cmake)
|
||||
set(common_incs
|
||||
src/include/
|
||||
${CMAKE_CURRENT_BINARY_DIR}/
|
||||
${HEXAGON_SDK_ROOT}/incs/
|
||||
${HEXAGON_SDK_ROOT}/incs/stddef/
|
||||
${HEXAGON_SDK_ROOT}/rtos/qurt/
|
||||
${HEXAGON_SDK_ROOT}/utils/examples/
|
||||
)
|
||||
include_directories(${common_incs})
|
||||
|
||||
# Sets the library as a shared library.
|
||||
SHARED
|
||||
add_compile_options(-Wno-error=reorder-ctor
|
||||
-Wno-error=unused-private-field
|
||||
-Wno-error=unused-variable
|
||||
-fvisibility=hidden
|
||||
-DNDEBUG
|
||||
-flto
|
||||
-ggdb
|
||||
"-D__QAIC_SKEL_EXPORT=__attribute__((visibility(\"default\")))")
|
||||
|
||||
# Provides a relative path to your source file(s).
|
||||
${FILES})
|
||||
if(${OS_TYPE} MATCHES "HLOS")
|
||||
add_compile_options(-DHEXAGON_STUB -Oz)
|
||||
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} -lc++")
|
||||
set(util_srcs
|
||||
${HEXAGON_SDK_ROOT}/utils/examples/dsp_capabilities_utils.c
|
||||
${HEXAGON_SDK_ROOT}/utils/examples/pd_status_notification.c)
|
||||
|
||||
target_link_libraries(v4a_re log) # kissfft)
|
||||
target_compile_options(v4a_re PRIVATE -flto -O3 -DNDEBUG)
|
||||
#target_compile_options(v4afx_r PRIVATE -O2 -DNDEBUG -Wall -Wsign-conversion -Wno-unused-result -Wno-unneeded-internal-declaration -fstrict-aliasing -fvisibility=hidden -Wextra -Wno-unused-parameter)
|
||||
add_library(v4a_re SHARED ${CMAKE_CURRENT_BINARY_DIR}/v4a_stub.c src/ViPER4Android.cpp src/ViperStub.cpp ${util_srcs})
|
||||
build_idl(src/include/v4a.idl v4a_re)
|
||||
|
||||
choose_dsprpc(${DSP_TYPE} dsprpc)
|
||||
target_link_options(v4a_re PUBLIC -llog)
|
||||
link_custom_library(v4a_re ${dsprpc})
|
||||
|
||||
copy_binaries(v4a_re)
|
||||
else()
|
||||
add_compile_options(-O3)
|
||||
add_library(v4a_skel SHARED ${CMAKE_CURRENT_BINARY_DIR}/v4a_skel.c src/version.c src/ViperHexagon.cpp ${FILES})
|
||||
build_idl(src/include/v4a.idl v4a_skel)
|
||||
|
||||
target_link_libraries(v4a_skel ${HEXAGON_LIB_DIR}/${HEXAGON_ARCH}/G0/pic/libc++abi.so.1)
|
||||
target_link_libraries(v4a_skel ${HEXAGON_LIB_DIR}/${HEXAGON_ARCH}/G0/pic/libc++.so.1)
|
||||
|
||||
copy_binaries(v4a_skel)
|
||||
endif()
|
||||
else()
|
||||
include_directories(src/include)
|
||||
add_library(
|
||||
# Sets the name of the library.
|
||||
v4a_re
|
||||
|
||||
# Sets the library as a shared library.
|
||||
SHARED
|
||||
|
||||
# Provides a relative path to your source file(s).
|
||||
${FILES}
|
||||
src/ViPER4Android.cpp)
|
||||
|
||||
target_link_libraries(v4a_re log) # kissfft)
|
||||
target_compile_options(v4a_re PRIVATE -flto -O3 -DNDEBUG)
|
||||
#target_compile_options(v4afx_r PRIVATE -O2 -DNDEBUG -Wall -Wsign-conversion -Wno-unused-result -Wno-unneeded-internal-declaration -fstrict-aliasing -fvisibility=hidden -Wextra -Wno-unused-parameter)
|
||||
endif()
|
||||
|
@ -10,6 +10,8 @@ typedef enum {
|
||||
PARAM_GET_DISABLE_REASON,
|
||||
PARAM_GET_CONFIG,
|
||||
PARAM_GET_ARCHITECTURE,
|
||||
|
||||
PARAM_GET_MAX,
|
||||
} param_get_t;
|
||||
|
||||
typedef enum {
|
||||
@ -53,4 +55,6 @@ typedef enum {
|
||||
PARAM_SET_DYNAMIC_SYSTEM_Y_COEFFICIENTS,
|
||||
PARAM_SET_DYNAMIC_SYSTEM_SIDE_GAIN,
|
||||
PARAM_SET_DYNAMIC_SYSTEM_STRENGTH,
|
||||
|
||||
PARAM_SET_MAX,
|
||||
} param_set_t;
|
||||
|
@ -6,7 +6,15 @@
|
||||
#include "log.h"
|
||||
#include "viper/constants.h"
|
||||
|
||||
#ifdef __hexagon__
|
||||
#define SET(type, ptr, value) \
|
||||
do { \
|
||||
type v = value; \
|
||||
memcpy(ptr, &v, sizeof(type)); \
|
||||
} while (false)
|
||||
#else
|
||||
#define SET(type, ptr, value) (*(type *) (ptr) = (value))
|
||||
#endif
|
||||
|
||||
ViperContext::ViperContext() :
|
||||
config({}),
|
||||
@ -17,6 +25,8 @@ ViperContext::ViperContext() :
|
||||
VIPER_LOGI("ViperContext created");
|
||||
}
|
||||
|
||||
ViperContext::~ViperContext() {}
|
||||
|
||||
void ViperContext::copyBufferConfig(buffer_config_t *dest, buffer_config_t *src) {
|
||||
if (src->mask & EFFECT_CONFIG_BUFFER) {
|
||||
dest->buffer = src->buffer;
|
||||
@ -809,7 +819,7 @@ int32_t ViperContext::process(audio_buffer_t *inBuffer, audio_buffer_t *outBuffe
|
||||
if (!enabled) {
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
|
||||
inBuffer = getBuffer(&config.inputCfg, inBuffer);
|
||||
outBuffer = getBuffer(&config.outputCfg, outBuffer);
|
||||
if (inBuffer == nullptr || outBuffer == nullptr ||
|
||||
|
@ -3,7 +3,11 @@
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include "essential.h"
|
||||
#ifndef HEXAGON_STUB
|
||||
#include "viper/ViPER.h"
|
||||
#else
|
||||
#include <mutex>
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
class ViperContext {
|
||||
@ -18,11 +22,18 @@ public:
|
||||
};
|
||||
|
||||
ViperContext();
|
||||
~ViperContext();
|
||||
|
||||
int32_t handleCommand(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData);
|
||||
int32_t process(audio_buffer_t *inBuffer, audio_buffer_t *outBuffer);
|
||||
|
||||
private:
|
||||
#ifdef HEXAGON_STUB
|
||||
std::mutex mHandleLock;
|
||||
uint64_t handle = 0;
|
||||
size_t in_size = 0;
|
||||
size_t out_size = 0;
|
||||
#else
|
||||
effect_config_t config;
|
||||
DisableReason disableReason;
|
||||
|
||||
@ -40,4 +51,5 @@ private:
|
||||
int32_t handleGetParam(effect_param_t *pCmdParam, effect_param_t *pReplyParam, uint32_t *pReplySize);
|
||||
|
||||
void setDisableReason(DisableReason reason);
|
||||
#endif
|
||||
};
|
||||
|
35
src/ViperHexagon.cpp
Normal file
35
src/ViperHexagon.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "v4a.h"
|
||||
#include "log.h"
|
||||
#include "ViperContext.h"
|
||||
|
||||
int v4a_open(const char *uri, remote_handle64 *handle) {
|
||||
*handle = (remote_handle64) new ViperContext();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v4a_close(remote_handle64 handle) {
|
||||
if (handle) {
|
||||
delete reinterpret_cast<ViperContext *>(handle);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t v4a_command(remote_handle64 handle, uint32_t cmdCode, const uint8_t *pCmdData, int cmdSize, uint8_t *pReplyData, int replySize, uint32_t *pReplySize) {
|
||||
return reinterpret_cast<ViperContext *>(handle)->handleCommand(cmdCode, cmdSize, (void *) pCmdData, pReplySize, (void *) pReplyData);
|
||||
}
|
||||
|
||||
int32_t v4a_process(remote_handle64 handle, const uint8_t *inPcm, int inPcmLen, uint8_t *outPcm, int outPcmLen, uint32_t frameCount) {
|
||||
audio_buffer_t in = {
|
||||
.frameCount = frameCount,
|
||||
.raw = (void *) inPcm,
|
||||
};
|
||||
audio_buffer_t out = {
|
||||
.frameCount = frameCount,
|
||||
.raw = (void *) outPcm,
|
||||
};
|
||||
return reinterpret_cast<ViperContext *>(handle)->process(&in, &out);
|
||||
}
|
167
src/ViperStub.cpp
Normal file
167
src/ViperStub.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
#include <remote.h>
|
||||
#include <dsp_capabilities_utils.h>
|
||||
extern "C" {
|
||||
#include <pd_status_notification.h>
|
||||
}
|
||||
#include "v4a.h"
|
||||
#include "ViperContext.h"
|
||||
#include "ViPER4Android.h"
|
||||
#include "log.h"
|
||||
#include "hexagon.h"
|
||||
|
||||
#define STATUS_CONTEXT 0x37303061
|
||||
|
||||
int pd_status_notifier_callback(void *context, int domain, int session, remote_rpc_status_flags_t status){
|
||||
int nErr = AEE_SUCCESS;
|
||||
switch (status){
|
||||
case FASTRPC_USER_PD_UP:
|
||||
VIPER_LOGI("PD is up");
|
||||
break;
|
||||
case FASTRPC_USER_PD_EXIT:
|
||||
VIPER_LOGI("PD closed");
|
||||
break;
|
||||
case FASTRPC_USER_PD_FORCE_KILL:
|
||||
VIPER_LOGI("PD force kill");
|
||||
break;
|
||||
case FASTRPC_USER_PD_EXCEPTION:
|
||||
VIPER_LOGI("PD exception");
|
||||
break;
|
||||
case FASTRPC_DSP_SSR:
|
||||
VIPER_LOGI("DSP SSR");
|
||||
break;
|
||||
default:
|
||||
nErr = AEE_EBADITEM;
|
||||
break;
|
||||
}
|
||||
return nErr;
|
||||
}
|
||||
|
||||
ViperContext::ViperContext() : mHandleLock() {
|
||||
std::lock_guard<std::mutex> guard(mHandleLock);
|
||||
|
||||
VIPER_LOGI("ViperContext created");
|
||||
int nErr = 0;
|
||||
|
||||
{
|
||||
uint32_t cap = 0;
|
||||
if (AEE_SUCCESS != (nErr = get_hex_arch_ver(CDSP_DOMAIN_ID, &cap))) {
|
||||
VIPER_LOGF("get_hex_arch_ver failed: 0x%x", nErr);
|
||||
} else {
|
||||
VIPER_LOGI("CDSP arch: 0x%08x", cap);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
struct remote_rpc_control_unsigned_module data;
|
||||
data.domain = CDSP_DOMAIN_ID;
|
||||
data.enable = 1;
|
||||
if (AEE_SUCCESS != (nErr = remote_session_control(DSPRPC_CONTROL_UNSIGNED_MODULE, (void*)&data, sizeof(data)))) {
|
||||
VIPER_LOGF("remote_session_control failed (unsigned PD): 0x%x", nErr);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
struct remote_rpc_thread_params data;
|
||||
data.domain = CDSP_DOMAIN_ID;
|
||||
data.prio = -1;
|
||||
data.stack_size = 7*1024*1024;;
|
||||
if (AEE_SUCCESS != (nErr = remote_session_control(FASTRPC_THREAD_PARAMS, (void*)&data, sizeof(data)))) {
|
||||
VIPER_LOGF("remote_session_control failed (stack size): 0x%x", nErr);
|
||||
}
|
||||
}
|
||||
|
||||
if(AEE_SUCCESS != (nErr = request_status_notifications_enable(CDSP_DOMAIN_ID, (void*)STATUS_CONTEXT, pd_status_notifier_callback))) {
|
||||
if(nErr != AEE_EUNSUPPORTEDAPI) {
|
||||
VIPER_LOGF("request_status_notifications_enable failed: 0x%x", nErr);
|
||||
}
|
||||
}
|
||||
|
||||
if (AEE_SUCCESS == (nErr = v4a_open(v4a_URI CDSP_DOMAIN, &handle))) {
|
||||
VIPER_LOGI("Offloaded effect library initialized: 0x%lx", handle);
|
||||
} else {
|
||||
VIPER_LOGF("Failed to initialize offloaded effect library: 0x%x", nErr);
|
||||
}
|
||||
}
|
||||
|
||||
ViperContext::~ViperContext() {
|
||||
std::lock_guard<std::mutex> guard(mHandleLock);
|
||||
v4a_close(handle);
|
||||
}
|
||||
|
||||
int32_t ViperContext::handleCommand(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *pReplySize, void *pReplyData) {
|
||||
std::lock_guard<std::mutex> guard(mHandleLock);
|
||||
hexagon_effect_config_t qdspCfg;
|
||||
effect_config_t *cfg = nullptr;
|
||||
if (cmdCode == EFFECT_CMD_SET_CONFIG) {
|
||||
cfg = (effect_config_t *) pCmdData;
|
||||
if (cfg->inputCfg.mask & EFFECT_CONFIG_FORMAT) {
|
||||
switch (cfg->inputCfg.format) {
|
||||
case AUDIO_FORMAT_PCM_FLOAT:
|
||||
case AUDIO_FORMAT_PCM_32_BIT:
|
||||
case AUDIO_FORMAT_PCM_8_24_BIT:
|
||||
in_size = 4;
|
||||
break;
|
||||
case AUDIO_FORMAT_PCM_24_BIT_PACKED:
|
||||
in_size = 3;
|
||||
break;
|
||||
case AUDIO_FORMAT_PCM_16_BIT:
|
||||
in_size = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cfg->outputCfg.mask & EFFECT_CONFIG_FORMAT) {
|
||||
switch (cfg->outputCfg.format) {
|
||||
case AUDIO_FORMAT_PCM_FLOAT:
|
||||
case AUDIO_FORMAT_PCM_32_BIT:
|
||||
case AUDIO_FORMAT_PCM_8_24_BIT:
|
||||
out_size = 4;
|
||||
break;
|
||||
case AUDIO_FORMAT_PCM_24_BIT_PACKED:
|
||||
out_size = 3;
|
||||
break;
|
||||
case AUDIO_FORMAT_PCM_16_BIT:
|
||||
out_size = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
host2hexagon(cfg, &qdspCfg);
|
||||
cmdSize = sizeof(qdspCfg);
|
||||
pCmdData = (void *) &qdspCfg;
|
||||
} else if (cmdCode == EFFECT_CMD_GET_CONFIG) {
|
||||
cfg = (effect_config_t *) pReplyData;
|
||||
*pReplySize = sizeof(qdspCfg);
|
||||
pReplyData = (void *) &qdspCfg;
|
||||
} else if (cmdCode == EFFECT_CMD_SET_PARAM) {
|
||||
uint32_t key = *(uint32_t *) (((effect_param_t *) pCmdData)->data);
|
||||
if (key >= PARAM_SET_MAX) {
|
||||
VIPER_LOGE("handleSetParam: called with unknown key: %d", key);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (cmdCode == EFFECT_CMD_GET_PARAM) {
|
||||
uint32_t key = *(uint32_t *) (((effect_param_t *) pCmdData)->data);
|
||||
if (key >= PARAM_GET_MAX) {
|
||||
VIPER_LOGE("handleGetParam: called with unknown key: %d", key);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (cmdCode == EFFECT_CMD_DUMP) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int replySize = pReplySize == nullptr ? 0 : *pReplySize;
|
||||
|
||||
int32_t result = v4a_command(handle, cmdCode, (const uint8_t *) pCmdData, cmdSize, (uint8_t *) pReplyData, replySize, pReplySize);
|
||||
VIPER_LOGD("v4a_command: %d", result);
|
||||
|
||||
if (cmdCode == EFFECT_CMD_GET_CONFIG) {
|
||||
hexagon2host(&qdspCfg, cfg);
|
||||
*pReplySize = sizeof(*cfg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t ViperContext::process(audio_buffer_t *in, audio_buffer_t *out) {
|
||||
std::lock_guard<std::mutex> guard(mHandleLock);
|
||||
return v4a_process(handle, (const uint8_t *) in->raw, in->frameCount * in_size * 2, (uint8_t *) out->raw, in->frameCount * out_size * 2, in->frameCount);
|
||||
}
|
||||
|
@ -392,6 +392,7 @@ enum effect_command_e
|
||||
EFFECT_CMD_SET_FEATURE_CONFIG, // set current feature configuration
|
||||
EFFECT_CMD_SET_AUDIO_SOURCE, // set the audio source (see audio.h, audio_source_t)
|
||||
EFFECT_CMD_OFFLOAD, // set if effect thread is an offload one,
|
||||
EFFECT_CMD_DUMP, // dump effect current state, for debugging
|
||||
// send the ioHandle of the effect thread
|
||||
EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code
|
||||
};
|
||||
|
94
src/include/hexagon.h
Normal file
94
src/include/hexagon.h
Normal file
@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
|
||||
#include "essential.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t frameCount; // number of frames in buffer
|
||||
union {
|
||||
uint32_t raw; // raw pointer to start of buffer
|
||||
uint32_t f32; // pointer to float 32 bit data at start of buffer
|
||||
uint32_t s32; // pointer to signed 32 bit data at start of buffer
|
||||
uint32_t s16; // pointer to signed 16 bit data at start of buffer
|
||||
uint32_t u8; // pointer to unsigned 8 bit data at start of buffer
|
||||
};
|
||||
} hexagon_audio_buffer_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t getBuffer; // retrieve next buffer
|
||||
uint32_t releaseBuffer; // release used buffer
|
||||
uint32_t cookie; // for use by client of buffer provider functions
|
||||
} hexagon_buffer_provider_t;
|
||||
|
||||
typedef struct {
|
||||
hexagon_audio_buffer_t buffer; // buffer for use by process() function if not passed explicitly
|
||||
uint32_t samplingRate; // sampling rate
|
||||
uint32_t channels; // channel mask (see audio_channel_mask_t in audio.h)
|
||||
hexagon_buffer_provider_t bufferProvider; // buffer provider
|
||||
uint8_t format; // Audio format (see audio_format_t in audio.h)
|
||||
uint8_t accessMode; // read/write or accumulate in buffer (effect_buffer_access_e)
|
||||
uint16_t mask; // indicates which of the above fields is valid
|
||||
} hexagon_buffer_config_t;
|
||||
|
||||
typedef struct {
|
||||
hexagon_buffer_config_t inputCfg;
|
||||
hexagon_buffer_config_t outputCfg;
|
||||
} hexagon_effect_config_t;
|
||||
|
||||
static_assert(sizeof(hexagon_effect_config_t) == 64, "hexagon_effect_config_t must be 64 bytes");
|
||||
|
||||
static inline void host2hexagon(buffer_config_t *in, hexagon_buffer_config_t *out) {
|
||||
if (in->mask & EFFECT_CONFIG_SMP_RATE) {
|
||||
out->mask |= EFFECT_CONFIG_SMP_RATE;
|
||||
out->samplingRate = in->samplingRate;
|
||||
}
|
||||
|
||||
if (in->mask & EFFECT_CONFIG_CHANNELS) {
|
||||
out->mask |= EFFECT_CONFIG_CHANNELS;
|
||||
out->channels = in->channels;
|
||||
}
|
||||
|
||||
if (in->mask & EFFECT_CONFIG_FORMAT) {
|
||||
out->mask |= EFFECT_CONFIG_FORMAT;
|
||||
out->format = in->format;
|
||||
}
|
||||
|
||||
if (in->mask & EFFECT_CONFIG_ACC_MODE) {
|
||||
out->mask |= EFFECT_CONFIG_ACC_MODE;
|
||||
out->accessMode = in->accessMode;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void host2hexagon(effect_config_t *in, hexagon_effect_config_t *out) {
|
||||
memset(out, 0, sizeof(*out));
|
||||
host2hexagon(&in->inputCfg, &out->inputCfg);
|
||||
host2hexagon(&in->outputCfg, &out->outputCfg);
|
||||
}
|
||||
|
||||
static inline void hexagon2host(hexagon_buffer_config_t *in, buffer_config_t *out) {
|
||||
if (in->mask & EFFECT_CONFIG_SMP_RATE) {
|
||||
out->mask |= EFFECT_CONFIG_SMP_RATE;
|
||||
out->samplingRate = in->samplingRate;
|
||||
}
|
||||
|
||||
if (in->mask & EFFECT_CONFIG_CHANNELS) {
|
||||
out->mask |= EFFECT_CONFIG_CHANNELS;
|
||||
out->channels = in->channels;
|
||||
}
|
||||
|
||||
if (in->mask & EFFECT_CONFIG_FORMAT) {
|
||||
out->mask |= EFFECT_CONFIG_FORMAT;
|
||||
out->format = in->format;
|
||||
}
|
||||
|
||||
if (in->mask & EFFECT_CONFIG_ACC_MODE) {
|
||||
out->mask |= EFFECT_CONFIG_ACC_MODE;
|
||||
out->accessMode = in->accessMode;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hexagon2host(hexagon_effect_config_t *in, effect_config_t *out) {
|
||||
memset(out, 0, sizeof(*out));
|
||||
hexagon2host(&in->inputCfg, &out->inputCfg);
|
||||
hexagon2host(&in->outputCfg, &out->outputCfg);
|
||||
}
|
9
src/include/v4a.idl
Normal file
9
src/include/v4a.idl
Normal file
@ -0,0 +1,9 @@
|
||||
#include "AEEStdDef.idl"
|
||||
#include "remote.idl"
|
||||
|
||||
const string IDL_VERSION = "1.0.0";
|
||||
|
||||
interface v4a : remote_handle64 {
|
||||
int32_t command(in uint32_t cmdCode, in sequence<uint8_t> cmdData, inrout sequence<uint8_t> replyData, inrout uint32_t replySize);
|
||||
int32_t process(in sequence<uint8_t> inPcm, rout sequence<uint8_t> outPcm, in uint32_t frameCount);
|
||||
};
|
20
src/log.h
20
src/log.h
@ -1,9 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#define TAG "ViPER4Android"
|
||||
|
||||
#ifdef __hexagon__
|
||||
#define FARF_HIGH 1
|
||||
#define FARF_MEDIUM 1
|
||||
#define FARF_ERROR 1
|
||||
#define FARF_LOW 1
|
||||
#include <HAP_farf.h>
|
||||
|
||||
#define VIPER_LOGF(...) FARF(FATAL, TAG ": " __VA_ARGS__)
|
||||
#define VIPER_LOGD(...) FARF(LOW, TAG ": " __VA_ARGS__)
|
||||
#define VIPER_LOGI(...) FARF(MEDIUM, TAG ": " __VA_ARGS__)
|
||||
#define VIPER_LOGE(...) FARF(ERROR, TAG ": " __VA_ARGS__)
|
||||
#else
|
||||
#include <android/log.h>
|
||||
|
||||
#define VIPER_LOGF(...) __android_log_print(ANDROID_LOG_FATAL, TAG, __VA_ARGS__)
|
||||
#define VIPER_LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
|
||||
#define VIPER_LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
|
||||
#define VIPER_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
|
||||
#define VIPER_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
|
||||
#endif
|
||||
|
9
src/version.c
Normal file
9
src/version.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "version_note.h"
|
||||
|
||||
const lib_ver_note_t so_ver __attribute__ ((section (".note.lib.ver")))
|
||||
__attribute__ ((visibility ("default"))) = {
|
||||
100,
|
||||
0,
|
||||
0,
|
||||
"lib.ver.1.0.0.libv4a_skel.so:1.0.0",
|
||||
};
|
@ -8,12 +8,17 @@
|
||||
|
||||
#include "../log.h" // TODO: Remove this dependency
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
enum class Architecture : uint8_t {
|
||||
UNKNOWN = 0,
|
||||
ARM,
|
||||
ARM64,
|
||||
X86,
|
||||
X86_64,
|
||||
HEXAGON,
|
||||
};
|
||||
|
||||
#if defined(__arm__)
|
||||
@ -24,6 +29,8 @@ enum class Architecture : uint8_t {
|
||||
#define VIPER_ARCHITECTURE Architecture::X86
|
||||
#elif defined(__x86_64__)
|
||||
#define VIPER_ARCHITECTURE Architecture::X86_64
|
||||
#elif defined(__hexagon__)
|
||||
#define VIPER_ARCHITECTURE Architecture::HEXAGON
|
||||
#else
|
||||
#warning "Unknown architecture"
|
||||
#define VIPER_ARCHITECTURE Architecture::UNKNOWN
|
||||
@ -37,4 +44,4 @@ enum class Architecture : uint8_t {
|
||||
|
||||
#define VIPER_NAME "ViPER4Android"
|
||||
#define VIPER_AUTHORS "viper.WYF, Martmists, Iscle"
|
||||
#define VIPER_DEFAULT_SAMPLING_RATE 44100
|
||||
#define VIPER_DEFAULT_SAMPLING_RATE 44100
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "Biquad.h"
|
||||
#include "../constants.h"
|
||||
#include <cmath>
|
||||
|
||||
// Iscle: Verified with the latest version at 13/12/2022
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "HighShelf.h"
|
||||
#include "../constants.h"
|
||||
#include <cmath>
|
||||
|
||||
double HighShelf::Process(double sample) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <cmath>
|
||||
#include "IIR_1st.h"
|
||||
#include "../constants.h"
|
||||
|
||||
// Seems to be taken from https://github.com/michaelwillis/dragonfly-reverb/blob/master/common/freeverb/efilter.cpp
|
||||
// Or similar sources
|
||||
@ -146,4 +147,4 @@ void IIR_1st::setZeroLPF(float frequency, uint32_t samplingRate) {
|
||||
this->a1 = 0.f;
|
||||
this->b0 = 1.f / (1.f + coeff);
|
||||
this->b1 = coeff / (1.f + coeff);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "MultiBiquad.h"
|
||||
#include "../constants.h"
|
||||
#include <cmath>
|
||||
|
||||
MultiBiquad::MultiBiquad() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user