-- Version 2 - 27.05.21 "beta" Include("Helpers/Scales.lua") -- start values scale = 1 root = 1 Low_Cut = 40 High_Cut = 87 Gate_Threshold = 25 Norm_Low=40 Norm_High=127 Min_Retrigger_ms = 25 frame_time_set = 0 ms_per_frame = 256.0 / 44.1 -- default --globals at start of script countdown = {} nts_startFade = {} -- here the notes nts_act = {} -- the enveloped verson of nts_in CurrentAfterTouch = {} prev_duration = {} function IsInScale(pitch) local s = Scales[scale] for i=1, #s do if pitch % 12 == (s[i]+root-1)%12 then return true end end return false end function OnNote(channel, pitch, velocity) if velocity == 0 then --noteoff : set countdown time nts_startFade[pitch]= Min_Retrigger_ms / ms_per_frame countdown[pitch] = 1 else --note on -- work out note velocity as percentage of midi maximum (127) PercOfMax = (velocity - Gate_Threshold) / (127 - Gate_Threshold) -- recalculate the value into the normalisation target range TargetRange = Norm_High - Norm_Low NewVelocity = math.floor(Norm_Low + (TargetRange * PercOfMax)) if (nts_act[pitch] == 0 and velocity > Gate_Threshold) then -- normal on if pitch < High_Cut and pitch >= Low_Cut and IsInScale(pitch) then if Sustain_Pedal ~= susp_old then Control(channel, 64, Sustain_Pedal) Print(" Sustain pedal:", Sustain_Pedal) end Note(channel, pitch, NewVelocity) susp_old = Sustain_Pedal end nts_act[pitch] = NewVelocity -- note this note countdown[pitch] = 0 nts_startFade[pitch] = 10 -- 99999 -- impossible long default fade time for easy logic else if (nts_startFade[pitch] < 1 and velocity > Gate_Threshold) then Note(channel , pitch , NewVelocity) nts_act[pitch] = NewVelocity end -- if (nts_startFade[pitch] < 1 and velocity > Gate_Threshold) end -- if (nts_act[pitch] == 0 and velocity > Gate_Threshold) end -- if velocity == 0 end -- function OnNote function OnFrame(notes) for i, n in ipairs(notes) do if( n.duration > 50 ) and frame_time_set == 0 then -- this ensures that prev_duration[n.pitch] is set properly ms_per_frame = n.duration - prev_duration[n.pitch] if ms_per_frame >= 1 and ms_per_frame < 1000 then frame_time_set = 1 end -- if ms_per_frame = > 1 and ms_per_frame < 1000 then end -- aif( n.duration > 50 ) and frame_time_set == 0 prev_duration[n.pitch] = n.duration end --for i, n in ipairs(notes) do for i=28, 88 do --Fader countdown stuff if nts_startFade[i] > 0 and countdown[i] == 1 then -- count down fade times nts_startFade[i] = nts_startFade[i] - 1 end -- if nts_startFade[i] > 0 and countdown[i] == 1 if nts_startFade[i] < 1 and nts_act[i] > 0 then -- if countdown ended and there is a note Note(1, i, 0) -- stop it nts_act[i] = 0 -- note this end -- nts_startFade[i] < 1 and nts_act[i] > 0 end -- for i=28, 88 do end -- function OnFrame(notes) function OnStart(info) -- assign a description to be displayed in the header info.description = "Customgate" info.link = "http://jamorigin.com/midi-machine" -- List("Sample_Freq_kHz", 0, "44.1", "48", "96", "192") -- List("Samples", 0, "64", "128", "256", "512") Knob("Sustain_Pedal", 1, 0, 127, 1) Knob("Low_Cut", 0, 28, 64, 1) Knob("High_Cut", 0, 38, 127, 1) Knob("Gate_Threshold", 1, 0, 127, 1) Knob("Norm_Low", 1, 1, 127, 1) Knob("Norm_High", 1, 1, 127, 1) Knob("Min_Retrigger_ms", 0, 1, 100, 1) List("root", 0, "C","C#","D","D#","E","F","F#","G","G#","A","A#","B") List("scale", 0, table.unpack(ScaleNames)) for i = 1, 127 do nts_act[i] = 0 nts_startFade[i] = 0 end -- for i = 1, 127 do end -- function OnStart