desc:MIDI legato (no notes overlaping) by Levitanus
slider1:0<0,1,{off,on}>-legato_delay
@init
notes = 100;
notes[0] = 0;
notes[1] = 0;
notes[2] = 0;
notes[3] = 0;
notes[4] = 0;
notes[5] = 0;
notes[6] = 0;
notes[7] = 0;
notes[8] = 0;
notes[9] = 0;
noteon_cnt = 0;
last_velocity = 0;
last_note = -1;
#print = "start";
function add_note_to_pool(note)
local(pos)(
noteon_cnt += 1;
notes[noteon_cnt*2] = note;
notes[noteon_cnt*2+1] = 2;
);
function mute_last_note(note)
local(pos, idx, flag)(
idx = 0;
flag = 1;
while(idx<10 && flag == 1)(
notes[idx*2+1] == 2?(
notes[idx*2+1] = -1;
flag = 0;
);
idx += 1;
);
);
function delete_note_from_list(idx)
local(inc_idx)(
noteon_cnt -= 1;
inc_idx = idx+1;
while(inc_idx<10)(
notes[(inc_idx-1)*2] = notes[inc_idx*2];
notes[(inc_idx-1)*2+1] = notes[inc_idx*2+1];
inc_idx+=1
);
);
function kill_overlaps(offset)
local (idx, flag)(
idx = 0;
flag = 1;
while(idx < 10)(
notes[idx * 2 + 1] == -1?(
midisend(offset, $x80, notes[idx * 2], 0);
notes[idx * 2 + 1] = 1;
);
notes[idx * 2 + 1] == -2?(
notes[idx * 2+1] = 0;
midisend(offset, $x80, notes[idx * 2], 0);
// delete_idx = idx+1;
delete_note_from_list(idx);
// flag = 0;
// idx+=1
);
idx+=1
);
);
function delete_note(note)
local(idx, flag)(
idx = 0;
flag = 1;
while(idx<10 && flag == 1)(
notes[idx*2] == note?(
notes[idx*2+1] == 1?(
delete_note_from_list(idx);
):(
notes[idx * 2+1] = -2;
);
flag = 0;
);
idx+=1
);
);
function on_note(note, velocity, offset)
local (ignore, idx, flag)(
ignore = 0;
last_velocity = velocity;
last_note = note;
noteon_cnt>0?(
mute_last_note()
);
add_note_to_pool(note);
slider1 == 0?(
kill_overlaps(offset);
);
ignore;
);
function play_last_note()
local(idx, flag)(
noteon_cnt>0?(
notes[noteon_cnt * 2+1] = 2;
new_note = notes[noteon_cnt * 2];
midisend(offset, $x90, new_note, last_velocity);
last_note = new_note;
);
);
function on_release(note, offset)
local (ignore, islastnote, new_note)(
ignore = 1;
islastnote = 0;
note == last_note?(
islastnote = 1;
);
// delete current note
delete_note(note);
slider1 == 0?( // delete it completely if no overlapping
kill_overlaps(offset);
);
//
islastnote == 1?(
play_last_note();
);
ignore;
);
@block
kill_overlaps(0);
while (midirecv(offset,msg1,msg2,msg3)) ( // REAPER 4.59+ syntax while()
msg1==$x90? (
msg3!=0?( // on note
ignore = on_note(msg2, msg3, offset);
ignore==0?(
midisend(offset,msg1,msg2,msg3);
);
) : ( // on release
ignore = on_release(msg2, offset);
ignore==0?(
midisend(offset,msg1,msg2,msg3);
);
);
) : ( msg1==$x80?( // on release
ignore = on_release(msg2, offset);
ignore==0?(
midisend(offset,msg1,msg2,msg3);
);
) : (
midisend(offset,msg1,msg2,msg3); // passthrough other events
);
);
);