Merge "audio_policy: modify few methods to appropriately override base"
diff --git a/hal/Android.mk b/hal/Android.mk
index 72042d1..e457b83 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -161,10 +161,6 @@
 endif
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTIPLE_TUNNEL)), true)
-    LOCAL_CFLAGS += -DMULTIPLE_OFFLOAD_ENABLED
-endif
-
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true)
     LOCAL_CFLAGS += -DFLAC_OFFLOAD_ENABLED
     LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 39ad4d1..ce8f965 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -874,9 +874,7 @@
 static perf_lock_acquire_t perf_lock_acq;
 static perf_lock_release_t perf_lock_rel;
 
-static int perf_lock_handle;
 char opt_lib_path[512] = {0};
-int perf_lock_opts[1] = {0x20E};
 
 int audio_extn_perf_lock_init(void)
 {
@@ -914,19 +912,30 @@
     return ret;
 }
 
-void audio_extn_perf_lock_acquire(void)
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+                                 int *perf_lock_opts, int size)
 {
-    if (perf_lock_acq)
-        perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, perf_lock_opts, 1);
-    else
-        ALOGE("%s: Perf lock acquire error \n", __func__);
+
+    if (!perf_lock_opts || !size || !perf_lock_acq || !handle)
+        return -EINVAL;
+    /*
+     * Acquire performance lock for 1 sec during device path bringup.
+     * Lock will be released either after 1 sec or when perf_lock_release
+     * function is executed.
+     */
+    *handle = perf_lock_acq(*handle, duration, perf_lock_opts, size);
+    if (*handle <= 0)
+        ALOGE("%s: Failed to acquire perf lock, err: %d\n",
+              __func__, *handle);
 }
 
-void audio_extn_perf_lock_release(void)
+void audio_extn_perf_lock_release(int *handle)
 {
-    if (perf_lock_rel && perf_lock_handle)
-        perf_lock_rel(perf_lock_handle);
-    else
+    if (perf_lock_rel && handle && (*handle > 0)) {
+        perf_lock_rel(*handle);
+        *handle = 0;
+    } else {
         ALOGE("%s: Perf lock release error \n", __func__);
+    }
 }
 #endif /* KPI_OPTIMIZE_ENABLED */
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 3645cdb..b4848a4 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -503,12 +503,14 @@
 
 #ifndef KPI_OPTIMIZE_ENABLED
 #define audio_extn_perf_lock_init() (0)
-#define audio_extn_perf_lock_acquire() (0)
-#define audio_extn_perf_lock_release() (0)
+#define audio_extn_perf_lock_acquire(handle, duration, opts, size) (0)
+#define audio_extn_perf_lock_release(handle) (0)
 #else
 int audio_extn_perf_lock_init(void);
-void audio_extn_perf_lock_acquire(void);
-void audio_extn_perf_lock_release(void);
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+                                 int *opts, int size);
+void audio_extn_perf_lock_release(int *handle);
+
 #endif /* KPI_OPTIMIZE_ENABLED */
 
 #ifndef AUDIO_EXTERNAL_HDMI_ENABLED
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index a73dfa1..3e09e55 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -47,6 +47,8 @@
 
 #ifdef PLATFORM_MSM8994
 #define HFP_RX_VOLUME     "SEC AUXPCM LOOPBACK Volume"
+#elif defined PLATFORM_MSM8996
+#define HFP_RX_VOLUME     "PRI AUXPCM LOOPBACK Volume"
 #else
 #define HFP_RX_VOLUME     "Internal HFP RX Volume"
 #endif
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index e69d060..e6fbc5f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -170,7 +170,6 @@
     [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
     //Enabled for Direct_PCM
     [USECASE_AUDIO_PLAYBACK_OFFLOAD2] = "compress-offload-playback2",
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     [USECASE_AUDIO_PLAYBACK_OFFLOAD3] = "compress-offload-playback3",
     [USECASE_AUDIO_PLAYBACK_OFFLOAD4] = "compress-offload-playback4",
     [USECASE_AUDIO_PLAYBACK_OFFLOAD5] = "compress-offload-playback5",
@@ -178,7 +177,6 @@
     [USECASE_AUDIO_PLAYBACK_OFFLOAD7] = "compress-offload-playback7",
     [USECASE_AUDIO_PLAYBACK_OFFLOAD8] = "compress-offload-playback8",
     [USECASE_AUDIO_PLAYBACK_OFFLOAD9] = "compress-offload-playback9",
-#endif
 
     [USECASE_AUDIO_RECORD] = "audio-record",
     [USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
@@ -215,7 +213,6 @@
 static const audio_usecase_t offload_usecases[] = {
     USECASE_AUDIO_PLAYBACK_OFFLOAD,
     USECASE_AUDIO_PLAYBACK_OFFLOAD2,
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     USECASE_AUDIO_PLAYBACK_OFFLOAD3,
     USECASE_AUDIO_PLAYBACK_OFFLOAD4,
     USECASE_AUDIO_PLAYBACK_OFFLOAD5,
@@ -223,7 +220,6 @@
     USECASE_AUDIO_PLAYBACK_OFFLOAD7,
     USECASE_AUDIO_PLAYBACK_OFFLOAD8,
     USECASE_AUDIO_PLAYBACK_OFFLOAD9,
-#endif
 };
 
 #define STRING_TO_ENUM(string) { #string, string }
@@ -1128,7 +1124,9 @@
     uc_info->out_snd_device = SND_DEVICE_NONE;
 
     list_add_tail(&adev->usecase_list, &uc_info->list);
-    audio_extn_perf_lock_acquire();
+    audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+                                 adev->perf_lock_opts,
+                                 adev->perf_lock_opts_size);
     select_devices(adev, in->usecase);
 
     ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
@@ -1170,16 +1168,14 @@
         goto error_open;
     }
 
