diff options
Diffstat (limited to 'ext/smoothwave')
-rw-r--r-- | ext/smoothwave/Makefile.am | 11 | ||||
-rw-r--r-- | ext/smoothwave/README | 6 | ||||
-rw-r--r-- | ext/smoothwave/gstsmoothwave.c | 301 | ||||
-rw-r--r-- | ext/smoothwave/gstsmoothwave.h | 71 |
4 files changed, 389 insertions, 0 deletions
diff --git a/ext/smoothwave/Makefile.am b/ext/smoothwave/Makefile.am new file mode 100644 index 00000000..f000c7a4 --- /dev/null +++ b/ext/smoothwave/Makefile.am @@ -0,0 +1,11 @@ +filterdir = $(libdir)/gst + +filter_LTLIBRARIES = libgstsmoothwave.la + +libgstsmoothwave_la_SOURCES = gstsmoothwave.c +libgstsmoothwave_la_CFLAGS = $(GST_CFLAGS) $(GTK_CFLAGS) +libgstsmoothwave_la_LIBADD = $(GTK_LIBS) + +noinst_HEADERS = gstsmoothwave.h + +EXTRA_DIST = README diff --git a/ext/smoothwave/README b/ext/smoothwave/README new file mode 100644 index 00000000..ff737852 --- /dev/null +++ b/ext/smoothwave/README @@ -0,0 +1,6 @@ +This is a home-grown visualization, with a couple lines of code copied +from synaesthesia. It draws the waveform in the bitmap, then fades out +the entire bitmap so older waveforms disappear. It looks OK, but it's +grayscale so far (haven't solved the cmap problems, note all the commented +out code). I'm going to try to make a much better version as time goes +on. diff --git a/ext/smoothwave/gstsmoothwave.c b/ext/smoothwave/gstsmoothwave.c new file mode 100644 index 00000000..befdba1d --- /dev/null +++ b/ext/smoothwave/gstsmoothwave.c @@ -0,0 +1,301 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> + * + * 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 <string.h> + +#include "gstsmoothwave.h" + +static GstElementDetails gst_smoothwave_details = { + "Smooth waveform", + "Sink/Visualization", + "Fading grayscale waveform display", + VERSION, + "Erik Walthinsen <omega@cse.ogi.edu>", + "(C) 1999", +}; + + +/* SmoothWave signals and args */ +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_WIDTH, + ARG_HEIGHT, + ARG_WIDGET, +}; + + +static void gst_smoothwave_class_init (GstSmoothWaveClass *klass); +static void gst_smoothwave_init (GstSmoothWave *smoothwave); + +static void gst_smoothwave_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void gst_smoothwave_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + +static void gst_smoothwave_chain (GstPad *pad, GstBuffer *buf); + +static GstElementClass *parent_class = NULL; +//static guint gst_smoothwave_signals[LAST_SIGNAL] = { 0 }; + + +GType +gst_smoothwave_get_type (void) +{ + static GType smoothwave_type = 0; + + if (!smoothwave_type) { + static const GTypeInfo smoothwave_info = { + sizeof(GstSmoothWaveClass), NULL, + NULL, + (GClassInitFunc)gst_smoothwave_class_init, + NULL, + NULL, + sizeof(GstSmoothWave), + 0, + (GInstanceInitFunc)gst_smoothwave_init, + }; + smoothwave_type = g_type_register_static(GST_TYPE_ELEMENT, "GstSmoothWave", &smoothwave_info, 0); + } + return smoothwave_type; +} + +static void +gst_smoothwave_class_init (GstSmoothWaveClass *klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = g_type_class_ref(GST_TYPE_ELEMENT); + + 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_READWRITE)); // CHECKME + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HEIGHT, + g_param_spec_int("height","height","height", + G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_WIDGET, + g_param_spec_object("widget","widget","widget", + GTK_TYPE_WIDGET,G_PARAM_READABLE)); // CHECKME! + + gobject_class->set_property = gst_smoothwave_set_property; + gobject_class->get_property = gst_smoothwave_get_property; +} + +static void +gst_smoothwave_init (GstSmoothWave *smoothwave) +{ + int i; + guint32 palette[256]; + + smoothwave->sinkpad = gst_pad_new("sink",GST_PAD_SINK); + gst_element_add_pad(GST_ELEMENT(smoothwave),smoothwave->sinkpad); + gst_pad_set_chain_function(smoothwave->sinkpad,gst_smoothwave_chain); + smoothwave->srcpad = gst_pad_new("src",GST_PAD_SRC); + gst_element_add_pad(GST_ELEMENT(smoothwave),smoothwave->srcpad); + +// smoothwave->meta = NULL; + smoothwave->width = 512; + smoothwave->height = 256; + + gdk_rgb_init(); +// gtk_widget_set_default_colormap (gdk_rgb_get_cmap()); +// gtk_widget_set_default_visual (gdk_rgb_get_visual()); + +// GST_DEBUG (0,"creating palette\n"); + for (i=0;i<256;i++) + palette[i] = (i << 16) || (i << 8); +// GST_DEBUG (0,"creating cmap\n"); + smoothwave->cmap = gdk_rgb_cmap_new(palette,256); +// GST_DEBUG (0,"created cmap\n"); +// gtk_widget_set_default_colormap (smoothwave->cmap); + + smoothwave->image = gtk_drawing_area_new(); + gtk_drawing_area_size(GTK_DRAWING_AREA(smoothwave->image), + smoothwave->width,smoothwave->height); + gtk_widget_show(smoothwave->image); + + smoothwave->imagebuffer = g_malloc(smoothwave->width*smoothwave->height); + memset(smoothwave->imagebuffer,0,smoothwave->width*smoothwave->height); +} + +static void +gst_smoothwave_chain (GstPad *pad, GstBuffer *buf) +{ + GstSmoothWave *smoothwave; + gint16 *samples; + gint samplecount,i; + register guint32 *ptr; + gint qheight; + + g_return_if_fail(pad != NULL); + g_return_if_fail(GST_IS_PAD(pad)); + g_return_if_fail(buf != NULL); +// g_return_if_fail(GST_IS_BUFFER(buf)); + + smoothwave = GST_SMOOTHWAVE(GST_OBJECT_PARENT (pad)); + + /* first deal with audio metadata */ +// if (buf->meta) { +// if (smoothwave->meta != NULL) { +// /* FIXME: need to unref the old metadata so it goes away */ +// } +// /* we just make a copy of the pointer */ +// smoothwave->meta = (MetaAudioRaw *)(buf->meta); +// /* FIXME: now we have to ref the metadata so it doesn't go away */ +// } + +// g_return_if_fail(smoothwave->meta != NULL); + + samples = (gint16 *)GST_BUFFER_DATA(buf); +// samplecount = buf->datasize / (smoothwave->meta->channels * sizeof(gint16)); + samplecount = GST_BUFFER_SIZE(buf) / (2 * sizeof(gint16)); + + qheight = smoothwave->height/4; + +// GST_DEBUG (0,"traversing %d\n",smoothwave->width); + for (i=0;i<MAX(smoothwave->width,samplecount);i++) { + gint16 y1 = (gint32)(samples[i*2] * qheight) / 32768 + + qheight; + gint16 y2 = (gint32)(samples[(i*2)+1] * qheight) / 32768 + + (qheight*3); + smoothwave->imagebuffer[y1*smoothwave->width + i] = 0xff; + smoothwave->imagebuffer[y2*smoothwave->width + i] = 0xff; +// smoothwave->imagebuffer[i+(smoothwave->width*5)] = i; + } + + ptr = (guint32 *)smoothwave->imagebuffer; + for (i=0;i<(smoothwave->width*smoothwave->height)/4;i++) { + if (*ptr) + *(ptr++) -= ((*ptr & 0xf0f0f0f0ul) >> 4) + ((*ptr & 0xe0e0e0e0ul) >> 5); + else + ptr++; + } + +// GST_DEBUG (0,"drawing\n"); +/* GST_DEBUG (0,"gdk_draw_indexed_image(%p,%p,%d,%d,%d,%d,%s,%p,%d,%p);\n", + smoothwave->image->window, + smoothwave->image->style->fg_gc[GTK_STATE_NORMAL], + 0,0,smoothwave->width,smoothwave->height, + "GDK_RGB_DITHER_NORMAL", + smoothwave->imagebuffer,smoothwave->width, + smoothwave->cmap);*/ +/* gdk_draw_indexed_image(smoothwave->image->window, + smoothwave->image->style->fg_gc[GTK_STATE_NORMAL], + 0,0,smoothwave->width,smoothwave->height, + GDK_RGB_DITHER_NONE, + smoothwave->imagebuffer,smoothwave->width, + smoothwave->cmap);*/ + gdk_draw_gray_image(smoothwave->image->window, + smoothwave->image->style->fg_gc[GTK_STATE_NORMAL], + 0,0,smoothwave->width,smoothwave->height, + GDK_RGB_DITHER_NORMAL, + smoothwave->imagebuffer,smoothwave->width); + +// gst_trace_add_entry(NULL,0,buf,"smoothwave: calculated smoothwave"); + + gst_buffer_unref(buf); +} + +static void +gst_smoothwave_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstSmoothWave *smoothwave; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_SMOOTHWAVE(object)); + smoothwave = GST_SMOOTHWAVE(object); + + switch (prop_id) { + case ARG_WIDTH: + smoothwave->width = g_value_get_int (value); + gtk_drawing_area_size(GTK_DRAWING_AREA(smoothwave->image), + smoothwave->width,smoothwave->height); + gtk_widget_set_usize(GTK_WIDGET(smoothwave->image), + smoothwave->width,smoothwave->height); + break; + case ARG_HEIGHT: + smoothwave->height = g_value_get_int (value); + gtk_drawing_area_size(GTK_DRAWING_AREA(smoothwave->image), + smoothwave->width,smoothwave->height); + gtk_widget_set_usize(GTK_WIDGET(smoothwave->image), + smoothwave->width,smoothwave->height); + break; + default: + break; + } +} + +static void +gst_smoothwave_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstSmoothWave *smoothwave; + + /* it's not null if we got it, but it might not be ours */ + smoothwave = GST_SMOOTHWAVE(object); + + switch (prop_id) { + case ARG_WIDTH: { + g_value_set_int (value, smoothwave->width); + break; + } + case ARG_HEIGHT: { + g_value_set_int (value, smoothwave->height); + break; + } + case ARG_WIDGET: { + g_value_set_object (value, smoothwave->image); + break; + } + default: { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } +} + + + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + GstElementFactory *factory; + + /* create an elementfactory for the smoothwave element */ + factory = gst_elementfactory_new("smoothwave",GST_TYPE_SMOOTHWAVE, + &gst_smoothwave_details); + g_return_val_if_fail(factory != NULL, FALSE); + + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); + + return TRUE; +} + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "smoothwave", + plugin_init +}; diff --git a/ext/smoothwave/gstsmoothwave.h b/ext/smoothwave/gstsmoothwave.h new file mode 100644 index 00000000..3f430097 --- /dev/null +++ b/ext/smoothwave/gstsmoothwave.h @@ -0,0 +1,71 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> + * + * 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. + */ + + +#ifndef __GST_SMOOTHWAVE_H__ +#define __GST_SMOOTHWAVE_H__ + + +#include <gst/gst.h> +#include <gtk/gtk.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GST_TYPE_SMOOTHWAVE \ + (gst_smoothwave_get_type()) +#define GST_SMOOTHWAVE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SMOOTHWAVE,GstSmoothWave)) +#define GST_SMOOTHWAVE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SMOOTHWAVE,GstSmoothWave)) +#define GST_IS_SMOOTHWAVE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SMOOTHWAVE)) +#define GST_IS_SMOOTHWAVE_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SMOOTHWAVE)) + +typedef struct _GstSmoothWave GstSmoothWave; +typedef struct _GstSmoothWaveClass GstSmoothWaveClass; + +struct _GstSmoothWave { + GstElement element; + + GstPad *sinkpad,*srcpad; + + gint width,height; + + GdkRgbCmap *cmap; + GtkWidget *image; + guchar *imagebuffer; +}; + +struct _GstSmoothWaveClass { + GstElementClass parent_class; +}; + +GType gst_smoothwave_get_type(void); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_SMOOTHWAVE_H__ */ |