audio: Apply app type gain at start of stream

App type for a usecase is derived at start of stream.
Therefore, any volume gain based on app type cannot be
applied before start. Cache any gain value
sent from AF before start of stream and send after
stream has started

Bug: 62393776
Test: hangout call
Change-Id: Ia772d5ee1b2cc7293d69b31f06f1c160a5d7284e
Signed-off-by: David Lin <dtwlin@google.com>
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;