[Banshee-devel-list] GStreamer Equalization support



I found out that an equalizer element has been commited in
gst-plugins-bad [1], so I hacked on adding equalization support for
that. In theory it should be working fine, but unfrotunatly with my
glib here I get some weired !IS_GVALUE assertation failures. I have
attached the patch if someone wants to give it a try and see if it
works for them. There are still that need polishing in the Equalizer.*
namespace, also some settings storing for the equalizer (enabled, load
last active preset at startup). I hope I will have more time to hack
on :-). In order for the equalizer to be activated one has to open
View -> Equalizer. Check stdout/err for output.

Regards.

[1] cvs -d:pserver:anoncvs freedesktop org/cvs/gstreamer co gst-plugins-bad
   in gst/equalizer

--
Ivan N. Zlatev

Web: http://www.i-nZ.net
"It's all some kind of whacked out conspiracy."
Index: banshee/src/Core/Banshee/PlayerInterface.cs
===================================================================
--- banshee/src/Core/Banshee/PlayerInterface.cs	(revision 2236)
+++ banshee/src/Core/Banshee/PlayerInterface.cs	(working copy)
@@ -157,7 +157,11 @@
             Globals.ActionManager.SongActions.Sensitive = false;
             Globals.ActionManager.PlaylistActions.Sensitive = false;
             Globals.ActionManager["JumpToPlayingAction"].Visible = false;
-            
+
+            if (PlayerEngineCore.ActiveEngine is IEqualizer) {
+                Globals.ActionManager["ShowEqualizerAction"].Visible = true;
+            }
+
             foreach(Action action in Globals.ActionManager) {
                 string method_name = "On" + action.Name;
                 MethodInfo method = GetType().GetMethod(method_name,
Index: banshee/src/Core/Banshee.Base/Banshee.Equalizer.Gui/EqualizerWindow.cs
===================================================================
--- banshee/src/Core/Banshee.Base/Banshee.Equalizer.Gui/EqualizerWindow.cs	(revision 2236)
+++ banshee/src/Core/Banshee.Base/Banshee.Equalizer.Gui/EqualizerWindow.cs	(working copy)
@@ -50,6 +50,8 @@
             eq_view.BorderWidth = 10;
             eq_view.SetSizeRequest(-1, 110);
             eq_view.Bands = EqualizerManager.Instance.SupportedBands;
+            eq_view.AmplifierChanged += OnAmplifierChanged;
+            eq_view.EqualizerChanged += OnEqualizerChanged;
             eq_view.Show();
             
             eq_preset_combo = new EqualizerPresetComboBox();
@@ -87,5 +89,15 @@
                 eq_view.EqualizerSetting = eq_preset_combo.ActiveEqualizer;
             }
         }
+
+        private void OnEqualizerChanged(object o, EqualizerChangedEventArgs args)
+        {
+            eq_view.EqualizerSetting.SetBand (args.Frequency, args.Value);
+        }
+
+        private void OnAmplifierChanged(object o, AmplifierChangedEventArgs args)
+        {
+            eq_view.EqualizerSetting.Preamp = args.Value;
+        }
     }
-}
\ No newline at end of file
+}
Index: banshee/src/Core/Banshee.Base/Banshee.Equalizer/EqualizerSetting.cs
===================================================================
--- banshee/src/Core/Banshee.Base/Banshee.Equalizer/EqualizerSetting.cs	(revision 2236)
+++ banshee/src/Core/Banshee.Base/Banshee.Equalizer/EqualizerSetting.cs	(working copy)
@@ -30,6 +30,9 @@
 using System.Xml;
 using System.Collections.Generic;
 
+using Banshee.Base;
+using Banshee.MediaEngine;
+
 namespace Banshee.Equalizer
 {
     public class EqualizerSetting
@@ -55,14 +58,14 @@
                 bands[band] = value;
             } else {
                 bands.Add(band, value);
-            }
-            
+            } 
             OnChanged();
         }
         
         public void SetBand(uint band, int value)
         {
             AddBand(band, value);
+            ((IEqualizer) PlayerEngineCore.ActiveEngine).SetEqualizerGain (band, value);
         }
         
         public void RemoveBand(uint band)
@@ -130,7 +133,8 @@
         public int Preamp {
             get { return preamp; }
             set { 
-                preamp = value; 
+                preamp = value;
+                ((IEqualizer) PlayerEngineCore.ActiveEngine).AmplifierLevel = value; 
                 OnChanged();
             }
         }
Index: banshee/src/Engines/Banshee.MediaEngine.GStreamer/GstPlayerEngine.cs
===================================================================
--- banshee/src/Engines/Banshee.MediaEngine.GStreamer/GstPlayerEngine.cs	(revision 2236)
+++ banshee/src/Engines/Banshee.MediaEngine.GStreamer/GstPlayerEngine.cs	(working copy)
@@ -112,7 +112,7 @@
         NumErrors
     }
     
-    public class GstreamerPlayerEngine : PlayerEngine
+    public class GstreamerPlayerEngine : PlayerEngine, IEqualizer
     {
         private uint GST_CORE_ERROR = 0;
         private uint GST_LIBRARY_ERROR = 0;
@@ -308,6 +308,20 @@
             get { return (uint)gst_playback_get_duration(handle) / 1000; }
         }
         
