| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #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; |
| 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 |