summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2001-12-22 23:27:31 +0000
committerAndy Wingo <wingo@pobox.com>2001-12-22 23:27:31 +0000
commit185612aae3b8acae2b32e0e6561691a7c640cd0d (patch)
tree7cd1990c3df5c63f402f3e0bdf6b51b3ed58fc41 /gst
parent87dab192cf5792f847a22e0c3e9afe78553739b5 (diff)
Initial revision
Original commit message from CVS: Initial revision
Diffstat (limited to 'gst')
-rw-r--r--gst/cutter/Makefile.am9
-rw-r--r--gst/cutter/README38
-rw-r--r--gst/cutter/filter.func16
-rw-r--r--gst/cutter/gstcutter.c419
-rw-r--r--gst/cutter/gstcutter.h84
-rw-r--r--gst/flx/Makefile.am9
-rw-r--r--gst/flx/flx_color.c94
-rw-r--r--gst/flx/flx_color.h43
-rw-r--r--gst/flx/flx_fmt.h136
-rw-r--r--gst/flx/gstflxdec.c644
-rw-r--r--gst/flx/gstflxdec.h79
-rw-r--r--gst/law/Makefile.am12
-rw-r--r--gst/law/alaw-conversion.c195
-rw-r--r--gst/law/alaw-conversion.h12
-rw-r--r--gst/law/alaw-decode.c186
-rw-r--r--gst/law/alaw-decode.h69
-rw-r--r--gst/law/alaw-encode.c182
-rw-r--r--gst/law/alaw-encode.h69
-rw-r--r--gst/law/alaw.c95
-rw-r--r--gst/law/mulaw-conversion.c102
-rw-r--r--gst/law/mulaw-conversion.h10
-rw-r--r--gst/law/mulaw-decode.c181
-rw-r--r--gst/law/mulaw-decode.h69
-rw-r--r--gst/law/mulaw-encode.c181
-rw-r--r--gst/law/mulaw-encode.h69
-rw-r--r--gst/law/mulaw.c103
-rw-r--r--gst/level/Makefile.am10
-rw-r--r--gst/level/README11
-rw-r--r--gst/level/filter.func45
-rw-r--r--gst/level/gstlevel.c285
-rw-r--r--gst/level/gstlevel.h69
-rw-r--r--gst/median/.gitignore7
-rw-r--r--gst/median/Makefile.am9
-rw-r--r--gst/median/gstmedian.c412
-rw-r--r--gst/median/gstmedian.h72
-rw-r--r--gst/spectrum/.gitignore7
-rw-r--r--gst/spectrum/Makefile.am10
-rw-r--r--gst/spectrum/README5
-rw-r--r--gst/spectrum/gstspectrum.c242
-rw-r--r--gst/spectrum/gstspectrum.h67
-rw-r--r--gst/udp/.gitignore7
-rw-r--r--gst/udp/Makefile.am10
-rw-r--r--gst/udp/README28
-rw-r--r--gst/udp/gstudp.c52
-rw-r--r--gst/udp/gstudpsink.c301
-rw-r--r--gst/udp/gstudpsink.h91
-rw-r--r--gst/udp/gstudpsrc.c300
-rw-r--r--gst/udp/gstudpsrc.h88
-rw-r--r--gst/wavparse/.gitignore7
-rw-r--r--gst/wavparse/Makefile.am8
-rw-r--r--gst/wavparse/gstriff.c144
-rw-r--r--gst/wavparse/gstriff.h67
-rw-r--r--gst/wavparse/gstwavparse.c367
-rw-r--r--gst/wavparse/gstwavparse.h99
54 files changed, 5926 insertions, 0 deletions
diff --git a/gst/cutter/Makefile.am b/gst/cutter/Makefile.am
new file mode 100644
index 00000000..d31d6f12
--- /dev/null
+++ b/gst/cutter/Makefile.am
@@ -0,0 +1,9 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstcutter.la
+
+libgstcutter_la_SOURCES = gstcutter.c
+
+noinst_HEADERS = gstcutter.h filter.func
+
+EXTRA_DIST = README
diff --git a/gst/cutter/README b/gst/cutter/README
new file mode 100644
index 00000000..fc0975e3
--- /dev/null
+++ b/gst/cutter/README
@@ -0,0 +1,38 @@
+cutter plugin by thomas <thomas@apestaart.org>
+
+SYNOPSIS
+
+This plugin emits signals when RMS level of audio signal crosses a
+threshold for a given amount of time.
+
+As soon as the buffer's RMS is greater than the threshold value, the plugin fires a CUT_START signal.
+
+When the buffer's RMS level drops below the threshold value for a consecutive run length longer than the given runlength, it sends a CUT_STOP signal.
+
+When a pre-recording buffer is used, the plugin will delay throughput of data when it's in "silent" mode for a maximum length equal to the pre-recording buffer length. As soon as the input level crosses the threshold level, this pre-recorded buffer is flushed to the src pad (so you can actually record the audio just before the threshold crossing) after sending the signal.
+
+ARGUMENTS
+
+GstCutter::threshold
+ level (between 0 and 1) of threshold
+GstCutter::threshold_dB
+ level of threshold in dB (between -inf and 0)
+GstCutter::runlength
+ minimum length (in seconds) before plugin sends cut_stop signal
+GstCutter::prelength
+ length of pre-recording buffer
+
+SIGNALS
+
+ CUT_START
+ gets sent when the level of the signal goes above threshold level
+ CUT_STOP
+ gets sent when the level of the signal has been below the
+ threshold level for a number of consecutive iterations of which
+ the cumulative length is more than the runlength
+
+LIMITATIONS
+
+ * RMS value is calculated over the whole data buffer, so
+ the time resolution is limited to the buffer length
+ * RMS value is calculated over all of the channels combined
diff --git a/gst/cutter/filter.func b/gst/cutter/filter.func
new file mode 100644
index 00000000..bdbe5663
--- /dev/null
+++ b/gst/cutter/filter.func
@@ -0,0 +1,16 @@
+{
+ guint j;
+ register double squaresum = 0.0;
+
+ /*
+ * process data here
+ * input sample data enters in *in_data as 8 or 16 bit data
+ * samples for left and right channel are interleaved
+ */
+
+ for (j = 0; j < num_samples; j++)
+ squaresum += data[j] * data[j];
+
+ return (squaresum / (float) num_samples);
+}
+
diff --git a/gst/cutter/gstcutter.c b/gst/cutter/gstcutter.c
new file mode 100644
index 00000000..8161d506
--- /dev/null
+++ b/gst/cutter/gstcutter.c
@@ -0,0 +1,419 @@
+/* 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 <gst/gst.h>
+#include <libs/audio/gstaudio.h>
+#include "cutter.h"
+#include "math.h"
+
+
+static GstElementDetails cutter_details = {
+ "Cutter",
+ "Filter/Effect",
+ "Audio Cutter to split audio into non-silent bits",
+ VERSION,
+ "Thomas <thomas@apestaart.org>",
+ "(C) 2001",
+};
+
+
+/* Filter signals and args */
+enum {
+ /* FILL ME */
+ CUT_START,
+ CUT_STOP,
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+ ARG_THRESHOLD,
+ ARG_THRESHOLD_DB,
+ ARG_RUN_LENGTH,
+ ARG_PRE_LENGTH
+};
+
+GST_PADTEMPLATE_FACTORY (cutter_src_factory,
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "test_src",
+ "audio/raw",
+ "channels", GST_PROPS_INT_RANGE (1, 2)
+ )
+);
+
+GST_PADTEMPLATE_FACTORY (cutter_sink_factory,
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "test_src",
+ "audio/raw",
+ "channels", GST_PROPS_INT_RANGE (1, 2)
+ )
+);
+
+static void gst_cutter_class_init (GstCutterClass *klass);
+static void gst_cutter_init (GstCutter *filter);
+
+static void gst_cutter_set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec);
+static void gst_cutter_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec);
+
+static void gst_cutter_chain (GstPad *pad, GstBuffer *buf);
+static double inline gst_cutter_16bit_ms (gint16* data, guint numsamples);
+static double inline gst_cutter_8bit_ms (gint8* data, guint numsamples);
+
+void gst_cutter_get_caps (GstPad *pad, GstCutter* filter);
+
+static GstElementClass *parent_class = NULL;
+static guint gst_cutter_signals[LAST_SIGNAL] = { 0 };
+
+static GstPadNegotiateReturn
+cutter_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
+{
+ GstCutter* filter = GST_CUTTER (gst_pad_get_parent (pad));
+
+ if (*caps==NULL)
+ return GST_PAD_NEGOTIATE_FAIL;
+
+ return gst_pad_negotiate_proxy(pad,filter->sinkpad,caps);
+}
+
+static GstPadNegotiateReturn
+cutter_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
+{
+ GstCutter* filter = GST_CUTTER (gst_pad_get_parent (pad));
+
+ if (*caps==NULL)
+ return GST_PAD_NEGOTIATE_FAIL;
+
+ return gst_pad_negotiate_proxy(pad,filter->srcpad,caps);
+}
+
+GType
+gst_cutter_get_type(void) {
+ static GType cutter_type = 0;
+
+ if (!cutter_type) {
+ static const GTypeInfo cutter_info = {
+ sizeof(GstCutterClass), NULL, NULL, (GClassInitFunc)gst_cutter_class_init,
+ NULL,
+ NULL,
+ sizeof(GstCutter),
+ 0,
+ (GInstanceInitFunc)gst_cutter_init,
+ };
+ cutter_type = g_type_register_static(GST_TYPE_ELEMENT, "GstCutter", &cutter_info, 0);
+ }
+ return cutter_type;
+}
+
+static void
+gst_cutter_class_init (GstCutterClass *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_THRESHOLD,
+ g_param_spec_double ("threshold", "threshold", "threshold",
+ G_MINDOUBLE, G_MAXDOUBLE, 0, G_PARAM_READWRITE)); // CHECKME
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_THRESHOLD_DB,
+ g_param_spec_double ("threshold_dB", "threshold_dB", "threshold_dB",
+ G_MINDOUBLE, G_MAXDOUBLE, 0, G_PARAM_READWRITE)); // CHECKME
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_RUN_LENGTH,
+ g_param_spec_double ("runlength", "runlength", "runlength",
+ G_MINDOUBLE, G_MAXDOUBLE, 0, G_PARAM_READWRITE)); // CHECKME
+
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PRE_LENGTH,
+ g_param_spec_double ("prelength", "prelength", "prelength",
+ G_MINDOUBLE, G_MAXDOUBLE, 0, G_PARAM_READWRITE)); // CHECKME
+ gst_cutter_signals[CUT_START] =
+ g_signal_new ("cut_start", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GstCutterClass, cut_start), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+ gst_cutter_signals[CUT_STOP] =
+ g_signal_new ("cut_stop", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GstCutterClass, cut_stop), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+
+ gobject_class->set_property = gst_cutter_set_property;
+ gobject_class->get_property = gst_cutter_get_property;
+}
+
+static void
+gst_cutter_init (GstCutter *filter)
+{
+ filter->sinkpad = gst_pad_new_from_template (cutter_sink_factory (),"sink");
+ filter->srcpad = gst_pad_new_from_template (cutter_src_factory (),"src");
+
+ filter->threshold_level = 0.1;
+ filter->threshold_length = 0.5;
+ filter->silent_run_length = 0.0;
+ filter->silent = TRUE;
+
+ filter->pre_length = 0.2;
+ filter->pre_run_length = 0.0;
+ filter->pre_buffer = NULL;
+
+ gst_pad_set_negotiate_function (filter->sinkpad,cutter_negotiate_sink);
+ gst_pad_set_negotiate_function (filter->srcpad,cutter_negotiate_src);
+
+ gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
+ gst_pad_set_chain_function (filter->sinkpad, gst_cutter_chain);
+ filter->srcpad = gst_pad_new ("src", GST_PAD_SRC);
+ gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
+}
+
+static void
+gst_cutter_chain (GstPad *pad, GstBuffer *buf)
+{
+ GstCutter *filter;
+ gint16 *in_data;
+ double RMS = 0.0; /* RMS of signal in buffer */
+ double ms = 0.0; /* mean square value of buffer */
+ static gboolean silent_prev = FALSE; /* previous value of silent */
+ GstBuffer* prebuf; /* pointer to a prebuffer element */
+
+ g_return_if_fail (pad != NULL);
+ g_return_if_fail (GST_IS_PAD (pad));
+ g_return_if_fail (buf != NULL);
+
+ filter = GST_CUTTER (GST_OBJECT_PARENT (pad));
+ g_return_if_fail (filter != NULL);
+ g_return_if_fail (GST_IS_CUTTER (filter));
+
+ g_return_if_fail (gst_audio_is_buffer_framed (pad, buf) == TRUE);
+
+ if (!filter->have_caps) gst_cutter_get_caps (pad, filter);
+
+ in_data = (gint16 *) GST_BUFFER_DATA (buf);
+ g_print ("DEBUG: cutter: length of prerec buffer: %.3f sec\n",
+ filter->pre_run_length);
+
+ /* calculate mean square value on buffer */
+ switch (filter->width)
+ {
+ case 16:
+ ms = gst_cutter_16bit_ms (in_data, GST_BUFFER_SIZE (buf) / 2);
+ break;
+ case 8:
+ ms = gst_cutter_8bit_ms ((gint8 *) in_data, GST_BUFFER_SIZE (buf));
+ break;
+ default:
+ /* this shouldn't happen */
+ g_print ("WARNING: no mean square function for width %d\n",
+ filter->width);
+ break;
+ }
+
+ silent_prev = filter->silent;
+
+ RMS = sqrt (ms) / (double) filter->max_sample;
+ /* if RMS below threshold, add buffer length to silent run length count
+ * if not, reset
+ */
+ //g_print ("DEBUG: cutter: ms %f, RMS %f\n", ms, RMS);
+ if (RMS < filter->threshold_level)
+ filter->silent_run_length += gst_audio_length (filter->srcpad, buf);
+ else
+ {
+ filter->silent_run_length = 0.0;
+ filter->silent = FALSE;
+ }
+
+ if (filter->silent_run_length > filter->threshold_length)
+ /* it has been silent long enough, flag it */
+ filter->silent = TRUE;
+
+ /* has the silent status changed ? if so, send right signal
+ * and, if from silent -> not silent, flush pre_record buffer
+ */
+ if (filter->silent != silent_prev)
+ {
+ if (filter->silent)
+ {
+// g_print ("DEBUG: cutter: cut to here, turning off out\n");
+ gtk_signal_emit (G_OBJECT (filter), gst_cutter_signals[CUT_STOP]);
+ }
+ else
+ {
+// g_print ("DEBUG: cutter: start from here, turning on out\n");
+ /* first of all, flush current buffer */
+ gtk_signal_emit (G_OBJECT (filter), gst_cutter_signals[CUT_START]);
+ g_print ("DEBUG: cutter: flushing buffer ");
+ while (filter->pre_buffer)
+ {
+ g_print (".");
+ prebuf = (g_list_first (filter->pre_buffer))->data;
+ filter->pre_buffer = g_list_remove (filter->pre_buffer, prebuf);
+ gst_pad_push (filter->srcpad, prebuf);
+ filter->pre_run_length = 0.0;
+ }
+ g_print ("\n");
+ }
+ }
+ /* now check if we have to add the new buffer to the cache or to the pad */
+ if (filter->silent)
+ {
+ filter->pre_buffer = g_list_append (filter->pre_buffer, buf);
+ filter->pre_run_length += gst_audio_length (filter->srcpad, buf);
+ while (filter->pre_run_length > filter->pre_length)
+ {
+ prebuf = (g_list_first (filter->pre_buffer))->data;
+ filter->pre_buffer = g_list_remove (filter->pre_buffer, prebuf);
+ gst_pad_push (filter->srcpad, prebuf);
+ filter->pre_run_length -= gst_audio_length (filter->srcpad, prebuf);
+ }
+ }
+ else
+ gst_pad_push (filter->srcpad, buf);
+}
+
+static double inline
+gst_cutter_16bit_ms (gint16* data, guint num_samples)
+#include "filter.func"
+
+static double inline
+gst_cutter_8bit_ms (gint8* data, guint num_samples)
+#include "filter.func"
+
+static void
+gst_cutter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstCutter *filter;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_CUTTER (object));
+ filter = GST_CUTTER (object);
+
+ switch (prop_id)
+ {
+ case ARG_THRESHOLD:
+ /* set the level */
+ filter->threshold_level = g_value_get_double (value);
+ g_print ("DEBUG: cutter: set threshold level to %f\n",
+ filter->threshold_level);
+ break;
+ case ARG_THRESHOLD_DB:
+ /* set the level given in dB
+ * value in dB = 20 * log (value)
+ * values in dB < 0 result in values between 0 and 1
+ */
+ filter->threshold_level = pow (10, g_value_get_double (value) / 20);
+ g_print ("DEBUG: cutter: set threshold level to %f\n",
+ filter->threshold_level);
+ break;
+ case ARG_RUN_LENGTH:
+ /* set the minimum length of the silent run required */
+ filter->threshold_length = g_value_get_double (value);
+ break;
+ case ARG_PRE_LENGTH:
+ /* set the length of the pre-record block */
+ filter->pre_length = g_value_get_double (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_cutter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstCutter *filter;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail (GST_IS_CUTTER(object));
+ filter = GST_CUTTER (object);
+
+ switch (prop_id)
+ {
+ case ARG_RUN_LENGTH:
+ g_value_set_double (value, filter->threshold_length);
+ break;
+ case ARG_THRESHOLD:
+ g_value_set_double (value, filter->threshold_level);
+ break;
+ case ARG_THRESHOLD_DB:
+ g_value_set_double (value, 20 * log (filter->threshold_level));
+ break;
+ case ARG_PRE_LENGTH:
+ g_value_set_double (value, filter->pre_length);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+ GstElementFactory *factory;
+
+ factory = gst_elementfactory_new("cutter",GST_TYPE_CUTTER,
+ &cutter_details);
+ g_return_val_if_fail(factory != NULL, FALSE);
+
+ gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (cutter_src_factory));
+ gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (cutter_sink_factory));
+
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+ /* load audio support library */
+ if (!gst_library_load ("gstaudio"))
+ {
+ gst_info ("cutter: could not load support library: 'gstaudio'\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+GstPluginDesc plugin_desc =
+{
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "cutter",
+ plugin_init
+};
+
+void
+gst_cutter_get_caps (GstPad *pad, GstCutter* filter)
+{
+ GstCaps *caps = NULL;
+
+ caps = GST_PAD_CAPS (pad);
+ // FIXME : Please change this to a better warning method !
+ if (caps == NULL)
+ printf ("WARNING: cutter: get_caps: Could not get caps of pad !\n");
+ filter->width = gst_caps_get_int (caps, "width");
+ filter->max_sample = gst_audio_highest_sample_value (pad);
+ filter->have_caps = TRUE;
+}
diff --git a/gst/cutter/gstcutter.h b/gst/cutter/gstcutter.h
new file mode 100644
index 00000000..18de8787
--- /dev/null
+++ b/gst/cutter/gstcutter.h
@@ -0,0 +1,84 @@
+/* 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_CUTTER_H__
+#define __GST_CUTTER_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+// #include <gst/meta/audioraw.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GST_TYPE_CUTTER \
+ (gst_cutter_get_type())
+#define GST_CUTTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CUTTER,GstCutter))
+#define GST_CUTTER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstCutter))
+#define GST_IS_CUTTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CUTTER))
+#define GST_IS_CUTTER_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CUTTER))
+
+typedef struct _GstCutter GstCutter;
+typedef struct _GstCutterClass GstCutterClass;
+
+struct _GstCutter
+{
+ GstElement element;
+
+ GstPad *sinkpad, *srcpad;
+
+ double threshold_level; /* level below which to cut */
+ double threshold_length; /* how long signal has to remain
+ * below this level before cutting
+ */
+ double silent_run_length; /* how long has it been below threshold ? */
+ gboolean silent;
+
+ double pre_length; /* how long can the pre-record buffer be ? */
+ double pre_run_length; /* how long is it currently ? */
+ GList *pre_buffer;
+
+ gboolean have_caps; /* did we get the needed caps yet ? */
+ gint width; /* bit width of data */
+ long max_sample; /* maximum sample value */
+};
+
+struct _GstCutterClass {
+ GstElementClass parent_class;
+ void (*cut_start) (GstCutter* filter);
+ void (*cut_stop) (GstCutter* filter);
+};
+
+GType gst_cutter_get_type(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_STEREO_H__ */
diff --git a/gst/flx/Makefile.am b/gst/flx/Makefile.am
new file mode 100644
index 00000000..79a6fba7
--- /dev/null
+++ b/gst/flx/Makefile.am
@@ -0,0 +1,9 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstflxdec.la
+
+libgstflxdec_la_SOURCES = gstflxdec.c flx_color.c
+libgstflxdec_la_CFLAGS = $(GST_CFLAGS)
+
+noinst_HEADERS = flx_fmt.h flx_color.h gstflxdec.h
+
diff --git a/gst/flx/flx_color.c b/gst/flx/flx_color.c
new file mode 100644
index 00000000..c61052d0
--- /dev/null
+++ b/gst/flx/flx_color.c
@@ -0,0 +1,94 @@
+/* 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 <gst/gst.h>
+
+
+#include "flx_color.h"
+
+FlxColorSpaceConverter *
+flx_colorspace_converter_new(gint width, gint height)
+{
+ FlxColorSpaceConverter *new = g_malloc(sizeof(FlxColorSpaceConverter));
+
+ new->width = width;
+ new->height = height;
+
+ memset(new->palvec, 0, sizeof(new->palvec));
+ return new;
+}
+
+void
+flx_colorspace_converter_destroy(FlxColorSpaceConverter *flxpal)
+{
+ g_return_if_fail(flxpal != NULL);
+
+ g_free(flxpal);
+}
+
+void
+flx_colorspace_convert(FlxColorSpaceConverter *flxpal, guchar *src, guchar *dest)
+{
+ guint size, col;
+
+ g_return_if_fail(flxpal != NULL);
+ g_return_if_fail(src != dest);
+
+
+ size = flxpal->width * flxpal->height;
+
+ while(size--) {
+ col = (*src++ * 3);
+ *dest++ = flxpal->palvec[col+2];
+ *dest++ = flxpal->palvec[col+1];
+ *dest++ = flxpal->palvec[col];
+ *dest++ = 0;
+ }
+
+}
+
+
+void
+flx_set_palette_vector(FlxColorSpaceConverter *flxpal, guint start, guint num, guchar *newpal)
+{
+ guint grab;
+
+ g_return_if_fail(flxpal != NULL);
+ g_return_if_fail(start < 0x100);
+
+ grab = ((start + num) > 0x100 ? 0x100 - start : num);
+
+ memcpy(&flxpal->palvec[start * 3], newpal, grab*3);
+
+}
+
+void
+flx_set_color(FlxColorSpaceConverter *flxpal, guint colr, guint red, guint green, guint blue)
+{
+
+ g_return_if_fail(flxpal != NULL);
+ g_return_if_fail(colr < 0x100);
+
+ flxpal->palvec[(colr * 3)] = red;
+ flxpal->palvec[(colr * 3) + 1] = green;
+ flxpal->palvec[(colr * 3) + 2] = blue;
+}
+
+
diff --git a/gst/flx/flx_color.h b/gst/flx/flx_color.h
new file mode 100644
index 00000000..5676c878
--- /dev/null
+++ b/gst/flx/flx_color.h
@@ -0,0 +1,43 @@
+/* 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.
+ */
+
+typedef enum {
+ FLX_COLORSPACE_RGB8,
+ FLX_COLORSPACE_RGB32,
+} FlxColorSpaceType;
+
+
+typedef struct _FlxColorSpaceConverter FlxColorSpaceConverter;
+
+struct _FlxColorSpaceConverter {
+ guint width;
+ guint height;
+ guchar palvec[768];
+};
+
+
+void flx_colorspace_converter_destroy(FlxColorSpaceConverter *flxpal);
+void flx_colorspace_convert(FlxColorSpaceConverter *flxpal, guchar *src, guchar *dest);
+FlxColorSpaceConverter * flx_colorspace_converter_new(gint width, gint height);
+
+void flx_set_palette_vector(FlxColorSpaceConverter *flxpal, guint start, guint num,
+ guchar *newpal);
+void flx_set_color(FlxColorSpaceConverter *flxpal, guint colr, guint red, guint green,
+ guint blue);
+
diff --git a/gst/flx/flx_fmt.h b/gst/flx/flx_fmt.h
new file mode 100644
index 00000000..5323de63
--- /dev/null
+++ b/gst/flx/flx_fmt.h
@@ -0,0 +1,136 @@
+/* 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_FLX_FMT__H__
+#define __GST_FLX_FMT_H__
+
+#include <gst/gst.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+enum Flx_TypeChunk
+{
+ /* frame chunks */
+ FLX_PREFIX_TYPE = 0xf100,
+ FLX_SCRIPT_CHUNK = 0xf1e0,
+ FLX_FRAME_TYPE = 0xf1fa,
+ FLX_SEGMENT_TABLE = 0xf1fb,
+ FLX_HUFFMAN_TABLE = 0xf1fc,
+
+ /* sub chunks */
+ FLX_CEL_DATA = 3,
+ FLX_COLOR256 = 4,
+ FLX_SS2 = 7,
+ FLX_COLOR64 = 11,
+ FLX_LC = 12,
+ FLX_BLACK = 13,
+ FLX_BRUN = 15,
+ FLX_COPY = 16,
+ FLX_MINI = 18,
+ FLX_DTA_RUN = 25,
+ FLX_DTA_COPY = 26,
+ FLX_DTA_LC = 27,
+ FLX_LABEL = 31,
+ FLX_BMP_MASK = 32,
+ FLX_MLEV_MASK = 33,
+ FLX_SEGMENT = 34,
+ FLX_KEY_IMAGE = 35,
+ FLX_KEY_PAL = 36,
+ FLX_REGION = 37,
+ FLX_WAVE = 38,
+ FLX_USERSTRING = 39,
+ FLX_RGN_MASK = 40,
+
+};
+
+enum Flx_MagicHdr
+{
+ FLX_MAGICHDR_FLI = 0xaf11,
+ FLX_MAGICHDR_FLC = 0xaf12,
+ FLX_MAGICHDR_FLX = 0xaf44,
+ FLX_MAGICHDR_HUFFBWT = 0xaf30,
+};
+
+
+
+typedef struct _FlxHeader
+{
+ guint32 size;
+ guint16 type;
+ guint16 frames;
+ guint16 width,height,depth,flags;
+ guint32 speed;
+ guint16 reserved1;
+ /* FLC */
+ guint32 created,creator,updated,updater;
+ guint16 aspect_dx, aspect_dy;
+ /* EGI */
+ guint16 ext_flags,keyframes,totalframes;
+ guint32 req_memory;
+ guint16 max_regions,transp_num;
+ guchar reserved2[24];
+ /* FLC */
+ guint32 oframe1,oframe2;
+ guchar reserved3[40];
+} FlxHeader;
+#define FlxHeaderSize 128
+
+typedef struct _FlxFrameChunk
+{
+ guint32 size;
+ guint16 id;
+} FlxFrameChunk;
+#define FlxFrameChunkSize 6
+
+typedef struct _FlxPrefixChunk
+{
+ guint16 chunks;
+ guchar reserved[8];
+} FlxPrefixChunk;
+
+typedef struct _FlxSegmentTable
+{
+ guint16 segments;
+} FlxSegmentTable;
+
+typedef struct _FlxHuffmanTable
+{
+ guint16 codelength;
+ guint16 numcodes;
+ guchar reserved[6];
+} FlxHuffmanTable;
+
+typedef struct _FlxFrameType
+{
+ guint16 chunks;
+ guint16 delay;
+ guchar reserved[6];
+} FlxFrameType;
+#define FlxFrameTypeSize 10
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_FLX_FMT_H__ */
diff --git a/gst/flx/gstflxdec.c b/gst/flx/gstflxdec.c
new file mode 100644
index 00000000..d6052bb6
--- /dev/null
+++ b/gst/flx/gstflxdec.c
@@ -0,0 +1,644 @@
+/* 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 "flx_fmt.h"
+#include "gstflxdec.h"
+
+static GstCaps* flxdec_typefind(GstBuffer *buf, gpointer private);
+
+/* flx element information */
+static GstElementDetails flxdec_details = {
+ "FLX Decoder",
+ "flxdec",
+ "FLX decoder",
+ VERSION,
+ "Sepp Wijnands <mrrazz@garbage-coderz.net>"
+ "(C) 2001",
+};
+
+static GstTypeDefinition flxdec_definition = {
+ "flxdec_video/fli",
+ "video/fli",
+ ".flc .fli",
+ flxdec_typefind,
+};
+
+/* Flx signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0
+};
+
+/* input */
+GST_PADTEMPLATE_FACTORY (sink_factory,
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "flxdec_sink",
+ "video/fli",
+ NULL
+ )
+)
+
+/* output */
+GST_PADTEMPLATE_FACTORY (src_video_factory,
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "src_video",
+ "video/raw",
+ "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R', 'G', 'B', ' ')),
+ "bpp", GST_PROPS_INT (32),
+ "depth", GST_PROPS_INT (32),
+ "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN),
+ "red_mask", GST_PROPS_INT (0x00ff0000),
+ "green_mask", GST_PROPS_INT (0x0000ff00),
+ "blue_mask", GST_PROPS_INT (0x000000ff),
+ "width", GST_PROPS_INT_RANGE(320, 1280),
+ "height", GST_PROPS_INT_RANGE(200, 1024)
+ )
+)
+
+
+static void gst_flxdec_class_init (GstFlxDecClass *klass);
+static void gst_flxdec_init (GstFlxDec *flxdec);
+
+static void gst_flxdec_loop (GstElement *element);
+
+static void gst_flxdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void gst_flxdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+
+static void flx_decode_color(GstFlxDec *, guchar *, guchar *);
+static void flx_decode_brun(GstFlxDec *, guchar *, guchar *);
+static void flx_decode_delta_fli(GstFlxDec *, guchar *, guchar *);
+static void flx_decode_delta_flc(GstFlxDec *, guchar *, guchar *);
+
+#define rndalign(off) ((off) + ((off) % 2))
+
+static GstElementClass *parent_class = NULL;
+
+static GstCaps*
+flxdec_typefind (GstBuffer *buf, gpointer private)
+{
+ guchar *data = GST_BUFFER_DATA(buf);
+ GstCaps *new;
+
+ // check magic
+ if ((data[4] == 0x11 || data[4] == 0x12
+ || data[4] == 0x30 || data[4] == 0x44) && data[5] == 0xaf) {
+ // check the frame type of the first frame
+ if ((data[132] == 0x00 || data[132] == 0xfa) && data[133] == 0xf1) {
+ g_print("GstFlxDec: found supported flx format\n");
+ new = gst_caps_new("flxdec_typefind","video/fli", NULL);
+ return new;
+ }
+ }
+
+ return NULL;
+}
+
+
+GType
+gst_flxdec_get_type(void)
+{
+ static GType flxdec_type = 0;
+
+ if (!flxdec_type) {
+ static const GTypeInfo flxdec_info = {
+ sizeof(GstFlxDecClass), NULL,
+ NULL,
+ (GClassInitFunc)gst_flxdec_class_init,
+ NULL,
+ NULL,
+ sizeof(GstFlxDec),
+ 0,
+ (GInstanceInitFunc)gst_flxdec_init,
+ };
+ flxdec_type = g_type_register_static(GST_TYPE_ELEMENT, "GstFlxDec", &flxdec_info, 0);
+ }
+ return flxdec_type;
+}
+
+static void
+gst_flxdec_class_init (GstFlxDecClass *klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+
+ gobject_class = (GObjectClass*)klass;
+ gstelement_class = (GstElementClass*)klass;
+
+ parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+
+ gobject_class->set_property = NULL;
+ gobject_class->get_property = NULL;
+
+}
+
+
+
+static void
+gst_flxdec_init(GstFlxDec *flxdec)
+{
+ flxdec->sinkpad = gst_pad_new_from_template (
+ GST_PADTEMPLATE_GET (sink_factory), "sink");
+ gst_element_add_pad(GST_ELEMENT(flxdec),flxdec->sinkpad);
+ gst_element_set_loop_function(GST_ELEMENT(flxdec),gst_flxdec_loop);
+
+ flxdec->srcpad = gst_pad_new_from_template (
+ GST_PADTEMPLATE_GET (src_video_factory), "src");
+ gst_element_add_pad(GST_ELEMENT(flxdec),flxdec->srcpad);
+
+ flxdec->buf = NULL;
+ flxdec->offset = 0;
+ flxdec->new_buf = TRUE;
+
+}
+
+static void
+flx_decode_chunks (GstFlxDec *flxdec , gulong count, gchar *data, gchar *dest)
+{
+ FlxFrameChunk *hdr;
+
+ g_return_if_fail(data != NULL);
+
+ while (count--) {
+ hdr = (FlxFrameChunk *) data;
+ data += FlxFrameChunkSize;
+
+ switch(hdr->id)
+ {
+ case FLX_COLOR64:
+ case FLX_COLOR256:
+ flx_decode_color(flxdec, data, dest);
+ data += rndalign(hdr->size) - FlxFrameChunkSize;
+ break;
+
+ case FLX_BRUN:
+ flx_decode_brun(flxdec, data, dest);
+ data += rndalign(hdr->size) - FlxFrameChunkSize;
+ break;
+
+ case FLX_LC:
+ flx_decode_delta_fli(flxdec, data, dest);
+ data += rndalign(hdr->size) - FlxFrameChunkSize;
+ break;
+
+ case FLX_SS2:
+ flx_decode_delta_flc(flxdec, data, dest);
+ data += rndalign(hdr->size) - FlxFrameChunkSize;
+ break;
+
+ case FLX_BLACK:
+ memset(dest, 0, flxdec->size);
+ break;
+
+ case FLX_MINI:
+ data += rndalign(hdr->size) - FlxFrameChunkSize;
+ break;
+
+ default:
+ g_print("GstFlxDec: Unimplented chunk type: 0x%02x size: %d\n",
+ hdr->id, hdr->size);
+ g_print("GstFlxDec: Skipping...\n");
+ data += rndalign(hdr->size) - FlxFrameChunkSize;
+ break;
+ }
+ }
+}
+
+
+static void
+flx_decode_color(GstFlxDec *flxdec, guchar *data, guchar *dest)
+{
+ guint packs, count, indx;
+
+ g_return_if_fail(flxdec != NULL);
+
+ packs = (data[0] + (data[1] << 8));
+
+ data += 2;
+ indx = 0;
+
+ g_print("GstFlxDec: cmap packs: %d\n", packs);
+ while (packs--) {
+ /* color map index + skip count */
+ indx += *data++;
+
+ /* number of rgb triplets */
+ count = *data++ & 0xff;
+ if (count == 0)
+ count = 256;
+
+ g_print("GstFlxDec: cmap count: %d (indx: %d)\n", count, indx);
+ flx_set_palette_vector(flxdec->converter, indx, count, data);
+
+ data += (count * 3);
+ }
+}
+
+static void
+flx_decode_brun(GstFlxDec *flxdec, guchar *data, guchar *dest)
+{
+ gulong count, lines, row;
+ guchar x;
+
+ g_return_if_fail(flxdec != NULL);
+
+ lines = flxdec->hdr.height;
+ while(lines--) {
+ /* packet count.
+ * should not be used anymore, since the flc format can
+ * contain more then 255 RLE packets. we use the frame
+ * width instead.
+ */
+ data++;
+
+ row = flxdec->hdr.width;
+ while(row) {
+ count = *data++;
+
+ if (count > 0x7f) {
+ /* literal run */
+ count = 0x100 - count;
+ row -= count;
+
+ while(count--)
+ *dest++ = *data++;
+
+ } else {
+ /* replicate run */
+ row -= count;
+ x = *data++;
+
+ while(count--)
+ *dest++ = x;
+ }
+ }
+ }
+}
+
+static void
+flx_decode_delta_fli(GstFlxDec *flxdec, guchar *data, guchar *dest)
+{
+ gulong count, packets, lines, start_line, start_l;
+ guchar *start_p, x;
+
+ g_return_if_fail(flxdec != NULL);
+ g_return_if_fail(flxdec->delta != NULL);
+
+
+ /* use last frame for delta */
+ memcpy(dest, GST_BUFFER_DATA(flxdec->delta),
+ GST_BUFFER_SIZE(flxdec->delta));
+
+ start_line = (data[0] + (data[1] << 8));
+ lines = (data[2] + (data[3] << 8));
+ data += 4;
+
+ /* start position of delta */
+ dest += (flxdec->hdr.width * start_line);
+ start_p = dest;
+ start_l = lines;
+
+ while(lines--) {
+ /* packet count */
+ packets = *data++;
+
+ dest = start_p + (flxdec->hdr.width * (start_l - lines));
+
+ while(packets--) {
+ /* skip count */
+ dest += *data++;
+
+ /* RLE count */
+ count = *data++;
+
+ if (count > 0x7f) {
+ /* literal run */
+ count = 0x100 - count;
+ x = *data++;
+
+ while (count--)
+ *dest++ = x;
+
+ } else {
+ /* replicate run */
+ while (count--)
+ *dest++ = *data++;
+ }
+ }
+ }
+}
+
+static void
+flx_decode_delta_flc(GstFlxDec *flxdec, guchar *data, guchar *dest)
+{
+ gulong count, lines, start_l, opcode;
+ guchar *start_p;
+
+ g_return_if_fail(flxdec != NULL);
+ g_return_if_fail(flxdec->delta != NULL);
+
+
+ /* use last frame for delta */
+ memcpy(dest, GST_BUFFER_DATA(flxdec->delta),
+ GST_BUFFER_SIZE(flxdec->delta));
+
+ lines = (data[0] + (data[1] << 8));
+ data += 2;
+
+ start_p = dest;
+ start_l = lines;
+
+ while(lines--) {
+ dest = start_p + (flxdec->hdr.width * (start_l - lines));
+
+ /* process opcode(s) */
+ while ((opcode = (data[0] + (data[1] << 8))) & 0xc000) {
+ data += 2;
+ if ((opcode & 0xc000) == 0xc000) {
+ /* skip count */
+ start_l += (0x10000 - opcode);
+ dest += flxdec->hdr.width * (0x10000 - opcode);
+ } else {
+ /* last pixel */
+ dest += flxdec->hdr.width;
+ *dest++ = (opcode & 0xff);
+ }
+ }
+ data += 2;
+
+ /* last opcode is the packet count */
+ while(opcode--) {
+ /* skip count */
+ dest += *data++;
+
+ /* RLE count */
+ count = *data++;
+
+ if (count > 0x7f) {
+ /* replicate word run */
+ count = 0x100 - count;
+ while (count--) {
+ *dest++ = data[0];
+ *dest++ = data[1];
+ }
+ data += 2;
+ } else {
+ /* literal word run */
+ while (count--) {
+ *dest++ = *data++;
+ *dest++ = *data++;
+ }
+ }
+ }
+ }
+}
+
+static GstBuffer*
+flx_get_data(GstFlxDec *flxdec, gulong size)
+{
+ GstBuffer *retbuf;
+
+ g_return_val_if_fail (flxdec != NULL, NULL);
+
+ if (flxdec->new_buf) {
+ retbuf = gst_pad_pullregion(flxdec->sinkpad,
+ GST_REGION_OFFSET_LEN, 0, size);
+ flxdec->new_buf = FALSE;
+ flxdec->offset = size;
+ } else {
+ retbuf = gst_pad_pullregion(flxdec->sinkpad, GST_REGION_OFFSET_LEN,
+ flxdec->offset, size);
+ flxdec->offset += size;
+ }
+
+ return retbuf;
+}
+
+
+static void
+gst_flxdec_loop (GstElement *element)
+{
+ GstBuffer *buf;
+ GstBuffer *databuf;
+ guchar *data, *chunk;
+
+ GstFlxDec *flxdec;
+ FlxHeader *flxh;
+ FlxFrameChunk *flxfh;
+
+ g_return_if_fail (element != NULL);
+ g_return_if_fail (GST_IS_FLXDEC(element));
+
+ GST_DEBUG (0, "entering loop function\n");
+
+ flxdec = GST_FLXDEC(element);
+
+ databuf = flx_get_data(flxdec, FlxHeaderSize);
+
+ g_return_if_fail (databuf != NULL);
+
+ data = GST_BUFFER_DATA(databuf);
+
+ memcpy((char *) &flxdec->hdr, data, sizeof(FlxHeader));
+
+ gst_buffer_unref (databuf);
+
+ flxh = &flxdec->hdr;
+
+ // check header
+ if (flxh->type != FLX_MAGICHDR_FLI &&
+ flxh->type != FLX_MAGICHDR_FLC &&
+ flxh->type != FLX_MAGICHDR_FLX)
+ return;
+
+
+ g_print("GstFlxDec: size : %d\n", flxh->size);
+ g_print("GstFlxDec: frames : %d\n", flxh->frames);
+ g_print("GstFlxDec: width : %d\n", flxh->width);
+ g_print("GstFlxDec: height : %d\n", flxh->height);
+ g_print("GstFlxDec: depth : %d\n", flxh->depth);
+ g_print("GstFlxDec: speed : %d\n", flxh->speed);
+
+ gst_pad_set_caps (flxdec->srcpad,
+ gst_caps_new (
+ "src_video",
+ "video/raw",
+ gst_props_new (
+ "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R', 'G', 'B', ' ')),
+ "bpp", GST_PROPS_INT (32),
+ "depth", GST_PROPS_INT (32),
+ "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN),
+ "red_mask", GST_PROPS_INT (0x00ff0000),
+ "green_mask", GST_PROPS_INT (0x0000ff00),
+ "blue_mask", GST_PROPS_INT (0x000000ff),
+ "width", GST_PROPS_INT (flxh->width),
+ "height", GST_PROPS_INT (flxh->height),
+ NULL)));
+
+ if (flxh->depth <= 8)
+ flxdec->converter = flx_colorspace_converter_new(flxh->width, flxh->height);
+
+ if (flxh->type == FLX_MAGICHDR_FLC ||
+ flxh->type == FLX_MAGICHDR_FLX) {
+ g_print("GstFlxDec: (FLC) aspect_dx : %d\n",
+ flxh->aspect_dx);
+ g_print("GstFlxDec: (FLC) aspect_dy : %d\n",
+ flxh->aspect_dy);
+ g_print("GstFlxDec: (FLC) oframe1 : 0x%08x\n",
+ flxh->oframe1);
+ g_print("GstFlxDec: (FLC) oframe2 : 0x%08x\n",
+ flxh->oframe2);
+ }
+
+
+ flxdec->size = (flxh->width * flxh->height);
+
+ // create delta and output frame
+ flxdec->frame = gst_buffer_new();
+ flxdec->delta = gst_buffer_new();
+ GST_BUFFER_DATA(flxdec->frame) = g_malloc(flxdec->size);
+ GST_BUFFER_SIZE(flxdec->frame) = flxdec->size;
+ GST_BUFFER_DATA(flxdec->delta) = g_malloc(flxdec->size);
+ GST_BUFFER_SIZE(flxdec->delta) = flxdec->size;
+
+ do
+ {
+
+ databuf = flx_get_data(flxdec, FlxFrameChunkSize);
+
+ flxfh = (FlxFrameChunk *) GST_BUFFER_DATA(databuf);
+
+ switch(flxfh->id)
+ {
+ case FLX_FRAME_TYPE:
+ buf = flx_get_data(flxdec, flxfh->size-FlxFrameChunkSize);
+
+ chunk = GST_BUFFER_DATA(buf);
+
+ if (((FlxFrameType *)chunk)->chunks == 0)
+ break;
+
+ // create 32 bits output frame
+ flxdec->out = gst_buffer_new();
+ GST_BUFFER_DATA(flxdec->out) = g_malloc(flxdec->size * 4);
+ GST_BUFFER_SIZE(flxdec->out) = flxdec->size * 4;
+
+
+ // decode chunks
+ flx_decode_chunks(flxdec,
+ ((FlxFrameType *)chunk)->chunks,
+ GST_BUFFER_DATA(buf) + FlxFrameTypeSize,
+ GST_BUFFER_DATA(flxdec->frame));
+
+ // destroy input buffer
+ gst_buffer_unref(buf);
+
+ // save copy of the current frame for possible delta.
+ memcpy(GST_BUFFER_DATA(flxdec->delta),
+ GST_BUFFER_DATA(flxdec->frame),
+ GST_BUFFER_SIZE(flxdec->delta));
+
+ // convert current frame.
+ flx_colorspace_convert(flxdec->converter,
+ GST_BUFFER_DATA(flxdec->frame),
+ GST_BUFFER_DATA(flxdec->out));
+
+ //GST_BUFFER_FLAG_SET(flxdec->out, GST_BUFFER_FLUSH);
+ gst_pad_push(flxdec->srcpad, flxdec->out);
+
+ break;
+ }
+
+ // destroy header buffer
+ gst_buffer_unref(databuf);
+
+ }
+ while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
+
+}
+
+static void
+gst_flxdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstFlxDec *flxdec;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_FLXDEC(object));
+ flxdec = GST_FLXDEC(object);
+
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gst_flxdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstFlxDec *flxdec;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_FLXDEC(object));
+ flxdec = GST_FLXDEC(object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+ GstElementFactory *factory;
+ GstTypeFactory *type;
+
+ factory = gst_elementfactory_new("flxdec", GST_TYPE_FLXDEC, &flxdec_details);
+ g_return_val_if_fail(factory != NULL, FALSE);
+
+ gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_factory));
+ gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_video_factory));
+
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+ type = gst_typefactory_new (&flxdec_definition);
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
+
+ return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "flxdec",
+ plugin_init
+};
diff --git a/gst/flx/gstflxdec.h b/gst/flx/gstflxdec.h
new file mode 100644
index 00000000..cc4c94db
--- /dev/null
+++ b/gst/flx/gstflxdec.h
@@ -0,0 +1,79 @@
+/* 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_FLX_DECODER_H__
+#define __GST_FLX_DECODER_H__
+
+#include <gst/gst.h>
+
+#include "flx_color.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Definition of structure storing data for this element. */
+typedef struct _GstFlxDec GstFlxDec;
+struct _GstFlxDec {
+ GstElement element;
+
+ GstPad *sinkpad,*srcpad;
+
+ gboolean active, new_meta, new_buf;
+
+ GstBuffer *buf, *out, *delta, *frame;
+ gulong offset, size;
+
+ FlxColorSpaceConverter *converter;
+
+ FlxHeader hdr;
+};
+
+/* Standard definition defining a class for this element. */
+typedef struct _GstFlxDecClass GstFlxDecClass;
+struct _GstFlxDecClass {
+ GstElementClass parent_class;
+};
+
+/* Standard macros for defining types for this element. */
+#define GST_TYPE_FLXDEC \
+ (gst_flxdec_get_type())
+#define GST_FLXDEC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FLXDEC,GstFlxDec))
+#define GST_FLXDEC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FLXDEC,GstFlxDec))
+#define GST_IS_FLXDEC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FLXDEC))
+#define GST_IS_FLXDEC_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FLXDEC))
+
+#define FLXDEC_BUFSIZE(buf, offset) \
+ ((GST_BUFFER_OFFSET(buf) + GST_BUFFER_SIZE(buf)) - offset)
+
+/* Standard function returning type information. */
+GType gst_flxdec_get_type(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_FLX_DECODER_H__ */
diff --git a/gst/law/Makefile.am b/gst/law/Makefile.am
new file mode 100644
index 00000000..76a73f79
--- /dev/null
+++ b/gst/law/Makefile.am
@@ -0,0 +1,12 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstalaw.la libgstmulaw.la
+
+libgstalaw_la_SOURCES = alaw-encode.c mulaw-conversion.c alaw-conversion.c alaw-decode.c alaw.c
+libgstalaw_la_CFLAGS = $(GST_CFLAGS)
+
+libgstmulaw_la_SOURCES = mulaw-encode.c mulaw-conversion.c mulaw-decode.c mulaw.c
+libgstmulaw_la_CFLAGS = $(GST_CFLAGS)
+
+noinst_HEADERS = mulaw-conversion.h alaw-encode.h alaw-decode.h alaw-conversion.h mulaw-encode.h mulaw-decode.h
+filterdir = $(libdir)/gst
diff --git a/gst/law/alaw-conversion.c b/gst/law/alaw-conversion.c
new file mode 100644
index 00000000..cb3be3e9
--- /dev/null
+++ b/gst/law/alaw-conversion.c
@@ -0,0 +1,195 @@
+/* $Id$
+
+ * Linux ISDN subsystem, audio conversion and compression (linklevel).
+ *
+ * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de)
+ * DTMF code (c) 1996 by Christian Mock (cm@kukuruz.ping.at)
+ * Silence detection (c) 1998 by Armin Schindler (mac@gismo.telekom.de)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <glib.h>
+/*
+ * Misc. lookup-tables.
+ */
+
+/* ulaw -> signed 16-bit */
+static gint16 isdn_audio_ulaw_to_s16[] =
+{
+ 0x8284, 0x8684, 0x8a84, 0x8e84, 0x9284, 0x9684, 0x9a84, 0x9e84,
+ 0xa284, 0xa684, 0xaa84, 0xae84, 0xb284, 0xb684, 0xba84, 0xbe84,
+ 0xc184, 0xc384, 0xc584, 0xc784, 0xc984, 0xcb84, 0xcd84, 0xcf84,
+ 0xd184, 0xd384, 0xd584, 0xd784, 0xd984, 0xdb84, 0xdd84, 0xdf84,
+ 0xe104, 0xe204, 0xe304, 0xe404, 0xe504, 0xe604, 0xe704, 0xe804,
+ 0xe904, 0xea04, 0xeb04, 0xec04, 0xed04, 0xee04, 0xef04, 0xf004,
+ 0xf0c4, 0xf144, 0xf1c4, 0xf244, 0xf2c4, 0xf344, 0xf3c4, 0xf444,
+ 0xf4c4, 0xf544, 0xf5c4, 0xf644, 0xf6c4, 0xf744, 0xf7c4, 0xf844,
+ 0xf8a4, 0xf8e4, 0xf924, 0xf964, 0xf9a4, 0xf9e4, 0xfa24, 0xfa64,
+ 0xfaa4, 0xfae4, 0xfb24, 0xfb64, 0xfba4, 0xfbe4, 0xfc24, 0xfc64,
+ 0xfc94, 0xfcb4, 0xfcd4, 0xfcf4, 0xfd14, 0xfd34, 0xfd54, 0xfd74,
+ 0xfd94, 0xfdb4, 0xfdd4, 0xfdf4, 0xfe14, 0xfe34, 0xfe54, 0xfe74,
+ 0xfe8c, 0xfe9c, 0xfeac, 0xfebc, 0xfecc, 0xfedc, 0xfeec, 0xfefc,
+ 0xff0c, 0xff1c, 0xff2c, 0xff3c, 0xff4c, 0xff5c, 0xff6c, 0xff7c,
+ 0xff88, 0xff90, 0xff98, 0xffa0, 0xffa8, 0xffb0, 0xffb8, 0xffc0,
+ 0xffc8, 0xffd0, 0xffd8, 0xffe0, 0xffe8, 0xfff0, 0xfff8, 0x0000,
+ 0x7d7c, 0x797c, 0x757c, 0x717c, 0x6d7c, 0x697c, 0x657c, 0x617c,
+ 0x5d7c, 0x597c, 0x557c, 0x517c, 0x4d7c, 0x497c, 0x457c, 0x417c,
+ 0x3e7c, 0x3c7c, 0x3a7c, 0x387c, 0x367c, 0x347c, 0x327c, 0x307c,
+ 0x2e7c, 0x2c7c, 0x2a7c, 0x287c, 0x267c, 0x247c, 0x227c, 0x207c,
+ 0x1efc, 0x1dfc, 0x1cfc, 0x1bfc, 0x1afc, 0x19fc, 0x18fc, 0x17fc,
+ 0x16fc, 0x15fc, 0x14fc, 0x13fc, 0x12fc, 0x11fc, 0x10fc, 0x0ffc,
+ 0x0f3c, 0x0ebc, 0x0e3c, 0x0dbc, 0x0d3c, 0x0cbc, 0x0c3c, 0x0bbc,
+ 0x0b3c, 0x0abc, 0x0a3c, 0x09bc, 0x093c, 0x08bc, 0x083c, 0x07bc,
+ 0x075c, 0x071c, 0x06dc, 0x069c, 0x065c, 0x061c, 0x05dc, 0x059c,
+ 0x055c, 0x051c, 0x04dc, 0x049c, 0x045c, 0x041c, 0x03dc, 0x039c,
+ 0x036c, 0x034c, 0x032c, 0x030c, 0x02ec, 0x02cc, 0x02ac, 0x028c,
+ 0x026c, 0x024c, 0x022c, 0x020c, 0x01ec, 0x01cc, 0x01ac, 0x018c,
+ 0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104,
+ 0x00f4, 0x00e4, 0x00d4, 0x00c4, 0x00b4, 0x00a4, 0x0094, 0x0084,
+ 0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040,
+ 0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000
+};
+
+/* alaw -> signed 16-bit */
+static gint16 isdn_audio_alaw_to_s16[] =
+{
+ 0x13fc, 0xec04, 0x0144, 0xfebc, 0x517c, 0xae84, 0x051c, 0xfae4,
+ 0x0a3c, 0xf5c4, 0x0048, 0xffb8, 0x287c, 0xd784, 0x028c, 0xfd74,
+ 0x1bfc, 0xe404, 0x01cc, 0xfe34, 0x717c, 0x8e84, 0x071c, 0xf8e4,
+ 0x0e3c, 0xf1c4, 0x00c4, 0xff3c, 0x387c, 0xc784, 0x039c, 0xfc64,
+ 0x0ffc, 0xf004, 0x0104, 0xfefc, 0x417c, 0xbe84, 0x041c, 0xfbe4,
+ 0x083c, 0xf7c4, 0x0008, 0xfff8, 0x207c, 0xdf84, 0x020c, 0xfdf4,
+ 0x17fc, 0xe804, 0x018c, 0xfe74, 0x617c, 0x9e84, 0x061c, 0xf9e4,
+ 0x0c3c, 0xf3c4, 0x0084, 0xff7c, 0x307c, 0xcf84, 0x030c, 0xfcf4,
+ 0x15fc, 0xea04, 0x0164, 0xfe9c, 0x597c, 0xa684, 0x059c, 0xfa64,
+ 0x0b3c, 0xf4c4, 0x0068, 0xff98, 0x2c7c, 0xd384, 0x02cc, 0xfd34,
+ 0x1dfc, 0xe204, 0x01ec, 0xfe14, 0x797c, 0x8684, 0x07bc, 0xf844,
+ 0x0f3c, 0xf0c4, 0x00e4, 0xff1c, 0x3c7c, 0xc384, 0x03dc, 0xfc24,
+ 0x11fc, 0xee04, 0x0124, 0xfedc, 0x497c, 0xb684, 0x049c, 0xfb64,
+ 0x093c, 0xf6c4, 0x0028, 0xffd8, 0x247c, 0xdb84, 0x024c, 0xfdb4,
+ 0x19fc, 0xe604, 0x01ac, 0xfe54, 0x697c, 0x9684, 0x069c, 0xf964,
+ 0x0d3c, 0xf2c4, 0x00a4, 0xff5c, 0x347c, 0xcb84, 0x034c, 0xfcb4,
+ 0x12fc, 0xed04, 0x0134, 0xfecc, 0x4d7c, 0xb284, 0x04dc, 0xfb24,
+ 0x09bc, 0xf644, 0x0038, 0xffc8, 0x267c, 0xd984, 0x026c, 0xfd94,
+ 0x1afc, 0xe504, 0x01ac, 0xfe54, 0x6d7c, 0x9284, 0x06dc, 0xf924,
+ 0x0dbc, 0xf244, 0x00b4, 0xff4c, 0x367c, 0xc984, 0x036c, 0xfc94,
+ 0x0f3c, 0xf0c4, 0x00f4, 0xff0c, 0x3e7c, 0xc184, 0x03dc, 0xfc24,
+ 0x07bc, 0xf844, 0x0008, 0xfff8, 0x1efc, 0xe104, 0x01ec, 0xfe14,
+ 0x16fc, 0xe904, 0x0174, 0xfe8c, 0x5d7c, 0xa284, 0x05dc, 0xfa24,
+ 0x0bbc, 0xf444, 0x0078, 0xff88, 0x2e7c, 0xd184, 0x02ec, 0xfd14,
+ 0x14fc, 0xeb04, 0x0154, 0xfeac, 0x557c, 0xaa84, 0x055c, 0xfaa4,
+ 0x0abc, 0xf544, 0x0058, 0xffa8, 0x2a7c, 0xd584, 0x02ac, 0xfd54,
+ 0x1cfc, 0xe304, 0x01cc, 0xfe34, 0x757c, 0x8a84, 0x075c, 0xf8a4,
+ 0x0ebc, 0xf144, 0x00d4, 0xff2c, 0x3a7c, 0xc584, 0x039c, 0xfc64,
+ 0x10fc, 0xef04, 0x0114, 0xfeec, 0x457c, 0xba84, 0x045c, 0xfba4,
+ 0x08bc, 0xf744, 0x0018, 0xffe8, 0x227c, 0xdd84, 0x022c, 0xfdd4,
+ 0x18fc, 0xe704, 0x018c, 0xfe74, 0x657c, 0x9a84, 0x065c, 0xf9a4,
+ 0x0cbc, 0xf344, 0x0094, 0xff6c, 0x327c, 0xcd84, 0x032c, 0xfcd4
+};
+
+/* alaw -> ulaw */
+static guint8 isdn_audio_alaw_to_ulaw[] =
+{
+ 0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
+ 0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
+ 0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
+ 0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
+ 0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
+ 0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
+ 0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
+ 0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
+ 0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
+ 0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
+ 0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
+ 0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
+ 0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
+ 0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
+ 0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
+ 0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
+ 0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
+ 0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
+ 0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
+ 0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
+ 0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
+ 0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
+ 0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
+ 0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
+ 0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
+ 0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
+ 0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
+ 0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
+ 0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
+ 0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
+ 0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
+ 0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
+};
+
+/* ulaw -> alaw */
+static guint8 isdn_audio_ulaw_to_alaw[] =
+{
+ 0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
+ 0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
+ 0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
+ 0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
+ 0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
+ 0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
+ 0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
+ 0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
+ 0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
+ 0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
+ 0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
+ 0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
+ 0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
+ 0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
+ 0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
+ 0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
+ 0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
+ 0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
+ 0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
+ 0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
+ 0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
+ 0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
+ 0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
+ 0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
+ 0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
+ 0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
+ 0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
+ 0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
+ 0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
+ 0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
+ 0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
+ 0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
+};
+
+static inline void
+isdn_audio_tlookup(const guint8 *table, guint8 *buff, gulong n)
+{
+ while (n--)
+ *buff++ = table[*(unsigned char *)buff];
+}
+
+void
+isdn_audio_ulaw2alaw(guint8 *buff, gulong len)
+{
+ isdn_audio_tlookup(isdn_audio_ulaw_to_alaw, buff, len);
+}
+
+void
+isdn_audio_alaw2ulaw(guint8 *buff, gulong len)
+{
+ isdn_audio_tlookup(isdn_audio_alaw_to_ulaw, buff, len);
+}
diff --git a/gst/law/alaw-conversion.h b/gst/law/alaw-conversion.h
new file mode 100644
index 00000000..b7d1297b
--- /dev/null
+++ b/gst/law/alaw-conversion.h
@@ -0,0 +1,12 @@
+#ifndef _GST_ALAW_CONVERSION_H
+#define _GST_ALAW_CONVERSION_H
+
+#include <glib.h>
+
+void
+isdn_audio_ulaw2alaw(guint8 *buff, gulong len);
+
+void
+isdn_audio_alaw2ulaw(guint8 *buff, gulong len);
+
+#endif
diff --git a/gst/law/alaw-decode.c b/gst/law/alaw-decode.c
new file mode 100644
index 00000000..872d5335
--- /dev/null
+++ b/gst/law/alaw-decode.c
@@ -0,0 +1,186 @@
+/* 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 <gst/gst.h>
+#include "alaw-decode.h"
+#include "mulaw-conversion.h"
+#include "alaw-conversion.h"
+
+extern GstPadTemplate *alawdec_src_template, *alawdec_sink_template;
+
+
+/* Stereo signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0
+};
+
+static void gst_alawdec_class_init (GstALawDecClass *klass);
+static void gst_alawdec_init (GstALawDec *alawdec);
+
+static void gst_alawdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void gst_alawdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+static void gst_alawdec_chain (GstPad *pad, GstBuffer *buf);
+
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_stereo_signals[LAST_SIGNAL] = { 0 };
+
+static GstPadNegotiateReturn
+alawdec_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+{
+ GstCaps* tempcaps;
+
+ GstALawDec* alawdec=GST_ALAWDEC (GST_OBJECT_PARENT (pad));
+
+ if (*caps==NULL)
+ return GST_PAD_NEGOTIATE_FAIL;
+
+ tempcaps = gst_caps_copy(*caps);
+
+ gst_caps_set(tempcaps,"format",GST_PROPS_STRING("int"));
+ gst_caps_set(tempcaps,"law",GST_PROPS_INT(0));
+ gst_caps_set(tempcaps,"depth",GST_PROPS_INT(16));
+ gst_caps_set(tempcaps,"width",GST_PROPS_INT(16));
+ gst_caps_set(tempcaps,"signed",GST_PROPS_BOOLEAN(TRUE));
+
+ if (gst_pad_set_caps (alawdec->srcpad, tempcaps))
+ {
+ return GST_PAD_NEGOTIATE_AGREE;
+ }
+ else {
+ gst_caps_unref (tempcaps);
+ return GST_PAD_NEGOTIATE_FAIL;
+ }
+}
+
+GType
+gst_alawdec_get_type(void) {
+ static GType alawdec_type = 0;
+
+ if (!alawdec_type) {
+ static const GTypeInfo alawdec_info = {
+ sizeof(GstALawDecClass), NULL,
+ NULL,
+ (GClassInitFunc)gst_alawdec_class_init,
+ NULL,
+ NULL,
+ sizeof(GstALawDec),
+ 0,
+ (GInstanceInitFunc)gst_alawdec_init,
+ };
+ alawdec_type = g_type_register_static(GST_TYPE_ELEMENT, "GstALawDec", &alawdec_info, 0);
+ }
+ return alawdec_type;
+}
+
+static void
+gst_alawdec_class_init (GstALawDecClass *klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+
+ gobject_class = (GObjectClass*)klass;
+ gstelement_class = (GstElementClass*)klass;
+
+ parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+
+ gobject_class->set_property = gst_alawdec_set_property;
+ gobject_class->get_property = gst_alawdec_get_property;
+}
+
+static void
+gst_alawdec_init (GstALawDec *alawdec)
+{
+ alawdec->sinkpad = gst_pad_new_from_template(alawdec_sink_template,"sink");
+ alawdec->srcpad = gst_pad_new_from_template(alawdec_src_template,"src");
+ gst_pad_set_negotiate_function(alawdec->sinkpad, alawdec_negotiate_sink);
+
+ gst_element_add_pad(GST_ELEMENT(alawdec),alawdec->sinkpad);
+ gst_pad_set_chain_function(alawdec->sinkpad,gst_alawdec_chain);
+ gst_element_add_pad(GST_ELEMENT(alawdec),alawdec->srcpad);
+}
+
+static void
+gst_alawdec_chain (GstPad *pad,GstBuffer *buf)
+{
+ GstALawDec *alawdec;
+ gint16 *linear_data;
+ guint8 *alaw_data;
+ GstBuffer* outbuf;
+
+ g_return_if_fail(pad != NULL);
+ g_return_if_fail(GST_IS_PAD(pad));
+ g_return_if_fail(buf != NULL);
+
+ alawdec = GST_ALAWDEC(GST_OBJECT_PARENT (pad));
+ g_return_if_fail(alawdec != NULL);
+ g_return_if_fail(GST_IS_ALAWDEC(alawdec));
+
+ alaw_data = (guint8 *)GST_BUFFER_DATA(buf);
+ outbuf=gst_buffer_new();
+ GST_BUFFER_DATA(outbuf) = (gchar*)g_new(gint16,GST_BUFFER_SIZE(buf));
+ GST_BUFFER_SIZE(outbuf) = GST_BUFFER_SIZE(buf)*2;
+
+ linear_data = (gint16*)GST_BUFFER_DATA(outbuf);
+
+ isdn_audio_alaw2ulaw(alaw_data,GST_BUFFER_SIZE(buf));
+ mulaw_decode(alaw_data,linear_data,GST_BUFFER_SIZE(buf));
+
+ gst_buffer_unref(buf);
+ gst_pad_push(alawdec->srcpad,outbuf);
+}
+
+static void
+gst_alawdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstALawDec *alawdec;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_ALAWDEC(object));
+ alawdec = GST_ALAWDEC(object);
+
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gst_alawdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstALawDec *alawdec;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_ALAWDEC(object));
+ alawdec = GST_ALAWDEC(object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
diff --git a/gst/law/alaw-decode.h b/gst/law/alaw-decode.h
new file mode 100644
index 00000000..f487009f
--- /dev/null
+++ b/gst/law/alaw-decode.h
@@ -0,0 +1,69 @@
+/* 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_ALAWDECODE_H__
+#define __GST_ALAWDECODE_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+// #include <gst/meta/audioraw.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GST_TYPE_ALAWDEC \
+ (gst_alawdec_get_type())
+#define GST_ALAWDEC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALAWDEC,GstALawDec))
+#define GST_ALAWDEC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALAWDEC,GstALawDec))
+#define GST_IS_ALAWDEC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALAWDEC))
+#define GST_IS_ALAWDEC_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALAWDEC))
+
+typedef struct _GstALawDec GstALawDec;
+typedef struct _GstALawDecClass GstALawDecClass;
+
+struct _GstALawDec {
+ GstElement element;
+
+ GstPad *sinkpad,*srcpad;
+
+ //MetaAudioRaw meta;
+
+};
+
+struct _GstALawDecClass {
+ GstElementClass parent_class;
+};
+
+GType gst_alawdec_get_type(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_STEREO_H__ */
diff --git a/gst/law/alaw-encode.c b/gst/law/alaw-encode.c
new file mode 100644
index 00000000..ab54bd16
--- /dev/null
+++ b/gst/law/alaw-encode.c
@@ -0,0 +1,182 @@
+/* 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 <gst/gst.h>
+#include "alaw-encode.h"
+#include "mulaw-conversion.h"
+#include "alaw-conversion.h"
+
+extern GstPadTemplate *alawenc_src_template, *alawenc_sink_template;
+
+
+/* Stereo signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0
+};
+
+static void gst_alawenc_class_init (GstALawEncClass *klass);
+static void gst_alawenc_init (GstALawEnc *alawenc);
+
+static void gst_alawenc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void gst_alawenc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+static void gst_alawenc_chain (GstPad *pad, GstBuffer *buf);
+
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_stereo_signals[LAST_SIGNAL] = { 0 };
+
+static GstPadNegotiateReturn
+alawenc_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+{
+ GstCaps* tempcaps;
+
+ GstALawEnc* alawenc=GST_ALAWENC (GST_OBJECT_PARENT (pad));
+
+ if (*caps==NULL)
+ return GST_PAD_NEGOTIATE_FAIL;
+
+ tempcaps = gst_caps_copy(*caps);
+
+ gst_caps_set(tempcaps,"format",GST_PROPS_STRING("int"));
+ gst_caps_set(tempcaps,"law",GST_PROPS_INT(2));
+ gst_caps_set(tempcaps,"depth",GST_PROPS_INT(8));
+ gst_caps_set(tempcaps,"width",GST_PROPS_INT(8));
+ gst_caps_set(tempcaps,"signed",GST_PROPS_BOOLEAN(FALSE));
+
+ if (gst_pad_set_caps (alawenc->srcpad, tempcaps))
+ {
+ return GST_PAD_NEGOTIATE_AGREE;
+ }
+ else {
+ gst_caps_unref (tempcaps);
+ return GST_PAD_NEGOTIATE_FAIL;
+ }
+}
+
+GType
+gst_alawenc_get_type(void) {
+ static GType alawenc_type = 0;
+
+ if (!alawenc_type) {
+ static const GTypeInfo alawenc_info = {
+ sizeof(GstALawEncClass), NULL,
+ NULL,
+ (GClassInitFunc)gst_alawenc_class_init,
+ NULL,
+ NULL,
+ sizeof(GstALawEnc),
+ 0,
+ (GInstanceInitFunc)gst_alawenc_init,
+ };
+ alawenc_type = g_type_register_static(GST_TYPE_ELEMENT, "GstALawEnc", &alawenc_info, 0);
+ }
+ return alawenc_type;
+}
+
+static void
+gst_alawenc_class_init (GstALawEncClass *klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+
+ gobject_class = (GObjectClass*)klass;
+ gstelement_class = (GstElementClass*)klass;
+
+ parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+
+ gobject_class->set_property = gst_alawenc_set_property;
+ gobject_class->get_property = gst_alawenc_get_property;
+}
+
+static void
+gst_alawenc_init (GstALawEnc *alawenc)
+{
+ alawenc->sinkpad = gst_pad_new_from_template(alawenc_sink_template,"sink");
+ alawenc->srcpad = gst_pad_new_from_template(alawenc_src_template,"src");
+ gst_pad_set_negotiate_function(alawenc->sinkpad, alawenc_negotiate_sink);
+
+ gst_element_add_pad(GST_ELEMENT(alawenc),alawenc->sinkpad);
+ gst_pad_set_chain_function(alawenc->sinkpad,gst_alawenc_chain);
+ gst_element_add_pad(GST_ELEMENT(alawenc),alawenc->srcpad);
+}
+
+static void
+gst_alawenc_chain (GstPad *pad,GstBuffer *buf)
+{
+ GstALawEnc *alawenc;
+ gint16 *linear_data;
+ guint8 *alaw_data;
+ GstBuffer* outbuf;
+
+ g_return_if_fail(pad != NULL);
+ g_return_if_fail(GST_IS_PAD(pad));
+ g_return_if_fail(buf != NULL);
+
+ alawenc = GST_ALAWENC(GST_OBJECT_PARENT (pad));
+ g_return_if_fail(alawenc != NULL);
+ g_return_if_fail(GST_IS_ALAWENC(alawenc));
+
+ linear_data = (gint16 *)GST_BUFFER_DATA(buf);
+ outbuf=gst_buffer_new();
+ GST_BUFFER_DATA(outbuf) = (gchar*)g_new(gint16,GST_BUFFER_SIZE(buf)/4);
+ GST_BUFFER_SIZE(outbuf) = GST_BUFFER_SIZE(buf)/2;
+
+ alaw_data = (guint8*)GST_BUFFER_DATA(outbuf);
+ mulaw_encode(linear_data,alaw_data,GST_BUFFER_SIZE(outbuf));
+ isdn_audio_ulaw2alaw(alaw_data,GST_BUFFER_SIZE(outbuf));
+ gst_buffer_unref(buf);
+ gst_pad_push(alawenc->srcpad,outbuf);
+}
+
+static void
+gst_alawenc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstALawEnc *alawenc;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_ALAWENC(object));
+ alawenc = GST_ALAWENC(object);
+
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gst_alawenc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstALawEnc *alawenc;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_ALAWENC(object));
+ alawenc = GST_ALAWENC(object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
diff --git a/gst/law/alaw-encode.h b/gst/law/alaw-encode.h
new file mode 100644
index 00000000..023d0633
--- /dev/null
+++ b/gst/law/alaw-encode.h
@@ -0,0 +1,69 @@
+/* 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_ALAWENCODE_H__
+#define __GST_ALAWENCODE_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+// #include <gst/meta/audioraw.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GST_TYPE_ALAWENC \
+ (gst_alawenc_get_type())
+#define GST_ALAWENC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALAWENC,GstALawEnc))
+#define GST_ALAWENC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALAWENC,GstALawEnc))
+#define GST_IS_ALAWENC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALAWENC))
+#define GST_IS_ALAWENC_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALAWENC))
+
+typedef struct _GstALawEnc GstALawEnc;
+typedef struct _GstALawEncClass GstALawEncClass;
+
+struct _GstALawEnc {
+ GstElement element;
+
+ GstPad *sinkpad,*srcpad;
+
+ //MetaAudioRaw meta;
+
+};
+
+struct _GstALawEncClass {
+ GstElementClass parent_class;
+};
+
+GType gst_alawenc_get_type(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_STEREO_H__ */
diff --git a/gst/law/alaw.c b/gst/law/alaw.c
new file mode 100644
index 00000000..1b9afb5c
--- /dev/null
+++ b/gst/law/alaw.c
@@ -0,0 +1,95 @@
+#include "alaw-encode.h"
+#include "alaw-decode.h"
+
+static GstElementDetails alawenc_details = {
+ "PCM to A Law conversion",
+ "Filter/Effect",
+ "Convert 16bit PCM to 8bit A law",
+ VERSION,
+ "Zaheer Merali <zaheer@bellworldwide.net>",
+ "(C) 2001"
+};
+
+static GstElementDetails alawdec_details = {
+ "A Law to PCM conversion",
+ "Filter/Effect",
+ "Convert 8bit A law to 16bit PCM",
+ VERSION,
+ "Zaheer Merali <zaheer@bellworldwide.net>",
+ "(C) 2001"
+};
+
+static GstCaps*
+alaw_factory (void)
+{
+ return
+ gst_caps_new (
+ "test_src",
+ "audio/raw",
+ gst_props_new (
+ "format", GST_PROPS_STRING ("int"),
+ "law", GST_PROPS_INT (2),
+ "width", GST_PROPS_INT(8),
+ "depth", GST_PROPS_INT(8),
+ "signed", GST_PROPS_BOOLEAN(FALSE),
+ NULL));
+}
+
+static GstCaps*
+linear_factory (void)
+{
+ return
+ gst_caps_new (
+ "test_sink",
+ "audio/raw",
+ gst_props_new (
+ "format", GST_PROPS_STRING ("int"),
+ "law", GST_PROPS_INT(0),
+ "width", GST_PROPS_INT(16),
+ "depth", GST_PROPS_INT(16),
+ "signed", GST_PROPS_BOOLEAN(TRUE),
+ NULL));
+}
+
+GstPadTemplate *alawenc_src_template, *alawenc_sink_template;
+GstPadTemplate *alawdec_src_template, *alawdec_sink_template;
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+ GstElementFactory *alawenc_factory, *alawdec_factory;
+ GstCaps* alaw_caps, *linear_caps;
+
+ alawenc_factory = gst_elementfactory_new("alawencode",GST_TYPE_ALAWENC,
+ &alawenc_details);
+ g_return_val_if_fail(alawenc_factory != NULL, FALSE);
+ alawdec_factory = gst_elementfactory_new("alawdecode",GST_TYPE_ALAWDEC,
+ &alawdec_details);
+ g_return_val_if_fail(alawdec_factory != NULL, FALSE);
+
+ alaw_caps = alaw_factory ();
+ linear_caps = linear_factory ();
+
+ alawenc_src_template = gst_padtemplate_new ("src",GST_PAD_SRC,GST_PAD_ALWAYS,alaw_caps, NULL);
+ alawenc_sink_template = gst_padtemplate_new ("sink",GST_PAD_SINK,GST_PAD_ALWAYS,linear_caps, NULL);
+ gst_elementfactory_add_padtemplate (alawenc_factory, alawenc_src_template);
+ gst_elementfactory_add_padtemplate (alawenc_factory, alawenc_sink_template);
+
+ alawdec_src_template = gst_padtemplate_new ("src",GST_PAD_SRC,GST_PAD_ALWAYS,linear_caps, NULL);
+ alawdec_sink_template = gst_padtemplate_new ("sink",GST_PAD_SINK,GST_PAD_ALWAYS,alaw_caps, NULL);
+
+ gst_elementfactory_add_padtemplate (alawdec_factory, alawdec_src_template);
+ gst_elementfactory_add_padtemplate (alawdec_factory, alawdec_sink_template);
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (alawenc_factory));
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (alawdec_factory));
+
+ return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "alaw",
+ plugin_init
+};
+
diff --git a/gst/law/mulaw-conversion.c b/gst/law/mulaw-conversion.c
new file mode 100644
index 00000000..ad3fcce6
--- /dev/null
+++ b/gst/law/mulaw-conversion.c
@@ -0,0 +1,102 @@
+/*
+ * This routine converts from linear to ulaw
+ * 29 September 1989
+ *
+ * Craig Reese: IDA/Supercomputing Research Center
+ * Joe Campbell: Department of Defense
+ *
+ * References:
+ * 1) CCITT Recommendation G.711 (very difficult to follow)
+ * 2) "A New Digital Technique for Implementation of Any
+ * Continuous PCM Companding Law," Villeret, Michel,
+ * et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
+ * 1973, pg. 11.12-11.17
+ * 3) MIL-STD-188-113,"Interoperability and Performance Standards
+ * for Analog-to_Digital Conversion Techniques,"
+ * 17 February 1987
+ *
+ * Input: Signed 16 bit linear sample
+ * Output: 8 bit ulaw sample
+ */
+
+#include <glib.h>
+
+#define ZEROTRAP /* turn on the trap as per the MIL-STD */
+#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
+#define CLIP 32635
+
+void
+mulaw_encode(gint16* in, guint8* out, gint numsamples)
+{
+ static gint16 exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
+ gint16 sign, exponent, mantissa,i;
+ gint16 sample;
+ guint8 ulawbyte;
+
+ for(i=0;i<numsamples;i++) {
+ sample=in[i];
+ /** get the sample into sign-magnitude **/
+ sign = (sample >> 8) & 0x80; /* set aside the sign */
+ if (sign != 0) sample = -sample; /* get magnitude */
+ if (sample > CLIP) sample = CLIP; /* clip the magnitude */
+ /** convert from 16 bit linear to ulaw **/
+ sample = sample + BIAS;
+ exponent = exp_lut[(sample>>7) & 0xFF];
+ mantissa = (sample >> (exponent+3)) & 0x0F;
+ ulawbyte = ~(sign | (exponent << 4) | mantissa);
+#ifdef ZEROTRAP
+ if (ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */
+#endif
+ out[i]=ulawbyte;
+ }
+}
+
+/*
+ * This routine converts from ulaw to 16 bit linear
+ * 29 September 1989
+ *
+ * Craig Reese: IDA/Supercomputing Research Center
+ *
+ * References:
+ * 1) CCITT Recommendation G.711 (very difficult to follow)
+ * 2) MIL-STD-188-113,"Interoperability and Performance Standards
+ * for Analog-to_Digital Conversion Techniques,"
+ * 17 February 1987
+ *
+ * Input: 8 bit ulaw sample
+ * Output: signed 16 bit linear sample
+ */
+
+void
+mulaw_decode(guint8* in,gint16* out,gint numsamples)
+{
+ static gint16 exp_lut[8]={0,132,396,924,1980,4092,8316,16764};
+ gint16 sign, exponent, mantissa;
+ guint8 ulawbyte;
+ gint16 linear,i;
+ for(i=0;i<numsamples;i++) {
+ ulawbyte=in[i];
+ ulawbyte = ~ulawbyte;
+ sign = (ulawbyte & 0x80);
+ exponent = (ulawbyte >> 4) & 0x07;
+ mantissa = ulawbyte & 0x0F;
+ linear = exp_lut[exponent] + (mantissa << (exponent+3));
+ if (sign != 0) linear = -linear;
+ out[i]=linear;
+ }
+}
diff --git a/gst/law/mulaw-conversion.h b/gst/law/mulaw-conversion.h
new file mode 100644
index 00000000..55180121
--- /dev/null
+++ b/gst/law/mulaw-conversion.h
@@ -0,0 +1,10 @@
+#ifndef _GST_ULAWDECODE_H
+#define _GST_ULAWDECODE_H
+
+#include <glib.h>
+
+void
+mulaw_encode(gint16* in, guint8* out, gint numsamples);
+void
+mulaw_decode(guint8* in,gint16* out,gint numsamples);
+#endif
diff --git a/gst/law/mulaw-decode.c b/gst/law/mulaw-decode.c
new file mode 100644
index 00000000..d93c6904
--- /dev/null
+++ b/gst/law/mulaw-decode.c
@@ -0,0 +1,181 @@
+/* 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 <gst/gst.h>
+#include "mulaw-decode.h"
+#include "mulaw-conversion.h"
+
+extern GstPadTemplate *mulawdec_src_template, *mulawdec_sink_template;
+
+
+/* Stereo signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0
+};
+
+static void gst_mulawdec_class_init (GstMuLawDecClass *klass);
+static void gst_mulawdec_init (GstMuLawDec *mulawdec);
+
+static void gst_mulawdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void gst_mulawdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+static void gst_mulawdec_chain (GstPad *pad, GstBuffer *buf);
+
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_stereo_signals[LAST_SIGNAL] = { 0 };
+
+static GstPadNegotiateReturn
+mulawdec_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+{
+ GstCaps* tempcaps;
+
+ GstMuLawDec* mulawdec=GST_MULAWDEC (GST_OBJECT_PARENT (pad));
+
+ if (*caps==NULL)
+ return GST_PAD_NEGOTIATE_FAIL;
+
+ tempcaps = gst_caps_copy(*caps);
+
+ gst_caps_set(tempcaps,"format",GST_PROPS_STRING("int"));
+ gst_caps_set(tempcaps,"law",GST_PROPS_INT(0));
+ gst_caps_set(tempcaps,"depth",GST_PROPS_INT(16));
+ gst_caps_set(tempcaps,"width",GST_PROPS_INT(16));
+ gst_caps_set(tempcaps,"signed",GST_PROPS_BOOLEAN(TRUE));
+
+ if (gst_pad_set_caps (mulawdec->srcpad, tempcaps))
+ {
+ return GST_PAD_NEGOTIATE_AGREE;
+ }
+ else {
+ gst_caps_unref (tempcaps);
+ return GST_PAD_NEGOTIATE_FAIL;
+ }
+}
+
+GType
+gst_mulawdec_get_type(void) {
+ static GType mulawdec_type = 0;
+
+ if (!mulawdec_type) {
+ static const GTypeInfo mulawdec_info = {
+ sizeof(GstMuLawDecClass), NULL,
+ NULL,
+ (GClassInitFunc)gst_mulawdec_class_init,
+ NULL,
+ NULL,
+ sizeof(GstMuLawDec),
+ 0,
+ (GInstanceInitFunc)gst_mulawdec_init,
+ };
+ mulawdec_type = g_type_register_static(GST_TYPE_ELEMENT, "GstMuLawDec", &mulawdec_info, 0);
+ }
+ return mulawdec_type;
+}
+
+static void
+gst_mulawdec_class_init (GstMuLawDecClass *klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+
+ gobject_class = (GObjectClass*)klass;
+ gstelement_class = (GstElementClass*)klass;
+
+ parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+
+ gobject_class->set_property = gst_mulawdec_set_property;
+ gobject_class->get_property = gst_mulawdec_get_property;
+}
+
+static void
+gst_mulawdec_init (GstMuLawDec *mulawdec)
+{
+ mulawdec->sinkpad = gst_pad_new_from_template(mulawdec_sink_template,"sink");
+ mulawdec->srcpad = gst_pad_new_from_template(mulawdec_src_template,"src");
+ gst_pad_set_negotiate_function(mulawdec->sinkpad, mulawdec_negotiate_sink);
+
+ gst_element_add_pad(GST_ELEMENT(mulawdec),mulawdec->sinkpad);
+ gst_pad_set_chain_function(mulawdec->sinkpad,gst_mulawdec_chain);
+ gst_element_add_pad(GST_ELEMENT(mulawdec),mulawdec->srcpad);
+}
+
+static void
+gst_mulawdec_chain (GstPad *pad,GstBuffer *buf)
+{
+ GstMuLawDec *mulawdec;
+ gint16 *linear_data;
+ guint8 *mulaw_data;
+ GstBuffer* outbuf;
+
+ g_return_if_fail(pad != NULL);
+ g_return_if_fail(GST_IS_PAD(pad));
+ g_return_if_fail(buf != NULL);
+
+ mulawdec = GST_MULAWDEC(GST_OBJECT_PARENT (pad));
+ g_return_if_fail(mulawdec != NULL);
+ g_return_if_fail(GST_IS_MULAWDEC(mulawdec));
+
+ mulaw_data = (guint8 *)GST_BUFFER_DATA(buf);
+ outbuf=gst_buffer_new();
+ GST_BUFFER_DATA(outbuf) = (gchar*)g_new(gint16,GST_BUFFER_SIZE(buf));
+ GST_BUFFER_SIZE(outbuf) = GST_BUFFER_SIZE(buf)*2;
+
+ linear_data = (gint16*)GST_BUFFER_DATA(outbuf);
+ mulaw_decode(mulaw_data,linear_data,GST_BUFFER_SIZE(buf));
+
+ gst_buffer_unref(buf);
+ gst_pad_push(mulawdec->srcpad,outbuf);
+}
+
+static void
+gst_mulawdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstMuLawDec *mulawdec;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_MULAWDEC(object));
+ mulawdec = GST_MULAWDEC(object);
+
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gst_mulawdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstMuLawDec *mulawdec;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_MULAWDEC(object));
+ mulawdec = GST_MULAWDEC(object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
diff --git a/gst/law/mulaw-decode.h b/gst/law/mulaw-decode.h
new file mode 100644
index 00000000..431b1bdc
--- /dev/null
+++ b/gst/law/mulaw-decode.h
@@ -0,0 +1,69 @@
+/* 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_MULAWDECODE_H__
+#define __GST_MULAWDECODE_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+// #include <gst/meta/audioraw.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GST_TYPE_MULAWDEC \
+ (gst_mulawdec_get_type())
+#define GST_MULAWDEC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MULAWDEC,GstMuLawDec))
+#define GST_MULAWDEC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MULAWDEC,GstMuLawDec))
+#define GST_IS_MULAWDEC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MULAWDEC))
+#define GST_IS_MULAWDEC_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MULAWDEC))
+
+typedef struct _GstMuLawDec GstMuLawDec;
+typedef struct _GstMuLawDecClass GstMuLawDecClass;
+
+struct _GstMuLawDec {
+ GstElement element;
+
+ GstPad *sinkpad,*srcpad;
+
+ //MetaAudioRaw meta;
+
+};
+
+struct _GstMuLawDecClass {
+ GstElementClass parent_class;
+};
+
+GType gst_mulawdec_get_type(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_STEREO_H__ */
diff --git a/gst/law/mulaw-encode.c b/gst/law/mulaw-encode.c
new file mode 100644
index 00000000..40d868d9
--- /dev/null
+++ b/gst/law/mulaw-encode.c
@@ -0,0 +1,181 @@
+/* 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 <gst/gst.h>
+#include "mulaw-encode.h"
+#include "mulaw-conversion.h"
+
+extern GstPadTemplate *mulawenc_src_template, *mulawenc_sink_template;
+
+
+/* Stereo signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0
+};
+
+static void gst_mulawenc_class_init (GstMuLawEncClass *klass);
+static void gst_mulawenc_init (GstMuLawEnc *mulawenc);
+
+static void gst_mulawenc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void gst_mulawenc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+static void gst_mulawenc_chain (GstPad *pad, GstBuffer *buf);
+
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_stereo_signals[LAST_SIGNAL] = { 0 };
+
+static GstPadNegotiateReturn
+mulawenc_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+{
+ GstCaps* tempcaps;
+
+ GstMuLawEnc* mulawenc=GST_MULAWENC (GST_OBJECT_PARENT (pad));
+
+ if (*caps==NULL)
+ return GST_PAD_NEGOTIATE_FAIL;
+
+ tempcaps = gst_caps_copy(*caps);
+
+ gst_caps_set(tempcaps,"format",GST_PROPS_STRING("int"));
+ gst_caps_set(tempcaps,"law",GST_PROPS_INT(1));
+ gst_caps_set(tempcaps,"depth",GST_PROPS_INT(8));
+ gst_caps_set(tempcaps,"width",GST_PROPS_INT(8));
+ gst_caps_set(tempcaps,"signed",GST_PROPS_BOOLEAN(FALSE));
+
+ if (gst_pad_set_caps (mulawenc->srcpad, tempcaps))
+ {
+ return GST_PAD_NEGOTIATE_AGREE;
+ }
+ else {
+ gst_caps_unref (tempcaps);
+ return GST_PAD_NEGOTIATE_FAIL;
+ }
+}
+
+GType
+gst_mulawenc_get_type(void) {
+ static GType mulawenc_type = 0;
+
+ if (!mulawenc_type) {
+ static const GTypeInfo mulawenc_info = {
+ sizeof(GstMuLawEncClass), NULL,
+ NULL,
+ (GClassInitFunc)gst_mulawenc_class_init,
+ NULL,
+ NULL,
+ sizeof(GstMuLawEnc),
+ 0,
+ (GInstanceInitFunc)gst_mulawenc_init,
+ };
+ mulawenc_type = g_type_register_static(GST_TYPE_ELEMENT, "GstMuLawEnc", &mulawenc_info, 0);
+ }
+ return mulawenc_type;
+}
+
+static void
+gst_mulawenc_class_init (GstMuLawEncClass *klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+
+ gobject_class = (GObjectClass*)klass;
+ gstelement_class = (GstElementClass*)klass;
+
+ parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+
+ gobject_class->set_property = gst_mulawenc_set_property;
+ gobject_class->get_property = gst_mulawenc_get_property;
+}
+
+static void
+gst_mulawenc_init (GstMuLawEnc *mulawenc)
+{
+ mulawenc->sinkpad = gst_pad_new_from_template(mulawenc_sink_template,"sink");
+ mulawenc->srcpad = gst_pad_new_from_template(mulawenc_src_template,"src");
+ gst_pad_set_negotiate_function(mulawenc->sinkpad, mulawenc_negotiate_sink);
+
+ gst_element_add_pad(GST_ELEMENT(mulawenc),mulawenc->sinkpad);
+ gst_pad_set_chain_function(mulawenc->sinkpad,gst_mulawenc_chain);
+ gst_element_add_pad(GST_ELEMENT(mulawenc),mulawenc->srcpad);
+}
+
+static void
+gst_mulawenc_chain (GstPad *pad,GstBuffer *buf)
+{
+ GstMuLawEnc *mulawenc;
+ gint16 *linear_data;
+ guint8 *mulaw_data;
+ GstBuffer* outbuf;
+
+ g_return_if_fail(pad != NULL);
+ g_return_if_fail(GST_IS_PAD(pad));
+ g_return_if_fail(buf != NULL);
+
+ mulawenc = GST_MULAWENC(GST_OBJECT_PARENT (pad));
+ g_return_if_fail(mulawenc != NULL);
+ g_return_if_fail(GST_IS_MULAWENC(mulawenc));
+
+ linear_data = (gint16 *)GST_BUFFER_DATA(buf);
+ outbuf=gst_buffer_new();
+ GST_BUFFER_DATA(outbuf) = (gchar*)g_new(gint16,GST_BUFFER_SIZE(buf)/4);
+ GST_BUFFER_SIZE(outbuf) = GST_BUFFER_SIZE(buf)/2;
+
+ mulaw_data = (gint8*)GST_BUFFER_DATA(outbuf);
+ mulaw_encode(linear_data,mulaw_data,GST_BUFFER_SIZE(outbuf));
+
+ gst_buffer_unref(buf);
+ gst_pad_push(mulawenc->srcpad,outbuf);
+}
+
+static void
+gst_mulawenc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstMuLawEnc *mulawenc;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_MULAWENC(object));
+ mulawenc = GST_MULAWENC(object);
+
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gst_mulawenc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstMuLawEnc *mulawenc;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_MULAWENC(object));
+ mulawenc = GST_MULAWENC(object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
diff --git a/gst/law/mulaw-encode.h b/gst/law/mulaw-encode.h
new file mode 100644
index 00000000..009b470b
--- /dev/null
+++ b/gst/law/mulaw-encode.h
@@ -0,0 +1,69 @@
+/* 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_MULAWENCODE_H__
+#define __GST_MULAWENCODE_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+// #include <gst/meta/audioraw.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GST_TYPE_MULAWENC \
+ (gst_mulawenc_get_type())
+#define GST_MULAWENC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MULAWENC,GstMuLawEnc))
+#define GST_MULAWENC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MULAWENC,GstMuLawEnc))
+#define GST_IS_MULAWENC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MULAWENC))
+#define GST_IS_MULAWENC_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MULAWENC))
+
+typedef struct _GstMuLawEnc GstMuLawEnc;
+typedef struct _GstMuLawEncClass GstMuLawEncClass;
+
+struct _GstMuLawEnc {
+ GstElement element;
+
+ GstPad *sinkpad,*srcpad;
+
+ //MetaAudioRaw meta;
+
+};
+
+struct _GstMuLawEncClass {
+ GstElementClass parent_class;
+};
+
+GType gst_mulawenc_get_type(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_STEREO_H__ */
diff --git a/gst/law/mulaw.c b/gst/law/mulaw.c
new file mode 100644
index 00000000..5b97eca3
--- /dev/null
+++ b/gst/law/mulaw.c
@@ -0,0 +1,103 @@
+#include "mulaw-encode.h"
+#include "mulaw-decode.h"
+
+static GstElementDetails mulawenc_details = {
+ "PCM to Mu Law conversion",
+ "Filter/Effect",
+ "Convert 16bit PCM to 8bit mu law",
+ VERSION,
+ "Zaheer Merali <zaheer@bellworldwide.net>",
+ "(C) 2001"
+};
+
+static GstElementDetails mulawdec_details = {
+ "Mu Law to PCM conversion",
+ "Filter/Effect",
+ "Convert 8bit mu law to 16bit PCM",
+ VERSION,
+ "Zaheer Merali <zaheer@bellworldwide.net>",
+ "(C) 2001"
+};
+
+static GstCaps*
+mulaw_factory (void)
+{
+ return
+ gst_caps_new (
+ "test_src",
+ "audio/raw",
+ gst_props_new (
+ "format", GST_PROPS_STRING ("int"),
+ "law", GST_PROPS_INT (1),
+ "width", GST_PROPS_INT(8),
+ "depth", GST_PROPS_INT(8),
+ "signed", GST_PROPS_BOOLEAN(FALSE),
+ NULL));
+}
+
+static GstCaps*
+linear_factory (void)
+{
+ return
+ gst_caps_new (
+ "test_sink",
+ "audio/raw",
+ gst_props_new (
+ "format", GST_PROPS_STRING ("int"),
+ "law", GST_PROPS_INT(0),
+ "width", GST_PROPS_INT(16),
+ "depth", GST_PROPS_INT(16),
+ "signed", GST_PROPS_BOOLEAN(TRUE),
+ NULL));
+}
+
+GstPadTemplate *mulawenc_src_template, *mulawenc_sink_template;
+GstPadTemplate *mulawdec_src_template, *mulawdec_sink_template;
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+ GstElementFactory *mulawenc_factory, *mulawdec_factory;
+ GstCaps* mulaw_caps, *linear_caps;
+
+ mulawenc_factory = gst_elementfactory_new("mulawencode",GST_TYPE_MULAWENC,
+ &mulawenc_details);
+ g_return_val_if_fail(mulawenc_factory != NULL, FALSE);
+ mulawdec_factory = gst_elementfactory_new("mulawdecode",GST_TYPE_MULAWDEC,
+ &mulawdec_details);
+ g_return_val_if_fail(mulawdec_factory != NULL, FALSE);
+
+ mulaw_caps = mulaw_factory ();
+ linear_caps = linear_factory ();
+
+ mulawenc_src_template = gst_padtemplate_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
+ mulaw_caps, NULL);
+ mulawenc_sink_template = gst_padtemplate_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
+ linear_caps, NULL);
+
+ gst_elementfactory_add_padtemplate (mulawenc_factory, mulawenc_src_template);
+ gst_elementfactory_add_padtemplate (mulawenc_factory, mulawenc_sink_template);
+
+ mulawdec_src_template = gst_padtemplate_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
+ linear_caps, NULL);
+ mulawdec_sink_template = gst_padtemplate_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
+ mulaw_caps, NULL);
+
+ gst_elementfactory_add_padtemplate (mulawdec_factory, mulawdec_src_template);
+ gst_elementfactory_add_padtemplate (mulawdec_factory, mulawdec_sink_template);
+
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (mulawenc_factory));
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (mulawdec_factory));
+
+
+
+ return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "mulaw",
+ plugin_init
+};
+
diff --git a/gst/level/Makefile.am b/gst/level/Makefile.am
new file mode 100644
index 00000000..df87d6c4
--- /dev/null
+++ b/gst/level/Makefile.am
@@ -0,0 +1,10 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstlevel.la
+
+libgstlevel_la_SOURCES = gstlevel.c
+libgstlevel_la_CFLAGS = $(GST_CFLAGS)
+
+noinst_HEADERS = gstlevel.h filter.func
+
+EXTRA_DIST = README
diff --git a/gst/level/README b/gst/level/README
new file mode 100644
index 00000000..c7dbf4ca
--- /dev/null
+++ b/gst/level/README
@@ -0,0 +1,11 @@
+level plugin by thomas <thomas@apestaart.org>
+
+basic level indicator; prints out RMS values averaged over the buffer of
+one iteration. Insert this into an audio/raw chain.
+
+You can plot the level envelope of the track using gnuplot, example :
+
+tools/gstreamer-launch disksrc location=foo.wav ! parsewav ! level ! \
+ fakesink silent=true > foo.level
+graph -T gif foo.level > foo.gif
+xview dark.gif
diff --git a/gst/level/filter.func b/gst/level/filter.func
new file mode 100644
index 00000000..ccdaf616
--- /dev/null
+++ b/gst/level/filter.func
@@ -0,0 +1,45 @@
+{
+ guint j;
+ double squaresum = 0.0;
+ double RMS = 0.0;
+ double RMS_dB = 0.0;
+ static int threshold_dB = -80;
+ static long int sample = 0;
+ double timepoint;
+
+ /*
+ * process data here
+ * input sample data enters in *in_data as 8 or 16 bit data
+ * samples for left and right channel are interleaved
+ */
+/*
+ for(j = 0; j < num_samples; j++) {
+ (*out_data)[j] = in_data[j];
+ squaresum += in_data[j] * in_data[j];
+ }
+ RMS = sqrt (squaresum / (float) num_samples);
+ printf ("RMS for this block : %f\n", RMS);
+ RMS_dB = 20 * log (RMS / 32767);
+ printf ("RMS in dB (for 16bit) : %f\n", RMS_dB);
+*/
+
+ for(j = 0; j < num_samples; j++) {
+ (*out_data)[j] = in_data[j];
+ squaresum += pow ((double) in_data[j] / 32767.0, 2);
+ }
+ RMS = sqrt (squaresum / (float) num_samples);
+ RMS_dB = 10 * log (RMS);
+ sample += num_samples;
+ timepoint = sample / (44100.0 * 2);
+
+ if (RMS_dB > (double) threshold_dB)
+ {
+/* printf ("Reached %d dB at %f sec (%f dB)\n",
+ threshold_dB, timepoint, RMS_dB);
+*/
+ threshold_dB += 1;
+ }
+/* printf ("RMS in dB (for 16bit) : %f\n", RMS_dB); */
+ printf ("%f %f\n", timepoint, RMS_dB);
+}
+
diff --git a/gst/level/gstlevel.c b/gst/level/gstlevel.c
new file mode 100644
index 00000000..cd839a32
--- /dev/null
+++ b/gst/level/gstlevel.c
@@ -0,0 +1,285 @@
+/* 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 <gst/gst.h>
+#include "gstlevel.h"
+#include "math.h"
+
+
+static GstElementDetails level_details = {
+ "Level",
+ "Filter/Effect",
+ "RMS Level indicator for audio/raw",
+ VERSION,
+ "Thomas <thomas@apestaart.org>",
+ "(C) 2001",
+};
+
+
+/* Filter signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0
+};
+
+static GstPadTemplate*
+level_src_factory (void)
+{
+ static GstPadTemplate *template = NULL;
+
+ if (!template) {
+ template = gst_padtemplate_new (
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ gst_caps_new (
+ "test_src",
+ "audio/raw",
+ gst_props_new (
+ "channels", GST_PROPS_INT_RANGE (1, 2),
+ NULL)),
+ NULL);
+ }
+ return template;
+}
+
+static GstPadTemplate*
+level_sink_factory (void)
+{
+ static GstPadTemplate *template = NULL;
+
+ if (!template) {
+ template = gst_padtemplate_new (
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ gst_caps_new (
+ "test_src",
+ "audio/raw",
+ gst_props_new (
+ "channels", GST_PROPS_INT_RANGE (1, 2),
+ NULL)),
+ NULL);
+ }
+ return template;
+}
+
+static void gst_level_class_init (GstLevelClass *klass);
+static void gst_level_init (GstLevel *filter);
+
+static void gst_level_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void gst_level_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+static void gst_level_chain (GstPad *pad, GstBuffer *buf);
+static void inline gst_level_fast_16bit_chain (gint16* data, gint16** out_data,
+ guint numsamples);
+static void inline gst_level_fast_8bit_chain (gint8* data, gint8** out_data,
+ guint numsamples);
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_filter_signals[LAST_SIGNAL] = { 0 };
+
+static GstPadNegotiateReturn
+level_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
+{
+ GstLevel* filter = GST_LEVEL (gst_pad_get_parent (pad));
+
+ if (*caps==NULL)
+ return GST_PAD_NEGOTIATE_FAIL;
+
+ return gst_pad_negotiate_proxy(pad,filter->sinkpad,caps);
+}
+
+static GstPadNegotiateReturn
+level_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
+{
+ GstLevel* filter = GST_LEVEL (gst_pad_get_parent (pad));
+
+ if (*caps==NULL)
+ return GST_PAD_NEGOTIATE_FAIL;
+
+ return gst_pad_negotiate_proxy(pad,filter->srcpad,caps);
+}
+
+GType
+gst_level_get_type(void) {
+ static GType level_type = 0;
+
+ if (!level_type) {
+ static const GTypeInfo level_info = {
+ sizeof(GstLevelClass), NULL,
+ NULL,
+ (GClassInitFunc)gst_level_class_init,
+ NULL,
+ NULL,
+ sizeof(GstLevel),
+ 0,
+ (GInstanceInitFunc)gst_level_init,
+ };
+ level_type = g_type_register_static(GST_TYPE_ELEMENT, "GstLevel", &level_info, 0);
+ }
+ return level_type;
+}
+
+static void
+gst_level_class_init (GstLevelClass *klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+
+ gobject_class = (GObjectClass*)klass;
+ gstelement_class = (GstElementClass*)klass;
+
+ parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+
+ gobject_class->set_property = gst_level_set_property;
+ gobject_class->get_property = gst_level_get_property;
+}
+
+static void
+gst_level_init (GstLevel *filter)
+{
+ filter->sinkpad = gst_pad_new_from_template(level_sink_factory (),"sink");
+ filter->srcpad = gst_pad_new_from_template(level_src_factory (),"src");
+
+ gst_pad_set_negotiate_function(filter->sinkpad,level_negotiate_sink);
+ gst_pad_set_negotiate_function(filter->srcpad,level_negotiate_src);
+
+ gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad);
+ gst_pad_set_chain_function(filter->sinkpad,gst_level_chain);
+ filter->srcpad = gst_pad_new("src",GST_PAD_SRC);
+ gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad);
+}
+
+static void
+gst_level_chain (GstPad *pad,GstBuffer *buf)
+{
+ GstLevel *filter;
+ gint16 *in_data;
+ gint16 *out_data;
+ GstBuffer* outbuf;
+ gint width;
+
+ GstCaps *caps;
+
+ g_return_if_fail(pad != NULL);
+ g_return_if_fail(GST_IS_PAD(pad));
+ g_return_if_fail(buf != NULL);
+
+ filter = GST_LEVEL(GST_OBJECT_PARENT (pad));
+ g_return_if_fail(filter != NULL);
+ g_return_if_fail(GST_IS_LEVEL(filter));
+
+ caps = NULL;
+ caps = GST_PAD_CAPS(pad);
+ if (caps == NULL)
+ {
+ // FIXME : Please change this to a better warning method !
+ printf ("WARNING : chain : Could not get caps of pad !\n");
+ }
+
+ width = gst_caps_get_int(caps, "width");
+
+ in_data = (gint16 *)GST_BUFFER_DATA(buf);
+ outbuf=gst_buffer_new();
+ GST_BUFFER_DATA(outbuf) = (gchar*)g_new(gint16,GST_BUFFER_SIZE(buf)/2);
+ GST_BUFFER_SIZE(outbuf) = GST_BUFFER_SIZE(buf);
+
+ out_data = (gint16*)GST_BUFFER_DATA(outbuf);
+
+ switch (width) {
+ case 16:
+ gst_level_fast_16bit_chain(in_data,&out_data,GST_BUFFER_SIZE(buf)/2);
+ break;
+ case 8:
+ gst_level_fast_8bit_chain((gint8*)in_data,(gint8**)&out_data,GST_BUFFER_SIZE(buf));
+ break;
+ }
+ gst_buffer_unref(buf);
+ gst_pad_push(filter->srcpad,outbuf);
+}
+
+static void inline
+gst_level_fast_16bit_chain(gint16* in_data, gint16** out_data,
+ guint num_samples)
+#include "filter.func"
+
+static void inline
+gst_level_fast_8bit_chain(gint8* in_data, gint8** out_data,
+ guint num_samples)
+#include "filter.func"
+
+static void
+gst_level_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstLevel *filter;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_LEVEL(object));
+ filter = GST_LEVEL(object);
+
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gst_level_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstLevel *filter;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_LEVEL(object));
+ filter = GST_LEVEL(object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+ GstElementFactory *factory;
+
+ factory = gst_elementfactory_new("level",GST_TYPE_LEVEL,
+ &level_details);
+ g_return_val_if_fail(factory != NULL, FALSE);
+
+ gst_elementfactory_add_padtemplate (factory, level_src_factory ());
+ gst_elementfactory_add_padtemplate (factory, level_sink_factory ());
+
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+ return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "level",
+ plugin_init
+};
diff --git a/gst/level/gstlevel.h b/gst/level/gstlevel.h
new file mode 100644
index 00000000..f9dade0a
--- /dev/null
+++ b/gst/level/gstlevel.h
@@ -0,0 +1,69 @@
+/* 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_LEVEL_H__
+#define __GST_LEVEL_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+// #include <gst/meta/audioraw.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GST_TYPE_LEVEL \
+ (gst_level_get_type())
+#define GST_LEVEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LEVEL,GstLevel))
+#define GST_LEVEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstLevel))
+#define GST_IS_LEVEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LEVEL))
+#define GST_IS_LEVEL_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LEVEL))
+
+typedef struct _GstLevel GstLevel;
+typedef struct _GstLevelClass GstLevelClass;
+
+struct _GstLevel {
+ GstElement element;
+
+ GstPad *sinkpad,*srcpad;
+
+ //MetaAudioRaw meta;
+
+};
+
+struct _GstLevelClass {
+ GstElementClass parent_class;
+};
+
+GType gst_level_get_type(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_STEREO_H__ */
diff --git a/gst/median/.gitignore b/gst/median/.gitignore
new file mode 100644
index 00000000..08f5ed37
--- /dev/null
+++ b/gst/median/.gitignore
@@ -0,0 +1,7 @@
+Makefile
+Makefile.in
+*.o
+*.lo
+*.la
+.deps
+.libs
diff --git a/gst/median/Makefile.am b/gst/median/Makefile.am
new file mode 100644
index 00000000..cf75f34f
--- /dev/null
+++ b/gst/median/Makefile.am
@@ -0,0 +1,9 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstmedian.la
+
+libgstmedian_la_SOURCES = gstmedian.c
+
+libgstmedian_la_CFLAGS = -O3 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math $(GST_CFLAGS)
+
+noinst_HEADERS = gstmedian.h
diff --git a/gst/median/gstmedian.c b/gst/median/gstmedian.c
new file mode 100644
index 00000000..f0e836af
--- /dev/null
+++ b/gst/median/gstmedian.c
@@ -0,0 +1,412 @@
+/* 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 <gstmedian.h>
+
+
+static GstElementDetails median_details = {
+ "Median effect",
+ "Filter/Effect",
+ "apply a median filter to an image",
+ VERSION,
+ "Wim Taymans <wim.taymans@chello.be>",
+ "(C) 2000",
+};
+
+GST_PADTEMPLATE_FACTORY (median_src_factory,
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "median_src",
+ "video/raw",
+ "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))
+ )
+)
+
+GST_PADTEMPLATE_FACTORY (median_sink_factory,
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "median_src",
+ "video/raw",
+ "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))
+ )
+)
+
+
+/* Median signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+ ARG_ACTIVE,
+ ARG_FILTERSIZE,
+ ARG_LUM_ONLY
+};
+
+static GType gst_median_get_type (void);
+static void gst_median_class_init (GstMedianClass *klass);
+static void gst_median_init (GstMedian *median);
+
+static void median_5 (unsigned char *src, unsigned char *dest, int height, int width);
+static void median_9 (unsigned char *src, unsigned char *dest, int height, int width);
+static void gst_median_chain (GstPad *pad, GstBuffer *buf);
+
+static void gst_median_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void gst_median_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_median_signals[LAST_SIGNAL] = { 0 };
+
+static GstPadNegotiateReturn
+median_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
+{
+ GstMedian* filter = GST_MEDIAN (gst_pad_get_parent (pad));
+
+ if (*caps==NULL)
+ return GST_PAD_NEGOTIATE_FAIL;
+
+ return gst_pad_negotiate_proxy (pad, filter->sinkpad, caps);
+}
+
+static GstPadNegotiateReturn
+median_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
+{
+ GstMedian* filter = GST_MEDIAN (gst_pad_get_parent (pad));
+
+ if (*caps==NULL)
+ return GST_PAD_NEGOTIATE_FAIL;
+
+ return gst_pad_negotiate_proxy (pad, filter->srcpad, caps);
+}
+
+GType
+gst_median_get_type (void)
+{
+ static GType median_type = 0;
+
+ if (!median_type) {
+ static const GTypeInfo median_info = {
+ sizeof(GstMedianClass), NULL, NULL, (GClassInitFunc)gst_median_class_init,
+ NULL,
+ NULL,
+ sizeof(GstMedian),
+ 0,
+ (GInstanceInitFunc)gst_median_init,
+ };
+ median_type = g_type_register_static(GST_TYPE_ELEMENT, "GstMedian", &median_info, 0);
+ }
+ return median_type;
+}
+
+static void
+gst_median_class_init (GstMedianClass *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_ACTIVE,
+ g_param_spec_boolean("active","active","active",
+ TRUE,G_PARAM_READWRITE)); // CHECKME
+ g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FILTERSIZE,
+ g_param_spec_int("filtersize","filtersize","filtersize",
+ G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME
+ g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_LUM_ONLY,
+ g_param_spec_boolean("lum_only","lum_only","lum_only",
+ TRUE,G_PARAM_READWRITE)); // CHECKME
+
+ gobject_class->set_property = gst_median_set_property;
+ gobject_class->get_property = gst_median_get_property;
+}
+
+static void
+gst_median_newcaps (GstPad *pad, GstCaps *caps)
+{
+ GstMedian *filter;
+
+ filter = GST_MEDIAN (gst_pad_get_parent (pad));
+
+ filter->width = gst_caps_get_int (caps, "width");
+ filter->height = gst_caps_get_int (caps, "height");
+}
+
+void gst_median_init (GstMedian *median)
+{
+ median->sinkpad = gst_pad_new_from_template (
+ GST_PADTEMPLATE_GET (median_sink_factory), "sink");
+ gst_pad_set_negotiate_function (median->sinkpad, median_negotiate_sink);
+ gst_pad_set_newcaps_function (median->sinkpad, gst_median_newcaps);
+ gst_pad_set_chain_function (median->sinkpad, gst_median_chain);
+ gst_element_add_pad (GST_ELEMENT (median), median->sinkpad);
+
+ median->srcpad = gst_pad_new_from_template (
+ GST_PADTEMPLATE_GET (median_src_factory), "src");
+ gst_pad_set_negotiate_function (median->srcpad, median_negotiate_src);
+ gst_element_add_pad (GST_ELEMENT (median), median->srcpad);
+
+ median->filtersize = 5;
+ median->lum_only = TRUE;
+ median->active = TRUE;
+}
+
+#define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); }
+#define PIX_SWAP(a,b) { unsigned char temp=(a);(a)=(b);(b)=temp; }
+
+static void
+median_5 (unsigned char *src, unsigned char *dest, int width, int height)
+{
+ int nLastRow;
+ int nLastCol;
+ unsigned char p[9];
+ int i, j, k;
+
+ nLastCol = width - 1;
+ nLastRow = height - 1;
+
+ //copy the top and bottom rows into the result array
+ for (i=0; i<width; i++) {
+ dest[i] = src[i];
+ dest[nLastRow * width + i] = src[nLastRow * width + i];
+ }
+ dest[i] = src[i];
+
+ nLastCol--;
+ nLastRow--;
+
+ /* process the interior pixels */
+ i = width + 1;
+ for (k=0; k < nLastRow; k++) {
+ for (j=0; j < nLastCol; j++, i++) {
+ p[0] = src[i-width];
+ p[1] = src[i-1];
+ p[2] = src[i];
+ p[3] = src[i+1];
+ p[4] = src[i+width];
+ PIX_SORT(p[0],p[1]) ; PIX_SORT(p[3],p[4]) ; PIX_SORT(p[0],p[3]) ;
+ PIX_SORT(p[1],p[4]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[2],p[3]) ;
+ PIX_SORT(p[1],p[2]) ;
+ dest[i] = p[2];
+ }
+ dest[i] = src[i++];
+ dest[i] = src[i++];
+ }
+ dest[i] = src[i++];
+}
+
+static void
+median_9 (unsigned char *src, unsigned char *dest, int width, int height)
+{
+ int nLastRow;
+ int nLastCol;
+ unsigned char p[9];
+ int i, j, k;
+
+ nLastCol = width - 1;
+ nLastRow = height - 1;
+
+ //copy the top and bottom rows into the result array
+ for (i=0; i<width; i++) {
+ dest[i] = src[i];
+ dest[nLastRow * width + i] = src[nLastRow * width + i];
+ }
+ dest[i] = src[i];
+
+ nLastCol--;
+ nLastRow--;
+
+ /* process the interior pixels */
+ i = width + 1;
+ for (k=0; k < nLastRow; k++) {
+ for (j=0; j < nLastCol; j++, i++) {
+ p[0] = src[i-width-1];
+ p[1] = src[i-width];
+ p[2] = src[i-width+1];
+ p[3] = src[i-1];
+ p[4] = src[i];
+ p[5] = src[i+1];
+ p[6] = src[i+width-1];
+ p[7] = src[i+width];
+ p[8] = src[i+width+1];
+ PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
+ PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ;
+ PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
+ PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ;
+ PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ;
+ PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ;
+ PIX_SORT(p[4], p[2]) ;
+ dest[i] = p[4];
+ }
+ dest[i] = src[i++];
+ dest[i] = src[i++];
+ }
+ dest[i] = src[i++];
+}
+
+static void
+gst_median_chain (GstPad *pad, GstBuffer *buf)
+{
+ GstMedian *median;
+ guchar *data;
+ gulong size;
+ GstBuffer *outbuf;
+// GstMeta *meta;
+ int lumsize, chromsize;
+
+ g_return_if_fail(pad != NULL);
+ g_return_if_fail(GST_IS_PAD(pad));
+ g_return_if_fail(buf != NULL);
+
+ median = GST_MEDIAN (GST_OBJECT_PARENT (pad));
+
+ if (!median->active) {
+ gst_pad_push(median->srcpad,buf);
+ return;
+ }
+
+ data = GST_BUFFER_DATA(buf);
+ size = GST_BUFFER_SIZE(buf);
+
+ GST_DEBUG (0,"median: have buffer of %d\n", GST_BUFFER_SIZE(buf));
+
+ outbuf = gst_buffer_new();
+ GST_BUFFER_DATA(outbuf) = g_malloc(GST_BUFFER_SIZE(buf));
+ GST_BUFFER_SIZE(outbuf) = GST_BUFFER_SIZE(buf);
+
+ lumsize = median->width * median->height;
+ chromsize = lumsize/4;
+
+ if (median->filtersize == 5) {
+ median_5(data, GST_BUFFER_DATA(outbuf), median->width, median->height);
+ if (!median->lum_only) {
+ median_5(data+lumsize, GST_BUFFER_DATA(outbuf)+lumsize, median->width/2, median->height/2);
+ median_5(data+lumsize+chromsize, GST_BUFFER_DATA(outbuf)+lumsize+chromsize, median->width/2, median->height/2);
+ }
+ else {
+ memcpy (GST_BUFFER_DATA (outbuf)+lumsize, data+lumsize, chromsize*2);
+ }
+ }
+ else {
+ median_9(data, GST_BUFFER_DATA(outbuf), median->width, median->height);
+ if (!median->lum_only) {
+ median_9(data+lumsize, GST_BUFFER_DATA(outbuf)+lumsize, median->width/2, median->height/2);
+ median_9(data+lumsize+chromsize, GST_BUFFER_DATA(outbuf)+lumsize+chromsize, median->width/2, median->height/2);
+ }
+ else {
+ memcpy (GST_BUFFER_DATA (outbuf)+lumsize, data+lumsize, chromsize*2);
+ }
+ }
+ GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
+
+ gst_buffer_unref(buf);
+
+ gst_pad_push(median->srcpad,outbuf);
+}
+
+static void
+gst_median_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstMedian *median;
+ gint argvalue;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_MEDIAN(object));
+ median = GST_MEDIAN(object);
+
+ switch (prop_id) {
+ case ARG_FILTERSIZE:
+ argvalue = g_value_get_int (value);
+ if (argvalue != 5 && argvalue != 9) {
+ g_warning ("median: invalid filtersize (%d), must be 5 or 9\n", argvalue);
+ }
+ else {
+ median->filtersize = argvalue;
+ }
+ break;
+ case ARG_ACTIVE:
+ median->active = g_value_get_boolean (value);
+ break;
+ case ARG_LUM_ONLY:
+ median->lum_only = g_value_get_boolean (value);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gst_median_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstMedian *median;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_MEDIAN(object));
+ median = GST_MEDIAN(object);
+
+ switch (prop_id) {
+ case ARG_FILTERSIZE:
+ g_value_set_int (value, median->filtersize);
+ break;
+ case ARG_ACTIVE:
+ g_value_set_boolean (value, median->active);
+ break;
+ case ARG_LUM_ONLY:
+ g_value_set_boolean (value, median->lum_only);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+ GstElementFactory *factory;
+
+ factory = gst_elementfactory_new("median",GST_TYPE_MEDIAN,
+ &median_details);
+ g_return_val_if_fail(factory != NULL, FALSE);
+
+ gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (median_sink_factory));
+ gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (median_src_factory));
+
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+ return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "median",
+ plugin_init
+};
+
diff --git a/gst/median/gstmedian.h b/gst/median/gstmedian.h
new file mode 100644
index 00000000..17c7d042
--- /dev/null
+++ b/gst/median/gstmedian.h
@@ -0,0 +1,72 @@
+/* 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_MEDIAN_H__
+#define __GST_MEDIAN_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GST_TYPE_MEDIAN \
+ (gst_median_get_type())
+#define GST_MEDIAN(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MEDIAN,GstMedian))
+#define GST_MEDIAN_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MEDIAN,GstMedian))
+#define GST_IS_MEDIAN(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MEDIAN))
+#define GST_IS_MEDIAN_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MEDIAN))
+
+typedef struct _GstMedian GstMedian;
+typedef struct _GstMedianClass GstMedianClass;
+
+struct _GstMedian {
+ GstElement element;
+
+ int format;
+ int width;
+ int height;
+
+ int filtersize;
+
+ gboolean active;
+ gboolean lum_only;
+
+ GstPad *sinkpad,*srcpad;
+};
+
+struct _GstMedianClass {
+ GstElementClass parent_class;
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_MEDIAN_H__ */
diff --git a/gst/spectrum/.gitignore b/gst/spectrum/.gitignore
new file mode 100644
index 00000000..08f5ed37
--- /dev/null
+++ b/gst/spectrum/.gitignore
@@ -0,0 +1,7 @@
+Makefile
+Makefile.in
+*.o
+*.lo
+*.la
+.deps
+.libs
diff --git a/gst/spectrum/Makefile.am b/gst/spectrum/Makefile.am
new file mode 100644
index 00000000..476c3fd1
--- /dev/null
+++ b/gst/spectrum/Makefile.am
@@ -0,0 +1,10 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstspectrum.la
+
+libgstspectrum_la_SOURCES = gstspectrum.c fix_fft.c
+libgstspectrum_la_CFLAGS = $(GST_CFLAGS)
+
+noinst_HEADERS = gstspectrum.h
+
+EXTRA_DIST = README
diff --git a/gst/spectrum/README b/gst/spectrum/README
new file mode 100644
index 00000000..87555712
--- /dev/null
+++ b/gst/spectrum/README
@@ -0,0 +1,5 @@
+This is a simple, rather lame spectrum analyzer made from the fix_fft.c
+code, as found I think in xmms-0.9.1 (the 75-wide output sounds like xmms
+to me), which is actually written by other people (see fix_fft.c for
+credits). It worked last time I had GiST working, which was a while ago.
+Yes, GiST is not included here yet, it will be in 0.1.0.
diff --git a/gst/spectrum/gstspectrum.c b/gst/spectrum/gstspectrum.c
new file mode 100644
index 00000000..0821545c
--- /dev/null
+++ b/gst/spectrum/gstspectrum.c
@@ -0,0 +1,242 @@
+/* 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 "gstspectrum.h"
+
+static GstElementDetails gst_spectrum_details = {
+ "Spectrum analyzer",
+ "Filter/Analysis",
+ "Run an FFT on the audio signal, output spectrum data",
+ VERSION,
+ "Erik Walthinsen <omega@cse.ogi.edu>",
+ "(C) 1999",
+};
+
+
+static GstTypeDefinition spectrumdefinition = {
+ "spectrum_spectrum_raw",
+ "spectrum/raw",
+ NULL,
+ NULL,
+};
+
+
+/* Spectrum signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+ ARG_WIDTH,
+};
+
+
+static void gst_spectrum_class_init (GstSpectrumClass *klass);
+static void gst_spectrum_init (GstSpectrum *spectrum);
+
+static void gst_spectrum_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+
+static void gst_spectrum_chain (GstPad *pad, GstBuffer *buf);
+
+#define fixed short
+int gst_spectrum_fix_fft(fixed fr[], fixed fi[], int m, int inverse);
+void gst_spectrum_fix_loud(fixed loud[], fixed fr[], fixed fi[], int n, int scale_shift);
+void gst_spectrum_window(fixed fr[], int n);
+
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_spectrum_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_spectrum_get_type (void)
+{
+ static GType spectrum_type = 0;
+
+ if (!spectrum_type) {
+ static const GTypeInfo spectrum_info = {
+ sizeof(GstSpectrumClass), NULL,
+ NULL,
+ (GClassInitFunc)gst_spectrum_class_init,
+ NULL,
+ NULL,
+ sizeof(GstSpectrum),
+ 0,
+ (GInstanceInitFunc)gst_spectrum_init,
+ };
+ spectrum_type = g_type_register_static(GST_TYPE_ELEMENT, "GstSpectrum", &spectrum_info, 0);
+ }
+ return spectrum_type;
+}
+
+static void
+gst_spectrum_class_init (GstSpectrumClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = (GObjectClass*)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_WRITABLE)); // CHECKME
+
+ gobject_class->set_property = gst_spectrum_set_property;
+}
+
+static void
+gst_spectrum_init (GstSpectrum *spectrum)
+{
+ spectrum->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
+ gst_element_add_pad(GST_ELEMENT(spectrum),spectrum->sinkpad);
+ gst_pad_set_chain_function(spectrum->sinkpad,gst_spectrum_chain);
+ spectrum->srcpad = gst_pad_new("src",GST_PAD_SRC);
+ gst_element_add_pad(GST_ELEMENT(spectrum),spectrum->srcpad);
+
+ spectrum->width = 75;
+}
+
+static void
+gst_spectrum_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstSpectrum *spectrum;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_SPECTRUM(object));
+ spectrum = GST_SPECTRUM(object);
+
+ switch (prop_id) {
+ case ARG_WIDTH:
+ spectrum->width = g_value_get_int (value);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gst_spectrum_chain (GstPad *pad, GstBuffer *buf)
+{
+ GstSpectrum *spectrum;
+ gint spec_base, spec_len;
+ gint16 *re, *im, *loud;
+ gint16 *samples;
+ gint samplecount,step,pos,i;
+ guchar *spect;
+ GstBuffer *newbuf;
+
+ g_return_if_fail(pad != NULL);
+ g_return_if_fail(GST_IS_PAD(pad));
+ g_return_if_fail(buf != NULL);
+
+ spectrum = GST_SPECTRUM (GST_OBJECT_PARENT (pad));
+
+ /* first deal with audio metadata */
+// FIXME
+// if (buf->meta) {
+// if (spectrum->meta != NULL) {
+// /* FIXME: need to unref the old metadata so it goes away */
+// }
+// /* we just make a copy of the pointer */
+// spectrum->meta = (MetaAudioRaw *)(buf->data);
+// /* FIXME: now we have to ref the metadata so it does go away */
+// }
+
+ //g_return_if_fail(spectrum->meta != NULL);
+
+ //samplecount = GST_BUFFER_SIZE(buf) /
+ // (spectrum->meta->channels * sizeof(gint16));
+// samples = (gint16 *)g_malloc(buf->datasize);
+// g_return_if_fail(samples != NULL);
+// memcpy(samples,(gint16
+//*)GST_BUFFER_DATA(buf),GST_BUFFER_DATASIZE(buf));
+// gst_buffer_unref(buf);
+ samples = (gint16 *)GST_BUFFER_DATA(buf);
+
+// return;
+// spec_base = (gint) (log(samplecount) / log(2));
+// if (spec_base > 10) spec_base = 10;
+// spec_len = (gint) pow(2, spec_base);
+ spec_base = 8;
+ spec_len = 1024;
+
+ im = g_malloc(spec_len * sizeof(gint16));
+ g_return_if_fail(im != NULL);
+ loud = g_malloc(spec_len * sizeof(gint16));
+ g_return_if_fail(loud != NULL);
+
+ memset(im,0,spec_len * sizeof(gint16));
+ //if (spectrum->meta->channels == 2) {
+ re = g_malloc(spec_len * sizeof(gint16));
+ for (i=0;i<spec_len;i++)
+ re[i] = (samples[(i*2)] + samples[(i*2)+1]) >> 1;
+ //} else
+ // re = samples;
+ gst_spectrum_window(re,spec_len);
+ gst_spectrum_fix_fft(re,im,spec_base,FALSE);
+ gst_spectrum_fix_loud(loud,re,im,spec_len,0);
+ if (re != samples) g_free(re);
+ g_free(im);
+ step = spec_len / (spectrum->width*2);
+ spect = (guchar *)g_malloc(spectrum->width);
+ for (i=0,pos=0;i<spectrum->width;i++,pos += step) {
+ if (loud[pos] > -60)
+ spect[i] = (loud[pos] + 60) / 2;
+ else
+ spect[i] = 0;
+// if (spect[i] > 15);
+// spect[i] = 15;
+ }
+ g_free(loud);
+ gst_buffer_unref(buf);
+// g_free(samples);
+
+ newbuf = gst_buffer_new();
+ g_return_if_fail(newbuf != NULL);
+ GST_BUFFER_DATA(newbuf) = spect;
+ GST_BUFFER_SIZE(newbuf) = spectrum->width;
+
+ gst_pad_push(spectrum->srcpad,newbuf);
+}
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+ GstElementFactory *factory;
+
+ /* create an elementfactory for the spectrum element */
+ factory = gst_elementfactory_new ("spectrum",GST_TYPE_SPECTRUM,
+ &gst_spectrum_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,
+ "spectrum",
+ plugin_init
+};
diff --git a/gst/spectrum/gstspectrum.h b/gst/spectrum/gstspectrum.h
new file mode 100644
index 00000000..f7a395ec
--- /dev/null
+++ b/gst/spectrum/gstspectrum.h
@@ -0,0 +1,67 @@
+/* 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_SPECTRUM_H__
+#define __GST_SPECTRUM_H__
+
+
+#include <gst/gst.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GST_TYPE_SPECTRUM \
+ (gst_spectrum_get_type())
+#define GST_SPECTRUM(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPECTRUM,GstSpectrum))
+#define GST_SPECTRUM_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPECTRUM,GstSpectrum))
+#define GST_IS_SPECTRUM(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPECTRUM))
+#define GST_IS_SPECTRUM_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPECTRUM))
+
+typedef struct _GstSpectrum GstSpectrum;
+typedef struct _GstSpectrumClass GstSpectrumClass;
+
+struct _GstSpectrum {
+ GstElement element;
+
+ GstPad *sinkpad,*srcpad;
+
+ gint width;
+};
+
+struct _GstSpectrumClass {
+ GstElementClass parent_class;
+};
+
+GType gst_spectrum_get_type(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_SPECTRUM_H__ */
diff --git a/gst/udp/.gitignore b/gst/udp/.gitignore
new file mode 100644
index 00000000..08f5ed37
--- /dev/null
+++ b/gst/udp/.gitignore
@@ -0,0 +1,7 @@
+Makefile
+Makefile.in
+*.o
+*.lo
+*.la
+.deps
+.libs
diff --git a/gst/udp/Makefile.am b/gst/udp/Makefile.am
new file mode 100644
index 00000000..0cd25aac
--- /dev/null
+++ b/gst/udp/Makefile.am
@@ -0,0 +1,10 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstudp.la
+
+libgstudp_la_SOURCES = gstudp.c gstudpsrc.c gstudpsink.c
+libgstudp_la_CFLAGS = $(GST_CFLAGS)
+
+noinst_HEADERS = gstudpsink.h gstudpsrc.h
+
+EXTRA_DIST = README
diff --git a/gst/udp/README b/gst/udp/README
new file mode 100644
index 00000000..e032e74f
--- /dev/null
+++ b/gst/udp/README
@@ -0,0 +1,28 @@
+* What is UDP src/sink?
+
+This plugin is *not* meant to be a professional stream broadcast
+solution, like icecast or realaudio or whatever.
+
+This plugin is basically for testing and simple hacks: raw audio
+or packetized gsm should be fine.
+
+
+* Shortcomings
+
+Even given our modest ambitions, the current code is doesn't handle
+caps negotiation robustly.
+
+
+* Todo
+
+This plugin should offer different modes for caps negotiation: none,
+udp, or tcp. The udp mode should include the caps every five packets
+(approx). The tcp mode can do bi-directional negotiation.
+
+Perhaps this plugin can be the example of how to do caps negotiation
+via a point-to-point protocol.
+
+
+12 Sep 2001
+Wim Taymans <wim.taymans@chello.be>
+Joshua N Pritikin <vishnu@pobox.com>
diff --git a/gst/udp/gstudp.c b/gst/udp/gstudp.c
new file mode 100644
index 00000000..8bea9876
--- /dev/null
+++ b/gst/udp/gstudp.c
@@ -0,0 +1,52 @@
+/* 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 "gstudpsrc.h"
+#include "gstudpsink.h"
+
+/* elementfactory information */
+extern GstElementDetails gst_udpsrc_details;
+extern GstElementDetails gst_udpsink_details;
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+ GstElementFactory *src, *sink;
+
+ /* create an elementfactory for the udpsrc element */
+ sink = gst_elementfactory_new ("udpsink",GST_TYPE_UDPSINK,
+ &gst_udpsink_details);
+ g_return_val_if_fail (sink != NULL, FALSE);
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (sink));
+
+ src = gst_elementfactory_new ("udpsrc",GST_TYPE_UDPSRC,
+ &gst_udpsrc_details);
+ g_return_val_if_fail (src != NULL, FALSE);
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (src));
+
+ return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "udp",
+ plugin_init
+};
diff --git a/gst/udp/gstudpsink.c b/gst/udp/gstudpsink.c
new file mode 100644
index 00000000..81d7a952
--- /dev/null
+++ b/gst/udp/gstudpsink.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 "gstudpsink.h"
+
+#define UDP_DEFAULT_HOST "localhost"
+#define UDP_DEFAULT_PORT 4951
+
+/* elementfactory information */
+GstElementDetails gst_udpsink_details = {
+ "UDP packet sender",
+ "Transport/",
+ "",
+ VERSION,
+ "Wim Taymans <wim.taymans@chello.be>",
+ "(C) 2001",
+};
+
+/* UDPSink signals and args */
+enum {
+ FRAME_ENCODED,
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+ ARG_HOST,
+ ARG_PORT,
+ /* FILL ME */
+};
+
+static void gst_udpsink_class_init (GstUDPSink *klass);
+static void gst_udpsink_init (GstUDPSink *udpsink);
+
+static void gst_udpsink_chain (GstPad *pad,GstBuffer *buf);
+static GstElementStateReturn gst_udpsink_change_state (GstElement *element);
+
+static void gst_udpsink_set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec);
+static void gst_udpsink_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec);
+
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_udpsink_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_udpsink_get_type (void)
+{
+ static GType udpsink_type = 0;
+
+
+ if (!udpsink_type) {
+ static const GTypeInfo udpsink_info = {
+ sizeof(GstUDPSinkClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)gst_udpsink_class_init,
+ NULL,
+ NULL,
+ sizeof(GstUDPSink),
+ 0,
+ (GInstanceInitFunc)gst_udpsink_init,
+ NULL
+ };
+ udpsink_type = g_type_register_static (GST_TYPE_ELEMENT, "GstUDPSink", &udpsink_info, 0);
+ }
+ return udpsink_type;
+}
+
+static void
+gst_udpsink_class_init (GstUDPSink *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_HOST,
+ g_param_spec_string ("host", "nost", "The host to send the packets to",
+ UDP_DEFAULT_HOST, G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PORT,
+ g_param_spec_int ("port", "port", "The port to send the packets to",
+ 0, 32768, UDP_DEFAULT_PORT, G_PARAM_READWRITE));
+
+ gobject_class->set_property = gst_udpsink_set_property;
+ gobject_class->get_property = gst_udpsink_get_property;
+
+ gstelement_class->change_state = gst_udpsink_change_state;
+}
+
+
+static void
+gst_udpsink_newcaps (GstPad *pad, GstCaps *caps)
+{
+ GstUDPSink *udpsink;
+ struct sockaddr_in serv_addr;
+ struct hostent *serverhost;
+ int fd;
+ FILE *f;
+#ifndef GST_DISABLE_LOADSAVE
+ xmlDocPtr doc;
+#endif
+
+ udpsink = GST_UDPSINK (gst_pad_get_parent (pad));
+
+ fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (fd < 0) {
+ perror("socket");
+ return;
+ }
+ memset(&serv_addr, 0, sizeof(serv_addr));
+ /* its a name rather than an ipnum */
+ serverhost = gethostbyname(udpsink->host);
+ if (serverhost == (struct hostent *)0) {
+ perror("gethostbyname");
+ return;
+ }
+ memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length);
+
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_port = htons(udpsink->port);
+
+ if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) {
+ g_printerr ("udpsink: connect to %s port %d failed: %s\n",
+ udpsink->host, udpsink->port, sys_errlist[errno]);
+ return;
+ }
+ f = fdopen (dup (fd), "wb");
+
+#ifndef GST_DISABLE_LOADSAVE
+ doc = xmlNewDoc ("1.0");
+ doc->xmlRootNode = xmlNewDocNode (doc, NULL, "NewCaps", NULL);
+
+ gst_caps_save_thyself (caps, doc->xmlRootNode);
+ xmlDocDump(f, doc);
+#endif
+
+ fclose (f);
+ close (fd);
+}
+
+static void
+gst_udpsink_init (GstUDPSink *udpsink)
+{
+ /* create the sink and src pads */
+ udpsink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
+ gst_element_add_pad (GST_ELEMENT (udpsink), udpsink->sinkpad);
+ gst_pad_set_chain_function (udpsink->sinkpad, gst_udpsink_chain);
+ gst_pad_set_newcaps_function (udpsink->sinkpad, gst_udpsink_newcaps);
+
+ udpsink->host = g_strdup (UDP_DEFAULT_HOST);
+ udpsink->port = UDP_DEFAULT_PORT;
+}
+
+static void
+gst_udpsink_chain (GstPad *pad, GstBuffer *buf)
+{
+ GstUDPSink *udpsink;
+ int tolen;
+
+ g_return_if_fail (pad != NULL);
+ g_return_if_fail (GST_IS_PAD (pad));
+ g_return_if_fail (buf != NULL);
+
+ udpsink = GST_UDPSINK (GST_OBJECT_PARENT (pad));
+
+ tolen = sizeof(udpsink->theiraddr);
+
+ if (sendto (udpsink->sock, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), 0,
+ (struct sockaddr *) &udpsink->theiraddr, tolen) == -1)
+ {
+ perror("sending");
+ }
+
+ gst_buffer_unref(buf);
+}
+
+static void
+gst_udpsink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstUDPSink *udpsink;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_UDPSINK(object));
+ udpsink = GST_UDPSINK(object);
+
+ switch (prop_id) {
+ case ARG_HOST:
+ if (udpsink->host != NULL) g_free(udpsink->host);
+ if (g_value_get_string (value) == NULL)
+ udpsink->host = NULL;
+ else
+ udpsink->host = g_strdup (g_value_get_string (value));
+ break;
+ case ARG_PORT:
+ udpsink->port = g_value_get_int (value);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gst_udpsink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstUDPSink *udpsink;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_UDPSINK(object));
+ udpsink = GST_UDPSINK(object);
+
+ switch (prop_id) {
+ case ARG_HOST:
+ g_value_set_string (value, udpsink->host);
+ break;
+ case ARG_PORT:
+ g_value_set_int (value, udpsink->port);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+// create a socket for sending to remote machine
+static gboolean
+gst_udpsink_init_send (GstUDPSink *sink)
+{
+ struct hostent *he;
+
+ bzero (&sink->theiraddr, sizeof (sink->theiraddr));
+ sink->theiraddr.sin_family = AF_INET; // host byte order
+ sink->theiraddr.sin_port = htons (sink->port); // short, network byte order
+ if ((he = gethostbyname (sink->host)) == NULL) {
+ perror("gethostbyname");
+ return FALSE;
+ }
+ sink->theiraddr.sin_addr = *((struct in_addr *) he->h_addr);
+
+ if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1) {
+ perror("socket");
+ return FALSE;
+ }
+
+ GST_FLAG_SET (sink, GST_UDPSINK_OPEN);
+
+ return TRUE;
+}
+
+static void
+gst_udpsink_close (GstUDPSink *sink)
+{
+ close (sink->sock);
+
+ GST_FLAG_UNSET (sink, GST_UDPSINK_OPEN);
+}
+
+static GstElementStateReturn
+gst_udpsink_change_state (GstElement *element)
+{
+ g_return_val_if_fail (GST_IS_UDPSINK (element), GST_STATE_FAILURE);
+
+ if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
+ if (GST_FLAG_IS_SET (element, GST_UDPSINK_OPEN))
+ gst_udpsink_close (GST_UDPSINK (element));
+ } else {
+ if (!GST_FLAG_IS_SET (element, GST_UDPSINK_OPEN)) {
+ if (!gst_udpsink_init_send (GST_UDPSINK (element)))
+ return GST_STATE_FAILURE;
+ }
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+ return GST_STATE_SUCCESS;
+}
+
diff --git a/gst/udp/gstudpsink.h b/gst/udp/gstudpsink.h
new file mode 100644
index 00000000..4a7c335b
--- /dev/null
+++ b/gst/udp/gstudpsink.h
@@ -0,0 +1,91 @@
+/* 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_UDPSINK_H__
+#define __GST_UDPSINK_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#define GST_TYPE_UDPSINK \
+ (gst_udpsink_get_type())
+#define GST_UDPSINK(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_UDPSINK,GstUDPSink))
+#define GST_UDPSINK_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_UDPSINK,GstUDPSink))
+#define GST_IS_UDPSINK(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_UDPSINK))
+#define GST_IS_UDPSINK_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_UDPSINK))
+
+typedef struct _GstUDPSink GstUDPSink;
+typedef struct _GstUDPSinkClass GstUDPSinkClass;
+
+typedef enum {
+ GST_UDPSINK_OPEN = GST_ELEMENT_FLAG_LAST,
+
+ GST_UDPSINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2,
+} GstUDPSinkFlags;
+
+struct _GstUDPSink {
+ GstElement element;
+
+ /* pads */
+ GstPad *sinkpad,*srcpad;
+
+ int sock;
+ struct sockaddr_in theiraddr;
+
+ gint port;
+ gchar *host;
+};
+
+struct _GstUDPSinkClass {
+ GstElementClass parent_class;
+
+};
+
+GType gst_udpsink_get_type(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_UDPSINK_H__ */
diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c
new file mode 100644
index 00000000..4400a064
--- /dev/null
+++ b/gst/udp/gstudpsrc.c
@@ -0,0 +1,300 @@
+/* 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 "gstudpsrc.h"
+
+#define UDP_DEFAULT_PORT 4951
+
+/* elementfactory information */
+GstElementDetails gst_udpsrc_details = {
+ "UDP packet receiver",
+ "Transport/",
+ "",
+ VERSION,
+ "Wim Taymans <wim.taymans@chello.be>",
+ "(C) 2001",
+};
+
+/* UDPSrc signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+ ARG_PORT,
+ /* FILL ME */
+};
+
+static void gst_udpsrc_class_init (GstUDPSrc *klass);
+static void gst_udpsrc_init (GstUDPSrc *udpsrc);
+
+static GstBuffer* gst_udpsrc_get (GstPad *pad);
+static GstElementStateReturn
+ gst_udpsrc_change_state (GstElement *element);
+
+static void gst_udpsrc_set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec);
+static void gst_udpsrc_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec);
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_udpsrc_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_udpsrc_get_type (void)
+{
+ static GType udpsrc_type = 0;
+
+
+ if (!udpsrc_type) {
+ static const GTypeInfo udpsrc_info = {
+ sizeof(GstUDPSrcClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)gst_udpsrc_class_init,
+ NULL,
+ NULL,
+ sizeof(GstUDPSrc),
+ 0,
+ (GInstanceInitFunc)gst_udpsrc_init,
+ NULL
+ };
+ udpsrc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstUDPSrc", &udpsrc_info, 0);
+ }
+ return udpsrc_type;
+}
+
+static void
+gst_udpsrc_class_init (GstUDPSrc *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_PORT,
+ g_param_spec_int ("port", "port", "The port to receive the packets from",
+ 0, 32768, UDP_DEFAULT_PORT, G_PARAM_READWRITE));
+
+ gobject_class->set_property = gst_udpsrc_set_property;
+ gobject_class->get_property = gst_udpsrc_get_property;
+
+ gstelement_class->change_state = gst_udpsrc_change_state;
+}
+
+
+static void
+gst_udpsrc_init (GstUDPSrc *udpsrc)
+{
+ /* create the src and src pads */
+ udpsrc->srcpad = gst_pad_new ("src", GST_PAD_SRC);
+ gst_element_add_pad (GST_ELEMENT (udpsrc), udpsrc->srcpad);
+ gst_pad_set_get_function (udpsrc->srcpad, gst_udpsrc_get);
+
+ udpsrc->port = UDP_DEFAULT_PORT;
+}
+
+static GstBuffer*
+gst_udpsrc_get (GstPad *pad)
+{
+ GstUDPSrc *udpsrc;
+ GstBuffer *outbuf;
+ struct sockaddr_in tmpaddr;
+ int len, numbytes;
+ fd_set read_fds;
+
+ g_return_val_if_fail (pad != NULL, NULL);
+ g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+
+ udpsrc = GST_UDPSRC (GST_OBJECT_PARENT (pad));
+
+ FD_ZERO (&read_fds);
+ FD_SET (udpsrc->control_sock, &read_fds);
+ FD_SET (udpsrc->sock, &read_fds);
+
+ if (select (udpsrc->control_sock+1, &read_fds, NULL, NULL, NULL) > 0) {
+ if (FD_ISSET (udpsrc->control_sock, &read_fds)) {
+#ifndef GST_DISABLE_LOADSAVE
+ guchar *buf;
+ int ret;
+ int fdread;
+ struct sockaddr addr;
+ socklen_t len;
+ xmlDocPtr doc;
+ GstCaps *caps;
+
+ buf = g_malloc (1024*10);
+
+ len = sizeof (struct sockaddr);
+ fdread = accept (udpsrc->control_sock, &addr, &len);
+ if (fdread < 0) {
+ perror ("accept");
+ }
+
+ ret = read (fdread, buf, 1024*10);
+ if (ret < 0) {
+ perror ("read");
+ }
+ buf[ret] = '\0';
+ doc = xmlParseMemory(buf, ret);
+ caps = gst_caps_load_thyself(doc->xmlRootNode);
+
+ gst_pad_set_caps (udpsrc->srcpad, caps);
+
+#endif
+ outbuf = NULL;
+ }
+ else {
+ outbuf = gst_buffer_new ();
+ GST_BUFFER_DATA (outbuf) = g_malloc (24000);
+ GST_BUFFER_SIZE (outbuf) = 24000;
+
+ numbytes = recvfrom (udpsrc->sock, GST_BUFFER_DATA (outbuf),
+ GST_BUFFER_SIZE (outbuf), 0, (struct sockaddr *)&tmpaddr, &len);
+
+ if (numbytes != -1) {
+ GST_BUFFER_SIZE (outbuf) = numbytes;
+ }
+ else {
+ perror ("recvfrom");
+ gst_buffer_unref (outbuf);
+ outbuf = NULL;
+ }
+
+ }
+ }
+ else {
+ perror ("select");
+ outbuf = NULL;
+ }
+ return outbuf;
+}
+
+
+static void
+gst_udpsrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstUDPSrc *udpsrc;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_UDPSRC(object));
+ udpsrc = GST_UDPSRC(object);
+
+ switch (prop_id) {
+ case ARG_PORT:
+ udpsrc->port = g_value_get_int (value);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gst_udpsrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstUDPSrc *udpsrc;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_UDPSRC(object));
+ udpsrc = GST_UDPSRC(object);
+
+ switch (prop_id) {
+ case ARG_PORT:
+ g_value_set_int (value, udpsrc->port);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+// create a socket for sending to remote machine
+static gboolean
+gst_udpsrc_init_receive (GstUDPSrc *src)
+{
+ bzero (&src->myaddr, sizeof (src->myaddr));
+ src->myaddr.sin_family = AF_INET; // host byte order
+ src->myaddr.sin_port = htons (src->port); // short, network byte order
+ src->myaddr.sin_addr.s_addr = INADDR_ANY;
+
+ if ((src->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1) {
+ perror("socket");
+ return FALSE;
+ }
+
+ if (bind (src->sock, (struct sockaddr *) &src->myaddr, sizeof (src->myaddr)) == -1) {
+ perror("bind");
+ return FALSE;
+ }
+
+ if ((src->control_sock = socket (AF_INET, SOCK_STREAM, 0)) == -1) {
+ perror("control_socket");
+ return FALSE;
+ }
+
+ if (bind (src->control_sock, (struct sockaddr *) &src->myaddr, sizeof (src->myaddr)) == -1) {
+ perror("control_bind");
+ return FALSE;
+ }
+ if (listen (src->control_sock, 5) == -1) {
+ perror("listen");
+ return FALSE;
+ }
+ fcntl (src->control_sock, F_SETFL, O_NONBLOCK);
+
+ GST_FLAG_SET (src, GST_UDPSRC_OPEN);
+
+ return TRUE;
+}
+
+static void
+gst_udpsrc_close (GstUDPSrc *src)
+{
+ close (src->sock);
+
+ GST_FLAG_UNSET (src, GST_UDPSRC_OPEN);
+}
+
+static GstElementStateReturn
+gst_udpsrc_change_state (GstElement *element)
+{
+ g_return_val_if_fail (GST_IS_UDPSRC (element), GST_STATE_FAILURE);
+
+ if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
+ if (GST_FLAG_IS_SET (element, GST_UDPSRC_OPEN))
+ gst_udpsrc_close (GST_UDPSRC (element));
+ } else {
+ if (!GST_FLAG_IS_SET (element, GST_UDPSRC_OPEN)) {
+ if (!gst_udpsrc_init_receive (GST_UDPSRC (element)))
+ return GST_STATE_FAILURE;
+ }
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+ return GST_STATE_SUCCESS;
+}
+
diff --git a/gst/udp/gstudpsrc.h b/gst/udp/gstudpsrc.h
new file mode 100644
index 00000000..cf0d1d38
--- /dev/null
+++ b/gst/udp/gstudpsrc.h
@@ -0,0 +1,88 @@
+/* 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_UDPSRC_H__
+#define __GST_UDPSRC_H__
+
+#include <config.h>
+#include <gst/gst.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#define GST_TYPE_UDPSRC \
+ (gst_udpsrc_get_type())
+#define GST_UDPSRC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_UDPSRC,GstUDPSrc))
+#define GST_UDPSRC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_UDPSRC,GstUDPSrc))
+#define GST_IS_UDPSRC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_UDPSRC))
+#define GST_IS_UDPSRC_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_UDPSRC))
+
+typedef struct _GstUDPSrc GstUDPSrc;
+typedef struct _GstUDPSrcClass GstUDPSrcClass;
+
+typedef enum {
+ GST_UDPSRC_OPEN = GST_ELEMENT_FLAG_LAST,
+
+ GST_UDPSRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2,
+} GstUDPSrcFlags;
+
+struct _GstUDPSrc {
+ GstElement element;
+
+ /* pads */
+ GstPad *sinkpad,*srcpad;
+
+ int port;
+ int sock;
+ int control_sock;
+ struct sockaddr_in myaddr;
+};
+
+struct _GstUDPSrcClass {
+ GstElementClass parent_class;
+};
+
+GType gst_udpsrc_get_type(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_UDPSRC_H__ */
diff --git a/gst/wavparse/.gitignore b/gst/wavparse/.gitignore
new file mode 100644
index 00000000..08f5ed37
--- /dev/null
+++ b/gst/wavparse/.gitignore
@@ -0,0 +1,7 @@
+Makefile
+Makefile.in
+*.o
+*.lo
+*.la
+.deps
+.libs
diff --git a/gst/wavparse/Makefile.am b/gst/wavparse/Makefile.am
new file mode 100644
index 00000000..d9c8e4df
--- /dev/null
+++ b/gst/wavparse/Makefile.am
@@ -0,0 +1,8 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstwavparse.la
+
+libgstwavparse_la_SOURCES = gstwavparse.c gstriff.c
+libgstwavparse_la_CFLAGS = $(GST_CFLAGS)
+
+noinst_HEADERS = gstwavparse.h gstriff.h
diff --git a/gst/wavparse/gstriff.c b/gst/wavparse/gstriff.c
new file mode 100644
index 00000000..d343568c
--- /dev/null
+++ b/gst/wavparse/gstriff.c
@@ -0,0 +1,144 @@
+/* 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 <stdlib.h>
+#include <gstriff.h>
+
+
+GstRiff *gst_riff_new() {
+ GstRiff *riff;
+
+ riff = (GstRiff *)malloc(sizeof(GstRiff));
+ g_return_val_if_fail(riff != NULL, NULL);
+
+ riff->form = 0;
+ riff->chunks = NULL;
+ riff->state = 0;
+ riff->curoffset = 0;
+ riff->nextlikely = 0;
+
+ return riff;
+}
+
+gint gst_riff_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off) {
+ gulong last;
+ GstRiffChunk *chunk;
+
+ g_return_val_if_fail(riff != NULL, 0);
+ g_return_val_if_fail(buf != NULL, 0);
+ g_return_val_if_fail(GST_BUFFER_DATA(buf) != NULL, 0);
+
+ last = off + GST_BUFFER_SIZE(buf);
+
+ if (off == 0) {
+ gulong *words = (gulong *)GST_BUFFER_DATA(buf);
+
+ /* verify this is a valid RIFF file, first of all */
+ if (words[0] != gst_riff_fourcc_to_id("RIFF")) {
+ riff->state = GST_RIFF_ENOTRIFF;
+ return riff->state;
+ }
+ riff->form = words[2];
+// g_print("form is 0x%08x '%s'\n",words[2],gst_riff_id_to_fourcc(words[2]));
+ riff->nextlikely = 12; /* skip 'RIFF', length, and form */
+ }
+
+ /* loop while the next likely chunk header is in this buffer */
+ while ((riff->nextlikely+8) < last) {
+ gulong *words = (gulong *)((guchar *)GST_BUFFER_DATA(buf) + riff->nextlikely);
+
+// g_print("next likely chunk is at offset 0x%08x\n",riff->nextlikely);
+ chunk = (GstRiffChunk *)malloc(sizeof(GstRiffChunk));
+ g_return_val_if_fail(chunk != NULL,0);
+ chunk->offset = riff->nextlikely+8; /* point to the actual data */
+ chunk->id = words[0];
+ chunk->size = words[1];
+// g_print("chunk id is 0x%08x '%s' and is 0x%08x long\n",words[0],
+// gst_riff_id_to_fourcc(words[0]),words[1]);
+ riff->nextlikely += 8 + chunk->size; /* doesn't include hdr */
+ riff->chunks = g_list_prepend(riff->chunks,chunk);
+ }
+
+ return 0;
+}
+
+
+gulong gst_riff_fourcc_to_id(gchar *fourcc) {
+ g_return_val_if_fail(fourcc != NULL,0);
+
+ return (fourcc[0] << 0) | (fourcc[1] << 8) |
+ (fourcc[2] << 16) | (fourcc[3] << 24);
+}
+
+gchar *gst_riff_id_to_fourcc(gulong id) {
+ gchar *fourcc = (gchar *)malloc(5);
+
+ g_return_val_if_fail(fourcc != NULL, NULL);
+
+ fourcc[0] = (id >> 0) & 0xff;
+ fourcc[1] = (id >> 8) & 0xff;
+ fourcc[2] = (id >> 16) & 0xff;
+ fourcc[3] = (id >> 24) & 0xff;
+ fourcc[4] = 0;
+
+ return fourcc;
+}
+
+GList *gst_riff_get_chunk_list(GstRiff *riff) {
+ g_return_val_if_fail(riff != NULL, NULL);
+
+ return riff->chunks;
+}
+
+GstRiffChunk *gst_riff_get_chunk(GstRiff *riff,gchar *fourcc) {
+ GList *chunk;
+
+ g_return_val_if_fail(riff != NULL, NULL);
+ g_return_val_if_fail(fourcc != NULL, NULL);
+
+ chunk = riff->chunks;
+ while (chunk) {
+ if (((GstRiffChunk *)(chunk->data))->id == gst_riff_fourcc_to_id(fourcc))
+ return (GstRiffChunk *)(chunk->data);
+ chunk = g_list_next(chunk);
+ }
+
+ return NULL;
+}
+
+gulong gst_riff_get_nextlikely(GstRiff *riff) {
+ g_return_val_if_fail(riff != NULL, 0);
+
+ return riff->nextlikely;
+}
+
+/*
+ guchar *hchar = (guchar *)(buf->data);
+ gulong hlong = *(gulong *)(buf->data);
+
+ g_print("header is 0x%08x native, %02x %02x %02x %02x, '%c%c%c%c'\n",
+ hlong,
+ hchar[0],hchar[1],hchar[2],hchar[3],
+ hchar[0],hchar[1],hchar[2],hchar[3]);
+ g_print("header 0x%08x translates to '%s'\n",hlong,
+ gst_riff_id_to_fourcc(hlong));
+ g_print("header 0x%08x trancodes to 0x%08x\n",hlong,
+ gst_riff_fourcc_to_id(gst_riff_id_to_fourcc(hlong)));
+*/
diff --git a/gst/wavparse/gstriff.h b/gst/wavparse/gstriff.h
new file mode 100644
index 00000000..de959fdc
--- /dev/null
+++ b/gst/wavparse/gstriff.h
@@ -0,0 +1,67 @@
+/* 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_RIFF_H__
+#define __GST_RIFF_H__
+
+
+#include <gst/gstbuffer.h>
+#include <gst/gstplugin.h>
+
+
+#define GST_RIFF_ENOTRIFF -1 /* not a RIFF file */
+
+
+typedef struct _GstRiff GstRiff;
+typedef struct _GstRiffChunk GstRiffChunk;
+
+struct _GstRiff {
+ guint32 form;
+
+ /* list of chunks, most recent at the head */
+ GList *chunks;
+
+ /* parse state */
+ gint state;
+ guint32 curoffset;
+ guint32 nextlikely;
+};
+
+struct _GstRiffChunk {
+ gulong offset;
+
+ guint32 id;
+ guint32 size;
+};
+
+
+GstRiff *gst_riff_new();
+gint gst_riff_next_buffer(GstRiff *riff,GstBuffer *buf,gulong off);
+GList *gst_riff_get_chunk_list(GstRiff *riff);
+GstRiffChunk *gst_riff_get_chunk(GstRiff *riff,gchar *fourcc);
+GstRiffChunk *gst_riff_get_chunk_number(GstRiff *riff,gint number);
+
+gulong gst_riff_get_nextlikely(GstRiff *riff);
+
+gulong gst_riff_fourcc_to_id(gchar *fourcc);
+gchar *gst_riff_id_to_fourcc(gulong id);
+
+
+#endif /* __GST_RIFF_H__ */
diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c
new file mode 100644
index 00000000..2e57da83
--- /dev/null
+++ b/gst/wavparse/gstwavparse.c
@@ -0,0 +1,367 @@
+/* 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 <gstwavparse.h>
+
+static void gst_parsewav_class_init (GstParseWavClass *klass);
+static void gst_parsewav_init (GstParseWav *parsewav);
+
+static GstCaps* wav_typefind (GstBuffer *buf, gpointer private);
+
+static void gst_parsewav_chain (GstPad *pad, GstBuffer *buf);
+
+/* elementfactory information */
+static GstElementDetails gst_parsewav_details = {
+ ".wav parser",
+ "Parser/Audio",
+ "Parse a .wav file into raw audio",
+ VERSION,
+ "Erik Walthinsen <omega@cse.ogi.edu>",
+ "(C) 1999",
+};
+
+GST_PADTEMPLATE_FACTORY (sink_template_factory,
+ "parsewav_sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "parsewav_wav",
+ "audio/wav",
+ NULL
+ )
+)
+
+GST_PADTEMPLATE_FACTORY (src_template_factory,
+ "parsewav_src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "parsewav_raw",
+ "audio/raw",
+ "format", GST_PROPS_STRING ("int"),
+ "law", GST_PROPS_INT (0),
+ "endianness", GST_PROPS_INT (G_BYTE_ORDER),
+ "signed", GST_PROPS_BOOLEAN (TRUE),
+ "width", GST_PROPS_LIST (
+ GST_PROPS_INT (8),
+ GST_PROPS_INT (16)
+ ),
+ "depth", GST_PROPS_LIST (
+ GST_PROPS_INT (8),
+ GST_PROPS_INT (16)
+ ),
+ "rate", GST_PROPS_INT_RANGE (8000, 48000),
+ "channels", GST_PROPS_INT_RANGE (1, 2)
+ )
+)
+
+/* typefactory for 'wav' */
+static GstTypeDefinition
+wavdefinition =
+{
+ "parsewav_audio/wav",
+ "audio/wav",
+ ".wav",
+ wav_typefind,
+};
+
+
+/* ParseWav signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+ /* FILL ME */
+};
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_parsewav_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_parsewav_get_type (void)
+{
+ static GType parsewav_type = 0;
+
+ if (!parsewav_type) {
+ static const GTypeInfo parsewav_info = {
+ sizeof(GstParseWavClass), NULL,
+ NULL,
+ (GClassInitFunc) gst_parsewav_class_init,
+ NULL,
+ NULL,
+ sizeof(GstParseWav),
+ 0,
+ (GInstanceInitFunc) gst_parsewav_init,
+ };
+ parsewav_type = g_type_register_static (GST_TYPE_ELEMENT, "GstParseWav", &parsewav_info, 0);
+ }
+ return parsewav_type;
+}
+
+static void
+gst_parsewav_class_init (GstParseWavClass *klass)
+{
+ GstElementClass *gstelement_class;
+
+ gstelement_class = (GstElementClass*) klass;
+
+ parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+}
+
+static void
+gst_parsewav_init (GstParseWav *parsewav)
+{
+ parsewav->sinkpad = gst_pad_new_from_template (GST_PADTEMPLATE_GET (sink_template_factory), "sink");
+ gst_element_add_pad (GST_ELEMENT (parsewav), parsewav->sinkpad);
+ gst_pad_set_chain_function (parsewav->sinkpad, gst_parsewav_chain);
+
+ parsewav->srcpad = gst_pad_new_from_template (GST_PADTEMPLATE_GET (src_template_factory), "src");
+ gst_element_add_pad (GST_ELEMENT (parsewav), parsewav->srcpad);
+
+ parsewav->riff = NULL;
+
+ parsewav->state = GST_PARSEWAV_UNKNOWN;
+ parsewav->riff = NULL;
+ parsewav->riff_nextlikely = 0;
+ parsewav->size = 0;
+ parsewav->bps = 0;
+}
+
+static GstCaps*
+wav_typefind (GstBuffer *buf, gpointer private)
+{
+ gchar *data = GST_BUFFER_DATA (buf);
+
+ if (strncmp (&data[0], "RIFF", 4)) return NULL;
+ if (strncmp (&data[8], "WAVE", 4)) return NULL;
+
+ return gst_caps_new ("wav_typefind", "audio/wav", NULL);
+}
+
+
+static void
+gst_parsewav_chain (GstPad *pad, GstBuffer *buf)
+{
+ GstParseWav *parsewav;
+ gboolean buffer_riffed = FALSE; /* so we don't parse twice */
+ gchar *data;
+ gulong size;
+
+ 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_BUFFER_DATA (buf) != NULL);
+
+ parsewav = GST_PARSEWAV (gst_pad_get_parent (pad));
+ GST_DEBUG (0, "gst_parsewav_chain: got buffer in '%s'\n",
+ gst_object_get_name (GST_OBJECT (parsewav)));
+ data = (guchar *) GST_BUFFER_DATA (buf);
+ size = GST_BUFFER_SIZE (buf);
+
+ /* walk through the states in priority order */
+ /* we're in the data region */
+ if (parsewav->state == GST_PARSEWAV_DATA) {
+ /* if we're expected to see a new chunk in this buffer */
+ if ((parsewav->riff_nextlikely - GST_BUFFER_OFFSET (buf)) < GST_BUFFER_SIZE (buf)) {
+
+ GST_BUFFER_SIZE (buf) = parsewav->riff_nextlikely - GST_BUFFER_OFFSET (buf);
+
+ parsewav->state = GST_PARSEWAV_OTHER;
+ /* I suppose we could signal an EOF at this point, but that may be
+ premature. We've stopped data flow, that's the main thing. */
+ }
+ gst_pad_push (parsewav->srcpad, buf);
+ return;
+ }
+
+ if (parsewav->state == GST_PARSEWAV_OTHER) {
+ GST_DEBUG (0, "we're in unknown territory here, not passing on\n");
+ return;
+ }
+
+
+ /* here we deal with parsing out the primary state */
+ /* these are sequenced such that in the normal case each (RIFF/WAVE,
+ fmt, data) will fire in sequence, as they should */
+
+ /* we're in null state now, look for the RIFF header, start parsing */
+ if (parsewav->state == GST_PARSEWAV_UNKNOWN) {
+ gint retval;
+
+ GST_DEBUG (0, "GstParseWav: checking for RIFF format\n");
+
+ /* create a new RIFF parser */
+ parsewav->riff = gst_riff_new ();
+
+ /* give it the current buffer to start parsing */
+ retval = gst_riff_next_buffer (parsewav->riff, buf, 0);
+ buffer_riffed = TRUE;
+ if (retval < 0) {
+ GST_DEBUG (0, "sorry, isn't RIFF\n");
+ return;
+ }
+
+ /* this has to be a file of form WAVE for us to deal with it */
+ if (parsewav->riff->form != gst_riff_fourcc_to_id ("WAVE")) {
+ GST_DEBUG (0, "sorry, isn't WAVE\n");
+ return;
+ }
+
+ /* at this point we're waiting for the 'fmt ' chunk */
+ parsewav->state = GST_PARSEWAV_CHUNK_FMT;
+ }
+
+ /* we're now looking for the 'fmt ' chunk to get the audio info */
+ if (parsewav->state == GST_PARSEWAV_CHUNK_FMT) {
+ GstRiffChunk *fmt;
+ GstParseWavFormat *format;
+
+ GST_DEBUG (0, "GstParseWav: looking for fmt chunk\n");
+
+ /* there's a good possibility we may not have parsed this buffer */
+ if (buffer_riffed == FALSE) {
+ gst_riff_next_buffer (parsewav->riff, buf, GST_BUFFER_OFFSET (buf));
+ buffer_riffed = TRUE;
+ }
+
+ /* see if the fmt chunk is available yet */
+ fmt = gst_riff_get_chunk (parsewav->riff, "fmt ");
+
+ /* if we've got something, deal with it */
+ if (fmt != NULL) {
+
+ /* we can gather format information now */
+ format = (GstParseWavFormat *)((guchar *) GST_BUFFER_DATA (buf) + fmt->offset);
+
+ /* set the caps on the src pad */
+ gst_pad_set_caps (parsewav->srcpad, gst_caps_new (
+ "parsewav_src",
+ "audio/raw",
+ gst_props_new (
+ "format", GST_PROPS_STRING ("int"),
+ "law", GST_PROPS_INT (0), //FIXME
+ "endianness", GST_PROPS_INT (G_BYTE_ORDER),
+ "signed", GST_PROPS_BOOLEAN (TRUE), //FIXME
+ "width", GST_PROPS_INT (format->wBitsPerSample),
+ "depth", GST_PROPS_INT (format->wBitsPerSample),
+ "rate", GST_PROPS_INT (format->dwSamplesPerSec),
+ "channels", GST_PROPS_INT (format->wChannels),
+ NULL
+ )
+ ));
+
+ parsewav->bps = format->wBlockAlign;
+ GST_DEBUG (0, "frequency %d, channels %d\n",
+ format->dwSamplesPerSec, format->wChannels);
+
+ /* we're now looking for the data chunk */
+ parsewav->state = GST_PARSEWAV_CHUNK_DATA;
+ } else {
+ /* otherwise we just sort of give up for this buffer */
+ gst_buffer_unref (buf);
+ return;
+ }
+ }
+
+ /* now we look for the data chunk */
+ if (parsewav->state == GST_PARSEWAV_CHUNK_DATA) {
+ GstBuffer *newbuf;
+ GstRiffChunk *datachunk;
+
+ GST_DEBUG (0, "GstParseWav: looking for data chunk\n");
+
+ /* again, we might need to parse the buffer */
+ if (buffer_riffed == FALSE) {
+ gst_riff_next_buffer (parsewav->riff, buf, GST_BUFFER_OFFSET (buf));
+ buffer_riffed = TRUE;
+ }
+
+ datachunk = gst_riff_get_chunk (parsewav->riff, "data");
+
+ if (datachunk != NULL) {
+ gulong subsize;
+
+ GST_DEBUG (0, "data begins at %ld\n", datachunk->offset);
+
+ /* at this point we can ACK that we have data */
+ parsewav->state = GST_PARSEWAV_DATA;
+
+ /* now we construct a new buffer for the remainder */
+ subsize = size - datachunk->offset;
+ GST_DEBUG (0, "sending last %ld bytes along as audio\n", subsize);
+
+ newbuf = gst_buffer_new ();
+ GST_BUFFER_DATA (newbuf) = g_malloc (subsize);
+ GST_BUFFER_SIZE (newbuf) = subsize;
+
+ memcpy (GST_BUFFER_DATA (newbuf), GST_BUFFER_DATA (buf) + datachunk->offset, subsize);
+
+ gst_buffer_unref (buf);
+
+ gst_pad_push (parsewav->srcpad, newbuf);
+
+ /* now we're ready to go, the next buffer should start data */
+ parsewav->state = GST_PARSEWAV_DATA;
+
+ /* however, we may be expecting another chunk at some point */
+ parsewav->riff_nextlikely = gst_riff_get_nextlikely (parsewav->riff);
+ } else {
+ /* otherwise we just sort of give up for this buffer */
+ gst_buffer_unref (buf);
+ return;
+ }
+ }
+}
+
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+ GstElementFactory *factory;
+ GstTypeFactory *type;
+
+ /* create an elementfactory for the parsewav element */
+ factory = gst_elementfactory_new ("parsewav", GST_TYPE_PARSEWAV,
+ &gst_parsewav_details);
+ g_return_val_if_fail(factory != NULL, FALSE);
+
+ /* register src pads */
+ gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_template_factory));
+ gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_template_factory));
+
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+ type = gst_typefactory_new (&wavdefinition);
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
+
+ return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "parsewav",
+ plugin_init
+};
diff --git a/gst/wavparse/gstwavparse.h b/gst/wavparse/gstwavparse.h
new file mode 100644
index 00000000..55cb4913
--- /dev/null
+++ b/gst/wavparse/gstwavparse.h
@@ -0,0 +1,99 @@
+/* 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_PARSEWAV_H__
+#define __GST_PARSEWAV_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+#include <gstriff.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GST_TYPE_PARSEWAV \
+ (gst_parsewav_get_type())
+#define GST_PARSEWAV(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PARSEWAV,GstParseWav))
+#define GST_PARSEWAV_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PARSEWAV,GstParseWav))
+#define GST_IS_PARSEWAV(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PARSEWAV))
+#define GST_IS_PARSEWAV_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PARSEWAV))
+
+
+#define GST_PARSEWAV_UNKNOWN 0 /* initialized state */
+#define GST_PARSEWAV_CHUNK_FMT 1 /* searching for fmt */
+#define GST_PARSEWAV_CHUNK_DATA 2 /* searching for data */
+#define GST_PARSEWAV_DATA 3 /* in data region */
+#define GST_PARSEWAV_OTHER 4 /* in unknown region */
+
+typedef struct _GstParseWav GstParseWav;
+typedef struct _GstParseWavClass GstParseWavClass;
+
+struct _GstParseWav {
+ GstElement element;
+
+ /* pads */
+ GstPad *sinkpad,*srcpad;
+
+ /* WAVE decoding state */
+ gint state;
+
+ /* RIFF decoding state */
+ GstRiff *riff;
+ gulong riff_nextlikely;
+
+ /* expected length of audio */
+ gulong size;
+
+ /* useful audio data */
+ gint bps;
+
+};
+
+struct _GstParseWavClass {
+ GstElementClass parent_class;
+};
+
+GType gst_parsewav_get_type(void);
+
+typedef struct _GstParseWavFormat GstParseWavFormat;
+
+struct _GstParseWavFormat {
+ gint16 wFormatTag;
+ guint16 wChannels;
+ guint32 dwSamplesPerSec;
+ guint32 dwAvgBytesPerSec;
+ guint16 wBlockAlign;
+ guint16 wBitsPerSample;
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_PARSEAU_H__ */