banshee r4021 - in trunk/banshee: . libbanshee src/Backends/Banshee.GStreamer/Banshee.GStreamer



Author: sdroege
Date: Thu May 29 06:38:41 2008
New Revision: 4021
URL: http://svn.gnome.org/viewvc/banshee?rev=4021&view=rev

Log:
* libbanshee/banshee-player-equalizer.c: (bp_equalizer_set_gain),
(bp_equalizer_get_bandrange), (bp_equalizer_get_nbands),
(bp_equalizer_get_frequencies):
* src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs:
Get the number of frequency bands from the element and always take
the complete gain range. Guard against some possible crashes and
don't return an array that is allocated on the stack to the caller
who provided us with a correctly allocated array already.
* libbanshee/banshee-player-pipeline.c: (_bp_pipeline_construct):
Some cleanup and only use the capsfilter hack with equalizer versions
that had the clipping bug on integer samples.


Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/libbanshee/banshee-player-equalizer.c
   trunk/banshee/libbanshee/banshee-player-pipeline.c
   trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs

Modified: trunk/banshee/libbanshee/banshee-player-equalizer.c
==============================================================================
--- trunk/banshee/libbanshee/banshee-player-equalizer.c	(original)
+++ trunk/banshee/libbanshee/banshee-player-equalizer.c	Thu May 29 06:38:41 2008
@@ -55,7 +55,11 @@
     g_return_if_fail (IS_BANSHEE_PLAYER (player));
     
     if (player->equalizer != NULL) {
-        GstObject *band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (player->equalizer), bandnum);
+        GstObject *band;
+
+        g_return_if_fail (bandnum < gst_child_proxy_get_children_count (GST_CHILD_PROXY (player->equalizer)));
+
+        band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (player->equalizer), bandnum);
         g_object_set (band, "gain", gain, NULL);
         g_object_unref (band);
     }
@@ -64,15 +68,8 @@
 P_INVOKE void
 bp_equalizer_get_bandrange (BansheePlayer *player, gint *min, gint *max)
 {    
-    // NOTE: This only refers to the newer version of the equalizer element.
-    //
-    // GStreamer's equalizer goes from -24 to +12, but -12 to +12 is much better:
-    //  - Equal levels on both sides, which means we get a nice linear y=x
-    //  - This also makes converting other eq presets easier.
-    //  - We get a nice roud 0 dB in the middle of the band range, instead of -6, which is stupid
-    //    since 0 dB gives us no gain, yet its not in the middle - less sense to the end user.
-    
-    GParamSpecDouble *pspec;
+    GParamSpec *pspec;
+    GParamSpecDouble *dpspec;
     
     g_return_if_fail (IS_BANSHEE_PLAYER (player));
     
@@ -81,43 +78,53 @@
     }
     
     // Fetch gain range of first band (since it should be the same for the rest)
-    pspec = (GParamSpecDouble*)g_object_class_find_property (G_OBJECT_GET_CLASS (player->equalizer), "band0");
-    if (pspec != NULL) {
-        // Assume old equalizer.
-        *min = pspec->minimum;
-        *max = pspec->maximum;
+    pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (player->equalizer), "band0::gain");
+    if (pspec == NULL)
+        pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (player->equalizer), "band0");
+
+    if (pspec != NULL && G_IS_PARAM_SPEC_DOUBLE (pspec)) {
+        dpspec = (GParamSpecDouble *) pspec;
+        *min = dpspec->minimum;
+        *max = dpspec->maximum;
         return;
-    } 
-    
-    pspec = (GParamSpecDouble*)g_object_class_find_property (G_OBJECT_GET_CLASS (player->equalizer), "band0::gain");
-    if (pspec != NULL && pspec->maximum == 12) {
-        // New equalizer - return even scale.
-        *min = -12;
-        *max = 12;
-    } else if (pspec != NULL) {
-        // Return just the ranges the equalizer supports
-        *min = pspec->minimum;
-        *max = pspec->maximum;
     } else {
        g_warning ("Could not find valid gain range for equalizer element");
     }
 }
 
+P_INVOKE guint
+bp_equalizer_get_nbands (BansheePlayer *player)
+{
+    guint count;
+    
+    g_return_val_if_fail (IS_BANSHEE_PLAYER (player), 0);
+
+    if (player->equalizer == NULL) {
+        return 0;
+    }
+
+    count = gst_child_proxy_get_children_count (GST_CHILD_PROXY (player->equalizer));
+    return count;
+}
+
 P_INVOKE void
 bp_equalizer_get_frequencies (BansheePlayer *player, gdouble **freq)
 {
-    gint i;
-    gdouble bandfreq[10];
+    gint i, count;
     
     g_return_if_fail (IS_BANSHEE_PLAYER (player));
+
+    if (player->equalizer == NULL) {
+        return;
+    }
+
+    count = gst_child_proxy_get_children_count (GST_CHILD_PROXY (player->equalizer));
     
-    for (i = 0; i < 10; i++) {
+    for (i = 0; i < count; i++) {
         GstObject *band;
         
         band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (player->equalizer), i);
-        g_object_get (G_OBJECT (band), "freq", &bandfreq[i], NULL);
+        g_object_get (G_OBJECT (band), "freq", &(*freq)[i], NULL);
         g_object_unref (band);
     }
-    
-    *freq = bandfreq;
 }

