#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "artsflow.h" #include "stdsynthmodule.h" #include "gst_artsio.h" #include "convert.h" #include "connect.h" #include "flowsystem.h" #include using namespace Arts; namespace Gst { class ArtsStereoSink_impl:virtual public ArtsStereoSink_skel, virtual public StdSynthModule { GstPad *sinkpad; GstPad *srcpad; unsigned long remainingsamples; GstData *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_data_unref (inbuf); inbuf = NULL; } // start by pulling a buffer from GStreamer inbuf = gst_pad_pull (sinkpad); while (GST_IS_EVENT (inbuf)) { switch (GST_EVENT_TYPE (inbuf)) { case GST_EVENT_EOS: gst_element_set_eos (GST_PAD_PARENT (sinkpad)); default: break; } gst_pad_event_default (srcpad, GST_EVENT (inbuf)); inbuf = gst_pad_pull (sinkpad); } dataptr = GST_BUFFER_DATA (GST_BUFFER (inbuf)); remainingsamples = GST_BUFFER_SIZE (GST_BUFFER (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; } void setSrcPad (GstPad * pad) { srcpad = 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, GST_DATA (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); sink_impl->setSrcPad (sourcepad); 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