mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
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:
parent
5b9028c52c
commit
65f4c4b3e6
1 changed files with 52 additions and 45 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue