summaryrefslogtreecommitdiffstats
path: root/gst/equalizer
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2008-05-31 08:37:00 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2008-05-31 08:37:00 +0000
commitf6ef43bbd7eea5d8f42a56211eadfd215cb0780e (patch)
tree28f3e2fc6edbed3d39f6eda3d66c4e233e297885 /gst/equalizer
parentc17d49ee20e40211c35ec86d50d4669ed68d0f38 (diff)
gst/equalizer/gstiirequalizer.c: Don't clip float/double samples, correctly unset passthrough mode and use better rou...
Original commit message from CVS: * gst/equalizer/gstiirequalizer.c: (gst_iir_equalizer_transform_ip): Don't clip float/double samples, correctly unset passthrough mode and use better rounding for integer samples.
Diffstat (limited to 'gst/equalizer')
-rw-r--r--gst/equalizer/gstiirequalizer.c70
1 files changed, 60 insertions, 10 deletions
diff --git a/gst/equalizer/gstiirequalizer.c b/gst/equalizer/gstiirequalizer.c
index b0954549..30743d89 100644
--- a/gst/equalizer/gstiirequalizer.c
+++ b/gst/equalizer/gstiirequalizer.c
@@ -543,7 +543,7 @@ gst_iir_equalizer_compute_frequencies (GstIirEqualizer * equ, guint new_count)
/* start of code that is type specific */
-#define CREATE_OPTIMIZED_FUNCTIONS(TYPE,BIG_TYPE,MIN_VAL,MAX_VAL) \
+#define CREATE_OPTIMIZED_FUNCTIONS_INT(TYPE,BIG_TYPE,MIN_VAL,MAX_VAL) \
typedef struct { \
BIG_TYPE x1, x2; /* history of input values for a filter */ \
BIG_TYPE y1, y2; /* history of output values for a filter */ \
@@ -554,9 +554,9 @@ one_step_ ## TYPE (GstIirEqualizerBand *filter, \
SecondOrderHistory ## TYPE *history, BIG_TYPE input) \
{ \
/* calculate output */ \
- BIG_TYPE output = filter->a0 * input + filter->a1 * history->x1 + \
- filter->a2 * history->x2 + filter->b1 * history->y1 + \
- filter->b2 * history->y2; \
+ BIG_TYPE output = floor (filter->a0 * input + \
+ filter->a1 * history->x1 + filter->a2 * history->x2 + \
+ filter->b1 * history->y1 + filter->b2 * history->y2 + 0.5); \
/* update history */ \
history->y2 = history->y1; \
history->y1 = output; \
@@ -594,9 +594,59 @@ guint size, guint channels) \
} \
}
-CREATE_OPTIMIZED_FUNCTIONS (gint16, gint32, -32768, 32767);
-CREATE_OPTIMIZED_FUNCTIONS (gfloat, gfloat, -1.0, 1.0);
-CREATE_OPTIMIZED_FUNCTIONS (gdouble, gdouble, -1.0, 1.0);
+#define CREATE_OPTIMIZED_FUNCTIONS(TYPE) \
+typedef struct { \
+ TYPE x1, x2; /* history of input values for a filter */ \
+ TYPE y1, y2; /* history of output values for a filter */ \
+} SecondOrderHistory ## TYPE; \
+ \
+static inline TYPE \
+one_step_ ## TYPE (GstIirEqualizerBand *filter, \
+ SecondOrderHistory ## TYPE *history, TYPE input) \
+{ \
+ /* calculate output */ \
+ TYPE output = filter->a0 * input + filter->a1 * history->x1 + \
+ filter->a2 * history->x2 + filter->b1 * history->y1 + \
+ filter->b2 * history->y2; \
+ /* update history */ \
+ history->y2 = history->y1; \
+ history->y1 = output; \
+ history->x2 = history->x1; \
+ history->x1 = input; \
+ \
+ return output; \
+} \
+ \
+static const guint \
+history_size_ ## TYPE = sizeof (SecondOrderHistory ## TYPE); \
+ \
+static void \
+gst_iir_equ_process_ ## TYPE (GstIirEqualizer *equ, guint8 *data, \
+guint size, guint channels) \
+{ \
+ guint frames = size / channels / sizeof (TYPE); \
+ guint i, c, f; \
+ TYPE cur; \
+ \
+ for (i = 0; i < frames; i++) { \
+ for (c = 0; c < channels; c++) { \
+ SecondOrderHistory ## TYPE *history = equ->history; \
+ cur = *((TYPE *) data); \
+ for (f = 0; f < equ->freq_band_count; f++) { \
+ GstIirEqualizerBand *filter = equ->bands[f]; \
+ \
+ cur = one_step_ ## TYPE (filter, history, cur); \
+ history++; \
+ } \
+ *((TYPE *) data) = (TYPE) cur; \
+ data += sizeof (TYPE); \
+ } \
+ } \
+}
+
+CREATE_OPTIMIZED_FUNCTIONS_INT (gint16, gint32, -32768, 32767);
+CREATE_OPTIMIZED_FUNCTIONS (gfloat);
+CREATE_OPTIMIZED_FUNCTIONS (gdouble);
static GstFlowReturn
gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
@@ -607,9 +657,6 @@ gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
GstClockTime timestamp;
- if (gst_base_transform_is_passthrough (btrans))
- return GST_FLOW_OK;
-
if (G_UNLIKELY (filter->format.channels < 1 || equ->process == NULL))
return GST_FLOW_NOT_NEGOTIATED;
@@ -618,6 +665,9 @@ gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
set_passthrough (equ);
}
+ if (gst_base_transform_is_passthrough (btrans))
+ return GST_FLOW_OK;
+
timestamp = GST_BUFFER_TIMESTAMP (buf);
timestamp =
gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME, timestamp);