gst-indent
[platform/upstream/gst-plugins-good.git] / gst / smoothwave / gstsmoothwave.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
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.
8  *
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.
13  *
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.
18  */
19
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 #include <string.h>
25
26 #include "gstsmoothwave.h"
27
28 static GstElementDetails gst_smoothwave_details =
29 GST_ELEMENT_DETAILS ("Smooth waveform",
30     "Visualization",
31     "Fading grayscale waveform display",
32     "Erik Walthinsen <omega@cse.ogi.edu>");
33
34
35 /* SmoothWave signals and args */
36 enum
37 {
38   /* FILL ME */
39   LAST_SIGNAL
40 };
41
42 enum
43 {
44   ARG_0,
45   ARG_WIDTH,
46   ARG_HEIGHT,
47   ARG_WIDGET,
48 };
49
50 static void gst_smoothwave_base_init (gpointer g_class);
51 static void gst_smoothwave_class_init (GstSmoothWaveClass * klass);
52 static void gst_smoothwave_init (GstSmoothWave * smoothwave);
53
54 static void gst_smoothwave_set_property (GObject * object, guint prop_id,
55     const GValue * value, GParamSpec * pspec);
56 static void gst_smoothwave_get_property (GObject * object, guint prop_id,
57     GValue * value, GParamSpec * pspec);
58
59 static void gst_smoothwave_chain (GstPad * pad, GstData * _data);
60
61 static GstElementClass *parent_class = NULL;
62
63 /*static guint gst_smoothwave_signals[LAST_SIGNAL] = { 0 }; */
64
65
66 GType
67 gst_smoothwave_get_type (void)
68 {
69   static GType smoothwave_type = 0;
70
71   if (!smoothwave_type) {
72     static const GTypeInfo smoothwave_info = {
73       sizeof (GstSmoothWaveClass),
74       gst_smoothwave_base_init,
75       NULL,
76       (GClassInitFunc) gst_smoothwave_class_init,
77       NULL,
78       NULL,
79       sizeof (GstSmoothWave),
80       0,
81       (GInstanceInitFunc) gst_smoothwave_init,
82     };
83     smoothwave_type =
84         g_type_register_static (GST_TYPE_ELEMENT, "GstSmoothWave",
85         &smoothwave_info, 0);
86   }
87   return smoothwave_type;
88 }
89
90 static void
91 gst_smoothwave_base_init (gpointer g_class)
92 {
93   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
94
95   gst_element_class_set_details (element_class, &gst_smoothwave_details);
96 }
97
98 static void
99 gst_smoothwave_class_init (GstSmoothWaveClass * klass)
100 {
101   GObjectClass *gobject_class;
102   GstElementClass *gstelement_class;
103
104   gobject_class = (GObjectClass *) klass;
105   gstelement_class = (GstElementClass *) klass;
106
107   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
108
109   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 */
110   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 */
111   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! */
112
113   gobject_class->set_property = gst_smoothwave_set_property;
114   gobject_class->get_property = gst_smoothwave_get_property;
115 }
116
117 static void
118 gst_smoothwave_init (GstSmoothWave * smoothwave)
119 {
120   int i;
121   guint32 palette[256];
122
123   smoothwave->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
124   gst_element_add_pad (GST_ELEMENT (smoothwave), smoothwave->sinkpad);
125   gst_pad_set_chain_function (smoothwave->sinkpad, gst_smoothwave_chain);
126   smoothwave->srcpad = gst_pad_new ("src", GST_PAD_SRC);
127   gst_element_add_pad (GST_ELEMENT (smoothwave), smoothwave->srcpad);
128
129 /*  smoothwave->meta = NULL; */
130   smoothwave->width = 512;
131   smoothwave->height = 256;
132
133   gdk_rgb_init ();
134 /*  gtk_widget_set_default_colormap (gdk_rgb_get_cmap()); */
135 /*  gtk_widget_set_default_visual (gdk_rgb_get_visual()); */
136
137 /*  GST_DEBUG ("creating palette"); */
138   for (i = 0; i < 256; i++)
139     palette[i] = (i << 16) || (i << 8);
140 /*  GST_DEBUG ("creating cmap"); */
141   smoothwave->cmap = gdk_rgb_cmap_new (palette, 256);
142 /*  GST_DEBUG ("created cmap"); */
143 /*  gtk_widget_set_default_colormap (smoothwave->cmap); */
144
145   smoothwave->image = gtk_drawing_area_new ();
146   gtk_drawing_area_size (GTK_DRAWING_AREA (smoothwave->image),
147       smoothwave->width, smoothwave->height);
148   gtk_widget_show (smoothwave->image);
149
150   smoothwave->imagebuffer = g_malloc (smoothwave->width * smoothwave->height);
151   memset (smoothwave->imagebuffer, 0, smoothwave->width * smoothwave->height);
152 }
153
154 static void
155 gst_smoothwave_chain (GstPad * pad, GstData * _data)
156 {
157   GstBuffer *buf = GST_BUFFER (_data);
158   GstSmoothWave *smoothwave;
159   gint16 *samples;
160   gint samplecount, i;
161   register guint32 *ptr;
162   gint qheight;
163
164   g_return_if_fail (pad != NULL);
165   g_return_if_fail (GST_IS_PAD (pad));
166   g_return_if_fail (buf != NULL);
167 /*  g_return_if_fail(GST_IS_BUFFER(buf)); */
168
169   smoothwave = GST_SMOOTHWAVE (GST_OBJECT_PARENT (pad));
170
171   /* first deal with audio metadata */
172 #if 0
173   if (buf->meta) {
174     if (smoothwave->meta != NULL) {
175       /* FIXME: need to unref the old metadata so it goes away */
176     }
177     /* we just make a copy of the pointer */
178     smoothwave->meta = (MetaAudioRaw *) (buf->meta);
179     /* FIXME: now we have to ref the metadata so it doesn't go away */
180   }
181 #endif
182
183 /*  g_return_if_fail(smoothwave->meta != NULL); */
184
185   samples = (gint16 *) GST_BUFFER_DATA (buf);
186 /*  samplecount = buf->datasize / (smoothwave->meta->channels * sizeof(gint16)); */
187   samplecount = GST_BUFFER_SIZE (buf) / (2 * sizeof (gint16));
188
189   qheight = smoothwave->height / 4;
190
191 /*  GST_DEBUG ("traversing %d",smoothwave->width); */
192   for (i = 0; i < MAX (smoothwave->width, samplecount); i++) {
193     gint16 y1 = (gint32) (samples[i * 2] * qheight) / 32768 + qheight;
194     gint16 y2 = (gint32) (samples[(i * 2) + 1] * qheight) / 32768 +
195         (qheight * 3);
196     smoothwave->imagebuffer[y1 * smoothwave->width + i] = 0xff;
197     smoothwave->imagebuffer[y2 * smoothwave->width + i] = 0xff;
198 /*    smoothwave->imagebuffer[i+(smoothwave->width*5)] = i; */
199   }
200
201   ptr = (guint32 *) smoothwave->imagebuffer;
202   for (i = 0; i < (smoothwave->width * smoothwave->height) / 4; i++) {
203     if (*ptr) {
204       *ptr -= ((*ptr & 0xf0f0f0f0ul) >> 4) + ((*ptr & 0xe0e0e0e0ul) >> 5);
205       ptr++;
206     } else {
207       ptr++;
208     }
209   }
210
211 /*  GST_DEBUG ("drawing"); */
212 /*  GST_DEBUG ("gdk_draw_indexed_image(%p,%p,%d,%d,%d,%d,%s,%p,%d,%p);",
213         smoothwave->image->window,
214         smoothwave->image->style->fg_gc[GTK_STATE_NORMAL],
215         0,0,smoothwave->width,smoothwave->height,
216         "GDK_RGB_DITHER_NORMAL",
217         smoothwave->imagebuffer,smoothwave->width,
218         smoothwave->cmap);*/
219 /*  gdk_draw_indexed_image(smoothwave->image->window,
220         smoothwave->image->style->fg_gc[GTK_STATE_NORMAL],
221         0,0,smoothwave->width,smoothwave->height,
222         GDK_RGB_DITHER_NONE,
223         smoothwave->imagebuffer,smoothwave->width,
224         smoothwave->cmap);*/
225   gdk_draw_gray_image (smoothwave->image->window,
226       smoothwave->image->style->fg_gc[GTK_STATE_NORMAL],
227       0, 0, smoothwave->width, smoothwave->height,
228       GDK_RGB_DITHER_NORMAL, smoothwave->imagebuffer, smoothwave->width);
229
230 /*  gst_trace_add_entry(NULL,0,buf,"smoothwave: calculated smoothwave"); */
231
232   gst_buffer_unref (buf);
233 }
234
235 static void
236 gst_smoothwave_set_property (GObject * object, guint prop_id,
237     const GValue * value, GParamSpec * pspec)
238 {
239   GstSmoothWave *smoothwave;
240
241   /* it's not null if we got it, but it might not be ours */
242   g_return_if_fail (GST_IS_SMOOTHWAVE (object));
243   smoothwave = GST_SMOOTHWAVE (object);
244
245   switch (prop_id) {
246     case ARG_WIDTH:
247       smoothwave->width = g_value_get_int (value);
248       gtk_drawing_area_size (GTK_DRAWING_AREA (smoothwave->image),
249           smoothwave->width, smoothwave->height);
250       gtk_widget_set_usize (GTK_WIDGET (smoothwave->image),
251           smoothwave->width, smoothwave->height);
252       break;
253     case ARG_HEIGHT:
254       smoothwave->height = g_value_get_int (value);
255       gtk_drawing_area_size (GTK_DRAWING_AREA (smoothwave->image),
256           smoothwave->width, smoothwave->height);
257       gtk_widget_set_usize (GTK_WIDGET (smoothwave->image),
258           smoothwave->width, smoothwave->height);
259       break;
260     default:
261       break;
262   }
263 }
264
265 static void
266 gst_smoothwave_get_property (GObject * object, guint prop_id, GValue * value,
267     GParamSpec * pspec)
268 {
269   GstSmoothWave *smoothwave;
270
271   /* it's not null if we got it, but it might not be ours */
272   smoothwave = GST_SMOOTHWAVE (object);
273
274   switch (prop_id) {
275     case ARG_WIDTH:{
276       g_value_set_int (value, smoothwave->width);
277       break;
278     }
279     case ARG_HEIGHT:{
280       g_value_set_int (value, smoothwave->height);
281       break;
282     }
283     case ARG_WIDGET:{
284       g_value_set_object (value, smoothwave->image);
285       break;
286     }
287     default:{
288       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
289       break;
290     }
291   }
292 }
293
294
295
296 static gboolean
297 plugin_init (GstPlugin * plugin)
298 {
299   if (!gst_element_register (plugin, "smoothwave", GST_RANK_NONE,
300           GST_TYPE_SMOOTHWAVE))
301     return FALSE;
302
303   return TRUE;
304 }
305
306 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
307     GST_VERSION_MINOR,
308     "smoothwave",
309     "Fading greyscale waveform display",
310     plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)