audio: Optimized audio hal sound effect logic [1/1]

PD#SWPL-195332

Problem:
1.Optimize sound logic

Solution:
1.tuning_binary can be customized
2.can choose to remove Amlogic sound effects
3.Optimized logic for HW_EQ_Full band drc on T6D when ini
does not exist
4.Sync changes on the roku project

Verify:
yocto

Change-Id: Ia108ea5be1116f0a0879007c642e3b9cba048f9d
Signed-off-by: hui.liu <hui.liu@amlogic.com>
diff --git a/aml_aq_hw/Amlogic_DRC_Param_Generator b/aml_aq_hw/Amlogic_DRC_Param_Generator
index 60e730f..bbb1a89 100644
--- a/aml_aq_hw/Amlogic_DRC_Param_Generator
+++ b/aml_aq_hw/Amlogic_DRC_Param_Generator
Binary files differ
diff --git a/aml_aq_hw/Amlogic_DRC_Param_Generator.a b/aml_aq_hw/Amlogic_DRC_Param_Generator.a
index 7f3be45..55ce1b4 100644
--- a/aml_aq_hw/Amlogic_DRC_Param_Generator.a
+++ b/aml_aq_hw/Amlogic_DRC_Param_Generator.a
Binary files differ
diff --git a/aml_aq_hw/Amlogic_DRC_Param_Generator64.a b/aml_aq_hw/Amlogic_DRC_Param_Generator64.a
index 3a185a1..2e739ca 100644
--- a/aml_aq_hw/Amlogic_DRC_Param_Generator64.a
+++ b/aml_aq_hw/Amlogic_DRC_Param_Generator64.a
Binary files differ
diff --git a/aml_aq_hw/Amlogic_EQ_Param_Generator b/aml_aq_hw/Amlogic_EQ_Param_Generator
index 1c01c73..34648d7 100644
--- a/aml_aq_hw/Amlogic_EQ_Param_Generator
+++ b/aml_aq_hw/Amlogic_EQ_Param_Generator
Binary files differ
diff --git a/aml_aq_hw/Amlogic_EQ_Param_Generator.a b/aml_aq_hw/Amlogic_EQ_Param_Generator.a
index 48ec057..78a4d1b 100644
--- a/aml_aq_hw/Amlogic_EQ_Param_Generator.a
+++ b/aml_aq_hw/Amlogic_EQ_Param_Generator.a
Binary files differ
diff --git a/aml_aq_hw/Amlogic_EQ_Param_Generator64.a b/aml_aq_hw/Amlogic_EQ_Param_Generator64.a
index 0f3d437..54672cf 100644
--- a/aml_aq_hw/Amlogic_EQ_Param_Generator64.a
+++ b/aml_aq_hw/Amlogic_EQ_Param_Generator64.a
Binary files differ
diff --git a/aml_aq_hw/aml_DRC_param_gen.h b/aml_aq_hw/aml_DRC_param_gen.h
index 252a8ee..a8254cc 100644
--- a/aml_aq_hw/aml_DRC_param_gen.h
+++ b/aml_aq_hw/aml_DRC_param_gen.h
@@ -23,8 +23,8 @@
 int setcsfilter_drc(unsigned int band_id, unsigned int fc);
 int setmb_drc(unsigned int band_id, unsigned int attrack_time, unsigned int release_time,
               unsigned int estimate_time, float K, float threshold);
-int setfb_drc(unsigned int band_id, unsigned int attrack_time, unsigned int release_time,
-              unsigned int estimate_time, float K, float threshold, unsigned int delays);
+int setfb_drc(unsigned int band_id, unsigned int attack_time, unsigned int release_time,
+              unsigned int estimate_time, float K, float threshold, float offset);
 #ifdef __cplusplus
 }
 #endif
diff --git a/aml_aq_hw/audio_eq_drc_compensation.c b/aml_aq_hw/audio_eq_drc_compensation.c
index 74666f0..2e58285 100644
--- a/aml_aq_hw/audio_eq_drc_compensation.c
+++ b/aml_aq_hw/audio_eq_drc_compensation.c
@@ -340,7 +340,15 @@
 
     return 0;
 }
