post_proc: Support Headphone:X in offload and non tunnel modes
Support Headphone:X in offload and non tunnel modes
Change-Id: Ib30d60bce67cb43556d58a2387735ce715d035a4
Signed-off-by: Alexy Joseph <alexyj@codeaurora.org>
diff --git a/post_proc/Android.mk b/post_proc/Android.mk
index e253159..880838a 100644
--- a/post_proc/Android.mk
+++ b/post_proc/Android.mk
@@ -59,6 +59,10 @@
LOCAL_CFLAGS += -O2 -fvisibility=hidden
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DTS_EAGLE)), true)
+LOCAL_CFLAGS += -DHW_ACC_HPX
+endif
+
LOCAL_MODULE:= libhwacceffectswrapper
include $(BUILD_STATIC_LIBRARY)
diff --git a/post_proc/EffectsHwAcc.cpp b/post_proc/EffectsHwAcc.cpp
index d88a199..0e4c55a 100644
--- a/post_proc/EffectsHwAcc.cpp
+++ b/post_proc/EffectsHwAcc.cpp
@@ -343,5 +343,33 @@
}
}
+#ifdef HW_ACC_HPX
+void EffectsHwAcc::updateHPXState(uint32_t state)
+{
+ EffectsBufferProvider *pHwAccbp = mBufferProvider;
+ if (pHwAccbp) {
+ ALOGV("updateHPXState: %d", state);
+ int cmdStatus, status;
+ uint32_t replySize = sizeof(int);
+ uint32_t data = state;
+ uint32_t size = (sizeof(effect_param_t) + 2 * sizeof(int32_t));
+ uint32_t buf32[size];
+ effect_param_t *param = (effect_param_t *)buf32;
+
+ param->psize = sizeof(int32_t);
+ *(int32_t *)param->data = HW_ACCELERATOR_HPX_STATE;
+ param->vsize = sizeof(int32_t);
+ memcpy((param->data + param->psize), &data, param->vsize);
+ status = (*pHwAccbp->mEffectsHandle)->command(pHwAccbp->mEffectsHandle,
+ EFFECT_CMD_SET_PARAM,
+ sizeof(effect_param_t) + param->psize +
+ param->vsize,
+ param, &replySize, &cmdStatus);
+
+ if ((status != 0) || (cmdStatus != 0))
+ ALOGE("error %d while updating HW ACC HPX BYPASS state", status);
+ }
+}
+#endif
// ----------------------------------------------------------------------------
}; // namespace android
diff --git a/post_proc/EffectsHwAcc.h b/post_proc/EffectsHwAcc.h
index 919332b..6420a9b 100644
--- a/post_proc/EffectsHwAcc.h
+++ b/post_proc/EffectsHwAcc.h
@@ -48,6 +48,10 @@
int frameCount);
virtual void setBufferProvider(AudioBufferProvider **bufferProvider,
AudioBufferProvider **trackBufferProvider);
+#ifdef HW_ACC_HPX
+ virtual void updateHPXState(uint32_t state);
+#endif
+
/* AudioBufferProvider that wraps a track AudioBufferProvider by a call to
h/w accelerated effect */
class EffectsBufferProvider : public AudioBufferProvider {
diff --git a/post_proc/bundle.c b/post_proc/bundle.c
index 871b087..410e17b 100644
--- a/post_proc/bundle.c
+++ b/post_proc/bundle.c
@@ -326,6 +326,132 @@
return ret;
}
+__attribute__ ((visibility ("default")))
+int offload_effects_bundle_set_hpx_state(bool hpx_state)
+{
+ int ret = 0;
+ struct listnode *node;
+
+ ALOGV("%s hpx state: %d", __func__, hpx_state);
+
+ if (lib_init() != 0)
+ return init_status;
+
+ pthread_mutex_lock(&lock);
+
+ if (hpx_state) {
+ /* set ramp down */
+ list_for_each(node, &active_outputs_list) {
+ output_context_t *out_ctxt = node_to_item(node,
+ output_context_t,
+ outputs_list_node);
+ struct soft_volume_params vol;
+ vol.master_gain = 0x0;
+ offload_transition_soft_volume_send_params(out_ctxt->ref_ctl, vol,
+ OFFLOAD_SEND_TRANSITION_SOFT_VOLUME_GAIN_MASTER);
+ }
+ /* wait for ramp down duration - 30msec */
+ usleep(30000);
+ /* disable effects modules */
+ list_for_each(node, &active_outputs_list) {
+ struct listnode *fx_node;
+ output_context_t *out_ctxt = node_to_item(node,
+ output_context_t,
+ outputs_list_node);
+ list_for_each(fx_node, &out_ctxt->effects_list) {
+ effect_context_t *fx_ctxt = node_to_item(fx_node,
+ effect_context_t,
+ output_node);
+ if ((fx_ctxt->state == EFFECT_STATE_ACTIVE) &&
+ (fx_ctxt->ops.stop != NULL))
+ fx_ctxt->ops.stop(fx_ctxt, out_ctxt);
+ }
+ out_ctxt->ctl = NULL;
+ }
+ /* set the channel mixer */
+ list_for_each(node, &active_outputs_list) {
+ /* send command to set channel mixer */
+ }
+ /* enable hpx modules */
+ list_for_each(node, &active_outputs_list) {
+ output_context_t *out_ctxt = node_to_item(node,
+ output_context_t,
+ outputs_list_node);
+ offload_hpx_send_params(out_ctxt->ref_ctl,
+ OFFLOAD_SEND_HPX_STATE_ON);
+ }
+ /* wait for transition state - 50msec */
+ usleep(50000);
+ /* set ramp up */
+ list_for_each(node, &active_outputs_list) {
+ output_context_t *out_ctxt = node_to_item(node,
+ output_context_t,
+ outputs_list_node);
+ struct soft_volume_params vol;
+ vol.master_gain = 0x2000;
+ offload_transition_soft_volume_send_params(out_ctxt->ref_ctl, vol,
+ OFFLOAD_SEND_TRANSITION_SOFT_VOLUME_GAIN_MASTER);
+ }
+ } else {
+ /* set ramp down */
+ list_for_each(node, &active_outputs_list) {
+ output_context_t *out_ctxt = node_to_item(node,
+ output_context_t,
+ outputs_list_node);
+ struct soft_volume_params vol;
+ vol.master_gain = 0x0;
+ offload_transition_soft_volume_send_params(out_ctxt->ref_ctl, vol,
+ OFFLOAD_SEND_TRANSITION_SOFT_VOLUME_GAIN_MASTER);
+ }
+ /* wait for ramp down duration - 30msec */
+ usleep(30000);
+ /* disable effects modules */
+ list_for_each(node, &active_outputs_list) {
+ output_context_t *out_ctxt = node_to_item(node,
+ output_context_t,
+ outputs_list_node);
+ offload_hpx_send_params(out_ctxt->ref_ctl,
+ OFFLOAD_SEND_HPX_STATE_OFF);
+ }
+ /* set the channel mixer */
+ list_for_each(node, &active_outputs_list) {
+ /* send command to set channel mixer */
+ }
+ /* enable effects modules */
+ list_for_each(node, &active_outputs_list) {
+ struct listnode *fx_node;
+ output_context_t *out_ctxt = node_to_item(node,
+ output_context_t,
+ outputs_list_node);
+ out_ctxt->ctl = out_ctxt->ref_ctl;
+ list_for_each(fx_node, &out_ctxt->effects_list) {
+ effect_context_t *fx_ctxt = node_to_item(fx_node,
+ effect_context_t,
+ output_node);
+ if ((fx_ctxt->state == EFFECT_STATE_ACTIVE) &&
+ (fx_ctxt->ops.start != NULL))
+ fx_ctxt->ops.start(fx_ctxt, out_ctxt);
+ }
+ }
+ /* wait for transition state - 50msec */
+ usleep(50000);
+ /* set ramp up */
+ list_for_each(node, &active_outputs_list) {
+ output_context_t *out_ctxt = node_to_item(node,
+ output_context_t,
+ outputs_list_node);
+ struct soft_volume_params vol;
+ vol.master_gain = 0x2000;
+ offload_transition_soft_volume_send_params(out_ctxt->ref_ctl, vol,
+ OFFLOAD_SEND_TRANSITION_SOFT_VOLUME_GAIN_MASTER);
+ }
+ }
+
+exit:
+ pthread_mutex_unlock(&lock);
+ return ret;
+}
+
/*
* Effect operations
*/
diff --git a/post_proc/effect_api.c b/post_proc/effect_api.c
index 61f6f00..7c1968e 100644
--- a/post_proc/effect_api.c
+++ b/post_proc/effect_api.c
@@ -882,3 +882,38 @@
return 0;
}
+
+static int hpx_send_params(eff_mode_t mode, void *ctl,
+ unsigned param_send_flags)
+{
+ int param_values[128] = {0};
+ int *p_param_values = param_values;
+ uint32_t i;
+
+ ALOGV("%s", __func__);
+ if (param_send_flags & OFFLOAD_SEND_HPX_STATE_OFF) {
+ *p_param_values++ = DTS_EAGLE_MODULE_ENABLE;
+ *p_param_values++ = 0; /* hpx off*/
+ } else if (param_send_flags & OFFLOAD_SEND_HPX_STATE_ON) {
+ *p_param_values++ = DTS_EAGLE_MODULE_ENABLE;
+ *p_param_values++ = 1; /* hpx on*/
+ }
+
+ if ((mode == OFFLOAD) && ctl)
+ mixer_ctl_set_array(ctl, param_values, ARRAY_SIZE(param_values));
+ else {
+ if (ioctl(*(int *)ctl, AUDIO_EFFECTS_SET_PP_PARAMS, param_values) < 0)
+ ALOGE("%s: sending h/w acc hpx state params fail[%d]", __func__, errno);
+ }
+ return 0;
+}
+
+int offload_hpx_send_params(struct mixer_ctl *ctl, unsigned param_send_flags)
+{
+ return hpx_send_params(OFFLOAD, (void *)ctl, param_send_flags);
+}
+
+int hw_acc_hpx_send_params(int fd, unsigned param_send_flags)
+{
+ return hpx_send_params(HW_ACCELERATOR, (void *)&fd, param_send_flags);
+}
diff --git a/post_proc/effect_api.h b/post_proc/effect_api.h
index d3b1d81..e05924a 100644
--- a/post_proc/effect_api.h
+++ b/post_proc/effect_api.h
@@ -192,6 +192,12 @@
int offload_transition_soft_volume_send_params(struct mixer_ctl *ctl,
struct soft_volume_params vol,
unsigned param_send_flags);
+
+#define OFFLOAD_SEND_HPX_STATE_ON (1 << 0)
+#define OFFLOAD_SEND_HPX_STATE_OFF (OFFLOAD_SEND_HPX_STATE_ON << 1)
+int offload_hpx_send_params(struct mixer_ctl *ctl, unsigned param_send_flags);
+int hw_acc_hpx_send_params(int fd, unsigned param_send_flags);
+
#if __cplusplus
} //extern "C"
#endif
diff --git a/post_proc/hw_accelerator.c b/post_proc/hw_accelerator.c
index b49337a..fd95db0 100644
--- a/post_proc/hw_accelerator.c
+++ b/post_proc/hw_accelerator.c
@@ -111,7 +111,14 @@
p->status = 0;
switch (param) {
- /* Placeholder for effects to use set param */
+ case HW_ACCELERATOR_HPX_STATE: {
+ int hpxState = (uint32_t)(*(int32_t *)value);
+ if (hpxState)
+ hw_acc_hpx_send_params(hw_acc_ctxt->fd, OFFLOAD_SEND_HPX_STATE_ON);
+ else
+ hw_acc_hpx_send_params(hw_acc_ctxt->fd, OFFLOAD_SEND_HPX_STATE_OFF);
+ break;
+ }
default:
p->status = -EINVAL;
break;