author | jiejing.wang <jiejing.wang@amlogic.com> | 2019-03-06 12:07:44 (GMT) |
---|---|---|
committer | jiejing.wang <jiejing.wang@amlogic.com> | 2019-03-11 06:00:11 (GMT) |
commit | 625b4c85596d21bcb0f6625467dba2826ad06007 (patch) | |
tree | db9d6f3fc2fbf85bdca8f52fa08607d38a286a3d | |
parent | b9a74c38c54d6209bc5b0b0345a1e9222bf2d2bb (diff) | |
download | av-625b4c85596d21bcb0f6625467dba2826ad06007.zip av-625b4c85596d21bcb0f6625467dba2826ad06007.tar.gz av-625b4c85596d21bcb0f6625467dba2826ad06007.tar.bz2 |
audio: libeffects: add geq function [1/2]
PD#TV-2467
Problem:
no nine bands geq effect
Solution:
add nine bands geq effect
Verify:
verify by marconi
Change-Id: I3de9d2c93503c16cede9555782423cd9ebcd063c
Signed-off-by: jiejing.wang <jiejing.wang@amlogic.com>
-rw-r--r-- | libaudioeffect/Geq/Android.mk | 42 | ||||
-rw-r--r-- | libaudioeffect/Geq/Geq.cpp | 815 | ||||
-rw-r--r-- | libaudioeffect/Geq/Geq.h | 24 | ||||
-rw-r--r-- | libaudioeffect/Geq/libAmlGeq.a | 325 | ||||
-rw-r--r-- | libaudioeffect/Geq/libAmlGeq.h | 25 | ||||
-rw-r--r-- | libaudioeffect/Geq/libAmlGeq64.a | 413 | ||||
-rw-r--r-- | libaudioeffect/effects_tool/main.cpp | 129 |
7 files changed, 1762 insertions, 11 deletions
diff --git a/libaudioeffect/Geq/Android.mk b/libaudioeffect/Geq/Android.mk new file mode 100644 index 0000000..0dbbb56 --- a/dev/null +++ b/libaudioeffect/Geq/Android.mk @@ -0,0 +1,42 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +#LOCAL_ARM_MODE := arm + +LOCAL_MODULE:= libgeq + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libdl \ + libutils \ + libamaudioutils + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + vendor/amlogic/frameworks/av/libaudioeffect/Utility \ + hardware/amlogic/audio/utils/ini/include \ + hardware/libhardware/include/hardware \ + hardware/libhardware/include \ + system/media/audio/include + +LOCAL_SRC_FILES += Geq.cpp +LOCAL_SRC_FILES += ../Utility/AudioFade.c + +LOCAL_LDFLAGS_arm += $(LOCAL_PATH)/libAmlGeq.a +LOCAL_LDFLAGS_arm64 += $(LOCAL_PATH)/libAmlGeq64.a + +LOCAL_MULTILIB := both + +LOCAL_PRELINK_MODULE := false + +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/Geq/Geq.cpp b/libaudioeffect/Geq/Geq.cpp new file mode 100644 index 0000000..0817d59 --- a/dev/null +++ b/libaudioeffect/Geq/Geq.cpp @@ -0,0 +1,815 @@ +/* + * 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 special EQ from Amlogic. + * + */ + +#define LOG_TAG "GEQ_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 <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 "Geq.h" + +extern "C" { + +#include "libAmlGeq.h" +#include "../Utility/AudioFade.h" + +#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" + +// effect_handle_t interface implementation for 9bands EQ effect +extern const struct effect_interface_s GEQInterface; + +//GEQ effect TYPE: 5f760a9b-d058-4b2b-acc7-145a5ebff7fe +//GEQ effect UUID: 2e2a5fa6-cae8-45f5-bb70-a29c1f3074b2 + +const effect_descriptor_t GEQDescriptor = { + {0x5f760a9b, 0xd058, 0x4b2b, 0xacc7, {0x14, 0x5a, 0x5e, 0xbf, 0xf7, 0xfe}}, // type + {0x2e2a5fa6, 0xcae8, 0x45f5, 0xbb70, {0xa2, 0x9c, 0x1f, 0x30, 0x74, 0xb2}}, // uuid + EFFECT_CONTROL_API_VERSION, + EFFECT_FLAG_TYPE_POST_PROC | EFFECT_FLAG_DEVICE_IND | EFFECT_FLAG_NO_PROCESS | EFFECT_FLAG_OFFLOAD_SUPPORTED, + GEQ_CUP_LOAD_ARM9E, + GEQ_MEM_USAGE, + "Geq",//nine bands eq + "Amlogic", +}; + +enum geq_state_e { + GEQ_STATE_UNINITIALIZED, + GEQ_STATE_INITIALIZED, + GEQ_STATE_ACTIVE, +}; + +typedef enum { + GEQ_PARAM_INVALID = -1, + GEQ_PARAM_ENABLE, + GEQ_PARAM_EFFECT_MODE, + GEQ_PARAM_EFFECT_CUSTOM, +} GEQparams; + +typedef struct GEQcfg_s { + int band1; + int band2; + int band3; + int band4; + int band5; + int band6; + int band7; + int band8; + int band9; +} GEQcfg; + +typedef struct GEQcfg_8bit_s { + signed char band1; + signed char band2; + signed char band3; + signed char band4; + signed char band5; + signed char band6; + signed char band7; + signed char band8; + signed char band9; +} GEQcfg_8bit; + +typedef struct GEQdata_s { + /* This struct is used to initialize GEQ default config*/ + GEQcfg cfg; + int32_t *usr_cfg; + int32_t count; + int32_t enable; + int32_t mode; + int32_t mode_num; + int32_t band_num; +} GEQdata; + +typedef struct GEQContext_s { + const struct effect_interface_s *itfe; + effect_config_t config; + geq_state_e state; + GEQdata gGEQdata; + + // when recieve setting change from app, + //"fade audio out->do setting->fade audio In" + int bUseFade; + AudioFade_t gAudFade; + int32_t modeValue; +} GEQContext; + +const char *GEQStatusstr[] = {"Disable", "Enable"}; + +static int getprop_bool(const char *path) +{ + char buf[PROPERTY_VALUE_MAX]; + int ret = -1; + + ret = property_get(path, buf, NULL); + if (ret > 0) { + if (strcasecmp(buf, "true") == 0 || strcmp(buf, "1") == 0) { + return 1; + } + } + return 0; +} + +int GEQ_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 GEQ_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; + + GEQ_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 GEQ_parse_mode_config(GEQContext *pContext, int mode_num, int band_num, const char *buffer) +{ + int i; + char *Rch = (char *)buffer; + GEQdata *data = &pContext->gGEQdata; + + if (data->usr_cfg == NULL) { + data->usr_cfg = (int *)calloc(mode_num * band_num, sizeof(int)); + if (!data->usr_cfg) { + ALOGE("%s: alloc failed", __FUNCTION__); + return -EINVAL; + } + } + for (i = 0; i < mode_num * band_num; i++) { + if (i == 0) + Rch = strtok(Rch, ","); + else + Rch = strtok(NULL, ","); + if (Rch == NULL) { + ALOGE("%s: Config Parse failed, using default config", __FUNCTION__); + return -1; + } + data->usr_cfg[i] = atoi(Rch); + } + + return 0; +} + +int GEQ_load_ini_file(GEQContext *pContext) +{ + int result = -1; + char ini_name[100] = {0}; + const char *ini_value = NULL; + GEQdata *data = &pContext->gGEQdata; + IniParser* pIniParser = NULL; + + if (GEQ_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("Geq", "geq_enable", "1"); + if (ini_value == NULL) + goto error; + ALOGD("%s: enable -> %s", __FUNCTION__, ini_value); + data->enable = atoi(ini_value); + + + ini_value = pIniParser->GetString("Geq", "geq_modenum", "6"); + if (ini_value == NULL) + goto error; + ALOGD("%s: sound mode num -> %s", __FUNCTION__, ini_value); + data->mode_num = atoi(ini_value); + ini_value = pIniParser->GetString("Geq", "geq_bandnum", "9"); + if (ini_value == NULL) + goto error; + ALOGD("%s: sound band num -> %s", __FUNCTION__, ini_value); + data->band_num = atoi(ini_value); + // level parse + ini_value = pIniParser->GetString("Geq", "geq_config", "NULL"); + if (ini_value == NULL) + goto error; + ALOGD("%s: condig -> %s", __FUNCTION__, ini_value); + result = GEQ_parse_mode_config(pContext, data->mode_num, data->band_num, ini_value); + + result = 0; +error: + ALOGD("%s: %s", __FUNCTION__, result == 0 ? "sucessful" : "failed"); + delete pIniParser; + pIniParser = NULL; + return result; +} + +int GEQ_init(GEQContext *pContext) +{ + GEQdata *data = &pContext->gGEQdata; + //int32_t count = data->count; + + 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; + + /* default band is usr_cfg[(count>>LSR)+1] */ + data->cfg.band1 = 0/*data->usr_cfg[(count >> LSR) + 1].band1*/; + data->cfg.band2 = 0/*data->usr_cfg[(count >> LSR) + 1].band2*/; + data->cfg.band3 = 0/*data->usr_cfg[(count >> LSR) + 1].band3*/; + data->cfg.band4 = 0/*data->usr_cfg[(count >> LSR) + 1].band4*/; + data->cfg.band5 = 0/*data->usr_cfg[(count >> LSR) + 1].band5*/; + data->cfg.band6 = 0/*data->usr_cfg[(count >> LSR) + 1].band6*/; + data->cfg.band7 = 0/*data->usr_cfg[(count >> LSR) + 1].band7*/; + data->cfg.band8 = 0/*data->usr_cfg[(count >> LSR) + 1].band8*/; + data->cfg.band9 = 0/*data->usr_cfg[(count >> LSR) + 1].band9*/; + + GEQ_init_api((void *)data); + + ALOGD("%s: sucessful", __FUNCTION__); + + return 0; +} +int GEQ_reset(GEQContext *pContext __unused) +{ + GEQ_reset_api(); + return 0; +} + +int GEQ_configure(GEQContext *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)); + + if (pContext->bUseFade) { + int channels = 2; + if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO) { + channels = 2; + } + AudioFadeSetFormat(&pContext->gAudFade, pConfig->inputCfg.samplingRate, channels, pConfig->inputCfg.format); + } + + return 0; +} + +int GEQ_getParameter(GEQContext *pContext, void *pParam, size_t *pValueSize, void *pValue) +{ + int32_t param = *(int32_t *)pParam; + int32_t i, value; + GEQcfg_8bit_s custom_value; + GEQdata *data = &pContext->gGEQdata; + + switch (param) { + case GEQ_PARAM_ENABLE: + if (*pValueSize < sizeof(int32_t)) { + *pValueSize = 0; + return -EINVAL; + } + value = data->enable; + *(int32_t *) pValue = value; + ALOGD("%s: Get status -> %s", __FUNCTION__, GEQStatusstr[value]); + break; + case GEQ_PARAM_EFFECT_MODE: + if (*pValueSize < sizeof(int32_t)) { + *pValueSize = 0; + return -EINVAL; + } + value = data->mode; + *(int32_t *) pValue = value; + ALOGD("%s: Get Mode -> %d", __FUNCTION__, value); + break; + case GEQ_PARAM_EFFECT_CUSTOM: + if (*pValueSize < sizeof(GEQcfg_8bit_s)) { + *pValueSize = 0; + return -EINVAL; + } + custom_value.band1 = (signed char)data->usr_cfg[(data->mode_num - 1) * data->band_num]; + custom_value.band2 = (signed char)data->usr_cfg[(data->mode_num - 1) * data->band_num + 1]; + custom_value.band3 = (signed char)data->usr_cfg[(data->mode_num - 1) * data->band_num + 2]; + custom_value.band4 = (signed char)data->usr_cfg[(data->mode_num - 1) * data->band_num + 3]; + custom_value.band5 = (signed char)data->usr_cfg[(data->mode_num - 1) * data->band_num + 4]; + custom_value.band6 = (signed char)data->usr_cfg[(data->mode_num - 1) * data->band_num + 5]; + custom_value.band7 = (signed char)data->usr_cfg[(data->mode_num - 1) * data->band_num + 6]; + custom_value.band8 = (signed char)data->usr_cfg[(data->mode_num - 1) * data->band_num + 7]; + custom_value.band9 = (signed char)data->usr_cfg[(data->mode_num - 1) * data->band_num + 8]; + *(GEQcfg_8bit_s *) pValue = custom_value; + for (i = 0; i < data->band_num; i++) { + ALOGD("%s: Get band[%d] -> %d", __FUNCTION__, i + 1, data->usr_cfg[(data->mode_num - 1) * data->band_num + i]); + } + break; + default: + ALOGE("%s: unknown param %d", __FUNCTION__, param); + return -EINVAL; + } + + return 0; +} + +int GEQ_setParameter(GEQContext *pContext, void *pParam, void *pValue) +{ + int32_t param = *(int32_t *)pParam; + int32_t i, value; + int needFade = 0; + GEQcfg_8bit_s custom_value; + GEQdata *data = &pContext->gGEQdata; + + switch (param) { + case GEQ_PARAM_ENABLE: + value = *(int32_t *)pValue; + data->enable = value; + ALOGD("%s: Set status -> %s", __FUNCTION__, GEQStatusstr[value]); + break; + case GEQ_PARAM_EFFECT_MODE: + value = *(int32_t *)pValue; + if (value < 0 || value > data->mode_num) { + ALOGE("%s: incorrect mode value %d", __FUNCTION__, value); + return -EINVAL; + } + data->mode = value; + pContext->modeValue = data->mode; + ALOGD("%s: Set Mode -> %d, bUseFade = %d", __FUNCTION__, value , pContext->bUseFade); + if (pContext->bUseFade) { + AudioFade_t *pAudioFade = (AudioFade_t *) & (pContext->gAudFade); + AudioFadeInit(pAudioFade, fadeLinear, 10, 0); + AudioFadeSetState(pAudioFade, AUD_FADE_OUT_START); + } else { + for (i = 0; i < data->band_num; i++) { + ALOGD("%s: Set band[%d] -> %d", __FUNCTION__, i + 1, data->usr_cfg[value * data->band_num + i]); + if (data->usr_cfg[data->mode * data->band_num + i] < -10) + data->usr_cfg[data->mode * data->band_num + i] = -10; + else if (data->usr_cfg[data->mode * data->band_num + i] > 10) + data->usr_cfg[data->mode * data->band_num + i] = 10; + GEQ_setBand_api(data->usr_cfg[data->mode * data->band_num + i], i + 1); + } + } + break; + case GEQ_PARAM_EFFECT_CUSTOM: + custom_value = *(GEQcfg_8bit_s *)pValue; + data->usr_cfg[(data->mode_num - 1) * data->band_num] = (signed int)custom_value.band1; + data->usr_cfg[(data->mode_num - 1) * data->band_num + 1] = (signed int)custom_value.band2; + data->usr_cfg[(data->mode_num - 1) * data->band_num + 2] = (signed int)custom_value.band3; + data->usr_cfg[(data->mode_num - 1) * data->band_num + 3] = (signed int)custom_value.band4; + data->usr_cfg[(data->mode_num - 1) * data->band_num + 4] = (signed int)custom_value.band5; + data->usr_cfg[(data->mode_num - 1) * data->band_num + 5] = (signed int)custom_value.band6; + data->usr_cfg[(data->mode_num - 1) * data->band_num + 6] = (signed int)custom_value.band7; + data->usr_cfg[(data->mode_num - 1) * data->band_num + 7] = (signed int)custom_value.band8; + data->usr_cfg[(data->mode_num - 1) * data->band_num + 8] = (signed int)custom_value.band9; + + if (pContext->modeValue != data->mode_num - 1) { + // if we change from other mode to "CUSTOM" mode , need to do fade + needFade = 1; + } else { + // if we are already in "CUSTOM" mode , no need to do fade + needFade = 0; + } + + pContext->modeValue = data->mode_num - 1; + ALOGD("%s: Set Mode -> %d, bUseFade = %d", __FUNCTION__, pContext->modeValue , pContext->bUseFade); + if (pContext->bUseFade && needFade) { + AudioFade_t *pAudioFade = (AudioFade_t *) & (pContext->gAudFade); + AudioFadeInit(pAudioFade, fadeLinear, 10, 0); + AudioFadeSetState(pAudioFade, AUD_FADE_OUT_START); + } else { + for (i = 0; i < data->band_num; i++) { + ALOGD("%s: Set band[%d] -> %d", __FUNCTION__, i + 1, data->usr_cfg[(data->mode_num - 1) * data->band_num + i]); + if (data->usr_cfg[(data->mode_num - 1) * data->band_num + i] > 10) + data->usr_cfg[(data->mode_num - 1) * data->band_num + i] = 10; + else if ( data->usr_cfg[(data->mode_num - 1) * data->band_num + i] < -10) + data->usr_cfg[(data->mode_num - 1) * data->band_num + i] = -10; + GEQ_setBand_api(data->usr_cfg[(data->mode_num - 1) * data->band_num + i], i + 1); + } + } + break; + default: + ALOGE("%s: unknown param %08x", __FUNCTION__, param); + return -EINVAL; + } + + return 0; +} + +int GEQ_release(GEQContext *pContext) +{ + GEQdata *data = &pContext->gGEQdata; + GEQ_release_api(); + if (data->usr_cfg != NULL) { + free(data->usr_cfg); + data->usr_cfg = NULL; + } + return 0; +} + +//-------------------Effect Control Interface Implementation-------------------------- + +int GEQ_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) +{ + GEQContext * pContext = (GEQContext *)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 != GEQ_STATE_ACTIVE) { + return -ENODATA; + } + int16_t *in = (int16_t *)inBuffer->raw; + int16_t *out = (int16_t *)outBuffer->raw; + GEQdata *data = &pContext->gGEQdata; + if (!data->enable) { + for (size_t i = 0; i < inBuffer->frameCount; i++) { + *out++ = *in++; + *out++ = *in++; + } + } else { + if (pContext->bUseFade) { + int i; + AudioFade_t *pAudFade = (AudioFade_t *) & (pContext->gAudFade); + unsigned int modeValue; + unsigned int nSamples = (unsigned int)inBuffer->frameCount; + + if (pAudFade->mFadeState != AUD_FADE_IDLE) { + ALOGI("%s: mFadeState -> %d, mCurrentVolume = %d,nSamples = %d", __FUNCTION__, pAudFade->mFadeState, pAudFade->mCurrentVolume, nSamples); + } + + // do audio traisition + switch (pAudFade->mFadeState) { + case AUD_FADE_OUT_START: { + pAudFade->mTargetVolume = 0; + pAudFade->mStartVolume = 1 << 16; + pAudFade->mCurrentVolume = 1 << 16; + pAudFade->mfadeTimeUsed = 0; + pAudFade->mfadeFramesUsed = 0; + pAudFade->mfadeTimeTotal = DEFAULT_FADE_OUT_MS; + pAudFade->muteCounts = 1; + AudioFadeBuf(pAudFade, in, nSamples); + pAudFade->mFadeState = AUD_FADE_OUT; + } + break; + case AUD_FADE_OUT: { + // do fade out process + if (pAudFade->mCurrentVolume != 0) { + AudioFadeBuf(pAudFade, in, nSamples); + } else { + pAudFade->mFadeState = AUD_FADE_MUTE; + // do actrually setting + modeValue = pContext->modeValue; + for (i = 0; i < data->band_num; i++) { + ALOGD("%s: Set band[%d] -> %d", __FUNCTION__, i + 1, data->usr_cfg[modeValue * data->band_num + i]); + GEQ_setBand_api(data->usr_cfg[modeValue * data->band_num + i], i + 1); + } + mutePCMBuf(pAudFade, in, nSamples); + } + } + break; + case AUD_FADE_MUTE: { + if (pAudFade->muteCounts <= 0) { + pAudFade->mFadeState = AUD_FADE_IN; + // slowly increase audio volume + pAudFade->mTargetVolume = 1 << 16; + pAudFade->mStartVolume = 0; + pAudFade->mCurrentVolume = 0; + pAudFade->mfadeTimeUsed = 0; + pAudFade->mfadeFramesUsed = 0; + pAudFade->mfadeTimeTotal = DEFAULT_FADE_IN_MS; + mutePCMBuf(pAudFade, in, nSamples); + } else { + mutePCMBuf(pAudFade, in, nSamples); + pAudFade->muteCounts--; + } + } + break; + case AUD_FADE_IN: { + AudioFadeBuf(pAudFade, in, nSamples); + if (pAudFade->mCurrentVolume == 1 << 16) { + pAudFade->mFadeState = AUD_FADE_IDLE; + } + } + break; + case AUD_FADE_IDLE: + // do nothing + break; + default: + break; + } + +#if 0 + if (getprop_bool("media.audiofade.dump1")) { + FILE *dump_fp = NULL; + dump_fp = fopen("/data/audio_hal/audio_in.pcm", "a+"); + if (dump_fp != NULL) { + fwrite(in, nSamples * 2 * 2, 1, dump_fp); + fclose(dump_fp); + } else { + ALOGW("[Error] Can't write to /data/dump_in.pcm"); + } + } +#endif + + GEQ_process_api(in, out, inBuffer->frameCount); + +#if 0 + if (getprop_bool("media.audiofade.dump1")) { + FILE *dump_fp = NULL; + dump_fp = fopen("/data/audio_hal/audio_out.pcm", "a+"); + if (dump_fp != NULL) { + fwrite(out, nSamples * 2 * 2, 1, dump_fp); + fclose(dump_fp); + } else { + ALOGW("[Error] Can't write to /data/dump_in.pcm"); + } + } +#endif + + } else { + // original processing + GEQ_process_api(in, out, inBuffer->frameCount); + } + } + return 0; +} + +int GEQ_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, + void *pCmdData, uint32_t *replySize, void *pReplyData) +{ + GEQContext * pContext = (GEQContext *)self; + effect_param_t *p; + int voffset; + + if (pContext == NULL || pContext->state == GEQ_STATE_UNINITIALIZED) { + return -EINVAL; + } + + ALOGD("%s: cmd = %u", __FUNCTION__, cmdCode); + switch (cmdCode) { + case EFFECT_CMD_INIT: + if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) { + return -EINVAL; + } + *(int *) pReplyData = GEQ_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 = GEQ_configure(pContext, (effect_config_t *) pCmdData); + break; + case EFFECT_CMD_RESET: + GEQ_reset(pContext); + break; + case EFFECT_CMD_ENABLE: + if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) + return -EINVAL; + if (pContext->state != GEQ_STATE_INITIALIZED) + return -ENOSYS; + pContext->state = GEQ_STATE_ACTIVE; + *(int *)pReplyData = 0; + break; + case EFFECT_CMD_DISABLE: + if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) + return -EINVAL; + if (pContext->state != GEQ_STATE_ACTIVE) + return -ENOSYS; + pContext->state = GEQ_STATE_INITIALIZED; + *(int *)pReplyData = 0; + break; + case EFFECT_CMD_GET_PARAM: + if (pCmdData == NULL || + cmdSize != (int)(sizeof(effect_param_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(GEQcfg_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 = GEQ_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(GEQcfg_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(GEQcfg_8bit_s)) { + *(int32_t *)pReplyData = -EINVAL; + break; + } + *(int *)pReplyData = GEQ_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 GEQ_getDescriptor(effect_handle_t self, effect_descriptor_t *pDescriptor) +{ + GEQContext * pContext = (GEQContext *) self; + + if (pContext == NULL || pDescriptor == NULL) { + ALOGE("%s: invalid param", __FUNCTION__); + return -EINVAL; + } + + *pDescriptor = GEQDescriptor; + + return 0; +} + +//-------------------- Effect Library Interface Implementation------------------------ + +int GEQLib_Create(const effect_uuid_t *uuid, int32_t sessionId __unused, int32_t ioId __unused, effect_handle_t *pHandle) +{ + //int ret; + + if (pHandle == NULL || uuid == NULL) { + return -EINVAL; + } + + if (memcmp(uuid, &GEQDescriptor.uuid, sizeof(effect_uuid_t)) != 0) { + return -EINVAL; + } + + GEQContext *pContext = new GEQContext; + if (!pContext) { + ALOGE("%s: alloc GEQContext failed", __FUNCTION__); + return -EINVAL; + } + memset(pContext, 0, sizeof(GEQContext)); + if (GEQ_load_ini_file(pContext) < 0) { + ALOGE("%s: Load INI File faied, use default param", __FUNCTION__); + pContext->gGEQdata.enable = 1; + } + + pContext->itfe = &GEQInterface; + pContext->state = GEQ_STATE_UNINITIALIZED; + + *pHandle = (effect_handle_t)pContext; + + pContext->state = GEQ_STATE_INITIALIZED; + + pContext->bUseFade = 1; + AudioFadeInit((AudioFade_t *) & (pContext->gAudFade), fadeLinear, 10, 0); + AudioFadeSetState((AudioFade_t *) & (pContext->gAudFade), AUD_FADE_IDLE); + + ALOGD("%s: %p", __FUNCTION__, pContext); + + return 0; +} + +int GEQLib_Release(effect_handle_t handle) +{ + GEQContext * pContext = (GEQContext *)handle; + + if (pContext == NULL) { + return -EINVAL; + } + + GEQ_release(pContext); + pContext->state = GEQ_STATE_UNINITIALIZED; + delete pContext; + + return 0; +} + +int GEQLib_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, &GEQDescriptor.uuid, sizeof(effect_uuid_t)) == 0) { + *pDescriptor = GEQDescriptor; + return 0; + } + + return -EINVAL; +} + +// effect_handle_t interface implementation for GEQ effect +const struct effect_interface_s GEQInterface = { + GEQ_process, + GEQ_command, + GEQ_getDescriptor, + NULL, +}; + +audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { + .tag = AUDIO_EFFECT_LIBRARY_TAG, + .version = EFFECT_LIBRARY_API_VERSION, + .name = "Geq", + .implementor = "Amlogic", + .create_effect = GEQLib_Create, + .release_effect = GEQLib_Release, + .get_descriptor = GEQLib_GetDescriptor, +}; + +}; // extern "C" + diff --git a/libaudioeffect/Geq/Geq.h b/libaudioeffect/Geq/Geq.h new file mode 100644 index 0000000..3f84a49 --- a/dev/null +++ b/libaudioeffect/Geq/Geq.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_GEQ_H_ +#define ANDROID_GEQ_H_ + +#define GEQ_CUP_LOAD_ARM9E 100 //Expressed in 0.1 MIPS +#define GEQ_MEM_USAGE 50 // Expressed in kB + +#endif + diff --git a/libaudioeffect/Geq/libAmlGeq.a b/libaudioeffect/Geq/libAmlGeq.a new file mode 100644 index 0000000..ac32cec --- a/dev/null +++ b/libaudioeffect/Geq/libAmlGeq.a @@ -0,0 +1,325 @@ +!<arch> +/ 0 0 0 0 306 ` + +EQ_coefficients.o/ + +hpeq_neon.o/ 0 0 0 644 1664 ` +ELF +A +"_ +:;' + + +ELF +"@R +qPЂԲؒ0 + + + +B,C|BqdEpBp1t2lE 3(`h hR@ +0"D"# +L +C +B/ +d +AP +C +A\ $P +P +4 +h +h h0\ + + +h + + + + + + + + + + + + + + + + + + + + + +I +3 +3 +3 + +3 + + + + + + + + + + + +" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +A + +~JJ E
wJ
rJJ"OH"LE EPLH!JI!K!LzJ!NJ!LF!NHLHFNLJ*RKyJwM*JoJ*JKKmJL*KhJJ +_J !PLH zJMP!HLF~J!JN~J!JJ zL!J~JJzJL!LFNE JzJP!HJHQ~J!JJ!LL~ vJ~JIMP!FF!NF~J!LJF H!LHNL~JK!NP!JH* +Jx* JIKLIKuJ*JKsJ~J JO E~J!J!MJHR~!JH~JJ!JN!JJ!zJ !JN~JJK!NJ*JyJz* J!wJH*
Ju*
Jj*JxJ* +JLtJ~J KI~JJRx!JLL!JF J!L!~JN!HJF!NEP*wJH*J!wJ*Ju*
J}QyJLLvJ*JtJ~J JO E~J!J!MJHR!FL~!JN!JLJ!~HP~JJ H~!NE!OH*wJH*J!wJ*Ju*
J}QyJLLvJ*kJ~J J~JKI~JJRF!JH~JJ!J!LJ z!JLJN!HJ~!Nz*
JwJ* J!wJH*
Ju*
JjJ*QsJ*PzJ*RLL fJ! +J vJ~JJ~JJ!KJH!L LzJ!LJ~*JwH!L*Ju*
J!qJ~J*JsJ*
JsJ*PtJL* +JxH*JL!tJ* JOrJ* JLL!oJG!KI JwJ J*
Jq*R!xJ* +JLFvJ*J fJJ!FH!N!~HPFNHH*JqJ*JqL*Jo*sLyJzJ xJRxJ*ErJL*JrJL*kJ EOQ!!H!JN!HHHPFNHH*Jq~J*JqJ*JqJ~JJLz xJRxJ*ErJL*JrJL*kJ EOQ!!H!JN!HHHPFNHH*Jq~J*JqJ*JqJ~JJLz xJRxJ*ErJL*JrJL*kJ EOQ!!H!JN!HHHPFNHH*Jq~J*JqJ*JqJ~JJLz xJRxJ*ErJL*JrJL*kJ EOQ!!H!JN!HHHPFNHH*Jq~J*JqJ*JqJ~JJLz xJRxJ*ErJL*JrJL*kJ EOQ!!H!JN!HHHPFNHH*Jq~J*JqJ*JqJ~JJLz xJRxJ*ErJL*JrJL*kJ EOQ!!H!JN!HHHPFNHH*Jq~J*JqJ*JqJ~JJLz xJRxJ*ErJL*JrJL*kJ EOQ!!H!JN!FHP~NHH*Jq~J*JqJ*JqJ!LLz xJRxJ*ErJL*JrJL*kJ E +J}Q!FLL}KL~J!FHL!HNL!zJJP!F*<zJ xJ*JKpJN*
JKpJN*
JqL,VJ*J*cJhJ5J}J}JJ}<JOJ1JOHJL6J HJJL H zJPNLzJ JPFHN* +J rJ*JqJN~LN* +JKuJ*JK mJJR*KkJ zJRH JNLHF JJHLHHNHHN*RKuJNHL*RvJ*JKK mJR*KkJ zJRH JJLLF JNL zJLL*RvJH*
JsJNL xJR*RKuJ*JKuJ*KkJ zJRH JJNHH JLN zJNHHLHHNHHN*RKuJNHL*RvJ*JKK mJJ*KkJ zJRH JLLF JHNJHNHLFNHHN*RKuJNHL*RvJ*JKK mJJRxJR*JKkJ zJRH JLLF JHNJHNHLFNHHN*RKuJNHL*RvJ*JKK mJJRxJR*JKkJ zJRH JLL~ JzJNFNHHN*RKuJNHL*RvJ*JKK mJJRxJR*JKkJ zJRH JLLF JHNJHNHLFNHHN*RKuJNHL*RvJ*JKK mJR*KkJ zJRH JJLLF JJ JLHNJHNHLFNHHN*RKuJNHL*RvJ*JKK mJR*KkJ zJRH JJLLF JJ JLHNJHNHLFNHHN*RKuJNHL*RvJ*JKK mJR*KkJ zJRH JJLLF JJ JLHNJHNHLFNHHN*RKuJNHL*RvJ*JKK mJR*KkJ zJRH JJLLF JJ JLHNJHNHLFNHHN*RKuJNHL*RvJ*JKK mJR*KkJ zJRH JJLLF JJ JLHNJHNHLFNHHN*RKuJNHL*RvJ*JKK mJR*KkJ zJRH JJLLF JJ JLHNJHNHLFNHHN*RKuJNHL*RvJ*JKK mJR*KkJ zJRH JJLLF JJ JLHNJHNHLFNHHN*RKuJNHL*RvJ*JKK mJJR*JVJ*JKkJ zJRL FPzJLHLNHHLL*RvJ F*JwJzJ JJLPzLL* +JtJ.J*_JKtJ +KN~NFN~JJ + +JzJJmJJR +LHFN +HJ +hJJPJJJJJJJJJJJJJJJJLNJJJJJJJJJJNsJJNJFOIJJKJIJJKJIJJKJIJJKJIJJKJMPJKJIJJKJIJJKJIJRxJKJO[J)JJNJKJIJJKJIJJKJIJJKJIJJKJIJJKJMPJKJIJJKJIJJKJIJRxJKJOCJ +5ILIKI5IN +|J|JJ=JoJ{5HLI5IJ/JK{ +K IKIKL{J{ +/J{ +{JG{t{J$ +@{J{tMJG4M JHJLE +OEP +JzJ{<t{ +{4${Jzf$$$$$$$$O/JK(zL +z4!zJ}f!!!!!!!!zJJ$zD + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +" +* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +_ + +ELF +)R') + +gi{$~ +?н + +;3D +Gf +Β$U + +G +56? +ur$ +&*G +B +O$ж +G +$ +( + +q0%f{ + +~% +V +#
5%! +O + +Y +<] +a&A +_b'Đ +A +Ķ(T +UJ+} +*[ +<l +}7&4u +e + + +2 + +)9$ +4 +M +th"r
1x + Fp/ +O + + +.& + +"Zt2@ +v'0,ED_ + +P + +;3D + +A + + diff --git a/libaudioeffect/Geq/libAmlGeq.h b/libaudioeffect/Geq/libAmlGeq.h new file mode 100644 index 0000000..36836a0 --- a/dev/null +++ b/libaudioeffect/Geq/libAmlGeq.h @@ -0,0 +1,25 @@ +/* + * 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_GEQ_API_H_ +#define ANDROID_GEQ_API_H_ +extern int GEQ_init_api(void *data); +extern int GEQ_release_api(void); +extern int GEQ_reset_api(void); +extern int GEQ_process_api(short *in, short *out, int framecount); +extern int GEQ_setBand_api(int band, int index); +extern int GEQ_getBand_api(int *band, int index); +#endif diff --git a/libaudioeffect/Geq/libAmlGeq64.a b/libaudioeffect/Geq/libAmlGeq64.a new file mode 100644 index 0000000..af626c6 --- a/dev/null +++ b/libaudioeffect/Geq/libAmlGeq64.a @@ -0,0 +1,413 @@ +!<arch> +/ 0 0 0 0 306 ` + + + + + + + + + + + + + + + +EQ_coefficients.o/ + +hpeq_neon_64.o/ 0 0 0 644 2240 ` +ELF +Jj x&x@(@xHxeD@eD@eD@D@D@&@H@ +Jj x&x@(@x +:;' + +ELF +$R2i|{2J*l,||/ + +7.8WOCK0DBiG9/܂%Hi:(2#Ki;H?<8~4TNi; .:=X|")(Qi <r|7h(,7,4Wi30Ti/3+L H2Zi+)}6<1\ H%*]i&l~}3x յ%) + +*+ Չ%1, +)* Ջ9X-
I- +X +*4+ԁ Չ%,-< n% +)<*܁ Ջ=X-
I- +X +*D+䁹 Չ%,聹-T n% +)L*쁹 Ջ
X-
I- +X,kU)(Li +*T+ Չ%,c +)\* ՋX-
I- +X;, kU.`[ +*d+ Չ%.h, k% +)l* +XK +(!)D*+ . H! )*$ h!
+(, M! (), jUXj)() +X/ +(!)4*/+.x H! )t* h!
+, M! (|) jQXj)+P () +X +(!)T*0Yi-.+0 H! )*47 h!
+8 M! ()< j Xj)() +X7($[i>`JU +(!)d*0\i=+@< H! )*D h!+H M! ()L jIXj)() +X
($^i;pJUg +(!)t* +$*h'X,+l)ă(pT|@J}j)) +(BC2+7(}(`X!@1; +*K,0DZi+|3l/|l| +X +(!
)4*8Mi/p0x- H! )t*?
ը!- O! (|) ժ-Xj)() +X?+@JU./c +(!)D*4Pi+ + h!+ N! () j1Xj)
() +X($Ri+PJU- +(!)T*+. H! )* h!
+, M! () jXj)() +X7 +(!)d*+ . H! )*$ h!
+(, M! (), jXj)+p () +X +(!)t*0Yi-.+0 H! )*4 h!
+8 M! ()< jXj)() +X +(!)*+@.Ȇ H! )Ć*D h!
+H,䀹 M! (̆)L jMXj)() +X +(!)*0_i=І+P<؆ H! )Ԇ*T h!+X; M! (܆)\ j
Xj)())X_ + 8膹(h)*솹 l cXh +X) / 7 $U#%(G +i$ +@ Չ%(,(X*KA+, U*@ |B!@-}@*4@.OA!*<@!^.. +.AX..PA.X@. @X.(.`@.h@.0@X.8.p@.x@.@@X.H.@.@.P@X.X.@.@.`@X.h.@.@.p@X.x.@.@.@X..w@.s@.g@X.._@.[@.O@X..K@.G@.;@X..3@./@.. +{EODWC_BgAoƨ_ ,@)j2?1 + + + +I +; +; +; + + +; + + + +J
rJJ
rJJ
rJ"J
mJJ"O
mJJ EO!OL"HF!LGMH!*JtJL
qJ*JqJNNwJJ OFNH*JsJHLL
pJO*JILLKL +eJJJL!HLHL!HJL!HJLH J!JLH JL!HJ JLJ!HL!H JLJH! JJLJH!L HJJJJ! JJLH!HJ! JLH! HJJ! JJLH!H!J JJL! HJ!JJL!J HJJ!JJ JL!JJ!`JJI z!JH!JH!JH!J!JFOLL!FLzJIK zJ +JEKL!JG!OJH!JH!EQ!JFOLL!FLyJK zJ +JEKL!JG!OJH!JH!EQ!JFOLLHzJ zJ! +JEJEKL!JLJ!JH!JH!!JFOLLHzJ zJ +JEKL!JL!JH!JL!JJFOLL!FFIK zJ +JEKL!JG!OJH!JH!EQ!JFOLL!FLzJIKN vJOKL!JG!OJH!JH!EQ!JFOFPHzJ!NE EOKL!JL!H!JHJ!L!JFOLLHyJK zJOKL!JL!JJH!JH!L!JFOLLHyJK zJOKL!JL!JJH!JHJ~P!JFOLyJ J!xJ zJ!JG!JEQ!JzJ!JHO!JJ~GOLyJON rJJK!JL!JL!JL!JzJLEQ!JHGQ!JFOLyJ J rJJK!JL!JL!JEQ!JzJLLH!JHGQ!JFOLyJ J rJOJK!JPF!JL!JJL!JzJLLH!JHGQ!JFOLyJ JxJ!JL!J xJOJKL*
JsJ
oJ*JLJqJ"H*JLFIxJ*
JLJ kJJ*JzJIrJ*JJLLLzJLLJLzJNLHLzJPzJNLzJJLLLzJLLJLyJOLsJ*PPKzJyJJ*JELGzJJ* JLuJ*JLzzzz~!sH!JH*LLzz*LLzz*LLzz*LLzz*LLzz*LLzz*LLzz*PvJ!LL*RLLtJ*PLLvJ*RLLJ!pJLyJ*JzJzJ*PvJ!L*
JlJOLwJOLzJ!JRJ*RLpJ*J!nJ xJ*JvJ*JL!rJ*JkJ*JrJ*R!xJyJK*JLmJM*rJ*R!xJH*RzJwJOL
nJJ*RLLEKLHKNhJ*JJK*_JKJ<MJJJL!HLHL!HLH!JL!HLH JL!HLH JLJ!H JJLJ HJ! JJJJ!J JJLJ HJ!JJ HJJJ!J L!JHJ!L!J HJJ JJJ!L!JH!JL!J HJ JJJ!L!JH J!JJ8 HJ J8JJJ!JHJJI z!JH!JH!JHJ!JL!JJFOFP!FFI }OKL!JL!JH!JHJ!JL!JJFOFP!FFI }OKL!JL!JH!JHJ!JL!JJFOFP!FFI }OKL!JL!H!JHJ!L!JFOLLHzJ zJ +J}KL!JLH!JHJ!L!JFOLLHyJK zJ +JEKL!JG!OJH!JH!EQ!JFOLL!FLyJKN vJOKL!JG!OJH!JH!EQ!JFOFPHzJ!NE EOKL!JL!H!JHJ!L!JFOLLHzJIK zJ +JEKL!JG!OJH!JH!EQ!JFOLL!FLzJIK zJOKL!JL!JJH!JH!FP!JFOLyJ J rJ!KL!JL!JL!JzJLLH!JEQ!JFOLLwJOF!J zJR!JG!JEQ!JzJ!JHO!JJ~GOLyJON rJJK!JL!JL!JL!JzJLEQ!JHGQ!JFOLyJ J rJOJK!JL!JL!JL!JzJLLH!JHGQ!JFOLyJ J rJP!JIM!JNyJO!JL!JzJLLH!JHGQ!JFO*JwJ*sJ*QLoJ!J zJ*JL
`J"
JI*JLzJI rJ*JzJqJ*JrJ*JLLuJ*RKLI!pJ*
JNLHLoJ*JzJ!uJN*
JzJLILtJ*JL!sJ*JkJ*JLsJ*PLOzJMtJ*JEL!uJ* JNHLLzJNJLJzJNLzJPzJNFLMzJJMLzzzz~nJKL*
JuJ!JHLFPJwJON*RLLrJ*RNzJoJ*JzJ*LLzz*LLzz*LLzz*LLzz*LLzz*LLzz*LLzz*LLzz*LLzz*LLzz*LLz
f*JM7J*GJKL6J g J +LIMIMIMH +NG +MGK +M wJMPJqJMJJJJJJJJJJJPJJJJJJJNJLPFJNKJIJKJIJKJIJKJIJKJIJKJ JJKJIJKJIJKJIJKJOJLPFJNKJIJKJIJKJIJKJIJKJIJKJ JJKJIJKJIJKJIJKJOJLPFJNKJIJKJIJKJIJKJIJKJIJKJ JJKJIJKJIJKJIJKJNJLPFJNKJIJKJIJKJIJKJIJKJIJKJ JJKJIJKJIJKJIJKJMJLPFJNKJIJKJIJKJIJKJIJKJIJKJ JJKJIJKJIJKJIJKJMJLPFJNKJIJKJIJKJIJKJIJKJIJKJ JJKJIJKJIJKJIJKJMJLPFJNKJIJKJIJKJIJKJIJKJIJKJ JJKJIJKJIJKJIJKJN~JJJJJJJJJJJJPJJJJJJJL +5IK5HN +=||JJ=Jp5IK5HJ/JK +M JK{<J +{J/J{JJ +MK{{ +M{M4JJGK LJHLKEJ +OK +JzJ{<< +{JJL{<$J{h$J$J$J$J$J$J$J$JOJ/JK( +zJJLz<!Jzf!J!J!J!J!J!J!J!JzJJ$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +& +9 +: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +* +ELF +)R') + +gi{$~ +?н + +;3D +Gf +Β$U + +G +56? +ur$ +&*G +B +O$ж +G +$ +( + +q0%f{ + +~% +V +#
5%! +O + +Y +<] +a&A +_b'Đ +A +Ķ(T +UJ+} +*[ +<l +}7&4u +e + + +2 + +)9$ +4 +M +th"r
1x + Fp/ +O + + +.& + +"Zt2@ +v'0,ED_ + +P + +;3D + + diff --git a/libaudioeffect/effects_tool/main.cpp b/libaudioeffect/effects_tool/main.cpp index 7ea414f..b4c25bc 100644 --- a/libaudioeffect/effects_tool/main.cpp +++ b/libaudioeffect/effects_tool/main.cpp @@ -196,6 +196,31 @@ HPEQ_param_t gHPEQParam[] = { const char *HPEQStatusstr[] = {"Disable", "Enable"}; +//-------------GEQ parameters-------------------------- +typedef struct GEQ_param_s { + effect_param_t param; + uint32_t command; + union { + uint32_t v; + float f; + signed char band[9]; + }; +} GEQ_param_t; + +typedef enum { + GEQ_PARAM_ENABLE = 0, + GEQ_PARAM_EFFECT_MODE, + GEQ_PARAM_EFFECT_CUSTOM, +} GEQ_params; + +GEQ_param_t gGEQParam[] = { + {{0, 4, 4}, GEQ_PARAM_ENABLE, {1}}, + {{0, 4, 4}, GEQ_PARAM_EFFECT_MODE, {0}}, + {{0, 4, 9}, GEQ_PARAM_EFFECT_CUSTOM, {0}}, +}; + +const char *GEQStatusstr[] = {"Disable", "Enable"}; + //-------------AVL parameters-------------------------- typedef struct Avl_param_s { effect_param_t param; @@ -235,6 +260,7 @@ typedef enum { EFFECT_TREBLEBASS, EFFECT_HPEQ, EFFECT_AVL, + EFFECT_GEQ, EFFECT_MAX, } EFFECT_params; @@ -244,6 +270,7 @@ effect_uuid_t gEffectStr[] = { {0x76733af0, 0x2889, 0x11e2, 0x81c1, {0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66}}, // 2:TrebleBass {0x049754aa, 0xc4cf, 0x439f, 0x897e, {0x37, 0xdd, 0x0c, 0x38, 0x11, 0x20}}, // 3:Hpeq {0x08246a2a, 0xb2d3, 0x4621, 0xb804, {0x42, 0xc9, 0xb4, 0x78, 0xeb, 0x9d}}, // 4:Avl + {0x2e2a5fa6, 0xcae8, 0x45f5, 0xbb70, {0xa2, 0x9c, 0x1f, 0x30, 0x74, 0xb2}}, // 5:Geq }; static inline float DbToAmpl(float decibels) @@ -658,6 +685,54 @@ static int HPEQ_effect_func(AudioEffect* gAudioEffect, int gParamIndex, int gPar } } +static int GEQ_effect_func(AudioEffect* gAudioEffect, int gParamIndex, int gParamValue, signed char gParamBands[9]) +{ + switch (gParamIndex) { + case GEQ_PARAM_ENABLE: + if (gParamValue < 0 || gParamValue > 1) { + LOG("GEQ: Status gParamValue = %d invalid\n", gParamValue); + return -1; + } + gGEQParam[gParamIndex].v = gParamValue; + gAudioEffect->setParameter(&gGEQParam[gParamIndex].param); + gAudioEffect->getParameter(&gGEQParam[gParamIndex].param); + LOG("GEQ: Status is %d -> %s\n", gParamValue, GEQStatusstr[gGEQParam[gParamIndex].v]); + return 0; + case GEQ_PARAM_EFFECT_MODE: + if (gParamValue < 0 || gParamValue > 6) { + LOG("Hpeq:gParamValue = %d invalid\n", gParamValue); + return -1; + } + gGEQParam[gParamIndex].v = gParamValue; + gAudioEffect->setParameter(&gGEQParam[gParamIndex].param); + gAudioEffect->getParameter(&gGEQParam[gParamIndex].param); + LOG("GEQ: mode is %d -> %d\n", gParamValue, gGEQParam[gParamIndex].v); + return 0; + case GEQ_PARAM_EFFECT_CUSTOM: + for (int i = 0; i < 9; i++) { + if (gParamBands[i]< -10 || gParamBands[i] >10) { + LOG("Geq:gParamBands[%d] = %d invalid\n",i, gParamBands[i]); + return -1; + } + } + gGEQParam[gParamIndex].band[0] = gParamBands[0]; + gGEQParam[gParamIndex].band[1] = gParamBands[1]; + gGEQParam[gParamIndex].band[2] = gParamBands[2]; + gGEQParam[gParamIndex].band[3] = gParamBands[3]; + gGEQParam[gParamIndex].band[4] = gParamBands[4]; + gGEQParam[gParamIndex].band[5] = gParamBands[5]; + gGEQParam[gParamIndex].band[6] = gParamBands[6]; + gGEQParam[gParamIndex].band[7] = gParamBands[7]; + gGEQParam[gParamIndex].band[8] = gParamBands[8]; + gAudioEffect->setParameter(&gGEQParam[gParamIndex].param); + gAudioEffect->getParameter(&gGEQParam[gParamIndex].param); + return 0; + default: + LOG("GEQ: ParamIndex = %d invalid\n", gParamIndex); + return -1; + } +} + static int Avl_effect_func(AudioEffect* gAudioEffect, int gParamIndex, int gParamValue) { switch (gParamIndex) { @@ -791,8 +866,10 @@ int main(int argc,char **argv) int gParamValue = 0; float gParamScale = 0.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 name16[EFFECT_MAX] = {String16("AudioEffectEQTest"), String16("AudioEffectSRSTest"), String16("AudioEffectHPEQTest"), + String16("AudioEffectAVLTest"), String16("AudioEffectGEQTest")}; AudioEffect* gAudioEffect[EFFECT_MAX] = {0}; audio_session_t gSessionId = AUDIO_SESSION_OUTPUT_MIX; @@ -881,7 +958,16 @@ int main(int argc,char **argv) LOG("ParamValue: 0 -> DTV 1 -> ATV 2 -> AV 3 -> HDMI 4 -> SPDIF 5->REMOTE_SUBMIX 6->WIRED_HEADSET\n"); LOG("****************************************************************************\n\n"); - if (argc != 4 && argc != 8) { + LOG("*********************************GEQ*********************************\n"); + LOG("EffectIndex: 5\n"); + LOG("ParamIndex: 0 -> Enable\n"); + LOG("ParamValue: 0 -> Disable 1 -> Enable\n"); + LOG("ParamIndex: 1 -> Mode\n"); + LOG("ParamValue: 0 -> Standard 1 -> Music 2 -> news 3 -> movie 4 -> game 5->user\n"); + LOG("ParamIndex: 2 -> custom\n"); + LOG("ParamValue: -10 ~10 \n"); + + if (argc != 4 && argc != 12 && argc != 8) { LOG("Usage: %s <EffectIndex> <ParamIndex> <ParamValue/ParamScale/gParamBand>\n", argv[0]); return -1; } else { @@ -896,8 +982,18 @@ int main(int argc,char **argv) sscanf(argv[5], "%d", &gParamBand[2]); sscanf(argv[6], "%d", &gParamBand[3]); sscanf(argv[7], "%d", &gParamBand[4]); - } else - sscanf(argv[3], "%d", &gParamValue); + } else if (gEffectIndex == 5 && gParamIndex == 2) { + sscanf(argv[3], "%d", &gParamBands[0]); + sscanf(argv[4], "%d", &gParamBands[1]); + sscanf(argv[5], "%d", &gParamBands[2]); + sscanf(argv[6], "%d", &gParamBands[3]); + sscanf(argv[7], "%d", &gParamBands[4]); + sscanf(argv[8], "%d", &gParamBands[5]); + sscanf(argv[9], "%d", &gParamBands[6]); + sscanf(argv[10], "%d", &gParamBands[7]); + sscanf(argv[11], "%d", &gParamBands[8]); + } else + sscanf(argv[3], "%d", &gParamValue); } if (gEffectIndex >= (int)(sizeof(gEffectStr)/sizeof(gEffectStr[0]))) { LOG("Effect is not exist\n"); @@ -909,6 +1005,9 @@ int main(int argc,char **argv) else if (gEffectIndex == 3 && gParamIndex == 2) { for (int i = 0; i < 5; i++) LOG("EffectIndex:%d, ParamIndex:%d, ParamBand:%d\n", gEffectIndex, gParamIndex, gParamBand[i]); + } else if (gEffectIndex == 5 && gParamIndex == 2) { + for (int i = 0; i < 9; i++) + LOG("EffectIndex:%d, ParamIndex:%d, ParamBand:%d\n", gEffectIndex, gParamIndex, gParamBands[i]); } else LOG("EffectIndex:%d, ParamIndex:%d, Paramvalue:%d\n", gEffectIndex, gParamIndex, gParamValue); while (1) { @@ -946,13 +1045,23 @@ int main(int argc,char **argv) case EFFECT_HPEQ: ret = create_audio_effect(&gAudioEffect[EFFECT_HPEQ], name16[EFFECT_HPEQ], EFFECT_HPEQ); if (ret < 0) { - LOG("create TrebleBass effect failed\n"); + LOG("create Hpeq effect failed\n"); goto Error; } //------------set HPEQ parameters------------------------------------------ if (HPEQ_effect_func(gAudioEffect[gEffectIndex], gParamIndex, gParamValue,gParamBand) < 0) LOG("HPEQ Test failed\n"); break; + case EFFECT_GEQ: + ret = create_audio_effect(&gAudioEffect[EFFECT_GEQ], name16[EFFECT_GEQ], EFFECT_GEQ); + if (ret < 0) { + LOG("create Geq effect failed\n"); + goto Error; + } + //------------set GEQ parameters------------------------------------------ + if (GEQ_effect_func(gAudioEffect[gEffectIndex], gParamIndex, gParamValue,gParamBands) < 0) + LOG("GEQ Test failed\n"); + break; case EFFECT_AVL: ret = create_audio_effect(&gAudioEffect[EFFECT_AVL], name16[EFFECT_AVL], EFFECT_AVL); if (ret < 0) { @@ -979,14 +1088,12 @@ int main(int argc,char **argv) if (gEffectIndex == 1 && (gParamIndex == 7 || gParamIndex == 9 || gParamIndex == 11 || (gParamIndex >= 13 && gParamIndex <= 16))) scanf("%f", &gParamScale); else if (gEffectIndex == 3 && gParamIndex == 2) { - sscanf(argv[3], "%d ", &gParamBand[0]); - sscanf(argv[4], "%d ", &gParamBand[1]); - sscanf(argv[5], "%d ", &gParamBand[2]); - sscanf(argv[6], "%d ", &gParamBand[3]); - sscanf(argv[7], "%d ", &gParamBand[4]); + scanf("%d %d %d %d %d",&gParamBand[0],&gParamBand[1],&gParamBand[2],&gParamBand[3],&gParamBand[4]); + } else if (gEffectIndex == 5 && gParamIndex == 2) { + scanf("%d %d %d %d %d %d %d %d %d",&gParamBands[0],&gParamBands[1],&gParamBands[2],&gParamBands[3],&gParamBands[4], + &gParamBands[5],&gParamBands[6],&gParamBands[7],&gParamBands[8]); } else scanf("%d", &gParamValue); - if (gEffectIndex >= (int)(sizeof(gEffectStr)/sizeof(gEffectStr[0]))) { LOG("Effect is not exist\n"); goto Error; |