[banshee: 1/7] Handle volume changes from outside Banshee.



commit 2e33a4d5747ebc62c0f23012b074b6e5ac9188ee
Author: Christopher James Halse Rogers <chrishr src gnome org>
Date:   Sun Mar 14 14:00:52 2010 +1100

    Handle volume changes from outside Banshee.
    
    When using PulseAudio, users can modify the stream volume behind Banshee's back with
    the volume control applet.  Hook up playbin2's notify::volume signal to keep
    Banshee's volume widget and gconf setting in sync

 libbanshee/banshee-player-pipeline.c               |   15 +++++++++++++++
 libbanshee/banshee-player-private.h                |    2 ++
 libbanshee/banshee-player.c                        |   11 ++++++++++-
 .../Banshee.GStreamer/PlayerEngine.cs              |   13 +++++++++++++
 .../Banshee.Gui.Widgets/ConnectedVolumeButton.cs   |    3 ++-
 5 files changed, 42 insertions(+), 2 deletions(-)
---
diff --git a/libbanshee/banshee-player-pipeline.c b/libbanshee/banshee-player-pipeline.c
index 376300a..90b968d 100644
--- a/libbanshee/banshee-player-pipeline.c
+++ b/libbanshee/banshee-player-pipeline.c
@@ -234,6 +234,19 @@ static void bp_about_to_finish_callback (GstElement *playbin, BansheePlayer *pla
 }
 #endif //ENABLE_GAPLESS
 
+static void bp_volume_changed_callback (GstElement *playbin, GParamSpec *spec, BansheePlayer *player)
+{
+    g_return_if_fail (IS_BANSHEE_PLAYER (player));
+    g_return_if_fail (GST_IS_ELEMENT (playbin));
+
+    gdouble volume;
+    g_object_get (G_OBJECT (playbin), "volume", &volume, NULL);
+
+    if (player->volume_changed_cb != NULL) {
+        player->volume_changed_cb (player, volume);
+    }
+}
+
 // ---------------------------------------------------------------------------
 // Internal Functions
 // ---------------------------------------------------------------------------
@@ -262,6 +275,8 @@ _bp_pipeline_construct (BansheePlayer *player)
 
     g_return_val_if_fail (player->playbin != NULL, FALSE);
 
+    g_signal_connect (player->playbin, "notify::volume", G_CALLBACK (bp_volume_changed_callback), player);
+
     // Try to find an audio sink, prefer gconf, which typically is set to auto these days,
     // fall back on auto, which should work on windows, and as a last ditch, try alsa
     audiosink = gst_element_factory_make ("gconfaudiosink", "audiosink");
diff --git a/libbanshee/banshee-player-private.h b/libbanshee/banshee-player-private.h
index 1edd375..f3f01b7 100644
--- a/libbanshee/banshee-player-private.h
+++ b/libbanshee/banshee-player-private.h
@@ -79,6 +79,7 @@ typedef void (* BansheePlayerVisDataCallback)      (BansheePlayer *player, gint
 typedef void (* BansheePlayerNextTrackStartingCallback)     (BansheePlayer *player);
 typedef void (* BansheePlayerAboutToFinishCallback)         (BansheePlayer *player);
 typedef GstElement * (* BansheePlayerVideoPipelineSetupCallback) (BansheePlayer *player, GstBus *bus);
+typedef void (* BansheePlayerVolumeChangedCallback) (BansheePlayer *player, gdouble new_volume);
 
 typedef enum {
     BP_VIDEO_DISPLAY_CONTEXT_UNSUPPORTED = 0,
@@ -98,6 +99,7 @@ struct BansheePlayer {
     BansheePlayerNextTrackStartingCallback next_track_starting_cb;
     BansheePlayerAboutToFinishCallback about_to_finish_cb;
     BansheePlayerVideoPipelineSetupCallback video_pipeline_setup_cb;
+    BansheePlayerVolumeChangedCallback volume_changed_cb;
 
     // Pipeline Elements
     GstElement *playbin;
diff --git a/libbanshee/banshee-player.c b/libbanshee/banshee-player.c
index 2c0cfb0..cd74ed3 100644
--- a/libbanshee/banshee-player.c
+++ b/libbanshee/banshee-player.c
@@ -308,7 +308,16 @@ P_INVOKE gdouble
 bp_get_volume (BansheePlayer *player)
 {
     g_return_val_if_fail (IS_BANSHEE_PLAYER (player), 0.0);
-    return player->current_volume;
+    g_return_val_if_fail (GST_IS_ELEMENT (player->playbin), 0.0);
+    gdouble volume;
+    g_object_get (player->playbin, "volume", &volume, NULL);
+    return volume;
+}
+
+P_INVOKE void
+bp_set_volume_changed_callback (BansheePlayer *player, BansheePlayerVolumeChangedCallback cb)
+{
+    SET_CALLBACK (volume_changed_cb);
 }
 
 P_INVOKE gboolean
diff --git a/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs b/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
index 1a48c63..30e9ce7 100644
--- a/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
+++ b/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
@@ -61,6 +61,7 @@ namespace Banshee.GStreamer
     internal delegate void BansheePlayerNextTrackStartingCallback (IntPtr player);
     internal delegate void BansheePlayerAboutToFinishCallback (IntPtr player);
     internal delegate IntPtr VideoPipelineSetupHandler (IntPtr player, IntPtr bus);
+    internal delegate void BansheePlayerVolumeChangedCallback (IntPtr player, double newVolume);
 
     internal delegate void GstTaggerTagFoundCallback (IntPtr player, string tagName, ref GLib.Value value);
 
@@ -88,6 +89,7 @@ namespace Banshee.GStreamer
         private GstTaggerTagFoundCallback tag_found_callback;
         private BansheePlayerNextTrackStartingCallback next_track_starting_callback;
         private BansheePlayerAboutToFinishCallback about_to_finish_callback;
+        private BansheePlayerVolumeChangedCallback volume_changed_callback;
 
         private bool next_track_pending;
         private SafeUri pending_uri;
@@ -152,6 +154,7 @@ namespace Banshee.GStreamer
             tag_found_callback = new GstTaggerTagFoundCallback (OnTagFound);
             next_track_starting_callback = new BansheePlayerNextTrackStartingCallback (OnNextTrackStarting);
             about_to_finish_callback = new BansheePlayerAboutToFinishCallback (OnAboutToFinish);
+            volume_changed_callback = new BansheePlayerVolumeChangedCallback (OnVolumeChanged);
             bp_set_eos_callback (handle, eos_callback);
 #if !WIN32
             bp_set_iterate_callback (handle, iterate_callback);
@@ -162,6 +165,7 @@ namespace Banshee.GStreamer
             bp_set_tag_found_callback (handle, tag_found_callback);
             bp_set_next_track_starting_callback (handle, next_track_starting_callback);
             bp_set_video_pipeline_setup_callback (handle, video_pipeline_setup_callback);
+            bp_set_volume_changed_callback (handle, volume_changed_callback);
 
             next_track_set = new EventWaitHandle (false, EventResetMode.ManualReset);
         }
@@ -480,6 +484,11 @@ namespace Banshee.GStreamer
             }
         }
 
+        private void OnVolumeChanged (IntPtr player, double newVolume)
+        {
+            OnEventChanged (PlayerEvent.Volume);
+        }
+
         private static StreamTag ProcessNativeTagResult (string tagName, ref GLib.Value valueRaw)
         {
             if (tagName == String.Empty || tagName == null) {
@@ -815,6 +824,10 @@ namespace Banshee.GStreamer
         private static extern double bp_get_volume (HandleRef player);
 
         [DllImport ("libbanshee.dll")]
+        private static extern void bp_set_volume_changed_callback (HandleRef player,
+            BansheePlayerVolumeChangedCallback cb);
+
+        [DllImport ("libbanshee.dll")]
         private static extern bool bp_can_seek (HandleRef player);
 
         [DllImport ("libbanshee.dll")]
diff --git a/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedVolumeButton.cs b/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedVolumeButton.cs
index c34ddf4..e027928 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedVolumeButton.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedVolumeButton.cs
@@ -57,12 +57,13 @@ namespace Banshee.Gui.Widgets
 
         protected override void OnVolumeChanged ()
         {
+            PlayerEngineService.VolumeSchema.Set (Volume);
+
             if (emit_lock) {
                 return;
             }
 
             ServiceManager.PlayerEngine.Volume = (ushort)Volume;
-            PlayerEngineService.VolumeSchema.Set(Volume);
 
             base.OnVolumeChanged ();
         }



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