am 74a4096d: Merge "Fix "hardware/qcom/audio/post_proc/effect_api.c:67:17: error: use of undeclared identifier \'EINVAL\'""

* commit '74a4096d03fdb2773d5d35b28d7d6ad95135daea':
  Fix "hardware/qcom/audio/post_proc/effect_api.c:67:17: error: use of undeclared identifier 'EINVAL'"
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index cd9ded8..864ab5c 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -209,19 +209,6 @@
     return id;
 }
 
-int pcm_ioctl(void *pcm, int request, ...)
-{
-    va_list ap;
-    void * arg;
-    int pcm_fd = *(int*)pcm;
-
-    va_start(ap, request);
-    arg = va_arg(ap, void *);
-    va_end(ap);
-
-    return ioctl(pcm_fd, request, arg);
-}
-
 int enable_audio_route(struct audio_device *adev,
                        struct audio_usecase *usecase)
 {
@@ -564,7 +551,8 @@
                                             usecase->stream.out->devices);
                 if (usecase->stream.out == adev->primary_output &&
                         adev->active_input &&
-                        adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
+                        adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
+                        out_snd_device != usecase->out_snd_device) {
                     select_devices(adev, adev->active_input->usecase);
                 }
             }
@@ -576,6 +564,7 @@
                 if (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
                         adev->primary_output && !adev->primary_output->standby) {
                     out_device = adev->primary_output->devices;
+                    platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
                 } else if (usecase->id == USECASE_AUDIO_RECORD_AFE_PROXY) {
                     out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX;
                 }
@@ -849,6 +838,8 @@
             compress_partial_drain(out->compr);
             send_callback = true;
             event = STREAM_CBK_EVENT_DRAIN_READY;
+            /* Resend the metadata for next iteration */
+            out->send_new_metadata = 1;
             break;
         case OFFLOAD_CMD_DRAIN:
             compress_drain(out->compr);
@@ -863,6 +854,7 @@
         out->offload_thread_blocked = false;
         pthread_cond_signal(&out->cond);
         if (send_callback) {
+            ALOGVV("%s: sending offload_callback event %d", __func__, event);
             out->offload_callback(event, NULL, out->offload_cookie);
         }
         free(cmd);
@@ -1997,8 +1989,7 @@
                 get_snd_codec_id(config->offload_info.format);
         out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
         out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
-        out->compr_config.codec->sample_rate =
-                    compress_get_alsa_rate(config->offload_info.sample_rate);
+        out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
         out->compr_config.codec->bit_rate =
                     config->offload_info.bit_rate;
         out->compr_config.codec->ch_in =
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index bec19d0..1888aa1 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -234,8 +234,6 @@
     int (*offload_effects_stop_output)(audio_io_handle_t, int);
 };
 
-int pcm_ioctl(void *pcm, int request, ...);
-
 int select_devices(struct audio_device *adev,
                    audio_usecase_t uc_id);
 
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index bc38b1d..4eaf488 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -445,7 +445,8 @@
     struct platform_data *my_data = (struct platform_data *)platform;
     int ret = 0;
 
