mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 04:56:24 +00:00
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.
This commit is contained in:
parent
c17d49ee20
commit
f6ef43bbd7
2 changed files with 67 additions and 10 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2008-05-31 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2008-05-30 Sebastian Dröge <slomo@circular-chaos.org>
|
2008-05-30 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
* gst/equalizer/gstiirequalizer.c:
|
* 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 */
|
/* 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 { \
|
typedef struct { \
|
||||||
BIG_TYPE x1, x2; /* history of input values for a filter */ \
|
BIG_TYPE x1, x2; /* history of input values for a filter */ \
|
||||||
BIG_TYPE y1, y2; /* history of output 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) \
|
SecondOrderHistory ## TYPE *history, BIG_TYPE input) \
|
||||||
{ \
|
{ \
|
||||||
/* calculate output */ \
|
/* calculate output */ \
|
||||||
BIG_TYPE output = filter->a0 * input + filter->a1 * history->x1 + \
|
BIG_TYPE output = floor (filter->a0 * input + \
|
||||||
filter->a2 * history->x2 + filter->b1 * history->y1 + \
|
filter->a1 * history->x1 + filter->a2 * history->x2 + \
|
||||||
filter->b2 * history->y2; \
|
filter->b1 * history->y1 + filter->b2 * history->y2 + 0.5); \
|
||||||
/* update history */ \
|
/* update history */ \
|
||||||
history->y2 = history->y1; \
|
history->y2 = history->y1; \
|
||||||
history->y1 = output; \
|
history->y1 = output; \
|
||||||
|
@ -594,9 +594,59 @@ guint size, guint channels) \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_OPTIMIZED_FUNCTIONS (gint16, gint32, -32768, 32767);
|
#define CREATE_OPTIMIZED_FUNCTIONS(TYPE) \
|
||||||
CREATE_OPTIMIZED_FUNCTIONS (gfloat, gfloat, -1.0, 1.0);
|
typedef struct { \
|
||||||
CREATE_OPTIMIZED_FUNCTIONS (gdouble, gdouble, -1.0, 1.0);
|
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
|
static GstFlowReturn
|
||||||
gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
|
gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
|
||||||
|
@ -607,9 +657,6 @@ gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
|
||||||
|
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
|
|
||||||
if (gst_base_transform_is_passthrough (btrans))
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
|
|
||||||
if (G_UNLIKELY (filter->format.channels < 1 || equ->process == NULL))
|
if (G_UNLIKELY (filter->format.channels < 1 || equ->process == NULL))
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
|
||||||
|
@ -618,6 +665,9 @@ gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
|
||||||
set_passthrough (equ);
|
set_passthrough (equ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gst_base_transform_is_passthrough (btrans))
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (buf);
|
timestamp = GST_BUFFER_TIMESTAMP (buf);
|
||||||
timestamp =
|
timestamp =
|
||||||
gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME, timestamp);
|
gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME, timestamp);
|
||||||
|
|
Loading…
Reference in a new issue