aboutsummaryrefslogtreecommitdiff
path: root/externals/vanilla
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2011-03-21 21:01:26 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2011-03-21 21:01:26 +0000
commit0f12c96d992570360af4676b90d1cb2f40cf6fa8 (patch)
treede217ab398ef18b7618001d084ed9f445196f2b2 /externals/vanilla
parent70fa5194a370320732db2d7048316c8e09b07a88 (diff)
refactored x_midi.c into individual objects, and split out inmidi_* functions to e_midi.c in pd-extended.git
svn path=/trunk/; revision=15037
Diffstat (limited to 'externals/vanilla')
-rw-r--r--externals/vanilla/bag.c99
-rw-r--r--externals/vanilla/bendin.c59
-rw-r--r--externals/vanilla/bendout.c41
-rw-r--r--externals/vanilla/ctlin.c67
-rw-r--r--externals/vanilla/ctlout.c44
-rw-r--r--externals/vanilla/makenote.c110
-rw-r--r--externals/vanilla/midiclkin.c50
-rw-r--r--externals/vanilla/midiin.c51
-rw-r--r--externals/vanilla/midiout.c42
-rw-r--r--externals/vanilla/midirealtimein.c55
-rw-r--r--externals/vanilla/notein.c64
-rw-r--r--externals/vanilla/noteout.c44
-rw-r--r--externals/vanilla/pgmin.c60
-rw-r--r--externals/vanilla/pgmout.c44
-rw-r--r--externals/vanilla/poly.c139
-rw-r--r--externals/vanilla/polytouchin.c66
-rw-r--r--externals/vanilla/polytouchout.c45
-rw-r--r--externals/vanilla/stripnote.c49
-rw-r--r--externals/vanilla/sysexin.c51
-rw-r--r--externals/vanilla/touchin.c60
-rw-r--r--externals/vanilla/touchout.c41
21 files changed, 1281 insertions, 0 deletions
diff --git a/externals/vanilla/bag.c b/externals/vanilla/bag.c
new file mode 100644
index 00000000..990d5384
--- /dev/null
+++ b/externals/vanilla/bag.c
@@ -0,0 +1,99 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_class *bag_class;
+
+typedef struct _bagelem
+{
+ struct _bagelem *e_next;
+ t_float e_value;
+} t_bagelem;
+
+typedef struct _bag
+{
+ t_object x_obj;
+ t_float x_velo;
+ t_bagelem *x_first;
+} t_bag;
+
+static void *bag_new(void )
+{
+ t_bag *x = (t_bag *)pd_new(bag_class);
+ x->x_velo = 0;
+ floatinlet_new(&x->x_obj, &x->x_velo);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_first = 0;
+ return (x);
+}
+
+static void bag_float(t_bag *x, t_float f)
+{
+ t_bagelem *bagelem, *e2, *e3;
+ if (x->x_velo != 0)
+ {
+ bagelem = (t_bagelem *)getbytes(sizeof *bagelem);
+ bagelem->e_next = 0;
+ bagelem->e_value = f;
+ if (!x->x_first) x->x_first = bagelem;
+ else /* LATER replace with a faster algorithm */
+ {
+ for (e2 = x->x_first; e3 = e2->e_next; e2 = e3)
+ ;
+ e2->e_next = bagelem;
+ }
+ }
+ else
+ {
+ if (!x->x_first) return;
+ if (x->x_first->e_value == f)
+ {
+ bagelem = x->x_first;
+ x->x_first = x->x_first->e_next;
+ freebytes(bagelem, sizeof(*bagelem));
+ return;
+ }
+ for (e2 = x->x_first; e3 = e2->e_next; e2 = e3)
+ if (e3->e_value == f)
+ {
+ e2->e_next = e3->e_next;
+ freebytes(e3, sizeof(*e3));
+ return;
+ }
+ }
+}
+
+static void bag_flush(t_bag *x)
+{
+ t_bagelem *bagelem;
+ while (bagelem = x->x_first)
+ {
+ outlet_float(x->x_obj.ob_outlet, bagelem->e_value);
+ x->x_first = bagelem->e_next;
+ freebytes(bagelem, sizeof(*bagelem));
+ }
+}
+
+static void bag_clear(t_bag *x)
+{
+ t_bagelem *bagelem;
+ while (bagelem = x->x_first)
+ {
+ x->x_first = bagelem->e_next;
+ freebytes(bagelem, sizeof(*bagelem));
+ }
+}
+
+void bag_setup(void)
+{
+ bag_class = class_new(gensym("bag"),
+ (t_newmethod)bag_new, (t_method)bag_clear,
+ sizeof(t_bag), 0, 0);
+ class_addfloat(bag_class, bag_float);
+ class_addmethod(bag_class, (t_method)bag_flush, gensym("flush"), 0);
+ class_addmethod(bag_class, (t_method)bag_clear, gensym("clear"), 0);
+}
diff --git a/externals/vanilla/bendin.c b/externals/vanilla/bendin.c
new file mode 100644
index 00000000..ce9c283b
--- /dev/null
+++ b/externals/vanilla/bendin.c
@@ -0,0 +1,59 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_symbol *bendin_sym;
+
+static t_class *bendin_class;
+
+typedef struct _bendin
+{
+ t_object x_obj;
+ t_float x_channel;
+ t_outlet *x_outlet1;
+ t_outlet *x_outlet2;
+} t_bendin;
+
+static void *bendin_new(t_floatarg f)
+{
+ t_bendin *x = (t_bendin *)pd_new(bendin_class);
+ x->x_channel = f;
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+ if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+ pd_bind(&x->x_obj.ob_pd, bendin_sym);
+ return (x);
+}
+
+static void bendin_list(t_bendin *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_float value = atom_getfloatarg(0, argc, argv);
+ t_float channel = atom_getfloatarg(1, argc, argv);
+ if (x->x_channel != 0)
+ {
+ if (channel != x->x_channel) return;
+ outlet_float(x->x_outlet1, value);
+ }
+ else
+ {
+ outlet_float(x->x_outlet2, channel);
+ outlet_float(x->x_outlet1, value);
+ }
+}
+
+static void bendin_free(t_bendin *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, bendin_sym);
+}
+
+void bendin_setup(void)
+{
+ bendin_class = class_new(gensym("bendin"), (t_newmethod)bendin_new,
+ (t_method)bendin_free, sizeof(t_bendin), CLASS_NOINLET, A_DEFFLOAT, 0);
+ class_addlist(bendin_class, bendin_list);
+ class_sethelpsymbol(bendin_class, gensym("midi"));
+ bendin_sym = gensym("#bendin");
+}
diff --git a/externals/vanilla/bendout.c b/externals/vanilla/bendout.c
new file mode 100644
index 00000000..0ec4f35f
--- /dev/null
+++ b/externals/vanilla/bendout.c
@@ -0,0 +1,41 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_class *bendout_class;
+
+typedef struct _bendout
+{
+ t_object x_obj;
+ t_float x_channel;
+} t_bendout;
+
+static void *bendout_new(t_floatarg channel)
+{
+ t_bendout *x = (t_bendout *)pd_new(bendout_class);
+ if (channel <= 0) channel = 1;
+ x->x_channel = channel;
+ floatinlet_new(&x->x_obj, &x->x_channel);
+ return (x);
+}
+
+static void bendout_float(t_bendout *x, t_float f)
+{
+ int binchan = x->x_channel - 1;
+ int n = (int)f + 8192;
+ if (binchan < 0)
+ binchan = 0;
+ outmidi_pitchbend((binchan >> 4), (binchan & 15), n);
+}
+
+void bendout_setup(void)
+{
+ bendout_class = class_new(gensym("bendout"), (t_newmethod)bendout_new, 0,
+ sizeof(t_bendout), 0, A_DEFFLOAT, 0);
+ class_addfloat(bendout_class, bendout_float);
+ class_sethelpsymbol(bendout_class, gensym("midi"));
+}
diff --git a/externals/vanilla/ctlin.c b/externals/vanilla/ctlin.c
new file mode 100644
index 00000000..53979592
--- /dev/null
+++ b/externals/vanilla/ctlin.c
@@ -0,0 +1,67 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_symbol *ctlin_sym;
+
+static t_class *ctlin_class;
+
+typedef struct _ctlin
+{
+ t_object x_obj;
+ t_float x_channel;
+ t_float x_ctlno;
+ t_outlet *x_outlet1;
+ t_outlet *x_outlet2;
+ t_outlet *x_outlet3;
+} t_ctlin;
+
+static void *ctlin_new(t_symbol *s, int argc, t_atom *argv)
+{
+ int ctlno, channel;
+ t_ctlin *x = (t_ctlin *)pd_new(ctlin_class);
+ if (!argc) ctlno = -1;
+ else ctlno = atom_getfloatarg(0, argc, argv);
+ channel = atom_getfloatarg(1, argc, argv);
+ x->x_channel = channel;
+ x->x_ctlno = ctlno;
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+ if (!channel)
+ {
+ if (x->x_ctlno < 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+ x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
+ }
+ pd_bind(&x->x_obj.ob_pd, ctlin_sym);
+ return (x);
+}
+
+static void ctlin_list(t_ctlin *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_float ctlnumber = atom_getfloatarg(0, argc, argv);
+ t_float value = atom_getfloatarg(1, argc, argv);
+ t_float channel = atom_getfloatarg(2, argc, argv);
+ if (x->x_ctlno >= 0 && x->x_ctlno != ctlnumber) return;
+ if (x->x_channel > 0 && x->x_channel != channel) return;
+ if (x->x_channel == 0) outlet_float(x->x_outlet3, channel);
+ if (x->x_ctlno < 0) outlet_float(x->x_outlet2, ctlnumber);
+ outlet_float(x->x_outlet1, value);
+}
+
+static void ctlin_free(t_ctlin *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, ctlin_sym);
+}
+
+void ctlin_setup(void)
+{
+ ctlin_class = class_new(gensym("ctlin"), (t_newmethod)ctlin_new,
+ (t_method)ctlin_free, sizeof(t_ctlin),
+ CLASS_NOINLET, A_GIMME, 0);
+ class_addlist(ctlin_class, ctlin_list);
+ class_sethelpsymbol(ctlin_class, gensym("midi"));
+ ctlin_sym = gensym("#ctlin");
+}
diff --git a/externals/vanilla/ctlout.c b/externals/vanilla/ctlout.c
new file mode 100644
index 00000000..058f3deb
--- /dev/null
+++ b/externals/vanilla/ctlout.c
@@ -0,0 +1,44 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_class *ctlout_class;
+
+typedef struct _ctlout
+{
+ t_object x_obj;
+ t_float x_ctl;
+ t_float x_channel;
+} t_ctlout;
+
+static void *ctlout_new(t_floatarg ctl, t_floatarg channel)
+{
+ t_ctlout *x = (t_ctlout *)pd_new(ctlout_class);
+ x->x_ctl = ctl;
+ if (channel <= 0) channel = 1;
+ x->x_channel = channel;
+ floatinlet_new(&x->x_obj, &x->x_ctl);
+ floatinlet_new(&x->x_obj, &x->x_channel);
+ return (x);
+}
+
+static void ctlout_float(t_ctlout *x, t_float f)
+{
+ int binchan = x->x_channel - 1;
+ if (binchan < 0)
+ binchan = 0;
+ outmidi_controlchange((binchan >> 4),
+ (binchan & 15), (int)(x->x_ctl), (int)f);
+}
+
+void ctlout_setup(void)
+{
+ ctlout_class = class_new(gensym("ctlout"), (t_newmethod)ctlout_new, 0,
+ sizeof(t_ctlout), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(ctlout_class, ctlout_float);
+ class_sethelpsymbol(ctlout_class, gensym("midi"));
+}
diff --git a/externals/vanilla/makenote.c b/externals/vanilla/makenote.c
new file mode 100644
index 00000000..cee6ffae
--- /dev/null
+++ b/externals/vanilla/makenote.c
@@ -0,0 +1,110 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_class *makenote_class;
+
+typedef struct _hang
+{
+ t_clock *h_clock;
+ struct _hang *h_next;
+ t_float h_pitch;
+ struct _makenote *h_owner;
+} t_hang;
+
+typedef struct _makenote
+{
+ t_object x_obj;
+ t_float x_velo;
+ t_float x_dur;
+ t_outlet *x_pitchout;
+ t_outlet *x_velout;
+ t_hang *x_hang;
+} t_makenote;
+
+static void *makenote_new(t_floatarg velo, t_floatarg dur)
+{
+ t_makenote *x = (t_makenote *)pd_new(makenote_class);
+ x->x_velo = velo;
+ x->x_dur = dur;
+ floatinlet_new(&x->x_obj, &x->x_velo);
+ floatinlet_new(&x->x_obj, &x->x_dur);
+ x->x_pitchout = outlet_new(&x->x_obj, &s_float);
+ x->x_velout = outlet_new(&x->x_obj, &s_float);
+ x->x_hang = 0;
+ return (x);
+}
+
+static void makenote_tick(t_hang *hang)
+{
+ t_makenote *x = hang->h_owner;
+ t_hang *h2, *h3;
+ outlet_float(x->x_velout, 0);
+ outlet_float(x->x_pitchout, hang->h_pitch);
+ if (x->x_hang == hang) x->x_hang = hang->h_next;
+ else for (h2 = x->x_hang; h3 = h2->h_next; h2 = h3)
+ {
+ if (h3 == hang)
+ {
+ h2->h_next = h3->h_next;
+ break;
+ }
+ }
+ clock_free(hang->h_clock);
+ freebytes(hang, sizeof(*hang));
+}
+
+static void makenote_float(t_makenote *x, t_float f)
+{
+ t_hang *hang;
+ if (!x->x_velo) return;
+ outlet_float(x->x_velout, x->x_velo);
+ outlet_float(x->x_pitchout, f);
+ hang = (t_hang *)getbytes(sizeof *hang);
+ hang->h_next = x->x_hang;
+ x->x_hang = hang;
+ hang->h_pitch = f;
+ hang->h_owner = x;
+ hang->h_clock = clock_new(hang, (t_method)makenote_tick);
+ clock_delay(hang->h_clock, (x->x_dur >= 0 ? x->x_dur : 0));
+}
+
+static void makenote_stop(t_makenote *x)
+{
+ t_hang *hang;
+ while (hang = x->x_hang)
+ {
+ outlet_float(x->x_velout, 0);
+ outlet_float(x->x_pitchout, hang->h_pitch);
+ x->x_hang = hang->h_next;
+ clock_free(hang->h_clock);
+ freebytes(hang, sizeof(*hang));
+ }
+}
+
+static void makenote_clear(t_makenote *x)
+{
+ t_hang *hang;
+ while (hang = x->x_hang)
+ {
+ x->x_hang = hang->h_next;
+ clock_free(hang->h_clock);
+ freebytes(hang, sizeof(*hang));
+ }
+}
+
+void makenote_setup(void)
+{
+ makenote_class = class_new(gensym("makenote"),
+ (t_newmethod)makenote_new, (t_method)makenote_clear,
+ sizeof(t_makenote), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(makenote_class, makenote_float);
+ class_addmethod(makenote_class, (t_method)makenote_stop, gensym("stop"),
+ 0);
+ class_addmethod(makenote_class, (t_method)makenote_clear, gensym("clear"),
+ 0);
+}
diff --git a/externals/vanilla/midiclkin.c b/externals/vanilla/midiclkin.c
new file mode 100644
index 00000000..29396abb
--- /dev/null
+++ b/externals/vanilla/midiclkin.c
@@ -0,0 +1,50 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_symbol *midiclkin_sym;
+
+static t_class *midiclkin_class;
+
+typedef struct _midiclkin
+{
+ t_object x_obj;
+ t_outlet *x_outlet1;
+ t_outlet *x_outlet2;
+} t_midiclkin;
+
+static void *midiclkin_new(t_floatarg f)
+{
+ t_midiclkin *x = (t_midiclkin *)pd_new(midiclkin_class);
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+ x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+ pd_bind(&x->x_obj.ob_pd, midiclkin_sym);
+ return (x);
+}
+
+static void midiclkin_list(t_midiclkin *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_float value = atom_getfloatarg(0, argc, argv);
+ t_float count = atom_getfloatarg(1, argc, argv);
+ outlet_float(x->x_outlet2, count);
+ outlet_float(x->x_outlet1, value);
+}
+
+static void midiclkin_free(t_midiclkin *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, midiclkin_sym);
+}
+
+void midiclkin_setup(void)
+{
+ midiclkin_class = class_new(gensym("midiclkin"),
+ (t_newmethod)midiclkin_new, (t_method)midiclkin_free,
+ sizeof(t_midiclkin), CLASS_NOINLET, A_DEFFLOAT, 0);
+ class_addlist(midiclkin_class, midiclkin_list);
+ class_sethelpsymbol(midiclkin_class, gensym("midi"));
+ midiclkin_sym = gensym("#midiclkin");
+}
diff --git a/externals/vanilla/midiin.c b/externals/vanilla/midiin.c
new file mode 100644
index 00000000..16b82a66
--- /dev/null
+++ b/externals/vanilla/midiin.c
@@ -0,0 +1,51 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_symbol *midiin_sym;
+
+static t_class *midiin_class;
+
+typedef struct _midiin
+{
+ t_object x_obj;
+ t_outlet *x_outlet1;
+ t_outlet *x_outlet2;
+} t_midiin;
+
+static void *midiin_new( void)
+{
+ t_midiin *x = (t_midiin *)pd_new(midiin_class);
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+ x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+ pd_bind(&x->x_obj.ob_pd, midiin_sym);
+#ifdef WIN32
+ pd_error(x, "midiin: windows: not supported");
+#endif
+ return (x);
+}
+
+static void midiin_list(t_midiin *x, t_symbol *s, int ac, t_atom *av)
+{
+ outlet_float(x->x_outlet2, atom_getfloatarg(1, ac, av) + 1);
+ outlet_float(x->x_outlet1, atom_getfloatarg(0, ac, av));
+}
+
+static void midiin_free(t_midiin *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, midiin_sym);
+}
+
+void midiin_setup(void)
+{
+ midiin_class = class_new(gensym("midiin"), (t_newmethod)midiin_new,
+ (t_method)midiin_free, sizeof(t_midiin),
+ CLASS_NOINLET, A_DEFFLOAT, 0);
+ class_addlist(midiin_class, midiin_list);
+ class_sethelpsymbol(midiin_class, gensym("midi"));
+ midiin_sym = gensym("#midiin");
+}
diff --git a/externals/vanilla/midiout.c b/externals/vanilla/midiout.c
new file mode 100644
index 00000000..29a43382
--- /dev/null
+++ b/externals/vanilla/midiout.c
@@ -0,0 +1,42 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_class *midiout_class;
+
+void sys_putmidibyte(int portno, int byte);
+
+typedef struct _midiout
+{
+ t_object x_obj;
+ t_float x_portno;
+} t_midiout;
+
+static void *midiout_new(t_floatarg portno)
+{
+ t_midiout *x = (t_midiout *)pd_new(midiout_class);
+ if (portno <= 0) portno = 1;
+ x->x_portno = portno;
+ floatinlet_new(&x->x_obj, &x->x_portno);
+#ifdef __irix__
+ post("midiout: unimplemented in IRIX");
+#endif
+ return (x);
+}
+
+static void midiout_float(t_midiout *x, t_floatarg f)
+{
+ outmidi_byte(x->x_portno - 1, f);
+}
+
+void midiout_setup(void)
+{
+ midiout_class = class_new(gensym("midiout"), (t_newmethod)midiout_new, 0,
+ sizeof(t_midiout), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(midiout_class, midiout_float);
+ class_sethelpsymbol(midiout_class, gensym("midi"));
+}
diff --git a/externals/vanilla/midirealtimein.c b/externals/vanilla/midirealtimein.c
new file mode 100644
index 00000000..3fdb404d
--- /dev/null
+++ b/externals/vanilla/midirealtimein.c
@@ -0,0 +1,55 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_symbol *midirealtimein_sym;
+
+static t_class *midirealtimein_class;
+
+typedef struct _midirealtimein
+{
+ t_object x_obj;
+ t_outlet *x_outlet1;
+ t_outlet *x_outlet2;
+} t_midirealtimein;
+
+static void *midirealtimein_new( void)
+{
+ t_midirealtimein *x = (t_midirealtimein *)pd_new(midirealtimein_class);
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+ x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+ pd_bind(&x->x_obj.ob_pd, midirealtimein_sym);
+#ifndef MSW
+ pd_error(x, "midirealtimein: works under MSW only");
+#endif
+ return (x);
+}
+
+static void midirealtimein_list(t_midirealtimein *x, t_symbol *s,
+ int argc, t_atom *argv)
+{
+ t_float portno = atom_getfloatarg(0, argc, argv);
+ t_float byte = atom_getfloatarg(1, argc, argv);
+
+ outlet_float(x->x_outlet2, portno);
+ outlet_float(x->x_outlet1, byte);
+}
+
+static void midirealtimein_free(t_midirealtimein *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, midirealtimein_sym);
+}
+
+void midirealtimein_setup(void)
+{
+ midirealtimein_class = class_new(gensym("midirealtimein"),
+ (t_newmethod)midirealtimein_new, (t_method)midirealtimein_free,
+ sizeof(t_midirealtimein), CLASS_NOINLET, A_DEFFLOAT, 0);
+ class_addlist(midirealtimein_class, midirealtimein_list);
+ class_sethelpsymbol(midirealtimein_class, gensym("midi"));
+ midirealtimein_sym = gensym("#midirealtimein");
+}
diff --git a/externals/vanilla/notein.c b/externals/vanilla/notein.c
new file mode 100644
index 00000000..00b41f0f
--- /dev/null
+++ b/externals/vanilla/notein.c
@@ -0,0 +1,64 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_symbol *notein_sym;
+
+static t_class *notein_class;
+
+typedef struct _notein
+{
+ t_object x_obj;
+ t_float x_channel;
+ t_outlet *x_outlet1;
+ t_outlet *x_outlet2;
+ t_outlet *x_outlet3;
+} t_notein;
+
+static void *notein_new(t_floatarg f)
+{
+ t_notein *x = (t_notein *)pd_new(notein_class);
+ x->x_channel = f;
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+ x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+ if (f == 0) x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
+ pd_bind(&x->x_obj.ob_pd, notein_sym);
+ return (x);
+}
+
+static void notein_list(t_notein *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_float pitch = atom_getfloatarg(0, argc, argv);
+ t_float velo = atom_getfloatarg(1, argc, argv);
+ t_float channel = atom_getfloatarg(2, argc, argv);
+ if (x->x_channel != 0)
+ {
+ if (channel != x->x_channel) return;
+ outlet_float(x->x_outlet2, velo);
+ outlet_float(x->x_outlet1, pitch);
+ }
+ else
+ {
+ outlet_float(x->x_outlet3, channel);
+ outlet_float(x->x_outlet2, velo);
+ outlet_float(x->x_outlet1, pitch);
+ }
+}
+
+static void notein_free(t_notein *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, notein_sym);
+}
+
+void notein_setup(void)
+{
+ notein_class = class_new(gensym("notein"), (t_newmethod)notein_new,
+ (t_method)notein_free, sizeof(t_notein), CLASS_NOINLET, A_DEFFLOAT, 0);
+ class_addlist(notein_class, notein_list);
+ class_sethelpsymbol(notein_class, gensym("midi"));
+ notein_sym = gensym("#notein");
+}
diff --git a/externals/vanilla/noteout.c b/externals/vanilla/noteout.c
new file mode 100644
index 00000000..5dd84af6
--- /dev/null
+++ b/externals/vanilla/noteout.c
@@ -0,0 +1,44 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_class *noteout_class;
+
+typedef struct _noteout
+{
+ t_object x_obj;
+ t_float x_velo;
+ t_float x_channel;
+} t_noteout;
+
+static void *noteout_new(t_floatarg channel)
+{
+ t_noteout *x = (t_noteout *)pd_new(noteout_class);
+ x->x_velo = 0;
+ if (channel < 1) channel = 1;
+ x->x_channel = channel;
+ floatinlet_new(&x->x_obj, &x->x_velo);
+ floatinlet_new(&x->x_obj, &x->x_channel);
+ return (x);
+}
+
+static void noteout_float(t_noteout *x, t_float f)
+{
+ int binchan = x->x_channel - 1;
+ if (binchan < 0)
+ binchan = 0;
+ outmidi_noteon((binchan >> 4),
+ (binchan & 15), (int)f, (int)x->x_velo);
+}
+
+void noteout_setup(void)
+{
+ noteout_class = class_new(gensym("noteout"), (t_newmethod)noteout_new, 0,
+ sizeof(t_noteout), 0, A_DEFFLOAT, 0);
+ class_addfloat(noteout_class, noteout_float);
+ class_sethelpsymbol(noteout_class, gensym("midi"));
+}
diff --git a/externals/vanilla/pgmin.c b/externals/vanilla/pgmin.c
new file mode 100644
index 00000000..c89d2814
--- /dev/null
+++ b/externals/vanilla/pgmin.c
@@ -0,0 +1,60 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_symbol *pgmin_sym;
+
+static t_class *pgmin_class;
+
+typedef struct _pgmin
+{
+ t_object x_obj;
+ t_float x_channel;
+ t_outlet *x_outlet1;
+ t_outlet *x_outlet2;
+} t_pgmin;
+
+static void *pgmin_new(t_floatarg f)
+{
+ t_pgmin *x = (t_pgmin *)pd_new(pgmin_class);
+ x->x_channel = f;
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+ if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+ pd_bind(&x->x_obj.ob_pd, pgmin_sym);
+ return (x);
+}
+
+static void pgmin_list(t_pgmin *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_float value = atom_getfloatarg(0, argc, argv);
+ t_float channel = atom_getfloatarg(1, argc, argv);
+ if (x->x_channel != 0)
+ {
+ if (channel != x->x_channel) return;
+ outlet_float(x->x_outlet1, value);
+ }
+ else
+ {
+ outlet_float(x->x_outlet2, channel);
+ outlet_float(x->x_outlet1, value);
+ }
+}
+
+static void pgmin_free(t_pgmin *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, pgmin_sym);
+}
+
+void pgmin_setup(void)
+{
+ pgmin_class = class_new(gensym("pgmin"), (t_newmethod)pgmin_new,
+ (t_method)pgmin_free, sizeof(t_pgmin),
+ CLASS_NOINLET, A_DEFFLOAT, 0);
+ class_addlist(pgmin_class, pgmin_list);
+ class_sethelpsymbol(pgmin_class, gensym("midi"));
+ pgmin_sym = gensym("#pgmin");
+}
diff --git a/externals/vanilla/pgmout.c b/externals/vanilla/pgmout.c
new file mode 100644
index 00000000..5b23c2b4
--- /dev/null
+++ b/externals/vanilla/pgmout.c
@@ -0,0 +1,44 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_class *pgmout_class;
+
+typedef struct _pgmout
+{
+ t_object x_obj;
+ t_float x_channel;
+} t_pgmout;
+
+static void *pgmout_new(t_floatarg channel)
+{
+ t_pgmout *x = (t_pgmout *)pd_new(pgmout_class);
+ if (channel <= 0) channel = 1;
+ x->x_channel = channel;
+ floatinlet_new(&x->x_obj, &x->x_channel);
+ return (x);
+}
+
+static void pgmout_float(t_pgmout *x, t_floatarg f)
+{
+ int binchan = x->x_channel - 1;
+ int n = f - 1;
+ if (binchan < 0)
+ binchan = 0;
+ if (n < 0) n = 0;
+ else if (n > 127) n = 127;
+ outmidi_programchange((binchan >> 4),
+ (binchan & 15), n);
+}
+
+void pgmout_setup(void)
+{
+ pgmout_class = class_new(gensym("pgmout"), (t_newmethod)pgmout_new, 0,
+ sizeof(t_pgmout), 0, A_DEFFLOAT, 0);
+ class_addfloat(pgmout_class, pgmout_float);
+ class_sethelpsymbol(pgmout_class, gensym("midi"));
+}
diff --git a/externals/vanilla/poly.c b/externals/vanilla/poly.c
new file mode 100644
index 00000000..cc20b855
--- /dev/null
+++ b/externals/vanilla/poly.c
@@ -0,0 +1,139 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_class *poly_class;
+
+typedef struct voice
+{
+ t_float v_pitch;
+ int v_used;
+ unsigned long v_serial;
+} t_voice;
+
+typedef struct poly
+{
+ t_object x_obj;
+ int x_n;
+ t_voice *x_vec;
+ t_float x_vel;
+ t_outlet *x_pitchout;
+ t_outlet *x_velout;
+ unsigned long x_serial;
+ int x_steal;
+} t_poly;
+
+static void *poly_new(t_float fnvoice, t_float fsteal)
+{
+ int i, n = fnvoice;
+ t_poly *x = (t_poly *)pd_new(poly_class);
+ t_voice *v;
+ if (n < 1) n = 1;
+ x->x_n = n;
+ x->x_vec = (t_voice *)getbytes(n * sizeof(*x->x_vec));
+ for (v = x->x_vec, i = n; i--; v++)
+ v->v_pitch = v->v_used = v->v_serial = 0;
+ x->x_vel = 0;
+ x->x_steal = (fsteal != 0);
+ floatinlet_new(&x->x_obj, &x->x_vel);
+ outlet_new(&x->x_obj, &s_float);
+ x->x_pitchout = outlet_new(&x->x_obj, &s_float);
+ x->x_velout = outlet_new(&x->x_obj, &s_float);
+ x->x_serial = 0;
+ return (x);
+}
+
+static void poly_float(t_poly *x, t_float f)
+{
+ int i;
+ t_voice *v;
+ t_voice *firston, *firstoff;
+ unsigned int serialon, serialoff, onindex = 0, offindex = 0;
+ if (x->x_vel > 0)
+ {
+ /* note on. Look for a vacant voice */
+ for (v = x->x_vec, i = 0, firston = firstoff = 0,
+ serialon = serialoff = 0xffffffff; i < x->x_n; v++, i++)
+ {
+ if (v->v_used && v->v_serial < serialon)
+ firston = v, serialon = v->v_serial, onindex = i;
+ else if (!v->v_used && v->v_serial < serialoff)
+ firstoff = v, serialoff = v->v_serial, offindex = i;
+ }
+ if (firstoff)
+ {
+ outlet_float(x->x_velout, x->x_vel);
+ outlet_float(x->x_pitchout, firstoff->v_pitch = f);
+ outlet_float(x->x_obj.ob_outlet, offindex+1);
+ firstoff->v_used = 1;
+ firstoff->v_serial = x->x_serial++;
+ }
+ /* if none, steal one */
+ else if (firston && x->x_steal)
+ {
+ outlet_float(x->x_velout, 0);
+ outlet_float(x->x_pitchout, firston->v_pitch);
+ outlet_float(x->x_obj.ob_outlet, onindex+1);
+ outlet_float(x->x_velout, x->x_vel);
+ outlet_float(x->x_pitchout, firston->v_pitch = f);
+ outlet_float(x->x_obj.ob_outlet, onindex+1);
+ firston->v_serial = x->x_serial++;
+ }
+ }
+ else /* note off. Turn off oldest match */
+ {
+ for (v = x->x_vec, i = 0, firston = 0, serialon = 0xffffffff;
+ i < x->x_n; v++, i++)
+ if (v->v_used && v->v_pitch == f && v->v_serial < serialon)
+ firston = v, serialon = v->v_serial, onindex = i;
+ if (firston)
+ {
+ firston->v_used = 0;
+ firston->v_serial = x->x_serial++;
+ outlet_float(x->x_velout, 0);
+ outlet_float(x->x_pitchout, firston->v_pitch);
+ outlet_float(x->x_obj.ob_outlet, onindex+1);
+ }
+ }
+}
+
+static void poly_stop(t_poly *x)
+{
+ int i;
+ t_voice *v;
+ for (i = 0, v = x->x_vec; i < x->x_n; i++, v++)
+ if (v->v_used)
+ {
+ outlet_float(x->x_velout, 0L);
+ outlet_float(x->x_pitchout, v->v_pitch);
+ outlet_float(x->x_obj.ob_outlet, i+1);
+ v->v_used = 0;
+ v->v_serial = x->x_serial++;
+ }
+}
+
+static void poly_clear(t_poly *x)
+{
+ int i;
+ t_voice *v;
+ for (v = x->x_vec, i = x->x_n; i--; v++) v->v_used = v->v_serial = 0;
+}
+
+static void poly_free(t_poly *x)
+{
+ freebytes(x->x_vec, x->x_n * sizeof (*x->x_vec));
+}
+
+void poly_setup(void)
+{
+ poly_class = class_new(gensym("poly"),
+ (t_newmethod)poly_new, (t_method)poly_free,
+ sizeof(t_poly), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(poly_class, poly_float);
+ class_addmethod(poly_class, (t_method)poly_stop, gensym("stop"), 0);
+ class_addmethod(poly_class, (t_method)poly_clear, gensym("clear"), 0);
+}
diff --git a/externals/vanilla/polytouchin.c b/externals/vanilla/polytouchin.c
new file mode 100644
index 00000000..627a47a6
--- /dev/null
+++ b/externals/vanilla/polytouchin.c
@@ -0,0 +1,66 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_symbol *polytouchin_sym;
+
+static t_class *polytouchin_class;
+
+typedef struct _polytouchin
+{
+ t_object x_obj;
+ t_float x_channel;
+ t_outlet *x_outlet1;
+ t_outlet *x_outlet2;
+ t_outlet *x_outlet3;
+} t_polytouchin;
+
+static void *polytouchin_new(t_floatarg f)
+{
+ t_polytouchin *x = (t_polytouchin *)pd_new(polytouchin_class);
+ x->x_channel = f;
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+ x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+ if (f == 0) x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
+ pd_bind(&x->x_obj.ob_pd, polytouchin_sym);
+ return (x);
+}
+
+static void polytouchin_list(t_polytouchin *x, t_symbol *s, int argc,
+ t_atom *argv)
+{
+ t_float pitch = atom_getfloatarg(0, argc, argv);
+ t_float value = atom_getfloatarg(1, argc, argv);
+ t_float channel = atom_getfloatarg(2, argc, argv);
+ if (x->x_channel != 0)
+ {
+ if (channel != x->x_channel) return;
+ outlet_float(x->x_outlet2, pitch);
+ outlet_float(x->x_outlet1, value);
+ }
+ else
+ {
+ outlet_float(x->x_outlet3, channel);
+ outlet_float(x->x_outlet2, pitch);
+ outlet_float(x->x_outlet1, value);
+ }
+}
+
+static void polytouchin_free(t_polytouchin *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, polytouchin_sym);
+}
+
+void polytouchin_setup(void)
+{
+ polytouchin_class = class_new(gensym("polytouchin"),
+ (t_newmethod)polytouchin_new, (t_method)polytouchin_free,
+ sizeof(t_polytouchin), CLASS_NOINLET, A_DEFFLOAT, 0);
+ class_addlist(polytouchin_class, polytouchin_list);
+ class_sethelpsymbol(polytouchin_class, gensym("midi"));
+ polytouchin_sym = gensym("#polytouchin");
+}
diff --git a/externals/vanilla/polytouchout.c b/externals/vanilla/polytouchout.c
new file mode 100644
index 00000000..ead6a99a
--- /dev/null
+++ b/externals/vanilla/polytouchout.c
@@ -0,0 +1,45 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+void outmidi_polyaftertouch(int portno, int channel, int pitch, int value);
+
+static t_class *polytouchout_class;
+
+typedef struct _polytouchout
+{
+ t_object x_obj;
+ t_float x_channel;
+ t_float x_pitch;
+} t_polytouchout;
+
+static void *polytouchout_new(t_floatarg channel)
+{
+ t_polytouchout *x = (t_polytouchout *)pd_new(polytouchout_class);
+ if (channel <= 0) channel = 1;
+ x->x_channel = channel;
+ x->x_pitch = 0;
+ floatinlet_new(&x->x_obj, &x->x_pitch);
+ floatinlet_new(&x->x_obj, &x->x_channel);
+ return (x);
+}
+
+static void polytouchout_float(t_polytouchout *x, t_float n)
+{
+ int binchan = x->x_channel - 1;
+ if (binchan < 0)
+ binchan = 0;
+ outmidi_polyaftertouch((binchan >> 4), (binchan & 15), x->x_pitch, n);
+}
+
+void polytouchout_setup(void)
+{
+ polytouchout_class = class_new(gensym("polytouchout"),
+ (t_newmethod)polytouchout_new, 0,
+ sizeof(t_polytouchout), 0, A_DEFFLOAT, 0);
+ class_addfloat(polytouchout_class, polytouchout_float);
+ class_sethelpsymbol(polytouchout_class, gensym("midi"));
+}
diff --git a/externals/vanilla/stripnote.c b/externals/vanilla/stripnote.c
new file mode 100644
index 00000000..d9899e76
--- /dev/null
+++ b/externals/vanilla/stripnote.c
@@ -0,0 +1,49 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_class *stripnote_class;
+
+typedef struct _hang
+{
+ t_clock *h_clock;
+ struct _hang *h_next;
+ t_float h_pitch;
+ struct _makenote *h_owner;
+} t_hang;
+
+typedef struct _stripnote
+{
+ t_object x_obj;
+ t_float x_velo;
+ t_outlet *x_pitchout;
+ t_outlet *x_velout;
+} t_stripnote;
+
+static void *stripnote_new(void )
+{
+ t_stripnote *x = (t_stripnote *)pd_new(stripnote_class);
+ floatinlet_new(&x->x_obj, &x->x_velo);
+ x->x_pitchout = outlet_new(&x->x_obj, &s_float);
+ x->x_velout = outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void stripnote_float(t_stripnote *x, t_float f)
+{
+ t_hang *hang;
+ if (!x->x_velo) return;
+ outlet_float(x->x_velout, x->x_velo);
+ outlet_float(x->x_pitchout, f);
+}
+
+void stripnote_setup(void)
+{
+ stripnote_class = class_new(gensym("stripnote"),
+ (t_newmethod)stripnote_new, 0, sizeof(t_stripnote), 0, 0);
+ class_addfloat(stripnote_class, stripnote_float);
+}
diff --git a/externals/vanilla/sysexin.c b/externals/vanilla/sysexin.c
new file mode 100644
index 00000000..19099926
--- /dev/null
+++ b/externals/vanilla/sysexin.c
@@ -0,0 +1,51 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_symbol *sysexin_sym;
+
+static t_class *sysexin_class;
+
+typedef struct _midiin
+{
+ t_object x_obj;
+ t_outlet *x_outlet1;
+ t_outlet *x_outlet2;
+} t_midiin;
+
+static void sysexin_list(t_midiin *x, t_symbol *s, int ac, t_atom *av)
+{
+ outlet_float(x->x_outlet2, atom_getfloatarg(1, ac, av) + 1);
+ outlet_float(x->x_outlet1, atom_getfloatarg(0, ac, av));
+}
+
+static void *sysexin_new( void)
+{
+ t_midiin *x = (t_midiin *)pd_new(sysexin_class);
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+ x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+ pd_bind(&x->x_obj.ob_pd, sysexin_sym);
+#ifdef WIN32
+ pd_error(x, "sysexin: windows: not supported");
+#endif
+ return (x);
+}
+
+static void sysexin_free(t_midiin *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, sysexin_sym);
+}
+
+void sysexin_setup(void)
+{
+ sysexin_class = class_new(gensym("sysexin"), (t_newmethod)sysexin_new,
+ (t_method)sysexin_free, sizeof(t_midiin),
+ CLASS_NOINLET, A_DEFFLOAT, 0);
+ class_addlist(sysexin_class, sysexin_list);
+ class_sethelpsymbol(sysexin_class, gensym("midi"));
+ sysexin_sym = gensym("#sysexin");
+}
diff --git a/externals/vanilla/touchin.c b/externals/vanilla/touchin.c
new file mode 100644
index 00000000..5fd68f53
--- /dev/null
+++ b/externals/vanilla/touchin.c
@@ -0,0 +1,60 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+
+static t_symbol *touchin_sym;
+
+static t_class *touchin_class;
+
+typedef struct _touchin
+{
+ t_object x_obj;
+ t_float x_channel;
+ t_outlet *x_outlet1;
+ t_outlet *x_outlet2;
+} t_touchin;
+
+static void *touchin_new(t_floatarg f)
+{
+ t_touchin *x = (t_touchin *)pd_new(touchin_class);
+ x->x_channel = f;
+ x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+ if (f == 0) x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+ pd_bind(&x->x_obj.ob_pd, touchin_sym);
+ return (x);
+}
+
+static void touchin_list(t_touchin *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_float value = atom_getfloatarg(0, argc, argv);
+ t_float channel = atom_getfloatarg(1, argc, argv);
+ if (x->x_channel)
+ {
+ if (channel != x->x_channel) return;
+ outlet_float(x->x_outlet1, value);
+ }
+ else
+ {
+ outlet_float(x->x_outlet2, channel);
+ outlet_float(x->x_outlet1, value);
+ }
+}
+
+static void touchin_free(t_touchin *x)
+{
+ pd_unbind(&x->x_obj.ob_pd, touchin_sym);
+}
+
+void touchin_setup(void)
+{
+ touchin_class = class_new(gensym("touchin"), (t_newmethod)touchin_new,
+ (t_method)touchin_free, sizeof(t_touchin),
+ CLASS_NOINLET, A_DEFFLOAT, 0);
+ class_addlist(touchin_class, touchin_list);
+ class_sethelpsymbol(touchin_class, gensym("midi"));
+ touchin_sym = gensym("#touchin");
+}
diff --git a/externals/vanilla/touchout.c b/externals/vanilla/touchout.c
new file mode 100644
index 00000000..c3bc720a
--- /dev/null
+++ b/externals/vanilla/touchout.c
@@ -0,0 +1,41 @@
+/* Copyright (c) 1997-2001 Miller Puckette and others.
+* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* MIDI. */
+
+#include "m_pd.h"
+void outmidi_aftertouch(int portno, int channel, int value);
+
+static t_class *touchout_class;
+
+typedef struct _touchout
+{
+ t_object x_obj;
+ t_float x_channel;
+} t_touchout;
+
+static void *touchout_new(t_floatarg channel)
+{
+ t_touchout *x = (t_touchout *)pd_new(touchout_class);
+ if (channel <= 0) channel = 1;
+ x->x_channel = channel;
+ floatinlet_new(&x->x_obj, &x->x_channel);
+ return (x);
+}
+
+static void touchout_float(t_touchout *x, t_float f)
+{
+ int binchan = x->x_channel - 1;
+ if (binchan < 0)
+ binchan = 0;
+ outmidi_aftertouch((binchan >> 4), (binchan & 15), (int)f);
+}
+
+void touchout_setup(void)
+{
+ touchout_class = class_new(gensym("touchout"), (t_newmethod)touchout_new, 0,
+ sizeof(t_touchout), 0, A_DEFFLOAT, 0);
+ class_addfloat(touchout_class, touchout_float);
+ class_sethelpsymbol(touchout_class, gensym("midi"));
+}