diff options
author | Thomas Vander Stichele <thomas@apestaart.org> | 2003-09-26 16:45:04 +0000 |
---|---|---|
committer | Thomas Vander Stichele <thomas@apestaart.org> | 2003-09-26 16:45:04 +0000 |
commit | 3ab75a571e204fbe6981c94d28cebb776124251b (patch) | |
tree | c3e50f08f81ca97109762a64cf73837fc6f7598c /gst | |
parent | 46860a7c533203cc3db68afff2936f039833cfde (diff) |
added second example with plotting fixed some aesthetics
Original commit message from CVS:
added second example with plotting
fixed some aesthetics
Diffstat (limited to 'gst')
-rw-r--r-- | gst/level/Makefile.am | 5 | ||||
-rw-r--r-- | gst/level/README | 18 | ||||
-rw-r--r-- | gst/level/demo.c | 7 | ||||
-rw-r--r-- | gst/level/gstlevel-marshal.list | 2 | ||||
-rw-r--r-- | gst/level/gstlevel.c | 17 | ||||
-rw-r--r-- | gst/level/gstlevel.h | 2 | ||||
-rw-r--r-- | gst/level/plot.c | 120 |
7 files changed, 160 insertions, 11 deletions
diff --git a/gst/level/Makefile.am b/gst/level/Makefile.am index cb3ee73c..8bb3c4dd 100644 --- a/gst/level/Makefile.am +++ b/gst/level/Makefile.am @@ -9,10 +9,13 @@ libgstlevel_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) noinst_HEADERS = gstlevel.h filter.func if HAVE_GTK -noinst_PROGRAMS = demo +noinst_PROGRAMS = demo plot demo_SOURCES = demo.c demo_CFLAGS = $(GTK_CFLAGS) $(GST_CFLAGS) demo_LDFLAGS = $(GTK_LIBS) $(GST_LIBS) +plot_SOURCES = plot.c +plot_CFLAGS = $(GTK_CFLAGS) $(GST_CFLAGS) +plot_LDFLAGS = $(GTK_LIBS) $(GST_LIBS) endif EXTRA_libgstlevel_la_SOURCES = gstlevel-marshal.list diff --git a/gst/level/README b/gst/level/README index fffc69fa..0ae84188 100644 --- a/gst/level/README +++ b/gst/level/README @@ -1,6 +1,7 @@ level plugin by thomas <thomas@apestaart.org> this plugin signals: + - running time since last EOS/start - channel - RMS level - peak level @@ -18,4 +19,21 @@ The element only takes unsigned data in; it could be extended to signed as well, if separate fast chain functions are made that displaces the incoming data to its midpoint (ie, 0,65535 should be mapped to -32768, 32767) +There are two demo apps, apps and plot. apps will create some GTK sliders +to display the volume. plot will output data readable by gnuplot. + +Here is a sample plot script to plot output of the plot command that was +stored to plot.dat + +set xlabel "Seconds" +set ylabel "dB" +set yrange [-60:0] +plot 'plot.dat' using 1:2 title 'L RMS' with lines, \ + 'plot.dat' using 1:3 title 'L peak' with lines, \ + 'plot.dat' using 1:4 title 'L decay' with lines + +plot 'plot.dat' using 1:5 title 'R RMS' with lines, \ + 'plot.dat' using 1:6 title 'R peak' with lines, \ + 'plot.dat' using 1:7 title 'R decay' with lines + diff --git a/gst/level/demo.c b/gst/level/demo.c index d1c6905e..b0dea33c 100644 --- a/gst/level/demo.c +++ b/gst/level/demo.c @@ -28,7 +28,7 @@ GtkWidget *scale[2][3]; static void -level_callback (GstElement *element, gint channel, +level_callback (GstElement *element, gdouble time, gint channel, gdouble rms, gdouble peak, gdouble decay) { gtk_range_set_value (GTK_RANGE (scale[channel][0]), rms); @@ -41,7 +41,10 @@ idler (gpointer data) { GstElement *pipeline = GST_ELEMENT (data); g_print ("+"); - return gst_bin_iterate (GST_BIN (pipeline)); + if (gst_bin_iterate (GST_BIN (pipeline))) + return TRUE; + gtk_main_quit (); + return FALSE; } static void diff --git a/gst/level/gstlevel-marshal.list b/gst/level/gstlevel-marshal.list index d2ae97ea..9a2455bb 100644 --- a/gst/level/gstlevel-marshal.list +++ b/gst/level/gstlevel-marshal.list @@ -1 +1 @@ -VOID:INT,DOUBLE,DOUBLE,DOUBLE +VOID:DOUBLE,INT,DOUBLE,DOUBLE,DOUBLE diff --git a/gst/level/gstlevel.c b/gst/level/gstlevel.c index 2b73e479..ca33743f 100644 --- a/gst/level/gstlevel.c +++ b/gst/level/gstlevel.c @@ -214,7 +214,7 @@ gst_level_chain (GstPad *pad, GstBuffer *buf) for (i = 0; i < filter->channels; ++i) filter->CS[i] = filter->peak[i] = filter->MS[i] = filter->RMS_dB[i] = 0.0; - in_data = (gint16 *) GST_BUFFER_DATA(buf); + in_data = (gint16 *) GST_BUFFER_DATA (buf); num_samples = GST_BUFFER_SIZE (buf) / (filter->width / 8); if (num_samples % filter->channels != 0) @@ -288,14 +288,18 @@ gst_level_chain (GstPad *pad, GstBuffer *buf) { if (filter->signal) { - gdouble RMS, peak; + gdouble RMS, peak, endtime; for (i = 0; i < filter->channels; ++i) { RMS = sqrt (filter->CS[i] / (filter->num_samples / filter->channels)); peak = filter->last_peak[i]; + num_samples = GST_BUFFER_SIZE (buf) / (filter->width / 8); + endtime = (double) GST_BUFFER_TIMESTAMP (buf) / GST_SECOND + + (double) num_samples / (double) filter->rate; g_signal_emit (G_OBJECT (filter), gst_filter_signals[SIGNAL_LEVEL], 0, - i, 20 * log10 (RMS), 20 * log10 (filter->last_peak[i]), + endtime, i, + 20 * log10 (RMS), 20 * log10 (filter->last_peak[i]), 20 * log10 (filter->decay_peak[i])); /* we emitted, so reset cumulative and normal peak */ filter->CS[i] = 0.0; @@ -397,9 +401,10 @@ gst_level_class_init (GstLevelClass *klass) gst_filter_signals[SIGNAL_LEVEL] = g_signal_new ("level", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstLevelClass, level), NULL, NULL, - gstlevel_cclosure_marshal_VOID__INT_DOUBLE_DOUBLE_DOUBLE, - G_TYPE_NONE, 4, - G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE); + gstlevel_cclosure_marshal_VOID__DOUBLE_INT_DOUBLE_DOUBLE_DOUBLE, + G_TYPE_NONE, 5, + G_TYPE_DOUBLE, G_TYPE_INT, + G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE); } static void diff --git a/gst/level/gstlevel.h b/gst/level/gstlevel.h index d5b8fd7e..37143275 100644 --- a/gst/level/gstlevel.h +++ b/gst/level/gstlevel.h @@ -77,7 +77,7 @@ struct _GstLevel { struct _GstLevelClass { GstElementClass parent_class; - void (*level) (GstElement *element, gint channel, + void (*level) (GstElement *element, gdouble time, gint channel, gdouble RMS_dB, gdouble peak_dB, gdouble decay_peak_dB); }; diff --git a/gst/level/plot.c b/gst/level/plot.c new file mode 100644 index 00000000..4e770326 --- /dev/null +++ b/gst/level/plot.c @@ -0,0 +1,120 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> + * + * plot.c: output data points to be graphed with gnuplot + * Copyright (C) 2003 + * Thomas Vander Stichele <thomas at apestaart dot org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gst/gst.h> +#include <gtk/gtk.h> + +gboolean got_channel[2] = { FALSE, FALSE}; /* to see if we got the signal for this one yet */ +gint channels = 0 ; /* guess at how many channels there are */ +gdouble last_time = 0.0; /* time of last signal */ +gdouble values[2][3]; /* array of levels from which to print */ + +static void +level_callback (GstElement *element, gdouble time, gint channel, + gdouble rms, gdouble peak, gdouble decay) +{ + int i = 0, j = 0; + gboolean got_all = FALSE; + + if (channel + 1> channels) channels = channel + 1; + + /* reset got_channel if this is a new time point */ + if (time > last_time) + { + for (i = 0; i < channels; ++i) got_channel[i] = FALSE; + last_time = time; + } + + /* store values */ + got_channel[channel] = TRUE; + values[channel][0] = rms; + values[channel][1] = peak; + values[channel][2] = decay; + + /* check if we have all channels, and output if we do */ + /* FIXME: this fails on the first, no ? */ + got_all = TRUE; + for (i = 0; i < channels; ++i) + if (!got_channel[i]) got_all = FALSE; + if (got_all) + { + g_print ("%f ", time); + for (i = 0; i < channels; ++i) + for (j = 0; j < 3; ++j) + g_print ("%f ", values[i][j]); + g_print ("\n"); + } +} + +static gboolean +idler (gpointer data) +{ + GstElement *pipeline = GST_ELEMENT (data); + if (gst_bin_iterate (GST_BIN (pipeline))) + return TRUE; + + gtk_main_quit (); + return FALSE; +} + +int main +(int argc, char *argv[]) +{ + + GstElement *pipeline = NULL; + GError *error = NULL; + GstElement *level; + + gst_init (&argc, &argv); + gtk_init (&argc, &argv); + + pipeline = gst_parse_launchv ((const gchar **) &argv[1], &error); + if (error) + { + g_print ("pipeline could not be constructed: %s\n", error->message); + g_print ("Please give a complete pipeline with a 'level' element.\n"); + g_print ("Example: sinesrc ! level ! osssink\n"); + g_error_free (error); + return 1; + } + + level = gst_bin_get_by_name (GST_BIN (pipeline), "level0"); + if (level == NULL) + { + g_print ("Please give a pipeline with a 'level' element in it\n"); + return 1; + } + + g_object_set (level, "signal", TRUE, NULL); + g_signal_connect (level, "level", G_CALLBACK (level_callback), NULL); + + + /* go to main loop */ + gst_element_set_state (pipeline, GST_STATE_PLAYING); + g_idle_add (idler, pipeline); + + gtk_main (); + + return 0; +} + |