Merge "hal: Update EC support for HPF usecase"
diff --git a/hal/Android.mk b/hal/Android.mk
index 41f712c..c4534b6 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -34,6 +34,10 @@
LOCAL_CFLAGS += -DANC_HEADSET_ENABLED
endif
+ifneq ($(strip $(AUDIO_FEATURE_DISABLED_FLUENCE)),true)
+ LOCAL_CFLAGS += -DFLUENCE_ENABLED
+endif
+
ifneq ($(strip $(AUDIO_FEATURE_DISABLED_PROXY_DEVICE)),true)
LOCAL_CFLAGS += -DAFE_PROXY_ENABLED
endif
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 3bc72de..b641bdb 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -28,6 +28,8 @@
#include "audio_hw.h"
#include "audio_extn.h"
+#include "platform.h"
+#include "platform_api.h"
#define MAX_SLEEP_RETRY 100
#define WIFI_INIT_WAIT_SLEEP 50
@@ -130,6 +132,60 @@
}
#endif /* ANC_HEADSET_ENABLED */
+#ifndef FLUENCE_ENABLED
+#define audio_extn_set_fluence_parameters(adev, parms) (0)
+#define audio_extn_get_fluence_parameters(adev, query, reply) (0)
+#else
+void audio_extn_set_fluence_parameters(struct audio_device *adev,
+ struct str_parms *parms)
+{
+ int ret = 0, err;
+ char value[32];
+ struct listnode *node;
+ struct audio_usecase *usecase;
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_FLUENCE,
+ value, sizeof(value));
+ ALOGV_IF(err >= 0, "%s: Set Fluence Type to %s", __func__, value);
+ if (err >= 0) {
+ ret = platform_set_fluence_type(adev->platform, value);
+ if (ret != 0) {
+ ALOGE("platform_set_fluence_type returned error: %d", ret);
+ } else {
+ /*
+ *If the fluence is manually set/reset, devices
+ *need to get updated for all the usecases
+ *i.e. audio and voice.
+ */
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ select_devices(adev, usecase->id);
+ }
+ }
+ }
+}
+
+int audio_extn_get_fluence_parameters(struct audio_device *adev,
+ struct str_parms *query, struct str_parms *reply)
+{
+ int ret = 0, err;
+ char value[256] = {0};
+
+ err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FLUENCE, value,
+ sizeof(value));
+ if (err >= 0) {
+ ret = platform_get_fluence_type(adev->platform, value, sizeof(value));
+ if (ret >= 0) {
+ ALOGV("%s: Fluence Type is %s", __func__, value);
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FLUENCE, value);
+ } else
+ goto done;
+ }
+done:
+ return ret;
+}
+#endif /* FLUENCE_ENABLED */
+
#ifndef AFE_PROXY_ENABLED
#define audio_extn_set_afe_proxy_parameters(adev, parms) (0)
#define audio_extn_get_afe_proxy_parameters(query, reply) (0)
@@ -329,6 +385,7 @@
struct str_parms *parms)
{
audio_extn_set_anc_parameters(adev, parms);
+ audio_extn_set_fluence_parameters(adev, parms);
audio_extn_set_afe_proxy_parameters(adev, parms);
audio_extn_fm_set_parameters(adev, parms);
audio_extn_listen_set_parameters(adev, parms);
@@ -342,6 +399,7 @@
{
char *kv_pairs = NULL;
audio_extn_get_afe_proxy_parameters(query, reply);
+ audio_extn_get_fluence_parameters(adev, query, reply);
kv_pairs = str_parms_to_str(reply);
ALOGD_IF(kv_pairs != NULL, "%s: returns %s", __func__, kv_pairs);
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index af0b285..aecef36 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -39,6 +39,16 @@
bool audio_extn_should_use_handset_anc(int in_channels);
#endif
+#ifndef FLUENCE_ENABLED
+#define audio_extn_set_fluence_parameters(adev, parms) (0)
+#define audio_extn_get_fluence_parameters(adev, query, reply) (0)
+#else
+void audio_extn_set_fluence_parameters(struct audio_device *adev,
+ struct str_parms *parms);
+int audio_extn_get_fluence_parameters(struct audio_device *adev,
+ struct str_parms *query, struct str_parms *reply);
+#endif
+
#ifndef AFE_PROXY_ENABLED
#define audio_extn_set_afe_proxy_channel_mixer(adev,channel_count) (0)
#define audio_extn_read_afe_proxy_channel_masks(out) (0)
@@ -61,6 +71,7 @@
#define audio_extn_usb_set_proxy_sound_card(sndcard_idx) (0)
#define audio_extn_usb_is_proxy_inuse() (0)
#else
+void initPlaybackVolume();
void audio_extn_usb_init(void *adev);
void audio_extn_usb_deinit();
void audio_extn_usb_start_playback(void *adev);
@@ -166,7 +177,7 @@
#endif
#ifndef DS1_DOLBY_DDP_ENABLED
-#define audio_extn_dolby_set_endpoint() (0)
+#define audio_extn_dolby_set_endpoint(adev) (0)
#else
void audio_extn_dolby_set_endpoint(struct audio_device *adev);
#endif
@@ -174,7 +185,7 @@
#ifndef DS1_DOLBY_DDP_ENABLED
#define audio_extn_ddp_set_parameters(adev, parms) (0)
#define audio_extn_is_dolby_format(format) (0)
-#define audio_extn_dolby_get_snd_codec_id(format) (0)
+#define audio_extn_dolby_get_snd_codec_id(adev, out, format) (0)
#define audio_extn_dolby_send_ddp_endp_params(adev) (0)
#else
bool audio_extn_is_dolby_format(audio_format_t format);
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index c480490..57d1f0c 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -1,5 +1,5 @@
/* hfp.c
-Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+Copyright (c) 2012-2014, 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
@@ -43,6 +43,7 @@
#ifdef HFP_ENABLED
#define AUDIO_PARAMETER_HFP_ENABLE "hfp_enable"
#define AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE "hfp_set_sampling_rate"
+#define AUDIO_PARAMETER_KEY_HFP_VOLUME "hfp_volume"
static int32_t start_hfp(struct audio_device *adev,
struct str_parms *parms);
@@ -55,7 +56,7 @@
struct pcm *hfp_pcm_rx;
struct pcm *hfp_pcm_tx;
bool is_hfp_running;
- int hfp_volume;
+ float hfp_volume;
audio_usecase_t ucid;
};
@@ -79,6 +80,46 @@
.avail_min = 0,
};
+static int32_t hfp_set_volume(struct audio_device *adev, float value)
+{
+ int32_t vol, ret = 0;
+ struct mixer_ctl *ctl;
+ const char *mixer_ctl_name = "Internal HFP RX Volume";
+
+ ALOGV("%s: entry", __func__);
+ ALOGD("%s: (%f)\n", __func__, value);
+
+ if (value < 0.0) {
+ ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
+ value = 0.0;
+ } else {
+ value = ((value > 15.000000) ? 1.0 : (value / 15));
+ ALOGW("%s: Volume brought with in range (%f)\n", __func__, value);
+ }
+ vol = lrint((value * 0x2000) + 0.5);
+ hfpmod.hfp_volume = value;
+
+ if (!hfpmod.is_hfp_running) {
+ ALOGV("%s: HFP not active, ignoring set_hfp_volume call", __func__);
+ return -EIO;
+ }
+
+ ALOGD("%s: Setting HFP volume to %d \n", __func__, vol);
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+ if(mixer_ctl_set_value(ctl, 0, vol) < 0) {
+ ALOGE("%s: Couldn't set HFP Volume: [%d]", __func__, vol);
+ return -EINVAL;
+ }
+
+ ALOGV("%s: exit", __func__);
+ return ret;
+}
+
static int32_t start_hfp(struct audio_device *adev,
struct str_parms *parms)
{
@@ -158,8 +199,8 @@
pcm_start(hfpmod.hfp_pcm_rx);
pcm_start(hfpmod.hfp_pcm_tx);
-
hfpmod.is_hfp_running = true;
+ hfp_set_volume(adev, hfpmod.hfp_volume);
ALOGD("%s: exit: status(%d)", __func__, ret);
return 0;
@@ -238,6 +279,7 @@
int ret;
int rate;
int val;
+ float vol;
char value[32]={0};
ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_ENABLE, value,
@@ -275,5 +317,20 @@
select_devices(adev, hfpmod.ucid);
}
}
+
+ memset(value, 0, sizeof(value));
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HFP_VOLUME,
+ value, sizeof(value));
+ if (ret >= 0) {
+ if (sscanf(value, "%f", &vol) != 1){
+ ALOGE("%s: error in retrieving hfp volume", __func__);
+ ret = -EIO;
+ goto exit;
+ }
+ ALOGD("%s: set_hfp_volume usecase, Vol: [%f]", __func__, vol);
+ hfp_set_volume(adev, vol);
+ }
+exit:
+ ALOGV("%s Exit",__func__);
}
#endif /*HFP_ENABLED*/
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 5ec7eba..6c0eec0 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -633,7 +633,11 @@
ret = -EINVAL;
}
}
+
exit:
+ /* Clear VI feedback cal and replace with handset MIC */
+ platform_send_audio_calibration(adev->platform,
+ SND_DEVICE_IN_HANDSET_MIC);
if (ret) {
if (handle.pcm_tx)
pcm_close(handle.pcm_tx);
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 699c3b7..281b445 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -96,6 +96,42 @@
usbmod = calloc(1, sizeof(struct usb_module));
}
+// Some USB audio accessories have a really low default volume set. Look for a suitable
+// volume control and set the volume to default volume level.
+static void initPlaybackVolume() {
+ ALOGD("initPlaybackVolume");
+ struct mixer *usbMixer = mixer_open(1);
+
+ if (usbMixer) {
+ struct mixer_ctl *ctl = NULL;
+ unsigned int usbPlaybackVolume;
+ unsigned int i;
+ unsigned int num_ctls = mixer_get_num_ctls(usbMixer);
+
+ // Look for the first control named ".*Playback Volume" that isn't for a microphone
+ for (i = 0; i < num_ctls; i++) {
+ ctl = mixer_get_ctl(usbMixer, i);
+ if (strstr((const char *)mixer_ctl_get_name(ctl), "Playback Volume") &&
+ !strstr((const char *)mixer_ctl_get_name(ctl), "Mic")) {
+ break;
+ }
+ }
+ if (ctl != NULL) {
+ ALOGD("Found a volume control for USB: %s", mixer_ctl_get_name(ctl) );
+ usbPlaybackVolume = mixer_ctl_get_value(ctl, 0);
+ ALOGD("Value got from mixer_ctl_get is:%u", usbPlaybackVolume);
+ if (mixer_ctl_set_value(ctl,0,usbPlaybackVolume) < 0) {
+ ALOGE("Failed to set volume; default volume might be used");
+ }
+ } else {
+ ALOGE("No playback volume control found; default volume will be used");
+ }
+ mixer_close(usbMixer);
+ } else {
+ ALOGE("Failed to open mixer for card 1");
+ }
+}
+
static int usb_get_numof_rates(char *rates_str)
{
int i, size = 0;
@@ -340,7 +376,7 @@
pcm_config_usbmod.channels = usbmod->channels_playback;
pcm_config_usbmod.period_count = AFE_PROXY_PERIOD_COUNT;
usbmod->proxy_device_id = AFE_PROXY_PLAYBACK_DEVICE;
- ALOGV("%s: proxy device %u:period %u:channels %u:sample", __func__,
+ ALOGD("%s: proxy device %u:period %u:channels %u:sample", __func__,
pcm_config_usbmod.period_size, pcm_config_usbmod.channels,
pcm_config_usbmod.rate);
@@ -375,6 +411,8 @@
ALOGD("%s: PROXY configured for playback", __func__);
pthread_mutex_unlock(&usbmod->usb_playback_lock);
+ ALOGD("Init USB volume");
+ initPlaybackVolume();
/* main loop to read from proxy and write to usb */
while (usbmod->is_playback_running) {
/* read data from proxy */
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index f0b745b..c0d47d9 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -551,21 +551,6 @@
return ret;
}
-static void update_devices_for_all_voice_usecases(struct audio_device *adev)
-{
- struct listnode *node;
- struct audio_usecase *usecase;
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == VOICE_CALL) {
- ALOGV("%s: updating device for usecase:%s", __func__,
- use_case_table[usecase->id]);
- select_devices(adev, usecase->id);
- }
- }
-}
-
static audio_usecase_t get_voice_usecase_id_from_list(struct audio_device *adev)
{
struct audio_usecase *usecase;
@@ -1457,7 +1442,7 @@
} else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
voice_is_in_call(adev) &&
(out == adev->primary_output)) {
- update_devices_for_all_voice_usecases(adev);
+ voice_update_devices_for_all_voice_usecases(adev);
}
}
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 2108a00..e1172ef 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -32,13 +32,15 @@
#define OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH "/system/lib/soundfx/libqcompostprocbundle.so"
/* Flags used to initialize acdb_settings variable that goes to ACDB library */
-#define DMIC_FLAG 0x00000002
-#define QMIC_FLAG 0x00000004
-#define TTY_MODE_OFF 0x00000010
-#define TTY_MODE_FULL 0x00000020
-#define TTY_MODE_VCO 0x00000040
-#define TTY_MODE_HCO 0x00000080
-#define TTY_MODE_CLEAR 0xFFFFFF0F
+#define NONE_FLAG 0x00000000
+#define DMIC_FLAG 0x00000002
+#define QMIC_FLAG 0x00000004
+#define TTY_MODE_OFF 0x00000010
+#define TTY_MODE_FULL 0x00000020
+#define TTY_MODE_VCO 0x00000040
+#define TTY_MODE_HCO 0x00000080
+#define TTY_MODE_CLEAR 0xFFFFFF0F
+#define FLUENCE_MODE_CLEAR 0xFFFFFFF0
#define ACDB_DEV_TYPE_OUT 1
#define ACDB_DEV_TYPE_IN 2
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 298c60d..dacf68e 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -551,6 +551,12 @@
return ret;
}
+int platform_set_device_mute(void *platform, bool state, char *dir)
+{
+ LOGE("%s: Not implemented", __func__);
+ return -ENOSYS;
+}
+
snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
{
struct platform_data *my_data = (struct platform_data *)platform;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 896b53a..b0cc5a7 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -106,6 +106,7 @@
bool fluence_in_voice_rec;
bool fluence_in_audio_rec;
int fluence_type;
+ char fluence_cap[PROPERTY_VALUE_MAX];
int btsco_sample_rate;
bool slowtalk;
/* Audio calibration related functions */
@@ -522,10 +523,10 @@
my_data->fluence_in_audio_rec = false;
my_data->fluence_type = FLUENCE_NONE;
- property_get("ro.qc.sdk.audio.fluencetype", value, "");
- if (!strncmp("fluencepro", value, sizeof("fluencepro"))) {
+ property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
+ if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
- } else if (!strncmp("fluence", value, sizeof("fluence"))) {
+ } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
my_data->fluence_type = FLUENCE_DUAL_MIC;
} else {
my_data->fluence_type = FLUENCE_NONE;
@@ -688,6 +689,63 @@
return device_id;
}
+int platform_set_fluence_type(void *platform, char *value)
+{
+ int ret = 0;
+ int fluence_type = FLUENCE_NONE;
+ int fluence_flag = NONE_FLAG;
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct audio_device *adev = my_data->adev;
+
+ ALOGV("%s: fluence type:%d", __func__, my_data->fluence_type);
+
+ /* only dual mic turn on and off is supported as of now through setparameters */
+ if (!strncmp(AUDIO_PARAMETER_VALUE_DUALMIC,value, sizeof(AUDIO_PARAMETER_VALUE_DUALMIC))) {
+ if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro")) ||
+ !strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
+ ALOGV("fluence dualmic feature enabled \n");
+ fluence_type = FLUENCE_DUAL_MIC;
+ fluence_flag = DMIC_FLAG;
+ } else {
+ ALOGE("%s: Failed to set DUALMIC", __func__);
+ ret = -1;
+ goto done;
+ }
+ } else if (!strncmp(AUDIO_PARAMETER_KEY_NO_FLUENCE, value, sizeof(AUDIO_PARAMETER_KEY_NO_FLUENCE))) {
+ ALOGV("fluence disabled");
+ fluence_type = FLUENCE_NONE;
+ } else {
+ ALOGE("Invalid fluence value : %s",value);
+ ret = -1;
+ goto done;
+ }
+
+ if (fluence_type != my_data->fluence_type) {
+ ALOGV("%s: Updating fluence_type to :%d", __func__, fluence_type);
+ my_data->fluence_type = fluence_type;
+ adev->acdb_settings = (adev->acdb_settings & FLUENCE_MODE_CLEAR) | fluence_flag;
+ }
+done:
+ return ret;
+}
+
+int platform_get_fluence_type(void *platform, char *value, uint32_t len)
+{
+ int ret = 0;
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if (my_data->fluence_type == FLUENCE_QUAD_MIC) {
+ strlcpy(value, "quadmic", len);
+ } else if (my_data->fluence_type == FLUENCE_DUAL_MIC) {
+ strlcpy(value, "dualmic", len);
+ } else if (my_data->fluence_type == FLUENCE_NONE) {
+ strlcpy(value, "none", len);
+ } else
+ ret = -1;
+
+ return ret;
+}
+
int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -872,6 +930,44 @@
return ret;
}
+int platform_set_device_mute(void *platform, bool state, char *dir)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct audio_device *adev = my_data->adev;
+ struct mixer_ctl *ctl;
+ char *mixer_ctl_name = NULL;
+ int ret = 0;
+ uint32_t set_values[ ] = {0,
+ ALL_SESSION_VSID,
+ 0};
+ if(dir == NULL) {
+ ALOGE("%s: Invalid direction:%s", __func__, dir);
+ return -EINVAL;
+ }
+
+ if (!strncmp("rx", dir, sizeof("rx"))) {
+ mixer_ctl_name = "Voice Rx Device Mute";
+ } else if (!strncmp("tx", dir, sizeof("tx"))) {
+ mixer_ctl_name = "Voice Tx Device Mute";
+ } else {
+ return -EINVAL;
+ }
+
+ set_values[0] = state;
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
+ __func__,state, mixer_ctl_name);
+ mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+
+ return ret;
+}
+
snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -1532,24 +1628,8 @@
char *str = NULL;
char value[256] = {0};
int ret;
- int fluence_type;
char *kv_pairs = NULL;
- ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FLUENCE_TYPE,
- value, sizeof(value));
- if (ret >= 0) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
- strlcpy(value, "fluencepro", sizeof(value));
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- strlcpy(value, "fluence", sizeof(value));
- } else {
- strlcpy(value, "none", sizeof(value));
- }
-
- str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FLUENCE_TYPE, value);
- }
-
- memset(value, 0, sizeof(value));
ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
value, sizeof(value));
if (ret >= 0) {
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index b71ae29..f119fcd 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -170,6 +170,15 @@
#define HFP_PCM_RX 5
#define INCALL_MUSIC_UPLINK_PCM_DEVICE 1
+
+#ifdef PLATFORM_MSM8610
+#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 15
+#elif PLATFORM_MSM8x26
+#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 16
+#else
+#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 35
+#endif
+
#define SPKR_PROT_CALIB_RX_PCM_DEVICE 5
#define SPKR_PROT_CALIB_TX_PCM_DEVICE 25
#define PLAYBACK_OFFLOAD_DEVICE 9
@@ -222,12 +231,6 @@
#define HFP_ASM_RX_TX 24
#endif
-#ifdef PLATFORM_MSM8610
-#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 15
-#else
-#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 16
-#endif
-
#define LIB_CSD_CLIENT "libcsd-client.so"
/* CSD-CLIENT related functions */
typedef int (*init_t)();
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 306aaad..7c4171d 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -27,6 +27,8 @@
char *device_name);
void platform_add_backend_name(char *mixer_path, snd_device_t snd_device);
int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type);
+int platform_set_fluence_type(void *platform, char *value);
+int platform_get_fluence_type(void *platform, char *value, uint32_t len);
int platform_send_audio_calibration(void *platform, snd_device_t snd_device);
int platform_switch_voice_call_device_pre(void *platform);
int platform_switch_voice_call_device_post(void *platform,
@@ -39,6 +41,7 @@
int platform_stop_voice_call(void *platform, uint32_t vsid);
int platform_set_voice_volume(void *platform, int volume);
int platform_set_mic_mute(void *platform, bool state);
+int platform_set_device_mute(void *platform, bool state, char *dir);
snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices);
snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device);
int platform_set_hdmi_channels(void *platform, int channel_count);
diff --git a/hal/voice.c b/hal/voice.c
index 28d44db..82813f6 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -397,8 +397,7 @@
adev->voice.tty_mode = tty_mode;
adev->acdb_settings = (adev->acdb_settings & TTY_MODE_CLEAR) | tty_mode;
if (voice_is_in_call(adev))
- //todo: what about voice2, volte and qchat usecases?
- select_devices(adev, USECASE_VOICE_CALL);
+ voice_update_devices_for_all_voice_usecases(adev);
}
}
@@ -438,4 +437,19 @@
voice_extn_init(adev);
}
+void voice_update_devices_for_all_voice_usecases(struct audio_device *adev)
+{
+ struct listnode *node;
+ struct audio_usecase *usecase;
+
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == VOICE_CALL) {
+ ALOGV("%s: updating device for usecase:%s", __func__,
+ use_case_table[usecase->id]);
+ select_devices(adev, usecase->id);
+ }
+ }
+}
+
diff --git a/hal/voice.h b/hal/voice.h
index 5e4ce7f..d160569 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -86,4 +86,5 @@
struct stream_out *out);
int voice_check_and_stop_incall_rec_usecase(struct audio_device *adev,
struct stream_in *in);
+void voice_update_devices_for_all_voice_usecases(struct audio_device *adev);
#endif //VOICE_H
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index f2dc6bc..f6083f3 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -38,6 +38,8 @@
#define AUDIO_PARAMETER_KEY_CALL_STATE "call_state"
#define AUDIO_PARAMETER_KEY_AUDIO_MODE "audio_mode"
#define AUDIO_PARAMETER_KEY_ALL_CALL_STATES "all_call_states"
+#define AUDIO_PARAMETER_KEY_DEVICE_MUTE "device_mute"
+#define AUDIO_PARAMETER_KEY_DIRECTION "direction"
#define VOICE_EXTN_PARAMETER_VALUE_MAX_LEN 256
@@ -440,6 +442,7 @@
int value;
int ret = 0, err;
char *kv_pairs = str_parms_to_str(parms);
+ char str_value[256] = {0};
ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
@@ -465,8 +468,34 @@
ret = -EINVAL;
goto done;
}
- } else {
- ALOGV("%s: Not handled here", __func__);
+ }
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DEVICE_MUTE, str_value,
+ sizeof(str_value));
+ if (err >= 0) {
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_DEVICE_MUTE);
+ bool mute = false;
+
+ if (!strncmp("true", str_value, sizeof("true"))) {
+ mute = true;
+ }
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DIRECTION, str_value,
+ sizeof(str_value));
+ if (err >= 0) {
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_DIRECTION);
+ } else {
+ ALOGE("%s: direction key not found", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = platform_set_device_mute(adev->platform, mute, str_value);
+ if (ret != 0) {
+ ALOGE("%s: Failed to set mute err:%d", __func__, ret);
+ ret = -EINVAL;
+ goto done;
+ }
}
done:
diff --git a/mm-audio/aenc-aac/qdsp6/inc/aenc_svr.h b/mm-audio/aenc-aac/qdsp6/inc/aenc_svr.h
index 72bfebe..9bc7200 100644
--- a/mm-audio/aenc-aac/qdsp6/inc/aenc_svr.h
+++ b/mm-audio/aenc-aac/qdsp6/inc/aenc_svr.h
@@ -60,7 +60,7 @@
#endif
#define DEBUG_PRINT_ERROR LOGE
-#define DEBUG_PRINT LOGI
+#define DEBUG_PRINT LOGV
#define DEBUG_DETAIL LOGV
typedef void (*message_func)(void* client_data, unsigned char id);
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index cb26ed6..0722aed 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -261,6 +261,130 @@
return BAD_VALUE;
}
+void AudioPolicyManager::setPhoneState(int state)
+{
+ ALOGV("setPhoneState() state %d", state);
+ audio_devices_t newDevice = AUDIO_DEVICE_NONE;
+ if (state < 0 || state >= AudioSystem::NUM_MODES) {
+ ALOGW("setPhoneState() invalid state %d", state);
+ return;
+ }
+
+ if (state == mPhoneState ) {
+ ALOGW("setPhoneState() setting same state %d", state);
+ return;
+ }
+
+ // if leaving call state, handle special case of active streams
+ // pertaining to sonification strategy see handleIncallSonification()
+ if (isInCall()) {
+ ALOGV("setPhoneState() in call state management: new state is %d", state);
+ for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+ handleIncallSonification(stream, false, true);
+ }
+ }
+
+ // store previous phone state for management of sonification strategy below
+ int oldState = mPhoneState;
+ mPhoneState = state;
+ bool force = false;
+
+ // are we entering or starting a call
+ if (!isStateInCall(oldState) && isStateInCall(state)) {
+ ALOGV(" Entering call in setPhoneState()");
+ // force routing command to audio hardware when starting a call
+ // even if no device change is needed
+ force = true;
+ for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
+ mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
+ sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j];
+ }
+ } else if (isStateInCall(oldState) && !isStateInCall(state)) {
+ ALOGV(" Exiting call in setPhoneState()");
+ // force routing command to audio hardware when exiting a call
+ // even if no device change is needed
+ force = true;
+ for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
+ mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
+ sVolumeProfiles[AUDIO_STREAM_DTMF][j];
+ }
+ } else if (isStateInCall(state) && (state != oldState)) {
+ ALOGV(" Switching between telephony and VoIP in setPhoneState()");
+ // force routing command to audio hardware when switching between telephony and VoIP
+ // even if no device change is needed
+ force = true;
+ }
+
+ // check for device and output changes triggered by new phone state
+ newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/);
+ checkA2dpSuspend();
+ checkOutputForAllStrategies();
+ updateDevicesAndOutputs();
+
+ AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
+
+ // force routing command to audio hardware when ending call
+ // even if no device change is needed
+ if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) {
+ newDevice = hwOutputDesc->device();
+ }
+
+ int delayMs = 0;
+ if (isStateInCall(state)) {
+ nsecs_t sysTime = systemTime();
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ AudioOutputDescriptor *desc = mOutputs.valueAt(i);
+ // mute media and sonification strategies and delay device switch by the largest
+ // latency of any output where either strategy is active.
+ // This avoid sending the ring tone or music tail into the earpiece or headset.
+ if ((desc->isStrategyActive(STRATEGY_MEDIA,
+ SONIFICATION_HEADSET_MUSIC_DELAY,
+ sysTime) ||
+ desc->isStrategyActive(STRATEGY_SONIFICATION,
+ SONIFICATION_HEADSET_MUSIC_DELAY,
+ sysTime)) &&
+ (delayMs < (int)desc->mLatency*2)) {
+ delayMs = desc->mLatency*2;
+ }
+ setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
+ setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
+ getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
+ setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i));
+ setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS,
+ getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
+ }
+ }
+
+ // change routing is necessary
+ setOutputDevice(mPrimaryOutput, newDevice, force, delayMs);
+
+ //update device for all non-primary outputs
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ audio_io_handle_t output = mOutputs.keyAt(i);
+ if (output != mPrimaryOutput) {
+ newDevice = getNewDevice(output, false /*fromCache*/);
+ setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
+ }
+ }
+
+ // if entering in call state, handle special case of active streams
+ // pertaining to sonification strategy see handleIncallSonification()
+ if (isStateInCall(state)) {
+ ALOGV("setPhoneState() in call state management: new state is %d", state);
+ for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+ handleIncallSonification(stream, true, true);
+ }
+ }
+
+ // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
+ if (state == AudioSystem::MODE_RINGTONE &&
+ isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
+ mLimitRingtoneVolume = true;
+ } else {
+ mLimitRingtoneVolume = false;
+ }
+}
+
void AudioPolicyManager::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
{
ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
@@ -351,6 +475,193 @@
}
+status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
+ AudioSystem::stream_type stream,
+ int session)
+{
+ ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session);
+ ssize_t index = mOutputs.indexOfKey(output);
+ if (index < 0) {
+ ALOGW("startOutput() unknow output %d", output);
+ return BAD_VALUE;
+ }
+
+ AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
+
+ // increment usage count for this stream on the requested output:
+ // NOTE that the usage count is the same for duplicated output and hardware output which is
+ // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
+ outputDesc->changeRefCount(stream, 1);
+
+ if (outputDesc->mRefCount[stream] == 1) {
+ audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/);
+ routing_strategy strategy = getStrategy(stream);
+ bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
+ (strategy == STRATEGY_SONIFICATION_RESPECTFUL);
+ uint32_t waitMs = 0;
+ bool force = false;
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ AudioOutputDescriptor *desc = mOutputs.valueAt(i);
+ if (desc != outputDesc) {
+ // force a device change if any other output is managed by the same hw
+ // module and has a current device selection that differs from selected device.
+ // In this case, the audio HAL must receive the new device selection so that it can
+ // change the device currently selected by the other active output.
+ if (outputDesc->sharesHwModuleWith(desc) &&
+ desc->device() != newDevice) {
+ force = true;
+ }
+ // wait for audio on other active outputs to be presented when starting
+ // a notification so that audio focus effect can propagate.
+ uint32_t latency = desc->latency();
+ if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
+ waitMs = latency;
+ }
+ }
+ }
+ uint32_t muteWaitMs = setOutputDevice(output, newDevice, force);
+
+ // handle special case for sonification while in call
+ if (isInCall()) {
+ handleIncallSonification(stream, true, false);
+ }
+
+ // apply volume rules for current stream and device if necessary
+ checkAndSetVolume(stream,
+ mStreams[stream].getVolumeIndex(newDevice),
+ output,
+ newDevice);
+
+ // update the outputs if starting an output with a stream that can affect notification
+ // routing
+ handleNotificationRoutingForStream(stream);
+ if (waitMs > muteWaitMs) {
+ usleep((waitMs - muteWaitMs) * 2 * 1000);
+ }
+ }
+#ifdef DOLBY_UDC
+ // It is observed that in some use-cases where both outputs are present eg. bluetooth and headphone,
+ // the output for particular stream type is decided in this routine. Hence we must call
+ // getDeviceForStrategy in order to get the current active output for this stream type and update
+ // the dolby system property.
+ if (stream == AudioSystem::MUSIC)
+ {
+ audio_devices_t audioOutputDevice = getDeviceForStrategy(getStrategy(AudioSystem::MUSIC), true);
+ DolbySystemProperty::set(audioOutputDevice);
+ }
+#endif // DOLBY_END
+ return NO_ERROR;
+}
+
+
+status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
+ AudioSystem::stream_type stream,
+ int session)
+{
+ ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
+ ssize_t index = mOutputs.indexOfKey(output);
+ if (index < 0) {
+ ALOGW("stopOutput() unknow output %d", output);
+ return BAD_VALUE;
+ }
+
+ AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
+
+ // handle special case for sonification while in call
+ if (isInCall()) {
+ handleIncallSonification(stream, false, false);
+ }
+
+ if (outputDesc->mRefCount[stream] > 0) {
+ // decrement usage count of this stream on the output
+ outputDesc->changeRefCount(stream, -1);
+ // store time at which the stream was stopped - see isStreamActive()
+ if (outputDesc->mRefCount[stream] == 0) {
+ outputDesc->mStopTime[stream] = systemTime();
+ audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/);
+ // delay the device switch by twice the latency because stopOutput() is executed when
+ // the track stop() command is received and at that time the audio track buffer can
+ // still contain data that needs to be drained. The latency only covers the audio HAL
+ // and kernel buffers. Also the latency does not always include additional delay in the
+ // audio path (audio DSP, CODEC ...)
+ setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
+
+ // force restoring the device selection on other active outputs if it differs from the
+ // one being selected for this output
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ audio_io_handle_t curOutput = mOutputs.keyAt(i);
+ AudioOutputDescriptor *desc = mOutputs.valueAt(i);
+ if (curOutput != output &&
+ desc->isActive() &&
+ outputDesc->sharesHwModuleWith(desc) &&
+ (newDevice != desc->device())) {
+ setOutputDevice(curOutput,
+ getNewDevice(curOutput, false /*fromCache*/),
+ true,
+ outputDesc->mLatency*2);
+ }
+ }
+ // update the outputs if stopping one with a stream that can affect notification routing
+ handleNotificationRoutingForStream(stream);
+ }
+ return NO_ERROR;
+ } else {
+ ALOGW("stopOutput() refcount is already 0 for output %d", output);
+ return INVALID_OPERATION;
+ }
+}
+
+audio_devices_t AudioPolicyManager::getNewDevice(audio_io_handle_t output, bool fromCache)
+{
+ audio_devices_t device = AUDIO_DEVICE_NONE;
+
+ AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+ AudioOutputDescriptor *primaryOutputDesc = mOutputs.valueFor(mPrimaryOutput);
+ // check the following by order of priority to request a routing change if necessary:
+ // 1: the strategy enforced audible is active on the output:
+ // use device for strategy enforced audible
+ // 2: we are in call or the strategy phone is active on the output:
+ // use device for strategy phone
+ // 3: the strategy sonification is active on the output:
+ // use device for strategy sonification
+ // 4: the strategy "respectful" sonification is active on the output:
+ // use device for strategy "respectful" sonification
+ // 5: the strategy media is active on the output:
+ // use device for strategy media
+ // 6: the strategy DTMF is active on the output:
+ // use device for strategy DTMF
+ if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) {
+ device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
+ } else if (isInCall() ||
+ outputDesc->isStrategyActive(STRATEGY_PHONE)) {
+ device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
+ } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)||
+ (primaryOutputDesc->isStrategyActive(STRATEGY_SONIFICATION)&& !primaryOutputDesc->isStrategyActive(STRATEGY_MEDIA))){
+ device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
+ } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) {
+ device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
+ } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) {
+ device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
+ } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) {
+ device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
+ }
+
+ ALOGV("getNewDevice() selected device %x", device);
+ return device;
+}
+
+//private function, no changes from AudioPolicyManagerBase
+void AudioPolicyManager::handleNotificationRoutingForStream(AudioSystem::stream_type stream) {
+ switch(stream) {
+ case AudioSystem::MUSIC:
+ checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
+ updateDevicesAndOutputs();
+ break;
+ default:
+ break;
+ }
+}
+
audio_io_handle_t AudioPolicyManager::getInput(int inputSource,
uint32_t samplingRate,
uint32_t format,
@@ -418,12 +729,32 @@
AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(AudioSystem::stream_type stream)
{
-#ifdef QCOM_INCALL_MUSIC_ENABLED
- if (stream == AudioSystem::INCALL_MUSIC)
- return STRATEGY_MEDIA;
+ // stream to strategy mapping
+ switch (stream) {
+ case AudioSystem::VOICE_CALL:
+ case AudioSystem::BLUETOOTH_SCO:
+ return STRATEGY_PHONE;
+ case AudioSystem::RING:
+ case AudioSystem::ALARM:
+ return STRATEGY_SONIFICATION;
+ case AudioSystem::NOTIFICATION:
+ return STRATEGY_SONIFICATION_RESPECTFUL;
+ case AudioSystem::DTMF:
+ return STRATEGY_DTMF;
+ default:
+ ALOGE("unknown stream type");
+ case AudioSystem::SYSTEM:
+ // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
+ // while key clicks are played produces a poor result
+ case AudioSystem::TTS:
+ case AudioSystem::MUSIC:
+#ifdef AUDIO_EXTN_INCALL_MUSIC_ENABLED
+ case AudioSystem::INCALL_MUSIC:
#endif
-
- return getStrategy(stream);
+ return STRATEGY_MEDIA;
+ case AudioSystem::ENFORCED_AUDIBLE:
+ return STRATEGY_ENFORCED_AUDIBLE;
+ }
}
audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 5defa24..8ef1cab 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -49,6 +49,13 @@
uint32_t channels,
AudioSystem::audio_in_acoustics acoustics);
virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
+ virtual void setPhoneState(int state);
+ virtual status_t startOutput(audio_io_handle_t output,
+ AudioSystem::stream_type stream,
+ int session = 0);
+ virtual status_t stopOutput(audio_io_handle_t output,
+ AudioSystem::stream_type stream,
+ int session = 0);
protected:
// return the strategy corresponding to a given stream type
@@ -77,8 +84,12 @@
// check that volume change is permitted, compute and send new volume to audio hardware
status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false);
+ audio_devices_t getNewDevice(audio_io_handle_t output, bool fromCache);
// returns the category the device belongs to with regard to volume curve management
static device_category getDeviceCategory(audio_devices_t device);
+private:
+ void handleNotificationRoutingForStream(AudioSystem::stream_type stream);
+
};
};
diff --git a/post_proc/bass_boost.c b/post_proc/bass_boost.c
index 53ec77f..2061cd0 100644
--- a/post_proc/bass_boost.c
+++ b/post_proc/bass_boost.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -153,16 +153,27 @@
bass_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_BLUETOOTH_A2DP_SPEAKER) ||
+ (device == AUDIO_DEVICE_OUT_PROXY) ||
+ (device == AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
+ (device == AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET)) {
if (offload_bassboost_get_enable_flag(&(bass_ctxt->offload_bass))) {
offload_bassboost_set_enable_flag(&(bass_ctxt->offload_bass), false);
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 (!offload_bassboost_get_enable_flag(&(bass_ctxt->offload_bass)) &&
bass_ctxt->temp_disabled) {
offload_bassboost_set_enable_flag(&(bass_ctxt->offload_bass), true);
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);
@@ -211,7 +222,9 @@
bassboost_context_t *bass_ctxt = (bassboost_context_t *)context;
ALOGV("%s", __func__);
- if (!offload_bassboost_get_enable_flag(&(bass_ctxt->offload_bass))) {
+
+ if (!offload_bassboost_get_enable_flag(&(bass_ctxt->offload_bass)) &&
+ !(bass_ctxt->temp_disabled)) {
offload_bassboost_set_enable_flag(&(bass_ctxt->offload_bass), true);
if (bass_ctxt->ctl && bass_ctxt->strength)
offload_bassboost_send_params(bass_ctxt->ctl,
diff --git a/post_proc/effect_api.c b/post_proc/effect_api.c
index a2e4f45..570ca8b 100644
--- a/post_proc/effect_api.c
+++ b/post_proc/effect_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 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
@@ -391,7 +391,7 @@
{
ALOGV("%s", __func__);
if (preset && (preset <= NUM_OSL_REVERB_PRESETS_SUPPORTED))
- reverb->preset = map_reverb_opensl_preset_2_offload_preset[preset][1];
+ reverb->preset = map_reverb_opensl_preset_2_offload_preset[preset-1][1];
}
void offload_reverb_set_wet_mix(struct reverb_params *reverb, int wet_mix)
diff --git a/post_proc/reverb.c b/post_proc/reverb.c
index d104073..60750b0 100644
--- a/post_proc/reverb.c
+++ b/post_proc/reverb.c
@@ -309,6 +309,7 @@
return -EINVAL;
*(uint16_t *)value = reverb_ctxt->next_preset;
ALOGV("get REVERB_PARAM_PRESET, preset %d", reverb_ctxt->next_preset);
+ return 0;
}
switch (param) {
case REVERB_PARAM_ROOM_LEVEL:
@@ -464,6 +465,7 @@
return -EINVAL;
}
reverb_set_preset(reverb_ctxt, preset);
+ return 0;
}
switch (param) {
case REVERB_PARAM_PROPERTIES:
@@ -603,6 +605,14 @@
ALOGV("%s", __func__);
reverb_ctxt->ctl = output->ctl;
+ if (offload_reverb_get_enable_flag(&(reverb_ctxt->offload_reverb))) {
+ if (reverb_ctxt->ctl && reverb_ctxt->preset) {
+ offload_reverb_send_params(reverb_ctxt->ctl, reverb_ctxt->offload_reverb,
+ OFFLOAD_SEND_REVERB_ENABLE_FLAG |
+ OFFLOAD_SEND_REVERB_PRESET);
+ }
+ }
+
return 0;
}
diff --git a/post_proc/virtualizer.c b/post_proc/virtualizer.c
index 3f65f00..8f6d000 100644
--- a/post_proc/virtualizer.c
+++ b/post_proc/virtualizer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -153,16 +153,27 @@
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_BLUETOOTH_A2DP_SPEAKER) ||
+ (device == AUDIO_DEVICE_OUT_PROXY) ||
+ (device == AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
+ (device == AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET)) {
if (offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt))) {
offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), false);
virt_ctxt->temp_disabled = true;
+ if (virt_ctxt->ctl)
+ offload_virtualizer_send_params(virt_ctxt->ctl,
+ virt_ctxt->offload_virt,
+ OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG);
}
} else {
if (!offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt)) &&
virt_ctxt->temp_disabled) {
offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), true);
virt_ctxt->temp_disabled = false;
+ if (virt_ctxt->ctl)
+ offload_virtualizer_send_params(virt_ctxt->ctl,
+ virt_ctxt->offload_virt,
+ OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG);
}
}
offload_virtualizer_set_device(&(virt_ctxt->offload_virt), device);
@@ -210,7 +221,9 @@
virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context;
ALOGV("%s", __func__);
- if (!offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt))) {
+
+ if (!offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt)) &&
+ !(virt_ctxt->temp_disabled)) {
offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), true);
if (virt_ctxt->ctl && virt_ctxt->strength)
offload_virtualizer_send_params(virt_ctxt->ctl,