spectrum: factor out the code that accumulated samples into the ring-buffer

Use a separate function to read a sample frame into a ringbuffer slot. In the
future we can use format-specific function pointer to avoid the reoccuring
format checks.
This commit is contained in:
Stefan Kost 2011-03-09 12:41:15 +02:00
parent 5b9028c52c
commit 65f4c4b3e6

View file

@ -518,6 +518,55 @@ gst_spectrum_message_new (GstSpectrum * spectrum, GstClockTime timestamp,
return gst_message_new_element (GST_OBJECT (spectrum), s);
}
/* FIXME: have dedicated read function pointers for each format */
static gfloat
gst_spectrum_input_data_mixed (const guint8 * data, gfloat is_float,
guint width, guint channels, gfloat max_value)
{
guint i;
gfloat v = 0.0;
if (is_float) {
if (width == 4) {
gfloat *in = (gfloat *) data;
for (i = 0; i < channels; i++)
v += in[i];
} else if (width == 8) {
gdouble *in = (gdouble *) data;
for (i = 0; i < channels; i++)
v += in[i];
} else {
g_assert_not_reached ();
}
} else {
if (width == 4) {
gint32 *in = (gint32 *) data;
/* max_value will be 0 when depth is 1,
* interpret -1 and 0 as -1 and +1 if that's the case. */
for (i = 0; i < channels; i++)
v += max_value ? in[i] / max_value : in[i] * 2 + 1;
} else if (width == 3) {
for (i = 0; i < channels; i++) {
#if G_BYTE_ORDER == G_BIG_ENDIAN
gint32 value = GST_READ_UINT24_BE (data);
#else
gint32 value = GST_READ_UINT24_LE (data);
#endif
if (value & 0x00800000)
value |= 0xff000000;
v += max_value ? value / max_value : value * 2 + 1;
}
} else if (width == 2) {
gint16 *in = (gint16 *) data;
for (i = 0; i < channels; i++)
v += max_value ? in[i] / max_value : in[i] * 2 + 1;
} else {
g_assert_not_reached ();
}
}
return v / channels;
}
static void
gst_spectrum_run_fft (GstSpectrum * spectrum, GstSpectrumChannel * cd,
guint input_pos)
@ -595,7 +644,6 @@ static GstFlowReturn
gst_spectrum_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
{
GstSpectrum *spectrum = GST_SPECTRUM (trans);
guint i;
GstRingBufferSpec *format = &GST_AUDIO_FILTER (spectrum)->format;
guint rate = format->rate;
guint channels = format->channels;
@ -646,50 +694,9 @@ gst_spectrum_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
input = cd->input;
while (size >= width * channels) {
/* Move the current frame into our ringbuffer and
* take the average of all channels
*/
input[input_pos] = 0.0;
if (is_float) {
if (width == 4) {
gfloat *in = (gfloat *) data;
for (i = 0; i < channels; i++)
input[input_pos] += in[i];
} else if (width == 8) {
gdouble *in = (gdouble *) data;
for (i = 0; i < channels; i++)
input[input_pos] += in[i];
} else {
g_assert_not_reached ();
}
} else {
if (width == 4) {
gint32 *in = (gint32 *) data;
for (i = 0; i < channels; i++)
/* max_value will be 0 when depth is 1, interpret -1 and 0
* as -1 and +1 if that's the case.
*/
input[input_pos] += max_value ? in[i] / max_value : in[i] * 2 + 1;
} else if (width == 3) {
for (i = 0; i < channels; i++) {
#if G_BYTE_ORDER == G_BIG_ENDIAN
gint32 value = GST_READ_UINT24_BE (data);
#else
gint32 value = GST_READ_UINT24_LE (data);
#endif
if (value & 0x00800000)
value |= 0xff000000;
input[input_pos] += max_value ? value / max_value : value * 2 + 1;
}
} else if (width == 2) {
gint16 *in = (gint16 *) data;
for (i = 0; i < channels; i++)
input[input_pos] += max_value ? in[i] / max_value : in[i] * 2 + 1;
} else {
g_assert_not_reached ();
}
}
input[input_pos] /= channels;
/* Move the mixdown of current frame into our ringbuffer */
input[input_pos] = gst_spectrum_input_data_mixed (data, is_float, width,
channels, max_value);
data += width * channels;
size -= width * channels;