mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-19 02:20:20 +00:00
187 lines
4.4 KiB
C++
187 lines
4.4 KiB
C++
#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
|