summaryrefslogtreecommitdiff
authorjiejing.wang <jiejing.wang@amlogic.com>2019-08-07 06:11:18 (GMT)
committer jiejing.wang <jiejing.wang@amlogic.com>2019-08-21 03:41:19 (GMT)
commitd2a5bfeb8e42535717bf71eedec7f0b3208d0549 (patch)
tree7ec111887ee5548936f55145b8dab6ab85d19707
parent207cf97ee887ba820dcb9c0a02c525f65b590e62 (diff)
downloadav-d2a5bfeb8e42535717bf71eedec7f0b3208d0549.zip
av-d2a5bfeb8e42535717bf71eedec7f0b3208d0549.tar.gz
av-d2a5bfeb8e42535717bf71eedec7f0b3208d0549.tar.bz2
audio: effect: add dbx function [2/2]
PD#SWPL-11360 Problem: without function dbx Solution: add dbx function Verify: verify by marconi Change-Id: I6c28b77168aa7594d95aa6c8cfb3a406a8052cb9 Signed-off-by: jiejing.wang <jiejing.wang@amlogic.com>
Diffstat
-rw-r--r--libaudioeffect/DBX/Android.mk36
-rw-r--r--libaudioeffect/DBX/dbx.cpp638
-rw-r--r--libaudioeffect/DBX/dbx.h24
-rw-r--r--libaudioeffect/effects_tool/main.cpp95
4 files changed, 786 insertions, 7 deletions
diff --git a/libaudioeffect/DBX/Android.mk b/libaudioeffect/DBX/Android.mk
new file mode 100644
index 0000000..b02c0a4
--- a/dev/null
+++ b/libaudioeffect/DBX/Android.mk
@@ -0,0 +1,36 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_MODULE := libdbx
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libdl \
+ libutils \
+ libamaudioutils
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH) \
+ hardware/amlogic/audio/utils/ini/include \
+ hardware/libhardware/include/hardware \
+ hardware/libhardware/include \
+ system/media/audio/include
+
+LOCAL_SRC_FILES := dbx.cpp
+
+LOCAL_CFLAGS += -O2
+
+LOCAL_LDLIBS += -llog
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
+LOCAL_PROPRIETARY_MODULE := true
+endif
+
+LOCAL_MODULE_RELATIVE_PATH := soundfx
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/libaudioeffect/DBX/dbx.cpp b/libaudioeffect/DBX/dbx.cpp
new file mode 100644
index 0000000..7106922
--- a/dev/null
+++ b/libaudioeffect/DBX/dbx.cpp
@@ -0,0 +1,638 @@
+/*
+ * Copyright (C) 2018 Amlogic Corporation.
+ *
+ * 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.
+ *
+ * DESCRIPTION:
+ * This file implements a DBX_TV effect.
+ *
+ */
+
+#define LOG_TAG "DBX_Effect"
+//#define LOG_NDEBUG 0
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <utils/Log.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <hardware/audio_effect.h>
+#include <cutils/properties.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "IniParser.h"
+#include "dbx.h"
+
+extern "C" {
+
+#define MODEL_SUM_DEFAULT_PATH "/vendor/etc/tvconfig/model/model_sum.ini"
+#define AUDIO_EFFECT_DEFAULT_PATH "/vendor/etc/tvconfig/audio/AMLOGIC_AUDIO_EFFECT_DEFAULT.ini"
+#define BUFFSIZE (1024)
+
+#if defined(__LP64__)
+#define LIBVX_PATH_A "/vendor/lib64/soundfx/libdbx_tv.so"
+#else
+#define LIBVX_PATH_A "/vendor/lib/soundfx/libdbx_tv.so"
+#endif
+
+const char *DBXStatusstr[] = {"Disable", "Enable"};
+
+// effect_handle_t interface implementation for DBX effectextern
+extern const struct effect_interface_s DBXInterface;
+
+//DBXTV effect TYPE: a41cedc0-578e-11e5-9cb0-0002a5d5c51b
+//DBXTV effect UUID: 07210842-7432-4624-8b97-35ac8782efa3
+
+const effect_descriptor_t DBXDescriptor = {
+ {0xa41cedc0, 0x578e, 0x11e5, 0x9cb0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
+ {0x07210842, 0x7432, 0x4624, 0x8b97, {0x35, 0xac, 0x87, 0x82, 0xef, 0xa3}}, // uuid
+ EFFECT_CONTROL_API_VERSION,
+ EFFECT_FLAG_TYPE_POST_PROC | EFFECT_FLAG_DEVICE_IND | EFFECT_FLAG_NO_PROCESS | EFFECT_FLAG_OFFLOAD_SUPPORTED,
+ DBX_CUP_LOAD_ARM9E,
+ DBX_MEM_USAGE,
+ "DBX",
+ "THAT Corporation",
+};
+
+enum DBX_state_e {
+ DBX_STATE_UNINITIALIZED,
+ DBX_STATE_INITIALIZED,
+ DBX_STATE_ACTIVE,
+};
+
+typedef struct DBXapi_s {
+ int (*DBX_init)(void*);
+ int (*DBX_release)(void);
+ int (*DBX_process)(int32_t *leftin, int32_t *rightin, int32_t *leftout, int32_t *rightout, int framecount);
+ int (*DBX_setParameter)(int son_mode, int vol_mode, int sur_mode);
+} DBxapi;
+
+typedef enum {
+ DBX_PARAM_ENABLE = 0,
+ DBX_SET_MODE = 1,
+} DBXparams;
+
+typedef struct DBXmode_8bit_s {
+ signed char son_mode;
+ signed char vol_mode;
+ signed char sur_mode;
+} DBXmode_8bit;
+
+typedef struct DBXmode_s {
+ int son_mode;
+ int vol_mode;
+ int sur_mode;
+} DBXmode;
+
+typedef struct DBXdata_s {
+ int enable;
+ DBXmode mode;
+} DBXdata;
+
+typedef struct DBXContext_s {
+ const struct effect_interface_s *itfe;
+ effect_config_t config;
+ DBX_state_e state;
+ void *gDBXLibHandler;
+ DBxapi gDBXapi;
+ DBXdata gDBXdata;
+ int32_t *aiLeftA;
+ int32_t *aiRightA;
+ int32_t *aiLeftB;
+ int32_t *aiRightB;
+} DBXContext;
+
+int DBX_get_model_name(char *model_name, int size)
+{
+ int ret = -1;
+ char node[PROPERTY_VALUE_MAX];
+
+ ret = property_get("tv.model_name", node, NULL);
+
+ if (ret < 0)
+ snprintf(model_name, size, "DEFAULT");
+ else
+ snprintf(model_name, size, "%s", node);
+ ALOGD("%s: Model Name -> %s", __FUNCTION__, model_name);
+ return ret;
+}
+
+int DBX_get_ini_file(char *ini_name, int size)
+{
+ int result = -1;
+ char model_name[50] = {0};
+ IniParser* pIniParser = NULL;
+ const char *ini_value = NULL;
+ const char *filename = MODEL_SUM_DEFAULT_PATH;
+
+ DBX_get_model_name(model_name, sizeof(model_name));
+ pIniParser = new IniParser();
+ if (pIniParser->parse(filename) < 0) {
+ ALOGW("%s: Load INI file -> %s Failed", __FUNCTION__, filename);
+ goto exit;
+ }
+
+ ini_value = pIniParser->GetString(model_name, "AMLOGIC_AUDIO_EFFECT_INI_PATH", AUDIO_EFFECT_DEFAULT_PATH);
+ if (ini_value == NULL || access(ini_value, F_OK) == -1) {
+ ALOGD("%s: INI File is not exist", __FUNCTION__);
+ goto exit;
+ }
+ ALOGD("%s: INI File -> %s", __FUNCTION__, ini_value);
+ strncpy(ini_name, ini_value, size);
+
+ result = 0;
+exit:
+ delete pIniParser;
+ pIniParser = NULL;
+ return result;
+}
+
+int DBX_load_ini_file(DBXContext *pContext)
+{
+ int result = -1;
+ char ini_name[100] = {0};
+ const char *ini_value = NULL;
+ char *Rch = NULL;
+ DBXdata *data = &pContext->gDBXdata;
+ IniParser* pIniParser = NULL;
+
+ if (DBX_get_ini_file(ini_name, sizeof(ini_name)) < 0)
+ goto error;
+
+ pIniParser = new IniParser();
+ if (pIniParser->parse((const char *)ini_name) < 0) {
+ ALOGD("%s: %s load failed", __FUNCTION__, ini_name);
+ goto error;
+ }
+
+ ini_value = pIniParser->GetString("DBX", "enable", "1");
+ if (ini_value == NULL)
+ goto error;
+ ALOGD("%s: enable -> %s", __FUNCTION__, ini_value);
+ data->enable = atoi(ini_value);
+
+ ini_value = pIniParser->GetString("DBX", "mode", "NULL");
+ if (ini_value == NULL)
+ goto error;
+ Rch = (char *)ini_value;
+ Rch = strtok(Rch, ",");
+ if (Rch == NULL) {
+ goto error;
+ }
+ data->mode.son_mode= atoi(Rch);
+ ALOGD("sonics mode is %d",data->mode.son_mode);
+ Rch = strtok(NULL, ",");
+ if (Rch == NULL) {
+ goto error;
+ }
+ data->mode.vol_mode = atoi(Rch);
+ ALOGD("volume mode is %d",data->mode.vol_mode);
+ Rch = strtok(NULL, ",");
+ if (Rch == NULL) {
+ goto error;
+ }
+ data->mode.sur_mode = atoi(Rch);
+ ALOGD("surround mode is %d",data->mode.sur_mode);
+ result = 0;
+error:
+ ALOGD("%s: %s", __FUNCTION__, result == 0 ? "sucessful" : "failed");
+ delete pIniParser;
+ pIniParser = NULL;
+ return result;
+}
+
+int DBX_load_lib(DBXContext *pContext)
+{
+ pContext->gDBXLibHandler = dlopen(LIBVX_PATH_A, RTLD_NOW);
+ if (!pContext->gDBXLibHandler) {
+ ALOGE("%s: failed", __FUNCTION__);
+ return -EINVAL;
+ }
+ pContext->gDBXapi.DBX_init = (int (*)(void*))dlsym(pContext->gDBXLibHandler, "DBXTV_init_api");
+ if (!pContext->gDBXapi.DBX_init) {
+ ALOGE("%s: find func DBX_init() failed\n", __FUNCTION__);
+ goto Error;
+ }
+ pContext->gDBXapi.DBX_process = (int (*)(int32_t*,int32_t*,int32_t*,int32_t*,int))dlsym(pContext->gDBXLibHandler, "DBXTV_process_api");
+ if (!pContext->gDBXapi.DBX_process) {
+ ALOGE("%s: find func DBX_process() failed\n", __FUNCTION__);
+ goto Error;
+ }
+ pContext->gDBXapi.DBX_setParameter = (int (*)(int,int,int))dlsym(pContext->gDBXLibHandler, "DBXTV_setParameter_api");
+ if (!pContext->gDBXapi.DBX_setParameter) {
+ ALOGE("%s: find func DBX_setParameter() failed\n", __FUNCTION__);
+ goto Error;
+ }
+ pContext->gDBXapi.DBX_release = (int (*)(void))dlsym(pContext->gDBXLibHandler, "DBXTV_release_api");
+ if (!pContext->gDBXapi.DBX_release) {
+ ALOGE("%s: find func DBX_release() failed\n", __FUNCTION__);
+ goto Error;
+ }
+ ALOGD("%s: sucessful", __FUNCTION__);
+ return 0;
+Error:
+ memset(&pContext->gDBXapi, 0, sizeof(pContext->gDBXapi));
+ dlclose(pContext->gDBXLibHandler);
+ pContext->gDBXLibHandler = NULL;
+ return -EINVAL;
+}
+
+int unload_DBX_lib(DBXContext *pContext)
+{
+ memset(&pContext->gDBXapi, 0, sizeof(pContext->gDBXapi));
+ if (pContext->gDBXLibHandler) {
+ dlclose(pContext->gDBXLibHandler);
+ pContext->gDBXLibHandler = NULL;
+ }
+ return 0;
+}
+
+int DBX_init(DBXContext *pContext)
+{
+ DBXdata *data = &pContext->gDBXdata;
+
+ pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
+ pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+ pContext->config.inputCfg.samplingRate = 48000;
+ pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
+ pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
+ pContext->config.inputCfg.bufferProvider.cookie = NULL;
+ pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
+ pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
+ pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+ pContext->config.outputCfg.samplingRate = 48000;
+ pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
+ pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
+ pContext->config.outputCfg.bufferProvider.cookie = NULL;
+ pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
+
+ pContext->aiLeftA = (int32_t *)malloc(sizeof(int32_t) * BUFFSIZE * 4);
+ pContext->aiLeftB = (int32_t *)malloc(sizeof(int32_t) * BUFFSIZE * 4);
+ pContext->aiRightA = (int32_t *)malloc(sizeof(int32_t) * BUFFSIZE * 4);
+ pContext->aiRightB = (int32_t *)malloc(sizeof(int32_t) * BUFFSIZE * 4);
+
+ if (pContext->aiLeftA == NULL || pContext->aiLeftB == NULL ||
+ pContext->aiRightA == NULL || pContext->aiRightB == NULL) {
+ ALOGE("Malloc temp buffer failed !\n");
+ return -EINVAL;
+ }
+
+ if (pContext->gDBXLibHandler) {
+ (*pContext->gDBXapi.DBX_init)((void*) data);
+ }
+ ALOGD("%s: sucessful", __FUNCTION__);
+
+ return 0;
+}
+
+int DBX_configure(DBXContext *pContext, effect_config_t *pConfig)
+{
+ if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate)
+ return -EINVAL;
+ if (pConfig->inputCfg.channels != pConfig->outputCfg.channels)
+ return -EINVAL;
+ if (pConfig->inputCfg.format != pConfig->outputCfg.format)
+ return -EINVAL;
+ if (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) {
+ ALOGW("%s: channels in = 0x%x channels out = 0x%x", __FUNCTION__, pConfig->inputCfg.channels, pConfig->outputCfg.channels);
+ pConfig->inputCfg.channels = pConfig->outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ }
+ if (pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_WRITE &&
+ pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE)
+ return -EINVAL;
+ if (pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
+ ALOGW("%s: format in = 0x%x format out = 0x%x", __FUNCTION__, pConfig->inputCfg.format, pConfig->outputCfg.format);
+ pConfig->inputCfg.format = pConfig->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+ }
+
+ memcpy(&pContext->config, pConfig, sizeof(effect_config_t));
+
+ return 0;
+}
+
+int DBX_getParameter(DBXContext *pContext, void *pParam, size_t *pValueSize,void *pValue) {
+ int32_t param = *(int32_t *)pParam;
+ int32_t value;
+ DBXdata *data = &pContext->gDBXdata;
+ DBXmode_8bit cfg_8bit;
+ switch (param) {
+ case DBX_PARAM_ENABLE:
+ if (*pValueSize < sizeof(int32_t)) {
+ *pValueSize = 0;
+ return -EINVAL;
+ }
+ value = data->enable;
+ *(int32_t *) pValue = value;
+ ALOGD("%s: Get status -> %s", __FUNCTION__, DBXStatusstr[value]);
+ break;
+ case DBX_SET_MODE:
+ if (*pValueSize < sizeof(DBXmode)) {
+ *pValueSize = 0;
+ return -EINVAL;
+ }
+ cfg_8bit.son_mode = (signed char)data->mode.son_mode;
+ cfg_8bit.sur_mode = (signed char)data->mode.sur_mode;
+ cfg_8bit.vol_mode = (signed char)data->mode.vol_mode;
+ *(DBXmode_8bit *) pValue = cfg_8bit;
+ break;
+ default:
+ ALOGE("%s: unknown param %d", __FUNCTION__, param);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int DBX_setParameter(DBXContext *pContext, void *pParam, void *pValue) {
+ int32_t param = *(int32_t *)pParam;
+ int32_t value;
+ DBXmode_8bit modecfg_8bit;
+ DBXdata *data = &pContext->gDBXdata;
+
+ switch (param) {
+ case DBX_PARAM_ENABLE:
+ if (!pContext->gDBXLibHandler) {
+ return 0;
+ }
+ value = *(int32_t *)pValue;
+ data->enable = value;
+ ALOGD("%s: Set status -> %s", __FUNCTION__, DBXStatusstr[value]);
+ break;
+ case DBX_SET_MODE:
+ if (!pContext->gDBXLibHandler) {
+ return 0;
+ }
+ modecfg_8bit = *(DBXmode_8bit *)pValue;
+ data->mode.son_mode = (signed int)modecfg_8bit.son_mode;
+ data->mode.vol_mode = (signed int)modecfg_8bit.vol_mode;
+ data->mode.sur_mode = (signed int)modecfg_8bit.sur_mode;
+ ALOGD("son_mode is %d,vol_mode is %d,sur_mode is %d",data->mode.son_mode,data->mode.vol_mode,data->mode.sur_mode);
+ if (data->mode.son_mode > 4 || data->mode.vol_mode > 2 || data->mode.sur_mode > 2) {
+ ALOGE("parameter exceed the range\n");
+ return -EINVAL;
+ }
+ (*pContext->gDBXapi.DBX_setParameter)(data->mode.son_mode, data->mode.vol_mode, data->mode.sur_mode);
+ break;
+ default:
+ ALOGE("%s: unknown param %08x", __FUNCTION__, param);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int DBX_release(DBXContext *pContext)
+{
+ if (pContext->aiLeftA != NULL || pContext->aiLeftB != NULL ||
+ pContext->aiRightA != NULL || pContext->aiRightB != NULL){
+ free(pContext->aiLeftA);
+ pContext->aiLeftA = NULL;
+ free(pContext->aiLeftB);
+ pContext->aiLeftB = NULL;
+ free(pContext->aiRightA);
+ pContext->aiRightA = NULL;
+ free(pContext->aiRightB);
+ pContext->aiRightB = NULL;
+ }
+ if (pContext->gDBXLibHandler) {
+ (*pContext->gDBXapi.DBX_release)();
+ }
+ return 0;
+}
+
+int DBX_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
+{
+ DBXContext *pContext = (DBXContext *)self;
+ if (pContext == NULL)
+ return -EINVAL;
+
+ if (inBuffer == NULL || inBuffer->raw == NULL ||
+ outBuffer == NULL || outBuffer->raw == NULL ||
+ inBuffer->frameCount != outBuffer->frameCount ||
+ inBuffer->frameCount == 0)
+ return -EINVAL;
+
+ if (pContext->state != DBX_STATE_ACTIVE)
+ return -ENODATA;
+
+ int16_t *in = (int16_t *)inBuffer->raw;
+ int16_t *out = (int16_t *)outBuffer->raw;
+ DBXdata *data = &pContext->gDBXdata;
+ if (!data->enable || !pContext->gDBXLibHandler) {
+ for (size_t i = 0; i < inBuffer->frameCount; i++) {
+ *out++ = *in++;
+ *out++ = *in++;
+ }
+ } else {
+ for (size_t i = 0; i < inBuffer->frameCount; i++) {
+ pContext->aiLeftA[i] = ((int32_t)in[i*2]) << 16;
+ pContext->aiRightA[i] = ((int32_t)in[i*2+1]) << 16;
+ }
+ (*pContext->gDBXapi.DBX_process)(pContext->aiLeftA, pContext->aiRightA, pContext->aiLeftB,
+ pContext->aiRightB, inBuffer->frameCount);
+ for (size_t i = 0; i < inBuffer->frameCount; i++) {
+ out[i*2] = (int16_t)(pContext->aiLeftB[i] >> 16);
+ out[i*2+1] = (int16_t)(pContext->aiRightB[i] >> 16);
+ }
+ }
+ return 0;
+}
+
+int DBX_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
+ void *pCmdData, uint32_t *replySize, void *pReplyData)
+{
+ DBXContext * pContext = (DBXContext *)self;
+ effect_param_t *p;
+ int voffset;
+ ALOGD("%s: cmd = %u", __FUNCTION__, cmdCode);
+ if (pContext == NULL || pContext->state == DBX_STATE_UNINITIALIZED)
+ return -EINVAL;
+ switch (cmdCode) {
+ case EFFECT_CMD_INIT:
+ if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int))
+ return -EINVAL;
+ *(int *) pReplyData = DBX_init(pContext);
+ break;
+ case EFFECT_CMD_SET_CONFIG:
+ if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || pReplyData == NULL || replySize == NULL || *replySize != sizeof(int))
+ return -EINVAL;
+ *(int *) pReplyData = DBX_configure(pContext,(effect_config_t *) pCmdData);
+ break;
+ case EFFECT_CMD_RESET:
+ //SRS_reset(pContext);
+ break;
+ case EFFECT_CMD_ENABLE:
+ if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int))
+ return -EINVAL;
+ if (pContext->state != DBX_STATE_INITIALIZED)
+ return -ENOSYS;
+ pContext->state = DBX_STATE_ACTIVE;
+ *(int *)pReplyData = 0;
+ break;
+ case EFFECT_CMD_DISABLE:
+ if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int))
+ return -EINVAL;
+ if (pContext->state != DBX_STATE_ACTIVE)
+ return -ENOSYS;
+ pContext->state = DBX_STATE_INITIALIZED;
+ *(int *)pReplyData = 0;
+ break;
+ case EFFECT_CMD_GET_PARAM:
+ if (pCmdData == NULL ||
+ cmdSize != (int)(sizeof(effect_param_t) + sizeof(uint32_t)+sizeof(uint32_t)) ||
+ pReplyData == NULL || replySize == NULL ||
+ (*replySize < (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint32_t)) &&
+ *replySize < (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(DBXmode_8bit_s))))
+ return -EINVAL;
+ p = (effect_param_t *)pCmdData;
+ memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
+ p = (effect_param_t *)pReplyData;
+
+ voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
+
+ p->status = DBX_getParameter(pContext, p->data, (size_t *)&p->vsize, p->data + voffset);
+ *replySize = sizeof(effect_param_t) + voffset + p->vsize;
+ break;
+ case EFFECT_CMD_SET_PARAM:
+ if (pCmdData == NULL ||
+ (cmdSize != (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint32_t)) &&
+ cmdSize != (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(DBXmode_8bit_s)))||
+ pReplyData == NULL || replySize == NULL || *replySize != sizeof(int32_t))
+ return -EINVAL;
+ p = (effect_param_t *)pCmdData;
+ if (p->psize != sizeof(uint32_t) && p->vsize != sizeof(DBXmode_8bit_s)) {
+ *(int32_t *)pReplyData = -EINVAL;
+ break;
+ }
+ *(int *)pReplyData = DBX_setParameter(pContext, (void *)p->data, p->data + p->psize);
+ break;
+ case EFFECT_CMD_OFFLOAD:
+ *(int *)pReplyData = 0;
+ break;
+ case EFFECT_CMD_SET_DEVICE:
+ case EFFECT_CMD_SET_VOLUME:
+ case EFFECT_CMD_SET_AUDIO_MODE:
+ break;
+ default:
+ ALOGE("%s: invalid command %d", __FUNCTION__, cmdCode);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int DBX_getDescriptor(effect_handle_t self, effect_descriptor_t *pDescriptor)
+{
+ DBXContext * pContext = (DBXContext *) self;
+
+ if (pContext == NULL || pDescriptor == NULL) {
+ ALOGE("%s: invalid param", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ *pDescriptor = DBXDescriptor;
+
+ return 0;
+}
+//-------------------- Effect Library Interface Implementation------------------------
+
+int DBXLib_Create(const effect_uuid_t *uuid, int32_t sessionId __unused, int32_t ioId __unused, effect_handle_t *pHandle)
+{
+ if (pHandle == NULL || uuid == NULL)
+ return -EINVAL;
+
+ if (memcmp(uuid, &DBXDescriptor.uuid, sizeof(effect_uuid_t)) != 0)
+ return -EINVAL;
+
+ DBXContext *pContext = new DBXContext;
+ if (!pContext) {
+ ALOGE("%s: alloc DBXContext failed", __FUNCTION__);
+ return -EINVAL;
+ }
+ memset(pContext, 0, sizeof(DBXContext));
+
+ if (DBX_load_ini_file(pContext) < 0) {
+ ALOGE("%s: Load INI File faied, use default param", __FUNCTION__);
+ pContext->gDBXdata.enable = 1;
+ }
+
+ if (DBX_load_lib(pContext) < 0) {
+ ALOGE("%s: Load Library File faied", __FUNCTION__);
+ }
+
+ pContext->itfe = &DBXInterface;
+ pContext->state = DBX_STATE_UNINITIALIZED;
+
+ *pHandle = (effect_handle_t)pContext;
+
+ pContext->state = DBX_STATE_INITIALIZED;
+
+ ALOGD("%s: %p", __FUNCTION__, pContext);
+
+ return 0;
+}
+
+int DBXLib_Release(effect_handle_t handle)
+{
+ DBXContext * pContext = (DBXContext *)handle;
+ if (pContext == NULL)
+ return -EINVAL;
+
+ DBX_release(pContext);
+ unload_DBX_lib(pContext);
+ pContext->state = DBX_STATE_UNINITIALIZED;
+
+ delete pContext;
+ ALOGD("DBXLib_Release");
+ return 0;
+}
+
+int DBXLib_GetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor)
+{
+ if (pDescriptor == NULL || uuid == NULL) {
+ ALOGE("%s: called with NULL pointer", __FUNCTION__);
+ return -EINVAL;
+ }
+ if (memcmp(uuid, &DBXDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
+ *pDescriptor = DBXDescriptor;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+// effect_handle_t interface implementation for DBX effect
+const struct effect_interface_s DBXInterface = {
+ DBX_process,
+ DBX_command,
+ DBX_getDescriptor,
+ NULL,
+};
+
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "DBX",
+ .implementor = "THAT Corporation",
+ .create_effect = DBXLib_Create,
+ .release_effect = DBXLib_Release,
+ .get_descriptor = DBXLib_GetDescriptor,
+};
+
+};//extern c \ No newline at end of file
diff --git a/libaudioeffect/DBX/dbx.h b/libaudioeffect/DBX/dbx.h
new file mode 100644
index 0000000..0144e6f
--- a/dev/null
+++ b/libaudioeffect/DBX/dbx.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#ifndef ANDROID_DBX_H_
+#define ANDROID_DBX_H_
+
+#define DBX_CUP_LOAD_ARM9E 100 //Expressed in 0.1 MIPS
+#define DBX_MEM_USAGE 50 // Expressed in kB
+
+#endif
+
diff --git a/libaudioeffect/effects_tool/main.cpp b/libaudioeffect/effects_tool/main.cpp
index 2b8894d..cfa1e31 100644
--- a/libaudioeffect/effects_tool/main.cpp
+++ b/libaudioeffect/effects_tool/main.cpp
@@ -418,6 +418,28 @@ Avl_param_t gAvlParam[] = {
const char *AvlStatusstr[] = {"Disable", "Enable"};
+//-------------DBX parameters--------------------------
+typedef struct dbxtv_param_s {
+ effect_param_t param;
+ uint32_t command;
+ union {
+ uint32_t v;
+ signed char mode[3];
+ };
+} dbxtv_param_t;
+
+typedef enum {
+ DBX_PARAM_ENABLE,
+ DBX_SET_MODE,
+} DBXparams;
+
+dbxtv_param_t gdbxtvparam[] = {
+ {{0, 4, 4}, DBX_PARAM_ENABLE, {1}},
+ {{0, 4, 4}, DBX_SET_MODE, {0}},
+};
+
+const char *DBXStatusstr[] = {"Disable", "Enable"};
+
//-------UUID------------------------------------------
typedef enum {
EFFECT_BALANCE = 0,
@@ -427,6 +449,7 @@ typedef enum {
EFFECT_AVL,
EFFECT_GEQ,
EFFECT_VIRTUALX,
+ EFFECT_DBX,
EFFECT_MAX,
} EFFECT_params;
@@ -438,6 +461,7 @@ effect_uuid_t gEffectStr[] = {
{0x08246a2a, 0xb2d3, 0x4621, 0xb804, {0x42, 0xc9, 0xb4, 0x78, 0xeb, 0x9d}}, // 4:Avl
{0x2e2a5fa6, 0xcae8, 0x45f5, 0xbb70, {0xa2, 0x9c, 0x1f, 0x30, 0x74, 0xb2}}, // 5:Geq
{0x61821587, 0xce3c, 0x4aac, 0x9122, {0x86, 0xd8, 0x74, 0xea, 0x1f, 0xb1}}, // 6:Virtualx
+ {0x07210842, 0x7432, 0x4624, 0x8b97, {0x35, 0xac, 0x87, 0x82, 0xef, 0xa3}}, // 7:DBX
};
static inline float DbToAmpl(float decibels)
@@ -1551,6 +1575,34 @@ static int HPEQ_effect_func(AudioEffect* gAudioEffect, int gParamIndex, int gPar
}
}
+static int DBX_effect_func(AudioEffect* gAudioEffect, int gParamIndex, int gParamValue, signed char gMode[3])
+{
+ int rc = 0;
+ switch (gParamIndex) {
+ case DBX_PARAM_ENABLE:
+ if (gParamValue < 0 || gParamValue > 1) {
+ LOG("DBX: Status gParamValue = %d invalid\n", gParamValue);
+ return -1;
+ }
+ gdbxtvparam[gParamIndex].v = gParamValue;
+ gAudioEffect->setParameter(&gdbxtvparam[gParamIndex].param);
+ LOG("DBX: Status is %d -> %s\n", gParamValue, DBXStatusstr[gdbxtvparam[gParamIndex].v]);
+ return 0;
+ case DBX_SET_MODE:
+ gdbxtvparam[gParamIndex].mode[0] = gMode[0];
+ LOG("DBX:mode[0] is %d\n",gdbxtvparam[gParamIndex].mode[0]);
+ gdbxtvparam[gParamIndex].mode[1] = gMode[1];
+ LOG("DBX:mode[1] is %d\n",gdbxtvparam[gParamIndex].mode[1]);
+ gdbxtvparam[gParamIndex].mode[2] = gMode[2];
+ LOG("DBX:mode[2] is %d\n",gdbxtvparam[gParamIndex].mode[2]);
+ rc = gAudioEffect->setParameter(&gdbxtvparam[gParamIndex].param);
+ LOG("rc is %d\n",rc);
+ return 0;
+ default:
+ LOG("DBX: ParamIndex = %d invalid\n", gParamIndex);
+ return -1;
+ }
+}
static int GEQ_effect_func(AudioEffect* gAudioEffect, int gParamIndex, int gParamValue, signed char gParamBands[9])
{
switch (gParamIndex) {
@@ -1731,11 +1783,12 @@ int main(int argc,char **argv)
int gParamIndex = 0;
int gParamValue = 0;
float gParamScale = 0.0f;
- signed char gParamBand[5]={0};
- signed char gParamBands[9]={0};
+ signed char gmode[3] = {0};
+ signed char gParamBand[5] = {0};
+ signed char gParamBands[9] = {0};
status_t status = NO_ERROR;
String16 name16[EFFECT_MAX] = {String16("AudioEffectEQTest"), String16("AudioEffectSRSTest"), String16("AudioEffectHPEQTest"),
- String16("AudioEffectAVLTest"), String16("AudioEffectGEQTest"),String16("AudioEffectVirtualxTest")};
+ String16("AudioEffectAVLTest"), String16("AudioEffectGEQTest"),String16("AudioEffectVirtualxTest"),String16("AudioEffectDBXTest")};
AudioEffect* gAudioEffect[EFFECT_MAX] = {0};
audio_session_t gSessionId = AUDIO_SESSION_OUTPUT_MIX;
LOG("**********************************Balance***********************************\n");
@@ -1974,7 +2027,16 @@ int main(int argc,char **argv)
LOG("ParamIndex: 73 -> mbhl frt midcross\n");
LOG("ParamScale 40 ~ 8000\n");
LOG("****************************************************************************\n\n");
- if (argc != 4 && argc != 12 && argc != 8 ) {
+
+ LOG("**********************************DBX***********************************\n");
+ LOG("EffectIndex: 7\n");
+ LOG("ParamIndex: 0 -> Enable\n");
+ LOG("ParamValue: 0 -> Disable 1 -> Enable\n");
+ LOG("ParamIndex: 1 -> Choose mode(son_mode--vol_mode--sur_mode)\n");
+ LOG("ParamValue: son_mode 0-4 vol_mode 0-2 sur_mode 0-2\n");
+ LOG("****************************************************************************\n\n");
+
+ if (argc != 4 && argc != 12 && argc != 8 && argc != 6) {
LOG("Usage: %s <EffectIndex> <ParamIndex> <ParamValue/ParamScale/gParamBand>\n", argv[0]);
return -1;
} else {
@@ -1999,12 +2061,16 @@ int main(int argc,char **argv)
sscanf(argv[9], "%d", &gParamBands[6]);
sscanf(argv[10], "%d", &gParamBands[7]);
sscanf(argv[11], "%d", &gParamBands[8]);
- } else if (gEffectIndex == 6 && ((gParamIndex >= 4 && gParamIndex <= 6) || gParamIndex == 9 || (gParamIndex >= 16 && gParamIndex <= 18)
+ } else if ((gEffectIndex == 6) && ((gParamIndex >= 4 && gParamIndex <= 6) || gParamIndex == 9 || (gParamIndex >= 16 && gParamIndex <= 18)
||(gParamIndex >= 20 && gParamIndex <= 22) || (gParamIndex >= 24 && gParamIndex <= 30) || gParamIndex == 38 || gParamIndex == 41
|| gParamIndex == 47 || gParamIndex == 48 || gParamIndex == 53 || gParamIndex == 54 || gParamIndex == 56 || gParamIndex == 59 ||
gParamIndex == 60 || gParamIndex == 62 || gParamIndex == 64) || (gParamIndex >= 70 && gParamIndex <= 73)) {
sscanf(argv[3], "%f", &gParamScale);
- } else
+ } else if (gEffectIndex == 7 && gParamIndex == 1) {
+ sscanf(argv[3], "%d", &gmode[0]);
+ sscanf(argv[4], "%d", &gmode[1]);
+ sscanf(argv[5], "%d", &gmode[2]);
+ } else
sscanf(argv[3], "%d", &gParamValue);
}
if (gEffectIndex >= (int)(sizeof(gEffectStr)/sizeof(gEffectStr[0]))) {
@@ -2025,7 +2091,10 @@ int main(int argc,char **argv)
|| gParamIndex == 47 || gParamIndex == 48 || gParamIndex == 53 || gParamIndex == 54 || gParamIndex == 56 || gParamIndex == 59 ||
gParamIndex == 60 || gParamIndex == 62 || gParamIndex == 64) || (gParamIndex >= 70 && gParamIndex <= 73) )
LOG("EffectIndex:%d, ParamIndex:%d, ParamScale:%f\n", gEffectIndex, gParamIndex, gParamScale);
- else
+ else if (gEffectIndex == 7 && gParamIndex == 1) {
+ for (int i = 0; i < 3; i++)
+ LOG("EffectIndex:%d, ParamIndex:%d, ParamMode:%d\n", gEffectIndex, gParamIndex, gmode[i]);
+ } else
LOG("EffectIndex:%d, ParamIndex:%d, Paramvalue:%d\n", gEffectIndex, gParamIndex, gParamValue);
while (1) {
switch (gEffectIndex) {
@@ -2099,6 +2168,16 @@ int main(int argc,char **argv)
if (Virtualx_effect_func(gAudioEffect[gEffectIndex], gParamIndex, gParamValue,gParamScale) < 0)
LOG("Virtualx Test failed\n");
break;
+ case EFFECT_DBX:
+ ret = create_audio_effect(&gAudioEffect[EFFECT_DBX], name16[EFFECT_DBX], EFFECT_DBX);
+ if (ret < 0) {
+ LOG("create EFFECT_DBX effect failed\n");
+ goto Error;
+ }
+ //------------set DBX parameters------------------------------------------------
+ if (DBX_effect_func(gAudioEffect[gEffectIndex], gParamIndex, gParamValue,gmode) < 0)
+ LOG("DBX Test failed\n");
+ break;
default:
LOG("EffectIndex = %d invalid\n", gEffectIndex);
break;
@@ -2124,6 +2203,8 @@ int main(int argc,char **argv)
|| gParamIndex == 47 || gParamIndex == 48 || gParamIndex == 53 || gParamIndex == 54 || gParamIndex == 56 || gParamIndex == 59 ||
gParamIndex == 60 || gParamIndex == 62 || gParamIndex == 64) || (gParamIndex >= 70 && gParamIndex <= 73)) {
scanf("%f", &gParamScale);
+ } else if (gEffectIndex == 7 && gParamIndex == 1) {
+ scanf("%d %d %d",&gmode[0],&gmode[1],&gmode[2]);
} else
scanf("%d", &gParamValue);
if (gEffectIndex >= (int)(sizeof(gEffectStr)/sizeof(gEffectStr[0]))) {