/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* <2001> Steve Baker <stevebaker_org@yahoo.co.uk>
+ * 2003 Andy Wingo <wingo at pobox.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* Boston, MA 02111-1307, USA.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include <string.h>
#include <math.h>
#include <gst/control/control.h>
+#include <gst/audio/audio.h>
#include "gstladspa.h"
#include <ladspa.h> /* main ladspa sdk include file */
#include "utils.h" /* ladspa sdk utility functions */
+/* 1.0 and the 1.1 preliminary headers don't define a version, but 1.1 final
+ does */
+#ifndef LADSPA_VERSION
+#define LADSPA_VERSION "1.0"
+#endif
/* takes ownership of the name */
static GstPadTemplate*
name,
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_CAPS_NEW (
+ gst_caps_new (
"ladspa_sink",
"audio/x-raw-float",
- "width", GST_PROPS_INT (32),
- "endianness", GST_PROPS_INT (G_BYTE_ORDER),
- "rate", GST_PROPS_INT_RANGE (4000, 96000),
- "buffer-frames", GST_PROPS_INT_RANGE (1, G_MAXINT),
- "channels", GST_PROPS_INT (1)
+ GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS
)
);
}
name,
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_CAPS_NEW (
+ gst_caps_new (
"ladspa_src",
"audio/x-raw-float",
- "width", GST_PROPS_INT (32),
- "endianness", GST_PROPS_INT (G_BYTE_ORDER),
- "rate", GST_PROPS_INT_RANGE (4000, 96000),
- "buffer-frames", GST_PROPS_INT_RANGE (1, G_MAXINT),
- "channels", GST_PROPS_INT (1)
+ GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_PROPS
)
);
}
static void gst_ladspa_class_init (GstLADSPAClass *klass);
+static void gst_ladspa_base_init (GstLADSPAClass *klass);
static void gst_ladspa_init (GstLADSPA *ladspa);
static void gst_ladspa_update_int (const GValue *value, gpointer data);
static GstElementStateReturn gst_ladspa_change_state (GstElement *element);
static void gst_ladspa_loop (GstElement *element);
-static void gst_ladspa_chain (GstPad *pad,GstBuffer *buf);
-static GstBuffer * gst_ladspa_get (GstPad *pad);
+static void gst_ladspa_chain (GstPad *pad,GstData *_data);
+static GstData * gst_ladspa_get (GstPad *pad);
static GstElementClass *parent_class = NULL;
static GstPlugin *ladspa_plugin;
static GHashTable *ladspa_descriptors;
+enum {
+ ARG_0,
+ ARG_SAMPLERATE,
+ ARG_BUFFERSIZE,
+ ARG_LAST,
+};
+
GST_DEBUG_CATEGORY_STATIC (ladspa_debug);
#define DEBUG(...) \
GST_CAT_LEVEL_LOG (ladspa_debug, GST_LEVEL_DEBUG, NULL, __VA_ARGS__)
GST_CAT_LEVEL_LOG (ladspa_debug, GST_LEVEL_DEBUG, obj, __VA_ARGS__)
static void
+gst_ladspa_base_init (GstLADSPAClass *klass)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+ GstPadTemplate *templ;
+ GstElementDetails *details;
+ LADSPA_Descriptor *desc;
+ gint j, sinkcount,srccount;
+
+ desc = g_hash_table_lookup(ladspa_descriptors,
+ GINT_TO_POINTER(G_TYPE_FROM_CLASS(klass)));
+ if (!desc)
+ desc = g_hash_table_lookup(ladspa_descriptors, GINT_TO_POINTER(0));
+ g_assert (desc);
+
+ /* construct the element details struct */
+ details = g_new0(GstElementDetails,1);
+ details->longname = g_strdup(desc->Name);
+ details->klass = "Filter/Effect/Audio/LADSPA";
+ details->description = details->longname;
+ details->author = g_strdup(desc->Maker);
+ gst_element_class_set_details (element_class, details);
+
+ /* pad templates */
+ klass->numports = desc->PortCount;
+ klass->numsinkpads = 0;
+ klass->numsrcpads = 0;
+ for (j=0;j<desc->PortCount;j++) {
+ if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j])) {
+ gchar *name = g_strdup((gchar *)desc->PortNames[j]);
+ g_strcanon (name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
+
+ /* the factories take ownership of the name */
+ if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
+ templ = ladspa_sink_factory (name);
+ klass->numsinkpads++;
+ } else {
+ templ = ladspa_src_factory (name);
+ klass->numsrcpads++;
+ }
+
+ gst_element_class_add_pad_template (element_class, templ);
+ }
+ }
+
+ klass->srcpad_portnums = g_new0(gint,klass->numsrcpads);
+ klass->sinkpad_portnums = g_new0(gint,klass->numsinkpads);
+ sinkcount = 0;
+ srccount = 0;
+
+ /* walk through the ports, note the portnums for srcpads, sinkpads */
+ for (j=0; j<desc->PortCount; j++) {
+ if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j])) {
+ if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j]))
+ klass->sinkpad_portnums[sinkcount++] = j;
+ else
+ klass->srcpad_portnums[srccount++] = j;
+ }
+ }
+
+ klass->descriptor = desc;
+}
+
+static void
gst_ladspa_class_init (GstLADSPAClass *klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
LADSPA_Descriptor *desc;
- gint i,current_portnum,sinkcount,srccount,controlcount;
+ gint i,current_portnum,controlcount;
gint hintdesc;
gint argtype,argperms;
GParamSpec *paramspec = NULL;
gstelement_class->change_state = gst_ladspa_change_state;
/* look up and store the ladspa descriptor */
- klass->descriptor = g_hash_table_lookup(ladspa_descriptors,GINT_TO_POINTER(G_TYPE_FROM_CLASS(klass)));
- desc = klass->descriptor;
+ desc = g_hash_table_lookup(ladspa_descriptors,
+ GINT_TO_POINTER(G_TYPE_FROM_CLASS(klass)));
+ if (!desc)
+ desc = g_hash_table_lookup(ladspa_descriptors, GINT_TO_POINTER(0));
+ g_assert (desc);
- klass->numports = desc->PortCount;
-
- klass->numsinkpads = 0;
- klass->numsrcpads = 0;
klass->numcontrols = 0;
/* walk through the ports, count the input, output and control ports */
for (i=0; i<desc->PortCount; i++) {
- if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]))
- if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i]))
- klass->numsinkpads++;
- else
- klass->numsrcpads++;
- else if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i]))
+ if (!LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
+ LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i]))
klass->numcontrols++;
}
g_type_name (G_TYPE_FROM_CLASS (klass)),
klass->numsinkpads, klass->numsrcpads, klass->numcontrols);
- klass->srcpad_portnums = g_new0(gint,klass->numsrcpads);
- klass->sinkpad_portnums = g_new0(gint,klass->numsinkpads);
klass->control_portnums = g_new0(gint,klass->numcontrols);
- sinkcount = 0;
- srccount = 0;
controlcount = 0;
- /* walk through the ports, note the portnums for srcpads, sinkpads and control
- params */
+ /* walk through the ports, note the portnums for control params */
for (i=0; i<desc->PortCount; i++) {
- if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]))
- if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i]))
- klass->sinkpad_portnums[sinkcount++] = i;
- else
- klass->srcpad_portnums[srccount++] = i;
- else if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i]))
+ if (!LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
+ LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i]))
klass->control_portnums[controlcount++] = i;
}
if (!ladspa->buffer_frames) {
ladspa->buffer_frames = 256; /* 5 ms at 44100 kHz (just a default...) */
g_return_if_fail (ladspa->bufpool == NULL);
- ladspa->bufpool = gst_buffer_pool_get_default (ladspa->buffer_frames * sizeof(gfloat),
- 3);
+ ladspa->bufpool =
+ gst_buffer_pool_get_default (ladspa->buffer_frames * sizeof(gfloat), 3);
}
DEBUG_OBJ (ladspa, "forcing caps with rate=%d, buffer-frames=%d",
ladspa->samplerate, ladspa->buffer_frames);
- gst_pad_try_set_caps (pad, gst_caps_new (
+ gst_pad_try_set_caps (pad,
+ gst_caps_new (
"ladspa_src_caps",
"audio/x-raw-float",
gst_props_new (
- "width", GST_PROPS_INT (32),
- "endianness", GST_PROPS_INT (G_BYTE_ORDER),
+ "width", GST_PROPS_INT (32),
+ "endianness", GST_PROPS_INT (G_BYTE_ORDER),
+ "rate", GST_PROPS_INT (ladspa->samplerate),
"buffer-frames", GST_PROPS_INT (ladspa->buffer_frames),
- "rate", GST_PROPS_INT (ladspa->samplerate),
"channels", GST_PROPS_INT (1),
- NULL
- )
- ));
+ NULL)));
}
static void
GstLADSPA *ladspa = (GstLADSPA*)object;
GstLADSPAClass *oclass;
ladspa_control_info *control_info;
-
+
oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
/* remember, properties have an offset of 1 */
/* verify it exists */
g_return_if_fail (prop_id < oclass->numcontrols);
-
+
control_info = &(oclass->control_info[prop_id]);
g_return_if_fail (control_info->name != NULL);
/* first get all the necessary data from the input ports */
for (i=0 ; i<numsinkpads ; i++){
get_buffer:
- buffers_in[i] = gst_pad_pull (ladspa->sinkpads[i]);
+ buffers_in[i] = GST_BUFFER (gst_pad_pull (ladspa->sinkpads[i]));
if (GST_IS_EVENT (buffers_in[i])) {
/* push it out on all pads */
gst_data_ref_by_count ((GstData*)buffers_in[i], numsrcpads);
for (j=0; j<numsrcpads; j++)
- gst_pad_push (ladspa->srcpads[j], buffers_in[i]);
+ gst_pad_push (ladspa->srcpads[j], GST_DATA (buffers_in[i]));
if (GST_EVENT_TYPE (buffers_in[i]) == GST_EVENT_EOS) {
/* shut down */
gst_element_set_eos (element);
}
for (i=0 ; i<numsrcpads ; i++) {
DEBUG_OBJ (ladspa, "pushing buffer (%p) on src pad %d", buffers_out[i], i);
- gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
+ gst_pad_push (ladspa->srcpads[i], GST_DATA (buffers_out[i]));
data_out[i] = NULL;
buffers_out[i] = NULL;
}
static void
-gst_ladspa_chain (GstPad *pad, GstBuffer *buffer_in)
+gst_ladspa_chain (GstPad *pad, GstData *_data)
{
+ GstBuffer *buffer_in = GST_BUFFER (_data);
LADSPA_Descriptor *desc;
LADSPA_Data *data_in, **data_out = NULL;
GstBuffer **buffers_out = NULL;
if (numsrcpads) {
for (i=0; i<numsrcpads; i++) {
- DEBUG_OBJ (ladspa, "pushing buffer (%p, length %d) on src pad %d",
- buffers_out[i], GST_BUFFER_SIZE (buffers_out[i])/sizeof(float), i);
- gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
+ DEBUG_OBJ (ladspa, "pushing buffer (%p, length %u bytes) on src pad %d",
+ buffers_out[i], GST_BUFFER_SIZE (buffers_out[i]), i);
+ gst_pad_push (ladspa->srcpads[i], GST_DATA (buffers_out[i]));
}
g_free(buffers_out);
}
}
-static GstBuffer *
+static GstData *
gst_ladspa_get(GstPad *pad)
{
GstLADSPA *ladspa;
num_processed = num_to_process;
}
- return buf;
+ return GST_DATA (buf);
}
static void
LADSPA_Descriptor_Function pfDescriptorFunction)
{
const LADSPA_Descriptor *desc;
- int i,j;
-
- GstElementDetails *details;
+ gint i;
GTypeInfo typeinfo = {
sizeof(GstLADSPAClass),
- NULL,
+ (GBaseInitFunc)gst_ladspa_base_init,
NULL,
(GClassInitFunc)gst_ladspa_class_init,
NULL,
(GInstanceInitFunc)gst_ladspa_init,
};
GType type;
- GstElementFactory *factory;
/* walk through all the plugins in this pluginlibrary */
i = 0;
g_free(type_name);
continue;
}
+
+ /* base-init temp alloc */
+ g_hash_table_insert(ladspa_descriptors,
+ GINT_TO_POINTER(0),
+ (gpointer)desc);
+
/* create the type now */
type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
-
- /* construct the element details struct */
- details = g_new0(GstElementDetails,1);
- details->longname = g_strdup(desc->Name);
- details->klass = "Filter/Audio/LADSPA";
- details->license = g_strdup (desc->Copyright);
- details->description = details->longname;
- details->version = g_strdup_printf("%ld",desc->UniqueID);
- details->author = g_strdup(desc->Maker);
- details->copyright = g_strdup(desc->Copyright);
-
- /* register the plugin with gstreamer */
- factory = gst_element_factory_new(type_name,type,details);
- g_return_if_fail(factory != NULL);
- gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
+ if (!gst_element_register (ladspa_plugin, type_name, GST_RANK_NONE, type))
+ continue;
/* add this plugin to the hash */
g_hash_table_insert(ladspa_descriptors,
GINT_TO_POINTER(type),
(gpointer)desc);
-
-
- for (j=0;j<desc->PortCount;j++) {
- if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j])) {
- gchar *name = g_strdup((gchar *)desc->PortNames[j]);
- g_strcanon (name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
- /* the factories take ownership of the name */
- if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j]))
- gst_element_factory_add_pad_template (factory, ladspa_sink_factory (name));
- else
- gst_element_factory_add_pad_template (factory, ladspa_src_factory (name));
- }
- }
}
+
+ g_hash_table_remove (ladspa_descriptors, GINT_TO_POINTER (0));
}
static gboolean
-plugin_init (GModule *module, GstPlugin *plugin)
+plugin_init (GstPlugin *plugin)
{
GST_DEBUG_CATEGORY_INIT (ladspa_debug, "ladspa",
GST_DEBUG_FG_GREEN | GST_DEBUG_BG_BLACK | GST_DEBUG_BOLD,
LADSPAPluginSearch(ladspa_describe_plugin);
- if (! gst_library_load ("gstbytestream"))
- return FALSE;
-
/* initialize dparam support library */
gst_control_init(NULL,NULL);
return TRUE;
}
-GstPluginDesc plugin_desc = {
+GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"ladspa",
- plugin_init
-};
+ "All LADSPA plugins",
+ plugin_init,
+ VERSION,
+ GST_LICENSE,
+ GST_PACKAGE,
+ GST_ORIGIN
+)