-
+/**
+ * @brief: Example Initialize the eq_drc_data parameter.
+ * @param eq_drc_data *pdata :structure of the EQ_DRC para
+ * @return:
+ *   AMLOGIC_FILE_EXIST(0x00) : The AMLOGIC_EFFECT_INI and AMLOGIC_SOC_INI files exist
+ *   NO_AMLOGIC_EFFECT_INI(0x01): AMLOGIC_EFFECT_INI file is missing, but AMLOGIC_SOC_INI file exists.
+ *   NO_AMLOGIC_SOC_INI (0x10): AMLOGIC_EFFECT_INI file exists, but AMLOGIC_SOC_INI file is missing.
+ *   NO_AMLOGIC_EFFECT_INI|NO_AMLOGIC_SOC_INI (0x11):Both AMLOGIC_EFFECT_INI and AMLOGIC_SOC_INI files are missing.
+*/
 int eq_drc_init(struct eq_drc_data *pdata)
 {
     int i, ret;
@@ -360,12 +368,10 @@
     if (ret < 0) {
         return -1;
     }
-
+    ret = AMLOGIC_FILE_EXIST;
     /*parse amlogic ini file*/
-    ret = parse_audio_sum(filename, model_name, &dev_cfg[0]);
-    if (ret == 0) {
-        ret = parse_audio_gain(dev_cfg[0].ini_file, pdata);
-        if (ret < 0 ) {
+    if ((parse_audio_sum(filename, model_name, &dev_cfg[0])) == 0) {
+        if ((parse_audio_gain(dev_cfg[0].ini_file, pdata)) < 0) {
             ALOGE("%s: Get amlogic gain config failed!", __FUNCTION__);
         } else {
             if (pdata->s_gain.enable) {
@@ -387,7 +393,6 @@
             ALOGE("%s: calloc amlogic audio_eq_drc_info_s failed", __FUNCTION__);
             return -1;
         }
-
         parse_audio_eq_drc_status(dev_cfg[0].ini_file, pdata->aml_attr);
         volume_set(pdata->aml_attr, pdata->card);
         eq_status_set(pdata->aml_attr, pdata->card);
@@ -395,10 +400,12 @@
         parse_audio_eq_drc_table(dev_cfg[0].ini_file, pdata->aml_attr);
         eq_mode_set(pdata, 0);
         drc_set(pdata);
+        ret &= ~(NO_AMLOGIC_EFFECT_INI);
+    } else {
+        ret |= NO_AMLOGIC_EFFECT_INI;
     }
 
-    ret = parse_audio_sum(filename, model_name, &dev_cfg[1]);
-    if (ret == 0) {
+    if ((parse_audio_sum(filename, model_name, &dev_cfg[1])) == 0) {
         parse_AMP_num(dev_cfg[1].ini_file, pdata);
         for (int i = 0; i < pdata->ext_amp_num; i++) {
             pdata->ext_attr[i] = (struct audio_eq_drc_info_s *)aml_audio_calloc(1, sizeof(struct audio_eq_drc_info_s));
@@ -415,9 +422,12 @@
             ext_eq_mode_set(pdata, 0, i);
             ext_drc_set(pdata, i);
         }
+        ret &= ~(NO_AMLOGIC_SOC_INI);
+    } else {
+        ret |= NO_AMLOGIC_SOC_INI;
     }
-
-    return 0;
+    ALOGI("%s; ret=0x%02X\n",__func__,ret);
+    return ret;
 }
 
 int eq_drc_release(struct eq_drc_data *pdata)
diff --git a/aml_aq_hw/audio_eq_drc_compensation.h b/aml_aq_hw/audio_eq_drc_compensation.h
index 6fa50d3..c3308cc 100644
--- a/aml_aq_hw/audio_eq_drc_compensation.h
+++ b/aml_aq_hw/audio_eq_drc_compensation.h
@@ -23,6 +23,10 @@
 extern "C" {
 #endif
 
+#define AMLOGIC_FILE_EXIST 0
+#define NO_AMLOGIC_EFFECT_INI  0x01
+#define NO_AMLOGIC_SOC_INI 0x10
+
 int eq_mode_set(struct eq_drc_data *pdata, int eq_mode);
 int eq_drc_init(struct eq_drc_data *pdata);
 int eq_drc_release(struct eq_drc_data *pdata);
diff --git a/audio_hal/audio_hw.c b/audio_hal/audio_hw.c
index 862e804..ab477ce 100644
--- a/audio_hal/audio_hw.c
+++ b/audio_hal/audio_hw.c
@@ -4656,10 +4656,10 @@
     }
     ret = str_parms_get_str(parms,"fb_drc",value,sizeof(value));
     if (ret >= 0) {
-        sscanf(value, "%u %u %u %u %f %f %u",&adev->Drc_data.band_id,&adev->Drc_data.attrack_time,&adev->Drc_data.release_time,
-             &adev->Drc_data.estimate_time,&adev->Drc_data.K,&adev->Drc_data.threshold,&adev->Drc_data.delays);
-        setfb_drc(adev->Drc_data.band_id,adev->Drc_data.attrack_time,adev->Drc_data.release_time,adev->Drc_data.estimate_time,
-               adev->Drc_data.K,adev->Drc_data.threshold,adev->Drc_data.delays);
+        sscanf(value, "%u %u %u %u %f %f %f",&adev->Drc_data.band_id,&adev->Drc_data.attrack_time,&adev->Drc_data.release_time,
+             &adev->Drc_data.estimate_time,&adev->Drc_data.K,&adev->Drc_data.threshold,&adev->Drc_data.offset);
+        setfb_drc(adev->Drc_data.band_id,adev->Drc_data.attrack_time,adev->Drc_data.release_time,
+                adev->Drc_data.estimate_time, adev->Drc_data.K, adev->Drc_data.threshold, adev->Drc_data.offset);
         goto exit;
     }
     ret = str_parms_get_str(parms,"csfilter_drc",value,sizeof(value));
@@ -5272,6 +5272,40 @@
         goto exit;
     }
 
+    ret = str_parms_get_str(parms, "tuning_binary", value, sizeof(value));
+    if (ret >= 0 && strlen(value)) {
+        if ((eDolbyMS12Lib == adev->dolby_lib_type) && (adev->dolby_ms12_audio_config != MS12_CONFIG_Y)) {
+            adev->is_ms12_tuning_dat = is_ms12_tuning_dat_in_dut(value);
+            if (adev->is_ms12_tuning_dat) {
+                /*ms12_tuning_dat exists, the Dolby config type X/Z remains unchanged */
+                if (strncmp(adev->ms12_tuning_dat_path, value, sizeof(value))) {
+                    /*If the ms12_tuning_dat path differs, re-initialize ms12*/
+                    memset(adev->ms12_tuning_dat_path, 0, AUDIO_HAL_CHAR_MAX_LEN);
+                    memcpy(adev->ms12_tuning_dat_path, value, sizeof(value));
+                    /* If ms12 has been initialized, dap needs to be re-initialized to take effect */
+                    if (ms12->dolby_ms12_init_flags) {
+                        adev_ms12_cleanup(&adev->hw_device);
+                        adev_ms12_prepare(&adev->hw_device);
+                        ALOGI("[%s:%d] Dolby dap tuning data update, need reset ms12", __func__, __LINE__);
+                    }
+                }
+            } else {
+                adev->dolby_ms12_audio_config = MS12_CONFIG_Y;
+                ALOGW("[%s:%d] The file in the %s path does not exist", __func__, __LINE__, value);
+            }
+        } else {
+            ALOGE("[%s:%d] Check if Dolby lib or Dolby config type supports.", __func__, __LINE__);
+        }
+        goto exit;
+    }
+    ret = str_parms_get_str(parms, "Dolby_Config_Type", value, sizeof(value));
+    if (ret >= 0 && strlen(value)) {
+            adev->dolby_ms12_audio_config = (strcasestr(value, "Z") != NULL) ? MS12_CONFIG_Z : \
+                (strcasestr(value, "X") != NULL) ? MS12_CONFIG_X : MS12_CONFIG_Y;
+        ALOGI("[%s:%d],use dolby config %d ", __func__, __LINE__, adev->dolby_ms12_audio_config);
+        goto exit;
+    }
+
     ret = str_parms_get_str(parms, "VX_SET_DTS_Mode", value, sizeof(value));
     if (ret >= 0) {
         int dts_decoder_output_mode = atoi(value);
@@ -5442,6 +5476,33 @@
         goto exit;
     }
 
+    ret = str_parms_get_str(parms,"remove_audio_effect", value , sizeof(value));
+    if (ret >= 0) {
+        char sound_effect_support_list[AUDIO_HAL_CHAR_MAX_LEN] = {0};
+        aml_get_support_effect_list(adev, sound_effect_support_list);
+        if (strncmp(value, "all", strlen(value)) == 0) {
+            ALOGI("adev->native_postprocess.num_postprocessors=%d\n",adev->native_postprocess.num_postprocessors);
+            effect_descriptor_t tmpdesc_remove;
+            while (adev->native_postprocess.num_postprocessors > 0) {
+                effect_handle_t effect = adev->native_postprocess.postprocessors[adev->native_postprocess.num_postprocessors-1];
+                adev_remove_device_effect(dev, 0, effect);
+            }
+            AM_LOGI("remove %s sound effect", value);
+        } else {
+            effect_descriptor_t tmpdesc_in_queue;
+            for (int i = 0; i < adev->native_postprocess.num_postprocessors; i++) {
+                (*adev->native_postprocess.postprocessors[i])->get_descriptor(adev->native_postprocess.postprocessors[i], &tmpdesc_in_queue);
+                if (strncmp (tmpdesc_in_queue.name, value, strlen(tmpdesc_in_queue.name)) == 0) {
+                    adev_remove_device_effect(dev, 0, adev->native_postprocess.postprocessors[i]);
+                    AM_LOGI("support %s effect, remove %s sound effect", sound_effect_support_list, value);
+                    break;
+                }
+            }
+            AM_LOGW("Not support %s effect, remove sound effect failed", value);
+        }
+        goto exit;
+    }
+
 #ifdef BUILD_LINUX
     ret = str_parms_get_str(parms, "setenv", value, sizeof(value));
     if (ret >= 0) {
@@ -8534,9 +8595,14 @@
     }
     effect_descriptor_t tmpdesc_in_queue;
     effect_descriptor_t tmpdesc_remove;
+    if (!effect) {
+        ALOGE("%s:Check parameters correctly",__func__);
+        status = -ENOSYS;
+        goto exit;
+    }
+    (*effect)->get_descriptor(effect, &tmpdesc_remove);
     for (i = 0; i < aml_dev->native_postprocess.num_postprocessors; i++) {
         (*aml_dev->native_postprocess.postprocessors[i])->get_descriptor(aml_dev->native_postprocess.postprocessors[i], &tmpdesc_in_queue);
-        (*aml_dev->native_postprocess.postprocessors[i])->get_descriptor(effect, &tmpdesc_remove);
         if (0 == strcmp(tmpdesc_in_queue.name, tmpdesc_remove.name)) {
             aml_dev->native_postprocess.postprocessors[i] = NULL;
             status = 0;
@@ -8926,8 +8992,11 @@
                 if (is_STB(adev)) { //STB set to Dolby config X, no DOLBY_TUNING_DAT, set DAP mode to DAP_CONTENT_PROC for content processing.
                     adev->dolby_ms12_dap_init_mode = DAP_CONTENT_PROC_MODE;
                 } else {
-                    adev->is_ms12_tuning_dat = is_ms12_tuning_dat_in_dut();
-                    if (!adev->is_ms12_tuning_dat) {
+                    adev->is_ms12_tuning_dat = is_ms12_tuning_dat_in_dut(DOLBY_TUNING_DAT);
+                    if (adev->is_ms12_tuning_dat) {
+                        memset(adev->ms12_tuning_dat_path, 0, AUDIO_HAL_CHAR_MAX_LEN);
+                        memcpy(adev->ms12_tuning_dat_path, DOLBY_TUNING_DAT, sizeof(DOLBY_TUNING_DAT));
+                    } else {
                         ALOGE("DOLBY_TUNING_DAT is missing, updated dolby config to Y (%s)", str_val);
                         adev->dolby_ms12_audio_config = MS12_CONFIG_Y;
                     }
@@ -9000,7 +9069,23 @@
     }
 
 #ifdef USE_EQ_DRC
-    if (eq_drc_init(&adev->eq_data) == 0) {
+    ret = eq_drc_init(&adev->eq_data);
+    if (ret > 0) {
+        if (0 != (ret & NO_AMLOGIC_EFFECT_INI)) {
+            /*If AMLOGIC_EFFECT_INI file missing, set default EQ_DRC full band params
+             *#Amlogic_DRC_Param_Generator -M 0 -m 2 -b 0 -a 2 -r 100 -e 10 -k 0 -t 0 -o 10
+             */
+            adev->Drc_data.band_id = 0;
+            adev->Drc_data.attrack_time = 2;
+            adev->Drc_data.release_time = 100;
+            adev->Drc_data.estimate_time = 10;
+            adev->Drc_data.K = 0;
+            adev->Drc_data.threshold = 0;
+            adev->Drc_data.offset = 10;
+            setfb_drc(adev->Drc_data.band_id,adev->Drc_data.attrack_time,adev->Drc_data.release_time,
+                adev->Drc_data.estimate_time, adev->Drc_data.K, adev->Drc_data.threshold, adev->Drc_data.offset);
+            aml_mixer_ctrl_set_int(&adev->alsa_mixer, AML_MIXER_ID_AED_FULL_DRC_ENABLE, 0);
+        }
         ALOGI("%s() audio source gain: atv:%f, dtv:%f, hdmiin:%f, av:%f, media:%f", __func__,
            adev->eq_data.s_gain.atv, adev->eq_data.s_gain.dtv,
            adev->eq_data.s_gain.hdmi, adev->eq_data.s_gain.av, adev->eq_data.s_gain.media);
diff --git a/audio_hal/audio_hw.h b/audio_hal/audio_hw.h
index 34a9881..5aa4bf1 100644
--- a/audio_hal/audio_hw.h
+++ b/audio_hal/audio_hw.h
@@ -137,7 +137,8 @@
 
 #define SOUND_DMX_MODE_SURROUND  0
 #define SOUND_DMX_MODE_STEREO    1
-
+/* Maximum string length in audio hal. */
+#define AUDIO_HAL_CHAR_MAX_LEN                          (256)
 
 struct renderpts_item {
     struct listnode list;
@@ -224,7 +225,7 @@
     unsigned int fc;
     unsigned int estimate_time;
     float K;
-    unsigned int delays;
+    float offset;
 };
 
 struct eq_data {
@@ -576,6 +577,7 @@
     /* display audio format on UI, both streaming and hdmiin*/
     audio_hal_info_t audio_hal_info;
     bool is_ms12_tuning_dat; /* a flag to determine the MS12 tuning data file is existing */
+    char ms12_tuning_dat_path[AUDIO_HAL_CHAR_MAX_LEN];
     /*
     defined for default speaker output channels:
     stb: default 2 channels.
@@ -1141,6 +1143,9 @@
 int get_stream_source_volume(struct aml_stream_out *aml_out);
 void set_rate_to_sync (struct aml_stream_out *aml_out, float rate);
 
+static int adev_remove_device_effect(struct audio_hw_device *dev, audio_port_handle_t device, effect_handle_t effect);
+
+
 
 /* 'bytes' are the number of bytes written to audio FIFO, for which 'timestamp' is valid.
  * 'available' is the number of frames available to read (for input) or yet to be played
@@ -1174,6 +1179,4 @@
 #define PLAYBACK_PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * PLAYBACK_PERIOD_MULTIPLIER)
 #define CHANNEL_STEREO 2
 #define PLAYBACK_CODEC_SAMPLING_RATE 48000
-/* Maximum string length in audio hal. */
-#define AUDIO_HAL_CHAR_MAX_LEN                          (256)
 #endif
diff --git a/audio_hal/audio_hw_ms12_v2.c b/audio_hal/audio_hw_ms12_v2.c
index 11b804f..da63732 100644
--- a/audio_hal/audio_hw_ms12_v2.c
+++ b/audio_hal/audio_hw_ms12_v2.c
@@ -1055,6 +1055,12 @@
     return dap_init_mode;
 }
 
+static void set_dolby_ms12_dap_tuning_data_file(char* dap_tuning_file_name)
+{
+    ALOGI("[%s:%d] Dap tuning file name is:%s", __FUNCTION__, __LINE__, dap_tuning_file_name);
+    dolby_ms12_set_dap2_initialisation_tuningfile(dap_tuning_file_name);
+}
+
 static void set_dolby_ms12_downmix_mode(struct aml_audio_device *adev)
 {
     struct dolby_ms12_desc *ms12 = &(adev->ms12);
@@ -1207,6 +1213,7 @@
 
     set_dolby_ms12_drc_parameters(input_format, output_config, adev->decoder_drc_control);
     if (dap_init_mode) {
+        set_dolby_ms12_dap_tuning_data_file(adev->ms12_tuning_dat_path);
         /*coverity[missing_lock]: adev->dap_drc_control does not need to be lock*/
         set_dap_drc_parameters(ms12, adev->dap_drc_control);
     }
diff --git a/audio_hal/dolby_lib_api.c b/audio_hal/dolby_lib_api.c
index 5510c33..2967988 100644
--- a/audio_hal/dolby_lib_api.c
+++ b/audio_hal/dolby_lib_api.c
@@ -232,12 +232,16 @@
     return dap_init_mode;
 }
 
-bool is_ms12_tuning_dat_in_dut() //availabe in Dolby MS12 V2.4 or later
+bool is_ms12_tuning_dat_in_dut(char *filename) //available in Dolby MS12 V2.4 or later
 {
-    if (file_accessible(DOLBY_TUNING_DAT) == 0)
-        return true;
-    else
-        return false;
+    if (NULL != filename) {
+        ALOGI("%s: DOLBY_TUNING_DAT path is %s\n", __FUNCTION__, filename);
+        if (file_accessible(filename) == RET_OK) {
+            return true;
+        } else {
+            return false;
+        }
+    }
 }
 
 #endif
diff --git a/audio_hal/dolby_lib_api.h b/audio_hal/dolby_lib_api.h
index 219007c..ade211e 100644
--- a/audio_hal/dolby_lib_api.h
+++ b/audio_hal/dolby_lib_api.h
@@ -45,6 +45,6 @@
 /*
  *@brief check that the MS12 Tuning dat is existing or not.
  */
-bool is_ms12_tuning_dat_in_dut();
+bool is_ms12_tuning_dat_in_dut(char *filename);
 
 #endif //_DOLBY_LIB_API_H_
diff --git a/decoder/libms12_v24/include/DolbyMS12ConfigParams.h b/decoder/libms12_v24/include/DolbyMS12ConfigParams.h
index 1e70a8b..3f4b81b 100644
--- a/decoder/libms12_v24/include/DolbyMS12ConfigParams.h
+++ b/decoder/libms12_v24/include/DolbyMS12ConfigParams.h
@@ -198,6 +198,15 @@
     {
         mDAPInitMode = val;    // 0 or 1
     }
+    virtual void setDAPV2InitialisationDAPTuningFile(char* dap_tuning_file_name)
+    {
+        if (dap_tuning_file_name != NULL) {
+            mDAPTuningFile = dap_tuning_file_name;
+            ALOGI("+%s(): str=%s mDAPTuningFile=%s\n", __FUNCTION__, dap_tuning_file_name, mDAPTuningFile);
+        } else {
+            ALOGE("+%s():mDAPTuningFile=%s\n", __FUNCTION__, mDAPTuningFile);
+        }
+    }
     virtual void setDAPV2VirtualBassEnable(bool flag)
     {
         mDAPVirtualBassEnable = flag;    // 0 or 1
diff --git a/decoder/libms12_v24/include/dolby_ms12_config_params.h b/decoder/libms12_v24/include/dolby_ms12_config_params.h
index 1cc934e..f623147 100644
--- a/decoder/libms12_v24/include/dolby_ms12_config_params.h
+++ b/decoder/libms12_v24/include/dolby_ms12_config_params.h
@@ -237,6 +237,11 @@
 void dolby_ms12_set_dap2_initialisation_mode(int val);
 
 /**
+ * Customize the dap_tuning_file path
+ */
+void dolby_ms12_set_dap2_initialisation_tuningfile(char* dap_tuning_file_name);
+
+/**
  * @brief DAPv2 Virtual Bass enable (additional delay)
  * 0 = DAPv2 Virtual Bass is not enabled (default)
  * 1 = DAPv2 Virtual Bass is enabled
diff --git a/decoder/libms12_v24/src/dolby_ms12_config_params.cpp b/decoder/libms12_v24/src/dolby_ms12_config_params.cpp
index fad6712..aade615 100644
--- a/decoder/libms12_v24/src/dolby_ms12_config_params.cpp
+++ b/decoder/libms12_v24/src/dolby_ms12_config_params.cpp
@@ -427,6 +427,15 @@
     }
 }
 
+extern "C" void dolby_ms12_set_dap2_initialisation_tuningfile(char* dap_tuning_file_name)
+{
+    ALOGV("%s():filename=%s\n", __FUNCTION__, dap_tuning_file_name);
+    android::DolbyMS12ConfigParams *config_param = getInstance();
+    if (config_param) {
+        config_param->setDAPV2InitialisationDAPTuningFile(dap_tuning_file_name);
+    }
+}
+
 extern "C" void dolby_ms12_set_dap2_virtual_bass_enable(bool flag)
 {
     ALOGV("%s()\n", __FUNCTION__);
diff --git a/decoder/libms12_v26/include/DolbyMS12ConfigParams.h b/decoder/libms12_v26/include/DolbyMS12ConfigParams.h
index e3a6a9c..fa3ffe3 100644
--- a/decoder/libms12_v26/include/DolbyMS12ConfigParams.h
+++ b/decoder/libms12_v26/include/DolbyMS12ConfigParams.h
@@ -199,6 +199,15 @@
     {
         mDAPInitMode = val;    // 0 or 1
     }
+    virtual void setDAPV2InitialisationDAPTuningFile(char* dap_tuning_file_name)
+    {
+        if (dap_tuning_file_name != NULL) {
+            mDAPTuningFile = dap_tuning_file_name;
+            ALOGI("+%s(): str=%s mDAPTuningFile=%s\n", __FUNCTION__, dap_tuning_file_name, mDAPTuningFile);
+        } else {
+            ALOGE("+%s():mDAPTuningFile=%s\n", __FUNCTION__, mDAPTuningFile);
+        }
+    }
     virtual void setDAPV2VirtualBassEnable(bool flag)
     {
         mDAPVirtualBassEnable = flag;    // 0 or 1
diff --git a/decoder/libms12_v26/include/dolby_ms12_config_params.h b/decoder/libms12_v26/include/dolby_ms12_config_params.h
index 16de5d8..d5d5183 100644
--- a/decoder/libms12_v26/include/dolby_ms12_config_params.h
+++ b/decoder/libms12_v26/include/dolby_ms12_config_params.h
@@ -233,6 +233,11 @@
 void dolby_ms12_set_dap2_initialisation_mode(int val);
 
 /**
+ * Customize the dap_tuning_file path
+ */
+void dolby_ms12_set_dap2_initialisation_tuningfile(char* dap_tuning_file_name);
+
+/**
  * @brief DAPv2 Virtual Bass enable (additional delay)
  * 0 = DAPv2 Virtual Bass is not enabled (default)
  * 1 = DAPv2 Virtual Bass is enabled
diff --git a/decoder/libms12_v26/src/dolby_ms12_config_params.cpp b/decoder/libms12_v26/src/dolby_ms12_config_params.cpp
index 7afe816..deebfa6 100644
--- a/decoder/libms12_v26/src/dolby_ms12_config_params.cpp
+++ b/decoder/libms12_v26/src/dolby_ms12_config_params.cpp
@@ -451,6 +451,15 @@
     }
 }
 
+extern "C" void dolby_ms12_set_dap2_initialisation_tuningfile(char* dap_tuning_file_name)
+{
+    ALOGV("%s():filename=%s\n", __FUNCTION__, dap_tuning_file_name);
+    android::DolbyMS12ConfigParams *config_param = getInstance();
+    if (config_param) {
+        config_param->setDAPV2InitialisationDAPTuningFile(dap_tuning_file_name);
+    }
+}
+
 extern "C" void dolby_ms12_set_dap2_virtual_bass_enable(bool flag)
 {
     ALOGV("%s()\n", __FUNCTION__);