-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpoly_mono_midi_router
116 lines (96 loc) · 2.74 KB
/
poly_mono_midi_router
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
desc:Dynamic poly/mono MIDI router
//tags: MIDI processing routing
//author: Tale
// Copyright (C) 2013-2017 Theo Niessink
// License: LGPL - http://www.gnu.org/licenses/lgpl.html
// This effect distributes incoming MIDI Note On/Off messages equally over
// the specified output channel range. Its typical use would be to convert a
// mono synth into a poly synth. To do this you insert it before multiple
// instances of the mono synth, each on a different MIDI channel.
slider1:0<0,16,1{Any,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>Input Ch
slider2:0<0,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>Output Ch Min
slider3:15<0,15,1{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}>Output Ch Max
slider4:0<0,1,1{Off,On}>Round-Robin
@init
// ch_buf = 0;
note_buf = 16;
@slider
in_ch = max(0, min(16, slider1 |0)) - 1;
min_ch = max(0, min(15, slider2 |0));
max_ch = max(0, min(15, slider3 |0));
min_ch > max_ch ? (
ch = min_ch;
min_ch = max_ch;
max_ch = ch;
);
rr_ch = slider4 >= 0.5 ? max(min_ch, min(max_ch, rr_ch)) : -1;
@block
while(midirecv(ofs, msg1, msg23) ? (
in_ch < 0 || msg1 & 0x0F == in_ch ? (
status = msg1 & 0xF0;
msg2 = msg23 & 0x7F;
msg3 = msg23 >> 8;
// Note On
status == 0x90 && msg3 ? (
ch = note_buf[msg2];
ch ? (
ch -= 1;
) : rr_ch >= 0 ? (
ch = rr_ch;
rr_ch += 1;
rr_ch > max_ch ? rr_ch = min_ch;
ch_buf[ch] += 1;
note_buf[msg2] = ch + 1;
num_note += 1;
) : (
ch = i = min_ch;
n = ch_buf[ch];
while(n && ((i += 1) <= max_ch) ? (
m = ch_buf[i];
m < n ? (
n = m;
ch = i;
);
1; // while
));
ch_buf[ch] += 1;
note_buf[msg2] = ch + 1;
num_note += 1;
);
msg1 = status | ch;
) :
// Note Off
status == 0x80 || status == 0x90 ? (
ch = note_buf[msg2];
ch ? (
ch -= 1;
ch_buf[ch] -= 1;
note_buf[msg2] = 0;
num_note -= 1;
msg1 = status | ch;
) : (
msg1 = 0;
);
) :
// Polyphonic Key Pressure
status == 0xA0 ? (
ch = note_buf[msg2];
msg1 = ch ? status | (ch - 1) : 0;
) :
// Control Change, Program Change, Channel Pressure, Pitch Bend
status >= 0xB0 && status <= 0xE0 ? (
ch = min_ch;
loop(max_ch - min_ch + 1,
midisend(ofs, status | ch, msg23);
ch += 1;
);
msg1 = 0;
// All Notes Off
status == 0xB0 && msg2 >= 123 && num_note ? (
memset(ch_buf, 0, 16 + 128);
num_note = 0;
);
);
);
msg1 ? midisend(ofs, msg1, msg23) : 1;
));