[banshee] libbanshee: Insert `volume` element into the pipeline (bgo#6000072)



commit c6b2f2c14406e378f42c47ce4294b228021d2ad2
Author: Alexander Kojevnikov <alexander kojevnikov com>
Date:   Wed Sep 15 12:32:41 2010 +1000

    libbanshee: Insert `volume` element into the pipeline (bgo#6000072)
    
    Changing the volume on the entire pipeline results in a noticeable
    latency on certain audio sinks. This commit adds a dedicated volume
    element, changing the volume on it drastically reduces the latency.
    
    Original patch by Christian Taedcke, adapted by Christopher Halse Rogers
    and myself.

 libbanshee/banshee-player-pipeline.c   |   18 ++++++++------
 libbanshee/banshee-player-private.h    |    1 +
 libbanshee/banshee-player-replaygain.c |    6 +---
 libbanshee/banshee-player.c            |   39 +++++++++++--------------------
 4 files changed, 27 insertions(+), 37 deletions(-)
---
diff --git a/libbanshee/banshee-player-pipeline.c b/libbanshee/banshee-player-pipeline.c
index 773f568..ce16a48 100644
--- a/libbanshee/banshee-player-pipeline.c
+++ b/libbanshee/banshee-player-pipeline.c
@@ -358,7 +358,11 @@ _bp_pipeline_construct (BansheePlayer *player)
     // Our audio sink is a tee, so plugins can attach their own pipelines
     player->audiotee = gst_element_factory_make ("tee", "audiotee");
     g_return_val_if_fail (player->audiotee != NULL, FALSE);
-    
+
+    // Create a volume control with low latency
+    player->volume = gst_element_factory_make ("volume", NULL);
+    g_return_val_if_fail (player->volume != NULL, FALSE);
+
     audiosinkqueue = gst_element_factory_make ("queue", "audiosinkqueue");
     g_return_val_if_fail (audiosinkqueue != NULL, FALSE);
 
@@ -371,7 +375,7 @@ _bp_pipeline_construct (BansheePlayer *player)
     }
     
     // Add elements to custom audio sink
-    gst_bin_add_many (GST_BIN (player->audiobin), player->audiotee, audiosinkqueue, audiosink, NULL);
+    gst_bin_add_many (GST_BIN (player->audiobin), player->audiotee, player->volume, audiosinkqueue, audiosink, NULL);
     
     if (player->equalizer != NULL) {
         gst_bin_add_many (GST_BIN (player->audiobin), eq_audioconvert, eq_audioconvert2, player->equalizer, player->preamp, NULL);
@@ -386,15 +390,13 @@ _bp_pipeline_construct (BansheePlayer *player)
     if (player->equalizer != NULL) {
         // link in equalizer, preamp and audioconvert.
         gst_element_link_many (audiosinkqueue, eq_audioconvert, player->preamp, 
-            player->equalizer, eq_audioconvert2, audiosink, NULL);
-        player->before_rgvolume = eq_audioconvert;
-        player->after_rgvolume = player->preamp;
+            player->equalizer, eq_audioconvert2, player->volume, audiosink, NULL);
     } else {
         // link the queue with the real audio sink
-        gst_element_link (audiosinkqueue, audiosink);
-        player->before_rgvolume = audiosinkqueue;
-        player->after_rgvolume = audiosink;
+        gst_element_link_many (audiosinkqueue, player->volume, audiosink, NULL);
     }
+    player->before_rgvolume = player->volume;
+    player->after_rgvolume = audiosink;
     player->rgvolume_in_pipeline = FALSE;
     _bp_replaygain_pipeline_rebuild (player);
 
diff --git a/libbanshee/banshee-player-private.h b/libbanshee/banshee-player-private.h
index 5286daf..f3e28a7 100644
--- a/libbanshee/banshee-player-private.h
+++ b/libbanshee/banshee-player-private.h
@@ -141,6 +141,7 @@ struct BansheePlayer {
     gboolean   rgvolume_in_pipeline;
 
     gint equalizer_status;
+    gdouble current_volume;
     
     // Pipeline/Playback State
     GMutex *video_mutex;
diff --git a/libbanshee/banshee-player-replaygain.c b/libbanshee/banshee-player-replaygain.c
index 43caa6b..a479d4a 100644
--- a/libbanshee/banshee-player-replaygain.c
+++ b/libbanshee/banshee-player-replaygain.c
@@ -169,14 +169,12 @@ void _bp_rgvolume_print_volume(BansheePlayer *player)
     g_return_if_fail (IS_BANSHEE_PLAYER (player));
     if (player->replaygain_enabled && (player->rgvolume != NULL)) {
         gdouble scale;
-        gdouble volume;
 
         g_object_get (G_OBJECT (player->rgvolume), "result-gain", &scale, NULL);
-        g_object_get (G_OBJECT (player->playbin), "volume", &volume, NULL);
 
         bp_debug4 ("scaled volume: %.2f (ReplayGain) * %.2f (User) = %.2f",
-                  bp_replaygain_db_to_linear (scale), volume,
-                  bp_replaygain_db_to_linear (scale) * volume);
+                  bp_replaygain_db_to_linear (scale), player->current_volume,
+                  bp_replaygain_db_to_linear (scale) * player->current_volume);
     }
 }
 
