aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil S. Matheussen <ksvalast@users.sourceforge.net>2004-01-08 14:55:24 +0000
committerKjetil S. Matheussen <ksvalast@users.sourceforge.net>2004-01-08 14:55:24 +0000
commite7001842641982a2698f759aa8014aacda6ce568 (patch)
tree95f7645accaeaf5f10c7187161ee045b3ce36153
First commit of k_vst~, k_guile and k_cextsvn2git-root
svn path=/trunk/externals/k_vst~/; revision=1253
-rw-r--r--Makefile38
-rw-r--r--README26
-rw-r--r--abyss.pd12
-rw-r--r--config.h63
-rw-r--r--help-k_vst~.pd25
-rw-r--r--help2-k_vst~.pd77
-rw-r--r--k_vst~.c812
-rw-r--r--plugin~.h189
-rw-r--r--plugin~_ladspa.h108
-rw-r--r--plugin~_vst.c571
-rw-r--r--plugin~_vst.h108
-rw-r--r--version.h28
-rw-r--r--vstutils.h50
13 files changed, 2107 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..08b004d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,38 @@
+
+
+
+NAME=k_vst~
+CSYM=k_vst_tilde
+
+current: pd_linux
+
+
+# ----------------------- LINUX i386 -----------------------
+
+pd_linux: $(NAME).pd_linux
+
+.SUFFIXES: .pd_linux
+
+LINUXCFLAGS = -DPD -DUNIX -DICECAST -O2 -funroll-loops -fomit-frame-pointer \
+ -Wall -W -Wno-shadow -Wstrict-prototypes \
+ -Wno-unused -Wno-parentheses -Wno-switch #-Werror
+
+LINUXINCLUDEPATH=../../src
+LINUXINCLUDE = -I$(LINUXINCLUDEPATH) -I../../vstserver/include
+
+.c.pd_linux:
+ cc $(LINUXCFLAGS) $(LINUXINCLUDE) -I/site/include/wine -c $(NAME).c -I../include -DPLUGIN_TILDE_USE_VST -DPLUGIN_DEBUG -DPLUGIN_TILDE_VERBOSE
+ cc $(LINUXCFLAGS) $(LINUXINCLUDE) -I/site/include/wine -c plugin~_vst.c -I../include -DPLUGIN_TILDE_USE_VST -DPLUGIN_DEBUG -DPLUGIN_TILDE_VERBOSE
+
+ ld -export_dynamic k_vst~.o plugin~_vst.o -shared -o $(NAME).pd_linux -lc -lm -L/usr/local/lib -L../../vstserver -lvst
+ strip --strip-unneeded $*.pd_linux
+ rm -f $*.o ../$*.pd_linux
+ ln -s k_vst~/$*.pd_linux ..
+
+# ----------------------------------------------------------
+
+install:
+ cp help-*.pd ../../doc/5.reference
+
+clean:
+ rm -f *.o *.pd_* so_locations
diff --git a/README b/README
new file mode 100644
index 0000000..40c167d
--- /dev/null
+++ b/README
@@ -0,0 +1,26 @@
+
+0.2.5 -> 0.2.6
+-Code to allow space in dll names added. Code made by Thomas Charbonnel.
+ Also updated the help2 patch to use space in dll name.
+
+0.2.4 -> 0.2.5
+-New midicommands: "ctl", "pitchbend", "aftertouch", "prg", "noteon"
+ and "noteoff". Code made by Thomas Charbonnel
+-Made a better help patch.
+
+0.2.3 -> 0.2.4
+- Added support for VST effect/synth programs; these may now be changed with
+ the 'program' message and a program number. (added by acb)
+ See the help2 example patch.
+
+V0.2.1 -> 0.2.3:
+-Added simple noteon and noteoff messages for vst instruments.
+ See help5-k_vst~.pd.
+
+Changes from v0.2.1 -> 0.2.2:
+-Added opengui and closegui commands.
+
+
+See comment in the top of the file k_vst~ and the
+file org/README.
+
diff --git a/abyss.pd b/abyss.pd
new file mode 100644
index 0000000..8ea4026
--- /dev/null
+++ b/abyss.pd
@@ -0,0 +1,12 @@
+#N canvas 262 30 450 300 10;
+#X obj 131 111 k_vst~ abyss;
+#X msg 59 59 print;
+#X msg 131 68 opengui;
+#X obj 197 68 adc~;
+#X obj 172 147 dac~;
+#X connect 0 1 4 0;
+#X connect 0 2 4 1;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 1;
+#X connect 3 1 0 2;
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..96c2f17
--- /dev/null
+++ b/config.h
@@ -0,0 +1,63 @@
+/* plugin~, a Pd tilde object for hosting LADSPA/VST plug-ins
+ Copyright (C) 2000 Jarno Seppänen
+ $Id: config.h,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. */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* plug-in architecture config */
+
+#if 0
+#ifdef __linux__ /* FIXME? */
+#define PLUGIN_TILDE_USE_LADSPA 1
+#else
+#define PLUGIN_TILDE_USE_LADSPA 0
+#endif
+#ifdef WIN32
+#define PLUGIN_TILDE_USE_VST 1
+#else
+#define PLUGIN_TILDE_USE_VST 0
+#endif
+#endif
+
+ /* make sure something was selected */
+#if (PLUGIN_TILDE_USE_LADSPA == 0) && (PLUGIN_TILDE_USE_VST == 0)
+#error Either PLUGIN_TILDE_USE_LADSPA or PLUGIN_TILDE_USE_VST must be positive
+#endif
+
+/* print debug information */
+#define PLUGIN_TILDE_DEBUG 0
+
+/* print "useful" information */
+#define PLUGIN_TILDE_VERBOSE 0
+
+/* force out-of-place processing */
+#define PLUGIN_TILDE_FORCE_OUTOFPLACE 0
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CONFIG_H__ */
+/* EOF */
diff --git a/help-k_vst~.pd b/help-k_vst~.pd
new file mode 100644
index 0000000..eb57407
--- /dev/null
+++ b/help-k_vst~.pd
@@ -0,0 +1,25 @@
+#N canvas 55 404 825 453 10;
+#X msg 20 138 aftertouch <value> <chan>;
+#X msg 23 99 pitchbend <value> <chan>;
+#X msg 22 177 prg <num> <chan>;
+#X msg 19 221 noteon <num> <level> <chan>;
+#X msg 24 59 ctl <cnum> <val> <chan>;
+#X obj 20 254 noteoff <num> <chan>;
+#X text 25 20 Midi commands:;
+#X text 25 35 --------------;
+#X text 280 25 GUI commands;
+#X text 281 38 -------------;
+#X msg 291 72 opengui;
+#X msg 293 111 closegui;
+#X text 495 17 Control value commands;
+#X msg 493 107 control /<control number> <value>;
+#X msg 493 62 control <control_name> <value>;
+#X text 287 184 Misc. commands;
+#X text 286 198 ---------------;
+#X msg 288 226 reset;
+#X msg 289 260 print;
+#X text 492 202 -----------------;
+#X msg 497 223 program <program number>;
+#X msg 497 262 programname <program name>;
+#X text 490 185 Program commands;
+#X obj 234 376 k_vst~ an_effect_or_softsynth.dll;
diff --git a/help2-k_vst~.pd b/help2-k_vst~.pd
new file mode 100644
index 0000000..585e5e4
--- /dev/null
+++ b/help2-k_vst~.pd
@@ -0,0 +1,77 @@
+#N canvas 531 498 450 300 10;
+#X text 281 30 mda_JX10 is available from http://www.mda-vst.com/;
+#X msg 118 152 print;
+#X msg 24 155 program \$1;
+#X floatatom 26 120 5 0 63;
+#X obj 242 250 dac~;
+#X obj 178 70 bng 15 250 50 0 empty empty empty 0 -6 0 8 -233017 -233017
+-1;
+#N canvas 0 0 559 288 playscale 0;
+#X obj 60 42 inlet;
+#X obj 63 258 outlet;
+#X text 122 41 <- bang here;
+#X text 127 264 <- noteon/noteoff events go here;
+#X msg 65 172 noteoff 48;
+#X obj 79 100 delay 400;
+#X obj 154 100 delay 800;
+#X obj 234 100 delay 1200;
+#X msg 148 172 noteoff 52;
+#X msg 234 172 noteoff 55;
+#X msg 33 201 noteon 48 100;
+#X msg 135 201 noteon 52 100;
+#X msg 239 201 noteon 55 100;
+#X obj 312 100 delay 1600;
+#X obj 395 100 delay 2000;
+#X msg 339 201 noteon 59 100;
+#X msg 325 172 noteoff 59;
+#X msg 442 201 noteon 60 100;
+#X msg 413 172 noteoff 60;
+#X obj 132 126 delay 760;
+#X obj 63 126 delay 360;
+#X obj 210 126 delay 1160;
+#X obj 298 127 delay 1560;
+#X text 532 270 acb;
+#X connect 0 0 10 0;
+#X connect 0 0 6 0;
+#X connect 0 0 7 0;
+#X connect 0 0 13 0;
+#X connect 0 0 14 0;
+#X connect 0 0 19 0;
+#X connect 0 0 5 0;
+#X connect 0 0 20 0;
+#X connect 0 0 21 0;
+#X connect 0 0 22 0;
+#X connect 4 0 1 0;
+#X connect 5 0 11 0;
+#X connect 6 0 12 0;
+#X connect 7 0 15 0;
+#X connect 8 0 1 0;
+#X connect 9 0 1 0;
+#X connect 10 0 1 0;
+#X connect 11 0 1 0;
+#X connect 12 0 1 0;
+#X connect 13 0 17 0;
+#X connect 14 0 18 0;
+#X connect 15 0 1 0;
+#X connect 16 0 1 0;
+#X connect 17 0 1 0;
+#X connect 18 0 1 0;
+#X connect 19 0 8 0;
+#X connect 20 0 4 0;
+#X connect 21 0 9 0;
+#X connect 22 0 16 0;
+#X restore 179 105 pd playscale;
+#X msg 70 196 reset;
+#X text 64 72 Click to hear->;
+#X msg 316 106 \; pd dsp 1;
+#X msg 315 150 \; pd dsp 0;
+#X text 31 35 Select preset below | | | V;
+#X obj 155 188 k_vst~ mda JX10;
+#X connect 1 0 12 0;
+#X connect 2 0 12 0;
+#X connect 3 0 2 0;
+#X connect 5 0 6 0;
+#X connect 6 0 12 0;
+#X connect 7 0 12 0;
+#X connect 12 1 4 0;
+#X connect 12 2 4 1;
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 */
diff --git a/plugin~.h b/plugin~.h
new file mode 100644
index 0000000..23cb376
--- /dev/null
+++ b/plugin~.h
@@ -0,0 +1,189 @@
+/* plugin~, a Pd tilde object for hosting LADSPA/VST plug-ins
+ Copyright (C) 2000 Jarno Seppänen
+ $Id: plugin~.h,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. */
+
+#ifndef __PLUGIN_TILDE_H__
+#define __PLUGIN_TILDE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "config.h"
+
+/* Pd header */
+#ifndef MAXPDSTRING /* lame */
+#include "m_pd.h"
+#endif /* MAXPDSTRING */
+
+#if 0
+# if PLUGIN_TILDE_USE_LADSPA
+# include "plugin~_ladspa.h"
+# endif
+# if PLUGIN_TILDE_USE_VST
+# include "plugin~_vst.h"
+# endif
+#endif /* 0 */
+/*
+ * Now I've moved the following two plug-in-architecture-specific structures
+ * here because having them in plugin~_ladspa.h and plugin~_vst.h proper will
+ * result in a cyclical header dependency
+ */
+#if PLUGIN_TILDE_USE_LADSPA
+#include "ladspa/ladspa.h"
+typedef struct
+{
+ const LADSPA_Descriptor* type;
+ LADSPA_Handle* instance;
+
+ /* Memory to pass async control data to/from the plugin */
+ float* control_input_values;
+ float* control_output_values;
+ /* Used for monitoring changes in the values */
+ float* prev_control_output_values;
+ int prev_control_output_values_invalid;
+
+ /* Pointers to signal memory for out-of-place processing */
+ float** outofplace_audio_outputs;
+ float** actual_audio_outputs; /* real audio outputs for out-of-place */
+
+ unsigned long num_samples;
+ unsigned long sample_rate;
+
+} Plugin_Tilde_Ladspa;
+#endif /* PLUGIN_TILDE_USE_LADSPA */
+
+#if PLUGIN_TILDE_USE_VST
+#include "vst/AEffect.h"
+typedef struct
+{
+ AEffect* instance;
+
+ /* audio wire buffer information */
+ float** audio_inputs;
+ float** audio_outputs;
+ unsigned long num_samples;
+
+ int editor_open;
+
+} Plugin_Tilde_Vst;
+#endif /* PLUGIN_TILDE_USE_VST */
+
+typedef struct
+{
+ /* Pd's way of object-oriented programming */
+ t_object x_obj;
+ t_clock* x_clock;
+
+ /* Access to LADSPA/VST plugins */
+ void* plugin_library;
+ const char* plugin_library_filename; /* only for diagnostics */
+ union {
+#if PLUGIN_TILDE_USE_LADSPA
+ Plugin_Tilde_Ladspa ladspa;
+#endif
+#if PLUGIN_TILDE_USE_VST
+ Plugin_Tilde_Vst vst;
+#endif
+ } plugin;
+
+ /* Plugin information */
+ unsigned num_audio_inputs;
+ unsigned num_audio_outputs;
+ unsigned num_control_inputs;
+ unsigned num_control_outputs;
+
+ /* Pointers to our Pd in- and outlets */
+ t_inlet** audio_inlets;
+ t_outlet** audio_outlets;
+ t_outlet* control_outlet;
+
+ /* Pd's way of passing parameters to the DSP routine */
+ t_int* dsp_vec;
+ unsigned dsp_vec_length;
+
+} Pd_Plugin_Tilde;
+
+/* Object construction and destruction */
+void plugin_tilde_setup (void);
+static void* plugin_tilde_new (t_symbol* s_name, int argc, t_atom *argv);
+static void plugin_tilde_free (Pd_Plugin_Tilde* x);
+static void plugin_tilde_tick (Pd_Plugin_Tilde* x);
+
+/* DSP callbacks */
+static void plugin_tilde_dsp (Pd_Plugin_Tilde* x, t_signal** sp);
+static t_int* plugin_tilde_perform (t_int* w);
+
+/* Plugin callback for sending control output messages */
+void plugin_tilde_emit_control_output (Pd_Plugin_Tilde* x,
+ const char* name,
+ float new_value);
+
+/* First inlet message callback for "control" messages */
+static void plugin_tilde_control (Pd_Plugin_Tilde* x,
+ t_symbol* ctrl_name,
+ t_float ctrl_value);
+
+static void plugin_tilde_opengui (Pd_Plugin_Tilde* x);
+
+static void plugin_tilde_closegui (Pd_Plugin_Tilde* x);
+
+/* First inlet message callback for "control" messages */
+static void plugin_tilde_print (Pd_Plugin_Tilde* x);
+
+/* First inlet message callback for "reset" messages */
+static void plugin_tilde_reset (Pd_Plugin_Tilde* x);
+
+static unsigned plugin_tilde_get_parm_number (Pd_Plugin_Tilde* x,
+ const char* str);
+
+/* internal API to wrap the different plug-in interfaces */
+static const char* plugin_tilde_search_plugin (Pd_Plugin_Tilde* x,
+ const char* name);
+static int plugin_tilde_open_plugin (Pd_Plugin_Tilde* x,
+ const char* name,
+ const char* lib_name,
+ unsigned long sample_rate);
+static void plugin_tilde_close_plugin (Pd_Plugin_Tilde* x);
+static void plugin_tilde_apply_plugin (Pd_Plugin_Tilde* x);
+
+static void plugin_tilde_connect_audio (Pd_Plugin_Tilde* x,
+ float** audio_inputs,
+ float** audio_outputs,
+ unsigned long num_samples);
+static void plugin_tilde_set_control_input_by_name (Pd_Plugin_Tilde* x,
+ const char* name,
+ float value);
+static void plugin_tilde_set_control_input_by_index (Pd_Plugin_Tilde* x,
+ unsigned index_,
+ float value);
+/*static float plugin_tilde_get_control_input (Pd_Plugin_Tilde* x,
+ unsigned int index);*/
+static void plugin_tilde_update_gui (Pd_Plugin_Tilde* x);
+
+static void plugin_tilde_program (Pd_Plugin_Tilde* x, t_float prog_num);
+static void plugin_tilde_programname (Pd_Plugin_Tilde* x, t_symbol* progname);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PLUGIN_TILDE_H__ */
+/* EOF */
diff --git a/plugin~_ladspa.h b/plugin~_ladspa.h
new file mode 100644
index 0000000..88e0086
--- /dev/null
+++ b/plugin~_ladspa.h
@@ -0,0 +1,108 @@
+/* plugin~, a Pd tilde object for hosting LADSPA/VST plug-ins
+ Copyright (C) 2000 Jarno Seppänen
+ $Id: plugin~_ladspa.h,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. */
+
+#ifndef __PLUGIN_TILDE_LADSPA_H__
+#define __PLUGIN_TILDE_LADSPA_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "config.h"
+
+#if PLUGIN_TILDE_USE_LADSPA
+
+#include "plugin~.h"
+
+/* LADSPA header */
+#include "ladspa/ladspa.h"
+
+#if 0 /* moved to plugin~.h because of cyclical header dependency */
+typedef struct
+{
+ const LADSPA_Descriptor* type;
+ LADSPA_Handle* instance;
+
+ /* Memory to pass async control data to/from the plugin */
+ float* control_input_values;
+ float* control_output_values;
+ /* Used for monitoring changes in the values */
+ float* prev_control_output_values;
+ int prev_control_output_values_invalid;
+
+ /* Pointers to signal memory for out-of-place processing */
+ float** outofplace_audio_outputs;
+ float** actual_audio_outputs; /* real audio outputs for out-of-place */
+
+ unsigned long num_samples;
+ unsigned long sample_rate;
+
+} Plugin_Tilde_Ladspa;
+#endif /* moved to plugin~.h because of cyclical header dependency */
+
+
+/* subroutines to wrap the LADSPA interface */
+const char* plugin_tilde_ladspa_search_plugin (Pd_Plugin_Tilde* x,
+ const char* name);
+int plugin_tilde_ladspa_open_plugin (Pd_Plugin_Tilde* x,
+ const char* name,
+ const char* lib_name,
+ unsigned long sample_rate);
+void plugin_tilde_ladspa_close_plugin (Pd_Plugin_Tilde* x);
+void plugin_tilde_ladspa_apply_plugin (Pd_Plugin_Tilde* x);
+
+void plugin_tilde_ladspa_print (Pd_Plugin_Tilde* x);
+void plugin_tilde_ladspa_reset (Pd_Plugin_Tilde* x);
+
+void plugin_tilde_ladspa_connect_audio (Pd_Plugin_Tilde* x,
+ float** audio_inputs,
+ float** audio_outputs,
+ unsigned long num_samples);
+void plugin_tilde_ladspa_set_control_input_by_name (Pd_Plugin_Tilde* x,
+ const char* name,
+ float value);
+void plugin_tilde_ladspa_set_control_input_by_index (Pd_Plugin_Tilde* x,
+ unsigned index_,
+ float value);
+/*float plugin_tilde_ladspa_get_control_input (Pd_Plugin_Tilde* x,
+ const char* name);*/
+/* Control output is handled with plugin_tilde_emit_control_output() callback */
+
+/* Local subroutines */
+static void plugin_tilde_ladspa_search_plugin_callback (const char* full_filename,
+ void* plugin_handle,
+ LADSPA_Descriptor_Function descriptor_function,
+ void* user_data);
+static void plugin_tilde_ladspa_count_ports (Pd_Plugin_Tilde* x);
+static void plugin_tilde_ladspa_connect_control_ports (Pd_Plugin_Tilde* x);
+
+static int plugin_tilde_ladspa_alloc_outofplace_memory (Pd_Plugin_Tilde* x, unsigned long buflen);
+static void plugin_tilde_ladspa_free_outofplace_memory (Pd_Plugin_Tilde* x);
+static int plugin_tilde_ladspa_alloc_control_memory (Pd_Plugin_Tilde* x);
+static void plugin_tilde_ladspa_free_control_memory (Pd_Plugin_Tilde* x);
+
+#endif /* PLUGIN_TILDE_USE_LADSPA */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PLUGIN_TILDE_LADSPA_H__ */
+/* EOF */
diff --git a/plugin~_vst.c b/plugin~_vst.c
new file mode 100644
index 0000000..001924f
--- /dev/null
+++ b/plugin~_vst.c
@@ -0,0 +1,571 @@
+/* plugin~, a Pd tilde object for hosting LADSPA/VST plug-ins
+ Copyright (C) 2000 Jarno Seppänen
+ $Id: plugin~_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"
+#if PLUGIN_TILDE_USE_VST
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "plugin~.h"
+#include "plugin~_vst.h"
+/* VST header */
+#define AEFFECTX_H_LINUXWORKAROUND
+#include "vst/aeffectx.h"
+//#include "vst/AEffect.h"
+/* VST dll helper functions */
+#include "vstutils.h"
+#ifdef WIN32
+#include "win/vitunmsvc.h" /* strncasecmp() */
+#include <windows.h> /* GetForegroundWindow() */
+#endif
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+
+const char*
+plugin_tilde_vst_search_plugin (Pd_Plugin_Tilde* x,
+ const char* name)
+{
+ /* searching through VST libraries not supported */
+ error ("plugin~: warning: searching through VST libraries not supported");
+ return NULL;
+}
+
+int
+plugin_tilde_vst_open_plugin (Pd_Plugin_Tilde* x,
+ const char* name,
+ const char* lib_name,
+ unsigned long sample_rate)
+{
+ unsigned port_index;
+
+ /* precondition(s) */
+ assert (x != NULL);
+ /* name is unused */
+ assert (lib_name != NULL);
+ assert (sample_rate != 0);
+
+ /* Initialize object struct */
+ x->plugin.vst.instance = NULL;
+ x->plugin.vst.audio_inputs = NULL;
+ x->plugin.vst.audio_outputs = NULL;
+ x->plugin.vst.num_samples = 0;
+ x->plugin.vst.editor_open = 0;
+
+#if 0
+ /* Attempt to load the plugin. */
+ x->plugin_library = vstutils_load_vst_plugin_dll (lib_name);
+ if (x->plugin_library == NULL)
+ {
+ error ("plugin~: Unable to load VST plugin library \"%s\"",
+ lib_name);
+ return 1;
+ }
+#endif
+
+ /* Construct the plugin. This is supposed to call
+ the AudioEffect::AudioEffect() ctor eventually */
+ x->plugin.vst.instance
+#if 1
+ =VSTLIB_new((char*)lib_name);
+#else
+ = vstutils_init_vst_plugin (x->plugin_library,
+ lib_name,
+ plugin_tilde_vst_audioMaster);
+#endif
+ if (x->plugin.vst.instance == NULL) {
+ error ("plugin~: Unable to instantiate VST plugin from library \"%s\"",
+ lib_name);
+ return 1;
+ }
+
+ /* Stuff Pd_Plugin_Tilde* x into user field of AEffect for audioMaster() to use */
+ x->plugin.vst.instance->user = x;
+
+ /* Call plugin open() (through dispatcher()) in order to ensure
+ plugin is properly constructed */
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effOpen,
+ 0, 0, NULL, 0);
+
+
+#if PLUGIN_TILDE_DEBUG
+ error ("DEBUG plugin~: constructed VST plugin \"%s\" successfully",
+ lib_name);
+#endif
+
+
+ /* Check another strange id */
+ if (x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effIdentify,
+ 0, 0, NULL, 0)
+ != 'NvEf') {
+ error ("plugin~_vst: warning: VST plugin malfunction (effIdentify != 'NvEf')");
+ }
+
+
+ /* Tell the sample rate and frame length to the VST plug-in */
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effSetSampleRate,
+ 0, 0, NULL, (float)sample_rate);
+
+ /* FIXME just give some value since it will be changed later */
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effSetBlockSize,
+ 0, 16, NULL, 0);
+ /* Find out the number of inputs and outputs needed (all VST
+ parameters can be automated i.e. output if the plug-in so wants
+ and the GUI can be operated). */
+ x->num_audio_inputs = x->plugin.vst.instance->numInputs;
+ x->num_audio_outputs = x->plugin.vst.instance->numOutputs;
+ x->num_control_inputs = x->plugin.vst.instance->numParams;
+ x->num_control_outputs = x->plugin.vst.instance->numParams;
+
+ /* Make sure that processReplacing() is implemented */
+ if (x->plugin.vst.instance->flags & effFlagsCanReplacing == 0) {
+ error ("plugin~_vst: sorry, this VST plug-in type isn't supported (processReplacing() not implemented)");
+ return 1;
+ }
+
+
+ /* Activate the plugin. */
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effMainsChanged,
+ 0, 1, NULL, 0);
+
+
+ /* Finally, attempt open editor GUI if available */
+ // plugin_tilde_vst_open_editor (x);
+
+
+ /* Make sure the user data still is there */
+ assert (x->plugin.vst.instance->user == x);
+
+ /* success */
+ return 0;
+}
+
+void
+plugin_tilde_vst_close_plugin (Pd_Plugin_Tilde* x)
+{
+ /* precondition(s) */
+ assert (x != NULL);
+
+ /* Attempt to close editor GUI */
+ plugin_tilde_vst_close_editor (x);
+
+ if (x->plugin.vst.instance != NULL)
+ {
+ /* Deactivate the plugin. */
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effMainsChanged,
+ 0, 0, NULL, 0);
+
+ /* Destruct the plugin. This is supposed to translate to
+ a call to the AudioEffect::~AudioEffect() dtor */
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effClose,
+ 0, 0, NULL, 0);
+#if 1
+ VSTLIB_delete(x->plugin.vst.instance);
+#endif
+ x->plugin.vst.instance = NULL;
+ }
+
+
+ if (x->plugin_library != NULL)
+ {
+#if 0
+ vstutils_unload_vst_plugin_dll (x->plugin_library);
+#endif
+ x->plugin_library = NULL;
+ }
+}
+
+void
+plugin_tilde_vst_apply_plugin (Pd_Plugin_Tilde* x)
+{
+ static int agurk=0;
+
+ /* Run the plugin on Pd's buffers */
+ /* FIXME need to implement out-of-place buffers and zero them here
+ if processReplacing() isn't implemented */
+
+ x->plugin.vst.instance->processReplacing (x->plugin.vst.instance,
+ x->plugin.vst.audio_inputs,
+ x->plugin.vst.audio_outputs,
+ x->plugin.vst.num_samples);
+
+}
+
+void
+plugin_tilde_vst_print (Pd_Plugin_Tilde* x)
+{
+ unsigned i;
+ char display[25];
+ long l, nprog;
+
+ printf ("control %d in/out; audio %d in/%d out\n"
+ "Loaded from library \"%s\".\n",
+ x->num_control_inputs,
+ x->num_audio_inputs,
+ x->num_audio_outputs,
+ x->plugin_library_filename);
+
+ /* print the current program name/number */
+ l = x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effGetProgram, 0, 0, display, 0);
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effGetProgramName, 0, 0, display, 0);
+ nprog = x->plugin.vst.instance->numPrograms;
+ printf("Program #%ld (of %ld), \"%s\".\n",l,nprog,display);
+
+ for (i = 0; i < x->num_control_inputs; i++) {
+ /* the Steinberg(tm) way... */
+ char name[9];
+ char label[9];
+ if (i == 0) {
+ printf ("Control input/output(s):\n");
+ }
+ memset (name, 0, 9);
+ memset (display, 0, 25);
+ memset (label, 0, 9);
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effGetParamName,
+ i, 0, name, 0);
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effGetParamDisplay,
+ i, 0, display, 0);
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effGetParamLabel,
+ i, 0, label, 0);
+ printf (" #%d \"%s\" (%s %s)\n",
+ i + 1, name, display, label);
+ }
+}
+
+void
+plugin_tilde_vst_reset (Pd_Plugin_Tilde* x)
+{
+ /* precondition(s) */
+ assert (x != NULL);
+ /* reset plug-in by first deactivating and then re-activating it */
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effMainsChanged,
+ 0, 0, NULL, 0);
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effMainsChanged,
+ 0, 1, NULL, 0);
+}
+
+void
+plugin_tilde_vst_connect_audio (Pd_Plugin_Tilde* x,
+ float** audio_inputs,
+ float** audio_outputs,
+ unsigned long num_samples)
+{
+ assert (x != NULL);
+ assert (audio_inputs != NULL);
+ assert (audio_outputs != NULL);
+ x->plugin.vst.audio_inputs = audio_inputs;
+ x->plugin.vst.audio_outputs = audio_outputs;
+ x->plugin.vst.num_samples = num_samples;
+ /* Tell the block size to the VST plug-in */
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effMainsChanged,
+ 0, 0, NULL, 0);
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effSetBlockSize,
+ 0, num_samples, NULL, 0);
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effMainsChanged,
+ 0, 1, NULL, 0);
+}
+
+void
+plugin_tilde_vst_set_control_input_by_name (Pd_Plugin_Tilde* x,
+ const char* name,
+ float value)
+{
+ unsigned parm_index;
+ int found_port; /* boolean */
+ char parm_name[9]; /* the Steinberg(tm) way! */
+
+ /* precondition(s) */
+ assert (x != NULL);
+
+ /* compare control name to VST parameters' names
+ case-insensitively */
+ found_port = 0;
+ for (parm_index = 0; parm_index < x->num_control_inputs; parm_index++)
+ {
+ unsigned cmp_start, cmp_length;
+ memset (parm_name, 0, 9);
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effGetParamName,
+ parm_index, 0, parm_name, 0);
+ /* skip any initial whitespace */
+ cmp_start = 0;
+ while (parm_name[cmp_start] != 0
+ && parm_name[cmp_start] == ' ') {
+ cmp_start++;
+ }
+ cmp_length = MIN (strlen (name), strlen (&parm_name[cmp_start]));
+ if (cmp_length != 0
+ && strncasecmp (name, &parm_name[cmp_start], cmp_length) == 0)
+ {
+ /* found the first port to match */
+ found_port = 1;
+ break;
+ }
+ }
+
+ if (!found_port)
+ {
+ error ("plugin~: VST plugin doesn't have a parameter named \"%s\"",
+ name);
+ return;
+ }
+
+ plugin_tilde_vst_set_control_input_by_index (x,
+ parm_index,
+ value);
+}
+
+void
+plugin_tilde_vst_set_control_input_by_index (Pd_Plugin_Tilde* x,
+ unsigned index_,
+ float value)
+{
+ char name[9]; /* the Steinberg(tm) way! */
+
+ /* precondition(s) */
+ assert (x != NULL);
+ /* assert (index_ >= 0); causes a warning */
+ assert (index_ < x->num_control_inputs);
+
+ /* Limit parameter to range [0, 1] */
+ if (value < 0.0 || value > 1.0) {
+ if (value < 0.0) {
+ value = 0.0;
+ }
+ else {
+ value = 1.0;
+ }
+ error ("plugin~: warning: parameter limited to within [0, 1]");
+ }
+
+ /* set the appropriate control port value */
+ x->plugin.vst.instance->setParameter (x->plugin.vst.instance,
+ index_,
+ value);
+
+#if PLUGIN_TILDE_DEBUG
+ memset (name, 0, 9);
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effGetParamName,
+ index_, 0, name, 0);
+ error ("DEBUG plugin~_vst: control change parameter #%ud: \"%s\" to value %f",
+ index_ + 1, name, value);
+#endif
+}
+
+/* change the plugin's program; takes a program index */
+void
+plugin_tilde_vst_set_program (Pd_Plugin_Tilde* x, long prog)
+{
+ long nprog = x->plugin.vst.instance->numPrograms;
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effSetProgram, 0, prog%nprog, 0, 0);
+}
+
+long
+plugin_tilde_vst_get_program (Pd_Plugin_Tilde* x)
+{
+ return x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effGetProgram, 0, 0, 0, 0);
+}
+
+long
+plugin_tilde_vst_get_num_of_programs (Pd_Plugin_Tilde* x)
+{
+ return x->plugin.vst.instance->numPrograms;
+}
+
+void
+plugin_tilde_vst_set_program_name (Pd_Plugin_Tilde* x, const char* progname)
+{
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effSetProgramName, 0, 0, (void*)progname, 0);
+}
+
+static long
+plugin_tilde_vst_audioMaster (AEffect* effect,
+ long opcode,
+ long index,
+ long value,
+ void* ptr,
+ float opt)
+{
+ char param_name[9];
+
+#if 0 /*PLUGIN_TILDE_DEBUG*/
+ error ("DEBUG plugin~_vst: audioMaster(0x%p, %ld, %ld, %ld, 0x%p, %f)",
+ effect, opcode, index, value, ptr, opt);
+#endif
+
+ switch (opcode) {
+ case audioMasterAutomate:
+ assert (effect != NULL);
+ assert (effect->user != NULL); /* this is Pd_Plugin_Tilde* */
+ effect->setParameter (effect, index, opt);
+ /* Send "control" messages from here */
+ memset (param_name, 0, 9);
+ effect->dispatcher (effect, effGetParamName, index, 0, param_name, 0);
+ plugin_tilde_emit_control_output (effect->user, param_name, opt);
+ return 0;
+ break;
+ case audioMasterVersion:
+ return 1;
+ break;
+ case audioMasterCurrentId:
+ return 0;
+ break;
+ case audioMasterIdle:
+ effect->dispatcher (effect, effEditIdle, 0, 0, NULL, 0);
+ return 0;
+ break;
+ case audioMasterPinConnected:
+ /* return 0="true" for all inquiries for now */
+ return 0;
+ break;
+ }
+#if 0 /*PLUGIN_TILDE_DEBUG*/
+ error ("DEBUG plugin~_vst: warning: unsupported audioMaster opcode");
+#endif
+ return 0;
+}
+
+void plugin_tilde_vst_open_editor (Pd_Plugin_Tilde* x)
+{
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effEditOpen,
+ 0, 0, NULL, 0);
+
+#if 0 /* FIXME doesn't work */
+#ifdef WIN32
+ HWND parent;
+
+ /* precondition(s) */
+ assert (x != NULL);
+
+#if PLUGIN_TILDE_DEBUG
+ error ("DEBUG plugin~_vst: open_editor()");
+#endif
+
+ if ((x->plugin.vst.instance->flags & effFlagsHasEditor) == 0
+ || x->plugin.vst.editor_open == 1) {
+ /* no editor or editor already open */
+ return;
+ }
+
+ /* Hmph, don't know about the Pd window, so give the desktop as
+ the parent to the plug-in; we could actually use
+ GetForegroundWindow(), since the user is currently typing into
+ the pd subpatch window */
+ /*parent = GetDesktopWindow ();*/
+ parent = GetForegroundWindow ();
+ /*parent = NULL;*/
+
+ /* Open the editor! */
+ if (!x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effEditOpen,
+ 0, 0, parent, 0)) {
+ /* no luck error */
+ error ("plugin~_vst: couldn't open editor");
+ } else {
+ x->plugin.vst.editor_open = 1;
+ }
+#endif /* WIN32 */
+#endif /* FIXME doesn't work */
+}
+
+void
+plugin_tilde_vst_close_editor (Pd_Plugin_Tilde* x)
+{
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effEditClose,
+ 0, 0, NULL, 0);
+
+#if 0 /* FIXME doesn't work */
+#ifdef WIN32
+
+ /* precondition(s) */
+ assert (x != NULL);
+
+#if PLUGIN_TILDE_DEBUG
+ error ("DEBUG plugin~_vst: close_editor()");
+#endif
+
+ if ((x->plugin.vst.instance->flags & effFlagsHasEditor) == 0
+ || x->plugin.vst.editor_open == 0) {
+ /* no editor or it isn't open */
+ return;
+ }
+
+ /* Close the editor */
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effEditClose,
+ 0, 0, NULL, 0);
+ x->plugin.vst.editor_open = 0;
+
+#endif /* WIN32 */
+#endif /* FIXME doesn't work */
+}
+
+void
+plugin_tilde_vst_update_gui (Pd_Plugin_Tilde* x)
+{
+#if 0 /* FIXME doesn't work */
+#ifdef WIN32
+
+ /* precondition(s) */
+ assert (x != NULL);
+
+#if PLUGIN_TILDE_DEBUG
+ error ("DEBUG plugin~_vst: update_gui()");
+#endif
+ if (x->plugin.vst.editor_open) {
+ x->plugin.vst.instance->dispatcher (x->plugin.vst.instance,
+ effEditIdle,
+ 0, 0, NULL, 0);
+ }
+#endif /* WIN32 */
+#endif /* FIXME doesn't work */
+}
+
+#endif /* PLUGIN_TILDE_USE_VST */
+
+/* EOF */
diff --git a/plugin~_vst.h b/plugin~_vst.h
new file mode 100644
index 0000000..ff12d40
--- /dev/null
+++ b/plugin~_vst.h
@@ -0,0 +1,108 @@
+/* plugin~, a Pd tilde object for hosting LADSPA/VST plug-ins
+ Copyright (C) 2000 Jarno Seppänen
+ $Id: plugin~_vst.h,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. */
+
+#ifndef __PLUGIN_TILDE_VST_H__
+#define __PLUGIN_TILDE_VST_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "config.h"
+
+#if PLUGIN_TILDE_USE_VST
+
+#include "plugin~.h"
+
+/* VST header */
+#include "vst/AEffect.h"
+
+#if 0 /* moved to plugin~.h because of cyclical header dependency */
+typedef struct
+{
+ AEffect* instance;
+
+ /* audio wire buffer information */
+ float** audio_inputs;
+ float** audio_outputs;
+ unsigned long num_samples;
+
+ int editor_open;
+} Plugin_Tilde_Vst;
+#endif /* moved to plugin~.h because of cyclical header dependency */
+
+
+/* subroutines to wrap the VST interface */
+const char* plugin_tilde_vst_search_plugin (Pd_Plugin_Tilde* x,
+ const char* name);
+int plugin_tilde_vst_open_plugin (Pd_Plugin_Tilde* x,
+ const char* name,
+ const char* lib_name,
+ unsigned long sample_rate);
+
+void plugin_tilde_vst_close_editor (Pd_Plugin_Tilde* x);
+void plugin_tilde_vst_open_editor (Pd_Plugin_Tilde* x);
+
+void plugin_tilde_vst_close_plugin (Pd_Plugin_Tilde* x);
+void plugin_tilde_vst_apply_plugin (Pd_Plugin_Tilde* x);
+
+void plugin_tilde_vst_print (Pd_Plugin_Tilde* x);
+void plugin_tilde_vst_reset (Pd_Plugin_Tilde* x);
+
+void plugin_tilde_vst_connect_audio (Pd_Plugin_Tilde* x,
+ float** audio_inputs,
+ float** audio_outputs,
+ unsigned long num_samples);
+void plugin_tilde_vst_set_control_input_by_name (Pd_Plugin_Tilde* x,
+ const char* name,
+ float value);
+void plugin_tilde_vst_set_control_input_by_index (Pd_Plugin_Tilde* x,
+ unsigned index_,
+ float value);
+
+
+/* subroutines needed by the VST interface */
+static long plugin_tilde_vst_audioMaster (AEffect* effect,
+ long opcode,
+ long index,
+ long value,
+ void* ptr,
+ float opt);
+
+ /*
+static void plugin_tilde_vst_open_editor (Pd_Plugin_Tilde* x);
+static void plugin_tilde_vst_close_editor (Pd_Plugin_Tilde* x);
+ */
+
+void plugin_tilde_vst_update_gui (Pd_Plugin_Tilde* x);
+
+void plugin_tilde_vst_set_program (Pd_Plugin_Tilde*, long);
+long plugin_tilde_vst_get_program (Pd_Plugin_Tilde*);
+long plugin_tilde_vst_get_num_of_programs (Pd_Plugin_Tilde*);
+void plugin_tilde_vst_set_program_name (Pd_Plugin_Tilde*, const char*);
+
+#endif /* PLUGIN_TILDE_USE_VST */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PLUGIN_TILDE_VST_H__ */
+/* EOF */
diff --git a/version.h b/version.h
new file mode 100644
index 0000000..8cb2f21
--- /dev/null
+++ b/version.h
@@ -0,0 +1,28 @@
+/* plugin~, a Pd tilde object for hosting LADSPA/VST plug-ins
+ Copyright (C) 2000 Jarno Seppänen
+ $Id: version.h,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. */
+
+#ifndef __PLUGIN_TILDE_VERSION_H__
+#define __PLUGIN_TILDE_VERSION_H__
+
+#ifndef PLUGIN_TILDE_VERSION
+#define PLUGIN_TILDE_VERSION "0.2"
+#endif
+
+#endif /* __PLUGIN_TILDE_VERSION_H__ */
diff --git a/vstutils.h b/vstutils.h
new file mode 100644
index 0000000..c90edde
--- /dev/null
+++ b/vstutils.h
@@ -0,0 +1,50 @@
+/* plugin~, a Pd tilde object for hosting LADSPA/VST plug-ins
+ Copyright (C) 2001 Jarno Seppänen
+ Copyright (C) 2000 Richard W.E. Furse
+ $Id: vstutils.h,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. */
+
+#ifndef __VSTUTILS_H__
+#define __VSTUTILS_H__
+
+#include <vstlib.h>
+
+#ifdef WIN32 /* currently for Windows only */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* VST SDK header */
+#include "vst/AEffect.h"
+
+void* vstutils_load_vst_plugin_dll (const char* plugin_dll_filename);
+void vstutils_unload_vst_plugin_dll (void* plugin_dll);
+AEffect* vstutils_init_vst_plugin (void* plugin_dll,
+ const char* plugin_dll_filename,
+ audioMasterCallback am);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* WIN32 */
+
+#endif /* __VSTUTILS_H__ */
+/* EOF */