ramp-mute new streams 99/10699/1
authorJanos Kovacs <jankovac503@gmail.com>
Fri, 4 Oct 2013 12:24:49 +0000 (15:24 +0300)
committerJaska Uimonen <jaska.uimonen@helsinki.fi>
Wed, 9 Oct 2013 11:31:07 +0000 (14:31 +0300)
Change-Id: Id8346e44fa7ee23e71e5489d51bdeeff8ecf581e

murphy/discover.c
murphy/fader.c
murphy/fader.h
murphy/stream-state.c

index 6e2c7b6..ad79839 100644 (file)
@@ -654,6 +654,8 @@ void pa_discover_add_source(struct userdata *u, pa_source *source)
 
             if (make_rset)
                 pa_murphyif_create_resource_set(u, node, resdef);
+
+            pa_fader_apply_volume_limits(u, node->stamp);
         }
     }
     else {
@@ -838,6 +840,7 @@ void pa_discover_preroute_sink_input(struct userdata *u,
     mir_node          *node;
     pa_muxnode        *mux;
     pa_nodeset_resdef *resdef;
+    bool               loopback;
 
     pa_assert(u);
     pa_assert(data);
@@ -849,6 +852,7 @@ void pa_discover_preroute_sink_input(struct userdata *u,
     mnam = (m = data->module) ? m->name : "";
 
     if (pa_streq(mnam, "module-combine-sink")) {
+        loopback = false;
         type = mir_node_type_unknown;
 
         if (!(mux  = pa_multiplex_find_by_module(multiplex, m)) ||
@@ -863,7 +867,9 @@ void pa_discover_preroute_sink_input(struct userdata *u,
         }
     }
     else {
-        if (pa_streq(mnam, "module-loopback")) {
+        loopback = pa_streq(mnam, "module-loopback");
+
+        if (loopback) {
             if (!(node = pa_utils_get_node_from_data(u, mir_input, data))) {
                 pa_log_debug("can't find loopback node for sink-input");
                 return;
@@ -889,6 +895,7 @@ void pa_discover_preroute_sink_input(struct userdata *u,
                 pa_log_debug("start corked");
             }
         }
+
         pa_utils_set_stream_routing_properties(pl, type, data->sink);
     }
 
@@ -913,13 +920,20 @@ void pa_discover_preroute_sink_input(struct userdata *u,
                 schedule_stream_uncorking(u, sink);
             }
 #endif
-
             if (pa_sink_input_new_data_set_sink(data, sink, FALSE))
                 pa_log_debug("set sink %u for new sink-input", sink->index);
             else
                 pa_log("can't set sink %u for new sink-input", sink->index);
         }
     }
+
+    if (loopback && data->sink && data->sink->module) {
+        if (pa_streq(data->sink->module->name, "module-combine-sink"))
+            return;
+    }
+
+    pa_log_debug("set sink-input ramp-muted");
+    data->flags |= PA_SINK_INPUT_START_RAMP_MUTED;
 }
 
 
@@ -1049,6 +1063,11 @@ void pa_discover_add_sink_input(struct userdata *u, pa_sink_input *sinp)
             csinp = pa_idxset_get_by_index(core->sink_inputs,
                                            data.mux->defstream_index);
             s = csinp ? csinp->sink : NULL;
+
+            if ((sinp->flags & PA_SINK_INPUT_START_RAMP_MUTED)) {
+                pa_log_debug("ramp '%s' to 100%", media);
+                pa_fader_ramp_volume(u, sinp, PA_VOLUME_NORM);
+            }
         }
     }
 
index 7963ce3..c37e278 100644 (file)
@@ -113,8 +113,18 @@ void pa_fader_apply_volume_limits(struct userdata *u, uint32_t stamp)
 
                 pa_log_debug("     stream %u (class %u)", sinp->index, class);
 
-                if (!class)
-                    pa_log_debug("        skipping");
+                if (!class) {
+                    if (!(sinp->flags & PA_SINK_INPUT_START_RAMP_MUTED))
+                        pa_log_debug("        skipping");
+                    else {
+                        sinp->flags &= ~PA_SINK_INPUT_START_RAMP_MUTED;
+                        time = transit->fade_in;
+                        
+                        pa_log_debug("        attenuation 0 dB "
+                                     "transition time %u ms", time);
+                        set_stream_volume_limit(u, sinp, PA_VOLUME_NORM, time);
+                    }
+                }
                 else {
                     dB = mir_volume_apply_limits(u, node, class, stamp);
                     newvol = pa_sw_volume_from_dB(dB);
@@ -148,6 +158,76 @@ void pa_fader_apply_volume_limits(struct userdata *u, uint32_t stamp)
     } /* PA_IDXSET_FOREACH sink */
 }
 