-    if (my_data->csd_client != NULL) {
+    if (my_data->csd_client != NULL &&
+        voice_is_in_call(my_data->adev)) {
         /* This must be called before disabling the mixer controls on APQ side */
         if (my_data->csd_disable_device == NULL) {
             ALOGE("%s: dlsym error for csd_disable_device", __func__);
@@ -596,7 +597,7 @@
         goto exit;
     }
 
-    if (mode == AUDIO_MODE_IN_CALL) {
+    if (voice_is_in_call(adev)) {
         if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
             devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
             if (adev->voice.tty_mode == TTY_MODE_FULL)
@@ -693,11 +694,7 @@
 
     ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
           __func__, out_device, in_device);
-    if (mode == AUDIO_MODE_IN_CALL) {
-        if (out_device == AUDIO_DEVICE_NONE) {
-            ALOGE("%s: No output device set for voice call", __func__);
-            goto exit;
-        }
+    if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
         if (adev->voice.tty_mode != TTY_MODE_OFF) {
             if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
                 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 27e39d9..7ba0bf0 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -87,6 +87,7 @@
     struct csd_data *csd;
     bool ext_speaker;
     bool ext_earpiece;
+    char ec_ref_mixer_path[64];
 };
 
 static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -409,23 +410,24 @@
 
 void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
 {
-    char mixer_path[50] = { 0 } ;
+    struct platform_data *my_data = (struct platform_data *)adev->platform;
     snd_device_t snd_device = SND_DEVICE_NONE;
-    struct listnode *node;
-    struct audio_usecase *usecase;
 
-    strcpy(mixer_path, "echo-reference");
-    if (out_device != AUDIO_DEVICE_NONE) {
-        snd_device = platform_get_output_snd_device(adev->platform, out_device);
-        platform_add_backend_name(adev->platform, mixer_path, snd_device);
+    if (strcmp(my_data->ec_ref_mixer_path, "")) {
+        ALOGV("%s: diabling %s", __func__, my_data->ec_ref_mixer_path);
+        audio_route_reset_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
     }
 
-    if (enable)
-        audio_route_apply_and_update_path(adev->audio_route, mixer_path);
-    else
-        audio_route_reset_and_update_path(adev->audio_route, mixer_path);
+    if (enable) {
+        strcpy(my_data->ec_ref_mixer_path, "echo-reference");
+        if (out_device != AUDIO_DEVICE_NONE) {
+            snd_device = platform_get_output_snd_device(adev->platform, out_device);
+            platform_add_backend_name(adev->platform, my_data->ec_ref_mixer_path, snd_device);
+        }
 
-    ALOGV("Setting EC Reference: %d for %s", enable, mixer_path);
+        ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
+        audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
+    }
 }
 
 static struct csd_data *open_csd_client(bool i2s_ext_modem)
@@ -930,7 +932,7 @@
     int ret = 0;
 
     if (my_data->csd != NULL &&
-        my_data->adev->mode == AUDIO_MODE_IN_CALL) {
+        voice_is_in_call(my_data->adev)) {
         /* This must be called before disabling mixer controls on APQ side */
         ret = my_data->csd->disable_device();
         if (ret < 0) {
@@ -1186,18 +1188,17 @@
         goto exit;
     }
 
-    if ((mode == AUDIO_MODE_IN_CALL) ||
-        (adev->enable_voicerx)) {
+    if (voice_is_in_call(adev) || adev->enable_voicerx) {
         if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
             devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
             devices & AUDIO_DEVICE_OUT_LINE) {
-            if ((mode == AUDIO_MODE_IN_CALL) &&
+            if (voice_is_in_call(adev) &&
                 (adev->voice.tty_mode == TTY_MODE_FULL))
                 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
-            else if ((mode == AUDIO_MODE_IN_CALL) &&
+            else if (voice_is_in_call(adev) &&
                 (adev->voice.tty_mode == TTY_MODE_VCO))
                 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
-            else if ((mode == AUDIO_MODE_IN_CALL) &&
+            else if (voice_is_in_call(adev) &&
                 (adev->voice.tty_mode == TTY_MODE_HCO))
                 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
             else {
@@ -1308,11 +1309,7 @@
 
     ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
           __func__, out_device, in_device);
-    if (mode == AUDIO_MODE_IN_CALL) {
-        if (out_device == AUDIO_DEVICE_NONE) {
-            ALOGE("%s: No output device set for voice call", __func__);
-            goto exit;
-        }
+    if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
         if (adev->voice.tty_mode != TTY_MODE_OFF) {
             if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
                 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
@@ -1424,7 +1421,7 @@
                } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
                    snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
                }
-                platform_set_echo_reference(adev, true, out_device);
+               platform_set_echo_reference(adev, true, out_device);
             } else if (adev->active_input->enable_ns) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode &&
diff --git a/hal/voice.c b/hal/voice.c
index 669484c..044dc28 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -327,11 +327,11 @@
 {
     int ret = 0;
 
+    adev->voice.in_call = true;
     ret = voice_extn_start_call(adev);
     if (ret == -ENOSYS) {
         ret = voice_start_usecase(adev, USECASE_VOICE_CALL);
     }
-    adev->voice.in_call = true;
 
     return ret;
 }
diff --git a/visualizer/Android.mk b/visualizer/Android.mk
index 3c92044..bec54d6 100644
--- a/visualizer/Android.mk
+++ b/visualizer/Android.mk
@@ -24,6 +24,7 @@
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
 	liblog \
+	libdl \
 	libtinyalsa
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
diff --git a/visualizer/offload_visualizer.c b/visualizer/offload_visualizer.c
index 9b11e20..9b25e5e 100644
--- a/visualizer/offload_visualizer.c
+++ b/visualizer/offload_visualizer.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <time.h>
 #include <sys/prctl.h>
+#include <dlfcn.h>
 
 #include <cutils/list.h>
 #include <cutils/log.h>
@@ -29,6 +30,15 @@
 #include <tinyalsa/asoundlib.h>
 #include <audio_effects/effect_visualizer.h>
 
+#define LIB_ACDB_LOADER "libacdbloader.so"
+#define ACDB_DEV_TYPE_OUT 1
+#define AFE_PROXY_ACDB_ID 45
+
+static void* acdb_handle;
+
+typedef void (*acdb_send_audio_cal_t)(int, int);
+
+acdb_send_audio_cal_t acdb_send_audio_cal;
 
 enum {
     EFFECT_STATE_UNINITIALIZED,
@@ -294,6 +304,9 @@
     const char *proxy_ctl_name = "AFE_PCM_RX Audio Mixer MultiMedia4";
     struct mixer_ctl *ctl;
 
+    if (value && acdb_send_audio_cal)
+        acdb_send_audio_cal(AFE_PROXY_ACDB_ID, ACDB_DEV_TYPE_OUT);
+
     ctl = mixer_get_ctl_by_name(mixer, proxy_ctl_name);
     if (ctl == NULL) {
         ALOGW("%s: could not get %s ctl", __func__, proxy_ctl_name);
@@ -609,6 +622,19 @@
 
     set_config(context, &context->config);
 
+    if (acdb_handle == NULL) {
+        acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
+        if (acdb_handle == NULL) {
+            ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
+        } else {
+            acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(acdb_handle,
+                                                    "acdb_loader_send_audio_cal");
+            if (!acdb_send_audio_cal)
+                ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
+                      __func__, LIB_ACDB_LOADER);
+            }
+    }
+
     return 0;
 }