diff --git a/libbanshee/banshee-player.c b/libbanshee/banshee-player.c
index 0c1c1ac..ef15efd 100644
--- a/libbanshee/banshee-player.c
+++ b/libbanshee/banshee-player.c
@@ -275,39 +275,28 @@ bp_audiosink_has_volume (BansheePlayer *player)
 P_INVOKE void
 bp_set_volume (BansheePlayer *player, gdouble volume)
 {
+    GParamSpec *volume_spec;
+    GValue value = { 0, };
+
     g_return_if_fail (IS_BANSHEE_PLAYER (player));
-    g_return_if_fail (GST_IS_ELEMENT (player->playbin));
-
-    if (bp_supports_stream_volume (player)) {
-        #if BANSHEE_CHECK_GST_VERSION(0,10,25)
-        gst_stream_volume_set_volume (GST_STREAM_VOLUME (player->playbin),
-            GST_STREAM_VOLUME_FORMAT_CUBIC, volume);
-        #endif
-    } else {
-        g_object_set (player->playbin, "volume", CLAMP (volume, 0.0, 1.0), NULL);
-    }
+    g_return_if_fail (GST_IS_ELEMENT(player->volume));
+
+    player->current_volume = CLAMP (volume, 0.0, 1.0);
+    volume_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (player->volume), "volume");
+    g_value_init (&value, G_TYPE_DOUBLE);
+    g_value_set_double (&value, player->current_volume);
+    g_param_value_validate (volume_spec, &value);
 
-    _bp_rgvolume_print_volume (player);
+    g_object_set_property (G_OBJECT (player->volume), "volume", &value);
+    g_value_unset (&value);
+    _bp_rgvolume_print_volume(player);
 }
 
 P_INVOKE gdouble
 bp_get_volume (BansheePlayer *player)
 {
-    gdouble volume;
-
     g_return_val_if_fail (IS_BANSHEE_PLAYER (player), 0.0);
-    g_return_val_if_fail (GST_IS_ELEMENT (player->playbin), 0.0);
-
-    if (bp_supports_stream_volume (player)) {
-        #if BANSHEE_CHECK_GST_VERSION(0,10,25)
-        volume = gst_stream_volume_get_volume (GST_STREAM_VOLUME (player->playbin),
-            GST_STREAM_VOLUME_FORMAT_CUBIC);
-        #endif
-    } else {
-        g_object_get (player->playbin, "volume", &volume, NULL);
-    }
-
-    return volume;
+    return player->current_volume;
 }
 
 P_INVOKE void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]