summaryrefslogtreecommitdiffstats
path: root/tests/examples
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2007-10-30 21:37:49 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2007-10-30 21:37:49 +0000
commitceb068d0e9d5fab22131f70be2cc3ab395c337f5 (patch)
tree97aaf5e013b49fd519033420fc1e567b905507c5 /tests/examples
parent7c8653f596847c56ad358c883fd0b3c72652bbf9 (diff)
gst/equalizer/: Add small demo application based on the spectrum demo applications that gets white noise as input, pu...
Original commit message from CVS: * gst/equalizer/Makefile.am: * gst/equalizer/demo.c: (on_window_destroy), (on_configure_event), (on_gain_changed), (on_bandwidth_changed), (on_freq_changed), (draw_spectrum), (message_handler), (main): Add small demo application based on the spectrum demo applications that gets white noise as input, pushes it through an equalizer and paints the spectrum. For every equalizer band it's possible to set gain, bandwidth and frequency. * gst/equalizer/gstiirequalizer.c: (setup_filter): Add some guarding against too large or too small frequencies and bandwidths. Also improve debugging a bit.
Diffstat (limited to 'tests/examples')
-rw-r--r--tests/examples/equalizer/demo.c246
1 files changed, 246 insertions, 0 deletions
diff --git a/tests/examples/equalizer/demo.c b/tests/examples/equalizer/demo.c
new file mode 100644
index 00000000..7e7fae4a
--- /dev/null
+++ b/tests/examples/equalizer/demo.c
@@ -0,0 +1,246 @@
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <gst/gst.h>
+#include <gtk/gtk.h>
+
+#define NBANDS 10
+
+static GtkWidget *drawingarea = NULL;
+static guint spect_height = 128;
+static guint spect_bands = 256;
+static gfloat height_scale = 2.0;
+
+static void
+on_window_destroy (GtkObject * object, gpointer user_data)
+{
+ drawingarea = NULL;
+ gtk_main_quit ();
+}
+
+static gboolean
+on_configure_event (GtkWidget * widget, GdkEventConfigure * event,
+ gpointer user_data)
+{
+ GstElement *spectrum = GST_ELEMENT (user_data);
+
+ /*GST_INFO ("%d x %d", event->width, event->height); */
+ spect_height = event->height;
+ height_scale = event->height / 64.0;
+ spect_bands = event->width;
+
+ g_object_set (G_OBJECT (spectrum), "bands", spect_bands, NULL);
+ return FALSE;
+}
+
+/* control gains */
+static void
+on_gain_changed (GtkRange * range, gpointer user_data)
+{
+ GstObject *band = GST_OBJECT (user_data);
+ gdouble value = gtk_range_get_value (range);
+
+ g_object_set (band, "gain", value, NULL);
+}
+
+/* control bandwidths */
+static void
+on_bandwidth_changed (GtkRange * range, gpointer user_data)
+{
+ GstObject *band = GST_OBJECT (user_data);
+ gdouble value = gtk_range_get_value (range);
+
+ g_object_set (band, "bandwidth", value, NULL);
+}
+
+/* control frequency */
+static void
+on_freq_changed (GtkRange * range, gpointer user_data)
+{
+ GstObject *band = GST_OBJECT (user_data);
+ gdouble value = gtk_range_get_value (range);
+
+ /* hbox */
+ GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (range));
+
+ /* frame */
+ GtkWidget *parent_parent = gtk_widget_get_parent (parent);
+ gchar *label = g_strdup_printf ("%d Hz", (int) (value + 0.5));
+
+ gtk_frame_set_label (GTK_FRAME (parent_parent), label);
+ g_free (label);
+
+ g_object_set (band, "freq", value, NULL);
+}
+
+/* draw frequency spectrum as a bunch of bars */
+static void
+draw_spectrum (gfloat * data)
+{
+ gint i;
+ GdkRectangle rect = { 0, 0, spect_bands, spect_height };
+
+ if (!drawingarea)
+ return;
+
+ gdk_window_begin_paint_rect (drawingarea->window, &rect);
+ gdk_draw_rectangle (drawingarea->window, drawingarea->style->black_gc,
+ TRUE, 0, 0, spect_bands, spect_height);
+ for (i = 0; i < spect_bands; i++) {
+ gdk_draw_rectangle (drawingarea->window, drawingarea->style->white_gc,
+ TRUE, i, spect_height - data[i], 1, data[i]);
+ }
+ gdk_window_end_paint (drawingarea->window);
+}
+
+/* receive spectral data from element message */
+gboolean
+message_handler (GstBus * bus, GstMessage * message, gpointer data)
+{
+ if (message->type == GST_MESSAGE_ELEMENT) {
+ const GstStructure *s = gst_message_get_structure (message);
+ const gchar *name = gst_structure_get_name (s);
+
+ if (strcmp (name, "spectrum") == 0) {
+ gfloat spect[spect_bands];
+ const GValue *list;
+ const GValue *value;
+ guint i;
+
+ list = gst_structure_get_value (s, "magnitude");
+ for (i = 0; i < spect_bands; ++i) {
+ value = gst_value_list_get_value (list, i);
+ spect[i] = height_scale * g_value_get_float (value);
+ }
+ draw_spectrum (spect);
+ }
+ }
+ return TRUE;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GstElement *bin;
+ GstElement *src, *capsfilter, *equalizer, *spectrum, *audioconvert, *sink;
+ GstCaps *caps;
+ GstBus *bus;
+ GtkWidget *appwindow, *vbox, *hbox, *widget;
+
+ gst_init (&argc, &argv);
+ gtk_init (&argc, &argv);
+
+ bin = gst_pipeline_new ("bin");
+
+ src = gst_element_factory_make ("audiotestsrc", "src");
+ g_object_set (G_OBJECT (src), "wave", 5, NULL); /* White noise */
+
+ /* Force float32 samples */
+ capsfilter = gst_element_factory_make ("capsfilter", "capsfilter");
+ caps =
+ gst_caps_new_simple ("audio/x-raw-float", "width", G_TYPE_INT, 32, NULL);
+ g_object_set (capsfilter, "caps", caps, NULL);
+
+ equalizer = gst_element_factory_make ("equalizer-nbands", "equalizer");
+ g_object_set (G_OBJECT (equalizer), "num-bands", NBANDS, NULL);
+
+ spectrum = gst_element_factory_make ("spectrum", "spectrum");
+ g_object_set (G_OBJECT (spectrum), "bands", spect_bands, "threshold", -80,
+ "message", TRUE, "interval", 500 * GST_MSECOND, NULL);
+
+ audioconvert = gst_element_factory_make ("audioconvert", "audioconvert");
+
+ sink = gst_element_factory_make ("autoaudiosink", "sink");
+
+ gst_bin_add_many (GST_BIN (bin), src, capsfilter, equalizer, spectrum,
+ audioconvert, sink, NULL);
+ if (!gst_element_link_many (src, capsfilter, equalizer, spectrum,
+ audioconvert, sink, NULL)) {
+ fprintf (stderr, "can't link elements\n");
+ exit (1);
+ }
+
+ bus = gst_element_get_bus (bin);
+ gst_bus_add_watch (bus, message_handler, NULL);
+ gst_object_unref (bus);
+
+ appwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (G_OBJECT (appwindow), "destroy",
+ G_CALLBACK (on_window_destroy), NULL);
+ vbox = gtk_vbox_new (FALSE, 6);
+
+ drawingarea = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (drawingarea, spect_bands, spect_height);
+ g_signal_connect (G_OBJECT (drawingarea), "configure-event",
+ G_CALLBACK (on_configure_event), (gpointer) spectrum);
+ gtk_box_pack_start (GTK_BOX (vbox), drawingarea, TRUE, TRUE, 0);
+
+ hbox = gtk_hbox_new (FALSE, 30);
+
+ int i;
+
+ for (i = 0; i < NBANDS; i++) {
+ GstObject *band;
+ gdouble freq;
+ gdouble bw;
+ gdouble gain;
+ gchar *label;
+ GtkWidget *frame, *scales_hbox;
+
+ band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (equalizer), i);
+ g_assert (band != NULL);
+ g_object_get (G_OBJECT (band), "freq", &freq, NULL);
+ g_object_get (G_OBJECT (band), "bandwidth", &bw, NULL);
+ g_object_get (G_OBJECT (band), "gain", &gain, NULL);
+
+ label = g_strdup_printf ("%d Hz", (int) (freq + 0.5));
+ frame = gtk_frame_new (label);
+ g_free (label);
+
+ scales_hbox = gtk_hbox_new (FALSE, 6);
+
+ widget = gtk_vscale_new_with_range (-24.0, 12.0, 0.5);
+ gtk_scale_set_draw_value (GTK_SCALE (widget), TRUE);
+ gtk_scale_set_value_pos (GTK_SCALE (widget), GTK_POS_TOP);
+ gtk_range_set_value (GTK_RANGE (widget), gain);
+ gtk_widget_set_size_request (widget, 25, 150);
+ g_signal_connect (G_OBJECT (widget), "value-changed",
+ G_CALLBACK (on_gain_changed), (gpointer) band);
+ gtk_box_pack_start (GTK_BOX (scales_hbox), widget, FALSE, FALSE, 0);
+
+ widget = gtk_vscale_new_with_range (1.0, 20000.0, 5.0);
+ gtk_scale_set_draw_value (GTK_SCALE (widget), TRUE);
+ gtk_scale_set_value_pos (GTK_SCALE (widget), GTK_POS_TOP);
+ gtk_range_set_value (GTK_RANGE (widget), bw);
+ gtk_widget_set_size_request (widget, 25, 150);
+ g_signal_connect (G_OBJECT (widget), "value-changed",
+ G_CALLBACK (on_bandwidth_changed), (gpointer) band);
+ gtk_box_pack_start (GTK_BOX (scales_hbox), widget, FALSE, FALSE, 0);
+
+ widget = gtk_vscale_new_with_range (20.0, 20000.0, 5.0);
+ gtk_scale_set_draw_value (GTK_SCALE (widget), TRUE);
+ gtk_scale_set_value_pos (GTK_SCALE (widget), GTK_POS_TOP);
+ gtk_range_set_value (GTK_RANGE (widget), freq);
+ gtk_widget_set_size_request (widget, 25, 150);
+ g_signal_connect (G_OBJECT (widget), "value-changed",
+ G_CALLBACK (on_freq_changed), (gpointer) band);
+ gtk_box_pack_start (GTK_BOX (scales_hbox), widget, FALSE, FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (frame), scales_hbox);
+
+ gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
+ }
+
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+
+ gtk_container_add (GTK_CONTAINER (appwindow), vbox);
+ gtk_widget_show_all (appwindow);
+
+ gst_element_set_state (bin, GST_STATE_PLAYING);
+ gtk_main ();
+ gst_element_set_state (bin, GST_STATE_NULL);
+
+ gst_object_unref (bin);
+
+ return 0;
+}