post_proc: add PBE effect for speaker

Enable PBE for speaker device.

Change-Id: I1a48dff038baf63376f1d4b355888159cf69ba81
This commit is contained in:
Dhananjay Kumar 2014-05-19 16:45:08 +08:00
parent 16b2dd39c4
commit 5f15ff9b7d
6 changed files with 668 additions and 125 deletions

View File

@ -26,7 +26,8 @@ endif
LOCAL_SHARED_LIBRARIES := \
libcutils \
liblog \
libtinyalsa
libtinyalsa \
libdl
LOCAL_MODULE_TAGS := optional

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@ -17,14 +17,17 @@
* limitations under the License.
*/
#define LOG_TAG "offload_effect_bass_boost"
#define LOG_TAG "offload_effect_bass"
//#define LOG_NDEBUG 0
#include <cutils/list.h>
#include <cutils/log.h>
#include <cutils/properties.h>
#include <tinyalsa/asoundlib.h>
#include <sound/audio_effects.h>
#include <audio_effects/effect_bassboost.h>
#include <stdlib.h>
#include <dlfcn.h>
#include "effect_api.h"
#include "bass_boost.h"
@ -41,6 +44,243 @@ const effect_descriptor_t bassboost_descriptor = {
"The Android Open Source Project",
};
#define LIB_ACDB_LOADER "libacdbloader.so"
#define PBE_CONF_APP_ID 0x00011134
enum {
AUDIO_DEVICE_CAL_TYPE = 0,
AUDIO_STREAM_CAL_TYPE,
};
typedef struct acdb_audio_cal_cfg {
uint32_t persist;
uint32_t snd_dev_id;
uint32_t dev_id;
int32_t acdb_dev_id;
uint32_t app_type;
uint32_t topo_id;
uint32_t sampling_rate;
uint32_t cal_type;
uint32_t module_id;
uint32_t param_id;
} acdb_audio_cal_cfg_t;
typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
static int pbe_load_config(struct pbe_params *params);
/*
* Bass operations
*/
int bass_get_parameter(effect_context_t *context, effect_param_t *p,
uint32_t *size)
{
bass_context_t *bass_ctxt = (bass_context_t *)context;
int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
int32_t *param_tmp = (int32_t *)p->data;
int32_t param = *param_tmp++;
void *value = p->data + voffset;
int i;
ALOGV("%s", __func__);
p->status = 0;
switch (param) {
case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
if (p->vsize < sizeof(uint32_t))
p->status = -EINVAL;
p->vsize = sizeof(uint32_t);
break;
case BASSBOOST_PARAM_STRENGTH:
if (p->vsize < sizeof(int16_t))
p->status = -EINVAL;
p->vsize = sizeof(int16_t);
break;
default:
p->status = -EINVAL;
}
*size = sizeof(effect_param_t) + voffset + p->vsize;
if (p->status != 0)
return 0;
switch (param) {
case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
ALOGV("%s: BASSBOOST_PARAM_STRENGTH_SUPPORTED", __func__);
if (bass_ctxt->active_index == BASS_BOOST)
*(uint32_t *)value = 1;
else
*(uint32_t *)value = 0;
break;
case BASSBOOST_PARAM_STRENGTH:
ALOGV("%s: BASSBOOST_PARAM_STRENGTH", __func__);
if (bass_ctxt->active_index == BASS_BOOST)
*(int16_t *)value = bassboost_get_strength(&(bass_ctxt->bassboost_ctxt));
else
*(int16_t *)value = 0;
break;
default:
p->status = -EINVAL;
break;
}
return 0;
}
int bass_set_parameter(effect_context_t *context, effect_param_t *p,
uint32_t size __unused)
{
bass_context_t *bass_ctxt = (bass_context_t *)context;
int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
void *value = p->data + voffset;
int32_t *param_tmp = (int32_t *)p->data;
int32_t param = *param_tmp++;
uint32_t strength;
ALOGV("%s", __func__);
p->status = 0;
switch (param) {
case BASSBOOST_PARAM_STRENGTH:
ALOGV("%s BASSBOOST_PARAM_STRENGTH", __func__);
if (bass_ctxt->active_index == BASS_BOOST) {
strength = (uint32_t)(*(int16_t *)value);
bassboost_set_strength(&(bass_ctxt->bassboost_ctxt), strength);
} else {
/* stength supported only for BB and not for PBE, but do not
* return error for unsupported case, as it fails cts test
*/
ALOGD("%s ignore set strength, index %d",
__func__, bass_ctxt->active_index);
break;
}
break;
default:
p->status = -EINVAL;
break;
}
return 0;
}
int bass_set_device(effect_context_t *context, uint32_t device)
{
bass_context_t *bass_ctxt = (bass_context_t *)context;
if (device == AUDIO_DEVICE_OUT_SPEAKER) {
bass_ctxt->active_index = BASS_PBE;
ALOGV("%s: set PBE mode, device: %x", __func__, device);
} else if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET ||
device == AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) {
ALOGV("%s: set BB mode, device: %x", __func__, device);
bass_ctxt->active_index = BASS_BOOST;
} else {
ALOGI("%s: disabled by device: %x", __func__, device);
bass_ctxt->active_index = BASS_INVALID;
}
bassboost_set_device((effect_context_t *)&(bass_ctxt->bassboost_ctxt), device);
pbe_set_device((effect_context_t *)&(bass_ctxt->pbe_ctxt), device);
return 0;
}
int bass_reset(effect_context_t *context)
{
bass_context_t *bass_ctxt = (bass_context_t *)context;
bassboost_reset((effect_context_t *)&(bass_ctxt->bassboost_ctxt));
pbe_reset((effect_context_t *)&(bass_ctxt->pbe_ctxt));
return 0;
}
int bass_init(effect_context_t *context)
{
bass_context_t *bass_ctxt = (bass_context_t *)context;
// convery i/o channel config to sub effects
bass_ctxt->bassboost_ctxt.common.config = context->config;
bass_ctxt->pbe_ctxt.common.config = context->config;
ALOGV("%s", __func__);
bass_ctxt->active_index = BASS_BOOST;
bassboost_init((effect_context_t *)&(bass_ctxt->bassboost_ctxt));
pbe_init((effect_context_t *)&(bass_ctxt->pbe_ctxt));
return 0;
}
int bass_enable(effect_context_t *context)
{
bass_context_t *bass_ctxt = (bass_context_t *)context;
ALOGV("%s", __func__);
bassboost_enable((effect_context_t *)&(bass_ctxt->bassboost_ctxt));
pbe_enable((effect_context_t *)&(bass_ctxt->pbe_ctxt));
return 0;
}
int bass_disable(effect_context_t *context)
{
bass_context_t *bass_ctxt = (bass_context_t *)context;
ALOGV("%s", __func__);
bassboost_disable((effect_context_t *)&(bass_ctxt->bassboost_ctxt));
pbe_disable((effect_context_t *)&(bass_ctxt->pbe_ctxt));
return 0;
}
int bass_start(effect_context_t *context, output_context_t *output)
{
bass_context_t *bass_ctxt = (bass_context_t *)context;
ALOGV("%s", __func__);
bassboost_start((effect_context_t *)&(bass_ctxt->bassboost_ctxt), output);
pbe_start((effect_context_t *)&(bass_ctxt->pbe_ctxt), output);
return 0;
}
int bass_stop(effect_context_t *context, output_context_t *output)
{
bass_context_t *bass_ctxt = (bass_context_t *)context;
ALOGV("%s", __func__);
bassboost_stop((effect_context_t *)&(bass_ctxt->bassboost_ctxt), output);
pbe_stop((effect_context_t *)&(bass_ctxt->pbe_ctxt), output);
return 0;
}
int bass_set_mode(effect_context_t *context, int32_t hw_acc_fd)
{
bass_context_t *bass_ctxt = (bass_context_t *)context;
ALOGV("%s", __func__);
bassboost_set_mode((effect_context_t *)&(bass_ctxt->bassboost_ctxt), hw_acc_fd);
pbe_set_mode((effect_context_t *)&(bass_ctxt->pbe_ctxt), hw_acc_fd);
return 0;
}
#undef LOG_TAG
#define LOG_TAG "offload_effect_bb"
/*
* Bassboost operations
*/
@ -70,99 +310,30 @@ int bassboost_set_strength(bassboost_context_t *context, uint32_t strength)
return 0;
}
int bassboost_get_parameter(effect_context_t *context, effect_param_t *p,
uint32_t *size)
{
bassboost_context_t *bass_ctxt = (bassboost_context_t *)context;
int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
int32_t *param_tmp = (int32_t *)p->data;
int32_t param = *param_tmp++;
void *value = p->data + voffset;
int i;
ALOGV("%s: ctxt %p, param %d", __func__, bass_ctxt, param);
p->status = 0;
switch (param) {
case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
if (p->vsize < sizeof(uint32_t))
p->status = -EINVAL;
p->vsize = sizeof(uint32_t);
break;
case BASSBOOST_PARAM_STRENGTH:
if (p->vsize < sizeof(int16_t))
p->status = -EINVAL;
p->vsize = sizeof(int16_t);
break;
default:
p->status = -EINVAL;
}
*size = sizeof(effect_param_t) + voffset + p->vsize;
if (p->status != 0)
return 0;
switch (param) {
case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
*(uint32_t *)value = 1;
break;
case BASSBOOST_PARAM_STRENGTH:
*(int16_t *)value = bassboost_get_strength(bass_ctxt);
break;
default:
p->status = -EINVAL;
break;
}
return 0;
}
int bassboost_set_parameter(effect_context_t *context, effect_param_t *p,
uint32_t size __unused)
{
bassboost_context_t *bass_ctxt = (bassboost_context_t *)context;
int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
void *value = p->data + voffset;
int32_t *param_tmp = (int32_t *)p->data;
int32_t param = *param_tmp++;
uint32_t strength;
ALOGV("%s: ctxt %p, param %d", __func__, bass_ctxt, param);
p->status = 0;
switch (param) {
case BASSBOOST_PARAM_STRENGTH:
strength = (uint32_t)(*(int16_t *)value);
bassboost_set_strength(bass_ctxt, strength);
break;
default:
p->status = -EINVAL;
break;
}
return 0;
}
int bassboost_set_device(effect_context_t *context, uint32_t device)
{
bassboost_context_t *bass_ctxt = (bassboost_context_t *)context;
ALOGV("%s: ctxt %p, device 0x%x", __func__, bass_ctxt, device);
bass_ctxt->device = device;
if((device == AUDIO_DEVICE_OUT_SPEAKER) ||
(device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) ||
(device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER) ||
#ifdef AFE_PROXY_ENABLED
(device == AUDIO_DEVICE_OUT_PROXY) ||
#endif
(device == AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
(device == AUDIO_DEVICE_OUT_USB_ACCESSORY) ||
(device == AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET)) {
if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET ||
device == AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) {
if (bass_ctxt->temp_disabled) {
if (effect_is_active(&bass_ctxt->common)) {
offload_bassboost_set_enable_flag(&(bass_ctxt->offload_bass), true);
if (bass_ctxt->ctl)
offload_bassboost_send_params(bass_ctxt->ctl,
&bass_ctxt->offload_bass,
OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG);
if (bass_ctxt->hw_acc_fd > 0)
hw_acc_bassboost_send_params(bass_ctxt->hw_acc_fd,
&bass_ctxt->offload_bass,
OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG);
}
bass_ctxt->temp_disabled = false;
}
} else {
if (!bass_ctxt->temp_disabled) {
if (effect_is_active(&bass_ctxt->common)) {
offload_bassboost_set_enable_flag(&(bass_ctxt->offload_bass), false);
@ -178,21 +349,6 @@ int bassboost_set_device(effect_context_t *context, uint32_t device)
bass_ctxt->temp_disabled = true;
}
ALOGI("%s: ctxt %p, disabled based on device", __func__, bass_ctxt);
} else {
if (bass_ctxt->temp_disabled) {
if (effect_is_active(&bass_ctxt->common)) {
offload_bassboost_set_enable_flag(&(bass_ctxt->offload_bass), true);
if (bass_ctxt->ctl)
offload_bassboost_send_params(bass_ctxt->ctl,
&bass_ctxt->offload_bass,
OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG);
if (bass_ctxt->hw_acc_fd > 0)
hw_acc_bassboost_send_params(bass_ctxt->hw_acc_fd,
&bass_ctxt->offload_bass,
OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG);
}
bass_ctxt->temp_disabled = false;
}
}
offload_bassboost_set_device(&(bass_ctxt->offload_bass), device);
return 0;
@ -329,3 +485,234 @@ int bassboost_set_mode(effect_context_t *context, int32_t hw_acc_fd)
OFFLOAD_SEND_BASSBOOST_STRENGTH);
return 0;
}
#undef LOG_TAG
#define LOG_TAG "offload_effect_pbe"
/*
* PBE operations
*/
int pbe_set_device(effect_context_t *context, uint32_t device)
{
pbe_context_t *pbe_ctxt = (pbe_context_t *)context;
char propValue[PROPERTY_VALUE_MAX];
bool pbe_enabled_by_prop = false;
ALOGV("%s: device: %d", __func__, device);
pbe_ctxt->device = device;
if (property_get("audio.safx.pbe.enabled", propValue, NULL)) {
pbe_enabled_by_prop = atoi(propValue) ||
!strncmp("true", propValue, 4);
}
if (device == AUDIO_DEVICE_OUT_SPEAKER && pbe_enabled_by_prop == true) {
if (pbe_ctxt->temp_disabled) {
if (effect_is_active(&pbe_ctxt->common)) {
offload_pbe_set_enable_flag(&(pbe_ctxt->offload_pbe), true);
if (pbe_ctxt->ctl)
offload_pbe_send_params(pbe_ctxt->ctl,
&pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG |
OFFLOAD_SEND_PBE_CONFIG);
if (pbe_ctxt->hw_acc_fd > 0)
hw_acc_pbe_send_params(pbe_ctxt->hw_acc_fd,
&pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG |
OFFLOAD_SEND_PBE_CONFIG);
}
pbe_ctxt->temp_disabled = false;
}
} else {
if (!pbe_ctxt->temp_disabled) {
if (effect_is_active(&pbe_ctxt->common)) {
offload_pbe_set_enable_flag(&(pbe_ctxt->offload_pbe), false);
if (pbe_ctxt->ctl)
offload_pbe_send_params(pbe_ctxt->ctl,
&pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG);
if (pbe_ctxt->hw_acc_fd > 0)
hw_acc_pbe_send_params(pbe_ctxt->hw_acc_fd,
&pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG);
}
pbe_ctxt->temp_disabled = true;
}
}
offload_pbe_set_device(&(pbe_ctxt->offload_pbe), device);
return 0;
}
int pbe_reset(effect_context_t *context)
{
pbe_context_t *pbe_ctxt = (pbe_context_t *)context;
return 0;
}
int pbe_init(effect_context_t *context)
{
pbe_context_t *pbe_ctxt = (pbe_context_t *)context;
ALOGV("%s", __func__);
context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
context->config.inputCfg.samplingRate = 44100;
context->config.inputCfg.bufferProvider.getBuffer = NULL;
context->config.inputCfg.bufferProvider.releaseBuffer = NULL;
context->config.inputCfg.bufferProvider.cookie = NULL;
context->config.inputCfg.mask = EFFECT_CONFIG_ALL;
context->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
context->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
context->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
context->config.outputCfg.samplingRate = 44100;
context->config.outputCfg.bufferProvider.getBuffer = NULL;
context->config.outputCfg.bufferProvider.releaseBuffer = NULL;
context->config.outputCfg.bufferProvider.cookie = NULL;
context->config.outputCfg.mask = EFFECT_CONFIG_ALL;
set_config(context, &context->config);
pbe_ctxt->hw_acc_fd = -1;
pbe_ctxt->temp_disabled = false;
memset(&(pbe_ctxt->offload_pbe), 0, sizeof(struct pbe_params));
pbe_load_config(&(pbe_ctxt->offload_pbe));
return 0;
}
int pbe_enable(effect_context_t *context)
{
pbe_context_t *pbe_ctxt = (pbe_context_t *)context;
ALOGV("%s", __func__);
if (!offload_pbe_get_enable_flag(&(pbe_ctxt->offload_pbe)) &&
!(pbe_ctxt->temp_disabled)) {
offload_pbe_set_enable_flag(&(pbe_ctxt->offload_pbe), true);
if (pbe_ctxt->ctl)
offload_pbe_send_params(pbe_ctxt->ctl,
&pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG |
OFFLOAD_SEND_PBE_CONFIG);
if (pbe_ctxt->hw_acc_fd > 0)
hw_acc_pbe_send_params(pbe_ctxt->hw_acc_fd,
&pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG |
OFFLOAD_SEND_PBE_CONFIG);
}
return 0;
}
int pbe_disable(effect_context_t *context)
{
pbe_context_t *pbe_ctxt = (pbe_context_t *)context;
ALOGV("%s", __func__);
if (offload_pbe_get_enable_flag(&(pbe_ctxt->offload_pbe))) {
offload_pbe_set_enable_flag(&(pbe_ctxt->offload_pbe), false);
if (pbe_ctxt->ctl)
offload_pbe_send_params(pbe_ctxt->ctl,
&pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG);
if (pbe_ctxt->hw_acc_fd > 0)
hw_acc_pbe_send_params(pbe_ctxt->hw_acc_fd,
&pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG);
}
return 0;
}
int pbe_start(effect_context_t *context, output_context_t *output)
{
pbe_context_t *pbe_ctxt = (pbe_context_t *)context;
ALOGV("%s", __func__);
pbe_ctxt->ctl = output->ctl;
ALOGV("output->ctl: %p", output->ctl);
if (offload_pbe_get_enable_flag(&(pbe_ctxt->offload_pbe))) {
if (pbe_ctxt->ctl)
offload_pbe_send_params(pbe_ctxt->ctl, &pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG |
OFFLOAD_SEND_PBE_CONFIG);
if (pbe_ctxt->hw_acc_fd > 0)
hw_acc_pbe_send_params(pbe_ctxt->hw_acc_fd,
&pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG |
OFFLOAD_SEND_PBE_CONFIG);
}
return 0;
}
int pbe_stop(effect_context_t *context, output_context_t *output __unused)
{
pbe_context_t *pbe_ctxt = (pbe_context_t *)context;
ALOGV("%s", __func__);
pbe_ctxt->ctl = NULL;
return 0;
}
int pbe_set_mode(effect_context_t *context, int32_t hw_acc_fd)
{
pbe_context_t *pbe_ctxt = (pbe_context_t *)context;
ALOGV("%s: ctxt %p", __func__, pbe_ctxt);
pbe_ctxt->hw_acc_fd = hw_acc_fd;
if ((pbe_ctxt->hw_acc_fd > 0) &&
(offload_pbe_get_enable_flag(&(pbe_ctxt->offload_pbe))))
hw_acc_pbe_send_params(pbe_ctxt->hw_acc_fd,
&pbe_ctxt->offload_pbe,
OFFLOAD_SEND_PBE_ENABLE_FLAG |
OFFLOAD_SEND_PBE_CONFIG);
return 0;
}
static int pbe_load_config(struct pbe_params *params)
{
int ret = 0;
uint32_t len = 0;
uint32_t propValue = 0;
uint32_t pbe_app_type = PBE_CONF_APP_ID;
char propValueStr[PROPERTY_VALUE_MAX];
void *acdb_handle = NULL;
acdb_get_audio_cal_t acdb_get_audio_cal = NULL;
acdb_audio_cal_cfg_t cal_cfg = {0};
acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
if (acdb_handle == NULL) {
ALOGE("%s error opening library %s", __func__, LIB_ACDB_LOADER);
return -EFAULT;
}
acdb_get_audio_cal = (acdb_get_audio_cal_t)dlsym(acdb_handle,
"acdb_loader_get_audio_cal_v2");
if (acdb_get_audio_cal == NULL) {
dlclose(acdb_handle);
ALOGE("%s error resolving acdb func symbols", __func__);
return -EFAULT;
}
if (property_get("audio.safx.pbe.app.type", propValueStr, "0")) {
propValue = atoll(propValueStr);
if (propValue != 0) {
pbe_app_type = propValue;
}
}
ALOGD("%s pbe_app_type = 0x%.8x", __func__, pbe_app_type);
cal_cfg.persist = 1;
cal_cfg.cal_type = AUDIO_STREAM_CAL_TYPE;
cal_cfg.app_type = pbe_app_type;
cal_cfg.module_id = PBE_CONF_MODULE_ID;
cal_cfg.param_id = PBE_CONF_PARAM_ID;
len = sizeof(params->config);
ret = acdb_get_audio_cal((void *)&cal_cfg, (void*)&(params->config), &len);
ALOGD("%s ret = %d, len = %u", __func__, ret, len);
if (ret == 0)
params->cfg_len = len;
dlclose(acdb_handle);
return ret;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@ -22,6 +22,13 @@
#include "bundle.h"
enum {
BASS_INVALID = -1,
BASS_BOOST = 0, // index of bassboost
BASS_PBE, // index of PBE
BASS_COUNT // totol number of bass type
};
extern const effect_descriptor_t bassboost_descriptor;
typedef struct bassboost_context_s {
@ -37,11 +44,50 @@ typedef struct bassboost_context_s {
struct bass_boost_params offload_bass;
} bassboost_context_t;
int bassboost_get_parameter(effect_context_t *context, effect_param_t *p,
uint32_t *size);
typedef struct pbe_context_s {
effect_context_t common;
int bassboost_set_parameter(effect_context_t *context, effect_param_t *p,
uint32_t size);
// Offload vars
struct mixer_ctl *ctl;
int hw_acc_fd;
bool temp_disabled;
uint32_t device;
struct pbe_params offload_pbe;
} pbe_context_t;
typedef struct bass_context_s {
effect_context_t common;
bassboost_context_t bassboost_ctxt;
pbe_context_t pbe_ctxt;
int active_index;
} bass_context_t;
int bass_get_parameter(effect_context_t *context, effect_param_t *p,
uint32_t *size);
int bass_set_parameter(effect_context_t *context, effect_param_t *p,
uint32_t size);
int bass_set_device(effect_context_t *context, uint32_t device);
int bass_set_mode(effect_context_t *context, int32_t hw_acc_fd);
int bass_reset(effect_context_t *context);
int bass_init(effect_context_t *context);
int bass_enable(effect_context_t *context);
int bass_disable(effect_context_t *context);
int bass_start(effect_context_t *context, output_context_t *output);
int bass_stop(effect_context_t *context, output_context_t *output);
int bassboost_get_strength(bassboost_context_t *context);
int bassboost_set_strength(bassboost_context_t *context, uint32_t strength);
int bassboost_set_device(effect_context_t *context, uint32_t device);
@ -59,4 +105,20 @@ int bassboost_start(effect_context_t *context, output_context_t *output);
int bassboost_stop(effect_context_t *context, output_context_t *output);
int pbe_set_device(effect_context_t *context, uint32_t device);
int pbe_set_mode(effect_context_t *context, int32_t hw_acc_fd);
int pbe_reset(effect_context_t *context);
int pbe_init(effect_context_t *context);
int pbe_enable(effect_context_t *context);
int pbe_disable(effect_context_t *context);
int pbe_start(effect_context_t *context, output_context_t *output);
int pbe_stop(effect_context_t *context, output_context_t *output);
#endif /* OFFLOAD_EFFECT_BASS_BOOST_H_ */

View File

@ -520,25 +520,26 @@ int effect_lib_create(const effect_uuid_t *uuid,
eq_ctxt->ctl = NULL;
} else if (memcmp(uuid, &bassboost_descriptor.uuid,
sizeof(effect_uuid_t)) == 0) {
bassboost_context_t *bass_ctxt = (bassboost_context_t *)
calloc(1, sizeof(bassboost_context_t));
bass_context_t *bass_ctxt = (bass_context_t *)
calloc(1, sizeof(bass_context_t));
if (bass_ctxt == NULL) {
return -ENOMEM;
}
context = (effect_context_t *)bass_ctxt;
context->ops.init = bassboost_init;
context->ops.reset = bassboost_reset;
context->ops.set_parameter = bassboost_set_parameter;
context->ops.get_parameter = bassboost_get_parameter;
context->ops.set_device = bassboost_set_device;
context->ops.set_hw_acc_mode = bassboost_set_mode;
context->ops.enable = bassboost_enable;
context->ops.disable = bassboost_disable;
context->ops.start = bassboost_start;
context->ops.stop = bassboost_stop;
context->ops.init = bass_init;
context->ops.reset = bass_reset;
context->ops.set_parameter = bass_set_parameter;
context->ops.get_parameter = bass_get_parameter;
context->ops.set_device = bass_set_device;
context->ops.set_hw_acc_mode = bass_set_mode;
context->ops.enable = bass_enable;
context->ops.disable = bass_disable;
context->ops.start = bass_start;
context->ops.stop = bass_stop;
context->desc = &bassboost_descriptor;
bass_ctxt->ctl = NULL;
bass_ctxt->bassboost_ctxt.ctl = NULL;
bass_ctxt->pbe_ctxt.ctl = NULL;
} else if (memcmp(uuid, &virtualizer_descriptor.uuid,
sizeof(effect_uuid_t)) == 0) {
virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -235,6 +235,83 @@ int hw_acc_bassboost_send_params(int fd, struct bass_boost_params *bassboost,
bassboost, param_send_flags);
}
void offload_pbe_set_device(struct pbe_params *pbe,
uint32_t device)
{
ALOGV("%s: device=%d", __func__, device);
pbe->device = device;
}
void offload_pbe_set_enable_flag(struct pbe_params *pbe,
bool enable)
{
ALOGV("%s: enable=%d", __func__, enable);
pbe->enable_flag = enable;
}
int offload_pbe_get_enable_flag(struct pbe_params *pbe)
{
ALOGV("%s: enabled=%d", __func__, pbe->enable_flag);
return pbe->enable_flag;
}
static int pbe_send_params(eff_mode_t mode, void *ctl,
struct pbe_params *pbe,
unsigned param_send_flags)
{
int param_values[128] = {0};
int i, *p_param_values = param_values, *cfg = NULL;
ALOGV("%s: enabled=%d", __func__, pbe->enable_flag);
*p_param_values++ = PBE_MODULE;
*p_param_values++ = pbe->device;
*p_param_values++ = 0; /* num of commands*/
if (param_send_flags & OFFLOAD_SEND_PBE_ENABLE_FLAG) {
*p_param_values++ = PBE_ENABLE;
*p_param_values++ = CONFIG_SET;
*p_param_values++ = 0; /* start offset if param size if greater than 128 */
*p_param_values++ = PBE_ENABLE_PARAM_LEN;
*p_param_values++ = pbe->enable_flag;
param_values[2] += 1;
}
if (param_send_flags & OFFLOAD_SEND_PBE_CONFIG) {
*p_param_values++ = PBE_CONFIG;
*p_param_values++ = CONFIG_SET;
*p_param_values++ = 0; /* start offset if param size if greater than 128 */
*p_param_values++ = pbe->cfg_len;
cfg = (int *)&pbe->config;
for (i = 0; i < (int)pbe->cfg_len ; i+= sizeof(*p_param_values))
*p_param_values++ = *cfg++;
param_values[2] += 1;
}
if ((mode == OFFLOAD) && param_values[2] && ctl) {
mixer_ctl_set_array((struct mixer_ctl *)ctl, param_values,
ARRAY_SIZE(param_values));
} else if ((mode == HW_ACCELERATOR) && param_values[2] &&
ctl && *(int *)ctl) {
if (ioctl(*(int *)ctl, AUDIO_EFFECTS_SET_PP_PARAMS, param_values) < 0)
ALOGE("%s: sending h/w acc effects params fail[%d]", __func__, errno);
}
return 0;
}
int offload_pbe_send_params(struct mixer_ctl *ctl,
struct pbe_params *pbe,
unsigned param_send_flags)
{
return pbe_send_params(OFFLOAD, (void *)ctl, pbe,
param_send_flags);
}
int hw_acc_pbe_send_params(int fd, struct pbe_params *pbe,
unsigned param_send_flags)
{
return pbe_send_params(HW_ACCELERATOR, (void *)&fd,
pbe, param_send_flags);
}
void offload_virtualizer_set_device(struct virtualizer_params *virtualizer,
uint32_t device)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -39,6 +39,21 @@ int offload_update_mixer_and_effects_ctl(int card, int device_id,
struct mixer_ctl **ctl);
void offload_close_mixer(struct mixer **mixer);
#define OFFLOAD_SEND_PBE_ENABLE_FLAG (1 << 0)
#define OFFLOAD_SEND_PBE_CONFIG (OFFLOAD_SEND_PBE_ENABLE_FLAG << 1)
void offload_pbe_set_device(struct pbe_params *pbe,
uint32_t device);
void offload_pbe_set_enable_flag(struct pbe_params *pbe,
bool enable);
int offload_pbe_get_enable_flag(struct pbe_params *pbe);
int offload_pbe_send_params(struct mixer_ctl *ctl,
struct pbe_params *pbe,
unsigned param_send_flags);
int hw_acc_pbe_send_params(int fd,
struct pbe_params *pbe,
unsigned param_send_flags);
#define OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG (1 << 0)
#define OFFLOAD_SEND_BASSBOOST_STRENGTH \
(OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG << 1)