stream-manager: Improve audio ducking function 55/210455/6 accepted/tizen/unified/20190724.063810 submit/tizen/20190723.054438
authorJeongmo Yang <jm80.yang@samsung.com>
Fri, 19 Jul 2019 05:56:14 +0000 (14:56 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Tue, 23 Jul 2019 04:44:54 +0000 (13:44 +0900)
1. Fix crash
: If ducked stream is removed without deactivating,
  the pointer for the removed stream is still remained in idxset of ducking_streams.
  It caused crash when ducking stream is destroyed.

2. Apply ducking to new stream
: If new role-matched stream is created when after ducked,
  apply ducking to it without fade-out.

[Version] 11.1.60
[Issue Type] Improvement

Change-Id: Ida0556e5d8c1d10f001357291ca17193174c26ae
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
packaging/pulseaudio-modules-tizen.spec
src/stream-manager-dbus.c
src/stream-manager-priv.h
src/stream-manager.c

index 3d5462c..3cfa404 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          11.1.59
+Version:          11.1.60
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 7df7710..1825221 100644 (file)
@@ -1810,6 +1810,13 @@ static void handle_activate_ducking(DBusConnection *conn, DBusMessage *msg, void
     /* get stream_ducking */
     pa_assert_se((sd = pa_hashmap_get(m->stream_duckings, (const void*)id)));
 
+    if (enable) {
+        snprintf(sd->vol_key, VOLUME_KEY_LENGTH, "stream_ducking_%u_%s", id, target_stream);
+        snprintf(sd->target_role, STREAM_ROLE_STR_MAX, "%s", target_stream);
+        sd->duration = duration;
+        sd->set_vol = PA_VOLUME_NORM * ratio;
+    }
+
     /* set volume ramp factor to target stream */
     PA_IDXSET_FOREACH(stream, m->core->sink_inputs, idx) {
         if (!pa_safe_streq(target_stream, pa_proplist_gets(stream->proplist, PA_PROP_MEDIA_ROLE)))
@@ -1819,25 +1826,22 @@ static void handle_activate_ducking(DBusConnection *conn, DBusMessage *msg, void
         sd->ducking_stream_count++;
 
         if (enable) {
-            pa_volume_t set_vol;
             pa_cvolume_ramp vol_ramp;
 
-            snprintf(sd->vol_ramp_key, VOLUME_RAMP_KEY_LENGTH, "stream_ducking_%u_%s", id, target_stream);
-
             pa_idxset_put(sd->idx_ducking_streams, (void *)stream, NULL);
 
-            set_vol = PA_VOLUME_NORM * ratio;
-
-            pa_log_info("ducking: [%p] set vol [%u], key [%s]", stream, set_vol, sd->vol_ramp_key);
+            pa_log_info("ducking: [%p] set vol [%u], key [%s], role [%s]",
+                stream, sd->set_vol, sd->vol_key, sd->target_role);
 
             pa_cvolume_ramp_set(&vol_ramp, stream->volume.channels,
-                PA_VOLUME_RAMP_TYPE_LINEAR, (long)duration, set_vol);
+                PA_VOLUME_RAMP_TYPE_LINEAR, (long)duration, sd->set_vol);
 
-            pa_sink_input_add_volume_ramp_factor(stream, sd->vol_ramp_key, &vol_ramp, true);
+            pa_sink_input_add_volume_ramp_factor(stream, sd->vol_key, &vol_ramp, true);
         } else {
-            pa_log_info("unducking : remove volume ramp factor [key:%s]", sd->vol_ramp_key);
+            pa_log_info("unducking : remove volume(ramp) factor [key:%s]", sd->vol_key);
 
-            pa_sink_input_remove_volume_ramp_factor(stream, sd->vol_ramp_key, true);
+            pa_sink_input_remove_volume_factor(stream, sd->vol_key);
+            pa_sink_input_remove_volume_ramp_factor(stream, sd->vol_key, true);
         }
     }
 
index ab5488d..d7449e5 100644 (file)
@@ -113,7 +113,8 @@ typedef enum _notify_command_type {
 #define STREAM_FOCUS_STATE_RELEASED    "0"
 #define STREAM_FOCUS_STATE_ACQUIRED    "1"
 
-#define VOLUME_RAMP_KEY_LENGTH         24
+#define VOLUME_KEY_LENGTH              24
+#define STREAM_ROLE_STR_MAX            32
 
 #define AVAIL_DEVICES_MAX 16
 #define AVAIL_FRAMEWORKS_MAX 16
@@ -194,11 +195,14 @@ typedef struct _stream_parent {
 } stream_parent;
 
 typedef struct _stream_ducking {
+    bool is_ducked;
     int trigger_index;
     int ducking_stream_count;
+    char vol_key[VOLUME_KEY_LENGTH];
+    char target_role[STREAM_ROLE_STR_MAX];
+    uint32_t duration;
+    pa_volume_t set_vol;
     pa_idxset *idx_ducking_streams;
-    char vol_ramp_key[VOLUME_RAMP_KEY_LENGTH];
-    bool is_ducked;
 } stream_ducking;
 
 typedef struct _filter_info {
index 9c6a00b..5537ba9 100644 (file)
@@ -2184,6 +2184,58 @@ static void remove_sink_input_from_muted_streams(pa_stream_manager *m, pa_sink_i
                 pa_idxset_remove_by_data(streams, i, NULL);
 }
 
+/* Remove the sink-input from ducking streams */
+static void remove_sink_input_from_ducking_streams(pa_stream_manager *m, pa_sink_input *i) {
+    uint32_t idx = 0;
+    stream_ducking *sd = NULL;
+    void *stream = NULL;
+    void *state;
+
+    pa_assert(m);
+
+    PA_HASHMAP_FOREACH(sd, m->stream_duckings, state) {
+        PA_IDXSET_FOREACH(stream, sd->idx_ducking_streams, idx) {
+            if (stream == i) {
+                pa_log_info("remove ducking stream[i:%u,%p] from idx_ducking_streams", i->index, i);
+                pa_idxset_remove_by_data(sd->idx_ducking_streams, stream, NULL);
+                return;
+            }
+        }
+    }
+}
+
+/* Add the sink-input to ducking streams */
+static void add_sink_input_to_ducking_streams(pa_stream_manager *m, pa_sink_input *i) {
+    stream_ducking *sd = NULL;
+    void *state;
+
+    pa_assert(m);
+
+    PA_HASHMAP_FOREACH(sd, m->stream_duckings, state) {
+        pa_cvolume_ramp vol_ramp;
+        pa_cvolume vol;
+
+        if (!pa_safe_streq(sd->target_role, pa_proplist_gets(i->proplist, PA_PROP_MEDIA_ROLE)))
+            continue;
+
+        pa_log_info("add ducking stream[i:%u,%p] to idx_ducking_streams, volume %u",
+            i->index, i, sd->set_vol);
+
+        pa_idxset_put(sd->idx_ducking_streams, (void *)i, NULL);
+
+        pa_cvolume_ramp_set(&vol_ramp, i->volume.channels,
+            PA_VOLUME_RAMP_TYPE_LINEAR, (long)sd->duration, sd->set_vol);
+
+        vol.channels = i->volume.channels;
+        vol.values[0] = sd->set_vol;
+
+        pa_sink_input_add_volume_factor(i, sd->vol_key, &vol);
+        pa_sink_input_add_volume_ramp_factor(i, sd->vol_key, &vol_ramp, false);
+
+        return;
+    }
+}
+
 static pa_hook_result_t sink_input_new_cb(pa_core *core, pa_sink_input_new_data *new_data, pa_stream_manager *m) {
     pa_core_assert_ref(core);
 
@@ -2211,6 +2263,8 @@ static pa_hook_result_t sink_input_put_cb(pa_core *core, pa_sink_input *i, pa_st
         m->on_call = true;
     }
 
+    add_sink_input_to_ducking_streams(m, i);
+
     return PA_HOOK_OK;
 }
 
@@ -2224,7 +2278,10 @@ static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, pa
         m->on_call = false;
         set_media_active_device(m);
     }
+
     remove_sink_input_from_muted_streams(m, i);
+    remove_sink_input_from_ducking_streams(m, i);
+
     process_stream(m, i, STREAM_SINK_INPUT, PROCESS_COMMAND_REMOVE_PARENT_ID, false);
     process_stream(m, i, STREAM_SINK_INPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false);
 
@@ -3213,8 +3270,9 @@ static void subscribe_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t
             pa_log_info(" - remove sd(%p), idx(%u)", sd, idx);
 
             PA_IDXSET_FOREACH(stream, sd->idx_ducking_streams, ducking_idx) {
-                pa_log_info("remove volume ramp for remained stream %p, key %s", stream, sd->vol_ramp_key);
-                pa_sink_input_remove_volume_ramp_factor(stream, sd->vol_ramp_key, true);
+                pa_log_info("remove volume ramp for remained stream %p, key %s", stream, sd->vol_key);
+                pa_sink_input_remove_volume_factor(stream, sd->vol_key);
+                pa_sink_input_remove_volume_ramp_factor(stream, sd->vol_key, true);
             }
 
             pa_idxset_free(sd->idx_ducking_streams, NULL);