aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2006-06-09 14:34:20 +0000
committerDavid Robillard <d@drobilla.net>2006-06-09 14:34:20 +0000
commit1ad3c632e91211ae84bc738eebd8d4a8318707c9 (patch)
treeb060300cf35069b227851f62f0957edb9006e989
Added omins
git-svn-id: http://svn.drobilla.net/lad/omins@8 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--AUTHORS9
-rw-r--r--ChangeLog4
-rw-r--r--Makefile.am1
-rw-r--r--NEWS5
-rw-r--r--README1
-rwxr-xr-xautogen.sh9
-rw-r--r--configure.ac71
-rw-r--r--omins.spec41
-rw-r--r--src/.sconsignbin0 -> 9769 bytes
-rw-r--r--src/Makefile.am40
-rw-r--r--src/SConstruct7
-rw-r--r--src/adenv.c375
-rw-r--r--src/adenv_lvl.c461
-rw-r--r--src/comparison_4440.c292
-rw-r--r--src/dahdsr_fexp.c510
-rw-r--r--src/dahdsr_hexp.c511
-rw-r--r--src/fast_crossfade_4410.c215
-rw-r--r--src/formant_filter_4300.c344
-rw-r--r--src/hz_voct_4200.c242
-rw-r--r--src/masher_4310.c346
-rw-r--r--src/multiplexer_4420.c249
-rw-r--r--src/power_4400.c237
-rw-r--r--src/prob_switch_2667.c276
-rw-r--r--src/range_trans_4210.c281
-rw-r--r--src/sample_and_hold_4430.c305
-rw-r--r--src/signal_abs_2669.c261
-rw-r--r--src/slew_limiter_2743.c272
-rw-r--r--src/slide_2741.c297
-rw-r--r--src/waveguide_mesh_2670.c362
29 files changed, 6024 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..84f0e6d
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,9 @@
+Authors:
+
+Dave Robillard <drobilla .a.t. connect.carleton.ca>
+
+Loki Davison <loki .a.t. berlios.de>
+
+Lars Luthman <larsl .a.t. users.sourceforge.net>
+
+Thorsten Wilms <t_w_ .a.t. freenet.de>
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..929c0bf
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,4 @@
+Omins: A collection of LADSPA plugins for modular synthesizers
+
+Version 0.1.0 (12/05/2005):
+ * Initial release
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..af437a6
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = src
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..2646e7d
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,5 @@
+Omins NEWS file
+
+0.1.0:
+ * Initial release
+
diff --git a/README b/README
new file mode 100644
index 0000000..39d60dc
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+Omins is a collection of LADSPA plugins, aimed at modular synthesizers.
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..a9a6c1b
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+echo 'Generating necessary files...'
+libtoolize --copy --force
+aclocal
+autoheader -Wall
+automake --gnu --add-missing -Wall
+autoconf
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..8e01f11
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,71 @@
+# configure.in for omins
+
+AC_INIT([omins],[0.2.1pre],[drobilla@connect.carleton.ca])
+AC_CONFIG_SRCDIR([src/hz_voct_4200.c])
+
+AC_CONFIG_HEADER([config.h])
+AM_INIT_AUTOMAKE
+
+AC_DISABLE_STATIC
+
+#AC_ENABLE_STATIC(no)
+#AC_ENABLE_SHARED(yes)
+
+# Checks for compilers
+AC_LANG([C])
+AC_PROG_CC
+
+AC_PROG_LIBTOOL
+
+# Check for standard lib stuff
+AC_HEADER_STDC
+AC_CHECK_HEADERS([stdlib.h string.h math.h])
+AC_CHECK_FUNCS([strdup strndup])
+
+# Check random other stuff
+AC_C_CONST
+AC_C_INLINE
+AC_FUNC_MALLOC
+AC_TYPE_SIZE_T
+
+# Check for ladspa.h
+AC_CHECK_HEADER(ladspa.h, , AC_MSG_ERROR([Omins requires LADSPA - you do not seem to have ladspa.h]))
+
+# Check plugin install directory
+AC_MSG_CHECKING([where to install LADSPA plugins])
+AC_ARG_WITH(ladspa-dir,
+ AS_HELP_STRING([--with-ladspa-dir=DIR],
+ [directory that LADSPA plugins should be installed in ($libdir/ladspa)]),
+ [ladspadir=$withval], [ladspadir=$libdir/ladspa])
+AC_MSG_RESULT($ladspadir)
+AC_SUBST(ladspadir)
+
+# Check for debugging flag
+debug="no"
+AC_ARG_ENABLE(debug,
+ [AS_HELP_STRING(--enable-debug, [Enable debugging (false)])],
+ [debug="$enableval"])
+if test "$debug" = "yes"; then
+ CFLAGS="-O1 -g -DDEBUG"
+else
+ CFLAGS="$CFLAGS -DNDEBUG"
+fi
+
+# Check for strict flag
+strict="no"
+AC_ARG_ENABLE(strict,
+ [AS_HELP_STRING(--enable-strict, [Enable strict compiler warnings and errors (false)])],
+ [strict="$enableval"])
+if test "$strict" = "yes"; then
+ CFLAGS="$CFLAGS -std=c99 -pedantic -Wall -Wconversion -Winit-self"
+fi
+
+# Bolt on a few specific flags to CFLAGS that should always be used
+CFLAGS="$CFLAGS -pipe -fmessage-length=139 -fdiagnostics-show-location=every-line"
+
+
+
+# Write it!
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([src/Makefile])
+AC_OUTPUT
diff --git a/omins.spec b/omins.spec
new file mode 100644
index 0000000..4e6d3ef
--- /dev/null
+++ b/omins.spec
@@ -0,0 +1,41 @@
+Summary: A collection of plugins useful for modular synths.
+Name: omins
+Version: 0.0.1
+Release: 1
+License: GPL
+Group: Applications/Multimedia
+URL: http://www.nongnu.org/om-synth/
+Source0: %{name}-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
+Requires: ladspa
+BuildRequires: ladspa-devel
+
+%description
+Omins is a collection of ladspa plugins that are useful for modular synths. This includes a formant filter, envelope generators, probalistic switches, and rate converters.
+
+%prep
+%setup -q
+
+%build
+%configure
+make
+
+%install
+%{__rm} -rf %{buildroot}
+%{__make} install \
+ DESTDIR="%{buildroot}"
+
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root,-)
+%{_libdir}/ladspa/*.so
+%doc AUTHORS ChangeLog COPYING NEWS README
+
+
+%changelog
+* Tue Apr 26 2005 Loki Davison <loki@berlios.de>
+- initial package, v0.0.1
+
diff --git a/src/.sconsign b/src/.sconsign
new file mode 100644
index 0000000..c56d217
--- /dev/null
+++ b/src/.sconsign
Binary files differ
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..55aeb32
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,40 @@
+AM_LDFLAGS = -module -avoidversion -Wc,-nostartfiles
+
+plugindir = @ladspadir@
+
+plugin_LTLIBRARIES = \
+ hz_voct_4200.la \
+ range_trans_4210.la \
+ formant_filter_4300.la \
+ adenv.la \
+ adenv_lvl.la \
+ dahdsr_fexp.la \
+ dahdsr_hexp.la \
+ prob_switch_2667.la \
+ signal_abs_2669.la \
+ slide_2741.la \
+ slew_limiter_2743.la \
+ waveguide_mesh_2670.la \
+ fast_crossfade_4410.la \
+ multiplexer_4420.la \
+ power_4400.la \
+ masher_4310.la \
+ sample_and_hold_4430.la \
+ comparison_4440.la
+
+# Stolen from swh-plugins, makes stupid libtool versions go away
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ mkdir -p @ladspadir@
+ list='$(plugin_LTLIBRARIES)'; \
+ for file in $$list; do \
+ sofile=`basename $$file .la`.so; \
+ $(INSTALL_PROGRAM) .libs/$$sofile @ladspadir@; \
+ done
+
+uninstall-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ list='$(plugin_LTLIBRARIES)'; \
+ for file in $$list; do \
+ sofile=`basename $$file .la`.so; \
+ rm -f @ladspadir@/$$sofile; \
+ done
+
diff --git a/src/SConstruct b/src/SConstruct
new file mode 100644
index 0000000..7749ebf
--- /dev/null
+++ b/src/SConstruct
@@ -0,0 +1,7 @@
+import glob
+
+env = Environment();
+env.Append(LINKFLAGS="-nostartfiles")
+
+for i in glob.glob("*.c"):
+ env.SharedLibrary(i[:-2], i)
diff --git a/src/adenv.c b/src/adenv.c
new file mode 100644
index 0000000..2fa8802
--- /dev/null
+++ b/src/adenv.c
@@ -0,0 +1,375 @@
+/*
+ adenv.c - A LADSPA plugin to generate percussive (i.e no sustain time), linear AD envelopes.
+
+ Copyright (C) 2005 Loki Davison
+ based on ADENV by Mike Rawes
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <ladspa.h>
+#include <stdio.h>
+#include <math.h>
+
+#ifdef ENABLE_NLS
+# include <locale.h>
+# define G_(s) gettext(s)
+#else
+# define G_(s) (s)
+#endif
+#define G_NOP(s) s
+
+
+#define ADENV_BASE_ID 2661
+#define ADENV_VARIANT_COUNT 1
+
+#define ADENV_GATE 0
+#define ADENV_TRIGGER 1
+#define ADENV_ATTACK 2
+#define ADENV_DECAY 3
+#define ADENV_OUTPUT 4
+
+LADSPA_Descriptor **dahdsr_descriptors = 0;
+
+typedef enum {
+ IDLE,
+ ATTACK,
+ DECAY,
+} ADENVState;
+
+typedef struct {
+ LADSPA_Data *gate;
+ LADSPA_Data *trigger;
+ LADSPA_Data *attack;
+ LADSPA_Data *decay;
+ LADSPA_Data *output;
+ LADSPA_Data srate;
+ LADSPA_Data inv_srate;
+ LADSPA_Data last_gate;
+ LADSPA_Data last_trigger;
+ LADSPA_Data from_level;
+ LADSPA_Data level;
+ ADENVState state;
+ unsigned long samples;
+} Dahdsr;
+
+const LADSPA_Descriptor *
+ladspa_descriptor(unsigned long index)
+{
+ if (index < ADENV_VARIANT_COUNT)
+ return dahdsr_descriptors[index];
+
+ return 0;
+}
+
+void
+cleanupDahdsr(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+void
+connectPortDahdsr(LADSPA_Handle instance,
+ unsigned long port, LADSPA_Data * data)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ switch (port) {
+ case ADENV_GATE:
+ plugin->gate = data;
+ break;
+ case ADENV_TRIGGER:
+ plugin->trigger = data;
+ break;
+ case ADENV_ATTACK:
+ plugin->attack = data;
+ break;
+ case ADENV_DECAY:
+ plugin->decay = data;
+ break;
+ case ADENV_OUTPUT:
+ plugin->output = data;
+ break;
+ }
+}
+
+LADSPA_Handle
+instantiateDahdsr(const LADSPA_Descriptor * descriptor,
+ unsigned long sample_rate)
+{
+ Dahdsr *plugin = (Dahdsr *) malloc(sizeof(Dahdsr));
+
+ plugin->srate = (LADSPA_Data) sample_rate;
+ plugin->inv_srate = 1.0f / plugin->srate;
+
+ return (LADSPA_Handle) plugin;
+}
+
+void
+activateDahdsr(LADSPA_Handle instance)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ plugin->last_gate = 0.0f;
+ plugin->last_trigger = 0.0f;
+ plugin->from_level = 0.0f;
+ plugin->level = 0.0f;
+ plugin->state = IDLE;
+ plugin->samples = 0;
+}
+
+void
+runDahdsr_Control(LADSPA_Handle instance, unsigned long sample_count)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ /* Gate */
+ LADSPA_Data *gate = plugin->gate;
+
+ /* Trigger */
+ LADSPA_Data *trigger = plugin->trigger;
+
+ /* Attack Time (s) */
+ LADSPA_Data attack = *(plugin->attack);
+
+ /* Decay Time (s) */
+ LADSPA_Data decay = *(plugin->decay);
+
+ /* Envelope Out */
+ LADSPA_Data *output = plugin->output;
+
+ /* Instance Data */
+ LADSPA_Data srate = plugin->srate;
+ LADSPA_Data inv_srate = plugin->inv_srate;
+ LADSPA_Data last_gate = plugin->last_gate;
+ LADSPA_Data last_trigger = plugin->last_trigger;
+ LADSPA_Data from_level = plugin->from_level;
+ LADSPA_Data level = plugin->level;
+ ADENVState state = plugin->state;
+ unsigned long samples = plugin->samples;
+
+ LADSPA_Data gat, trg, att, dec;
+ LADSPA_Data elapsed;
+ unsigned long s;
+
+ /* Convert times into rates */
+ att = attack > 0.0f ? inv_srate / attack : srate;
+ dec = decay > 0.0f ? inv_srate / decay : srate;
+ /* cuse's formula ...
+ * ReleaseCoeff = (ln(EndLevel) - ln(StartLevel)) / (EnvelopeDuration * SampleRate)
+ *
+ * while (currentSample < endSample) Level += Level * ReleaseCoeff;
+ */
+
+ LADSPA_Data ReleaseCoeff = log(0.001) / (decay * srate);
+
+ for (s = 0; s < sample_count; s++) {
+ gat = gate[s];
+ trg = trigger[s];
+
+ /* Initialise delay phase if gate is opened and was closed, or
+ we received a trigger */
+ if ((trg > 0.0f && !(last_trigger > 0.0f)) ||
+ (gat > 0.0f && !(last_gate > 0.0f))) {
+ //fprintf(stderr, "triggered in control \n");
+ if (att <= srate) {
+ state = ATTACK;
+ }
+ samples = 0;
+ }
+
+ if (samples == 0)
+ from_level = level;
+
+ /* Calculate level of envelope from current state */
+ switch (state) {
+ case IDLE:
+ level = 0;
+ break;
+ case ATTACK:
+ samples++;
+ elapsed = (LADSPA_Data) samples *att;
+
+ if (elapsed > 1.0f) {
+ state = DECAY;
+ level = 1.0f;
+ samples = 0;
+ } else {
+ level = from_level + elapsed * (1.0f - from_level);
+ }
+ break;
+ case DECAY:
+ samples++;
+ elapsed = (LADSPA_Data) samples *dec;
+
+ if (elapsed > 1.0f) {
+ state = IDLE;
+ level = 0.0f;
+ samples = 0;
+ } else {
+ //fprintf(stderr, "decay, dec %f elapsed %f from level %f level %f\n", dec, elapsed, from_level, level);
+ level += level * ReleaseCoeff;
+
+ }
+ break;
+ default:
+ /* Should never happen */
+ fprintf(stderr, "bugger!!!");
+ level = 0.0f;
+ }
+
+ output[s] = level;
+ last_gate = gat;
+ last_trigger = trg;
+ }
+
+ plugin->last_gate = last_gate;
+ plugin->last_trigger = last_trigger;
+ plugin->from_level = from_level;
+ plugin->level = level;
+ plugin->state = state;
+ plugin->samples = samples;
+}
+
+void
+_init(void)
+{
+ static const unsigned long ids[] = { ADENV_BASE_ID };
+ static const char *labels[] = { "adenv" };
+ static const char *names[] = { G_NOP("Percussive AD Envelope") };
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+ LADSPA_Descriptor *descriptor;
+
+ LADSPA_PortDescriptor gate_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO };
+ LADSPA_PortDescriptor trigger_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO };
+ LADSPA_PortDescriptor attack_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor decay_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor output_port_descriptors[] =
+ { LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO };
+
+ void (*run_functions[]) (LADSPA_Handle, unsigned long) = {
+ runDahdsr_Control};
+
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+#endif
+
+ dahdsr_descriptors =
+ (LADSPA_Descriptor **) calloc(ADENV_VARIANT_COUNT,
+ sizeof(LADSPA_Descriptor));
+
+ if (dahdsr_descriptors) {
+ int i = 0;
+
+ dahdsr_descriptors[i] =
+ (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor));
+ descriptor = dahdsr_descriptors[i];
+ if (descriptor) {
+ descriptor->UniqueID = ids[i];
+ descriptor->Label = labels[i];
+ descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ descriptor->Name = G_(names[i]);
+ descriptor->Maker =
+ "Loki Davison <ltdav1[at]student.monash.edu.au>";
+ descriptor->Copyright = "GPL";
+
+ descriptor->PortCount = 5;
+
+ port_descriptors =
+ (LADSPA_PortDescriptor *) calloc(5,
+ sizeof
+ (LADSPA_PortDescriptor));
+ descriptor->PortDescriptors =
+ (const LADSPA_PortDescriptor *)port_descriptors;
+
+ port_range_hints =
+ (LADSPA_PortRangeHint *) calloc(5,
+ sizeof(LADSPA_PortRangeHint));
+ descriptor->PortRangeHints =
+ (const LADSPA_PortRangeHint *)port_range_hints;
+
+ port_names = (char **)calloc(5, sizeof(char *));
+ descriptor->PortNames = (const char **)port_names;
+
+ /* Parameters for Gate */
+ port_descriptors[ADENV_GATE] = gate_port_descriptors[i];
+ port_names[ADENV_GATE] = G_("Gate");
+ port_range_hints[ADENV_GATE].HintDescriptor =
+ LADSPA_HINT_TOGGLED;
+
+ /* Parameters for Trigger */
+ port_descriptors[ADENV_TRIGGER] = trigger_port_descriptors[i];
+ port_names[ADENV_TRIGGER] = G_("Trigger");
+ port_range_hints[ADENV_TRIGGER].HintDescriptor =
+ LADSPA_HINT_TOGGLED;
+
+ /* Parameters for Attack Time (s) */
+ port_descriptors[ADENV_ATTACK] = attack_port_descriptors[i];
+ port_names[ADENV_ATTACK] = G_("Attack Time (s)");
+ port_range_hints[ADENV_ATTACK].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[ADENV_ATTACK].LowerBound = 0.0f;
+
+ /* Parameters for Decay Time (s) */
+ port_descriptors[ADENV_DECAY] = decay_port_descriptors[i];
+ port_names[ADENV_DECAY] = G_("Decay Time (s)");
+ port_range_hints[ADENV_DECAY].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[ADENV_DECAY].LowerBound = 0.0f;
+
+ /* Parameters for Envelope Out */
+ port_descriptors[ADENV_OUTPUT] = output_port_descriptors[i];
+ port_names[ADENV_OUTPUT] = G_("Envelope Out");
+ port_range_hints[ADENV_OUTPUT].HintDescriptor = 0;
+
+ descriptor->activate = activateDahdsr;
+ descriptor->cleanup = cleanupDahdsr;
+ descriptor->connect_port = connectPortDahdsr;
+ descriptor->deactivate = NULL;
+ descriptor->instantiate = instantiateDahdsr;
+ descriptor->run = run_functions[i];
+ descriptor->run_adding = NULL;
+ descriptor->set_run_adding_gain = NULL;
+ }
+ }
+
+}
+
+void
+_fini(void)
+{
+ LADSPA_Descriptor *descriptor;
+
+ if (dahdsr_descriptors) {
+ descriptor = dahdsr_descriptors[0];
+ if (descriptor) {
+ free((LADSPA_PortDescriptor *) descriptor->PortDescriptors);
+ free((char **)descriptor->PortNames);
+ free((LADSPA_PortRangeHint *) descriptor->PortRangeHints);
+ free(descriptor);
+ }
+ free(dahdsr_descriptors);
+ }
+}
diff --git a/src/adenv_lvl.c b/src/adenv_lvl.c
new file mode 100644
index 0000000..10c8378
--- /dev/null
+++ b/src/adenv_lvl.c
@@ -0,0 +1,461 @@
+/*
+ adenv.c - A LADSPA plugin to generate percussive (i.e no sustain time), linear AD envelopes.
+ This one takes in levels to make filter sweeps/etc easier.
+
+ Copyright (C) 2005 Loki Davison
+ based of DADSR by Mike Rawes
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <ladspa.h>
+#include <stdio.h>
+#include <math.h>
+
+#ifdef ENABLE_NLS
+# include <locale.h>
+# define G_(s) gettext(s)
+#else
+# define G_(s) (s)
+#endif
+#define G_NOP(s) s
+
+#define ADENVLVL_BASE_ID 2662
+#define ADENVLVL_VARIANT_COUNT 1
+
+#define ADENVLVL_GATE 0
+#define ADENVLVL_TRIGGER 1
+#define ADENVLVL_START_LEVEL 2
+#define ADENVLVL_ATTACK_LEVEL 3
+#define ADENVLVL_DECAY_LEVEL 4
+#define ADENVLVL_ATTACK 5
+#define ADENVLVL_DECAY 6
+#define ADENVLVL_OUTPUT 7
+#define ADENVLVL_RESET 8
+
+LADSPA_Descriptor **dahdsr_descriptors = 0;
+
+typedef enum {
+ IDLE,
+ ATTACK,
+ DECAY,
+} ADENVLVLState;
+
+typedef struct {
+ LADSPA_Data *gate;
+ LADSPA_Data *trigger;
+ LADSPA_Data *attack;
+ LADSPA_Data *reset;
+ LADSPA_Data *decay;
+ LADSPA_Data *start_level;
+ LADSPA_Data *attack_level;
+ LADSPA_Data *decay_level;
+ LADSPA_Data *output;
+ LADSPA_Data srate;
+ LADSPA_Data inv_srate;
+ LADSPA_Data last_gate;
+ LADSPA_Data last_trigger;
+ LADSPA_Data last_reset;
+ LADSPA_Data level;
+ ADENVLVLState state;
+ unsigned long samples;
+} Dahdsr;
+
+const LADSPA_Descriptor *
+ladspa_descriptor(unsigned long index)
+{
+ if (index < ADENVLVL_VARIANT_COUNT)
+ return dahdsr_descriptors[index];
+
+ return 0;
+}
+
+void
+cleanupDahdsr(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+void
+connectPortDahdsr(LADSPA_Handle instance,
+ unsigned long port, LADSPA_Data * data)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ switch (port) {
+ case ADENVLVL_GATE:
+ plugin->gate = data;
+ break;
+ case ADENVLVL_TRIGGER:
+ plugin->trigger = data;
+ break;
+ case ADENVLVL_START_LEVEL:
+ plugin->start_level = data;
+ break;
+ case ADENVLVL_ATTACK_LEVEL:
+ plugin->attack_level = data;
+ break;
+ case ADENVLVL_DECAY_LEVEL:
+ plugin->decay_level = data;
+ break;
+ case ADENVLVL_ATTACK:
+ plugin->attack = data;
+ break;
+ case ADENVLVL_DECAY:
+ plugin->decay = data;
+ break;
+ case ADENVLVL_RESET:
+ plugin->reset = data;
+ break;
+ case ADENVLVL_OUTPUT:
+ plugin->output = data;
+ break;
+ }
+}
+
+LADSPA_Handle
+instantiateDahdsr(const LADSPA_Descriptor * descriptor,
+ unsigned long sample_rate)
+{
+ Dahdsr *plugin = (Dahdsr *) malloc(sizeof(Dahdsr));
+
+ plugin->srate = (LADSPA_Data) sample_rate;
+ plugin->inv_srate = 1.0f / plugin->srate;
+
+ return (LADSPA_Handle) plugin;
+}
+
+void
+activateDahdsr(LADSPA_Handle instance)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ plugin->last_gate = 0.0f;
+ plugin->last_trigger = 0.0f;
+ plugin->last_reset = 0.0f;
+ plugin->level = 0.0f;
+ plugin->state = IDLE;
+ plugin->samples = 0;
+}
+
+void
+runDahdsr_Control(LADSPA_Handle instance, unsigned long sample_count)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ /* Gate */
+ LADSPA_Data *gate = plugin->gate;
+
+ /* Trigger */
+ LADSPA_Data *trigger = plugin->trigger;
+
+ /* Reset */
+ LADSPA_Data *reset = plugin->reset;
+
+ /* Start Level */
+ LADSPA_Data start_level = *(plugin->start_level);
+
+ /* Attack Level */
+ LADSPA_Data attack_level = *(plugin->attack_level);
+
+ /* Decay Level */
+ LADSPA_Data decay_level = *(plugin->decay_level);
+
+ /* Attack Time (s) */
+ LADSPA_Data attack = *(plugin->attack);
+
+ /* Decay Time (s) */
+ LADSPA_Data decay = *(plugin->decay);
+
+ /* Envelope Out */
+ LADSPA_Data *output = plugin->output;
+
+ /* Instance Data */
+ LADSPA_Data srate = plugin->srate;
+ LADSPA_Data inv_srate = plugin->inv_srate;
+ LADSPA_Data last_gate = plugin->last_gate;
+ LADSPA_Data last_trigger = plugin->last_trigger;
+ LADSPA_Data last_reset = plugin->last_reset;
+ LADSPA_Data level = plugin->level;
+ ADENVLVLState state = plugin->state;
+ unsigned long samples = plugin->samples;
+
+ LADSPA_Data gat, trg, att, dec;
+ LADSPA_Data elapsed;
+ unsigned long s;
+
+ /* Convert times into rates */
+ att = attack > 0.0f ? inv_srate / attack : srate;
+ dec = decay > 0.0f ? inv_srate / decay : srate;
+ /* cuse's formula ...
+ * ReleaseCoeff = (ln(EndLevel) - ln(StartLevel)) / (EnvelopeDuration * SampleRate)
+ *
+ * while (currentSample < endSample) Level += Level * ReleaseCoeff;
+ */
+ /* check params don't cause div by zero */
+ if (start_level == 0) {
+ start_level = 0.0000001;
+ }
+ if (attack_level == 0) {
+ attack_level = 0.0000001;
+ }
+ if (decay_level == 0) {
+ decay_level = 0.0000001;
+ }
+ LADSPA_Data ReleaseCoeff_att =
+ (log(attack_level) - log(start_level)) / (attack * srate);
+ LADSPA_Data ReleaseCoeff_dec =
+ (log(decay_level) - log(attack_level)) / (decay * srate);
+
+ for (s = 0; s < sample_count; s++) {
+ gat = gate[s];
+ trg = trigger[s];
+
+ /* Initialise delay phase if gate is opened and was closed, or
+ we received a trigger */
+ if ((trg > 0.0f && !(last_trigger > 0.0f)) ||
+ (gat > 0.0f && !(last_gate > 0.0f))) {
+ //fprintf(stderr, "triggered in control \n");
+ if (att < srate) {
+ state = ATTACK;
+ }
+ samples = 0;
+ }
+ /* if we got a reset */
+
+ if (reset[s] > 0.0f && !(last_reset > 0.0f)) {
+ level = start_level;
+ /*fprintf(stderr, "got reset start level %f \n", start_level); */
+ }
+
+ /* Calculate level of envelope from current state */
+ switch (state) {
+ case IDLE:
+ /* might need to fix this... */
+ break;
+ case ATTACK:
+ /* fix level adding prob */
+ if (samples == 0) {
+ level = start_level;
+ }
+ samples++;
+ elapsed = (LADSPA_Data) samples *att;
+
+ if (elapsed > 1.0f) {
+ state = DECAY;
+ samples = 0;
+ //fprintf(stderr, "finished attack, RC %f, level %f attack_level %f start %f\n", ReleaseCoeff_att, level, attack_level, start_level);
+ } else {
+ level += level * ReleaseCoeff_att;
+ }
+ break;
+ case DECAY:
+ samples++;
+ elapsed = (LADSPA_Data) samples *dec;
+
+ if (elapsed > 1.0f) {
+ //fprintf(stderr, "finished decay, RC %f , level %f decay_level %f start %f\n", ReleaseCoeff_dec, level, decay_level, start_level);
+ state = IDLE;
+ samples = 0;
+ } else {
+ level += level * ReleaseCoeff_dec;
+ }
+ break;
+ default:
+ /* Should never happen */
+ fprintf(stderr, "bugger!!!");
+ level = 0.0f;
+ }
+
+ output[s] = level;
+ last_gate = gat;
+ last_trigger = trg;
+ last_reset = reset[s];
+ }
+
+ plugin->last_gate = last_gate;
+ plugin->last_trigger = last_trigger;
+ plugin->last_reset = last_reset;
+ plugin->level = level;
+ plugin->state = state;
+ plugin->samples = samples;
+}
+
+void
+_init(void)
+{
+ static const unsigned long ids[] = { ADENVLVL_BASE_ID };
+ static const char *labels[] = { "adenv_lvl" };
+ static const char *names[] =
+ { G_NOP("Percussive AD Envelope with levels") };
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+ LADSPA_Descriptor *descriptor;
+
+ LADSPA_PortDescriptor gate_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO };
+ LADSPA_PortDescriptor trigger_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO };
+ LADSPA_PortDescriptor start_level_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor attack_level_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor decay_level_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor attack_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor decay_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor output_port_descriptors[] =
+ { LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO };
+
+ void (*run_functions[]) (LADSPA_Handle, unsigned long) = {
+ runDahdsr_Control};
+
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+#endif
+
+ dahdsr_descriptors =
+ (LADSPA_Descriptor **) calloc(ADENVLVL_VARIANT_COUNT,
+ sizeof(LADSPA_Descriptor));
+
+ if (dahdsr_descriptors) {
+ int i = 0;
+
+ dahdsr_descriptors[i] =
+ (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor));
+ descriptor = dahdsr_descriptors[i];
+ if (descriptor) {
+ descriptor->UniqueID = ids[i];
+ descriptor->Label = labels[i];
+ descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ descriptor->Name = G_(names[i]);
+ descriptor->Maker =
+ "Loki Davison <ltdav1[at]student.monash.edu.au>";
+ descriptor->Copyright = "GPL";
+
+ descriptor->PortCount = 9;
+
+ port_descriptors =
+ (LADSPA_PortDescriptor *) calloc(9,
+ sizeof
+ (LADSPA_PortDescriptor));
+ descriptor->PortDescriptors =
+ (const LADSPA_PortDescriptor *)port_descriptors;
+
+ port_range_hints =
+ (LADSPA_PortRangeHint *) calloc(9,
+ sizeof(LADSPA_PortRangeHint));
+ descriptor->PortRangeHints =
+ (const LADSPA_PortRangeHint *)port_range_hints;
+
+ port_names = (char **)calloc(9, sizeof(char *));
+ descriptor->PortNames = (const char **)port_names;
+
+ /* Parameters for Gate */
+ port_descriptors[ADENVLVL_GATE] = gate_port_descriptors[i];
+ port_names[ADENVLVL_GATE] = G_("Gate");
+ port_range_hints[ADENVLVL_GATE].HintDescriptor =
+ LADSPA_HINT_TOGGLED;
+
+ /* Parameters for Trigger */
+ port_descriptors[ADENVLVL_TRIGGER] = trigger_port_descriptors[i];
+ port_names[ADENVLVL_TRIGGER] = G_("Trigger");
+ port_range_hints[ADENVLVL_TRIGGER].HintDescriptor =
+ LADSPA_HINT_TOGGLED;
+ /* Parameters for Reset */
+ port_descriptors[ADENVLVL_RESET] = trigger_port_descriptors[i];
+ port_names[ADENVLVL_RESET] = G_("Reset Level");
+ port_range_hints[ADENVLVL_RESET].HintDescriptor =
+ LADSPA_HINT_TOGGLED;
+
+ /* Parameters for Attack Time (s) */
+ port_descriptors[ADENVLVL_ATTACK] = attack_port_descriptors[i];
+ port_names[ADENVLVL_ATTACK] = G_("Attack Time (s)");
+ port_range_hints[ADENVLVL_ATTACK].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[ADENVLVL_ATTACK].LowerBound = 0.0f;
+
+ /* Parameters for Start Level */
+ port_descriptors[ADENVLVL_START_LEVEL] =
+ start_level_port_descriptors[i];
+ port_names[ADENVLVL_START_LEVEL] = G_("Initial Level");
+ port_range_hints[ADENVLVL_START_LEVEL].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[ADENVLVL_START_LEVEL].LowerBound = 0.0f;
+
+ /* Parameters for Attack to level (s) */
+ port_descriptors[ADENVLVL_ATTACK_LEVEL] =
+ attack_level_port_descriptors[i];
+ port_names[ADENVLVL_ATTACK_LEVEL] = G_("Attack to Level");
+ port_range_hints[ADENVLVL_ATTACK_LEVEL].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_1;
+ port_range_hints[ADENVLVL_ATTACK_LEVEL].LowerBound = 0.0f;
+
+ /* Parameters for Decay to level (s) */
+ port_descriptors[ADENVLVL_DECAY_LEVEL] =
+ decay_level_port_descriptors[i];
+ port_names[ADENVLVL_DECAY_LEVEL] = G_("Decay to Level");
+ port_range_hints[ADENVLVL_DECAY_LEVEL].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[ADENVLVL_DECAY_LEVEL].LowerBound = 0.0f;
+
+ /* Parameters for Decay Time (s) */
+ port_descriptors[ADENVLVL_DECAY] = decay_port_descriptors[i];
+ port_names[ADENVLVL_DECAY] = G_("Decay Time (s)");
+ port_range_hints[ADENVLVL_DECAY].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[ADENVLVL_DECAY].LowerBound = 0.0f;
+
+ /* Parameters for Envelope Out */
+ port_descriptors[ADENVLVL_OUTPUT] = output_port_descriptors[i];
+ port_names[ADENVLVL_OUTPUT] = G_("Envelope Out");
+ port_range_hints[ADENVLVL_OUTPUT].HintDescriptor = 0;
+
+ descriptor->activate = activateDahdsr;
+ descriptor->cleanup = cleanupDahdsr;
+ descriptor->connect_port = connectPortDahdsr;
+ descriptor->deactivate = NULL;
+ descriptor->instantiate = instantiateDahdsr;
+ descriptor->run = run_functions[i];
+ descriptor->run_adding = NULL;
+ descriptor->set_run_adding_gain = NULL;
+ }
+ }
+
+}
+
+void
+_fini(void)
+{
+ LADSPA_Descriptor *descriptor;
+
+ if (dahdsr_descriptors) {
+ descriptor = dahdsr_descriptors[0];
+ if (descriptor) {
+ free((LADSPA_PortDescriptor *) descriptor->PortDescriptors);
+ free((char **)descriptor->PortNames);
+ free((LADSPA_PortRangeHint *) descriptor->PortRangeHints);
+ free(descriptor);
+ }
+ free(dahdsr_descriptors);
+ }
+}
diff --git a/src/comparison_4440.c b/src/comparison_4440.c
new file mode 100644
index 0000000..210c88a
--- /dev/null
+++ b/src/comparison_4440.c
@@ -0,0 +1,292 @@
+/* Comparison plugin. Copyright (C) 2005 Thorsten Wilms.
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+
+#include "ladspa.h"
+
+#define COMP_BASE_ID 4440
+
+#define COMP_NUM_PORTS 6
+
+/* Port Numbers */
+#define COMP_A 0
+#define COMP_B 1
+#define COMP_LARGER 2
+#define COMP_SMALLER 3
+#define COMP_A_LARGER 4
+#define COMP_EQUAL 5
+
+
+/* All state information for plugin */
+typedef struct {
+ /* Ports */
+ LADSPA_Data *a_buffer;
+ LADSPA_Data *b_buffer;
+ LADSPA_Data *larger_buffer;
+ LADSPA_Data *smaller_buffer;
+ LADSPA_Data *a_larger_buffer;
+ LADSPA_Data *equal_buffer;
+} Comp;
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+comp_instantiate(const LADSPA_Descriptor* descriptor,
+ unsigned long srate)
+{
+ Comp* plugin = malloc(sizeof(Comp));
+ plugin->a_buffer = NULL;
+ plugin->b_buffer = NULL;
+ plugin->larger_buffer = NULL;
+ plugin->smaller_buffer = NULL;
+ plugin->a_larger_buffer = NULL;
+ plugin->equal_buffer = NULL;
+ return (LADSPA_Handle)plugin;
+}
+
+
+/* Connect a port to a data location */
+void
+comp_connect_port(LADSPA_Handle instance,
+ unsigned long port,
+ LADSPA_Data* location)
+{
+ Comp* plugin;
+
+ plugin = (Comp*)instance;
+ switch (port) {
+ case COMP_A:
+ plugin->a_buffer = location;
+ break;
+ case COMP_B:
+ plugin->b_buffer = location;
+ break;
+ case COMP_LARGER:
+ plugin->larger_buffer = location;
+ break;
+ case COMP_SMALLER:
+ plugin->smaller_buffer = location;
+ break;
+ case COMP_A_LARGER:
+ plugin->a_larger_buffer = location;
+ break;
+ case COMP_EQUAL:
+ plugin->equal_buffer = location;
+ break;
+ }
+}
+
+
+void
+comp_run_ac(LADSPA_Handle instance, unsigned long nframes)
+{
+ Comp* const plugin = (Comp*)instance;
+ const LADSPA_Data* const a = plugin->a_buffer;
+ const LADSPA_Data const b = *plugin->b_buffer;
+ LADSPA_Data* const larger = plugin->larger_buffer;
+ LADSPA_Data* const smaller = plugin->smaller_buffer;
+ LADSPA_Data* const a_larger = plugin->a_larger_buffer;
+ LADSPA_Data* const equal = plugin->equal_buffer;
+ unsigned long i;
+
+ for (i = 0; i < nframes; i++) {
+ equal[i] = (a[i] == b) ? 1.0 : 0.0;
+ larger[i] = (a[i] > b) ? a[i] : b;
+ smaller[i] = (a[i] < b) ? a[i] : b;
+ a_larger[i] = (a[i] > b) ? 1.0 : 0.0;
+ }
+}
+
+
+void
+comp_run_aa(LADSPA_Handle instance, unsigned long nframes)
+{
+ Comp* const plugin = (Comp*)instance;
+ const LADSPA_Data* const a = plugin->a_buffer;
+ const LADSPA_Data* const b = plugin->b_buffer;
+ LADSPA_Data* const larger = plugin->larger_buffer;
+ LADSPA_Data* const smaller = plugin->smaller_buffer;
+ LADSPA_Data* const a_larger = plugin->a_larger_buffer;
+ LADSPA_Data* const equal = plugin->equal_buffer;
+ unsigned long i;
+
+ for (i = 0; i < nframes; i++) {
+ equal[i] = (a[i] == b[i]) ? 1.0 : 0.0;
+ larger[i] = (a[i] > b[i]) ? a[i] : b[i];
+ smaller[i] = (a[i] < b[i]) ? a[i] : b[i];
+ a_larger[i] = (a[i] > b[i]) ? 1.0 : 0.0;
+ }
+}
+
+
+void
+comp_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor* comp_ac_desc = NULL;
+LADSPA_Descriptor* comp_aa_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+
+ comp_ac_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ comp_aa_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+
+ if (comp_ac_desc) {
+
+ comp_ac_desc->UniqueID = COMP_BASE_ID;
+ comp_ac_desc->Label = strdup("comp_ac");
+ comp_ac_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ comp_ac_desc->Name = strdup("Comparison (AC)");
+ comp_ac_desc->Maker = strdup("Thorsten Wilms");
+ comp_ac_desc->Copyright = strdup("GPL");
+ comp_ac_desc->PortCount = COMP_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(COMP_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ comp_ac_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[COMP_A] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[COMP_B] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[COMP_LARGER] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[COMP_SMALLER] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[COMP_A_LARGER] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[COMP_EQUAL] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(COMP_NUM_PORTS, sizeof(char*));
+ comp_ac_desc->PortNames = (const char**)port_names;
+ port_names[COMP_A] = strdup("A");
+ port_names[COMP_B] = strdup("B");
+ port_names[COMP_LARGER] = strdup("Larger");
+ port_names[COMP_SMALLER] = strdup("Smaller");
+ port_names[COMP_A_LARGER] = strdup("A > B");
+ port_names[COMP_EQUAL] = strdup("A = B");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(COMP_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ comp_ac_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[COMP_A].HintDescriptor = 0;
+ port_range_hints[COMP_B].HintDescriptor = 0;
+ port_range_hints[COMP_LARGER].HintDescriptor = 0;
+ port_range_hints[COMP_SMALLER].HintDescriptor = 0;
+ port_range_hints[COMP_A_LARGER].HintDescriptor = 0;
+ port_range_hints[COMP_EQUAL].HintDescriptor = 0;
+ comp_ac_desc->instantiate = comp_instantiate;
+ comp_ac_desc->connect_port = comp_connect_port;
+ comp_ac_desc->activate = NULL;
+ comp_ac_desc->run = comp_run_ac;
+ comp_ac_desc->run_adding = NULL;
+ comp_ac_desc->set_run_adding_gain = NULL;
+ comp_ac_desc->deactivate = NULL;
+ comp_ac_desc->cleanup = comp_cleanup;
+ }
+
+ if (comp_aa_desc) {
+
+ comp_aa_desc->UniqueID = COMP_BASE_ID+1;
+ comp_aa_desc->Label = strdup("comp_aa");
+ comp_aa_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ comp_aa_desc->Name = strdup("Comparison (AA)");
+ comp_aa_desc->Maker = strdup("Thorsten Wilms");
+ comp_aa_desc->Copyright = strdup("GPL");
+ comp_aa_desc->PortCount = COMP_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(COMP_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ comp_aa_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[COMP_A] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[COMP_B] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[COMP_LARGER] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[COMP_SMALLER] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[COMP_A_LARGER] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[COMP_EQUAL] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(COMP_NUM_PORTS, sizeof(char*));
+ comp_aa_desc->PortNames = (const char**)port_names;
+ port_names[COMP_A] = strdup("A");
+ port_names[COMP_B] = strdup("B");
+ port_names[COMP_LARGER] = strdup("Larger");
+ port_names[COMP_SMALLER] = strdup("Smaller");
+ port_names[COMP_A_LARGER] = strdup("A > B");
+ port_names[COMP_EQUAL] = strdup("A = B");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(COMP_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ comp_aa_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[COMP_A].HintDescriptor = 0;
+ port_range_hints[COMP_B].HintDescriptor = 0;
+ port_range_hints[COMP_LARGER].HintDescriptor = 0;
+ port_range_hints[COMP_SMALLER].HintDescriptor = 0;
+ port_range_hints[COMP_A_LARGER].HintDescriptor = 0;
+ port_range_hints[COMP_EQUAL].HintDescriptor = 0;
+ comp_aa_desc->instantiate = comp_instantiate;
+ comp_aa_desc->connect_port = comp_connect_port;
+ comp_aa_desc->activate = NULL;
+ comp_aa_desc->run = comp_run_aa;
+ comp_aa_desc->run_adding = NULL;
+ comp_aa_desc->set_run_adding_gain = NULL;
+ comp_aa_desc->deactivate = NULL;
+ comp_aa_desc->cleanup = comp_cleanup;
+ }
+}
+
+
+void
+comp_delete_descriptor(LADSPA_Descriptor* psDescriptor)
+{
+ unsigned long lIndex;
+ if (psDescriptor) {
+ free((char*)psDescriptor->Label);
+ free((char*)psDescriptor->Name);
+ free((char*)psDescriptor->Maker);
+ free((char*)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char*)(psDescriptor->PortNames[lIndex]));
+ free((char**)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ comp_delete_descriptor(comp_ac_desc);
+ comp_delete_descriptor(comp_aa_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor*
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return comp_ac_desc;
+ case 1:
+ return comp_aa_desc;
+ default:
+ return NULL;
+ }
+}
+
diff --git a/src/dahdsr_fexp.c b/src/dahdsr_fexp.c
new file mode 100644
index 0000000..3da8c3f
--- /dev/null
+++ b/src/dahdsr_fexp.c
@@ -0,0 +1,510 @@
+/*
+ dahdsr_fexp.c - A LADSPA plugin to generate DAHDSR envelopes
+ exponential attack, decay and release version.
+ Copyright (C) 2005 Loki Davison, based on DAHDSR by Mike Rawes
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <ladspa.h>
+#include <math.h>
+
+#ifdef ENABLE_NLS
+# include <locale.h>
+# define G_(s) gettext(s)
+#else
+# define G_(s) (s)
+#endif
+#define G_NOP(s) s
+
+#define DAHDSR_VARIANT_COUNT 1
+
+#define DAHDSR_GATE 0
+#define DAHDSR_TRIGGER 1
+#define DAHDSR_DELAY 2
+#define DAHDSR_ATTACK 3
+#define DAHDSR_HOLD 4
+#define DAHDSR_DECAY 5
+#define DAHDSR_SUSTAIN 6
+#define DAHDSR_RELEASE 7
+#define DAHDSR_OUTPUT 8
+
+LADSPA_Descriptor **dahdsr_descriptors = 0;
+
+typedef enum {
+ IDLE,
+ DELAY,
+ ATTACK,
+ HOLD,
+ DECAY,
+ SUSTAIN,
+ RELEASE
+} DAHDSRState;
+
+typedef struct {
+ LADSPA_Data *gate;
+ LADSPA_Data *trigger;
+ LADSPA_Data *delay;
+ LADSPA_Data *attack;
+ LADSPA_Data *hold;
+ LADSPA_Data *decay;
+ LADSPA_Data *sustain;
+ LADSPA_Data *release;
+ LADSPA_Data *output;
+ LADSPA_Data srate;
+ LADSPA_Data inv_srate;
+ LADSPA_Data last_gate;
+ LADSPA_Data last_trigger;
+ LADSPA_Data from_level;
+ LADSPA_Data level;
+ DAHDSRState state;
+ unsigned long samples;
+} Dahdsr;
+
+const LADSPA_Descriptor *
+ladspa_descriptor(unsigned long index)
+{
+ if (index < DAHDSR_VARIANT_COUNT)
+ return dahdsr_descriptors[index];
+
+ return 0;
+}
+
+void
+cleanupDahdsr(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+void
+connectPortDahdsr(LADSPA_Handle instance,
+ unsigned long port, LADSPA_Data * data)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ switch (port) {
+ case DAHDSR_GATE:
+ plugin->gate = data;
+ break;
+ case DAHDSR_TRIGGER:
+ plugin->trigger = data;
+ break;
+ case DAHDSR_DELAY:
+ plugin->delay = data;
+ break;
+ case DAHDSR_ATTACK:
+ plugin->attack = data;
+ break;
+ case DAHDSR_HOLD:
+ plugin->hold = data;
+ break;
+ case DAHDSR_DECAY:
+ plugin->decay = data;
+ break;
+ case DAHDSR_SUSTAIN:
+ plugin->sustain = data;
+ break;
+ case DAHDSR_RELEASE:
+ plugin->release = data;
+ break;
+ case DAHDSR_OUTPUT:
+ plugin->output = data;
+ break;
+ }
+}
+
+LADSPA_Handle
+instantiateDahdsr(const LADSPA_Descriptor * descriptor,
+ unsigned long sample_rate)
+{
+ Dahdsr *plugin = (Dahdsr *) malloc(sizeof(Dahdsr));
+
+ plugin->srate = (LADSPA_Data) sample_rate;
+ plugin->inv_srate = 1.0f / plugin->srate;
+
+ return (LADSPA_Handle) plugin;
+}
+
+void
+activateDahdsr(LADSPA_Handle instance)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ plugin->last_gate = 0.0f;
+ plugin->last_trigger = 0.0f;
+ plugin->from_level = 0.0f;
+ plugin->level = 0.0f;
+ plugin->state = IDLE;
+ plugin->samples = 0;
+}
+
+void
+runDahdsr_Control(LADSPA_Handle instance, unsigned long sample_count)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ /* Gate */
+ LADSPA_Data *gate = plugin->gate;
+
+ /* Trigger */
+ LADSPA_Data *trigger = plugin->trigger;
+
+ /* Delay Time (s) */
+ LADSPA_Data delay = *(plugin->delay);
+
+ /* Attack Time (s) */
+ LADSPA_Data attack = *(plugin->attack);
+
+ /* Hold Time (s) */
+ LADSPA_Data hold = *(plugin->hold);
+
+ /* Decay Time (s) */
+ LADSPA_Data decay = *(plugin->decay);
+
+ /* Sustain Level */
+ LADSPA_Data sustain = *(plugin->sustain);
+
+ /* Release Time (s) */
+ LADSPA_Data release = *(plugin->release);
+
+ /* Envelope Out */
+ LADSPA_Data *output = plugin->output;
+
+ /* Instance Data */
+ LADSPA_Data srate = plugin->srate;
+ LADSPA_Data inv_srate = plugin->inv_srate;
+ LADSPA_Data last_gate = plugin->last_gate;
+ LADSPA_Data last_trigger = plugin->last_trigger;
+ LADSPA_Data from_level = plugin->from_level;
+ LADSPA_Data level = plugin->level;
+ DAHDSRState state = plugin->state;
+ unsigned long samples = plugin->samples;
+
+ LADSPA_Data gat, trg, del, att, hld, dec, sus, rel;
+ LADSPA_Data elapsed;
+ unsigned long s;
+
+ /* Convert times into rates */
+ del = delay > 0.0f ? inv_srate / delay : srate;
+ att = attack > 0.0f ? inv_srate / attack : srate;
+ hld = hold > 0.0f ? inv_srate / hold : srate;
+ dec = decay > 0.0f ? inv_srate / decay : srate;
+ rel = release > 0.0f ? inv_srate / release : srate;
+ sus = sustain;
+
+ if (sus == 0.0f) {
+ sus = 0.001f;
+ }
+ if (sus > 1.0f) {
+ sus = 1.0f;
+ }
+
+ LADSPA_Data ReleaseCoeff_att = (0 - log(0.001)) / (attack * srate);
+ LADSPA_Data ReleaseCoeff_dec = (log(sus)) / (decay * srate);
+ LADSPA_Data ReleaseCoeff_rel =
+ (log(0.001) - log(sus)) / (release * srate);
+
+ for (s = 0; s < sample_count; s++) {
+ gat = gate[s];
+ trg = trigger[s];
+
+ /* Initialise delay phase if gate is opened and was closed, or
+ we received a trigger */
+ if ((trg > 0.0f && !(last_trigger > 0.0f)) ||
+ (gat > 0.0f && !(last_gate > 0.0f))) {
+ if (del < srate) {
+ state = DELAY;
+ } else if (att < srate) {
+ state = ATTACK;
+ } else {
+ state = hld < srate ? HOLD
+ : (dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE : IDLE)));
+ level = 1.0f;
+ }
+ samples = 0;
+ }
+
+ /* Release if gate was open and now closed */
+ if (state != IDLE && state != RELEASE &&
+ last_gate > 0.0f && !(gat > 0.0f)) {
+ state = rel < srate ? RELEASE : IDLE;
+ samples = 0;
+ }
+
+ if (samples == 0)
+ from_level = level;
+
+ /* Calculate level of envelope from current state */
+ switch (state) {
+ case IDLE:
+ level = 0;
+ break;
+ case DELAY:
+ samples++;
+ elapsed = (LADSPA_Data) samples *del;
+
+ if (elapsed > 1.0f) {
+ state = att < srate ? ATTACK
+ : (hld < srate ? HOLD
+ : (dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE : IDLE))));
+ samples = 0;
+ }
+ break;
+ case ATTACK:
+ samples++;
+ elapsed = (LADSPA_Data) samples *att;
+
+ if (elapsed > 1.0f) {
+ state = hld < srate ? HOLD
+ : (dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE : IDLE)));
+ level = 1.0f;
+ samples = 0;
+ } else {
+ level += level * ReleaseCoeff_att;
+ }
+ break;
+ case HOLD:
+ samples++;
+ elapsed = (LADSPA_Data) samples *hld;
+
+ if (elapsed > 1.0f) {
+ state = dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN : (rel < srate ? RELEASE : IDLE));
+ samples = 0;
+ }
+ break;
+ case DECAY:
+ samples++;
+ elapsed = (LADSPA_Data) samples *dec;
+
+ if (elapsed > 1.0f) {
+ state = gat > 0.0f ? SUSTAIN : (rel < srate ? RELEASE : IDLE);
+ level = sus;
+ samples = 0;
+ } else {
+ level += level * ReleaseCoeff_dec;
+ }
+ break;
+ case SUSTAIN:
+ level = sus;
+ break;
+ case RELEASE:
+ samples++;
+ elapsed = (LADSPA_Data) samples *rel;
+
+ if (elapsed > 1.0f) {
+ state = IDLE;
+ level = 0.0f;
+ samples = 0;
+ } else {
+ level += level * ReleaseCoeff_rel;
+ }
+ break;
+ default:
+ /* Should never happen */
+ level = 0.0f;
+ }
+
+ output[s] = level;
+
+ last_gate = gat;
+ last_trigger = trg;
+ }
+
+ plugin->last_gate = last_gate;
+ plugin->last_trigger = last_trigger;
+ plugin->from_level = from_level;
+ plugin->level = level;
+ plugin->state = state;
+ plugin->samples = samples;
+}
+
+void
+_init(void)
+{
+ static const unsigned long ids[] = { 2664 };
+ static const char *labels[] = { "dahdsr_fexp" };
+ static const char *names[] = { G_NOP("DAHDSR Envelope full exp, adr") };
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+ LADSPA_Descriptor *descriptor;
+
+ LADSPA_PortDescriptor gate_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO };
+ LADSPA_PortDescriptor trigger_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO };
+ LADSPA_PortDescriptor delay_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor attack_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor hold_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor decay_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor sustain_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor release_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor output_port_descriptors[] =
+ { LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO };
+
+ void (*run_functions[]) (LADSPA_Handle, unsigned long) = {
+ runDahdsr_Control};
+
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+#endif
+
+ dahdsr_descriptors =
+ (LADSPA_Descriptor **) calloc(DAHDSR_VARIANT_COUNT,
+ sizeof(LADSPA_Descriptor));
+
+ if (dahdsr_descriptors) {
+ int i = 0;
+
+ dahdsr_descriptors[i] =
+ (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor));
+ descriptor = dahdsr_descriptors[i];
+ if (descriptor) {
+ descriptor->UniqueID = ids[i];
+ descriptor->Label = labels[i];
+ descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ descriptor->Name = G_(names[i]);
+ descriptor->Maker =
+ "Loki Davison <ltdav1[at]student.monash.edu.au>";
+ descriptor->Copyright = "GPL";
+
+ descriptor->PortCount = 9;
+
+ port_descriptors =
+ (LADSPA_PortDescriptor *) calloc(9,
+ sizeof
+ (LADSPA_PortDescriptor));
+ descriptor->PortDescriptors =
+ (const LADSPA_PortDescriptor *)port_descriptors;
+
+ port_range_hints =
+ (LADSPA_PortRangeHint *) calloc(9,
+ sizeof(LADSPA_PortRangeHint));
+ descriptor->PortRangeHints =
+ (const LADSPA_PortRangeHint *)port_range_hints;
+
+ port_names = (char **)calloc(9, sizeof(char *));
+ descriptor->PortNames = (const char **)port_names;
+
+ /* Parameters for Gate */
+ port_descriptors[DAHDSR_GATE] = gate_port_descriptors[i];
+ port_names[DAHDSR_GATE] = G_("Gate");
+ port_range_hints[DAHDSR_GATE].HintDescriptor =
+ LADSPA_HINT_TOGGLED;
+
+ /* Parameters for Trigger */
+ port_descriptors[DAHDSR_TRIGGER] = trigger_port_descriptors[i];
+ port_names[DAHDSR_TRIGGER] = G_("Trigger");
+ port_range_hints[DAHDSR_TRIGGER].HintDescriptor =
+ LADSPA_HINT_TOGGLED;
+
+ /* Parameters for Delay Time (s) */
+ port_descriptors[DAHDSR_DELAY] = delay_port_descriptors[i];
+ port_names[DAHDSR_DELAY] = G_("Delay Time (s)");
+ port_range_hints[DAHDSR_DELAY].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[DAHDSR_DELAY].LowerBound = 0.0f;
+
+ /* Parameters for Attack Time (s) */
+ port_descriptors[DAHDSR_ATTACK] = attack_port_descriptors[i];
+ port_names[DAHDSR_ATTACK] = G_("Attack Time (s)");
+ port_range_hints[DAHDSR_ATTACK].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[DAHDSR_ATTACK].LowerBound = 0.0f;
+
+ /* Parameters for Hold Time (s) */
+ port_descriptors[DAHDSR_HOLD] = hold_port_descriptors[i];
+ port_names[DAHDSR_HOLD] = G_("Hold Time (s)");
+ port_range_hints[DAHDSR_HOLD].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[DAHDSR_HOLD].LowerBound = 0.0f;
+
+ /* Parameters for Decay Time (s) */
+ port_descriptors[DAHDSR_DECAY] = decay_port_descriptors[i];
+ port_names[DAHDSR_DECAY] = G_("Decay Time (s)");
+ port_range_hints[DAHDSR_DECAY].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[DAHDSR_DECAY].LowerBound = 0.0f;
+
+ /* Parameters for Sustain Level */
+ port_descriptors[DAHDSR_SUSTAIN] = sustain_port_descriptors[i];
+ port_names[DAHDSR_SUSTAIN] = G_("Sustain Level");
+ port_range_hints[DAHDSR_SUSTAIN].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE |
+ LADSPA_HINT_DEFAULT_MAXIMUM;
+ port_range_hints[DAHDSR_SUSTAIN].LowerBound = 0.0f;
+ port_range_hints[DAHDSR_SUSTAIN].UpperBound = 1.0f;
+
+ /* Parameters for Release Time (s) */
+ port_descriptors[DAHDSR_RELEASE] = release_port_descriptors[i];
+ port_names[DAHDSR_RELEASE] = G_("Release Time (s)");
+ port_range_hints[DAHDSR_RELEASE].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[DAHDSR_RELEASE].LowerBound = 0.0f;
+
+ /* Parameters for Envelope Out */
+ port_descriptors[DAHDSR_OUTPUT] = output_port_descriptors[i];
+ port_names[DAHDSR_OUTPUT] = G_("Envelope Out");
+ port_range_hints[DAHDSR_OUTPUT].HintDescriptor = 0;
+
+ descriptor->activate = activateDahdsr;
+ descriptor->cleanup = cleanupDahdsr;
+ descriptor->connect_port = connectPortDahdsr;
+ descriptor->deactivate = NULL;
+ descriptor->instantiate = instantiateDahdsr;
+ descriptor->run = run_functions[i];
+ descriptor->run_adding = NULL;
+ descriptor->set_run_adding_gain = NULL;
+
+ }
+ }
+}
+
+void
+_fini(void)
+{
+ LADSPA_Descriptor *descriptor;
+ int i;
+
+ if (dahdsr_descriptors) {
+ for (i = 0; i < DAHDSR_VARIANT_COUNT; i++) {
+ descriptor = dahdsr_descriptors[i];
+ if (descriptor) {
+ free((LADSPA_PortDescriptor *) descriptor->PortDescriptors);
+ free((char **)descriptor->PortNames);
+ free((LADSPA_PortRangeHint *) descriptor->PortRangeHints);
+ free(descriptor);
+ }
+ }
+ free(dahdsr_descriptors);
+ }
+}
diff --git a/src/dahdsr_hexp.c b/src/dahdsr_hexp.c
new file mode 100644
index 0000000..a091e14
--- /dev/null
+++ b/src/dahdsr_hexp.c
@@ -0,0 +1,511 @@
+/*
+ dahdsr.so.c - A LADSPA plugin to generate DAHDSR envelopes
+ linear attack, exponential decay and release version.
+ Copyright (C) 2005 Loki Davison, based on DAHDSR by Mike Rawes
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <ladspa.h>
+#include <math.h>
+
+#ifdef ENABLE_NLS
+# include <locale.h>
+# define G_(s) gettext(s)
+#else
+# define G_(s) (s)
+#endif
+#define G_NOP(s) s
+
+#define DAHDSR_VARIANT_COUNT 1
+
+#define DAHDSR_GATE 0
+#define DAHDSR_TRIGGER 1
+#define DAHDSR_DELAY 2
+#define DAHDSR_ATTACK 3
+#define DAHDSR_HOLD 4
+#define DAHDSR_DECAY 5
+#define DAHDSR_SUSTAIN 6
+#define DAHDSR_RELEASE 7
+#define DAHDSR_OUTPUT 8
+
+LADSPA_Descriptor **dahdsr_descriptors = 0;
+
+typedef enum {
+ IDLE,
+ DELAY,
+ ATTACK,
+ HOLD,
+ DECAY,
+ SUSTAIN,
+ RELEASE
+} DAHDSRState;
+
+typedef struct {
+ LADSPA_Data *gate;
+ LADSPA_Data *trigger;
+ LADSPA_Data *delay;
+ LADSPA_Data *attack;
+ LADSPA_Data *hold;
+ LADSPA_Data *decay;
+ LADSPA_Data *sustain;
+ LADSPA_Data *release;
+ LADSPA_Data *output;
+ LADSPA_Data srate;
+ LADSPA_Data inv_srate;
+ LADSPA_Data last_gate;
+ LADSPA_Data last_trigger;
+ LADSPA_Data from_level;
+ LADSPA_Data level;
+ DAHDSRState state;
+ unsigned long samples;
+} Dahdsr;
+
+const LADSPA_Descriptor *
+ladspa_descriptor(unsigned long index)
+{
+ if (index < DAHDSR_VARIANT_COUNT)
+ return dahdsr_descriptors[index];
+
+ return 0;
+}
+
+void
+cleanupDahdsr(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+void
+connectPortDahdsr(LADSPA_Handle instance,
+ unsigned long port, LADSPA_Data * data)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ switch (port) {
+ case DAHDSR_GATE:
+ plugin->gate = data;
+ break;
+ case DAHDSR_TRIGGER:
+ plugin->trigger = data;
+ break;
+ case DAHDSR_DELAY:
+ plugin->delay = data;
+ break;
+ case DAHDSR_ATTACK:
+ plugin->attack = data;
+ break;
+ case DAHDSR_HOLD:
+ plugin->hold = data;
+ break;
+ case DAHDSR_DECAY:
+ plugin->decay = data;
+ break;
+ case DAHDSR_SUSTAIN:
+ plugin->sustain = data;
+ break;
+ case DAHDSR_RELEASE:
+ plugin->release = data;
+ break;
+ case DAHDSR_OUTPUT:
+ plugin->output = data;
+ break;
+ }
+}
+
+LADSPA_Handle
+instantiateDahdsr(const LADSPA_Descriptor * descriptor,
+ unsigned long sample_rate)
+{
+ Dahdsr *plugin = (Dahdsr *) malloc(sizeof(Dahdsr));
+
+ plugin->srate = (LADSPA_Data) sample_rate;
+ plugin->inv_srate = 1.0f / plugin->srate;
+
+ return (LADSPA_Handle) plugin;
+}
+
+void
+activateDahdsr(LADSPA_Handle instance)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ plugin->last_gate = 0.0f;
+ plugin->last_trigger = 0.0f;
+ plugin->from_level = 0.0f;
+ plugin->level = 0.0f;
+ plugin->state = IDLE;
+ plugin->samples = 0;
+}
+
+void
+runDahdsr_Control(LADSPA_Handle instance, unsigned long sample_count)
+{
+ Dahdsr *plugin = (Dahdsr *) instance;
+
+ /* Gate */
+ LADSPA_Data *gate = plugin->gate;
+
+ /* Trigger */
+ LADSPA_Data *trigger = plugin->trigger;
+
+ /* Delay Time (s) */
+ LADSPA_Data delay = *(plugin->delay);
+
+ /* Attack Time (s) */
+ LADSPA_Data attack = *(plugin->attack);
+
+ /* Hold Time (s) */
+ LADSPA_Data hold = *(plugin->hold);
+
+ /* Decay Time (s) */
+ LADSPA_Data decay = *(plugin->decay);
+
+ /* Sustain Level */
+ LADSPA_Data sustain = *(plugin->sustain);
+
+ /* Release Time (s) */
+ LADSPA_Data release = *(plugin->release);
+
+ /* Envelope Out */
+ LADSPA_Data *output = plugin->output;
+
+ /* Instance Data */
+ LADSPA_Data srate = plugin->srate;
+ LADSPA_Data inv_srate = plugin->inv_srate;
+ LADSPA_Data last_gate = plugin->last_gate;
+ LADSPA_Data last_trigger = plugin->last_trigger;
+ LADSPA_Data from_level = plugin->from_level;
+ LADSPA_Data level = plugin->level;
+ DAHDSRState state = plugin->state;
+ unsigned long samples = plugin->samples;
+
+ LADSPA_Data gat, trg, del, att, hld, dec, sus, rel;
+ LADSPA_Data elapsed;
+ unsigned long s;
+
+ /* Convert times into rates */
+ del = delay > 0.0f ? inv_srate / delay : srate;
+ att = attack > 0.0f ? inv_srate / attack : srate;
+ hld = hold > 0.0f ? inv_srate / hold : srate;
+ dec = decay > 0.0f ? inv_srate / decay : srate;
+ rel = release > 0.0f ? inv_srate / release : srate;
+ sus = sustain;
+
+ if (sus == 0) {
+ sus = 0.001;
+ }
+ if (sus > 1.0f) {
+ sus = 1.0f;
+ }
+
+ //LADSPA_Data ReleaseCoeff_att = (0 - log(0.001)) / (attack * srate);
+ LADSPA_Data ReleaseCoeff_dec = (log(sus)) / (decay * srate);
+ LADSPA_Data ReleaseCoeff_rel =
+ (log(0.001) - log(sus)) / (release * srate);
+
+ for (s = 0; s < sample_count; s++) {
+ gat = gate[s];
+ trg = trigger[s];
+
+ /* Initialise delay phase if gate is opened and was closed, or
+ we received a trigger */
+ if ((trg > 0.0f && !(last_trigger > 0.0f)) ||
+ (gat > 0.0f && !(last_gate > 0.0f))) {
+ if (del < srate) {
+ state = DELAY;
+ } else if (att < srate) {
+ state = ATTACK;
+ } else {
+ state = hld < srate ? HOLD
+ : (dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE : IDLE)));
+ level = 1.0f;
+ }
+ samples = 0;
+ }
+
+ /* Release if gate was open and now closed */
+ if (state != IDLE && state != RELEASE &&
+ last_gate > 0.0f && !(gat > 0.0f)) {
+ state = rel < srate ? RELEASE : IDLE;
+ samples = 0;
+ }
+
+ if (samples == 0)
+ from_level = level;
+
+ /* Calculate level of envelope from current state */
+ switch (state) {
+ case IDLE:
+ level = 0;
+ break;
+ case DELAY:
+ samples++;
+ elapsed = (LADSPA_Data) samples *del;
+
+ if (elapsed > 1.0f) {
+ state = att < srate ? ATTACK
+ : (hld < srate ? HOLD
+ : (dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE : IDLE))));
+ samples = 0;
+ }
+ break;
+ case ATTACK:
+ samples++;
+ elapsed = (LADSPA_Data) samples *att;
+
+ if (elapsed > 1.0f) {
+ state = hld < srate ? HOLD
+ : (dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN
+ : (rel < srate ? RELEASE : IDLE)));
+ level = 1.0f;
+ samples = 0;
+ } else {
+ level = from_level + elapsed * (1.0f - from_level);
+ }
+ break;
+ case HOLD:
+ samples++;
+ elapsed = (LADSPA_Data) samples *hld;
+
+ if (elapsed > 1.0f) {
+ state = dec < srate ? DECAY
+ : (gat > 0.0f ? SUSTAIN : (rel < srate ? RELEASE : IDLE));
+ samples = 0;
+ }
+ break;
+ case DECAY:
+ samples++;
+ elapsed = (LADSPA_Data) samples *dec;
+
+ if (elapsed > 1.0f) {
+ state = gat > 0.0f ? SUSTAIN : (rel < srate ? RELEASE : IDLE);
+ level = sus;
+ samples = 0;
+ } else {
+ level += level * ReleaseCoeff_dec;
+ }
+ break;
+ case SUSTAIN:
+ level = sus;
+ break;
+ case RELEASE:
+ samples++;
+ elapsed = (LADSPA_Data) samples *rel;
+
+ if (elapsed > 1.0f) {
+ state = IDLE;
+ level = 0.0f;
+ samples = 0;
+ } else {
+ level += level * ReleaseCoeff_rel;
+ }
+ break;
+ default:
+ /* Should never happen */
+ level = 0.0f;
+ }
+
+ output[s] = level;
+
+ last_gate = gat;
+ last_trigger = trg;
+ }
+
+ plugin->last_gate = last_gate;
+ plugin->last_trigger = last_trigger;
+ plugin->from_level = from_level;
+ plugin->level = level;
+ plugin->state = state;
+ plugin->samples = samples;
+}
+
+void
+_init(void)
+{
+ static const unsigned long ids[] = { 2663 };
+ static const char *labels[] = { "dahdsr_hexp" };
+ static const char *names[] =
+ { G_NOP("DAHDSR Envelope linear attack exp dr") };
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+ LADSPA_Descriptor *descriptor;
+
+ LADSPA_PortDescriptor gate_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO };
+ LADSPA_PortDescriptor trigger_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO };
+ LADSPA_PortDescriptor delay_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor attack_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor hold_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor decay_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor sustain_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor release_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor output_port_descriptors[] =
+ { LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO };
+
+ void (*run_functions[]) (LADSPA_Handle, unsigned long) = {
+ runDahdsr_Control};
+
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+#endif
+
+ dahdsr_descriptors =
+ (LADSPA_Descriptor **) calloc(DAHDSR_VARIANT_COUNT,
+ sizeof(LADSPA_Descriptor));
+
+ if (dahdsr_descriptors) {
+ int i = 0;
+
+ dahdsr_descriptors[i] =
+ (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor));
+ descriptor = dahdsr_descriptors[i];
+ if (descriptor) {
+ descriptor->UniqueID = ids[i];
+ descriptor->Label = labels[i];
+ descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ descriptor->Name = G_(names[i]);
+ descriptor->Maker =
+ "Loki Davison <ltdav1[at]student.monash.edu.au>";
+ descriptor->Copyright = "GPL";
+
+ descriptor->PortCount = 9;
+
+ port_descriptors =
+ (LADSPA_PortDescriptor *) calloc(9,
+ sizeof
+ (LADSPA_PortDescriptor));
+ descriptor->PortDescriptors =
+ (const LADSPA_PortDescriptor *)port_descriptors;
+
+ port_range_hints =
+ (LADSPA_PortRangeHint *) calloc(9,
+ sizeof(LADSPA_PortRangeHint));
+ descriptor->PortRangeHints =
+ (const LADSPA_PortRangeHint *)port_range_hints;
+
+ port_names = (char **)calloc(9, sizeof(char *));
+ descriptor->PortNames = (const char **)port_names;
+
+ /* Parameters for Gate */
+ port_descriptors[DAHDSR_GATE] = gate_port_descriptors[i];
+ port_names[DAHDSR_GATE] = G_("Gate");
+ port_range_hints[DAHDSR_GATE].HintDescriptor =
+ LADSPA_HINT_TOGGLED;
+
+ /* Parameters for Trigger */
+ port_descriptors[DAHDSR_TRIGGER] = trigger_port_descriptors[i];
+ port_names[DAHDSR_TRIGGER] = G_("Trigger");
+ port_range_hints[DAHDSR_TRIGGER].HintDescriptor =
+ LADSPA_HINT_TOGGLED;
+
+ /* Parameters for Delay Time (s) */
+ port_descriptors[DAHDSR_DELAY] = delay_port_descriptors[i];
+ port_names[DAHDSR_DELAY] = G_("Delay Time (s)");
+ port_range_hints[DAHDSR_DELAY].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[DAHDSR_DELAY].LowerBound = 0.0f;
+
+ /* Parameters for Attack Time (s) */
+ port_descriptors[DAHDSR_ATTACK] = attack_port_descriptors[i];
+ port_names[DAHDSR_ATTACK] = G_("Attack Time (s)");
+ port_range_hints[DAHDSR_ATTACK].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[DAHDSR_ATTACK].LowerBound = 0.0f;
+
+ /* Parameters for Hold Time (s) */
+ port_descriptors[DAHDSR_HOLD] = hold_port_descriptors[i];
+ port_names[DAHDSR_HOLD] = G_("Hold Time (s)");
+ port_range_hints[DAHDSR_HOLD].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[DAHDSR_HOLD].LowerBound = 0.0f;
+
+ /* Parameters for Decay Time (s) */
+ port_descriptors[DAHDSR_DECAY] = decay_port_descriptors[i];
+ port_names[DAHDSR_DECAY] = G_("Decay Time (s)");
+ port_range_hints[DAHDSR_DECAY].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[DAHDSR_DECAY].LowerBound = 0.0f;
+
+ /* Parameters for Sustain Level */
+ port_descriptors[DAHDSR_SUSTAIN] = sustain_port_descriptors[i];
+ port_names[DAHDSR_SUSTAIN] = G_("Sustain Level");
+ port_range_hints[DAHDSR_SUSTAIN].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE |
+ LADSPA_HINT_DEFAULT_MAXIMUM;
+ port_range_hints[DAHDSR_SUSTAIN].LowerBound = 0.0f;
+ port_range_hints[DAHDSR_SUSTAIN].UpperBound = 1.0f;
+
+ /* Parameters for Release Time (s) */
+ port_descriptors[DAHDSR_RELEASE] = release_port_descriptors[i];
+ port_names[DAHDSR_RELEASE] = G_("Release Time (s)");
+ port_range_hints[DAHDSR_RELEASE].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_DEFAULT_MINIMUM;
+ port_range_hints[DAHDSR_RELEASE].LowerBound = 0.0f;
+
+ /* Parameters for Envelope Out */
+ port_descriptors[DAHDSR_OUTPUT] = output_port_descriptors[i];
+ port_names[DAHDSR_OUTPUT] = G_("Envelope Out");
+ port_range_hints[DAHDSR_OUTPUT].HintDescriptor = 0;
+
+ descriptor->activate = activateDahdsr;
+ descriptor->cleanup = cleanupDahdsr;
+ descriptor->connect_port = connectPortDahdsr;
+ descriptor->deactivate = NULL;
+ descriptor->instantiate = instantiateDahdsr;
+ descriptor->run = run_functions[i];
+ descriptor->run_adding = NULL;
+ descriptor->set_run_adding_gain = NULL;
+
+ }
+ }
+}
+
+void
+_fini(void)
+{
+ LADSPA_Descriptor *descriptor;
+ int i;
+
+ if (dahdsr_descriptors) {
+ for (i = 0; i < DAHDSR_VARIANT_COUNT; i++) {
+ descriptor = dahdsr_descriptors[i];
+ if (descriptor) {
+ free((LADSPA_PortDescriptor *) descriptor->PortDescriptors);
+ free((char **)descriptor->PortNames);
+ free((LADSPA_PortRangeHint *) descriptor->PortRangeHints);
+ free(descriptor);
+ }
+ }
+ free(dahdsr_descriptors);
+ }
+}
diff --git a/src/fast_crossfade_4410.c b/src/fast_crossfade_4410.c
new file mode 100644
index 0000000..c961565
--- /dev/null
+++ b/src/fast_crossfade_4410.c
@@ -0,0 +1,215 @@
+/* Crossfade with AR Level plugin. Copyright (C) 2005 Thorsten Wilms.
+ * Based on Dave Robillard's "Hz to AMS style V/Oct" plugin for the skeleton.
+ * Thanks to Florian Schmidt for explaining how to calculate the scale values
+ * before I could work it out myself! ;-)
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+
+#include "ladspa.h"
+
+#define XFADE_LEVEL_ID 4410
+
+#define XFADE_NUM_PORTS 4
+
+/* Port Numbers */
+#define XFADE_LEVEL 0
+#define XFADE_A 1
+#define XFADE_B 2
+#define XFADE_OUTPUT 3
+
+/* All state information for plugin */
+typedef struct {
+ /* Ports */
+ LADSPA_Data *level_buffer;
+ LADSPA_Data *a_buffer;
+ LADSPA_Data *b_buffer;
+ LADSPA_Data *output_buffer;
+} XFADE;
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+XFADE_instantiate(const LADSPA_Descriptor * descriptor, unsigned long srate)
+{
+ return (LADSPA_Handle)malloc(sizeof(XFADE));
+}
+
+
+/* Connect a port to a data location */
+void
+XFADE_connect_port(LADSPA_Handle instance,
+ unsigned long port, LADSPA_Data * location)
+{
+ XFADE* plugin;
+
+ plugin = (XFADE*) instance;
+ switch (port) {
+ case XFADE_LEVEL:
+ plugin->level_buffer = location;
+ break;
+ case XFADE_A:
+ plugin->a_buffer = location;
+ break;
+ case XFADE_B:
+ plugin->b_buffer = location;
+ break;
+ case XFADE_OUTPUT:
+ plugin->output_buffer = location;
+ break;
+ }
+}
+
+
+void
+XFADE_run_ar(LADSPA_Handle instance, unsigned long nframes)
+{
+ LADSPA_Data* level;
+ LADSPA_Data* a;
+ LADSPA_Data* b;
+ LADSPA_Data* output;
+ XFADE* plugin;
+ unsigned long i;
+ float l;
+
+ plugin = (XFADE*)instance;
+
+ level = plugin->level_buffer;
+ a = plugin->a_buffer;
+ b = plugin->b_buffer;
+ output = plugin->output_buffer;
+
+ for (i = 0; i < nframes; i++) {
+ /* transfer multiplication value to 0 to 1 range */
+ if (level[i] < -1) {
+ l = 0;
+ } else if (level[i] > 1) {
+ l = 1;
+ } else {
+ l = (level[i] + 1) / 2;
+ }
+
+ output[i] = a[i] * l + b[i] * (1 - l);
+ }
+}
+
+
+void
+XFADE_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor *xfade_descriptor = NULL;
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+
+ xfade_descriptor =
+ (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor));
+
+ if (xfade_descriptor) {
+ xfade_descriptor->UniqueID = XFADE_LEVEL_ID;
+ xfade_descriptor->Label = strdup("fast_xfade");
+ xfade_descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ xfade_descriptor->Name = strdup("Fast Crossfade");
+ xfade_descriptor->Maker = strdup("Thorsten Wilms");
+ xfade_descriptor->Copyright = strdup("GPL");
+ xfade_descriptor->PortCount = XFADE_NUM_PORTS;
+ port_descriptors =
+ (LADSPA_PortDescriptor *) calloc(XFADE_NUM_PORTS,
+ sizeof(LADSPA_PortDescriptor));
+ xfade_descriptor->PortDescriptors =
+ (const LADSPA_PortDescriptor *)port_descriptors;
+ port_descriptors[XFADE_LEVEL] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[XFADE_A] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[XFADE_B] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[XFADE_OUTPUT] =
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char **)calloc(XFADE_NUM_PORTS, sizeof(char *));
+ xfade_descriptor->PortNames = (const char **)port_names;
+ port_names[XFADE_LEVEL] = strdup("Level");
+ port_names[XFADE_A] = strdup("A");
+ port_names[XFADE_B] = strdup("B");
+ port_names[XFADE_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(XFADE_NUM_PORTS,
+ sizeof(LADSPA_PortRangeHint)));
+ xfade_descriptor->PortRangeHints =
+ (const LADSPA_PortRangeHint *)port_range_hints;
+ port_range_hints[XFADE_LEVEL].HintDescriptor = 0;
+ port_range_hints[XFADE_A].HintDescriptor = 0;
+ port_range_hints[XFADE_B].HintDescriptor = 0;
+ port_range_hints[XFADE_OUTPUT].HintDescriptor = 0;
+ xfade_descriptor->instantiate = XFADE_instantiate;
+ xfade_descriptor->connect_port = XFADE_connect_port;
+ xfade_descriptor->activate = NULL;
+ xfade_descriptor->run = XFADE_run_ar;
+ xfade_descriptor->run_adding = NULL;
+ xfade_descriptor->set_run_adding_gain = NULL;
+ xfade_descriptor->deactivate = NULL;
+ xfade_descriptor->cleanup = XFADE_cleanup;
+ }
+
+}
+
+
+void
+XFADE_delete_descriptors(LADSPA_Descriptor * psdescriptors)
+{
+ unsigned long lIndex;
+
+ if (psdescriptors) {
+ free((char *)psdescriptors->Label);
+ free((char *)psdescriptors->Name);
+ free((char *)psdescriptors->Maker);
+ free((char *)psdescriptors->Copyright);
+ free((LADSPA_PortDescriptor *) psdescriptors->PortDescriptors);
+ for (lIndex = 0; lIndex < psdescriptors->PortCount; lIndex++)
+ free((char *)(psdescriptors->PortNames[lIndex]));
+ free((char **)psdescriptors->PortNames);
+ free((LADSPA_PortRangeHint *) psdescriptors->PortRangeHints);
+ free(psdescriptors);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ XFADE_delete_descriptors(xfade_descriptor);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor *
+ladspa_descriptor(unsigned long index)
+{
+ if (index == 0)
+ return xfade_descriptor;
+ return 0;
+}
+
diff --git a/src/formant_filter_4300.c b/src/formant_filter_4300.c
new file mode 100644
index 0000000..7b2e587
--- /dev/null
+++ b/src/formant_filter_4300.c
@@ -0,0 +1,344 @@
+/* Formant filter plugin. Copyright (C) 2005 Dave Robillard.
+ *
+ * Based on SSM formant filter,
+ * Copyright (C) 2001 David Griffiths <dave@pawfal.org>
+ *
+ * Based on public domain code from alex@smartelectronix.com
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "ladspa.h"
+
+#define FORMANT_BASE_ID 4300
+
+#define FORMANT_NUM_PORTS 3
+
+/* Port Numbers */
+#define FORMANT_VOWEL 0
+#define FORMANT_INPUT 1
+#define FORMANT_OUTPUT 2
+
+
+/* Vowel Coefficients */
+const double coeff[5][11] = {
+ { /* A */ 8.11044e-06,
+ 8.943665402, -36.83889529, 92.01697887, -154.337906, 181.6233289,
+ -151.8651235, 89.09614114, -35.10298511, 8.388101016, -0.923313471
+ },
+ { /* E */ 4.36215e-06,
+ 8.90438318, -36.55179099, 91.05750846, -152.422234, 179.1170248,
+ -149.6496211, 87.78352223, -34.60687431, 8.282228154, -0.914150747
+ },
+ { /* I */ 3.33819e-06,
+ 8.893102966, -36.49532826, 90.96543286, -152.4545478, 179.4835618,
+ -150.315433, 88.43409371, -34.98612086, 8.407803364, -0.932568035
+ },
+ { /* O */ 1.13572e-06,
+ 8.994734087, -37.2084849, 93.22900521, -156.6929844, 184.596544,
+ -154.3755513, 90.49663749, -35.58964535, 8.478996281, -0.929252233
+ },
+ { /* U */ 4.09431e-07,
+ 8.997322763, -37.20218544, 93.11385476, -156.2530937, 183.7080141,
+ -153.2631681, 89.59539726, -35.12454591, 8.338655623, -0.910251753
+ }
+};
+
+
+/* All state information for plugin */
+typedef struct
+{
+ /* Ports */
+ LADSPA_Data* vowel;
+ LADSPA_Data* input;
+ LADSPA_Data* output;
+
+ double memory[5][10];
+} Formant;
+
+
+/* Linear interpolation */
+inline float
+linear(float bot, float top, float pos, float val1, float val2)
+{
+ float t = (pos - bot) / (top - bot);
+ return val1 * t + val2 * (1.0f - t);
+}
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+formant_instantiate(const LADSPA_Descriptor* descriptor,
+ unsigned long srate)
+{
+ return (LADSPA_Handle)malloc(sizeof(Formant));
+}
+
+
+/** Activate an instance */
+void
+formant_activate(LADSPA_Handle instance)
+{
+ Formant* plugin = (Formant*)instance;
+ int i, j;
+
+ for (i = 0; i < 5; ++i)
+ for (j = 0; j < 10; ++j)
+ plugin->memory[i][j] = 0.0;
+}
+
+
+/* Connect a port to a data location */
+void
+formant_connect_port(LADSPA_Handle instance,
+ unsigned long port,
+ LADSPA_Data* location)
+{
+ Formant* plugin;
+
+ plugin = (Formant*)instance;
+ switch (port) {
+ case FORMANT_VOWEL:
+ plugin->vowel = location;
+ break;
+ case FORMANT_INPUT:
+ plugin->input = location;
+ break;
+ case FORMANT_OUTPUT:
+ plugin->output = location;
+ break;
+ }
+}
+
+
+void
+formant_run_vc(LADSPA_Handle instance, unsigned long nframes)
+{
+ Formant* plugin = (Formant*)instance;
+ LADSPA_Data vowel;
+ LADSPA_Data in;
+ LADSPA_Data* out;
+ LADSPA_Data res;
+ LADSPA_Data o[5];
+ size_t n, v;
+
+ for (n=0; n < nframes; ++n) {
+ vowel = plugin->vowel[0];
+ in = plugin->input[n];
+ out = plugin->output;
+
+ for (v=0; v < 5; ++v) {
+ res = (float) (coeff[v][0] * (in * 0.1f) +
+ coeff[v][1] * plugin->memory[v][0] +
+ coeff[v][2] * plugin->memory[v][1] +
+ coeff[v][3] * plugin->memory[v][2] +
+ coeff[v][4] * plugin->memory[v][3] +
+ coeff[v][5] * plugin->memory[v][4] +
+ coeff[v][6] * plugin->memory[v][5] +
+ coeff[v][7] * plugin->memory[v][6] +
+ coeff[v][8] * plugin->memory[v][7] +
+ coeff[v][9] * plugin->memory[v][8] +
+ coeff[v][10] * plugin->memory[v][9] );
+
+ plugin->memory[v][9] = plugin->memory[v][8];
+ plugin->memory[v][8] = plugin->memory[v][7];
+ plugin->memory[v][7] = plugin->memory[v][6];
+ plugin->memory[v][6] = plugin->memory[v][5];
+ plugin->memory[v][5] = plugin->memory[v][4];
+ plugin->memory[v][4] = plugin->memory[v][3];
+ plugin->memory[v][3] = plugin->memory[v][2];
+ plugin->memory[v][2] = plugin->memory[v][1];
+ plugin->memory[v][1] = plugin->memory[v][0];
+ plugin->memory[v][0] = (double)res;
+
+ o[v] = res;
+ }
+
+ // Mix between formants
+ if (vowel <= 0)
+ out[n] = o[0];
+ else if (vowel > 0 && vowel < 1)
+ out[n] = linear(0.0f, 1.0f, vowel, o[1], o[0]);
+ else if (vowel == 1)
+ out[n] = o[1];
+ else if (vowel > 1 && vowel < 2)
+ out[n] = linear(0.0f, 1.0f, vowel - 1.0f, o[2], o[1]);
+ else if (vowel == 2)
+ out[n] = o[2];
+ else if (vowel > 2 && vowel < 3)
+ out[n] = linear(0.0f, 1.0f, vowel - 2.0f, o[3], o[2]);
+ else if (vowel == 3)
+ out[n] = o[3];
+ else if (vowel > 3 && vowel < 4)
+ out[n] = linear(0.0f, 1.0f, vowel - 3.0f, o[4], o[3]);
+ else //if (vowel >= 4)
+ out[n] = o[4];
+ }
+}
+
+/*
+void
+formant_run_va(LADSPA_Handle instance, unsigned long nframes)
+{
+ LADSPA_Data* input;
+ LADSPA_Data* output;
+ Formant* plugin = (Formant*)instance;
+}*/
+
+
+void
+formant_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor* formant_vc_desc = NULL;
+//LADSPA_Descriptor* formant_va_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+
+ formant_vc_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ //formant_va_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+
+ if (formant_vc_desc) {
+
+ formant_vc_desc->UniqueID = FORMANT_BASE_ID;
+ formant_vc_desc->Label = strdup("formant_vc");
+ formant_vc_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ formant_vc_desc->Name = strdup("Formant Filter (CR vowel)");
+ formant_vc_desc->Maker = strdup("Dave Robillard");
+ formant_vc_desc->Copyright = strdup("GPL");
+ formant_vc_desc->PortCount = FORMANT_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(FORMANT_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ formant_vc_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[FORMANT_VOWEL] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[FORMANT_INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[FORMANT_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(FORMANT_NUM_PORTS, sizeof(char*));
+ formant_vc_desc->PortNames = (const char**)port_names;
+ port_names[FORMANT_VOWEL] = strdup("Vowel");
+ port_names[FORMANT_INPUT] = strdup("Input");
+ port_names[FORMANT_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(FORMANT_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ formant_vc_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[FORMANT_VOWEL].LowerBound = 0.0f;
+ port_range_hints[FORMANT_VOWEL].UpperBound = 4.0f;
+ port_range_hints[FORMANT_VOWEL].HintDescriptor =
+ LADSPA_HINT_DEFAULT_0 | LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
+ port_range_hints[FORMANT_INPUT].HintDescriptor = 0;
+ port_range_hints[FORMANT_OUTPUT].HintDescriptor = 0;
+ formant_vc_desc->instantiate = formant_instantiate;
+ formant_vc_desc->connect_port = formant_connect_port;
+ formant_vc_desc->activate = formant_activate;
+ formant_vc_desc->run = formant_run_vc;
+ formant_vc_desc->run_adding = NULL;
+ formant_vc_desc->set_run_adding_gain = NULL;
+ formant_vc_desc->deactivate = NULL;
+ formant_vc_desc->cleanup = formant_cleanup;
+ }
+
+ /*if (formant_va_desc) {
+
+ formant_va_desc->UniqueID = FORMANT_BASE_ID+1;
+ formant_va_desc->Label = strdup("formant_va");
+ formant_va_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ formant_va_desc->Name = strdup("Formant Filter (AR vowel)");
+ formant_va_desc->Maker = strdup("Dave Robillard");
+ formant_va_desc->Copyright = strdup("GPL");
+ formant_va_desc->PortCount = FORMANT_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(FORMANT_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ formant_va_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[FORMANT_VOWEL] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[FORMANT_INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[FORMANT_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(FORMANT_NUM_PORTS, sizeof(char*));
+ formant_va_desc->PortNames = (const char**)port_names;
+ port_names[FORMANT_VOWEL] = strdup("Vowel");
+ port_names[FORMANT_INPUT] = strdup("Input");
+ port_names[FORMANT_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(FORMANT_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ formant_va_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[FORMANT_VOWEL].HintDescriptor = 0;
+ port_range_hints[FORMANT_INPUT].HintDescriptor = 0;
+ port_range_hints[FORMANT_OUTPUT].HintDescriptor = 0;
+ formant_va_desc->instantiate = formant_instantiate;
+ formant_va_desc->connect_port = formant_connect_port;
+ formant_va_desc->activate = formant_activate;
+ formant_va_desc->run = formant_run_va;
+ formant_va_desc->run_adding = NULL;
+ formant_va_desc->set_run_adding_gain = NULL;
+ formant_va_desc->deactivate = NULL;
+ formant_va_desc->cleanup = formant_cleanup;
+ }*/
+}
+
+
+void
+formant_delete_descriptor(LADSPA_Descriptor* psDescriptor)
+{
+ unsigned long lIndex;
+ if (psDescriptor) {
+ free((char*)psDescriptor->Label);
+ free((char*)psDescriptor->Name);
+ free((char*)psDescriptor->Maker);
+ free((char*)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor*)psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char*)(psDescriptor->PortNames[lIndex]));
+ free((char**)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint*)psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ formant_delete_descriptor(formant_vc_desc);
+ //formant_delete_descriptor(formant_va_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor*
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return formant_vc_desc;
+ //case 1:
+ // return formant_va_desc;
+ default:
+ return NULL;
+ }
+}
+
diff --git a/src/hz_voct_4200.c b/src/hz_voct_4200.c
new file mode 100644
index 0000000..977a405
--- /dev/null
+++ b/src/hz_voct_4200.c
@@ -0,0 +1,242 @@
+/* Hz to AMS style V/Oct plugin. Copyright (C) 2005 Dave Robillard.
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "ladspa.h"
+
+#define HZVOCT_BASE_ID 4200
+
+#define HZVOCT_NUM_PORTS 2
+
+/* Port Numbers */
+#define HZVOCT_INPUT 0
+#define HZVOCT_OUTPUT 1
+
+
+/* All state information for plugin */
+typedef struct
+{
+ /* Ports */
+ LADSPA_Data* input_buffer;
+ LADSPA_Data* output_buffer;
+} HzVoct;
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+hzvoct_instantiate(const LADSPA_Descriptor* descriptor,
+ unsigned long srate)
+{
+ HzVoct* plugin = malloc(sizeof(HzVoct));
+ plugin->input_buffer = NULL;
+ plugin->output_buffer = NULL;
+ return (LADSPA_Handle)plugin;
+}
+
+
+/* Connect a port to a data location */
+void
+hzvoct_connect_port(LADSPA_Handle instance,
+ unsigned long port,
+ LADSPA_Data* location)
+{
+ HzVoct* plugin;
+
+ plugin = (HzVoct*)instance;
+ switch (port) {
+ case HZVOCT_INPUT:
+ plugin->input_buffer = location;
+ break;
+ case HZVOCT_OUTPUT:
+ plugin->output_buffer = location;
+ break;
+ }
+}
+
+
+void
+hzvoct_run_cr(LADSPA_Handle instance, unsigned long nframes)
+{
+ HzVoct* plugin;
+ float log2inv;
+ float eighth = 1.0f/8.0f;
+ const float offset = 2.0313842f; // + octave, ... -1, 0, 1 ...
+
+ plugin = (HzVoct*)instance;
+ log2inv = 1.0f/logf(2.0f);
+
+ *plugin->output_buffer = logf(*plugin->input_buffer * eighth) * log2inv - offset;
+}
+
+
+void
+hzvoct_run_ar(LADSPA_Handle instance, unsigned long nframes)
+{
+ LADSPA_Data* input;
+ LADSPA_Data* output;
+ HzVoct* plugin;
+ unsigned long i;
+ float log2inv;
+ float eighth = 1.0f/8.0f;
+ const float offset = 5.0313842; // + octave, ... -1, 0, 1 ...
+
+ plugin = (HzVoct*)instance;
+ log2inv = 1.0f/logf(2.0);
+
+ input = plugin->input_buffer;
+ output = plugin->output_buffer;
+
+ // Inverse of the formula used in AMS's converter module (except the 1/8 part)
+ for (i = 0; i < nframes; i++)
+ *output++ = logf((*input++) * eighth) * log2inv - offset;
+}
+
+
+void
+hzvoct_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor* hz_voct_cr_desc = NULL;
+LADSPA_Descriptor* hz_voct_ar_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+
+ hz_voct_cr_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ hz_voct_ar_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+
+ if (hz_voct_cr_desc) {
+
+ hz_voct_cr_desc->UniqueID = HZVOCT_BASE_ID;
+ hz_voct_cr_desc->Label = strdup("hz_voct_cr");
+ hz_voct_cr_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ hz_voct_cr_desc->Name = strdup("Hz to V/Oct Converter (CR)");
+ hz_voct_cr_desc->Maker = strdup("Dave Robillard");
+ hz_voct_cr_desc->Copyright = strdup("GPL");
+ hz_voct_cr_desc->PortCount = HZVOCT_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(HZVOCT_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ hz_voct_cr_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[HZVOCT_INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[HZVOCT_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
+ port_names = (char**)calloc(HZVOCT_NUM_PORTS, sizeof(char*));
+ hz_voct_cr_desc->PortNames = (const char**)port_names;
+ port_names[HZVOCT_INPUT] = strdup("Input");
+ port_names[HZVOCT_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(HZVOCT_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ hz_voct_cr_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[HZVOCT_INPUT].HintDescriptor = 0;
+ port_range_hints[HZVOCT_OUTPUT].HintDescriptor = 0;
+ hz_voct_cr_desc->instantiate = hzvoct_instantiate;
+ hz_voct_cr_desc->connect_port = hzvoct_connect_port;
+ hz_voct_cr_desc->activate = NULL;
+ hz_voct_cr_desc->run = hzvoct_run_cr;
+ hz_voct_cr_desc->run_adding = NULL;
+ hz_voct_cr_desc->set_run_adding_gain = NULL;
+ hz_voct_cr_desc->deactivate = NULL;
+ hz_voct_cr_desc->cleanup = hzvoct_cleanup;
+ }
+
+ if (hz_voct_ar_desc) {
+
+ hz_voct_ar_desc->UniqueID = HZVOCT_BASE_ID+1;
+ hz_voct_ar_desc->Label = strdup("hz_voct_ar");
+ hz_voct_ar_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ hz_voct_ar_desc->Name = strdup("Hz to V/Oct Converter (AR)");
+ hz_voct_ar_desc->Maker = strdup("Dave Robillard");
+ hz_voct_ar_desc->Copyright = strdup("GPL");
+ hz_voct_ar_desc->PortCount = HZVOCT_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(HZVOCT_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ hz_voct_ar_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[HZVOCT_INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[HZVOCT_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(HZVOCT_NUM_PORTS, sizeof(char*));
+ hz_voct_ar_desc->PortNames = (const char**)port_names;
+ port_names[HZVOCT_INPUT] = strdup("Input");
+ port_names[HZVOCT_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(HZVOCT_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ hz_voct_ar_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[HZVOCT_INPUT].HintDescriptor = 0;
+ port_range_hints[HZVOCT_OUTPUT].HintDescriptor = 0;
+ hz_voct_ar_desc->instantiate = hzvoct_instantiate;
+ hz_voct_ar_desc->connect_port = hzvoct_connect_port;
+ hz_voct_ar_desc->activate = NULL;
+ hz_voct_ar_desc->run = hzvoct_run_ar;
+ hz_voct_ar_desc->run_adding = NULL;
+ hz_voct_ar_desc->set_run_adding_gain = NULL;
+ hz_voct_ar_desc->deactivate = NULL;
+ hz_voct_ar_desc->cleanup = hzvoct_cleanup;
+ }
+}
+
+
+void
+hzvoct_delete_descriptor(LADSPA_Descriptor* psDescriptor)
+{
+ unsigned long lIndex;
+ if (psDescriptor) {
+ free((char*)psDescriptor->Label);
+ free((char*)psDescriptor->Name);
+ free((char*)psDescriptor->Maker);
+ free((char*)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char*)(psDescriptor->PortNames[lIndex]));
+ free((char**)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ hzvoct_delete_descriptor(hz_voct_cr_desc);
+ hzvoct_delete_descriptor(hz_voct_ar_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor*
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return hz_voct_cr_desc;
+ case 1:
+ return hz_voct_ar_desc;
+ default:
+ return NULL;
+ }
+}
+
diff --git a/src/masher_4310.c b/src/masher_4310.c
new file mode 100644
index 0000000..34ef7aa
--- /dev/null
+++ b/src/masher_4310.c
@@ -0,0 +1,346 @@
+/* Masher
+ * Copyright (C) 2001 David Griffiths <dave@pawfal.org>
+ * LADSPAfication (C) 2005 Dave Robillard <drobilla@connect.carelton.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+/* NOTE: This is a very dirty hack full of arbitrary limits and assumptions.
+ * It needs fixing/completion */
+
+
+#define _XOPEN_SOURCE 600 /* posix_memalign */
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "ladspa.h"
+
+#define MASHER_BASE_ID 4310
+
+#define MASHER_NUM_PORTS 4
+
+/* Port Numbers */
+#define MASHER_INPUT 0
+#define MASHER_GRAINPITCH 1
+#define MASHER_DENSITY 2
+#define MASHER_OUTPUT 3
+
+#define GRAINSTORE_SIZE 1000
+#define OVERLAPS_SIZE 1000
+#define MAX_GRAIN_SIZE 2048
+
+typedef struct {
+ LADSPA_Data* data;
+ size_t length;
+} Sample;
+
+
+typedef struct {
+ int pos;
+ int grain;
+} GrainDesc;
+
+
+/* All state information for plugin */
+typedef struct {
+ /* Ports */
+ LADSPA_Data *input;
+ LADSPA_Data *grain_pitch;
+ LADSPA_Data *density;
+ LADSPA_Data *output;
+
+ Sample grain_store[GRAINSTORE_SIZE];
+ GrainDesc overlaps[OVERLAPS_SIZE];
+ size_t overlaps_size;
+
+ size_t write_grain;
+} Masher;
+
+
+float
+rand_range(float l, float h)
+{
+ return ((rand() % 10000 / 10000.0f) * (h - l)) + l;
+}
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+masher_instantiate(const LADSPA_Descriptor * descriptor, unsigned long srate)
+{
+ return (LADSPA_Handle)malloc(sizeof(Masher));
+}
+
+
+/** Activate an instance */
+void
+masher_activate(LADSPA_Handle instance)
+{
+ Masher *plugin = (Masher*)instance;
+ int i = 0;
+
+ plugin->overlaps_size = 0;
+ plugin->write_grain = 0;
+
+ for (i=0; i < GRAINSTORE_SIZE; ++i) {
+ //plugin->grain_store[i].data = (LADSPA_Data*)calloc(MAX_GRAIN_SIZE, sizeof(LADSPA_Data));
+ posix_memalign((void**)&plugin->grain_store[i].data, 16, MAX_GRAIN_SIZE * sizeof(LADSPA_Data));
+ plugin->grain_store[i].length = 0;
+ }
+}
+
+
+/* Connect a port to a data location */
+void
+masher_connect_port(LADSPA_Handle instance,
+ unsigned long port, LADSPA_Data * location)
+{
+ Masher *plugin = (Masher *) instance;
+
+ switch (port) {
+ case MASHER_INPUT:
+ plugin->input = location;
+ break;
+ case MASHER_GRAINPITCH:
+ plugin->grain_pitch = location;
+ break;
+ case MASHER_DENSITY:
+ plugin->density = location;
+ break;
+ case MASHER_OUTPUT:
+ plugin->output = location;
+ break;
+ }
+}
+
+
+void
+mix_pitch(Sample* src, Sample* dst, size_t pos, float pitch)
+{
+ float n = 0;
+ size_t p = pos;
+
+ while (n < src->length && p < dst->length) {
+ dst->data[p] = dst->data[p] + src->data[(size_t)n];
+ n += pitch;
+ p++;
+ }
+}
+
+
+void
+masher_run(LADSPA_Handle instance, unsigned long nframes)
+{
+ Masher* plugin = (Masher*)instance;
+
+ static const int randomness = 1.0; // FIXME: make a control port
+ int read_grain = 0; // FIXME: what is this?
+ int grain_store_size = 100; // FIXME: what is this? (max 1000)
+
+ const LADSPA_Data grain_pitch = *plugin->grain_pitch;
+ const LADSPA_Data density = *plugin->density;
+
+ const LADSPA_Data* const in = plugin->input;
+ LADSPA_Data* const out = plugin->output;
+
+ Sample out_sample = { out, nframes };
+
+ size_t n = 0;
+ float s = in[0];
+ int last = 0;
+ bool first = true;
+ size_t grain_index = 0;
+ size_t next_grain = 0;
+
+ // Zero output buffer
+ for (n = 0; n < nframes; ++n)
+ out[n] = 0.0f;
+
+ // Paste any overlapping grains to the start of the buffer.
+ for (n = 0; n < plugin->overlaps_size; ++n) {
+ mix_pitch(&plugin->grain_store[plugin->overlaps[n].grain], &out_sample,
+ plugin->overlaps[n].pos - nframes, grain_pitch);
+ }
+ plugin->overlaps_size = 0;
+
+ // Chop up the buffer and put the grains in the grainstore
+ for (n = 0; n < nframes; n++) {
+ if ((s < 0 && in[n] > 0) || (s > 0 && in[n] < 0)) {
+ // Chop the bits between zero crossings
+ if (!first) {
+ if (n - last <= MAX_GRAIN_SIZE) {
+ grain_index = plugin->write_grain % grain_store_size;
+ memcpy(plugin->grain_store[grain_index].data, in, nframes);
+ plugin->grain_store[grain_index].length = n - last;
+ }
+ plugin->write_grain++; // FIXME: overflow?
+ } else {
+ first = false;
+ }
+
+ last = n;
+ s = in[n];
+ }
+ }
+
+ for (n = 0; n < nframes; n++) {
+ if (n >= next_grain || rand() % 1000 < density) {
+ size_t grain_num = read_grain % grain_store_size;
+ mix_pitch(&plugin->grain_store[grain_num], &out_sample, n, grain_pitch);
+ size_t grain_length = (plugin->grain_store[grain_num].length * grain_pitch);
+
+ next_grain = n + plugin->grain_store[grain_num].length;
+
+ // If this grain overlaps the buffer
+ if (n + grain_length > nframes) {
+ if (plugin->overlaps_size < OVERLAPS_SIZE) {
+ GrainDesc new_grain;
+
+ new_grain.pos = n;
+ new_grain.grain = grain_num;
+ plugin->overlaps[plugin->overlaps_size++] = new_grain;
+ }
+ }
+
+ if (randomness)
+ read_grain += 1 + rand() % randomness;
+ else
+ read_grain++;
+ }
+ }
+}
+
+
+void
+masher_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor *masher_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+
+ masher_desc = (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor));
+
+ if (masher_desc) {
+
+ masher_desc->UniqueID = MASHER_BASE_ID;
+ masher_desc->Label = strdup("ssm_masher");
+ masher_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ masher_desc->Name = strdup("Masher");
+ masher_desc->Maker = strdup("Dave Griffiths");
+ masher_desc->Copyright = strdup("GPL");
+ masher_desc->PortCount = MASHER_NUM_PORTS;
+ port_descriptors =
+ (LADSPA_PortDescriptor *) calloc(MASHER_NUM_PORTS,
+ sizeof(LADSPA_PortDescriptor));
+ masher_desc->PortDescriptors =
+ (const LADSPA_PortDescriptor *)port_descriptors;
+ port_descriptors[MASHER_INPUT] =
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[MASHER_GRAINPITCH] =
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[MASHER_DENSITY] =
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[MASHER_OUTPUT] =
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char **)calloc(MASHER_NUM_PORTS, sizeof(char *));
+ masher_desc->PortNames = (const char **)port_names;
+ port_names[MASHER_INPUT] = strdup("Input");
+ port_names[MASHER_GRAINPITCH] = strdup("Grain Pitch");
+ port_names[MASHER_DENSITY] = strdup("Density");
+ port_names[MASHER_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(MASHER_NUM_PORTS,
+ sizeof(LADSPA_PortRangeHint)));
+ masher_desc->PortRangeHints =
+ (const LADSPA_PortRangeHint *)port_range_hints;
+
+ port_range_hints[MASHER_GRAINPITCH].LowerBound = 1.0f;
+ port_range_hints[MASHER_GRAINPITCH].UpperBound = 10.0f;
+ port_range_hints[MASHER_GRAINPITCH].HintDescriptor =
+ LADSPA_HINT_DEFAULT_1 | LADSPA_HINT_BOUNDED_BELOW |
+ LADSPA_HINT_BOUNDED_ABOVE;
+ port_range_hints[MASHER_DENSITY].LowerBound = 0.0f;
+ port_range_hints[MASHER_DENSITY].UpperBound = 800.0f;
+ port_range_hints[MASHER_DENSITY].HintDescriptor =
+ LADSPA_HINT_DEFAULT_MIDDLE | LADSPA_HINT_BOUNDED_BELOW |
+ LADSPA_HINT_BOUNDED_ABOVE;
+ port_range_hints[MASHER_INPUT].HintDescriptor = 0;
+ port_range_hints[MASHER_OUTPUT].HintDescriptor = 0;
+ masher_desc->instantiate = masher_instantiate;
+ masher_desc->connect_port = masher_connect_port;
+ masher_desc->activate = masher_activate;
+ masher_desc->run = masher_run;
+ masher_desc->run_adding = NULL;
+ masher_desc->set_run_adding_gain = NULL;
+ masher_desc->deactivate = NULL;
+ masher_desc->cleanup = masher_cleanup;
+ }
+}
+
+
+void
+masher_delete_descriptor(LADSPA_Descriptor * psDescriptor)
+{
+ unsigned long lIndex;
+
+ if (psDescriptor) {
+ free((char *)psDescriptor->Label);
+ free((char *)psDescriptor->Name);
+ free((char *)psDescriptor->Maker);
+ free((char *)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor *) psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char *)(psDescriptor->PortNames[lIndex]));
+ free((char **)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint *) psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ masher_delete_descriptor(masher_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor *
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return masher_desc;
+ default:
+ return NULL;
+ }
+}
+
+
diff --git a/src/multiplexer_4420.c b/src/multiplexer_4420.c
new file mode 100644
index 0000000..cff4c36
--- /dev/null
+++ b/src/multiplexer_4420.c
@@ -0,0 +1,249 @@
+/* Multiplxer plugin. Copyright (C) 2005 Thorsten Wilms.
+ * GATEd on Dave Robillard's "Hz to AMS style V/Oct" plugin for the skeleton.
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "ladspa.h"
+
+#define MUX_GATE_ID 4420
+
+#define MUX_NUM_PORTS 4
+
+/* Port Numbers */
+#define MUX_GATE 0
+#define MUX_OFF 1
+#define MUX_ON 2
+#define MUX_OUTPUT 3
+
+
+/* All state information for plugin */
+typedef struct
+{
+ /* Ports */
+ LADSPA_Data* gate_buffer;
+ LADSPA_Data* off_buffer;
+ LADSPA_Data* on_buffer;
+ LADSPA_Data* output_buffer;
+} MUX;
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+MUX_instantiate(const LADSPA_Descriptor* descriptor,
+ unsigned long srate)
+{
+ return (LADSPA_Handle)malloc(sizeof(MUX));
+}
+
+
+/* Connect a port to a data location */
+void
+MUX_connect_port(LADSPA_Handle instance,
+ unsigned long port,
+ LADSPA_Data* location)
+{
+ MUX* plugin;
+
+ plugin = (MUX*)instance;
+ switch (port) {
+ case MUX_GATE:
+ plugin->gate_buffer = location;
+ break;
+ case MUX_OFF:
+ plugin->off_buffer = location;
+ break;
+ case MUX_ON:
+ plugin->on_buffer = location;
+ break;
+ case MUX_OUTPUT:
+ plugin->output_buffer = location;
+ break;
+ }
+}
+
+
+void
+MUX_run_cr(LADSPA_Handle instance, unsigned long nframes)
+{
+ const MUX* const plugin = (MUX*)instance;
+
+ if (*plugin->gate_buffer <= 0)
+ *plugin->output_buffer = *plugin->off_buffer;
+ else
+ *plugin->output_buffer = *plugin->on_buffer;
+}
+
+
+void
+MUX_run_ar(LADSPA_Handle instance, unsigned long nframes)
+{
+ const MUX* const plugin = (MUX*)instance;
+ const LADSPA_Data* const gate = plugin->gate_buffer;
+ const LADSPA_Data* const off = plugin->off_buffer;
+ const LADSPA_Data* const on = plugin->on_buffer;
+ LADSPA_Data* const output = plugin->output_buffer;
+ unsigned long i;
+
+ for (i = 0; i < nframes; i++)
+ output[i] = (gate[i] <= 0) ? off[i] : on[i];
+}
+
+
+void
+MUX_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor* MUX_cr_desc = NULL;
+LADSPA_Descriptor* MUX_ar_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+
+ MUX_cr_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ MUX_ar_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+
+ if (MUX_cr_desc) {
+ MUX_cr_desc->UniqueID = MUX_GATE_ID;
+ MUX_cr_desc->Label = strdup("mux_cr");
+ MUX_cr_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ MUX_cr_desc->Name = strdup("Multiplexer (CR)");
+ MUX_cr_desc->Maker = strdup("Thorsten Wilms");
+ MUX_cr_desc->Copyright = strdup("GPL");
+ MUX_cr_desc->PortCount = MUX_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(MUX_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ MUX_cr_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[MUX_GATE] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[MUX_OFF] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[MUX_ON] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[MUX_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
+ port_names = (char**)calloc(MUX_NUM_PORTS, sizeof(char*));
+ MUX_cr_desc->PortNames = (const char**)port_names;
+ port_names[MUX_GATE] = strdup("Gate");
+ port_names[MUX_OFF] = strdup("Off");
+ port_names[MUX_ON] = strdup("On");
+ port_names[MUX_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(MUX_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ MUX_cr_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[MUX_GATE].HintDescriptor = 0;
+ port_range_hints[MUX_OFF].HintDescriptor = 0;
+ port_range_hints[MUX_ON].HintDescriptor = 0;
+ port_range_hints[MUX_OUTPUT].HintDescriptor = 0;
+ MUX_cr_desc->instantiate = MUX_instantiate;
+ MUX_cr_desc->connect_port = MUX_connect_port;
+ MUX_cr_desc->activate = NULL;
+ MUX_cr_desc->run = MUX_run_cr;
+ MUX_cr_desc->run_adding = NULL;
+ MUX_cr_desc->set_run_adding_gain = NULL;
+ MUX_cr_desc->deactivate = NULL;
+ MUX_cr_desc->cleanup = MUX_cleanup;
+ }
+
+ if (MUX_ar_desc) {
+ MUX_ar_desc->UniqueID = MUX_GATE_ID+1;
+ MUX_ar_desc->Label = strdup("mux_ar");
+ MUX_ar_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ MUX_ar_desc->Name = strdup("Multiplexer (AR)");
+ MUX_ar_desc->Maker = strdup("Thorsten Wilms");
+ MUX_ar_desc->Copyright = strdup("GPL");
+ MUX_ar_desc->PortCount = MUX_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(MUX_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ MUX_ar_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[MUX_GATE] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[MUX_OFF] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[MUX_ON] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[MUX_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(MUX_NUM_PORTS, sizeof(char*));
+ MUX_ar_desc->PortNames = (const char**)port_names;
+ port_names[MUX_GATE] = strdup("Gate");
+ port_names[MUX_OFF] = strdup("Off");
+ port_names[MUX_ON] = strdup("On");
+ port_names[MUX_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(MUX_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ MUX_ar_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[MUX_GATE].HintDescriptor = 0;
+ port_range_hints[MUX_OFF].HintDescriptor = 0;
+ port_range_hints[MUX_ON].HintDescriptor = 0;
+ port_range_hints[MUX_OUTPUT].HintDescriptor = 0;
+ MUX_ar_desc->instantiate = MUX_instantiate;
+ MUX_ar_desc->connect_port = MUX_connect_port;
+ MUX_ar_desc->activate = NULL;
+ MUX_ar_desc->run = MUX_run_ar;
+ MUX_ar_desc->run_adding = NULL;
+ MUX_ar_desc->set_run_adding_gain = NULL;
+ MUX_ar_desc->deactivate = NULL;
+ MUX_ar_desc->cleanup = MUX_cleanup;
+ }
+}
+
+
+void
+MUX_delete_descriptor(LADSPA_Descriptor* psDescriptor)
+{
+ unsigned long lIndex;
+ if (psDescriptor) {
+ free((char*)psDescriptor->Label);
+ free((char*)psDescriptor->Name);
+ free((char*)psDescriptor->Maker);
+ free((char*)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char*)(psDescriptor->PortNames[lIndex]));
+ free((char**)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ MUX_delete_descriptor(MUX_cr_desc);
+ MUX_delete_descriptor(MUX_ar_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor*
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return MUX_cr_desc;
+ case 1:
+ return MUX_ar_desc;
+ default:
+ return NULL;
+ }
+}
+
diff --git a/src/power_4400.c b/src/power_4400.c
new file mode 100644
index 0000000..4c38677
--- /dev/null
+++ b/src/power_4400.c
@@ -0,0 +1,237 @@
+/* Base to the power of Exponent plugin. Copyright (C) 2005 Thorsten Wilms.
+ * Based on Dave Robillard's "Hz to AMS style V/Oct" plugin for the skeleton,
+ * and there's not much else in here :).
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "ladspa.h"
+
+#define POWER_BASE_ID 4400
+
+#define POWER_NUM_PORTS 3
+
+/* Port Numbers */
+#define POWER_BASE 0
+#define POWER_EXPONENT 1
+#define POWER_RESULT 2
+
+
+/* All state information for plugin */
+typedef struct
+{
+ /* Ports */
+ LADSPA_Data* base_buffer;
+ LADSPA_Data* exponent_buffer;
+ LADSPA_Data* result_buffer;
+} POWER;
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+POWER_instantiate(const LADSPA_Descriptor* descriptor,
+ unsigned long srate)
+{
+ return (LADSPA_Handle)malloc(sizeof(POWER));
+}
+
+
+/* Connect a port to a data location */
+void
+POWER_connect_port(LADSPA_Handle instance,
+ unsigned long port,
+ LADSPA_Data* location)
+{
+ POWER* plugin;
+
+ plugin = (POWER*)instance;
+ switch (port) {
+ case POWER_BASE:
+ plugin->base_buffer = location;
+ break;
+ case POWER_EXPONENT:
+ plugin->exponent_buffer = location;
+ break;
+ case POWER_RESULT:
+ plugin->result_buffer = location;
+ break;
+ }
+}
+
+
+void
+POWER_run_cr(LADSPA_Handle instance, unsigned long nframes)
+{
+ POWER* plugin = (POWER*)instance;
+
+ *plugin->result_buffer = powf(*plugin->base_buffer, *plugin->exponent_buffer);
+}
+
+
+void
+POWER_run_ar(LADSPA_Handle instance, unsigned long nframes)
+{
+ const POWER* const plugin = (POWER*)instance;
+ const LADSPA_Data* const base = plugin->base_buffer;
+ const LADSPA_Data* const exponent = plugin->exponent_buffer;
+ LADSPA_Data* const result = plugin->result_buffer;
+ unsigned long i;
+
+ for (i = 0; i < nframes; ++i)
+ result[i] = powf(base[i], exponent[i]);
+}
+
+
+void
+POWER_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor* power_cr_desc = NULL;
+LADSPA_Descriptor* power_ar_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+
+ power_cr_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ power_ar_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+
+ if (power_cr_desc) {
+
+ power_cr_desc->UniqueID = POWER_BASE_ID;
+ power_cr_desc->Label = strdup("power_cr");
+ power_cr_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ power_cr_desc->Name = strdup("Power (CR)");
+ power_cr_desc->Maker = strdup("Thorsten Wilms");
+ power_cr_desc->Copyright = strdup("GPL");
+ power_cr_desc->PortCount = POWER_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(POWER_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ power_cr_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[POWER_BASE] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[POWER_EXPONENT] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[POWER_RESULT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL;
+ port_names = (char**)calloc(POWER_NUM_PORTS, sizeof(char*));
+ power_cr_desc->PortNames = (const char**)port_names;
+ port_names[POWER_BASE] = strdup("Base");
+ port_names[POWER_EXPONENT] = strdup("Exponent");
+ port_names[POWER_RESULT] = strdup("Result");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(POWER_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ power_cr_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[POWER_BASE].HintDescriptor = 0;
+ port_range_hints[POWER_EXPONENT].HintDescriptor = 0;
+ port_range_hints[POWER_RESULT].HintDescriptor = 0;
+ power_cr_desc->instantiate = POWER_instantiate;
+ power_cr_desc->connect_port = POWER_connect_port;
+ power_cr_desc->activate = NULL;
+ power_cr_desc->run = POWER_run_cr;
+ power_cr_desc->run_adding = NULL;
+ power_cr_desc->set_run_adding_gain = NULL;
+ power_cr_desc->deactivate = NULL;
+ power_cr_desc->cleanup = POWER_cleanup;
+ }
+
+ if (power_ar_desc) {
+
+ power_ar_desc->UniqueID = POWER_BASE_ID+1;
+ power_ar_desc->Label = strdup("power");
+ power_ar_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ power_ar_desc->Name = strdup("Power (AR)");
+ power_ar_desc->Maker = strdup("Thorsten Wilms");
+ power_ar_desc->Copyright = strdup("GPL");
+ power_ar_desc->PortCount = POWER_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(POWER_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ power_ar_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[POWER_BASE] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[POWER_EXPONENT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[POWER_RESULT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(POWER_NUM_PORTS, sizeof(char*));
+ power_ar_desc->PortNames = (const char**)port_names;
+ port_names[POWER_BASE] = strdup("Base");
+ port_names[POWER_EXPONENT] = strdup("Exponent");
+ port_names[POWER_RESULT] = strdup("Result");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(POWER_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ power_ar_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[POWER_BASE].HintDescriptor = 0;
+ port_range_hints[POWER_EXPONENT].HintDescriptor = 0;
+ port_range_hints[POWER_RESULT].HintDescriptor = 0;
+ power_ar_desc->instantiate = POWER_instantiate;
+ power_ar_desc->connect_port = POWER_connect_port;
+ power_ar_desc->activate = NULL;
+ power_ar_desc->run = POWER_run_ar;
+ power_ar_desc->run_adding = NULL;
+ power_ar_desc->set_run_adding_gain = NULL;
+ power_ar_desc->deactivate = NULL;
+ power_ar_desc->cleanup = POWER_cleanup;
+ }
+}
+
+
+void
+POWER_delete_descriptor(LADSPA_Descriptor* psDescriptor)
+{
+ unsigned long lIndex;
+ if (psDescriptor) {
+ free((char*)psDescriptor->Label);
+ free((char*)psDescriptor->Name);
+ free((char*)psDescriptor->Maker);
+ free((char*)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char*)(psDescriptor->PortNames[lIndex]));
+ free((char**)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ POWER_delete_descriptor(power_cr_desc);
+ POWER_delete_descriptor(power_ar_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor*
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return power_cr_desc;
+ case 1:
+ return power_ar_desc;
+ default:
+ return NULL;
+ }
+}
+
diff --git a/src/prob_switch_2667.c b/src/prob_switch_2667.c
new file mode 100644
index 0000000..d1d4b21
--- /dev/null
+++ b/src/prob_switch_2667.c
@@ -0,0 +1,276 @@
+/* This file is an audio plugin. Copyright (C) 2005 Loki Davison.
+ *
+ * Probability parameter is the prob of input 1 being the output value.
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "ladspa.h"
+
+#define PROBSWITCH_BASE_ID 2667
+
+#define PROBSWITCH_NUM_PORTS 4
+
+/* Port Numbers */
+#define PROBSWITCH_INPUT1 0
+#define PROBSWITCH_INPUT2 1
+#define PROBSWITCH_PROB 2
+#define PROBSWITCH_OUTPUT 3
+
+
+/* All state information for plugin */
+typedef struct
+{
+ /* Ports */
+ LADSPA_Data* input2;
+ LADSPA_Data* prob;
+ LADSPA_Data* input1;
+ LADSPA_Data* output;
+} ProbSwitch;
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+probswitch_instantiate(const LADSPA_Descriptor* descriptor,
+ unsigned long srate)
+{
+ return (LADSPA_Handle)malloc(sizeof(ProbSwitch));
+}
+
+
+/* Connect a port to a data location */
+void
+probswitch_connect_port(LADSPA_Handle instance,
+ unsigned long port,
+ LADSPA_Data* location)
+{
+ ProbSwitch* plugin;
+
+ plugin = (ProbSwitch*)instance;
+ switch (port) {
+ case PROBSWITCH_INPUT2:
+ plugin->input2 = location;
+ break;
+ case PROBSWITCH_PROB:
+ plugin->prob = location;
+ break;
+ case PROBSWITCH_INPUT1:
+ plugin->input1 = location;
+ break;
+ case PROBSWITCH_OUTPUT:
+ plugin->output = location;
+ break;
+ }
+}
+
+
+void
+probswitch_run_cr(LADSPA_Handle instance, unsigned long nframes)
+{
+ ProbSwitch* plugin = (ProbSwitch*)instance;
+ LADSPA_Data* input1 = plugin->input1;
+ LADSPA_Data* input2 = plugin->input2;
+ LADSPA_Data* output = plugin->output;
+ LADSPA_Data prob = * (plugin->prob);
+ size_t i;
+ LADSPA_Data temp;
+
+ for (i = 0; i < nframes; ++i)
+ {
+ temp = rand();
+ if((temp/RAND_MAX) <= prob)
+ {
+ output[i] = input1[i];
+ }
+ else
+ {
+ output[i] = input2[i];
+ }
+ }
+
+}
+
+
+void
+probswitch_run_ar(LADSPA_Handle instance, unsigned long nframes)
+{
+ ProbSwitch* plugin = (ProbSwitch*)instance;
+ LADSPA_Data* input2 = plugin->input2;
+ LADSPA_Data* prob = plugin->prob;
+ LADSPA_Data* input1 = plugin->input1;
+ LADSPA_Data* output = plugin->output;
+ size_t i;
+
+ for (i = 0; i < nframes; ++i)
+ {
+ if((rand()/RAND_MAX) <= prob[i])
+ {
+ output[i] = input1[i];
+ }
+ else
+ {
+ output[i] = input2[i];
+ }
+ }
+}
+
+
+void
+probswitch_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor* prob_switch_cr_desc = NULL;
+LADSPA_Descriptor* prob_switch_ar_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+
+ prob_switch_cr_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ prob_switch_ar_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+
+ if (prob_switch_cr_desc) {
+
+ prob_switch_cr_desc->UniqueID = PROBSWITCH_BASE_ID;
+ prob_switch_cr_desc->Label = strdup("prob_switch_cr");
+ prob_switch_cr_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ prob_switch_cr_desc->Name = strdup("Probability Switch (CR Controls)");
+ prob_switch_cr_desc->Maker = strdup("Loki Davison");
+ prob_switch_cr_desc->Copyright = strdup("GPL");
+ prob_switch_cr_desc->PortCount = PROBSWITCH_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(PROBSWITCH_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ prob_switch_cr_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[PROBSWITCH_INPUT2] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[PROBSWITCH_PROB] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[PROBSWITCH_INPUT1] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[PROBSWITCH_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(PROBSWITCH_NUM_PORTS, sizeof(char*));
+ prob_switch_cr_desc->PortNames = (const char**)port_names;
+ port_names[PROBSWITCH_INPUT2] = strdup("Input 2");
+ port_names[PROBSWITCH_PROB] = strdup("Probability");
+ port_names[PROBSWITCH_INPUT1] = strdup("Input 1");
+ port_names[PROBSWITCH_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(PROBSWITCH_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ prob_switch_cr_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[PROBSWITCH_INPUT2].HintDescriptor = 0;
+ port_range_hints[PROBSWITCH_PROB].HintDescriptor = LADSPA_HINT_DEFAULT_1;
+ port_range_hints[PROBSWITCH_INPUT1].HintDescriptor = 0;
+ port_range_hints[PROBSWITCH_OUTPUT].HintDescriptor = 0;
+ prob_switch_cr_desc->instantiate = probswitch_instantiate;
+ prob_switch_cr_desc->connect_port = probswitch_connect_port;
+ prob_switch_cr_desc->activate = NULL;
+ prob_switch_cr_desc->run = probswitch_run_cr;
+ prob_switch_cr_desc->run_adding = NULL;
+ prob_switch_cr_desc->set_run_adding_gain = NULL;
+ prob_switch_cr_desc->deactivate = NULL;
+ prob_switch_cr_desc->cleanup = probswitch_cleanup;
+ }
+
+ if (prob_switch_ar_desc) {
+
+ prob_switch_ar_desc->UniqueID = PROBSWITCH_BASE_ID+1;
+ prob_switch_ar_desc->Label = strdup("prob_switch_ar");
+ prob_switch_ar_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ prob_switch_ar_desc->Name = strdup("Probability Switch (AR Controls)");
+ prob_switch_ar_desc->Maker = strdup("Loki Davison");
+ prob_switch_ar_desc->Copyright = strdup("GPL");
+ prob_switch_ar_desc->PortCount = PROBSWITCH_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(PROBSWITCH_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ prob_switch_ar_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[PROBSWITCH_INPUT2] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[PROBSWITCH_PROB] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[PROBSWITCH_INPUT1] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[PROBSWITCH_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(PROBSWITCH_NUM_PORTS, sizeof(char*));
+ prob_switch_ar_desc->PortNames = (const char**)port_names;
+ port_names[PROBSWITCH_INPUT2] = strdup("Input 2");
+ port_names[PROBSWITCH_PROB] = strdup("Probability");
+ port_names[PROBSWITCH_INPUT1] = strdup("Input 1");
+ port_names[PROBSWITCH_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(PROBSWITCH_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ prob_switch_ar_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[PROBSWITCH_INPUT2].HintDescriptor = 0;
+ port_range_hints[PROBSWITCH_PROB].HintDescriptor = 0;
+ port_range_hints[PROBSWITCH_INPUT1].HintDescriptor = 0;
+ port_range_hints[PROBSWITCH_OUTPUT].HintDescriptor = 0;
+ prob_switch_ar_desc->instantiate = probswitch_instantiate;
+ prob_switch_ar_desc->connect_port = probswitch_connect_port;
+ prob_switch_ar_desc->activate = NULL;
+ prob_switch_ar_desc->run = probswitch_run_ar;
+ prob_switch_ar_desc->run_adding = NULL;
+ prob_switch_ar_desc->set_run_adding_gain = NULL;
+ prob_switch_ar_desc->deactivate = NULL;
+ prob_switch_ar_desc->cleanup = probswitch_cleanup;
+ }
+}
+
+
+void
+probswitch_delete_descriptor(LADSPA_Descriptor* psDescriptor)
+{
+ unsigned long lIndex;
+ if (psDescriptor) {
+ free((char*)psDescriptor->Label);
+ free((char*)psDescriptor->Name);
+ free((char*)psDescriptor->Maker);
+ free((char*)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char*)(psDescriptor->PortNames[lIndex]));
+ free((char**)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ probswitch_delete_descriptor(prob_switch_cr_desc);
+ probswitch_delete_descriptor(prob_switch_ar_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor*
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return prob_switch_cr_desc;
+ case 1:
+ return prob_switch_ar_desc;
+ default:
+ return NULL;
+ }
+}
+
diff --git a/src/range_trans_4210.c b/src/range_trans_4210.c
new file mode 100644
index 0000000..4b65eb5
--- /dev/null
+++ b/src/range_trans_4210.c
@@ -0,0 +1,281 @@
+/* This file is an audio plugin. Copyright (C) 2005 Dave Robillard.
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "ladspa.h"
+
+#define RANGETRANS_BASE_ID 4210
+
+#define RANGETRANS_NUM_PORTS 6
+
+/* Port Numbers */
+#define RANGETRANS_IN_MIN 0
+#define RANGETRANS_IN_MAX 1
+#define RANGETRANS_OUT_MIN 2
+#define RANGETRANS_OUT_MAX 3
+#define RANGETRANS_INPUT 4
+#define RANGETRANS_OUTPUT 5
+
+
+/* All state information for plugin */
+typedef struct
+{
+ /* Ports */
+ LADSPA_Data* in_min;
+ LADSPA_Data* in_max;
+ LADSPA_Data* out_min;
+ LADSPA_Data* out_max;
+ LADSPA_Data* input;
+ LADSPA_Data* output;
+} RangeTrans;
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+rangetrans_instantiate(const LADSPA_Descriptor* descriptor,
+ unsigned long srate)
+{
+ return (LADSPA_Handle)malloc(sizeof(RangeTrans));
+}
+
+
+/* Connect a port to a data location */
+void
+rangetrans_connect_port(LADSPA_Handle instance,
+ unsigned long port,
+ LADSPA_Data* location)
+{
+ RangeTrans* plugin;
+
+ plugin = (RangeTrans*)instance;
+ switch (port) {
+ case RANGETRANS_IN_MIN:
+ plugin->in_min = location;
+ break;
+ case RANGETRANS_IN_MAX:
+ plugin->in_max = location;
+ break;
+ case RANGETRANS_OUT_MIN:
+ plugin->out_min = location;
+ break;
+ case RANGETRANS_OUT_MAX:
+ plugin->out_max = location;
+ break;
+ case RANGETRANS_INPUT:
+ plugin->input = location;
+ break;
+ case RANGETRANS_OUTPUT:
+ plugin->output = location;
+ break;
+ }
+}
+
+
+void
+rangetrans_run_cr(LADSPA_Handle instance, unsigned long nframes)
+{
+ const RangeTrans* const plugin = (RangeTrans*)instance;
+ const LADSPA_Data in_min = *plugin->in_min;
+ const LADSPA_Data in_max = *plugin->in_max;
+ const LADSPA_Data out_min = *plugin->out_min;
+ const LADSPA_Data out_max = *plugin->out_max;
+ const LADSPA_Data* const input = plugin->input;
+ LADSPA_Data* const output = plugin->output;
+ unsigned long i;
+
+ for (i = 0; i < nframes; ++i)
+ output[i] = ((input[i] - in_min) / (in_max - in_min))
+ * (out_max - out_min) + out_min;
+}
+
+
+void
+rangetrans_run_ar(LADSPA_Handle instance, unsigned long nframes)
+{
+ const RangeTrans* const plugin = (RangeTrans*)instance;
+ const LADSPA_Data* const in_min = plugin->in_min;
+ const LADSPA_Data* const in_max = plugin->in_max;
+ const LADSPA_Data* const out_min = plugin->out_min;
+ const LADSPA_Data* const out_max = plugin->out_max;
+ const LADSPA_Data* const input = plugin->input;
+ LADSPA_Data* const output = plugin->output;
+ unsigned long i;
+
+ for (i = 0; i < nframes; ++i)
+ output[i] = ((input[i] - in_min[i]) / (in_max[i] - in_min[i]))
+ * (out_max[i] - out_min[i]) + out_min[i];
+}
+
+
+void
+rangetrans_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor* range_trans_cr_desc = NULL;
+LADSPA_Descriptor* range_trans_ar_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+
+ range_trans_cr_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ range_trans_ar_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+
+ if (range_trans_cr_desc) {
+
+ range_trans_cr_desc->UniqueID = RANGETRANS_BASE_ID;
+ range_trans_cr_desc->Label = strdup("range_trans_cr");
+ range_trans_cr_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ range_trans_cr_desc->Name = strdup("Range Translator (CR Controls)");
+ range_trans_cr_desc->Maker = strdup("Dave Robillard");
+ range_trans_cr_desc->Copyright = strdup("GPL");
+ range_trans_cr_desc->PortCount = RANGETRANS_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(RANGETRANS_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ range_trans_cr_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[RANGETRANS_IN_MIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[RANGETRANS_IN_MAX] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[RANGETRANS_OUT_MIN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[RANGETRANS_OUT_MAX] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[RANGETRANS_INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[RANGETRANS_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(RANGETRANS_NUM_PORTS, sizeof(char*));
+ range_trans_cr_desc->PortNames = (const char**)port_names;
+ port_names[RANGETRANS_IN_MIN] = strdup("Input Min");
+ port_names[RANGETRANS_IN_MAX] = strdup("Input Max");
+ port_names[RANGETRANS_OUT_MIN] = strdup("Output Min");
+ port_names[RANGETRANS_OUT_MAX] = strdup("Output Max");
+ port_names[RANGETRANS_INPUT] = strdup("Input");
+ port_names[RANGETRANS_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(RANGETRANS_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ range_trans_cr_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[RANGETRANS_IN_MIN].HintDescriptor = LADSPA_HINT_DEFAULT_0;
+ port_range_hints[RANGETRANS_IN_MAX].HintDescriptor = LADSPA_HINT_DEFAULT_1;
+ port_range_hints[RANGETRANS_OUT_MIN].HintDescriptor = LADSPA_HINT_DEFAULT_0;
+ port_range_hints[RANGETRANS_OUT_MAX].HintDescriptor = LADSPA_HINT_DEFAULT_1;
+ port_range_hints[RANGETRANS_INPUT].HintDescriptor = 0;
+ port_range_hints[RANGETRANS_OUTPUT].HintDescriptor = 0;
+ range_trans_cr_desc->instantiate = rangetrans_instantiate;
+ range_trans_cr_desc->connect_port = rangetrans_connect_port;
+ range_trans_cr_desc->activate = NULL;
+ range_trans_cr_desc->run = rangetrans_run_cr;
+ range_trans_cr_desc->run_adding = NULL;
+ range_trans_cr_desc->set_run_adding_gain = NULL;
+ range_trans_cr_desc->deactivate = NULL;
+ range_trans_cr_desc->cleanup = rangetrans_cleanup;
+ }
+
+ if (range_trans_ar_desc) {
+
+ range_trans_ar_desc->UniqueID = RANGETRANS_BASE_ID+1;
+ range_trans_ar_desc->Label = strdup("range_trans_ar");
+ range_trans_ar_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ range_trans_ar_desc->Name = strdup("Range Translator (AR Controls)");
+ range_trans_ar_desc->Maker = strdup("Dave Robillard");
+ range_trans_ar_desc->Copyright = strdup("GPL");
+ range_trans_ar_desc->PortCount = RANGETRANS_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(RANGETRANS_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ range_trans_ar_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[RANGETRANS_IN_MIN] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[RANGETRANS_IN_MAX] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[RANGETRANS_OUT_MIN] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[RANGETRANS_OUT_MAX] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[RANGETRANS_INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[RANGETRANS_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(RANGETRANS_NUM_PORTS, sizeof(char*));
+ range_trans_ar_desc->PortNames = (const char**)port_names;
+ port_names[RANGETRANS_IN_MIN] = strdup("Input Min");
+ port_names[RANGETRANS_IN_MAX] = strdup("Input Max");
+ port_names[RANGETRANS_OUT_MIN] = strdup("Output Min");
+ port_names[RANGETRANS_OUT_MAX] = strdup("Output Max");
+ port_names[RANGETRANS_INPUT] = strdup("Input");
+ port_names[RANGETRANS_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(RANGETRANS_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ range_trans_ar_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[RANGETRANS_IN_MIN].HintDescriptor = 0;
+ port_range_hints[RANGETRANS_IN_MAX].HintDescriptor = 0;
+ port_range_hints[RANGETRANS_OUT_MIN].HintDescriptor = 0;
+ port_range_hints[RANGETRANS_OUT_MAX].HintDescriptor = 0;
+ port_range_hints[RANGETRANS_INPUT].HintDescriptor = 0;
+ port_range_hints[RANGETRANS_OUTPUT].HintDescriptor = 0;
+ range_trans_ar_desc->instantiate = rangetrans_instantiate;
+ range_trans_ar_desc->connect_port = rangetrans_connect_port;
+ range_trans_ar_desc->activate = NULL;
+ range_trans_ar_desc->run = rangetrans_run_ar;
+ range_trans_ar_desc->run_adding = NULL;
+ range_trans_ar_desc->set_run_adding_gain = NULL;
+ range_trans_ar_desc->deactivate = NULL;
+ range_trans_ar_desc->cleanup = rangetrans_cleanup;
+ }
+}
+
+
+void
+rangetrans_delete_descriptor(LADSPA_Descriptor* psDescriptor)
+{
+ unsigned long lIndex;
+ if (psDescriptor) {
+ free((char*)psDescriptor->Label);
+ free((char*)psDescriptor->Name);
+ free((char*)psDescriptor->Maker);
+ free((char*)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char*)(psDescriptor->PortNames[lIndex]));
+ free((char**)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ rangetrans_delete_descriptor(range_trans_cr_desc);
+ rangetrans_delete_descriptor(range_trans_ar_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor*
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return range_trans_cr_desc;
+ case 1:
+ return range_trans_ar_desc;
+ default:
+ return NULL;
+ }
+}
+
diff --git a/src/sample_and_hold_4430.c b/src/sample_and_hold_4430.c
new file mode 100644
index 0000000..2d706f0
--- /dev/null
+++ b/src/sample_and_hold_4430.c
@@ -0,0 +1,305 @@
+/* Sample and Hold. Copyright (C) 2005 Thorsten Wilms.
+ * Based on Dave Robillard's "Hz to AMS style V/Oct" plugin for the skeleton.
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+
+#include "ladspa.h"
+
+#define SH_ID 4430
+
+#define SH_NUM_PORTS 5
+
+/* Port Numbers */
+#define SH_INPUT 0
+#define SH_TRIGGER 1
+#define SH_THRESHOLD 2
+#define SH_CONTINUOUS 3
+#define SH_OUTPUT 4
+
+
+/* All state information for plugin */
+typedef struct
+{
+ /* Ports */
+ LADSPA_Data* input_buffer;
+ LADSPA_Data* trigger_buffer;
+ LADSPA_Data* threshold_buffer;
+ LADSPA_Data* continuous_buffer;
+ LADSPA_Data* output_buffer;
+
+ float hold; /* the value sampled and held */
+ float last_trigger; /* trigger port value from the previous frame */
+} SH;
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+SH_instantiate(const LADSPA_Descriptor * descriptor, unsigned long srate)
+{
+ return (LADSPA_Handle)malloc(sizeof(SH));
+}
+
+
+/* Connect a port to a data location */
+void
+SH_connect_port(LADSPA_Handle instance,
+ unsigned long port,
+ LADSPA_Data* location)
+{
+ SH* plugin = (SH*)instance;
+
+ switch (port) {
+ case SH_INPUT:
+ plugin->input_buffer = location;
+ break;
+ case SH_TRIGGER:
+ plugin->trigger_buffer = location;
+ break;
+ case SH_THRESHOLD:
+ plugin->threshold_buffer = location;
+ break;
+ case SH_CONTINUOUS:
+ plugin->continuous_buffer = location;
+ break;
+ case SH_OUTPUT:
+ plugin->output_buffer = location;
+ break;
+ }
+}
+
+void
+SH_activate(LADSPA_Handle instance)
+{
+ SH* plugin = (SH*)instance;
+
+ plugin->hold = 0;
+ plugin->last_trigger = 0;
+}
+
+void
+SH_run_cr(LADSPA_Handle instance, unsigned long nframes)
+{
+ SH* const plugin = (SH*)instance;
+ const LADSPA_Data* const input = plugin->input_buffer;
+ const LADSPA_Data* const trigger = plugin->trigger_buffer;
+ const LADSPA_Data threshold = *plugin->threshold_buffer;
+ const LADSPA_Data continuous = *plugin->continuous_buffer;
+ LADSPA_Data* const output = plugin->output_buffer;
+
+ unsigned long i;
+
+ /* Continuous triggering on (sample while trigger > threshold) */
+ if (continuous != 0.0f) {
+ for (i = 0; i < nframes; i++) {
+ if (trigger[i] >= threshold)
+ plugin->hold = input[i];
+ plugin->last_trigger = trigger[i];
+ output[i] = plugin->hold;
+ }
+
+ /* Continuous triggering off
+ * (only sample on first frame with trigger > threshold) */
+ } else {
+ for (i = 0; i < nframes; i++) {
+ if (plugin->last_trigger < threshold && trigger[i] >= threshold)
+ plugin->hold = input[i];
+ plugin->last_trigger = trigger[i];
+ output[i] = plugin->hold;
+ }
+ }
+}
+
+
+void
+SH_run_ar(LADSPA_Handle instance, unsigned long nframes)
+{
+ SH* const plugin = (SH*)instance;
+ const LADSPA_Data* const input = plugin->input_buffer;
+ const LADSPA_Data* const trigger = plugin->trigger_buffer;
+ const LADSPA_Data* const threshold = plugin->threshold_buffer;
+ const LADSPA_Data* const continuous = plugin->continuous_buffer;
+ LADSPA_Data* const output = plugin->output_buffer;
+
+ unsigned long i;
+
+ for (i = 0; i < nframes; i++) {
+ if (continuous[0] != 0) {
+ /* Continuous triggering on (sample while trigger > threshold) */
+ if (trigger[i] >= threshold[i])
+ plugin->hold = input[i];
+ } else {
+ /* Continuous triggering off
+ * (only sample on first frame with trigger > threshold) */
+ if (plugin->last_trigger < threshold[i] && trigger[i] >= threshold[i])
+ plugin->hold = input[i];
+ }
+
+ plugin->last_trigger = trigger[i];
+ output[i] = plugin->hold;
+ }
+}
+
+
+void
+SH_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor* SH_cr_desc = NULL;
+LADSPA_Descriptor* SH_ar_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+
+ SH_cr_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ SH_ar_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+
+ if (SH_cr_desc) {
+ SH_cr_desc->UniqueID = SH_ID;
+ SH_cr_desc->Label = strdup("sh_cr");
+ SH_cr_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ SH_cr_desc->Name = strdup("Sample and Hold (CR Threshold)");
+ SH_cr_desc->Maker = strdup("Thorsten Wilms");
+ SH_cr_desc->Copyright = strdup("GPL");
+ SH_cr_desc->PortCount = SH_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(SH_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ SH_cr_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[SH_INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[SH_TRIGGER] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[SH_THRESHOLD] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[SH_CONTINUOUS] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[SH_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(SH_NUM_PORTS, sizeof(char*));
+ SH_cr_desc->PortNames = (const char**)port_names;
+ port_names[SH_INPUT] = strdup("Input");
+ port_names[SH_TRIGGER] = strdup("Trigger");
+ port_names[SH_THRESHOLD] = strdup("Threshold");
+ port_names[SH_CONTINUOUS] = strdup("Continuous Triggering");
+ port_names[SH_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(SH_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ SH_cr_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[SH_INPUT].HintDescriptor = 0;
+ port_range_hints[SH_TRIGGER].HintDescriptor = 0;
+ port_range_hints[SH_THRESHOLD].HintDescriptor = 0;
+ port_range_hints[SH_CONTINUOUS].HintDescriptor = LADSPA_HINT_TOGGLED;
+ port_range_hints[SH_OUTPUT].HintDescriptor = 0;
+ SH_cr_desc->instantiate = SH_instantiate;
+ SH_cr_desc->connect_port = SH_connect_port;
+ SH_cr_desc->activate = SH_activate;
+ SH_cr_desc->run = SH_run_cr;
+ SH_cr_desc->run_adding = NULL;
+ SH_cr_desc->set_run_adding_gain = NULL;
+ SH_cr_desc->deactivate = NULL;
+ SH_cr_desc->cleanup = SH_cleanup;
+ }
+
+ if (SH_ar_desc) {
+ SH_ar_desc->UniqueID = SH_ID+1;
+ SH_ar_desc->Label = strdup("sh_ar");
+ SH_ar_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ SH_ar_desc->Name = strdup("Sample and Hold (AR Threshold)");
+ SH_ar_desc->Maker = strdup("Thorsten Wilms");
+ SH_ar_desc->Copyright = strdup("GPL");
+ SH_ar_desc->PortCount = SH_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(SH_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ SH_ar_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[SH_INPUT] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[SH_TRIGGER] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[SH_THRESHOLD] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[SH_CONTINUOUS] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[SH_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(SH_NUM_PORTS, sizeof(char*));
+ SH_ar_desc->PortNames = (const char**)port_names;
+ port_names[SH_INPUT] = strdup("Input");
+ port_names[SH_TRIGGER] = strdup("Trigger");
+ port_names[SH_THRESHOLD] = strdup("Threshold");
+ port_names[SH_CONTINUOUS] = strdup("Continuous Triggering");
+ port_names[SH_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(SH_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ SH_ar_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[SH_INPUT].HintDescriptor = 0;
+ port_range_hints[SH_TRIGGER].HintDescriptor = 0;
+ port_range_hints[SH_THRESHOLD].HintDescriptor = 0;
+ port_range_hints[SH_CONTINUOUS].HintDescriptor = LADSPA_HINT_TOGGLED;
+ port_range_hints[SH_OUTPUT].HintDescriptor = 0;
+ SH_ar_desc->instantiate = SH_instantiate;
+ SH_ar_desc->connect_port = SH_connect_port;
+ SH_ar_desc->activate = SH_activate;
+ SH_ar_desc->run = SH_run_ar;
+ SH_ar_desc->run_adding = NULL;
+ SH_ar_desc->set_run_adding_gain = NULL;
+ SH_ar_desc->deactivate = NULL;
+ SH_ar_desc->cleanup = SH_cleanup;
+ }
+}
+
+
+void
+SH_delete_descriptor(LADSPA_Descriptor* psDescriptor)
+{
+ unsigned long lIndex;
+ if (psDescriptor) {
+ free((char*)psDescriptor->Label);
+ free((char*)psDescriptor->Name);
+ free((char*)psDescriptor->Maker);
+ free((char*)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char*)(psDescriptor->PortNames[lIndex]));
+ free((char**)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ SH_delete_descriptor(SH_cr_desc);
+ SH_delete_descriptor(SH_ar_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor*
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return SH_cr_desc;
+ case 1:
+ return SH_ar_desc;
+ default:
+ return NULL;
+ }
+}
+
diff --git a/src/signal_abs_2669.c b/src/signal_abs_2669.c
new file mode 100644
index 0000000..c7e93ea
--- /dev/null
+++ b/src/signal_abs_2669.c
@@ -0,0 +1,261 @@
+/* This file is an audio plugin. Copyright (C) 2005 Loki Davison.
+ *
+ * Sign parameter is the sign of the output, 0 being negative and >0 begin positive.
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "ladspa.h"
+
+#define SIGNAL_ABS_BASE_ID 2669
+
+#define SIGNAL_ABS_NUM_PORTS 3
+
+/* Port Numbers */
+#define SIGNAL_ABS_INPUT1 0
+#define SIGNAL_ABS_SIGN 1
+#define SIGNAL_ABS_OUTPUT 2
+
+
+/* All state information for plugin */
+typedef struct
+{
+ /* Ports */
+ LADSPA_Data* sign;
+ LADSPA_Data* input1;
+ LADSPA_Data* output;
+} SignalAbs;
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+signalabs_instantiate(const LADSPA_Descriptor* descriptor,
+ unsigned long srate)
+{
+ return (LADSPA_Handle)malloc(sizeof(SignalAbs));
+}
+
+
+/* Connect a port to a data location */
+void
+signalabs_connect_port(LADSPA_Handle instance,
+ unsigned long port,
+ LADSPA_Data* location)
+{
+ SignalAbs* plugin;
+
+ plugin = (SignalAbs*)instance;
+ switch (port) {
+ case SIGNAL_ABS_SIGN:
+ plugin->sign = location;
+ break;
+ case SIGNAL_ABS_INPUT1:
+ plugin->input1 = location;
+ break;
+ case SIGNAL_ABS_OUTPUT:
+ plugin->output = location;
+ break;
+ }
+}
+
+
+void
+signalabs_run_cr(LADSPA_Handle instance, unsigned long nframes)
+{
+ SignalAbs* plugin = (SignalAbs*)instance;
+ LADSPA_Data* input1 = plugin->input1;
+ LADSPA_Data* output = plugin->output;
+ LADSPA_Data sign = * (plugin->sign);
+ size_t i;
+
+ for (i = 0; i < nframes; ++i)
+ {
+ if(sign > 0)
+ {
+ output[i] = fabs(input1[i]);
+ }
+ else
+ {
+ output[i] = fabs(input1[i]) * -1;
+ }
+ }
+
+}
+
+
+void
+signalabs_run_ar(LADSPA_Handle instance, unsigned long nframes)
+{
+ SignalAbs* plugin = (SignalAbs*)instance;
+ LADSPA_Data* sign = plugin->sign;
+ LADSPA_Data* input1 = plugin->input1;
+ LADSPA_Data* output = plugin->output;
+ size_t i;
+
+ for (i = 0; i < nframes; ++i)
+ {
+ if(sign[i] > 0.5)
+ {
+ output[i] = fabs(input1[i]);
+ }
+ else
+ {
+ output[i] = fabs(input1[i]) * -1;
+ }
+ }
+}
+
+
+void
+signalabs_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor* signal_abs_cr_desc = NULL;
+LADSPA_Descriptor* signal_abs_ar_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+
+ signal_abs_cr_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ signal_abs_ar_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+
+ if (signal_abs_cr_desc) {
+
+ signal_abs_cr_desc->UniqueID = SIGNAL_ABS_BASE_ID;
+ signal_abs_cr_desc->Label = strdup("signal_abs_cr");
+ signal_abs_cr_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ signal_abs_cr_desc->Name = strdup("Signal Absolute value, negative or positive (CR Controls)");
+ signal_abs_cr_desc->Maker = strdup("Loki Davison");
+ signal_abs_cr_desc->Copyright = strdup("GPL");
+ signal_abs_cr_desc->PortCount = SIGNAL_ABS_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(SIGNAL_ABS_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ signal_abs_cr_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[SIGNAL_ABS_SIGN] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[SIGNAL_ABS_INPUT1] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[SIGNAL_ABS_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(SIGNAL_ABS_NUM_PORTS, sizeof(char*));
+ signal_abs_cr_desc->PortNames = (const char**)port_names;
+ port_names[SIGNAL_ABS_SIGN] = strdup("Sign");
+ port_names[SIGNAL_ABS_INPUT1] = strdup("Input");
+ port_names[SIGNAL_ABS_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(SIGNAL_ABS_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ signal_abs_cr_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[SIGNAL_ABS_SIGN].HintDescriptor = LADSPA_HINT_DEFAULT_1 | LADSPA_HINT_TOGGLED;
+ port_range_hints[SIGNAL_ABS_INPUT1].HintDescriptor = 0;
+ port_range_hints[SIGNAL_ABS_OUTPUT].HintDescriptor = 0;
+ signal_abs_cr_desc->instantiate = signalabs_instantiate;
+ signal_abs_cr_desc->connect_port = signalabs_connect_port;
+ signal_abs_cr_desc->activate = NULL;
+ signal_abs_cr_desc->run = signalabs_run_cr;
+ signal_abs_cr_desc->run_adding = NULL;
+ signal_abs_cr_desc->set_run_adding_gain = NULL;
+ signal_abs_cr_desc->deactivate = NULL;
+ signal_abs_cr_desc->cleanup = signalabs_cleanup;
+ }
+
+ if (signal_abs_ar_desc) {
+
+ signal_abs_ar_desc->UniqueID = SIGNAL_ABS_BASE_ID+1;
+ signal_abs_ar_desc->Label = strdup("signal_abs_ar");
+ signal_abs_ar_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ signal_abs_ar_desc->Name = strdup("Signal Absolute value, negative or positive (AR Controls)");
+ signal_abs_ar_desc->Maker = strdup("Loki Davison");
+ signal_abs_ar_desc->Copyright = strdup("GPL");
+ signal_abs_ar_desc->PortCount = SIGNAL_ABS_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(SIGNAL_ABS_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ signal_abs_ar_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[SIGNAL_ABS_SIGN] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[SIGNAL_ABS_INPUT1] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[SIGNAL_ABS_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_names = (char**)calloc(SIGNAL_ABS_NUM_PORTS, sizeof(char*));
+ signal_abs_ar_desc->PortNames = (const char**)port_names;
+ port_names[SIGNAL_ABS_SIGN] = strdup("Sign");
+ port_names[SIGNAL_ABS_INPUT1] = strdup("Input 1");
+ port_names[SIGNAL_ABS_OUTPUT] = strdup("Output");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(SIGNAL_ABS_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ signal_abs_ar_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[SIGNAL_ABS_SIGN].HintDescriptor = 0;
+ port_range_hints[SIGNAL_ABS_INPUT1].HintDescriptor = 0;
+ port_range_hints[SIGNAL_ABS_OUTPUT].HintDescriptor = 0;
+ signal_abs_ar_desc->instantiate = signalabs_instantiate;
+ signal_abs_ar_desc->connect_port = signalabs_connect_port;
+ signal_abs_ar_desc->activate = NULL;
+ signal_abs_ar_desc->run = signalabs_run_ar;
+ signal_abs_ar_desc->run_adding = NULL;
+ signal_abs_ar_desc->set_run_adding_gain = NULL;
+ signal_abs_ar_desc->deactivate = NULL;
+ signal_abs_ar_desc->cleanup = signalabs_cleanup;
+ }
+}
+
+
+void
+signalabs_delete_descriptor(LADSPA_Descriptor* psDescriptor)
+{
+ unsigned long lIndex;
+ if (psDescriptor) {
+ free((char*)psDescriptor->Label);
+ free((char*)psDescriptor->Name);
+ free((char*)psDescriptor->Maker);
+ free((char*)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char*)(psDescriptor->PortNames[lIndex]));
+ free((char**)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ signalabs_delete_descriptor(signal_abs_cr_desc);
+ signalabs_delete_descriptor(signal_abs_ar_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor*
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return signal_abs_cr_desc;
+ case 1:
+ return signal_abs_ar_desc;
+ default:
+ return NULL;
+ }
+}
+
diff --git a/src/slew_limiter_2743.c b/src/slew_limiter_2743.c
new file mode 100644
index 0000000..dd486b5
--- /dev/null
+++ b/src/slew_limiter_2743.c
@@ -0,0 +1,272 @@
+/* slew_limiter - A LADSPA plugin that limits the rate of change of a
+ * signal. Increases and decreases in the signal can be
+ * limited separately.
+ *
+ * Copyright (C) 2005 Lars Luthman
+ * LADSPA skeleton code taken from dahdsr_fexp.c by Loki Davison
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <ladspa.h>
+#include <math.h>
+
+/* This defines the number of "variants", i.e. the number of separate plugins
+ in this file */
+#define SLIM_VARIANT_COUNT 2
+
+/* These are the port numbers */
+#define SLIM_INPUT 0
+#define SLIM_MAXRISE 1
+#define SLIM_MAXFALL 2
+#define SLIM_OUTPUT 3
+
+
+/* This is an array pointer to the descriptors of the different variants */
+LADSPA_Descriptor** slim_descriptors = 0;
+
+
+/* This is the data for a single instance of the plugin */
+typedef struct
+{
+ LADSPA_Data* input;
+ LADSPA_Data* maxrise;
+ LADSPA_Data* maxfall;
+ LADSPA_Data* reset;
+ LADSPA_Data* output;
+ LADSPA_Data srate;
+ LADSPA_Data last_output;
+}
+SLim;
+
+
+
+/* LADSPA hosts use this function to get the plugin descriptors */
+const LADSPA_Descriptor* ladspa_descriptor(unsigned long index)
+{
+ if (index < SLIM_VARIANT_COUNT)
+ return slim_descriptors[index];
+ return 0;
+}
+
+
+/* Clean up after a plugin instance */
+void cleanupSLim (LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+/* This is called when the hosts connects a port to a buffer */
+void connectPortSLim(LADSPA_Handle instance,
+ unsigned long port, LADSPA_Data* data)
+{
+ SLim* plugin = (SLim *)instance;
+
+ switch (port) {
+ case SLIM_INPUT:
+ plugin->input = data;
+ break;
+ case SLIM_MAXRISE:
+ plugin->maxrise = data;
+ break;
+ case SLIM_MAXFALL:
+ plugin->maxfall = data;
+ break;
+ case SLIM_OUTPUT:
+ plugin->output = data;
+ break;
+ }
+}
+
+
+/* The host uses this function to create an instance of a plugin */
+LADSPA_Handle instantiateSLim(const LADSPA_Descriptor * descriptor,
+ unsigned long sample_rate)
+{
+ SLim* plugin = (SLim*)calloc(1, sizeof(SLim));
+ plugin->srate = (LADSPA_Data)sample_rate;
+ return (LADSPA_Handle)plugin;
+}
+
+
+/* This is called before the hosts starts to use the plugin instance */
+void activateSLim(LADSPA_Handle instance)
+{
+ SLim* plugin = (SLim*)instance;
+ plugin->last_output = 0;
+}
+
+
+/* The run function! */
+void runSLim(LADSPA_Handle instance, unsigned long sample_count, int variant)
+{
+ SLim* plugin = (SLim*)instance;
+
+ if (plugin->input && plugin->output) {
+ unsigned long i;
+ LADSPA_Data maxrise, maxfall;
+ for (i = 0; i < sample_count; ++i) {
+
+ if (plugin->maxrise && variant == 0)
+ maxrise = plugin->maxrise[i];
+ else if (plugin->maxrise && variant == 1)
+ maxrise = plugin->maxrise[0];
+ else
+ maxrise = 0;
+
+ if (plugin->maxfall && variant == 0)
+ maxfall = plugin->maxfall[i];
+ else if (plugin->maxfall && variant == 1)
+ maxfall = plugin->maxfall[0];
+ else
+ maxfall = 0;
+
+ LADSPA_Data maxinc = maxrise / plugin->srate;
+ LADSPA_Data maxdec = maxfall / plugin->srate;
+ LADSPA_Data increment = plugin->input[i] - plugin->last_output;
+ if (increment > maxinc)
+ increment = maxinc;
+ else if (increment < -maxdec)
+ increment = -maxdec;
+
+ plugin->output[i] = plugin->last_output + increment;
+ plugin->last_output = plugin->output[i];
+ }
+ }
+}
+
+
+void runSLim_audio(LADSPA_Handle instance, unsigned long sample_count)
+{
+ runSLim(instance, sample_count, 0);
+}
+
+
+void runSLim_control(LADSPA_Handle instance, unsigned long sample_count)
+{
+ runSLim(instance, sample_count, 1);
+}
+
+
+/* Called automagically by the dynamic linker - set up global stuff here */
+void _init(void)
+{
+ static const unsigned long ids[] = { 2743, 2744 };
+ static const char * labels[] = { "slew_limiter_ra", "slew_limiter_rc" };
+ static const char * names[] = { "Slew limiter (RA)", "Slew limiter (RC)" };
+
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+ LADSPA_Descriptor* descriptor;
+
+ LADSPA_PortDescriptor input_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO };
+ LADSPA_PortDescriptor maxrise_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor maxfall_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor output_port_descriptors[] =
+ { LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO };
+
+ void (*run_functions[]) (LADSPA_Handle, unsigned long) = { runSLim_audio,
+ runSLim_control };
+
+ slim_descriptors = (LADSPA_Descriptor**)calloc(SLIM_VARIANT_COUNT,
+ sizeof(LADSPA_Descriptor));
+
+ if (slim_descriptors) {
+ int i;
+ for (i = 0; i < SLIM_VARIANT_COUNT; ++i) {
+ slim_descriptors[i] =
+ (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ descriptor = slim_descriptors[i];
+ if (descriptor) {
+ descriptor->UniqueID = ids[i];
+ descriptor->Label = labels[i];
+ descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ descriptor->Name = names[i];
+ descriptor->Maker = "Lars Luthman <larsl@users.sourceforge.net>";
+ descriptor->Copyright = "GPL";
+ descriptor->PortCount = 4;
+
+ port_descriptors =
+ (LADSPA_PortDescriptor*)calloc(4, sizeof(LADSPA_PortDescriptor));
+ descriptor->PortDescriptors =
+ (const LADSPA_PortDescriptor*)port_descriptors;
+ port_range_hints =
+ (LADSPA_PortRangeHint*)calloc(4, sizeof(LADSPA_PortRangeHint));
+ descriptor->PortRangeHints =
+ (const LADSPA_PortRangeHint*)port_range_hints;
+
+ port_names = (char**)calloc(9, sizeof (char*));
+ descriptor->PortNames = (const char**)port_names;
+
+ /* Parameters for Input */
+ port_descriptors[SLIM_INPUT] = input_port_descriptors[i];
+ port_names[SLIM_INPUT] = "Input";
+
+ /* Parameters for Rise rate */
+ port_descriptors[SLIM_MAXRISE] = maxrise_port_descriptors[i];
+ port_names[SLIM_MAXRISE] = "Rise rate (1/s)";
+
+ /* Parameters for Fall rate */
+ port_descriptors[SLIM_MAXFALL] = maxfall_port_descriptors[i];
+ port_names[SLIM_MAXFALL] = "Fall rate (1/s)";
+
+ /* Parameters for Output*/
+ port_descriptors[SLIM_OUTPUT] = output_port_descriptors[i];
+ port_names[SLIM_OUTPUT] = "Output";
+
+ descriptor->activate = activateSLim;
+ descriptor->cleanup = cleanupSLim;
+ descriptor->connect_port = connectPortSLim;
+ descriptor->deactivate = NULL;
+ descriptor->instantiate = instantiateSLim;
+ descriptor->run = run_functions[i];
+ descriptor->run_adding = NULL;
+ descriptor->set_run_adding_gain = NULL;
+ }
+ }
+ }
+}
+
+
+/* Called automagically by the dynamic linker - free global stuff here */
+void _fini(void)
+{
+ LADSPA_Descriptor* descriptor;
+ int i;
+
+ if (slim_descriptors) {
+ for (i = 0; i < SLIM_VARIANT_COUNT; i++) {
+ descriptor = slim_descriptors[i];
+ if (descriptor) {
+ free((LADSPA_PortDescriptor*)descriptor->PortDescriptors);
+ free((char**)descriptor->PortNames);
+ free((LADSPA_PortRangeHint*)descriptor->PortRangeHints);
+ free(descriptor);
+ }
+ }
+ free(slim_descriptors);
+ }
+}
diff --git a/src/slide_2741.c b/src/slide_2741.c
new file mode 100644
index 0000000..908329d
--- /dev/null
+++ b/src/slide_2741.c
@@ -0,0 +1,297 @@
+/* slide.c - A LADSPA plugin that "slides" the output signal between
+ * the current and the previous input value, taking the given
+ * number of seconds to reach the current input value.
+ *
+ * Copyright (C) 2005 Lars Luthman
+ * LADSPA skeleton code taken from dahdsr_fexp.c by Loki Davison
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <ladspa.h>
+#include <math.h>
+
+/* This defines the number of "variants", i.e. the number of separate plugins
+ in this library */
+#define SLIDE_VARIANT_COUNT 2
+
+/* These are the port numbers */
+#define SLIDE_INPUT 0
+#define SLIDE_RISETIME 1
+#define SLIDE_FALLTIME 2
+#define SLIDE_OUTPUT 3
+
+
+/* This is an array pointer to the descriptors of the different variants */
+LADSPA_Descriptor** slide_descriptors = 0;
+
+
+/* This is the data for a single instance of the plugin */
+typedef struct
+{
+ LADSPA_Data* input;
+ LADSPA_Data* risetime;
+ LADSPA_Data* falltime;
+ LADSPA_Data* output;
+ LADSPA_Data srate;
+ LADSPA_Data from;
+ LADSPA_Data to;
+ LADSPA_Data last_output;
+} Slide;
+
+
+
+/* LADSPA hosts use this function to get the plugin descriptors */
+const LADSPA_Descriptor* ladspa_descriptor(unsigned long index)
+{
+ if (index < SLIDE_VARIANT_COUNT)
+ return slide_descriptors[index];
+ return 0;
+}
+
+
+/* Clean up after a plugin instance */
+void cleanupSlide (LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+/* This is called when the hosts connects a port to a buffer */
+void connectPortSlide(LADSPA_Handle instance,
+ unsigned long port, LADSPA_Data* data)
+{
+ Slide* plugin = (Slide *)instance;
+
+ switch (port) {
+ case SLIDE_INPUT:
+ plugin->input = data;
+ break;
+ case SLIDE_RISETIME:
+ plugin->risetime = data;
+ break;
+ case SLIDE_FALLTIME:
+ plugin->falltime = data;
+ break;
+ case SLIDE_OUTPUT:
+ plugin->output = data;
+ break;
+ }
+}
+
+
+/* The host uses this function to create an instance of a plugin */
+LADSPA_Handle instantiateSlide(const LADSPA_Descriptor * descriptor,
+ unsigned long sample_rate)
+{
+ Slide* plugin = (Slide*)calloc(1, sizeof(Slide));
+ plugin->srate = (LADSPA_Data)sample_rate;
+ return (LADSPA_Handle)plugin;
+}
+
+
+/* This is called before the hosts starts to use the plugin instance */
+void activateSlide(LADSPA_Handle instance)
+{
+ Slide* plugin = (Slide*)instance;
+ plugin->last_output = 0;
+ plugin->from = 0;
+ plugin->to = 0;
+}
+
+
+/* The run function! */
+void runSlide(LADSPA_Handle instance, unsigned long sample_count, int variant)
+{
+ Slide* plugin = (Slide*)instance;
+
+ if (plugin->input && plugin->output) {
+ unsigned long i;
+ LADSPA_Data risetime, falltime;
+ for (i = 0; i < sample_count; ++i) {
+
+ if (plugin->risetime && variant == 0)
+ risetime = plugin->risetime[i];
+ else if (plugin->risetime && variant == 1)
+ risetime = plugin->risetime[0];
+ else
+ risetime = 0;
+
+ if (plugin->falltime)
+ falltime = plugin->falltime[i];
+ else if (plugin->falltime && variant == 1)
+ falltime = plugin->falltime[0];
+ else
+ falltime = 0;
+
+ /* If the signal changed, start sliding to the new value */
+ if (plugin->input[i] != plugin->to) {
+ plugin->from = plugin->last_output;
+ plugin->to = plugin->input[i];
+ }
+
+ LADSPA_Data time;
+ int rising;
+ if (plugin->to > plugin->from) {
+ time = risetime;
+ rising = 1;
+ } else {
+ time = falltime;
+ rising = 0;
+ }
+
+ /* If the rise/fall time is 0, just copy the input to the output */
+ if (time == 0)
+ plugin->output[i] = plugin->input[i];
+
+ /* Otherwise, do the portamento */
+ else {
+ LADSPA_Data increment =
+ (plugin->to - plugin->from) / (time * plugin->srate);
+ plugin->output[i] = plugin->last_output + increment;
+ if ((plugin->output[i] > plugin->to && rising) ||
+ (plugin->output[i] < plugin->to && !rising)) {
+ plugin->output[i] = plugin->to;
+ }
+ }
+
+ plugin->last_output = plugin->output[i];
+ }
+ }
+}
+
+
+void runSlide_audio(LADSPA_Handle instance, unsigned long sample_count)
+{
+ runSlide(instance, sample_count, 0);
+}
+
+
+void runSlide_control(LADSPA_Handle instance, unsigned long sample_count)
+{
+ runSlide(instance, sample_count, 1);
+}
+
+
+/* Called automagically by the dynamic linker - set up global stuff here */
+void _init(void)
+{
+ static const unsigned long ids[] = { 2741, 2742 };
+ static const char * labels[] = { "slide_ta", "slide_tc" };
+ static const char * names[] = { "Slide (TA)", "Slide (TC)" };
+
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+ LADSPA_Descriptor* descriptor;
+
+ LADSPA_PortDescriptor input_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO };
+ LADSPA_PortDescriptor risetime_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor falltime_port_descriptors[] =
+ { LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL };
+ LADSPA_PortDescriptor output_port_descriptors[] =
+ { LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO };
+
+ void (*run_functions[])(LADSPA_Handle, unsigned long) =
+ { runSlide_audio, runSlide_control };
+
+ slide_descriptors = (LADSPA_Descriptor**)calloc(SLIDE_VARIANT_COUNT,
+ sizeof(LADSPA_Descriptor));
+
+ if (slide_descriptors) {
+ int i;
+ for (i = 0; i < SLIDE_VARIANT_COUNT; ++i) {
+ slide_descriptors[i] =
+ (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+ descriptor = slide_descriptors[i];
+ if (descriptor) {
+ descriptor->UniqueID = ids[i];
+ descriptor->Label = labels[i];
+ descriptor->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ descriptor->Name = names[i];
+ descriptor->Maker = "Lars Luthman <larsl@users.sourceforge.net>";
+ descriptor->Copyright = "GPL";
+ descriptor->PortCount = 4;
+
+ port_descriptors =
+ (LADSPA_PortDescriptor*)calloc(4, sizeof(LADSPA_PortDescriptor));
+ descriptor->PortDescriptors =
+ (const LADSPA_PortDescriptor*)port_descriptors;
+ port_range_hints =
+ (LADSPA_PortRangeHint*)calloc(4, sizeof(LADSPA_PortRangeHint));
+ descriptor->PortRangeHints =
+ (const LADSPA_PortRangeHint*)port_range_hints;
+
+ port_names = (char **) calloc (9, sizeof (char*));
+ descriptor->PortNames = (const char **) port_names;
+
+ /* Parameters for Input */
+ port_descriptors[SLIDE_INPUT] = input_port_descriptors[i];
+ port_names[SLIDE_INPUT] = "Input";
+
+ /* Parameters for Rise rate */
+ port_descriptors[SLIDE_RISETIME] = risetime_port_descriptors[i];
+ port_names[SLIDE_RISETIME] = "Rise time (s)";
+
+ /* Parameters for Fall rate */
+ port_descriptors[SLIDE_FALLTIME] = falltime_port_descriptors[i];
+ port_names[SLIDE_FALLTIME] = "Fall time (s)";
+
+ /* Parameters for Output*/
+ port_descriptors[SLIDE_OUTPUT] = output_port_descriptors[i];
+ port_names[SLIDE_OUTPUT] = "Output";
+
+ descriptor->activate = activateSlide;
+ descriptor->cleanup = cleanupSlide;
+ descriptor->connect_port = connectPortSlide;
+ descriptor->deactivate = NULL;
+ descriptor->instantiate = instantiateSlide;
+ descriptor->run = run_functions[i];
+ descriptor->run_adding = NULL;
+ descriptor->set_run_adding_gain = NULL;
+ }
+ }
+ }
+}
+
+
+/* Called automagically by the dynamic linker - free global stuff here */
+void _fini(void)
+{
+ LADSPA_Descriptor* descriptor;
+ int i;
+
+ if (slide_descriptors) {
+ for (i = 0; i < SLIDE_VARIANT_COUNT; i++) {
+ descriptor = slide_descriptors[i];
+ if (descriptor) {
+ free((LADSPA_PortDescriptor*)descriptor->PortDescriptors);
+ free((char**)descriptor->PortNames);
+ free((LADSPA_PortRangeHint*)descriptor->PortRangeHints);
+ free(descriptor);
+ }
+ }
+ free(slide_descriptors);
+ }
+}
+
diff --git a/src/waveguide_mesh_2670.c b/src/waveguide_mesh_2670.c
new file mode 100644
index 0000000..3b6535b
--- /dev/null
+++ b/src/waveguide_mesh_2670.c
@@ -0,0 +1,362 @@
+/* This file is an audio plugin. Copyright (C) 2005 Loki Davison. Based on code by Brook Eaton and a couple
+ * of papers...
+ *
+ * Implements a Waveguide Mesh drum. FIXME to be extended, to have rimguides, power normalisation and all
+ * manner of other goodies.
+ *
+ * Tension is well, drum tension
+ * power is how hard you hit it.
+ *
+ *
+ * This plugin is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This plugin is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _XOPEN_SOURCE 500 /* strdup */
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "ladspa.h"
+
+#define MESH_BASE_ID 2670
+
+#define MESH_NUM_PORTS 6
+
+/* Port Numbers */
+#define MESH_INPUT1 0
+#define MESH_OUTPUT 1
+#define MESH_TENSION 2
+#define MESH_POWER 3
+#define MESH_EX_X 4
+#define MESH_EX_Y 5
+
+
+#define LENGTH 8 // must be divisible by 4!!
+#define WIDTH 8
+#define SIZE LENGTH*WIDTH // Size of mesh
+#define INITIAL 0 // initial values stored at junctions
+#define LOSS 0.2 // loss in wave propagation
+#define INIT_DELTA 6 // initial values
+#define INIT_T 0.1 // for the impedances
+#define INIT_GAMMA 8 //
+#define PORTS 8 //for the initialization of junction velocities from excitation
+
+// 2D array of junctions.
+// The important function of the junction is to store
+// the velocities of travelling waves so that adjacent junction's
+// velocities can be calculated.
+typedef struct _junction
+{
+ LADSPA_Data v_junction; // junction velocity
+ LADSPA_Data n_junction; // velocity heading north into junction
+ LADSPA_Data s_junction; // velocity heading south into junction
+ LADSPA_Data e_junction; // velocity heading east into junction
+ LADSPA_Data w_junction; // velocity heading west into junction
+ LADSPA_Data c_junction; // velocity heading back into the junction (delayed)
+ LADSPA_Data s_temp; // these two 'temp' values are used because calculation
+ LADSPA_Data e_temp; // of the mesh updates s/e values before they are used
+} _junction; // to calculate north and south velocities!
+
+/* All state information for plugin */
+
+typedef struct
+{
+ /* Ports */
+ LADSPA_Data* input1;
+ LADSPA_Data* output;
+ LADSPA_Data* tension;
+ LADSPA_Data* power;
+ LADSPA_Data* ex_x;
+ LADSPA_Data* ex_y;
+
+ /* vars */
+ _junction mesh[LENGTH][WIDTH];
+ LADSPA_Data last_trigger;
+
+} WgMesh;
+
+
+/* Construct a new plugin instance */
+LADSPA_Handle
+wgmesh_instantiate(const LADSPA_Descriptor* descriptor,
+ unsigned long srate)
+{
+ WgMesh * plugin = (WgMesh *) malloc (sizeof (WgMesh));
+ int i, j;
+
+ //// Init Mesh
+ for (i=0; i<LENGTH; i++) {
+ for (j=0; j<WIDTH; j++) {
+ plugin->mesh[i][j].v_junction = INITIAL;
+ plugin->mesh[i][j].n_junction = INITIAL;
+ plugin->mesh[i][j].s_junction = INITIAL;
+ plugin->mesh[i][j].e_junction = INITIAL;
+ plugin->mesh[i][j].w_junction = INITIAL;
+ plugin->mesh[i][j].c_junction = INITIAL;
+ plugin->mesh[i][j].s_temp = INITIAL;
+ plugin->mesh[i][j].e_temp = INITIAL;
+ }
+ }
+ plugin->last_trigger = 0.0;
+ return (LADSPA_Handle)plugin;
+}
+
+
+/* Connect a port to a data location */
+void
+wgmesh_connect_port(LADSPA_Handle instance,
+ unsigned long port,
+ LADSPA_Data* location)
+{
+ WgMesh* plugin;
+
+ plugin = (WgMesh*)instance;
+ switch (port) {
+ case MESH_INPUT1:
+ plugin->input1 = location;
+ break;
+ case MESH_OUTPUT:
+ plugin->output = location;
+ break;
+ case MESH_TENSION:
+ plugin->tension = location;
+ break;
+ case MESH_POWER:
+ plugin->power = location;
+ break;
+ case MESH_EX_X:
+ plugin->ex_x = location;
+ break;
+ case MESH_EX_Y:
+ plugin->ex_y = location;
+ break;
+ }
+}
+
+
+inline void excite_mesh(WgMesh* plugin, LADSPA_Data power, LADSPA_Data ex_x, LADSPA_Data ex_y)
+{
+ int i=ex_x,j=ex_y;
+ LADSPA_Data temp;
+ LADSPA_Data Yj;
+
+ Yj = 2*(INIT_DELTA*INIT_DELTA/((INIT_T*INIT_T)*(INIT_GAMMA*INIT_GAMMA))); // junction admittance
+ temp = power*2/(LENGTH+WIDTH);
+ plugin->mesh[i][j].v_junction = plugin->mesh[i][j].v_junction + temp;
+ plugin->mesh[i][j].n_junction = plugin->mesh[i][j].n_junction + Yj*temp/PORTS;
+ // All velocities leaving the junction are equal to
+ plugin->mesh[i][j].s_junction = plugin->mesh[i][j].s_junction + Yj*temp/PORTS;
+ // the total velocity in the junction * the admittance
+ plugin->mesh[i][j].e_junction = plugin->mesh[i][j].e_junction + Yj*temp/PORTS;
+ // divided by the number of outgoing ports.
+ plugin->mesh[i][j].w_junction = plugin->mesh[i][j].w_junction + Yj*temp/PORTS;
+ //mesh[i][j].c_junction = 0;
+}
+
+void
+wgmesh_run_cr(LADSPA_Handle instance, unsigned long nframes)
+{
+ WgMesh* plugin = (WgMesh*)instance;
+ LADSPA_Data tension = *(plugin->tension);
+ LADSPA_Data ex_x = *(plugin->ex_x);
+ LADSPA_Data ex_y = *(plugin->ex_y);
+ LADSPA_Data* input = plugin->input1;
+ LADSPA_Data* out = plugin->output;
+ LADSPA_Data* power = plugin->power;
+ LADSPA_Data last_trigger = plugin->last_trigger;
+ size_t i,j,k;
+ LADSPA_Data filt, trg, oldfilt;
+ LADSPA_Data Yc,Yj,tempN,tempS,tempE,tempW;
+
+ // Set input variables //
+ oldfilt = plugin->mesh[LENGTH-LENGTH/4][WIDTH-WIDTH/4].v_junction;
+
+ for (k=0; k<nframes; k++) {
+ if (tension==0)
+ tension=0.0001;
+ trg = input[k];
+
+ if (trg > 0.0f && !(last_trigger > 0.0f))
+ {
+ //printf("got trigger, exciting mesh, %f \n", tension);
+ excite_mesh(plugin, power[k], ex_x, ex_y);
+ }
+
+ //junction admitance
+ Yj = 2*INIT_DELTA*INIT_DELTA/(( (tension)*((tension) )*(INIT_GAMMA*INIT_GAMMA)));
+ Yc = Yj-4; // junction admittance (left shift is for multiply by 2!)
+ //plugin->v_power = power[k];
+
+ for (i=1; i<LENGTH-1; i++) {
+ // INNER MESH //
+ for (j=1; j<WIDTH-1; j++) { // to multiply by 2 - simply shift to the left by 1!
+ plugin->mesh[i][j].v_junction = 2.0*(plugin->mesh[i][j].n_junction + plugin->mesh[i][j].s_junction
+ + plugin->mesh[i][j].e_junction + plugin->mesh[i][j].w_junction + Yc*plugin->mesh[i][j].c_junction)/Yj;
+
+ plugin->mesh[i][j+1].s_junction = plugin->mesh[i][j].v_junction - plugin->mesh[i][j].n_junction;
+ plugin->mesh[i][j-1].n_junction = plugin->mesh[i][j].v_junction - plugin->mesh[i][j].s_temp;
+
+ plugin->mesh[i+1][j].e_junction = plugin->mesh[i][j].v_junction - plugin->mesh[i][j].w_junction;
+ plugin->mesh[i-1][j].w_junction = plugin->mesh[i][j].v_junction - plugin->mesh[i][j].e_temp;
+
+ plugin->mesh[i][j].c_junction = plugin->mesh[i][j].v_junction - plugin->mesh[i][j].c_junction;
+
+ plugin->mesh[i][j].s_temp = plugin->mesh[i][j].s_junction; //
+ plugin->mesh[i][j].e_temp = plugin->mesh[i][j].e_junction; // update current values in the temp slots!
+ }
+ // BOUNDARY //
+ tempS = plugin->mesh[i][0].s_junction;
+ plugin->mesh[i][0].s_junction = -plugin->mesh[i][0].n_junction;
+ plugin->mesh[i][1].s_junction = plugin->mesh[i][1].s_temp = tempS;
+ tempN = plugin->mesh[i][WIDTH-1].n_junction;
+ plugin->mesh[i][WIDTH-1].n_junction = -plugin->mesh[i][WIDTH-1].s_junction;
+ plugin->mesh[i][WIDTH-2].n_junction = tempN;
+ // 'i's in the neplugint few lines are really 'j's!
+ tempE = plugin->mesh[0][i].e_junction;
+ plugin->mesh[0][i].e_junction = -plugin->mesh[0][i].w_junction;
+ plugin->mesh[1][i].e_junction = plugin->mesh[1][i].e_temp = tempE;
+ tempW = plugin->mesh[WIDTH-1][i].w_junction;
+ plugin->mesh[WIDTH-1][i].w_junction = -plugin->mesh[WIDTH-1][i].e_junction;
+ plugin->mesh[WIDTH-2][i].w_junction = tempW;
+ }
+
+ filt = LOSS*(plugin->mesh[LENGTH-LENGTH/4][WIDTH-WIDTH/4].v_junction + oldfilt);
+ oldfilt = plugin->mesh[LENGTH-LENGTH/4][WIDTH-WIDTH/4].v_junction;
+ plugin->mesh[LENGTH-LENGTH/4][WIDTH-WIDTH/4].v_junction = filt;
+
+ out[k] = plugin->mesh[WIDTH/4][WIDTH/4-1].v_junction;
+ last_trigger = trg;
+ }
+ plugin->last_trigger = last_trigger;
+
+}
+
+void
+wgmesh_cleanup(LADSPA_Handle instance)
+{
+ free(instance);
+}
+
+
+LADSPA_Descriptor* wg_mesh_cr_desc = NULL;
+
+
+/* Called automatically when the plugin library is first loaded. */
+void
+_init()
+{
+ char** port_names;
+ LADSPA_PortDescriptor* port_descriptors;
+ LADSPA_PortRangeHint* port_range_hints;
+
+ wg_mesh_cr_desc = (LADSPA_Descriptor*)malloc(sizeof(LADSPA_Descriptor));
+
+ if (wg_mesh_cr_desc) {
+
+ wg_mesh_cr_desc->UniqueID = MESH_BASE_ID;
+ wg_mesh_cr_desc->Label = strdup("wg_mesh_cr");
+ wg_mesh_cr_desc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
+ wg_mesh_cr_desc->Name = strdup("Simple waveguide mesh (CR Controls)");
+ wg_mesh_cr_desc->Maker = strdup("Loki Davison");
+ wg_mesh_cr_desc->Copyright = strdup("GPL");
+ wg_mesh_cr_desc->PortCount = MESH_NUM_PORTS;
+ port_descriptors = (LADSPA_PortDescriptor*)calloc(MESH_NUM_PORTS, sizeof(LADSPA_PortDescriptor));
+ wg_mesh_cr_desc->PortDescriptors = (const LADSPA_PortDescriptor*)port_descriptors;
+ port_descriptors[MESH_TENSION] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[MESH_POWER] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[MESH_INPUT1] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[MESH_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+ port_descriptors[MESH_EX_X] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_descriptors[MESH_EX_Y] = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
+ port_names = (char**)calloc(MESH_NUM_PORTS, sizeof(char*));
+ wg_mesh_cr_desc->PortNames = (const char**)port_names;
+ port_names[MESH_TENSION] = strdup("Tension");
+ port_names[MESH_POWER] = strdup("Power");
+ port_names[MESH_INPUT1] = strdup("Trigger");
+ port_names[MESH_OUTPUT] = strdup("Output");
+ port_names[MESH_EX_X] = strdup("Excitation X");
+ port_names[MESH_EX_Y] = strdup("Excitation Y");
+ port_range_hints = ((LADSPA_PortRangeHint *)
+ calloc(MESH_NUM_PORTS, sizeof(LADSPA_PortRangeHint)));
+ wg_mesh_cr_desc->PortRangeHints = (const LADSPA_PortRangeHint*)port_range_hints;
+ port_range_hints[MESH_TENSION].HintDescriptor = LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE
+| LADSPA_HINT_DEFAULT_MIDDLE;
+ port_range_hints[MESH_TENSION].LowerBound = 0.0001f;
+ port_range_hints[MESH_TENSION].UpperBound = 0.22f;
+ port_range_hints[MESH_POWER].HintDescriptor = LADSPA_HINT_DEFAULT_1 | LADSPA_HINT_BOUNDED_BELOW;
+ port_range_hints[MESH_POWER].LowerBound = 0.000f;
+ port_range_hints[MESH_POWER].UpperBound = 20.000f;
+
+ port_range_hints[MESH_EX_X].HintDescriptor = LADSPA_HINT_DEFAULT_1 | LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_INTEGER;
+ port_range_hints[MESH_EX_X].LowerBound = 0.950f; //1
+ port_range_hints[MESH_EX_X].UpperBound = LENGTH-0.99;//length-1 ish
+
+ port_range_hints[MESH_EX_Y].HintDescriptor = LADSPA_HINT_DEFAULT_1 | LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_INTEGER;
+ port_range_hints[MESH_EX_Y].LowerBound = 0.950f; //1
+ port_range_hints[MESH_EX_Y].UpperBound = LENGTH-0.99;//length-1 ish
+
+ port_range_hints[MESH_INPUT1].HintDescriptor = 0;
+ port_range_hints[MESH_OUTPUT].HintDescriptor = 0;
+ wg_mesh_cr_desc->instantiate = wgmesh_instantiate;
+ wg_mesh_cr_desc->connect_port = wgmesh_connect_port;
+ wg_mesh_cr_desc->activate = NULL;
+ wg_mesh_cr_desc->run = wgmesh_run_cr;
+ wg_mesh_cr_desc->run_adding = NULL;
+ wg_mesh_cr_desc->set_run_adding_gain = NULL;
+ wg_mesh_cr_desc->deactivate = NULL;
+ wg_mesh_cr_desc->cleanup = wgmesh_cleanup;
+ }
+}
+
+
+void
+wgmesh_delete_descriptor(LADSPA_Descriptor* psDescriptor)
+{
+ unsigned long lIndex;
+ if (psDescriptor) {
+ free((char*)psDescriptor->Label);
+ free((char*)psDescriptor->Name);
+ free((char*)psDescriptor->Maker);
+ free((char*)psDescriptor->Copyright);
+ free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
+ for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
+ free((char*)(psDescriptor->PortNames[lIndex]));
+ free((char**)psDescriptor->PortNames);
+ free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
+ free(psDescriptor);
+ }
+}
+
+
+/* Called automatically when the library is unloaded. */
+void
+_fini()
+{
+ wgmesh_delete_descriptor(wg_mesh_cr_desc);
+}
+
+
+/* Return a descriptor of the requested plugin type. */
+const LADSPA_Descriptor*
+ladspa_descriptor(unsigned long Index)
+{
+ switch (Index) {
+ case 0:
+ return wg_mesh_cr_desc;
+ default:
+ return NULL;
+ }
+}
+