aboutsummaryrefslogtreecommitdiff
path: root/k_vst~.c
diff options
context:
space:
mode:
Diffstat (limited to 'k_vst~.c')
-rw-r--r--k_vst~.c812
1 files changed, 812 insertions, 0 deletions
diff --git a/k_vst~.c b/k_vst~.c
new file mode 100644
index 0000000..0353ef5
--- /dev/null
+++ b/k_vst~.c
@@ -0,0 +1,812 @@
+/*
+
+ k_vst~, a Pd tilde object for hosting VST plug-ins.
+
+ This is really just the plugin~ source made by Jarno Seppänen,
+ but with a few lines changed (very few that is) to make it
+ work with vst-plugins using the vstlib.
+
+ The name was changed from plugin~ to k_vst~ to avoid nameclash
+ with the plugin~ object running ladspa plugins.
+
+ This object is for i386 non-windows (ie. linux/freebsd) only.
+
+ Copyright (C) 2002 Kjetil S. Matheussen / Notam,
+ k.s.matheussen@notam02.no
+
+ VST program change code made by Andrew C. Bulhak (acb at dev.null.org)
+
+ MIDI code by Thomas Charbonnel <thomas@undata.org>.
+
+ Code to allow space in dll names also made by Thomas Charbonnel <thomas@undata.org>.
+
+
+------------------
+
+ plugin~, a Pd tilde object for hosting LADSPA/VST plug-ins
+ Copyright (C) 2000 Jarno Seppänen
+ $Id: k_vst~.c,v 1.1 2004-01-08 14:55:24 ksvalast Exp $
+
+ This file is part of plugin~.
+
+ 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. */
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "plugin~.h"
+#include "plugin~_ladspa.h"
+#include "plugin~_vst.h"
+#include "version.h"
+
+#define AEFFECTX_H_LINUXWORKAROUND
+#include "vst/aeffectx.h"
+
+#if PLUGIN_TILDE_USE_LADSPA
+#define PLUGIN_TILDE_BRAND "LADSPA"
+#endif
+#if PLUGIN_TILDE_USE_VST
+#define PLUGIN_TILDE_BRAND "VST"
+#endif
+
+static t_class* plugin_tilde_class = NULL;
+
+
+static char valid_channel (float ch) {
+ if (ch < 1.) {
+ return 0;
+ } else if (ch > 16.) {
+ return 15;
+ } else {
+ return (char)(ch-1);
+ }
+}
+
+static void send_midi_to_plugin (
+ Pd_Plugin_Tilde* x,
+ char data0,
+ char data1,
+ char data2
+ )
+{
+ struct VstMidiEvent das_event;
+ struct VstMidiEvent *pevent=&das_event;
+
+ struct VstEvents events;
+
+ pevent->type = kVstMidiType;
+ pevent->byteSize = 24;
+ pevent->deltaFrames = 0;
+ pevent->flags = 0;
+ pevent->detune = 0;
+ pevent->noteLength = 0;
+ pevent->noteOffset = 0;
+ pevent->reserved1 = 0;
+ pevent->reserved2 = 0;
+ pevent->noteOffVelocity = 0;
+ pevent->midiData[0] = data0;
+ pevent->midiData[1] = data1;
+ pevent->midiData[2] = data2;
+ pevent->midiData[3] = 0;
+
+
+ events.numEvents = 1;
+ events.reserved = 0;
+ events.events[0]=(VstEvent*)pevent;
+
+ x->plugin.vst.instance->dispatcher(
+ x->plugin.vst.instance,
+ effProcessEvents, 0, 0, &events, 0.0f
+ );
+
+}
+
+static void plugin_tilde_ctl (
+ Pd_Plugin_Tilde* x,
+ t_float ctlnum,
+ t_float ctlval,
+ t_float ctlchan
+ )
+{
+ send_midi_to_plugin(x, 0xb0 | valid_channel(ctlchan), (char)ctlnum, (char)ctlval);
+}
+
+static void plugin_tilde_pitchbend (
+ Pd_Plugin_Tilde* x,
+ t_float pitchvalue,
+ t_float pitchchan
+ )
+{
+ send_midi_to_plugin(x, 0xe0 | valid_channel(pitchchan), (((int)pitchvalue)>>7) & 127, (int)pitchvalue & 127);
+}
+
+static void plugin_tilde_aftertouch (
+ Pd_Plugin_Tilde* x,
+ t_float atvalue,
+ t_float atchan
+ )
+{
+ send_midi_to_plugin(x, 0xa0 | valid_channel(atchan), (char)atvalue, 0);
+}
+
+
+
+static void plugin_tilde_prg (
+ Pd_Plugin_Tilde* x,
+ t_float prgnum,
+ t_float prgchan
+ )
+{
+ send_midi_to_plugin(x, 0xc0 | valid_channel(prgchan), (char)prgnum, 0);
+}
+
+
+
+static void plugin_tilde_noteon (
+ Pd_Plugin_Tilde* x,
+ t_float notenum,
+ t_float notevel,
+ t_float notechan
+ )
+{
+ send_midi_to_plugin(x, 0x90 | valid_channel(notechan), (char)notenum, (char)notevel);
+}
+
+static void plugin_tilde_noteoff(
+ Pd_Plugin_Tilde* x,
+ t_float notenum,
+ t_float notechan
+ )
+{
+ send_midi_to_plugin(x, 0x90 | valid_channel(notechan), (char)notenum, 0);
+}
+
+
+void
+k_vst_tilde_setup (void)
+{
+ /* Make a new Pd class with 2 string creation parameters */
+ plugin_tilde_class = class_new (gensym ("k_vst~"),
+ (t_newmethod)plugin_tilde_new,
+ (t_method)plugin_tilde_free,
+ sizeof (Pd_Plugin_Tilde),
+ 0,
+ A_GIMME, 0);
+ assert (plugin_tilde_class != NULL);
+
+ /* Let's be explicit in not converting the signals in any way */
+ assert (sizeof (float) == sizeof (t_float));
+#if PLUGIN_TILDE_USE_LADSPA
+ assert (sizeof (float) == sizeof (LADSPA_Data));
+#endif
+
+ /* Set the callback for DSP events; this is a standard Pd message */
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_dsp,
+ gensym ("dsp"),
+ 0);
+
+ /* Set the callback for "control" messages in the first inlet;
+ this is a message of our own for changing LADSPA control
+ ports/VST parameters */
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_ctl,
+ gensym ("ctl"),
+ A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_pitchbend,
+ gensym ("pitchbend"),
+ A_DEFFLOAT, A_DEFFLOAT, 0);
+
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_aftertouch,
+ gensym ("aftertouch"),
+ A_DEFFLOAT, A_DEFFLOAT, 0);
+
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_prg,
+ gensym ("prg"),
+ A_DEFFLOAT, A_DEFFLOAT, 0);
+
+
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_noteon,
+ gensym ("noteon"),
+ A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_noteoff,
+ gensym ("noteoff"),
+ A_DEFFLOAT, A_DEFFLOAT, 0);
+
+ /* Set the callback for "control" messages in the first inlet;
+ this is a message of our own for changing LADSPA control
+ ports/VST parameters */
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_control,
+ gensym ("control"),
+ A_DEFSYM, A_DEFFLOAT, 0);
+
+ /* Register a callback for "print" messages in the first inlet;
+ this is a message for printing information on the plug-in */
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_print,
+ gensym ("print"),
+ 0);
+
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_opengui,
+ gensym ("opengui"),
+ 0);
+
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_closegui,
+ gensym ("closegui"),
+ 0);
+
+ /* Register a callback for "reset" messages in the first inlet;
+ this is a message for resetting plug-in state */
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_reset,
+ gensym ("reset"),
+ 0);
+
+ /* Register a callback for setting the program */
+
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_program,
+ gensym ("program"),
+ A_DEFFLOAT, 0);
+
+ class_addmethod (plugin_tilde_class,
+ (t_method)plugin_tilde_programname,
+ gensym ("programname"),
+ A_DEFSYM, 0);
+
+ /* We have to make a "null" callback for signal input to the first
+ inlet or otherwise Pd'll gracefully fuck the inlets up */
+ class_addmethod (plugin_tilde_class,
+ nullfn,
+ gensym ("signal"),
+ 0);
+}
+
+static void*
+plugin_tilde_new (t_symbol* s_name, int argc, t_atom *argv)
+{
+ char buf[255];
+ char name[255];
+ int z;
+ int offset = 0;
+ Pd_Plugin_Tilde* x = NULL;
+ unsigned i = 0;
+
+ /* Allocate object struct */
+ x = (Pd_Plugin_Tilde*)pd_new (plugin_tilde_class);
+ assert (x != NULL);
+
+ /* Initialize object struct */
+ x->plugin_library = NULL;
+ x->plugin_library_filename = NULL;
+ x->num_audio_inputs = 0;
+ x->num_audio_outputs = 0;
+ x->num_control_inputs = 0;
+ x->num_control_outputs = 0;
+ x->audio_inlets = NULL;
+ x->audio_outlets = NULL;
+ x->control_outlet = NULL;
+ x->dsp_vec = NULL;
+ x->dsp_vec_length = 0;
+
+ for (z = 0; z < argc; z++) {
+ atom_string(&argv[z], buf, 255);
+ if (z == 0)
+ {
+ snprintf(&name[offset], 255, "%s", buf);
+ offset += strnlen(buf, 255);
+ } else {
+ if (255-offset > 0) {
+ snprintf(&name[offset], 255-offset, " %s", buf);
+ offset += strnlen(buf, 255);
+ }
+ }
+ }
+
+ /* Construct the clock */
+ x->x_clock = clock_new (x, (t_method)plugin_tilde_tick);
+ assert (x->x_clock != NULL);
+
+#if PLUGIN_TILDE_USE_LADSPA
+ assert (&name[0] != NULL);
+ if (&name[0] == NULL || strlen (&name[0]) == 0) {
+ /* Search for the plugin library */
+ x->plugin_library_filename = plugin_tilde_search_plugin (x, &name[0]);
+ if (x->plugin_library_filename == NULL) {
+ error ("plugin~: " PLUGIN_TILDE_BRAND " plugin not found in any library");
+ goto PLUGIN_TILDE_NEW_RETURN_NULL;
+ }
+ }
+ else {
+ /* Search in the given plugin library */
+ x->plugin_library_filename = strdup (&name[0]);
+ }
+#endif /* PLUGIN_TILDE_USE_LADSPA */
+#if PLUGIN_TILDE_USE_VST
+ /* Remember plugin library filename */
+ x->plugin_library_filename = strdup (&name[0]);
+#endif /* PLUGIN_TILDE_USE_VST */
+
+ /* Load LADSPA/VST plugin */
+ if (plugin_tilde_open_plugin (x,
+ &name[0],
+ x->plugin_library_filename,
+ (unsigned long)sys_getsr ())) {
+ error ("plugin~: Unable to open " PLUGIN_TILDE_BRAND " plugin");
+ goto PLUGIN_TILDE_NEW_RETURN_NULL;
+ }
+
+ /* Start the clock (used for plug-in GUI update) */
+ plugin_tilde_tick (x);
+
+ /* Create in- and outlet(s) */
+
+ /* Allocate memory for in- and outlet pointers */
+ x->audio_inlets = (t_inlet**)calloc (x->num_audio_inputs, sizeof (t_inlet*));
+ x->audio_outlets = (t_outlet**)calloc (x->num_audio_outputs, sizeof (t_outlet*));
+ assert (x->audio_inlets != NULL && x->audio_outlets != NULL);
+
+ /* The first inlet is always there (needn't be created), and is
+ used for control messages. Now, create the rest of the
+ inlets for audio signal input. */
+ for (i = 0; i < x->num_audio_inputs; i++) {
+ x->audio_inlets[i] = inlet_new (&x->x_obj,
+ &x->x_obj.ob_pd,
+ gensym ("signal"),
+ gensym ("signal"));
+ }
+
+ /* We use the first outlet always for LADSPA/VST parameter control
+ messages */
+ x->control_outlet = outlet_new (&x->x_obj, gensym ("control"));
+
+ /* The rest of the outlets are used for audio signal output */
+ for (i = 0; i < x->num_audio_outputs; i++) {
+ x->audio_outlets[i] = outlet_new (&x->x_obj, gensym ("signal"));
+ }
+
+ /* Allocate memory for DSP parameters */
+ x->dsp_vec_length = x->num_audio_inputs + x->num_audio_outputs + 2;
+ x->dsp_vec = (t_int*)calloc (x->dsp_vec_length, sizeof (t_int));
+ assert (x->dsp_vec != NULL);
+
+ return x;
+
+ /* erroneous returns */
+ PLUGIN_TILDE_NEW_RETURN_NULL:
+ if (x->plugin_library_filename != NULL) {
+ free ((void*)x->plugin_library_filename);
+ x->plugin_library_filename = NULL;
+ }
+ if (x->x_clock != NULL) {
+ clock_free (x->x_clock);
+ x->x_clock = NULL;
+ }
+ return NULL; /* Indicate error to Pd */
+}
+
+static void
+plugin_tilde_free (Pd_Plugin_Tilde* x)
+{
+ unsigned i = 0;
+
+ /* precondition(s) */
+ assert (x != NULL);
+
+ /* Stop and destruct the clock */
+ clock_unset (x->x_clock);
+ clock_free (x->x_clock);
+ x->x_clock = NULL;
+
+ /* Unload LADSPA/VST plugin */
+ plugin_tilde_close_plugin (x);
+
+ /* Free DSP parameter memory */
+ if (x->dsp_vec != NULL) {
+ free (x->dsp_vec);
+ x->dsp_vec = NULL;
+ x->dsp_vec_length = 0;
+ }
+
+ /* Destroy inlets */
+ if (x->audio_inlets != NULL) {
+ for (i = 0; i < x->num_audio_inputs; i++) {
+ inlet_free (x->audio_inlets[i]);
+ }
+ free (x->audio_inlets);
+ x->audio_inlets = NULL;
+ }
+
+ /* Destroy outlets */
+ if (x->control_outlet != NULL) {
+ outlet_free (x->control_outlet);
+ x->control_outlet = NULL;
+ }
+ if (x->audio_outlets != NULL) {
+ for (i = 0; i < x->num_audio_outputs; i++) {
+ outlet_free (x->audio_outlets[i]);
+ }
+ free (x->audio_outlets);
+ x->audio_outlets = NULL;
+ }
+
+
+ if (x->plugin_library_filename != NULL) {
+ free ((void*)x->plugin_library_filename);
+ x->plugin_library_filename = NULL;
+ }
+
+}
+
+static void
+plugin_tilde_tick (Pd_Plugin_Tilde* x)
+{
+ /* precondition(s) */
+ assert (x != NULL);
+
+ /* Issue a GUI update (FIXME should use separate GUI thread) */
+ plugin_tilde_update_gui (x);
+
+ /* Schedule next update */
+ clock_delay (x->x_clock, 100); /* FIXME period OK? */
+}
+
+static void
+plugin_tilde_dsp (Pd_Plugin_Tilde* x, t_signal** sp)
+{
+ unsigned i = 0;
+ unsigned long num_samples;
+
+ num_samples = sp[0]->s_n;
+
+ /* Pack vector of parameters for DSP routine */
+ x->dsp_vec[0] = (t_int)x;
+ x->dsp_vec[1] = (t_int)num_samples;
+ /* Inputs are before outputs; ignore the first "null" input */
+ for (i = 2; i < x->dsp_vec_length; i++) {
+ x->dsp_vec[i] = (t_int)(sp[i - 1]->s_vec);
+ }
+
+ /* Connect audio ports with buffers (this is only done when DSP
+ processing begins) */
+ plugin_tilde_connect_audio (x,
+ (float**)(&x->dsp_vec[2]),
+ (float**)(&x->dsp_vec[2 + x->num_audio_inputs]),
+ num_samples);
+
+ /* add DSP routine to Pd's DSP chain */
+ dsp_addv (plugin_tilde_perform, x->dsp_vec_length, x->dsp_vec);
+}
+
+static t_int*
+plugin_tilde_perform (t_int* w)
+{
+ unsigned i = 0;
+ Pd_Plugin_Tilde* x = NULL;
+ t_float** audio_inputs = NULL;
+ t_float** audio_outputs = NULL;
+ int num_samples = 0;
+
+ /* precondition(s) */
+ assert (w != NULL);
+
+ /* Unpack DSP parameter vector */
+ x = (Pd_Plugin_Tilde*)(w[1]);
+ num_samples = (int)(w[2]);
+ audio_inputs = (t_float**)(&w[3]);
+ audio_outputs = (t_float**)(&w[3 + x->num_audio_inputs]);
+
+ /* Call the LADSPA/VST plugin */
+ plugin_tilde_apply_plugin (x);
+
+ return w + (x->dsp_vec_length + 1);
+}
+
+void
+plugin_tilde_emit_control_output (Pd_Plugin_Tilde* x,
+ const char* name,
+ float new_value)
+{
+ /* Construct and outlet a "control" message with two Pd atoms */
+ t_atom anything_atoms[2];
+ anything_atoms[0].a_type = A_SYMBOL;
+ anything_atoms[0].a_w.w_symbol = gensym ((char*)name);
+ anything_atoms[1].a_type = A_FLOAT;
+ anything_atoms[1].a_w.w_float = new_value;
+ outlet_anything (x->control_outlet, gensym ("control"), 2, anything_atoms);
+}
+
+static void
+plugin_tilde_control (Pd_Plugin_Tilde* x,
+ t_symbol* ctrl_name,
+ t_float ctrl_value)
+ /* Change the value of a named control port of the plug-in */
+{
+ unsigned parm_num = 0;
+
+ /* precondition(s) */
+ assert (x != NULL);
+ /* FIXME we assert that the plug-in is already properly opened */
+ if (ctrl_name->s_name == NULL || strlen (ctrl_name->s_name) == 0) {
+ error ("plugin~: control messages must have a name and a value");
+ return;
+ }
+ if (ctrl_name->s_name[0]=='/'){
+ parm_num = atoi(ctrl_name->s_name+1);
+ }else{
+ parm_num = plugin_tilde_get_parm_number (x, ctrl_name->s_name);
+ }
+ if (parm_num) {
+ plugin_tilde_set_control_input_by_index (x, parm_num - 1, ctrl_value);
+ }
+ else {
+ plugin_tilde_set_control_input_by_name (x, ctrl_name->s_name, ctrl_value);
+ }
+}
+
+static void plugin_tilde_opengui (Pd_Plugin_Tilde* x){
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_open_editor(x);
+#endif
+}
+
+static void plugin_tilde_closegui (Pd_Plugin_Tilde* x){
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_close_editor(x);
+#endif
+}
+
+static void
+plugin_tilde_print (Pd_Plugin_Tilde* x)
+ /* Print plug-in name, port names and other information */
+
+/*
+stereo_amp: "Stereo amplifier"; control 1 in/0 out; audio 2 in/2 out
+Control inputs:
+Control outputs:
+Audio inputs:
+Audio outputs:
+ */
+{
+ /* precondition(s) */
+ assert (x != NULL);
+
+#if 1
+ printf("This is k_vst~ version %s. Made by Kjetil S. Matheussen, but ~99.9 percent based on code\n",PLUGIN_TILDE_VERSION);
+ printf("written by Jarno Seppänen.\n\n");
+#else
+ printf ("This is plugin~ version %s -- NO WARRANTY -- Copyright (C) 2000 Jarno Seppänen\n",
+ PLUGIN_TILDE_VERSION);
+#endif
+#if PLUGIN_TILDE_USE_LADSPA
+ plugin_tilde_ladspa_print (x);
+#endif
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_print (x);
+#endif
+}
+
+static void
+plugin_tilde_reset (Pd_Plugin_Tilde* x)
+{
+ /* precondition(s) */
+ assert (x != NULL);
+#if PLUGIN_TILDE_USE_LADSPA
+ plugin_tilde_ladspa_reset (x);
+#endif
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_reset (x);
+#endif
+}
+
+static unsigned
+plugin_tilde_get_parm_number (Pd_Plugin_Tilde* x,
+ const char* str)
+/* find out if str points to a parameter number or not and return the
+ number or zero. The number string has to begin with a '#' character */
+{
+ long num = 0;
+ char* strend = NULL;
+
+ assert (x != NULL);
+ if (str == NULL) {
+ return 0;
+ }
+ if (str[0] != '#') {
+ return 0;
+ }
+ num = strtol (&str[1], &strend, 10);
+ if (str[1] == 0 || *strend != 0) {
+ /* invalid string */
+ return 0;
+ }
+ else if (num >= 1 && num <= (long)x->num_control_inputs) {
+ /* string ok and within range */
+ return (unsigned)num;
+ }
+ else {
+ /* number out of range */
+ return 0;
+ }
+}
+
+static const char*
+plugin_tilde_search_plugin (Pd_Plugin_Tilde* x,
+ const char* name)
+{
+#if PLUGIN_TILDE_USE_LADSPA
+ return plugin_tilde_ladspa_search_plugin (x, name);
+#endif
+#if PLUGIN_TILDE_USE_VST
+ return plugin_tilde_vst_search_plugin (x, name);
+#endif
+}
+
+static int
+plugin_tilde_open_plugin (Pd_Plugin_Tilde* x,
+ const char* name,
+ const char* lib_name,
+ unsigned long sample_rate)
+{
+ int ret = 0;
+
+#if PLUGIN_TILDE_DEBUG
+ error ("DEBUG plugin~: open_plugin (x, \"%s\", \"%s\", %ld);",
+ name, lib_name, sample_rate);
+#endif
+
+#if PLUGIN_TILDE_USE_LADSPA
+ ret = plugin_tilde_ladspa_open_plugin (x, name, lib_name, sample_rate);
+#endif
+#if PLUGIN_TILDE_USE_VST
+ ret = plugin_tilde_vst_open_plugin (x, name, lib_name, sample_rate);
+#endif
+
+#if PLUGIN_TILDE_DEBUG
+ error ("DEBUG plugin~: plugin active");
+#endif
+
+#if PLUGIN_TILDE_VERBOSE
+ plugin_tilde_print (x);
+#endif
+ return ret;
+}
+
+static void
+plugin_tilde_close_plugin (Pd_Plugin_Tilde* x)
+{
+#if PLUGIN_TILDE_DEBUG
+ error ("DEBUG plugin~: close_plugin (x)");
+#endif
+
+#if PLUGIN_TILDE_USE_LADSPA
+ plugin_tilde_ladspa_close_plugin (x);
+#endif
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_close_plugin (x);
+#endif
+
+#if PLUGIN_TILDE_DEBUG
+ error ("DEBUG plugin~: destructed plugin successfully");
+#endif
+}
+
+static void
+plugin_tilde_apply_plugin (Pd_Plugin_Tilde* x)
+{
+#if PLUGIN_TILDE_USE_LADSPA
+ plugin_tilde_ladspa_apply_plugin (x);
+#endif
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_apply_plugin (x);
+#endif
+}
+
+static void
+plugin_tilde_connect_audio (Pd_Plugin_Tilde* x,
+ float** audio_inputs,
+ float** audio_outputs,
+ unsigned long num_samples)
+{
+#if PLUGIN_TILDE_USE_LADSPA
+ plugin_tilde_ladspa_connect_audio (x, audio_inputs, audio_outputs,
+ num_samples);
+#endif
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_connect_audio (x, audio_inputs, audio_outputs,
+ num_samples);
+#endif
+}
+
+static void
+plugin_tilde_set_control_input_by_name (Pd_Plugin_Tilde* x,
+ const char* name,
+ float value)
+{
+#if PLUGIN_TILDE_USE_LADSPA
+ plugin_tilde_ladspa_set_control_input_by_name (x, name, value);
+#endif
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_set_control_input_by_name (x, name, value);
+#endif
+}
+
+static void
+plugin_tilde_set_control_input_by_index (Pd_Plugin_Tilde* x,
+ unsigned index_,
+ float value)
+/* plugin~.c:535: warning: declaration of `index' shadows global declaration */
+{
+#if PLUGIN_TILDE_USE_LADSPA
+ plugin_tilde_ladspa_set_control_input_by_index (x, index_, value);
+#endif
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_set_control_input_by_index (x, index_, value);
+#endif
+}
+
+static void
+plugin_tilde_update_gui (Pd_Plugin_Tilde* x)
+{
+#if PLUGIN_TILDE_USE_LADSPA
+ /* FIXME LADSPA doesn't support GUI's at the moment */
+#endif
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_update_gui (x);
+#endif
+}
+
+static void
+plugin_tilde_program (Pd_Plugin_Tilde* x, t_float prog_num)
+ /* set the plugin's controls to one of its presets */
+{
+#if PLUGIN_TILDE_USE_LADSPA
+#endif
+#if PLUGIN_TILDE_USE_VST
+ plugin_tilde_vst_set_program(x, (long) prog_num);
+#endif
+}
+
+static void
+plugin_tilde_programname (Pd_Plugin_Tilde* x, t_symbol* progname)
+ /* set the name of the current program in the plugin */
+{
+#if PLUGIN_TILDE_USE_LADSPA
+#endif
+#if PLUGIN_TILDE_USE_VST
+ if (progname->s_name == NULL || strlen (progname->s_name) == 0) {
+ error ("plugin~: control messages must have a name and a value");
+ return;
+ }
+ plugin_tilde_vst_set_program_name(x, progname->s_name);
+#endif
+}
+
+
+/* EOF */