summaryrefslogtreecommitdiffstats
path: root/gst/spectrum
diff options
context:
space:
mode:
authorStefan Kost <ensonic@users.sourceforge.net>2006-05-20 22:42:15 +0000
committerStefan Kost <ensonic@users.sourceforge.net>2006-05-20 22:42:15 +0000
commit83b3960a08bd99ccff51a8f3f65c4a0ac777713c (patch)
treef4f127deff40ff57df899317cde63f2b4924f4b3 /gst/spectrum
parent343fc544c5116cda1fce3ff253474377a1186474 (diff)
Initial port of the spectrum element
Original commit message from CVS: * configure.ac: * gst/spectrum/demo-osssrc.c: (spectrum_chain), (main): * gst/spectrum/fix_fft.c: (gst_spectrum_fix_dot): * gst/spectrum/gstspectrum.c: (gst_spectrum_get_type), (gst_spectrum_base_init), (gst_spectrum_class_init), (gst_spectrum_init), (gst_spectrum_dispose), (gst_spectrum_set_property), (gst_spectrum_chain): * gst/spectrum/gstspectrum.h: Initial port of the spectrum element
Diffstat (limited to 'gst/spectrum')
-rw-r--r--gst/spectrum/gstspectrum.c167
-rw-r--r--gst/spectrum/gstspectrum.h4
2 files changed, 105 insertions, 66 deletions
diff --git a/gst/spectrum/gstspectrum.c b/gst/spectrum/gstspectrum.c
index 4f01ceff..12762c58 100644
--- a/gst/spectrum/gstspectrum.c
+++ b/gst/spectrum/gstspectrum.c
@@ -1,5 +1,6 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * <2006> Stefan Kost <ensonic@users.sf.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,12 +25,33 @@
#include "gstspectrum.h"
+GST_DEBUG_CATEGORY_STATIC (gst_spectrum_debug);
+#define GST_CAT_DEFAULT gst_spectrum_debug
+
/* elementfactory information */
static const GstElementDetails gst_spectrum_details =
GST_ELEMENT_DETAILS ("Spectrum analyzer",
"Filter/Analyzer/Audio",
"Run an FFT on the audio signal, output spectrum data",
- "Erik Walthinsen <omega@cse.ogi.edu>");
+ "Erik Walthinsen <omega@cse.ogi.edu>,"
+ "Stefan Kost <ensonic@users.sf.net>");
+
+static GstStaticPadTemplate sink_template_factory =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("audio/x-raw-int, "
+ "rate = (int) [ 1, MAX ], "
+ "channels = (int) 1, "
+ "endianness = (int) BYTE_ORDER, "
+ "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true")
+ );
+
+static GstStaticPadTemplate src_template_factory =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS_ANY);
/* Spectrum signals and args */
enum
@@ -48,18 +70,17 @@ enum
static void gst_spectrum_base_init (gpointer g_class);
static void gst_spectrum_class_init (GstSpectrumClass * klass);
static void gst_spectrum_init (GstSpectrum * spectrum);
-
+static void gst_spectrum_dispose (GObject * object);
static void gst_spectrum_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
-static void gst_spectrum_chain (GstPad * pad, GstData * _data);
+static GstFlowReturn gst_spectrum_chain (GstPad * pad, GstBuffer * buffer);
#define fixed short
-int gst_spectrum_fix_fft (fixed fr[], fixed fi[], int m, int inverse);
-void gst_spectrum_fix_loud (fixed loud[], fixed fr[], fixed fi[], int n,
+extern int gst_spectrum_fix_fft (fixed fr[], fixed fi[], int m, int inverse);
+extern void gst_spectrum_fix_loud (fixed loud[], fixed fr[], fixed fi[], int n,
int scale_shift);
-void gst_spectrum_window (fixed fr[], int n);
-
+extern void gst_spectrum_window (fixed fr[], int n);
static GstElementClass *parent_class = NULL;
@@ -83,9 +104,10 @@ gst_spectrum_get_type (void)
(GInstanceInitFunc) gst_spectrum_init,
};
- spectrum_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstSpectrum", &spectrum_info,
- 0);
+ spectrum_type = g_type_register_static (GST_TYPE_ELEMENT, "GstSpectrum",
+ &spectrum_info, 0);
+ GST_DEBUG_CATEGORY_INIT (gst_spectrum_debug, "spectrum", 0,
+ "audio spectrum analyser element");
}
return spectrum_type;
}
@@ -95,113 +117,128 @@ gst_spectrum_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_template_factory));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_template_factory));
gst_element_class_set_details (element_class, &gst_spectrum_details);
}
+
static void
gst_spectrum_class_init (GstSpectrumClass * klass)
{
- GObjectClass *gobject_class;
-
- gobject_class = (GObjectClass *) klass;
+ GObjectClass *gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_peek_parent (klass);
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_WIDTH, g_param_spec_int ("width", "width", "width", G_MININT, G_MAXINT, 0, G_PARAM_WRITABLE)); /* CHECKME */
-
gobject_class->set_property = gst_spectrum_set_property;
+ gobject_class->dispose = gst_spectrum_dispose;
+
+ g_object_class_install_property (gobject_class, ARG_WIDTH,
+ g_param_spec_int ("width", "width", "width",
+ G_MININT, G_MAXINT, 0, G_PARAM_WRITABLE));
+
}
static void
gst_spectrum_init (GstSpectrum * spectrum)
{
- spectrum->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
+ spectrum->sinkpad =
+ gst_pad_new_from_static_template (&sink_template_factory, "sink");
gst_element_add_pad (GST_ELEMENT (spectrum), spectrum->sinkpad);
gst_pad_set_chain_function (spectrum->sinkpad, gst_spectrum_chain);
- spectrum->srcpad = gst_pad_new ("src", GST_PAD_SRC);
+
+ spectrum->srcpad =
+ gst_pad_new_from_static_template (&src_template_factory, "src");
gst_element_add_pad (GST_ELEMENT (spectrum), spectrum->srcpad);
spectrum->width = 75;
+ spectrum->base = 8;
+ spectrum->len = 1024;
+
+ spectrum->loud = g_malloc (spectrum->len * sizeof (gint16));
+ spectrum->im = g_malloc (spectrum->len * sizeof (gint16));
+ memset (spectrum->im, 0, spectrum->len * sizeof (gint16));
+ spectrum->re = g_malloc (spectrum->len * sizeof (gint16));
+ memset (spectrum->re, 0, spectrum->len * sizeof (gint16));
+}
+
+static void
+gst_spectrum_dispose (GObject * object)
+{
+ GstSpectrum *spectrum = GST_SPECTRUM (object);
+
+ g_free (spectrum->re);
+ g_free (spectrum->im);
+ g_free (spectrum->loud);
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gst_spectrum_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
- GstSpectrum *spectrum;
-
- g_return_if_fail (GST_IS_SPECTRUM (object));
- spectrum = GST_SPECTRUM (object);
+ GstSpectrum *spectrum = GST_SPECTRUM (object);
switch (prop_id) {
case ARG_WIDTH:
spectrum->width = g_value_get_int (value);
break;
default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
-static void
-gst_spectrum_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_spectrum_chain (GstPad * pad, GstBuffer * buffer)
{
- GstBuffer *buf = GST_BUFFER (_data);
GstSpectrum *spectrum;
- gint spec_base, spec_len;
- gint16 *re, *im, *loud;
gint16 *samples;
- gint step, pos, i;
+ gint step, pos, num, i;
guchar *spect;
GstBuffer *newbuf;
- g_return_if_fail (pad != NULL);
- g_return_if_fail (GST_IS_PAD (pad));
- g_return_if_fail (buf != NULL);
-
spectrum = GST_SPECTRUM (GST_OBJECT_PARENT (pad));
+ samples = (gint16 *) GST_BUFFER_DATA (buffer);
+
+ GST_LOG ("buffer-size = %ld", GST_BUFFER_SIZE (buffer));
+
+ /* FIXME:need a gst_adapter */
+ num = GST_BUFFER_SIZE (buffer) / 2;
+ num = MIN (num, spectrum->len);
+
+ for (i = 0; i < num; i++)
+ spectrum->re[i] = (samples[(i * 2)] + samples[(i * 2) + 1]) >> 1;
+
+ gst_spectrum_window (spectrum->re, spectrum->len);
+ gst_spectrum_fix_fft (spectrum->re, spectrum->im, spectrum->base, FALSE);
+ gst_spectrum_fix_loud (spectrum->loud, spectrum->re, spectrum->im,
+ spectrum->len, 0);
- samples = (gint16 *) GST_BUFFER_DATA (buf);
-
- spec_base = 8;
- spec_len = 1024;
-
- im = g_malloc (spec_len * sizeof (gint16));
- g_return_if_fail (im != NULL);
- loud = g_malloc (spec_len * sizeof (gint16));
- g_return_if_fail (loud != NULL);
-
- memset (im, 0, spec_len * sizeof (gint16));
- /*if (spectrum->meta->channels == 2) { */
- re = g_malloc (spec_len * sizeof (gint16));
- for (i = 0; i < spec_len; i++)
- re[i] = (samples[(i * 2)] + samples[(i * 2) + 1]) >> 1;
- /*} else */
- /* re = samples; */
- gst_spectrum_window (re, spec_len);
- gst_spectrum_fix_fft (re, im, spec_base, FALSE);
- gst_spectrum_fix_loud (loud, re, im, spec_len, 0);
- if (re != samples)
- g_free (re);
- g_free (im);
- step = spec_len / (spectrum->width * 2);
+ /* resample to requested width */
+ step = spectrum->len / (spectrum->width * 4); /* <-- shouldn't this be 2 instead of 4? */
spect = (guchar *) g_malloc (spectrum->width);
for (i = 0, pos = 0; i < spectrum->width; i++, pos += step) {
- if (loud[pos] > -60)
- spect[i] = (loud[pos] + 60) / 2;
- else
+ /* > -60 db? */
+ if (spectrum->loud[pos] > -60) {
+ spect[i] = spectrum->loud[pos] + 60;
+ /*
+ if (spect[i] > 15);
+ spect[i] = 15;
+ */
+ } else
+ /* treat as silence */
spect[i] = 0;
-/* if (spect[i] > 15); */
-/* spect[i] = 15; */
}
- g_free (loud);
- gst_buffer_unref (buf);
-/* g_free(samples); */
+ gst_buffer_unref (buffer);
newbuf = gst_buffer_new ();
- g_return_if_fail (newbuf != NULL);
GST_BUFFER_DATA (newbuf) = spect;
GST_BUFFER_SIZE (newbuf) = spectrum->width;
- gst_pad_push (spectrum->srcpad, GST_DATA (newbuf));
+ return gst_pad_push (spectrum->srcpad, newbuf);
}
static gboolean
diff --git a/gst/spectrum/gstspectrum.h b/gst/spectrum/gstspectrum.h
index 8cc546ec..2dbc2242 100644
--- a/gst/spectrum/gstspectrum.h
+++ b/gst/spectrum/gstspectrum.h
@@ -39,7 +39,7 @@ extern "C" {
#define GST_IS_SPECTRUM(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPECTRUM))
#define GST_IS_SPECTRUM_CLASS(obj) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPECTRUM))
+ (G_TYPE_CHECK_CLASS_TYPE((obj),GST_TYPE_SPECTRUM))
typedef struct _GstSpectrum GstSpectrum;
typedef struct _GstSpectrumClass GstSpectrumClass;
@@ -50,6 +50,8 @@ struct _GstSpectrum {
GstPad *sinkpad,*srcpad;
gint width;
+ gint base, len;
+ gint16 *re, *im, *loud;
};
struct _GstSpectrumClass {