1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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);
}
|