audio: Apply app type gain at start of stream
am: 4a824779a3

Change-Id: Ib8b7df37636eec5a8607109559a43e9f3892f7fe
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 600c179..36a8ba5 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -145,6 +145,9 @@
                                        struct audio_usecase *usecase);
 void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
                                              struct audio_usecase *usecase);
+int audio_extn_utils_send_app_type_gain(struct audio_device *adev,
+                                        int app_type,
+                                        int *gain);
 #ifndef HWDEP_CAL_ENABLED
 #define  audio_extn_hwdep_cal_send(snd_card, acdb_handle) (0)
 #else
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 2fc424c..c9d2397 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -218,7 +218,7 @@
     struct stream_app_type_cfg *app_type_cfg = &in->app_type_cfg;
 
     *sample_rate = DEFAULT_INPUT_SAMPLING_RATE;
-    if (in->device & AUDIO_DEVICE_IN_USB_DEVICE) {
+    if (audio_is_usb_in_device(in->device)) {
         platform_check_and_update_copp_sample_rate(adev->platform,
                                                    usecase->in_snd_device,
                                                    in->sample_rate,
@@ -271,7 +271,7 @@
 
     // add speaker prot changes if needed
     // and use that to check for device
-    if (out->devices & AUDIO_DEVICE_OUT_USB_DEVICE) {
+    if (audio_is_usb_out_device(out->devices)) {
         platform_check_and_update_copp_sample_rate(adev->platform,
                                                    usecase->out_snd_device,
                                                    out->sample_rate,
@@ -385,6 +385,28 @@
     return 0;
 }
 
+int audio_extn_utils_send_app_type_gain(struct audio_device *adev,
+                                        int app_type,
+                                        int *gain)
+{
+    int gain_cfg[4];
+    const char *mixer_ctl_name = "App Type Gain";
+    struct mixer_ctl *ctl;
+    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: Could not get volume ctl mixer %s", __func__,
+              mixer_ctl_name);
+        return -EINVAL;
+    }
+    gain_cfg[0] = 0;
+    gain_cfg[1] = app_type;
+    gain_cfg[2] = gain[0];
+    gain_cfg[3] = gain[1];
+    ALOGV("%s app_type %d l(%d) r(%d)", __func__,  app_type, gain[0], gain[1]);
+    return mixer_ctl_set_array(ctl, gain_cfg,
+                               sizeof(gain_cfg)/sizeof(gain_cfg[0]));
+}
+
 // this assumes correct app_type and sample_rate fields
 // have been set for the stream using audio_extn_utils_send_app_type_cfg
 void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 44a0216..3ad965e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -66,7 +66,11 @@
 #define COMPRESS_OFFLOAD_NUM_FRAGMENTS 3
 /* ToDo: Check and update a proper value in msec */
 #define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96
+/* treat as unsigned Q1.13 */
+#define APP_TYPE_GAIN_DEFAULT         0x2000
 #define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
+
+/* treat as unsigned Q1.13 */
 #define VOIP_PLAYBACK_VOLUME_MAX 0x2000
 
 #define PROXY_OPEN_RETRY_COUNT           100
@@ -536,6 +540,11 @@
     return ret;
 }
 
+static void stream_app_type_cfg_init(struct stream_app_type_cfg *cfg)
+{
+    cfg->gain[0] = cfg->gain[1] = APP_TYPE_GAIN_DEFAULT;
+}
+
 int enable_audio_route(struct audio_device *adev,
                        struct audio_usecase *usecase)
 {
@@ -1859,7 +1868,9 @@
     register_out_stream(out);
     audio_extn_perf_lock_release();
     audio_extn_tfa_98xx_enable_speaker();
-
+    audio_extn_utils_send_app_type_gain(out->dev,
+                                        out->app_type_cfg.app_type,
+                                        &out->app_type_cfg.gain[0]);
     ALOGV("%s: exit", __func__);
     return 0;
 error_open:
@@ -2378,21 +2389,14 @@
         mixer_ctl_set_array(ctl, volume, sizeof(volume)/sizeof(volume[0]));
         return 0;
     } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
-        int gain_cfg[4];
-        const char *mixer_ctl_name = "App Type Gain";
-        struct audio_device *adev = out->dev;
-        struct mixer_ctl *ctl;
-        ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
-        if (!ctl) {
-            ALOGE("%s: Could not get volume ctl mixer %s", __func__,
-                  mixer_ctl_name);
-            return -EINVAL;
+        out->app_type_cfg.gain[0] = (int)(left * VOIP_PLAYBACK_VOLUME_MAX);
+        out->app_type_cfg.gain[1] = (int)(right * VOIP_PLAYBACK_VOLUME_MAX);
+        if (!out->standby) {
+            // if in standby, cached volume will be sent after stream is opened
+            audio_extn_utils_send_app_type_gain(out->dev,
+                                                out->app_type_cfg.app_type,
+                                                &out->app_type_cfg.gain[0]);
         }
-        gain_cfg[0] = 0;
-        gain_cfg[1] = out->app_type_cfg.app_type;
-        gain_cfg[2] = (int)(left * VOIP_PLAYBACK_VOLUME_MAX);
-        gain_cfg[3] = (int)(right * VOIP_PLAYBACK_VOLUME_MAX);
-        mixer_ctl_set_array(ctl, gain_cfg, sizeof(gain_cfg)/sizeof(gain_cfg[0]));
         return 0;
     }
 
@@ -3765,6 +3769,8 @@
     pthread_mutex_unlock(&adev->lock);
     pthread_mutex_unlock(&out->lock);
 
+    stream_app_type_cfg_init(&out->app_type_cfg);
+
     *stream_out = &out->stream;
 
     ALOGV("%s: exit", __func__);
@@ -4258,6 +4264,7 @@
             ALOGV("%s: USECASE_AUDIO_RECORD_MMAP", __func__);
         } else if (in->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
                    in->dev->mode == AUDIO_MODE_IN_COMMUNICATION &&
+                   in->flags & AUDIO_INPUT_FLAG_VOIP_TX &&
                    (config->sample_rate == 8000 ||
                     config->sample_rate == 16000 ||
                     config->sample_rate == 32000 ||
@@ -4274,7 +4281,6 @@
             in->config.period_count = VOIP_CAPTURE_PERIOD_COUNT;
             in->config.rate = config->sample_rate;
             in->af_period_multiplier = 1;
-            in->flags |= AUDIO_INPUT_FLAG_VOIP_TX;
         } else {
             in->config = pcm_config_audio_capture;
             frame_size = audio_stream_in_frame_size(&in->stream);
@@ -4305,6 +4311,8 @@
     pthread_mutex_unlock(&adev->lock);
     pthread_mutex_unlock(&in->lock);
 
+    stream_app_type_cfg_init(&in->app_type_cfg);
+
     *stream_in = &in->stream;
     ALOGV("%s: exit", __func__);
     return 0;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 28bf19b..46384a2 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -177,6 +177,7 @@
     uint32_t bit_width; // unused
     const char *mode;
     int app_type;
+    int gain[2];
 };
 
 struct stream_out {