diff options
Diffstat (limited to 'ext/arts')
-rw-r--r-- | ext/arts/Makefile.am | 30 | ||||
-rw-r--r-- | ext/arts/gst_arts.c | 243 | ||||
-rw-r--r-- | ext/arts/gst_arts.h | 66 | ||||
-rw-r--r-- | ext/arts/gst_artsio.idl | 21 | ||||
-rw-r--r-- | ext/arts/gst_artsio_impl.cc | 159 | ||||
-rw-r--r-- | ext/arts/gst_artsio_impl.h | 14 |
6 files changed, 533 insertions, 0 deletions
diff --git a/ext/arts/Makefile.am b/ext/arts/Makefile.am new file mode 100644 index 00000000..0be9ebb4 --- /dev/null +++ b/ext/arts/Makefile.am @@ -0,0 +1,30 @@ +filterdir = $(libdir)/gst + +filter_LTLIBRARIES = libgst_arts.la + +gst_artsio_impl.lo: gst_artsio.cc + +SUFFIXES = .idl +.idl.cc: + mcopidl -t $< $(ARTS_MCOPFLAGS) + +# mcopidl Extension Expansion Technology clean up +CLEANFILES = gst_artsio.h gst_artsio.cc gst_artsio.mcopclass gst_artsio.mcoptype + +libgst_arts_la_SOURCES = gst_arts.c gst_artsio.cc gst_artsio_impl.cc +noinst_HEADERS = gst_arts.h gst_artsio_impl.h + +# FIXME automake 1.4 hack, 1.5 should let us put the .idl in +# _SOURCES at which point the follow can be removed +EXTRA_DIST = gst_artsio.idl +dist-hook: + rm -f $(distdir)/gst_artsio.cc + +# gst_artsio.cc and gst_artsio.h are generated from the idl, and the tools +# needed to do this should be present on any platform where the rest of arts +# is present: therefore, these don't need to go in the dist. +#EXTRA_DIST = gst_artsio.cc gst_artsio.h + +libgst_arts_la_CFLAGS = $(ARTS_CFLAGS) +libgst_arts_la_CXXFLAGS = $(ARTS_CFLAGS) $(CFLAGS) +libgst_arts_la_LDFLAGS = $(ARTS_LIBS) diff --git a/ext/arts/gst_arts.c b/ext/arts/gst_arts.c new file mode 100644 index 00000000..a513f677 --- /dev/null +++ b/ext/arts/gst_arts.c @@ -0,0 +1,243 @@ +/* GStreamer + * 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 <math.h> +#include <sys/soundcard.h> + +//#define DEBUG_ENABLED +#include "gst_arts.h" +#include "gst_artsio_impl.h" + +/* elementfactory information */ +static GstElementDetails gst_arts_details = { + "aRts plugin", + "Filter/Audio", + "aRts plugin", + VERSION, + "Erik Walthinsen <omega@temple-baptist.com, +Stefan Westerfeld <stefan@space.twc.de>", + "(C) 2000", +}; + + +GST_PADTEMPLATE_FACTORY ( sink_temp, + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "arts_sample", + "audio/raw", + "format", GST_PROPS_INT ("int"), + "law", GST_PROPS_INT (0), + "depth", GST_PROPS_INT (16), + "width", GST_PROPS_INT (16), + "signed", GST_PROPS_BOOLEAN (TRUE), + "channels", GST_PROPS_INT (2), + "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN) + ) +) + +GST_PADTEMPLATE_FACTORY ( src_temp, + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "arts_sample", + "audio/raw", + "format", GST_PROPS_INT ("int"), + "law", GST_PROPS_INT (0), + "depth", GST_PROPS_INT (16), + "width", GST_PROPS_INT (16), + "signed", GST_PROPS_BOOLEAN (TRUE), + "channels", GST_PROPS_INT (2), + "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN) + ) +) + +static GstPadTemplate* +mad_src_template_factory (void) +{ + static GstPadTemplate *templ = NULL; + + if (!templ) { + templ = gst_padtemplate_new ( + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + gst_caps_new ( + "mad_src", + "audio/raw", + gst_props_new ( + "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_INT (16), + "depth", GST_PROPS_INT (16), + "rate", GST_PROPS_INT (44100), + "channels", GST_PROPS_INT (2), + NULL)), + NULL); + } + return templ; +} + +enum { + ARG_0, + ARG_LAST, +}; + +static void gst_arts_class_init (GstARTSClass *klass); +static void gst_arts_init (GstARTS *arts); + +static void gst_arts_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void gst_arts_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + +static GstElementStateReturn gst_arts_change_state (GstElement *element); +static void gst_arts_loop (GstElement *element); + + +static GstElementClass *parent_class = NULL; +//static guint gst_arts_signals[LAST_SIGNAL] = { 0 }; + +GType +gst_arts_get_type (void) +{ + static GType gst_arts_type = 0; + + if (!gst_arts_type) { + static const GTypeInfo gst_arts_info = { + sizeof(GstARTSClass), NULL, + NULL, + (GClassInitFunc)gst_arts_class_init, + NULL, + NULL, + sizeof(GstARTS), + 0, + (GInstanceInitFunc)gst_arts_init, + }; + gst_arts_type = g_type_register_static(GST_TYPE_ELEMENT, "GstArts", &gst_arts_info, 0); + } + return gst_arts_type; +} + +static void +gst_arts_class_init (GstARTSClass *klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + gobject_class->set_property = gst_arts_set_property; + gobject_class->get_property = gst_arts_get_property; + + gstelement_class->change_state = gst_arts_change_state; +} + +static void +gst_arts_init (GstARTS *arts) +{ + arts->sinkpad = gst_pad_new_from_template(GST_PADTEMPLATE_GET(sink_temp),"sink"); + gst_element_add_pad(GST_ELEMENT(arts),arts->sinkpad); + +// arts->srcpad = gst_pad_new_from_template(GST_PADTEMPLATE_GET(src_temp),"src"); + arts->srcpad = gst_pad_new_from_template(mad_src_template_factory (), "src"); + gst_element_add_pad(GST_ELEMENT(arts),arts->srcpad); + + gst_element_set_loop_function (GST_ELEMENT (arts), gst_arts_loop); + + arts->wrapper = gst_arts_wrapper_new(arts->sinkpad,arts->srcpad); +} + +static void +gst_arts_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstARTS *arts = (GstARTS*)object; + GstARTSClass *oclass = (GstARTSClass*)(G_OBJECT_CLASS (object)); + +} + +static void +gst_arts_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstARTS *arts = (GstARTS*)object; + GstARTSClass *oclass = (GstARTSClass*)(G_OBJECT_CLASS (object)); + +} + +static GstElementStateReturn +gst_arts_change_state (GstElement *element) +{ + GstARTS *arts = (GstARTS*)element; + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_NULL_TO_READY: + break; + default: + break; + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); + + return GST_STATE_SUCCESS; +} + +static void +gst_arts_loop (GstElement *element) +{ + GstARTS *arts = (GstARTS*)element; + + g_return_if_fail (arts != NULL); + +// do { + + gst_arts_wrapper_do(arts->wrapper); + +// } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); +} + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + GstElementFactory *gstarts; + + parent_class = g_type_class_ref(GST_TYPE_ELEMENT); + + gstarts = gst_elementfactory_new("gstarts",GST_TYPE_ARTS,&gst_arts_details); + g_return_val_if_fail(gstarts != NULL, FALSE); + + gst_elementfactory_add_padtemplate(gstarts, GST_PADTEMPLATE_GET(sink_temp)); +// gst_elementfactory_add_padtemplate(gstarts, GST_PADTEMPLATE_GET(src_temp)); + gst_elementfactory_add_padtemplate(gstarts, mad_src_template_factory ()); + + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (gstarts)); + + return TRUE; +} + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "gst_arts", + plugin_init +}; diff --git a/ext/arts/gst_arts.h b/ext/arts/gst_arts.h new file mode 100644 index 00000000..9ecdbaef --- /dev/null +++ b/ext/arts/gst_arts.h @@ -0,0 +1,66 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> + * + * gstarts.h: Header for ARTS plugin + * + * 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_ARTS_H__ +#define __GST_ARTS_H__ + + +#include <config.h> +#include <gst/gst.h> + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define GST_TYPE_ARTS \ + (gst_arts_get_type()) +#define GST_ARTS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ARTS,GstARTS)) +#define GST_ARTS_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ARTS,GstARTS)) +#define GST_IS_ARTS(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ARTS)) +#define GST_IS_ARTS_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ARTS)) + +typedef struct _GstARTS GstARTS; +typedef struct _GstARTSClass GstARTSClass; + +struct _GstARTS { + GstElement element; + + GstPad *sinkpad, *srcpad; + void *wrapper; +}; + +struct _GstARTSClass { + GstElementClass parent_class; +}; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_ARTS_H__ */ diff --git a/ext/arts/gst_artsio.idl b/ext/arts/gst_artsio.idl new file mode 100644 index 00000000..b656a0ac --- /dev/null +++ b/ext/arts/gst_artsio.idl @@ -0,0 +1,21 @@ +#include "artsflow.idl" + +module Gst { + +interface ArtsMonoSink : Arts::SynthModule { + default out audio stream output; +}; + +interface ArtsStereoSink : Arts::SynthModule { + default out audio stream outleft,outright; +}; + +interface ArtsMonoSrc : Arts::SynthModule { + default in audio stream input; +}; + +interface ArtsStereoSrc : Arts::SynthModule { + default in audio stream inleft,inright; +}; + +}; diff --git a/ext/arts/gst_artsio_impl.cc b/ext/arts/gst_artsio_impl.cc new file mode 100644 index 00000000..4d7eb3f9 --- /dev/null +++ b/ext/arts/gst_artsio_impl.cc @@ -0,0 +1,159 @@ +#include <math.h> +#include "artsflow.h" +#include "stdsynthmodule.h" +#include "gst_artsio.h" +#include "convert.h" +#include "connect.h" +#include "flowsystem.h" + +#include <gst/gst.h> + +using namespace Arts; + +namespace Gst { + +class ArtsStereoSink_impl : virtual public ArtsStereoSink_skel, + virtual public StdSynthModule +{ + + GstPad *sinkpad; + long remainingsamples; + GstBuffer *inbuf; + unsigned char *dataptr; + +public: + + ArtsStereoSink_impl() + { + remainingsamples = 0; + inbuf = NULL; + dataptr = NULL; + } + + void calculateBlock (unsigned long samples) + { + unsigned long fulfilled = 0; +//gint16 *s; +//fprintf(stderr,"StereoSink: getting %d samples\n",samples); + + while (fulfilled < samples) { + if (remainingsamples == 0) { +//fprintf(stderr,"need to get a buffer\n"); + if (inbuf) { + gst_buffer_unref(inbuf); + inbuf = 0; + } + + // start by pulling a buffer from GStreamer + inbuf = gst_pad_pull (sinkpad); + dataptr = GST_BUFFER_DATA(inbuf); + remainingsamples = GST_BUFFER_SIZE(inbuf) / 4; +//fprintf(stderr,"got a buffer with %d samples\n",remainingsamples); + } + + unsigned long count = MIN(remainingsamples,samples-fulfilled); +//fprintf(stderr,"have %d samples left, can fill %d\n",remainingsamples,count); + convert_stereo_i16le_2float(count,dataptr,outleft,outright); +//s = (gint16 *)dataptr; +//fprintf(stderr,"samples in are %d and %d, out are %f and %f\n",s[0],s[1],outleft[0],outright[0]); + remainingsamples -= count; + dataptr += 4 * count; + fulfilled += count; + } + } + + + void setPad(GstPad *pad) + { + sinkpad = pad; + } +}; + + +class ArtsStereoSrc_impl : virtual public ArtsStereoSrc_skel, + virtual public StdSynthModule +{ + + GstPad *srcpad; + GstBuffer *outbuf; + unsigned char *dataptr; + +public: + + void calculateBlock (unsigned long samples) + { +//gint16 *s; +//fprintf(stderr,"StereoSrc: handed %d samples\n",samples); + outbuf = gst_buffer_new(); + GST_BUFFER_DATA(outbuf) = (guchar *)g_malloc(samples*4); + GST_BUFFER_SIZE(outbuf) = samples*4; + memset(GST_BUFFER_DATA(outbuf),0,samples*4); + convert_stereo_2float_i16le(samples,inleft,inright,GST_BUFFER_DATA(outbuf)); +//s = (gint16 *)GST_BUFFER_DATA(outbuf); +//fprintf(stderr,"samples in are %f and %f, out are %d and %d\n",inleft[0],inright[0],s[0],s[1]); + gst_pad_push(srcpad,outbuf); + outbuf = NULL; + } + + + void setPad(GstPad *pad) + { + srcpad = pad; + } +}; + +class GstArtsWrapper { + Dispatcher *dispatcher; + ArtsStereoSink sink; + ArtsStereoSrc source; + StereoVolumeControl effect; + +public: + GstArtsWrapper(GstPad *sinkpad, GstPad *sourcepad) { + dispatcher = new Arts::Dispatcher(); + ArtsStereoSink_impl *sink_impl = new ArtsStereoSink_impl(); + ArtsStereoSrc_impl *source_impl = new ArtsStereoSrc_impl(); + sink_impl->setPad(sinkpad); + source_impl->setPad(sourcepad); + sink = ArtsStereoSink::_from_base(sink_impl); + source = ArtsStereoSrc::_from_base(source_impl); + sink.start(); + effect.start(); + source.start(); + effect.scaleFactor(0.5); + connect(sink, effect); + connect(effect, source); +// connect(sink,source); + } + void iterate() + { + source._node()->requireFlow(); + } +}; + + +}; + + +extern "C" { + +void *gst_arts_wrapper_new(GstPad *sinkpad, GstPad *sourcepad) +{ + return new Gst::GstArtsWrapper(sinkpad, sourcepad); +} + +void gst_arts_wrapper_free(void *wrapper) +{ + Gst::GstArtsWrapper *w = (Gst::GstArtsWrapper *)wrapper; + delete w; +} + +void gst_arts_wrapper_do(void *wrapper) +{ + Gst::GstArtsWrapper *w = (Gst::GstArtsWrapper *)wrapper; + w->iterate(); +} + +} + +// vim:sts=2:sw=2 diff --git a/ext/arts/gst_artsio_impl.h b/ext/arts/gst_artsio_impl.h new file mode 100644 index 00000000..8ffb29b6 --- /dev/null +++ b/ext/arts/gst_artsio_impl.h @@ -0,0 +1,14 @@ +#include <gst/gst.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void *gst_arts_wrapper_new(GstPad *sinkpad, GstPad *sourcepad); +void gst_arts_wrapper_free(void *wrapper); +void gst_arts_wrapper_do(void *wrapper); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + |