summaryrefslogtreecommitdiffstats
path: root/ext/arts/gst_artsio_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/arts/gst_artsio_impl.cc')
-rw-r--r--ext/arts/gst_artsio_impl.cc159
1 files changed, 159 insertions, 0 deletions
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