+        public void SetEqualizerGain(uint frequency, int value)
+        {
+            gst_playback_set_equalizer_gain(handle, frequency, value);
+        }
+        
+        public uint [] EqualizerFrequencies {
+            get { return new uint[] { 20, 43, 93, 200, 430, 928, 2000, 4308, 9283, 20000 }; }
+        }
+        
+        public int AmplifierLevel {
+            get { return gst_playback_get_amplifier_gain (handle); }
+            set { gst_playback_set_amplifier_gain (handle, value); }
+        }
+
         public override string Id {
             get { return "gstreamer"; }
         }
@@ -388,5 +402,14 @@
         [DllImport("libbanshee")]
         private static extern void gst_playback_get_error_quarks(out uint core, out uint library, 
             out uint resource, out uint stream);
+
+        [DllImport("libbanshee")]
+        private static extern void gst_playback_set_equalizer_gain(HandleRef engine, uint freq, int gain);
+
+        [DllImport("libbanshee")]
+        private static extern void gst_playback_set_amplifier_gain(HandleRef engine, int gain);
+
+        [DllImport("libbanshee")]
+        private static extern int gst_playback_get_amplifier_gain(HandleRef engine);
     }
 }
Index: banshee/libbanshee/gst-playback-0.10.c
===================================================================
--- banshee/libbanshee/gst-playback-0.10.c	(revision 2236)
+++ banshee/libbanshee/gst-playback-0.10.c	(working copy)
@@ -53,6 +53,7 @@
 struct GstPlayback {
     GstElement *playbin;
     GstElement *audiotee;
+    GstElement *equalizer;
     GstElement *audiobin;
     
     guint iterate_timeout_id;
@@ -243,6 +244,7 @@
     GstElement *fakesink;
     GstElement *audiosink;
     GstElement *audiosinkqueue;
+    GstElementFactory *eqFactory;
     GstPad *teepad;
     
     g_return_val_if_fail(IS_GST_PLAYBACK(engine), FALSE);
@@ -264,12 +266,20 @@
     
     engine->audiotee = gst_element_factory_make("tee", "audiotee");
     g_return_val_if_fail(engine->audiotee != NULL, FALSE);
+
+    eqFactory = gst_element_factory_find("equalizer-10bands");
+    if(eqFactory != NULL) {
+        engine->equalizer = gst_element_factory_create (eqFactory, "equalizer-10bands");
+    }
     
     audiosinkqueue = gst_element_factory_make("queue", "audiosinkqueue");
     g_return_val_if_fail(audiosinkqueue != NULL, FALSE);
     
     // add elements to custom audio sink
     gst_bin_add(GST_BIN(engine->audiobin), engine->audiotee);
+    if(engine->equalizer != NULL) {
+        gst_bin_add(GST_BIN(engine->audiobin), engine->equalizer);
+    }
     gst_bin_add(GST_BIN(engine->audiobin), audiosinkqueue);
     gst_bin_add(GST_BIN(engine->audiobin), audiosink);
     
@@ -508,8 +518,8 @@
 {
     gdouble act_volume;
     g_return_if_fail(IS_GST_PLAYBACK(engine));
-	act_volume = CLAMP(volume, 0, 100) / 100.0;
-	g_object_set(G_OBJECT(engine->playbin), "volume", act_volume, NULL);
+    act_volume = CLAMP(volume, 0, 100) / 100.0;
+    g_object_set(G_OBJECT(engine->playbin), "volume", act_volume, NULL);
 }
 
 gint
@@ -609,3 +619,53 @@
     *resource = GST_RESOURCE_ERROR;
     *stream = GST_STREAM_ERROR;
 }
+
+// gst frequencies (Hz): 20, 43, 93, 200, 430, 928, 2000, 4308, 9283, 20000 
+// gst gain: -1.0 .. 1.0
+// banshee gain: -100 .. +100
+void
+gst_playback_set_equalizer_gain(GstPlayback *engine, guint freq, gint gain)
+{
+    static const guint supported_freqs[] = { 20, 43, 93, 200, 430, 928, 2000, 4308, 9283, 20000 };
+    guint band_number = 0;
+    gint i;
+    gchar prop_name[6]; // "bandX", X=0..9
+    gdouble gain_gst;
+    GValue gain_gst_boxed = { 0, };
+
+    if(engine->equalizer == NULL) {
+        return;
+    }
+    // normalize freq supplied by banshee against the available
+    for(i=0; i + 1 < G_N_ELEMENTS(supported_freqs); i++) {
+        if(freq == supported_freqs[i]) {
+            band_number = i;
+            break;
+        }
+        else if(freq > supported_freqs[i] && freq < supported_freqs[i+1]) {
+            band_number = (freq <= (supported_freqs[i] + supported_freqs[i+1]) / 2) ? i : i+1;
+            break;
+        }
+    }
+
+    g_snprintf(prop_name, G_N_ELEMENTS (prop_name), "band%d", band_number);
+    gain_gst = (double) gain;
+    gain_gst *= 0.001;
+
+    g_value_init (&gain_gst_boxed, G_TYPE_DOUBLE);
+    g_value_set_double (&gain_gst_boxed, gain_gst);
+    g_object_set(G_OBJECT (engine->equalizer), prop_name, &gain_gst_boxed, NULL);
+}
+
+// banshee gain: -100 .. +100
+void
+gst_playback_set_amplifier_gain(GstPlayback *engine, gint gain)
+{
+}
+
+// banshee gain: -100 .. +100
+gint
+gst_playback_get_amplifier_gain(GstPlayback *engine)
+{
+    return 0;
+}


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