diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/.sconsign | bin | 0 -> 9769 bytes | |||
-rw-r--r-- | src/Makefile.am | 40 | ||||
-rw-r--r-- | src/SConstruct | 7 | ||||
-rw-r--r-- | src/adenv.c | 375 | ||||
-rw-r--r-- | src/adenv_lvl.c | 461 | ||||
-rw-r--r-- | src/comparison_4440.c | 292 | ||||
-rw-r--r-- | src/dahdsr_fexp.c | 510 | ||||
-rw-r--r-- | src/dahdsr_hexp.c | 511 | ||||
-rw-r--r-- | src/fast_crossfade_4410.c | 215 | ||||
-rw-r--r-- | src/formant_filter_4300.c | 344 | ||||
-rw-r--r-- | src/hz_voct_4200.c | 242 | ||||
-rw-r--r-- | src/masher_4310.c | 346 | ||||
-rw-r--r-- | src/multiplexer_4420.c | 249 | ||||
-rw-r--r-- | src/power_4400.c | 237 | ||||
-rw-r--r-- | src/prob_switch_2667.c | 276 | ||||
-rw-r--r-- | src/range_trans_4210.c | 281 | ||||
-rw-r--r-- | src/sample_and_hold_4430.c | 305 | ||||
-rw-r--r-- | src/signal_abs_2669.c | 261 | ||||
-rw-r--r-- | src/slew_limiter_2743.c | 272 | ||||
-rw-r--r-- | src/slide_2741.c | 297 | ||||
-rw-r--r-- | src/waveguide_mesh_2670.c | 362 |
21 files changed, 5883 insertions, 0 deletions
diff --git a/src/.sconsign b/src/.sconsign Binary files differnew file mode 100644 index 0000000..c56d217 --- /dev/null +++ b/src/.sconsign 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; + } +} + |