equalizer: Use floating point arithmetic internally for the int16 mode
authorGhislain 'Aus' Lacroix <aus@songbirdnest.com>
Thu, 28 May 2009 10:39:46 +0000 (12:39 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 28 May 2009 10:39:46 +0000 (12:39 +0200)
By using int32 arithmetic we will introduce distortions as the
IIR filter is very sensitive to rounding errors. Fixes bug #580214.

gst/equalizer/gstiirequalizer.c

index 4d21a87424a4ee2194fdedaacd92e1a2cf138502..060441a3e527a8e4ac7617102c197f75a771513b 100644 (file)
@@ -392,9 +392,9 @@ setup_filter (GstIirEqualizer * equ, GstIirEqualizerBand * band)
 
     gain = arg_to_scale (band->gain);
 
-    if (band->freq / GST_AUDIO_FILTER (equ)->format.rate > 0.5)
+    if (band->freq / GST_AUDIO_FILTER (equ)->format.rate >= 0.5)
       omega = M_PI;
-    else if (band->freq < 0.0)
+    else if (band->freq <= 0.0)
       omega = 0.0;
     else
       omega = 2.0 * M_PI * (band->freq / GST_AUDIO_FILTER (equ)->format.rate);
@@ -557,9 +557,9 @@ one_step_ ## TYPE (GstIirEqualizerBand *filter,                         \
     SecondOrderHistory ## TYPE *history, BIG_TYPE input)                \
 {                                                                       \
   /* calculate output */                                                \
-  BIG_TYPE output = floor (filter->a0 * input +                         \
+  BIG_TYPE output = filter->a0 * input +                                \
       filter->a1 * history->x1 + filter->a2 * history->x2 +             \
-      filter->b1 * history->y1 + filter->b2 * history->y2 + 0.5);       \
+      filter->b1 * history->y1 + filter->b2 * history->y2;              \
   /* update history */                                                  \
   history->y2 = history->y1;                                            \
   history->y1 = output;                                                 \
@@ -591,7 +591,7 @@ guint size, guint channels)                                             \
         history++;                                                      \
       }                                                                 \
       cur = CLAMP (cur, MIN_VAL, MAX_VAL);                              \
-      *((TYPE *) data) = (TYPE) cur;                                    \
+      *((TYPE *) data) = (TYPE) floor (cur);                            \
       data += sizeof (TYPE);                                            \
     }                                                                   \
   }                                                                     \
@@ -647,7 +647,7 @@ guint size, guint channels)                                             \
   }                                                                     \
 }
 
-CREATE_OPTIMIZED_FUNCTIONS_INT (gint16, gint32, -32768, 32767);
+CREATE_OPTIMIZED_FUNCTIONS_INT (gint16, gfloat, -32768.0, 32767.0);
 CREATE_OPTIMIZED_FUNCTIONS (gfloat);
 CREATE_OPTIMIZED_FUNCTIONS (gdouble);