Modified: trunk/banshee/libbanshee/banshee-player-pipeline.c
==============================================================================
--- trunk/banshee/libbanshee/banshee-player-pipeline.c	(original)
+++ trunk/banshee/libbanshee/banshee-player-pipeline.c	Thu May 29 06:38:41 2008
@@ -175,8 +175,8 @@
     GstElement *audiosink;
     GstElement *audiosinkqueue;
     GstElement *audioconvert, *audioconvert2;
-    GstElement *capsfilter;
-    GstCaps *caps;
+    GstElement *capsfilter = NULL;
+    gboolean buggy_eq = FALSE;
     
     g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE);
     
@@ -212,23 +212,37 @@
     
     audiosinkqueue = gst_element_factory_make ("queue", "audiosinkqueue");
     g_return_val_if_fail (audiosinkqueue != NULL, FALSE);
-    
-    capsfilter = gst_element_factory_make("capsfilter", "capsfilter");
-    caps = gst_caps_new_simple ("audio/x-raw-float", NULL);
-    g_object_set (capsfilter, "caps", caps, NULL);
-    gst_caps_unref (caps);
 
     audioconvert = gst_element_factory_make("audioconvert", "audioconvert");
     audioconvert2 = gst_element_factory_make("audioconvert", "audioconvert2");
     player->equalizer = gst_element_factory_make("equalizer-10bands", "equalizer-10bands");
     player->preamp = gst_element_factory_make("volume", "preamp");
-    
+
+    /* Workaround for equalizer bug that caused clipping when processing integer samples */
+    if (player->equalizer != NULL) {
+        GstElementFactory *efactory = gst_element_get_factory (player->equalizer);
+
+        buggy_eq = !gst_plugin_feature_check_version (GST_PLUGIN_FEATURE (efactory), 0, 10, 9);
+
+        if (buggy_eq) {
+            GstCaps *caps;
+
+            capsfilter = gst_element_factory_make("capsfilter", "capsfilter");
+            caps = gst_caps_new_simple ("audio/x-raw-float", NULL);
+            g_object_set (capsfilter, "caps", caps, NULL);
+            gst_caps_unref (caps);
+      }
+    }
+
     // Add elements to custom audio sink
     gst_bin_add (GST_BIN (player->audiobin), player->audiotee);
     if (player->equalizer != NULL) {
         gst_bin_add (GST_BIN (player->audiobin), audioconvert);
         gst_bin_add (GST_BIN (player->audiobin), audioconvert2);
-        gst_bin_add (GST_BIN (player->audiobin), capsfilter);
+
+        if (buggy_eq)
+            gst_bin_add (GST_BIN (player->audiobin), capsfilter);
+
         gst_bin_add (GST_BIN (player->audiobin), player->equalizer);
         gst_bin_add (GST_BIN (player->audiobin), player->preamp);
     } else {
@@ -236,7 +250,6 @@
         player->preamp = NULL;
         g_object_unref(audioconvert);
         g_object_unref(audioconvert2);
-        g_object_unref(capsfilter);
     }
     gst_bin_add (GST_BIN (player->audiobin), audiosinkqueue);
     gst_bin_add (GST_BIN (player->audiobin), audiosink);
@@ -253,7 +266,10 @@
     // Link the queue and the actual audio sink
     if (player->equalizer != NULL) {
         // link in equalizer, preamp and audioconvert.
-        gst_element_link_many (audiosinkqueue, audioconvert, capsfilter, player->preamp, player->equalizer, audioconvert2, audiosink, NULL);
+        if (buggy_eq)
+            gst_element_link_many (audiosinkqueue, audioconvert, player->preamp, player->equalizer, audioconvert2, audiosink, NULL);
+        else
+            gst_element_link_many (audiosinkqueue, audioconvert, capsfilter, player->preamp, player->equalizer, audioconvert2, audiosink, NULL);
     } else {
         // link the queue with the real audio sink
         gst_element_link (audiosinkqueue, audiosink);

Modified: trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
==============================================================================
--- trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs	(original)
+++ trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs	Thu May 29 06:38:41 2008
@@ -396,11 +396,13 @@
         
         public uint [] EqualizerFrequencies {
             get {
-                double [] freq = new double[10];
+	        uint count = bp_equalizer_get_nbands (handle);
+                double [] freq = new double[count];
+
                 bp_equalizer_get_frequencies (handle, out freq);
                 
-                uint [] ret = new uint[freq.Length];
-                for (int i = 0; i < freq.Length; i++) {
+                uint [] ret = new uint[count];
+                for (int i = 0; i < count; i++) {
                     ret[i] = (uint)freq[i];
                 }
                 
@@ -513,6 +515,9 @@
         [DllImport ("libbanshee")]
         private static extern void bp_equalizer_get_bandrange (HandleRef player, out int min, out int max);
         
+	[DllImport ("libbanshee")]
+        private static extern uint bp_equalizer_get_nbands (HandleRef player);
+        
         [DllImport ("libbanshee")]
         private static extern void bp_equalizer_get_frequencies (HandleRef player,
             [MarshalAs (UnmanagedType.LPArray)] out double [] freq);



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