2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
25 #include "gstspectrum.h"
27 /* elementfactory information */
28 static GstElementDetails gst_spectrum_details =
29 GST_ELEMENT_DETAILS ("Spectrum analyzer",
30 "Filter/Analyzer/Audio",
31 "Run an FFT on the audio signal, output spectrum data",
32 "Erik Walthinsen <omega@cse.ogi.edu>");
34 /* Spectrum signals and args */
48 static void gst_spectrum_base_init (gpointer g_class);
49 static void gst_spectrum_class_init (GstSpectrumClass * klass);
50 static void gst_spectrum_init (GstSpectrum * spectrum);
52 static void gst_spectrum_set_property (GObject * object, guint prop_id,
53 const GValue * value, GParamSpec * pspec);
55 static void gst_spectrum_chain (GstPad * pad, GstData * _data);
58 int gst_spectrum_fix_fft (fixed fr[], fixed fi[], int m, int inverse);
59 void gst_spectrum_fix_loud (fixed loud[], fixed fr[], fixed fi[], int n,
61 void gst_spectrum_window (fixed fr[], int n);
64 static GstElementClass *parent_class = NULL;
66 /*static guint gst_spectrum_signals[LAST_SIGNAL] = { 0 }; */
69 gst_spectrum_get_type (void)
71 static GType spectrum_type = 0;
74 static const GTypeInfo spectrum_info = {
75 sizeof (GstSpectrumClass),
76 gst_spectrum_base_init,
78 (GClassInitFunc) gst_spectrum_class_init,
83 (GInstanceInitFunc) gst_spectrum_init,
86 g_type_register_static (GST_TYPE_ELEMENT, "GstSpectrum", &spectrum_info,
93 gst_spectrum_base_init (gpointer g_class)
95 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
97 gst_element_class_set_details (element_class, &gst_spectrum_details);
100 gst_spectrum_class_init (GstSpectrumClass * klass)
102 GObjectClass *gobject_class;
104 gobject_class = (GObjectClass *) klass;
106 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
108 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 */
110 gobject_class->set_property = gst_spectrum_set_property;
114 gst_spectrum_init (GstSpectrum * spectrum)
116 spectrum->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
117 gst_element_add_pad (GST_ELEMENT (spectrum), spectrum->sinkpad);
118 gst_pad_set_chain_function (spectrum->sinkpad, gst_spectrum_chain);
119 spectrum->srcpad = gst_pad_new ("src", GST_PAD_SRC);
120 gst_element_add_pad (GST_ELEMENT (spectrum), spectrum->srcpad);
122 spectrum->width = 75;
126 gst_spectrum_set_property (GObject * object, guint prop_id,
127 const GValue * value, GParamSpec * pspec)
129 GstSpectrum *spectrum;
131 /* it's not null if we got it, but it might not be ours */
132 g_return_if_fail (GST_IS_SPECTRUM (object));
133 spectrum = GST_SPECTRUM (object);
137 spectrum->width = g_value_get_int (value);
145 gst_spectrum_chain (GstPad * pad, GstData * _data)
147 GstBuffer *buf = GST_BUFFER (_data);
148 GstSpectrum *spectrum;
149 gint spec_base, spec_len;
150 gint16 *re, *im, *loud;
156 g_return_if_fail (pad != NULL);
157 g_return_if_fail (GST_IS_PAD (pad));
158 g_return_if_fail (buf != NULL);
160 spectrum = GST_SPECTRUM (GST_OBJECT_PARENT (pad));
162 samples = (gint16 *) GST_BUFFER_DATA (buf);
167 im = g_malloc (spec_len * sizeof (gint16));
168 g_return_if_fail (im != NULL);
169 loud = g_malloc (spec_len * sizeof (gint16));
170 g_return_if_fail (loud != NULL);
172 memset (im, 0, spec_len * sizeof (gint16));
173 /*if (spectrum->meta->channels == 2) { */
174 re = g_malloc (spec_len * sizeof (gint16));
175 for (i = 0; i < spec_len; i++)
176 re[i] = (samples[(i * 2)] + samples[(i * 2) + 1]) >> 1;
179 gst_spectrum_window (re, spec_len);
180 gst_spectrum_fix_fft (re, im, spec_base, FALSE);
181 gst_spectrum_fix_loud (loud, re, im, spec_len, 0);
185 step = spec_len / (spectrum->width * 2);
186 spect = (guchar *) g_malloc (spectrum->width);
187 for (i = 0, pos = 0; i < spectrum->width; i++, pos += step) {
189 spect[i] = (loud[pos] + 60) / 2;
192 /* if (spect[i] > 15); */
196 gst_buffer_unref (buf);
197 /* g_free(samples); */
199 newbuf = gst_buffer_new ();
200 g_return_if_fail (newbuf != NULL);
201 GST_BUFFER_DATA (newbuf) = spect;
202 GST_BUFFER_SIZE (newbuf) = spectrum->width;
204 gst_pad_push (spectrum->srcpad, GST_DATA (newbuf));
208 plugin_init (GstPlugin * plugin)
210 return gst_element_register (plugin, "spectrum", GST_RANK_NONE,
214 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
217 "Run an FFT on the audio signal, output spectrum data",
218 plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)