-    audio_extn_perf_lock_release();
-
+    audio_extn_perf_lock_release(&adev->perf_lock_handle);
     ALOGD("%s: exit", __func__);
 
     return ret;
 
 error_open:
+    audio_extn_perf_lock_release(&adev->perf_lock_handle);
     stop_input_stream(in);
-    audio_extn_perf_lock_release();
-
 error_config:
     adev->active_input = NULL;
     /*
@@ -1648,6 +1644,9 @@
     }
     list_add_tail(&adev->usecase_list, &uc_info->list);
 
+    audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+                                 adev->perf_lock_opts,
+                                 adev->perf_lock_opts_size);
     select_devices(adev, out->usecase);
 
     ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
@@ -1738,11 +1737,12 @@
             audio_extn_check_and_set_dts_hpx_state(adev);
         }
     }
-
+    audio_extn_perf_lock_release(&adev->perf_lock_handle);
     ALOGD("%s: exit", __func__);
 
     return 0;
 error_open:
+    audio_extn_perf_lock_release(&adev->perf_lock_handle);
     stop_output_stream(out);
 error_config:
     /*
@@ -3665,7 +3665,6 @@
     /* This stream could be for sound trigger lab,
        get sound trigger pcm if present */
     audio_extn_sound_trigger_check_and_get_session(in);
-    audio_extn_perf_lock_init();
 
     *stream_in = &in->stream;
     ALOGV("%s: exit", __func__);
@@ -3826,6 +3825,9 @@
     adev->cur_wfd_channels = 2;
     adev->offload_usecases_state = 0;
     adev->is_channel_status_set = false;
+    adev->perf_lock_opts[0] = 0x101;
+    adev->perf_lock_opts[1] = 0x20E;
+    adev->perf_lock_opts_size = 2;
 
     pthread_mutex_init(&adev->snd_card_status.lock, (const pthread_mutexattr_t *) NULL);
     adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
@@ -3943,6 +3945,7 @@
     if (adev->adm_init)
         adev->adm_data = adev->adm_init();
 
+    audio_extn_perf_lock_init();
     ALOGV("%s: exit", __func__);
     return 0;
 }
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index e4a43ad..fd19211 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -74,6 +74,8 @@
 #define SND_CARD_STATE_OFFLINE 0
 #define SND_CARD_STATE_ONLINE 1
 
+#define MAX_PERF_LOCK_OPTS 20
+
 /* These are the supported use cases by the hardware.
  * Each usecase is mapped to a specific PCM device.
  * Refer to pcm_device_table[].
@@ -86,7 +88,6 @@
     USECASE_AUDIO_PLAYBACK_MULTI_CH,
     USECASE_AUDIO_PLAYBACK_OFFLOAD,
     USECASE_AUDIO_PLAYBACK_OFFLOAD2,
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     USECASE_AUDIO_PLAYBACK_OFFLOAD3,
     USECASE_AUDIO_PLAYBACK_OFFLOAD4,
     USECASE_AUDIO_PLAYBACK_OFFLOAD5,
@@ -94,7 +95,6 @@
     USECASE_AUDIO_PLAYBACK_OFFLOAD7,
     USECASE_AUDIO_PLAYBACK_OFFLOAD8,
     USECASE_AUDIO_PLAYBACK_OFFLOAD9,
-#endif
     USECASE_AUDIO_PLAYBACK_ULL,
 
     /* FM usecase */
@@ -355,6 +355,9 @@
     void (*offload_effects_set_parameters)(struct str_parms *);
 
     bool multi_offload_enable;
+    int perf_lock_handle;
+    int perf_lock_opts[MAX_PERF_LOCK_OPTS];
+    int perf_lock_opts_size;
 };
 
 int select_devices(struct audio_device *adev,
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index df81a68..a478f93 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -268,7 +268,6 @@
                                         MULTIMEDIA2_PCM_DEVICE},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
                      {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     /* Below entries are initialized with invalid values
      * Valid values should be updated from fnc platform_info_init()
      * based on pcm ids defined in audio_platform_info.xml.
@@ -281,7 +280,6 @@
     [USECASE_AUDIO_PLAYBACK_OFFLOAD7] = {-1, -1},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD8] = {-1, -1},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD9] = {-1, -1},
-#endif
     [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
     [USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
     [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -657,7 +655,6 @@
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD2)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD3)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD4)},
@@ -666,7 +663,6 @@
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD7)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
-#endif
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
     {TO_NAME_INDEX(USECASE_VOICE_CALL)},
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 95b1cde..0bf50be 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -118,6 +118,7 @@
 #define AUDIO_PARAMETER_KEY_AUD_CALDATA   "cal_data"
 #define AUDIO_PARAMETER_KEY_AUD_CALRESULT "cal_result"
 
+#define AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS "perf_lock_opts"
 
 /* Query external audio device connection status */
 #define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
@@ -259,7 +260,6 @@
                      {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
                      {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     [USECASE_AUDIO_PLAYBACK_OFFLOAD3] =
                      {PLAYBACK_OFFLOAD_DEVICE3, PLAYBACK_OFFLOAD_DEVICE3},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD4] =
@@ -274,7 +274,6 @@
                      {PLAYBACK_OFFLOAD_DEVICE8, PLAYBACK_OFFLOAD_DEVICE8},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD9] =
                      {PLAYBACK_OFFLOAD_DEVICE9, PLAYBACK_OFFLOAD_DEVICE9},
-#endif
 
 
     [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
@@ -632,7 +631,6 @@
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD2)},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD3)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD4)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD5)},
@@ -640,7 +638,6 @@
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD7)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
-#endif
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
     {TO_NAME_INDEX(USECASE_VOICE_CALL)},
@@ -1264,7 +1261,7 @@
     char value[PROPERTY_VALUE_MAX];
     struct platform_data *my_data = NULL;
     int retry_num = 0, snd_card_num = 0, key = 0;
-    const char *snd_card_name;
+    const char *snd_card_name = NULL;
     char *cvd_version = NULL;
     char *snd_internal_name = NULL;
     char *tmp = NULL;
@@ -1376,7 +1373,8 @@
     if (snd_card_num >= MAX_SND_CARD) {
         ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
         free(my_data);
-        free(snd_card_name);
+        if (snd_card_name)
+            free(snd_card_name);
         return NULL;
     }
 
@@ -3004,6 +3002,44 @@
         free(dptr);
 }
 
+static void perf_lock_set_params(struct platform_data *platform,
+                          struct str_parms *parms,
+                          char *value, int len)
+{
+    int err = 0, i = 0, num_opts = 0;
+    char *test_r = NULL;
+    char *opts = NULL;
+    char *opts_size = NULL;
+
+    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS,
+                            value, len);
+    if (err >= 0) {
+        opts_size = strtok_r(value, ", ", &test_r);
+        if (opts_size == NULL) {
+            ALOGE("%s: incorrect perf lock opts\n", __func__);
+            return;
+        }
+        num_opts = atoi(opts_size);
+        if (num_opts > 0) {
+            if (num_opts > MAX_PERF_LOCK_OPTS) {
+                ALOGD("%s: num_opts %d exceeds max %d, setting to max\n",
+                      __func__, num_opts, MAX_PERF_LOCK_OPTS);
+                num_opts = MAX_PERF_LOCK_OPTS;
+            }
+            for (i = 0; i < num_opts; i++) {
+                opts = strtok_r(NULL, ", ", &test_r);
+                if (opts == NULL) {
+                    ALOGE("%s: incorrect perf lock opts\n", __func__);
+                    break;
+                }
+                platform->adev->perf_lock_opts[i] = strtoul(opts, NULL, 16);
+            }
+            platform->adev->perf_lock_opts_size = i;
+        }
+        str_parms_del(parms, AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS);
+    }
+}
+
 int platform_set_parameters(void *platform, struct str_parms *parms)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
@@ -3097,6 +3133,7 @@
     set_audiocal(platform, parms, value, len);
     native_audio_set_params(platform, parms, value, len);
     audio_extn_spkr_prot_set_parameters(parms, value, len);
+    perf_lock_set_params(platform, parms, value, len);
 done:
     ALOGV("%s: exit with code(%d)", __func__, ret);
     if(kv_pairs != NULL)
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 22d66e8..438bad6 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -253,7 +253,6 @@
 #define PLAYBACK_OFFLOAD_DEVICE2 17
 #endif
 
-#ifdef MULTIPLE_OFFLOAD_ENABLED
 #ifdef PLATFORM_APQ8084
 #define PLAYBACK_OFFLOAD_DEVICE3 18
 #define PLAYBACK_OFFLOAD_DEVICE4 34
@@ -272,7 +271,6 @@
 #define PLAYBACK_OFFLOAD_DEVICE8 41
 #define PLAYBACK_OFFLOAD_DEVICE9 42
 #endif
-#endif
 
 #define COMPRESS_VOIP_CALL_PCM_DEVICE 3
 
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 6b43044..46c58c5 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -1587,23 +1587,29 @@
     if (profile != 0) {
         sp<SwAudioOutputDescriptor> outputDesc = NULL;
 
-        for (size_t i = 0; i < mOutputs.size(); i++) {
-            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
-            if (!desc->isDuplicated() && (profile == desc->mProfile)) {
-                outputDesc = desc;
-                // reuse direct output if currently open and configured with same parameters
-                if ((samplingRate == outputDesc->mSamplingRate) &&
-                        (format == outputDesc->mFormat) &&
-                        (channelMask == outputDesc->mChannelMask)) {
-                    outputDesc->mDirectOpenCount++;
-                    ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
-                    return mOutputs.keyAt(i);
+        // if multiple concurrent offload decode is supported
+        // do no check for reuse and also don't close previous output if its offload
+        // previous output will be closed during track destruction
+        if (!(property_get_bool("audio.offload.multiple.enabled", false) &&
+                ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0))) {
+            for (size_t i = 0; i < mOutputs.size(); i++) {
+                sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+                if (!desc->isDuplicated() && (profile == desc->mProfile)) {
+                    outputDesc = desc;
+                    // reuse direct output if currently open and configured with same parameters
+                    if ((samplingRate == outputDesc->mSamplingRate) &&
+                            (format == outputDesc->mFormat) &&
+                            (channelMask == outputDesc->mChannelMask)) {
+                        outputDesc->mDirectOpenCount++;
+                        ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
+                        return mOutputs.keyAt(i);
+                    }
                 }
             }
-        }
-        // close direct output if currently open and configured with different parameters
-        if (outputDesc != NULL) {
-            closeOutput(outputDesc->mIoHandle);
+            // close direct output if currently open and configured with different parameters
+            if (outputDesc != NULL) {
+                closeOutput(outputDesc->mIoHandle);
+            }
         }
 
         // if the selected profile is offloaded and no offload info was specified,
diff --git a/post_proc/volume_listener.c b/post_proc/volume_listener.c
index d540bf5..e1dd026 100644
--- a/post_proc/volume_listener.c
+++ b/post_proc/volume_listener.c
@@ -324,6 +324,13 @@
  * Effect Control Interface Implementation
  */
 
+static inline int16_t clamp16(int32_t sample)
+{
+    if ((sample>>15) ^ (sample>>31))
+        sample = 0x7FFF ^ (sample>>31);
+    return sample;
+}
+
 static int vol_effect_process(effect_handle_t self,
                               audio_buffer_t *in_buffer,
                               audio_buffer_t *out_buffer)
@@ -342,7 +349,14 @@
 
     // calculation based on channel count 2
     if (in_buffer->raw != out_buffer->raw) {
-        memcpy(out_buffer->raw, in_buffer->raw, out_buffer->frameCount * 2 * sizeof(int16_t));
+        if (context->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+            size_t i;
+            for (i = 0; i < out_buffer->frameCount*2; i++) {
+                out_buffer->s16[i] = clamp16(out_buffer->s16[i] + in_buffer->s16[i]);
+            }
+        } else {
+            memcpy(out_buffer->raw, in_buffer->raw, out_buffer->frameCount * 2 * sizeof(int16_t));
+        }
     } else {
         ALOGV("%s: something wrong, didn't handle in_buffer and out_buffer same address case",
               __func__);
@@ -386,6 +400,12 @@
 
     case EFFECT_CMD_SET_CONFIG:
         ALOGV("%s :: cmd called EFFECT_CMD_SET_CONFIG", __func__);
+        if (p_cmd_data == NULL || cmd_size != sizeof(effect_config_t)
+                || p_reply_data == NULL || reply_size == NULL || *reply_size != sizeof(int)) {
+            return -EINVAL;
+        }
+        context->config = *(effect_config_t *)p_cmd_data;
+        *(int *)p_reply_data = 0;
         break;
 
     case EFFECT_CMD_GET_CONFIG:
@@ -612,7 +632,7 @@
 
 static int vol_prc_lib_create(const effect_uuid_t *uuid,
                               int32_t session_id,
-                              int32_t io_id,
+                              int32_t io_id __unused,
                               effect_handle_t *p_handle)
 {
     int itt = 0;