From 5f15ff9b7dc319bd5937c2d401eaefeb83a3d1c1 Mon Sep 17 00:00:00 2001 From: Dhananjay Kumar Date: Mon, 19 May 2014 16:45:08 +0800 Subject: [PATCH] post_proc: add PBE effect for speaker Enable PBE for speaker device. Change-Id: I1a48dff038baf63376f1d4b355888159cf69ba81 --- post_proc/Android.mk | 3 +- post_proc/bass_boost.c | 595 ++++++++++++++++++++++++++++++++++------- post_proc/bass_boost.h | 72 ++++- post_proc/bundle.c | 27 +- post_proc/effect_api.c | 79 +++++- post_proc/effect_api.h | 17 +- 6 files changed, 668 insertions(+), 125 deletions(-) diff --git a/post_proc/Android.mk b/post_proc/Android.mk index 880838ae..be70166a 100644 --- a/post_proc/Android.mk +++ b/post_proc/Android.mk @@ -26,7 +26,8 @@ endif LOCAL_SHARED_LIBRARIES := \ libcutils \ liblog \ - libtinyalsa + libtinyalsa \ + libdl LOCAL_MODULE_TAGS := optional diff --git a/post_proc/bass_boost.c b/post_proc/bass_boost.c index 57cf8efd..ad1e7c9f 100644 --- a/post_proc/bass_boost.c +++ b/post_proc/bass_boost.c @@ -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 #include +#include #include #include #include +#include +#include #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; +} diff --git a/post_proc/bass_boost.h b/post_proc/bass_boost.h index 6f0e61b6..14d6c977 100644 --- a/post_proc/bass_boost.h +++ b/post_proc/bass_boost.h @@ -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_ */ diff --git a/post_proc/bundle.c b/post_proc/bundle.c index 606c66b4..a89b02ba 100644 --- a/post_proc/bundle.c +++ b/post_proc/bundle.c @@ -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 *) diff --git a/post_proc/effect_api.c b/post_proc/effect_api.c index 7c1968e4..c850fa52 100644 --- a/post_proc/effect_api.c +++ b/post_proc/effect_api.c @@ -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) { diff --git a/post_proc/effect_api.h b/post_proc/effect_api.h index e05924a4..ce0503a7 100644 --- a/post_proc/effect_api.h +++ b/post_proc/effect_api.h @@ -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)