aboutsummaryrefslogtreecommitdiff
path: root/cyclone/hammer/midiflush.c
diff options
context:
space:
mode:
Diffstat (limited to 'cyclone/hammer/midiflush.c')
-rw-r--r--cyclone/hammer/midiflush.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/cyclone/hammer/midiflush.c b/cyclone/hammer/midiflush.c
new file mode 100644
index 0000000..592d9e0
--- /dev/null
+++ b/cyclone/hammer/midiflush.c
@@ -0,0 +1,102 @@
+/* Copyright (c) 2002-2003 krzYszcz and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+#include <string.h>
+#include "m_pd.h"
+
+#define MIDIFLUSH_NCHANNELS 16
+#define MIDIFLUSH_NPITCHES 128
+#define MIDIFLUSH_VOIDPITCH 0xFF
+
+typedef struct _midiflush
+{
+ t_object x_ob;
+ unsigned char x_status;
+ unsigned char x_channel;
+ unsigned char x_pitch;
+ unsigned char x_notes[MIDIFLUSH_NCHANNELS][MIDIFLUSH_NPITCHES];
+} t_midiflush;
+
+static t_class *midiflush_class;
+
+static void midiflush_float(t_midiflush *x, t_float f)
+{
+ int ival = (int)f;
+ if (ival >= 0 && ival < 256)
+ {
+ unsigned char bval = ival;
+ outlet_float(((t_object *)x)->ob_outlet, bval);
+ if (bval & 0x80)
+ {
+ x->x_status = bval & 0xF0;
+ if (x->x_status == 0x80 || x->x_status == 0x90)
+ x->x_channel = bval & 0x0F;
+ else
+ x->x_status = 0;
+ }
+ else if (x->x_status)
+ {
+ if (x->x_pitch == MIDIFLUSH_VOIDPITCH)
+ {
+ x->x_pitch = bval;
+ return;
+ }
+ else if (x->x_status == 0x90 && bval)
+ {
+ x->x_notes[x->x_channel][x->x_pitch]++;
+ }
+ else
+ {
+ x->x_notes[x->x_channel][x->x_pitch]--;
+ }
+ }
+ }
+ x->x_pitch = MIDIFLUSH_VOIDPITCH;
+}
+
+static void midiflush_bang(t_midiflush *x)
+{
+ int chn, pch;
+ for (chn = 0; chn < MIDIFLUSH_NCHANNELS; chn++)
+ {
+ for (pch = 0; pch < MIDIFLUSH_NPITCHES; pch++)
+ {
+ int status = 0x090 | chn;
+ while (x->x_notes[chn][pch])
+ {
+ outlet_float(((t_object *)x)->ob_outlet, status);
+ outlet_float(((t_object *)x)->ob_outlet, pch);
+ outlet_float(((t_object *)x)->ob_outlet, 0);
+ x->x_notes[chn][pch]--;
+ }
+ }
+ }
+}
+
+static void midiflush_clear(t_midiflush *x)
+{
+ memset(x->x_notes, 0, sizeof(x->x_notes));
+}
+
+static void *midiflush_new(void)
+{
+ t_midiflush *x = (t_midiflush *)pd_new(midiflush_class);
+ x->x_status = 0; /* `not a note' */
+ x->x_pitch = MIDIFLUSH_VOIDPITCH;
+ midiflush_clear(x);
+ outlet_new((t_object *)x, &s_float);
+ return (x);
+}
+
+void midiflush_setup(void)
+{
+ midiflush_class = class_new(gensym("midiflush"),
+ (t_newmethod)midiflush_new,
+ 0, /* CHECKED: no flushout */
+ sizeof(t_midiflush), 0, 0);
+ class_addfloat(midiflush_class, midiflush_float);
+ class_addbang(midiflush_class, midiflush_bang);
+ class_addmethod(midiflush_class, (t_method)midiflush_clear,
+ gensym("clear"), 0);
+}