summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwjiang <wjiang@codeaurora.org>2014-03-28 12:29:58 +0800
committerSteve Kondik <steve@cyngn.com>2016-03-23 22:06:58 -0700
commit9828fdc5c7183c627eccd752c731541d61311ea4 (patch)
tree7ce68d1b36d729ce3b0f08b288463c5a80a94a6e
parent3e55a8628681cc32c38d97f11b5e44881d56bc96 (diff)
downloadandroid_hardware_qcom_audio-9828fdc5c7183c627eccd752c731541d61311ea4.tar.gz
android_hardware_qcom_audio-9828fdc5c7183c627eccd752c731541d61311ea4.tar.bz2
android_hardware_qcom_audio-9828fdc5c7183c627eccd752c731541d61311ea4.zip
post_proc: Squash upstream changes
post_proc: disable effect immediately when routed to invalid devices Offload effect is still perceived when invalid output device is connected. We should send disable command immediately once phone is routed to unexpected device and forbid effect enablement during temporary disabled state. Change-Id: I26d4ccfd77037a879622b0437ae3916ff0071a69 CRs-Fixed: 630408 post_proc: disable Bassboost and Virtualizer for USB_ACCESSORY USB_ACCESSORY is not intended to be applied with SA+ bassboost and virtualizer, so add into invalid devices list. CRs-Fixed: 659191 Change-Id: If1f3421f9935ce624dc21895d9244d36d195b2bd post_proc: fix post and pre process KW issues KW issue fix includes: - handle memory allocation failure - array index boundary check Change-Id: I083952ba58d348a5b650601a83e6f492b0d686bb post_proc: Fix improper datatype of EQ preset band level value unsigned int causes negative band level turn out to be extreme large value, which results in EQ works abnormally due to unexpected parameter sent. Change-Id: I81120c604f4e9f23b25d5a45a7b0294fea63d207 CRs-Fixed: 696825 post_proc: add support for virtualizer capability query Add extra virtualizer interfaces to keep align with aosp design. Extended capabilities include: - Stub interface to allow querying speaker angles. - Force set output device as specific virtualize mode. - Query virtualize mode Stub function remains to be refined in sync with upcoming aosp changes. Change-Id: I3316f6d944db1c9954eda7643a5ce433defa1a6c CRs-Fixed: 810294 post_proc: remove unnecessary command size check Up bound check for command size of EFFECT_CMD_SET_PARAM is not applicable for DSP effect bundle. Remove the check to avoid parameter not taking effect. Change-Id: I7e8f73377699f11bdc1f62a05f6bea03c9c24151 CRs-Fixed: 816053 post_proc: explicitly disable virtualizer module if strength is 0 0 stength in DSP virtualizer is not equivalent to disable state as down mix is still happening for multichannel inputs. For better user experience, explicitly disable virtualizer module when strength is 0. Change-Id: Ic2884ac7010e4f835df871719d546c0c05173f4b CRs-Fixed: 872772 post_proc: fix reverb processing issue when preset is set to NONE Reverb effects are getting applied even after setting reverb preset to REVERB_PRESET_NONE. Preset NONE is used by client and is supposed to be equivalent to disabled state, even though this preset is not supported in DSP. Fix this issue by avoiding enable command from post processing HAL to DSP when preset NONE is in use. CRs-Fixed: 868041 Change-Id: Iad626a7400246e80a97a926234cfb7756ec6083e post_proc: fix crash in offload effect bundle during stop output Effect bundle stop() frees mixer contol before doing module stop(), whereas module's stop() still needs this control to send disable command down the layer. Crash is observed if memory associated with effect control is reused and gets altered by the time mixer control is completed. Move mixer control's deletion after module's stop() to fix this issue. CRs-Fixed: 860604 Change-Id: Ia8b6d5f847b69392afbda1ba77fc740a47aba25d
-rw-r--r--post_proc/bass_boost.c9
-rw-r--r--post_proc/bundle.c25
-rw-r--r--post_proc/effect_api.c5
-rw-r--r--post_proc/equalizer.c2
-rw-r--r--post_proc/reverb.c22
-rw-r--r--post_proc/reverb.h1
-rw-r--r--post_proc/virtualizer.c287
-rw-r--r--post_proc/virtualizer.h5
-rw-r--r--visualizer/offload_visualizer.c9
-rw-r--r--voice_processing/voice_processing.c8
10 files changed, 339 insertions, 34 deletions
diff --git a/post_proc/bass_boost.c b/post_proc/bass_boost.c
index f303886f..1cb68e3c 100644
--- a/post_proc/bass_boost.c
+++ b/post_proc/bass_boost.c
@@ -152,6 +152,7 @@ int bassboost_set_device(effect_context_t *context, uint32_t device)
(device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) ||
(device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER) ||
(device == AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
+ (device == AUDIO_DEVICE_OUT_USB_ACCESSORY) ||
(device == AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET)) {
if (!bass_ctxt->temp_disabled) {
if (effect_is_active(&bass_ctxt->common)) {
@@ -162,6 +163,10 @@ int bassboost_set_device(effect_context_t *context, uint32_t device)
OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG);
}
bass_ctxt->temp_disabled = true;
+ if (bass_ctxt->ctl)
+ offload_bassboost_send_params(bass_ctxt->ctl,
+ &bass_ctxt->offload_bass,
+ OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG);
}
} else {
if (bass_ctxt->temp_disabled) {
@@ -173,6 +178,10 @@ int bassboost_set_device(effect_context_t *context, uint32_t device)
OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG);
}
bass_ctxt->temp_disabled = false;
+ if (bass_ctxt->ctl)
+ offload_bassboost_send_params(bass_ctxt->ctl,
+ &bass_ctxt->offload_bass,
+ OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG);
}
}
offload_bassboost_set_device(&(bass_ctxt->offload_bass), device);
diff --git a/post_proc/bundle.c b/post_proc/bundle.c
index a6b07278..c728115c 100644
--- a/post_proc/bundle.c
+++ b/post_proc/bundle.c
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -198,6 +200,11 @@ int offload_effects_bundle_hal_start_output(audio_io_handle_t output, int pcm_id
out_ctxt = (output_context_t *)
malloc(sizeof(output_context_t));
+ if (!out_ctxt) {
+ ALOGE("%s fail to allocate for output context", __func__);
+ ret = -ENOMEM;
+ goto exit;
+ }
out_ctxt->handle = output;
out_ctxt->pcm_device_id = pcm_id;
@@ -263,9 +270,6 @@ int offload_effects_bundle_hal_stop_output(audio_io_handle_t output, int pcm_id)
goto exit;
}
- if (out_ctxt->mixer)
- mixer_close(out_ctxt->mixer);
-
list_for_each(fx_node, &out_ctxt->effects_list) {
effect_context_t *fx_ctxt = node_to_item(fx_node,
effect_context_t,
@@ -274,6 +278,9 @@ int offload_effects_bundle_hal_stop_output(audio_io_handle_t output, int pcm_id)
fx_ctxt->ops.stop(fx_ctxt, out_ctxt);
}
+ if (out_ctxt->mixer)
+ mixer_close(out_ctxt->mixer);
+
list_remove(&out_ctxt->outputs_list_node);
free(out_ctxt);
@@ -333,6 +340,9 @@ int effect_lib_create(const effect_uuid_t *uuid,
sizeof(effect_uuid_t)) == 0) {
equalizer_context_t *eq_ctxt = (equalizer_context_t *)
calloc(1, sizeof(equalizer_context_t));
+ if (eq_ctxt == NULL) {
+ return -ENOMEM;
+ }
context = (effect_context_t *)eq_ctxt;
context->ops.init = equalizer_init;
context->ops.reset = equalizer_reset;
@@ -350,6 +360,9 @@ int effect_lib_create(const effect_uuid_t *uuid,
sizeof(effect_uuid_t)) == 0) {
bassboost_context_t *bass_ctxt = (bassboost_context_t *)
calloc(1, sizeof(bassboost_context_t));
+ if (bass_ctxt == NULL) {
+ return -ENOMEM;
+ }
context = (effect_context_t *)bass_ctxt;
context->ops.init = bassboost_init;
context->ops.reset = bassboost_reset;
@@ -367,6 +380,9 @@ int effect_lib_create(const effect_uuid_t *uuid,
sizeof(effect_uuid_t)) == 0) {
virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)
calloc(1, sizeof(virtualizer_context_t));
+ if (virt_ctxt == NULL) {
+ return -ENOMEM;
+ }
context = (effect_context_t *)virt_ctxt;
context->ops.init = virtualizer_init;
context->ops.reset = virtualizer_reset;
@@ -390,6 +406,9 @@ int effect_lib_create(const effect_uuid_t *uuid,
sizeof(effect_uuid_t)) == 0)) {
reverb_context_t *reverb_ctxt = (reverb_context_t *)
calloc(1, sizeof(reverb_context_t));
+ if (reverb_ctxt == NULL) {
+ return -ENOMEM;
+ }
context = (effect_context_t *)reverb_ctxt;
context->ops.init = reverb_init;
context->ops.reset = reverb_reset;
diff --git a/post_proc/effect_api.c b/post_proc/effect_api.c
index 9c15e8f5..f2daadca 100644
--- a/post_proc/effect_api.c
+++ b/post_proc/effect_api.c
@@ -299,8 +299,9 @@ int offload_eq_send_params(struct mixer_ctl *ctl, struct eq_params *eq,
int *p_param_values = param_values;
uint32_t i;
- ALOGV("%s", __func__);
- if (eq->config.preset_id < -1 ) {
+ ALOGV("%s: flags 0x%x", __func__, param_send_flags);
+ if ((eq->config.preset_id < -1) ||
+ ((param_send_flags & OFFLOAD_SEND_EQ_PRESET) && (eq->config.preset_id == -1))) {
ALOGV("No Valid preset to set");
return 0;
}
diff --git a/post_proc/equalizer.c b/post_proc/equalizer.c
index 7cff3488..dfb40d8f 100644
--- a/post_proc/equalizer.c
+++ b/post_proc/equalizer.c
@@ -49,7 +49,7 @@ static const char *equalizer_preset_names[] = {
"Jazz",
"Pop",
"Rock"
- };
+};
static const uint32_t equalizer_band_freq_range[NUM_EQ_BANDS][2] = {
{30000, 120000},
diff --git a/post_proc/reverb.c b/post_proc/reverb.c
index e5fc9509..07086005 100644
--- a/post_proc/reverb.c
+++ b/post_proc/reverb.c
@@ -246,13 +246,15 @@ void reverb_set_preset(reverb_context_t *context, int16_t preset)
context->next_preset = preset;
offload_reverb_set_preset(&(context->offload_reverb), preset);
- enable = (preset == REVERB_PRESET_NONE) ? false: true;
- offload_reverb_set_enable_flag(&(context->offload_reverb), enable);
+ if (context->enabled_by_client) {
+ enable = (preset == REVERB_PRESET_NONE) ? false: true;
+ offload_reverb_set_enable_flag(&(context->offload_reverb), enable);
- if (context->ctl)
- offload_reverb_send_params(context->ctl, &context->offload_reverb,
+ if (context->ctl)
+ offload_reverb_send_params(context->ctl, &context->offload_reverb,
OFFLOAD_SEND_REVERB_ENABLE_FLAG |
OFFLOAD_SEND_REVERB_PRESET);
+ }
}
void reverb_set_all_properties(reverb_context_t *context,
@@ -568,6 +570,7 @@ int reverb_init(effect_context_t *context)
set_config(context, &context->config);
+ reverb_ctxt->enabled_by_client = false;
memset(&(reverb_ctxt->reverb_settings), 0, sizeof(reverb_settings_t));
memset(&(reverb_ctxt->offload_reverb), 0, sizeof(struct reverb_params));
@@ -583,6 +586,16 @@ int reverb_enable(effect_context_t *context)
reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
ALOGV("%s", __func__);
+ reverb_ctxt->enabled_by_client = true;
+
+ /* REVERB_PRESET_NONE is equivalent to disabled state,
+ * But support for this state is not provided in DSP.
+ * Hence, do not set enable flag, if in peset mode with preset "NONE".
+ * Effect would be enabled when valid preset is set.
+ */
+ if ((reverb_ctxt->preset == true) &&
+ (reverb_ctxt->next_preset == REVERB_PRESET_NONE))
+ return 0;
if (!offload_reverb_get_enable_flag(&(reverb_ctxt->offload_reverb)))
offload_reverb_set_enable_flag(&(reverb_ctxt->offload_reverb), true);
@@ -594,6 +607,7 @@ int reverb_disable(effect_context_t *context)
reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
ALOGV("%s", __func__);
+ reverb_ctxt->enabled_by_client = false;
if (offload_reverb_get_enable_flag(&(reverb_ctxt->offload_reverb))) {
offload_reverb_set_enable_flag(&(reverb_ctxt->offload_reverb), false);
if (reverb_ctxt->ctl)
diff --git a/post_proc/reverb.h b/post_proc/reverb.h
index aba2b275..f284f660 100644
--- a/post_proc/reverb.h
+++ b/post_proc/reverb.h
@@ -44,6 +44,7 @@ typedef struct reverb_context_s {
// Offload vars
struct mixer_ctl *ctl;
+ bool enabled_by_client;
bool auxiliary;
bool preset;
uint16_t cur_preset;
diff --git a/post_proc/virtualizer.c b/post_proc/virtualizer.c
index 40bbf38f..1ab59278 100644
--- a/post_proc/virtualizer.c
+++ b/post_proc/virtualizer.c
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,6 +55,15 @@ int virtualizer_set_strength(virtualizer_context_t *context, uint32_t strength)
ALOGV("%s: strength: %d", __func__, strength);
context->strength = strength;
+ /*
+ * Zero strength is not equivalent to disable state as down mix
+ * is still happening for multichannel inputs.
+ * For better user experience, explicitly disable virtualizer module
+ * when strength is 0.
+ */
+ offload_virtualizer_set_enable_flag(&(context->offload_virt),
+ ((strength > 0) && !(context->temp_disabled)) ?
+ true : false);
offload_virtualizer_set_strength(&(context->offload_virt), strength);
if (context->ctl)
offload_virtualizer_send_params(context->ctl, &context->offload_virt,
@@ -61,6 +72,189 @@ int virtualizer_set_strength(virtualizer_context_t *context, uint32_t strength)
return 0;
}
+/*
+ * Check if an audio device is supported by this implementation
+ *
+ * [in]
+ * device device that is intented for processing (e.g. for binaural vs transaural)
+ * [out]
+ * false device is not applicable for effect
+ * true device is applicable for effect
+ */
+bool virtualizer_is_device_supported(audio_devices_t device) {
+ switch (device) {
+ case AUDIO_DEVICE_OUT_SPEAKER:
+ case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
+ case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
+#ifdef AFE_PROXY_ENABLED
+ case AUDIO_DEVICE_OUT_PROXY:
+#endif
+ case AUDIO_DEVICE_OUT_AUX_DIGITAL:
+ case AUDIO_DEVICE_OUT_USB_ACCESSORY:
+ case AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET:
+ return false;
+ default :
+ return true;
+ }
+}
+
+/*
+ * Check if a channel mask + audio device is supported by this implementation
+ *
+ * [in]
+ * channel_mask channel mask of input buffer
+ * device device that is intented for processing (e.g. for binaural vs transaural)
+ * [out]
+ * false if the configuration is not supported or it is unknown
+ * true if the configuration is supported
+ */
+bool virtualizer_is_configuration_supported(audio_channel_mask_t channel_mask,
+ audio_devices_t device) {
+ uint32_t channelCount = audio_channel_count_from_out_mask(channel_mask);
+ if ((channelCount == 0) || (channelCount > 2)) {
+ return false;
+ }
+
+ return virtualizer_is_device_supported(device);
+}
+
+/*
+ * Force the virtualization mode to that of the given audio device
+ *
+ * [in]
+ * context effect engine context
+ * forced_device device whose virtualization mode we'll always use
+ * [out]
+ * -EINVAL if the device is not supported or is unknown
+ * 0 if the device is supported and the virtualization mode forced
+ */
+int virtualizer_force_virtualization_mode(virtualizer_context_t *context,
+ audio_devices_t forced_device) {
+ virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context;
+ int status = 0;
+ bool use_virt = false;
+ int is_virt_enabled =
+ offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt));
+
+ ALOGV("%s: ctxt %p, forcedDev=0x%x enabled=%d tmpDisabled=%d", __func__, virt_ctxt,
+ forced_device, is_virt_enabled, virt_ctxt->temp_disabled);
+
+ if (virtualizer_is_device_supported(forced_device) == false) {
+ if (forced_device != AUDIO_DEVICE_NONE) {
+ //forced device is not supported, make it behave as a reset of forced mode
+ forced_device = AUDIO_DEVICE_NONE;
+ // but return an error
+ status = -EINVAL;
+ }
+ }
+
+ if (forced_device == AUDIO_DEVICE_NONE) {
+ // disabling forced virtualization mode:
+ // verify whether the virtualization should be enabled or disabled
+ if (virtualizer_is_device_supported(virt_ctxt->device)) {
+ use_virt = (is_virt_enabled == true);
+ }
+ virt_ctxt->forced_device = AUDIO_DEVICE_NONE;
+ } else {
+ // forcing virtualization mode:
+ // TODO: we assume device is supported, so hard coded a fixed one.
+ virt_ctxt->forced_device = AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+ // TODO: only enable for a supported mode, when the effect is enabled
+ use_virt = (is_virt_enabled == true);
+ }
+
+ if (use_virt) {
+ if (virt_ctxt->temp_disabled == true) {
+ if (effect_is_active(&virt_ctxt->common)) {
+ offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), true);
+ if (virt_ctxt->ctl)
+ offload_virtualizer_send_params(virt_ctxt->ctl,
+ &virt_ctxt->offload_virt,
+ OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG);
+ }
+ ALOGV("%s: re-enable VIRTUALIZER", __func__);
+ virt_ctxt->temp_disabled = false;
+ } else {
+ ALOGV("%s: leaving VIRTUALIZER enabled", __func__);
+ }
+ } else {
+ if (virt_ctxt->temp_disabled == false) {
+ if (effect_is_active(&virt_ctxt->common)) {
+ offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), false);
+ if (virt_ctxt->ctl)
+ offload_virtualizer_send_params(virt_ctxt->ctl,
+ &virt_ctxt->offload_virt,
+ OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG);
+ }
+ ALOGV("%s: disable VIRTUALIZER", __func__);
+ virt_ctxt->temp_disabled = true;
+ } else {
+ ALOGV("%s: leaving VIRTUALIZER disabled", __func__);
+ }
+ }
+
+ ALOGV("after %s: ctxt %p, enabled=%d tmpDisabled=%d", __func__, virt_ctxt,
+ is_virt_enabled, virt_ctxt->temp_disabled);
+
+ return status;
+}
+
+/*
+ * Get the virtual speaker angles for a channel mask + audio device configuration
+ * which is guaranteed to be supported by this implementation
+ *
+ * [in]
+ * channel_mask the channel mask of the input to virtualize
+ * device the type of device that affects the processing (e.g. for binaural vs transaural)
+ * [in/out]
+ * speaker_angles the array of integer where each speaker angle is written as a triplet in the
+ * following format:
+ * int32_t a bit mask with a single value selected for each speaker, following
+ * the convention of the audio_channel_mask_t type
+ * int32_t a value in degrees expressing the speaker azimuth, where 0 is in front
+ * of the user, 180 behind, -90 to the left, 90 to the right of the user
+ * int32_t a value in degrees expressing the speaker elevation, where 0 is the
+ * horizontal plane, +90 is directly above the user, -90 below
+ *
+ */
+void virtualizer_get_speaker_angles(audio_channel_mask_t channel_mask __unused,
+ audio_devices_t device __unused, int32_t *speaker_angles) {
+ // the channel count is guaranteed to be 1 or 2
+ // the device is guaranteed to be of type headphone
+ // this virtualizer is always 2in with speakers at -90 and 90deg of azimuth, 0deg of elevation
+ *speaker_angles++ = (int32_t) AUDIO_CHANNEL_OUT_FRONT_LEFT;
+ *speaker_angles++ = -90; // azimuth
+ *speaker_angles++ = 0; // elevation
+ *speaker_angles++ = (int32_t) AUDIO_CHANNEL_OUT_FRONT_RIGHT;
+ *speaker_angles++ = 90; // azimuth
+ *speaker_angles = 0; // elevation
+}
+
+/*
+ * Retrieve the current device whose processing mode is used by this effect
+ *
+ * [out]
+ * AUDIO_DEVICE_NONE if the effect is not virtualizing
+ * or the device type if the effect is virtualizing
+ */
+audio_devices_t virtualizer_get_virtualization_mode(virtualizer_context_t *context) {
+ virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context;
+ audio_devices_t device = AUDIO_DEVICE_NONE;
+
+ if ((offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt)))
+ && (virt_ctxt->temp_disabled == false)) {
+ if (virt_ctxt->forced_device != AUDIO_DEVICE_NONE) {
+ // virtualization mode is forced, return that device
+ device = virt_ctxt->forced_device;
+ } else {
+ // no forced mode, return the current device
+ device = virt_ctxt->device;
+ }
+ }
+ ALOGV("%s: returning 0x%x", __func__, device);
+ return device;
+}
+
int virtualizer_get_parameter(effect_context_t *context, effect_param_t *p,
uint32_t *size)
{
@@ -86,6 +280,15 @@ int virtualizer_get_parameter(effect_context_t *context, effect_param_t *p,
p->status = -EINVAL;
p->vsize = sizeof(int16_t);
break;
+ case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES:
+ // return value size can only be interpreted as relative to input value,
+ // deferring validity check to below
+ break;
+ case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE:
+ if (p->vsize != sizeof(uint32_t))
+ p->status = -EINVAL;
+ p->vsize = sizeof(uint32_t);
+ break;
default:
p->status = -EINVAL;
}
@@ -106,6 +309,31 @@ int virtualizer_get_parameter(effect_context_t *context, effect_param_t *p,
*(int16_t *)value = virtualizer_get_strength(virt_ctxt);
break;
+ case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES:
+ {
+ const audio_channel_mask_t channel_mask = (audio_channel_mask_t) *param_tmp++;
+ const audio_devices_t device = (audio_devices_t) *param_tmp;
+ uint32_t channel_cnt = audio_channel_count_from_out_mask(channel_mask);
+
+ if (p->vsize < 3 * channel_cnt * sizeof(int32_t)){
+ p->status = -EINVAL;
+ break;
+ }
+ // verify the configuration is supported
+ if(virtualizer_is_configuration_supported(channel_mask, device)) {
+ // configuration is supported, get the angles
+ virtualizer_get_speaker_angles(channel_mask, device, (int32_t *)value);
+ } else {
+ p->status = -EINVAL;
+ }
+
+ break;
+ }
+
+ case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE:
+ *(uint32_t *)value = (uint32_t) virtualizer_get_virtualization_mode(virt_ctxt);
+ break;
+
default:
p->status = -EINVAL;
break;
@@ -134,6 +362,14 @@ int virtualizer_set_parameter(effect_context_t *context, effect_param_t *p,
strength = (uint32_t)(*(int16_t *)value);
virtualizer_set_strength(virt_ctxt, strength);
break;
+ case VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE:
+ {
+ const audio_devices_t device = *(audio_devices_t *)value;
+ if (0 != virtualizer_force_virtualization_mode(virt_ctxt, device)) {
+ p->status = -EINVAL;
+ }
+ break;
+ }
default:
p->status = -EINVAL;
break;
@@ -148,33 +384,36 @@ int virtualizer_set_device(effect_context_t *context, uint32_t device)
ALOGV("%s: device: %d", __func__, device);
virt_ctxt->device = device;
- if ((device == AUDIO_DEVICE_OUT_SPEAKER) ||
- (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) ||
- (device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER) ||
- (device == AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
- (device == AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET)) {
- if (!virt_ctxt->temp_disabled) {
- if (effect_is_active(&virt_ctxt->common)) {
- offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), false);
- if (virt_ctxt->ctl)
- offload_virtualizer_send_params(virt_ctxt->ctl,
- &virt_ctxt->offload_virt,
- OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG);
+
+ if (virt_ctxt->forced_device == AUDIO_DEVICE_NONE) {
+ // default case unless configuration is forced
+ if (virtualizer_is_device_supported(device) == false) {
+ if (!virt_ctxt->temp_disabled) {
+ if (effect_is_active(&virt_ctxt->common)) {
+ offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), false);
+ if (virt_ctxt->ctl)
+ offload_virtualizer_send_params(virt_ctxt->ctl,
+ &virt_ctxt->offload_virt,
+ OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG);
+ }
+ virt_ctxt->temp_disabled = true;
+ ALOGI("%s: ctxt %p, disabled based on device", __func__, virt_ctxt);
}
- virt_ctxt->temp_disabled = true;
- }
- } else {
- if (virt_ctxt->temp_disabled) {
- if (effect_is_active(&virt_ctxt->common)) {
- offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), true);
- if (virt_ctxt->ctl)
- offload_virtualizer_send_params(virt_ctxt->ctl,
- &virt_ctxt->offload_virt,
- OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG);
+ } else {
+ if (virt_ctxt->temp_disabled) {
+ if (effect_is_active(&virt_ctxt->common)) {
+ offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), true);
+ if (virt_ctxt->ctl)
+ offload_virtualizer_send_params(virt_ctxt->ctl,
+ &virt_ctxt->offload_virt,
+ OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG);
+ }
+ virt_ctxt->temp_disabled = false;
}
- virt_ctxt->temp_disabled = false;
}
}
+ // else virtualization mode is forced to a certain device, nothing to do
+
offload_virtualizer_set_device(&(virt_ctxt->offload_virt), device);
return 0;
}
@@ -211,6 +450,8 @@ int virtualizer_init(effect_context_t *context)
set_config(context, &context->config);
virt_ctxt->temp_disabled = false;
+ virt_ctxt->forced_device = AUDIO_DEVICE_NONE;
+ virt_ctxt->device = AUDIO_DEVICE_NONE;
memset(&(virt_ctxt->offload_virt), 0, sizeof(struct virtualizer_params));
return 0;
diff --git a/post_proc/virtualizer.h b/post_proc/virtualizer.h
index 978dc863..e7b9dd03 100644
--- a/post_proc/virtualizer.h
+++ b/post_proc/virtualizer.h
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +31,8 @@ typedef struct virtualizer_context_s {
// Offload vars
struct mixer_ctl *ctl;
bool temp_disabled;
- uint32_t device;
+ audio_devices_t forced_device;
+ audio_devices_t device;
struct virtualizer_params offload_virt;
} virtualizer_context_t;
diff --git a/visualizer/offload_visualizer.c b/visualizer/offload_visualizer.c
index 9b25e5e5..a7b4e549 100644
--- a/visualizer/offload_visualizer.c
+++ b/visualizer/offload_visualizer.c
@@ -444,6 +444,11 @@ int visualizer_hal_start_output(audio_io_handle_t output, int pcm_id) {
}
output_context_t *out_ctxt = (output_context_t *)malloc(sizeof(output_context_t));
+ if (out_ctxt == NULL) {
+ ALOGE("%s fail to allocate memory", __func__);
+ ret = -ENOMEM;
+ goto exit;
+ }
out_ctxt->handle = output;
list_init(&out_ctxt->effects_list);
@@ -953,6 +958,10 @@ int effect_lib_create(const effect_uuid_t *uuid,
if (memcmp(uuid, &visualizer_descriptor.uuid, sizeof(effect_uuid_t)) == 0) {
visualizer_context_t *visu_ctxt = (visualizer_context_t *)calloc(1,
sizeof(visualizer_context_t));
+ if (visu_ctxt == NULL) {
+ ALOGE("%s fail to allocate memory", __func__);
+ return -ENOMEM;
+ }
context = (effect_context_t *)visu_ctxt;
context->ops.init = visualizer_init;
context->ops.reset = visualizer_reset;
diff --git a/voice_processing/voice_processing.c b/voice_processing/voice_processing.c
index b3f97c6a..90034115 100644
--- a/voice_processing/voice_processing.c
+++ b/voice_processing/voice_processing.c
@@ -409,6 +409,10 @@ static struct session_s *get_session(int32_t id, int32_t sessionId, int32_t io
}
session = (struct session_s *)calloc(1, sizeof(struct session_s));
+ if (session == NULL) {
+ ALOGE("get_session() fail to allocate memory");
+ return NULL;
+ }
session_init(session);
session->id = sessionId;
session->io = ioId;
@@ -683,6 +687,10 @@ static int lib_create(const effect_uuid_t *uuid,
return -EINVAL;
}
id = uuid_to_id(&desc->type);
+ if (id >= NUM_ID) {
+ ALOGW("lib_create: fx not found type: %08x", desc->type.timeLow);
+ return -EINVAL;
+ }
session = get_session(id, sessionId, ioId);