+void pa_fader_ramp_volume(struct userdata *u,
+                          pa_sink_input *sinp,
+                          pa_volume_t newvol)
+{
+    transition_time *transit;
+    pa_bool_t        rampit;
+    pa_volume_t      oldvol;
+    pa_cvolume_ramp_int  *ramp;
+    uint32_t         time;
+    pa_cvolume_ramp  rampvol;
+
+    pa_assert(u);
+    pa_assert(u->fader);
+    pa_assert(sinp);
+
+    transit = &u->fader->transit;
+    rampit  = transit->fade_in > 0 &&  transit->fade_out > 0;
+    ramp    = &sinp->ramp;
+    oldvol  = ramp->ramps[0].target;
+
+    if (rampit && oldvol != newvol) {
+        time = (oldvol > newvol) ? transit->fade_out : transit->fade_in;
+
+        pa_cvolume_ramp_set(&rampvol,
+                            sinp->volume.channels,
+                            PA_VOLUME_RAMP_TYPE_LINEAR,
+                            time, newvol);
+
+        pa_sink_input_set_volume_ramp(sinp, &rampvol, TRUE, FALSE);
+    }
+}
+
+
+void pa_fader_set_volume(struct userdata *u,
+                          pa_sink_input *sinp,
+                          pa_volume_t newvol)
+{
+    pa_volume_t oldvol;
+    pa_cvolume_ramp_int *ramp;
+    pa_cvolume_ramp  rampvol;
+
+    pa_assert(u);
+    pa_assert(sinp);
+
+    ramp   = &sinp->ramp;
+    oldvol = ramp->ramps[0].target;
+
+    if (oldvol != newvol) {
+        pa_cvolume_ramp_set(&rampvol,
+                            sinp->volume.channels,
+                            PA_VOLUME_RAMP_TYPE_LINEAR,
+                            0, newvol);
+
+        pa_sink_input_set_volume_ramp(sinp, &rampvol, TRUE, FALSE);
+    }
+}
+
+pa_volume_t pa_fader_get_volume(struct userdata *u, pa_sink_input *sinp)
+{
+    pa_cvolume_ramp_int *ramp;
+    pa_volume_t vol;
+
+    pa_assert(u);
+    pa_assert(sinp);
+
+    ramp = &sinp->ramp;
+    vol  = ramp->ramps[0].target;
+
+    return vol;
+}
 
 static void set_stream_volume_limit(struct userdata *u,
                                     pa_sink_input   *sinp,
index 378c6b7..66fe48e 100644 (file)
@@ -31,6 +31,9 @@ void pa_fader_done(struct userdata *);
 
 void pa_fader_apply_volume_limits(struct userdata *, uint32_t);
 
+void pa_fader_ramp_volume(struct userdata *, pa_sink_input *, pa_volume_t);
+void pa_fader_set_volume(struct userdata *, pa_sink_input *, pa_volume_t);
+pa_volume_t pa_fader_get_volume(struct userdata *, pa_sink_input *);
 
 #endif  /* foomirfaderfoo */
 
index 4990079..baac0fe 100644 (file)
 #include "stream-state.h"
 #include "node.h"
 #include "loopback.h"
+#include "fader.h"
 
 static const char *scache_driver = "play-memblockq.c";
 static pa_sink_input_flags_t flag_mask = PA_SINK_INPUT_NO_CREATE_ON_SUSPEND |
                                          PA_SINK_INPUT_KILL_ON_SUSPEND;
 
 
-static void sink_input_block(pa_sink_input *, pa_bool_t);
+static void sink_input_block(struct userdata *, pa_sink_input *, pa_bool_t);
 
 pa_bool_t pa_stream_state_start_corked(struct userdata *u,
                                        pa_sink_input_new_data *data,
@@ -118,12 +119,12 @@ void pa_stream_state_change(struct userdata *u, mir_node *node, int req)
                 
             case PA_STREAM_BLOCK:
                 pa_log_debug("blocking '%s'", node->amname);
-                sink_input_block(sinp, TRUE);
+                sink_input_block(u, sinp, TRUE);
                 break;
                 
             case PA_STREAM_RUN:
                 pa_log_debug("unblock '%s'", node->amname);
-                sink_input_block(sinp, FALSE);
+                sink_input_block(u, sinp, FALSE);
                 break;
                 
             default:
@@ -140,12 +141,15 @@ void pa_stream_state_change(struct userdata *u, mir_node *node, int req)
 }
 
 
-static void sink_input_block(pa_sink_input *sinp, pa_bool_t block)
+static void sink_input_block(struct userdata *u,
+                             pa_sink_input *sinp,
+                             pa_bool_t block)
 {
     const char *event;
     pa_proplist *pl;
     bool block_by_mute;
     bool muted, corked;
+    pa_volume_t oldvol;
 
     pa_assert(sinp);
 
@@ -168,8 +172,18 @@ static void sink_input_block(pa_sink_input *sinp, pa_bool_t block)
                  block_by_mute ? "muting":"corking");
 
     if (block_by_mute) {
-        if ((muted && !block) || (!muted && block))
+        if ((muted && !block) || (!muted && block)) {
+            if (!block) {
+                oldvol = pa_fader_get_volume(u, sinp);
+
+                pa_log_debug("fading in to %u", oldvol);
+
+                pa_fader_set_volume(u, sinp, 0);
+                pa_fader_ramp_volume(u, sinp, oldvol);
+            }
+
             pa_sink_input_set_mute(sinp, block, FALSE);
+        }
     }
     else {
         if ((corked && !block) || (!corked &&  block)) {