Skip to content

Commit 84b688d

Browse files
authored
Update MIDI Multi Channel Pre-Delay v0.5 > v0.6 (#414)
1 parent 64358f3 commit 84b688d

2 files changed

Lines changed: 255 additions & 39 deletions

File tree

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
noindex: true
2+
desc: MIDI Multi Channel Pre-Delay Live Flagger
3+
version: 0.6
4+
author: Ben 'Talagan' Babut
5+
6+
options:gmem=MIDIMultiChannelPredelay
7+
8+
9+
// This plugin flags live events in GMEM so that another plugin in the normal FX Chain
10+
// can check if incoming MIDI Events are live events or not.
11+
// Currently the check is based on the perfect equality for : the event content + offset in current block
12+
13+
// GMEM : queue of currently processed events.
14+
// They are shared among all instances,
15+
// so beware of the gardener.
16+
17+
// The life of a stored event is 1 block only.
18+
// Just the time for the FX chain to process it.
19+
20+
// Stored Event :
21+
// - Magic : check end of queue
22+
// - Owner UID : check if it belongs to us
23+
// - timestamp : time_precise of the event, drop if > 100ms
24+
// - block num : num of the block, drop if not == current block
25+
// - msg content : msg1 | msg2 | msg3
26+
// - offset in block : offset in block, useful for receiver
27+
28+
@init
29+
30+
ext_noinit = 0;
31+
g_last_play_state = play_state;
32+
33+
MAGIC_NUMBER = 0xF5AF5BB0;
34+
35+
EVENT_START_ADDR = 0;
36+
STORED_EVENT_SIZE = 6;
37+
38+
g_block_num = 0;
39+
b_now = 0;
40+
b_cursor = 0;
41+
42+
@block
43+
44+
function getUID()
45+
local(cp, flags)
46+
(
47+
get_host_placement(cp, flags);
48+
);
49+
50+
function slotIsReusable(slot_address)
51+
local(mg, st, id, ts, bn)
52+
(
53+
mg = gmem[slot_address+0];
54+
id = gmem[slot_address+1];
55+
ts = gmem[slot_address+2];
56+
bn = gmem[slot_address+3];
57+
58+
(mg != MAGIC_NUMBER) || // The slot is crap
59+
((id == UID) && (bn != g_block_num)) || // This is one of ours but not during this block so it is now obsolete
60+
(ts + 0.1 < b_now); // Too old, obsolete, probably a leftover of another plugin
61+
);
62+
63+
function cleanupMemory()
64+
local(last)
65+
(
66+
last = b_cursor;
67+
// Advance till we meet something which is not a slot
68+
while(gmem[b_cursor] == MAGIC_NUMBER) (
69+
last = b_cursor;
70+
b_cursor += STORED_EVENT_SIZE;
71+
);
72+
73+
// Now rewind-erase the end of the queue
74+
while(slotIsReusable(last) && (last >= 0)) (
75+
gmem[last] = 0;
76+
gmem[last+1] = 0;
77+
gmem[last+2] = 0;
78+
gmem[last+3] = 0;
79+
gmem[last+4] = 0;
80+
gmem[last+5] = 0;
81+
last -= STORED_EVENT_SIZE;
82+
);
83+
);
84+
85+
function findNextFreeSlotAddress()
86+
local()
87+
(
88+
while(!slotIsReusable(b_cursor)) (
89+
b_cursor += STORED_EVENT_SIZE;
90+
);
91+
92+
b_cursor;
93+
);
94+
95+
function flagEvent(offset, msg1, msg2, msg3)
96+
local(slot_address)
97+
(
98+
// Calculate address to store next event
99+
slot_address = findNextFreeSlotAddress();
100+
101+
// Store UID / Offsetof the event at this address
102+
gmem[slot_address] = MAGIC_NUMBER;
103+
gmem[slot_address+1] = UID;
104+
gmem[slot_address+2] = b_now;
105+
gmem[slot_address+3] = g_block_num;
106+
gmem[slot_address+4] = (msg1 << 16) | (msg2 << 8) | msg3;
107+
gmem[slot_address+5] = offset;
108+
);
109+
110+
111+
function receiveEvents()
112+
local(offset,msg1,msg2,msg3)
113+
(
114+
// Don't flag system events, use midirecv
115+
while(midirecv(offset, msg1, msg2, msg3)) (
116+
((msg1 & 0xF0) < 0xF0)?(
117+
// It's a message with a channel
118+
flagEvent(offset, msg1, msg2, msg3);
119+
);
120+
midisend(offset, msg1, msg2, msg3);
121+
);
122+
);
123+
124+
//----------------------
125+
126+
b_now = time_precise();
127+
b_cursor = 0;
128+
129+
// Resync the counter on play changes
130+
131+
(g_last_play_state != play_state)?(
132+
g_block_num = 0;
133+
g_last_play_state = play_state;
134+
);
135+
136+
// Read some events, and flag them in gmem
137+
138+
UID = getUID();
139+
receiveEvents();
140+
cleanupMemory();
141+
142+
g_block_num += 1;
143+

0 commit comments

Comments
 (0)