PSdH:HHM ꣸C̭6VI AZ LuaExample : 3 BandsXAZLU#--[[ 3 band channel splitter, middle band is between Bass and Voice Each band has own velocity control and can be transposed. Bands assigned to MIDI channel 1,2 and 3 on output. AZ, 2016 ]]-- local Band = {} local BassKey = { Label = "Bass under", Type = "Key", Value = MfxKey("C3") } local VoiceKey = { Label = "Voice over", Type = "Key", Value = MfxKey("C5") } local Solo = { Label = "Solo band (0 - no solo)", Type = "Int", Value = 0, Min = 0, Max = 3 } local band_names = { "Bass", "Middle", "Voice"} GUI = { BassKey, VoiceKey, Solo } for i, name in ipairs( band_names ) do local b = {} b.Transpose = { Label = name.." transpose", Type = "Int", Value = 0, Min = -48, Max = 48 } b.Velocity = { Label = name.." velocity", Type = "Int", Value = 0, Min = -48, Max = 48 } Band[i] = b table.insert(GUI, b.Transpose) table.insert(GUI, b.Velocity) end local active = MfxOffNotes.new() function OnInput(pqIn, pqOut) for i,e in ipairs(pqIn) do e = active.move(e, pqOut ) if not e then elseif e.Vel then base = e:copy() local i = 2 -- Middle if e.Key < BassKey.Value then i = 1 elseif e.Key > VoiceKey.Value then i = 3 end if Solo.Value > 0 and Solo.Value ~= i then e = nil else e.Chan = i e.Key = e.Key + Band[i].Transpose.Value e.Vel = e.Vel + Band[i].Velocity.Value end active.add(base, e) end pqOut.add(e) end end OnEvents = function ( From, To, pqIn, pqOut) OnInput(pqIn, pqOut) end $<Example : C3 SwitchKeyXAZLUF--[[Use C3 as a Switch Key to transpose one octave ]]-- local switch_key = MfxKey("C3") -- local active = MfxOffNotes.new() local skey_live = false local skey_clip = { from = 0, to = 0 } function SwitchKey( e ) if not e or not e.Key or (e.Key ~= switch_key) then return e end if e.Type == Note then skey_clip.from = e.Time skey_clip.to = e.Time + e.Duration elseif e.Type == NoteOn then skey_live = true else -- NoteOff skey_live = false end return nil end function IsSwitchedAt( time ) return skey_live or ( (time >= skey_clip.from) and (time < skey_clip.to) ) end function OnInput(pqIn, pqOut) for i,e in ipairs(pqIn) do e = active.move(e, pqOut ) e = SwitchKey(e) if not e then elseif e.Vel then -- process Note/NoteOn (but not NoteOff) base = e:copy() if IsSwitchedAt(e.Time) then e.Key = e.Key + 12 -- transpose end active.add(base, e) end pqOut.add(e) end end OnEvents = function ( From, To, pqIn, pqOut) OnInput(pqIn, pqOut) end Example : Mod 2 PCAZLU--[[ Convert modulation to the Program Change ]]-- function OnInput(pqIn, pqOut) for i,e in ipairs(pqIn) do if e.Type == Control and e.Num == 1 then local pc = MfxEvent.new(Patch) pc.Time = e.Time pc.Chan = e.Chan pc.Patch = e.Val e = pc end pqOut.add(e) end end OnEvents = function ( From, To, pqIn, pqOut) OnInput(pqIn, pqOut) end Example : SplitXAZLUG--[[ Split to channel 1 / 2 by key 64 ]]-- function OnInput(pqIn, pqOut) for i,e in ipairs(pqIn) do if e.Key then if e.Key < 64 then e.Chan = 1 else e.Chan = 2 end end pqOut.add(e) end end OnEvents = function ( From, To, pqIn, pqOut) OnInput(pqIn, pqOut) end Example : CC to channeldAZLUL--[[ Use Controller to switch MIDI channel for Notes AZ 2016 ]]-- local Ctl = { Label = "Controller", Type = "Int", Value = 1 } local ChMax = { Label = "Max channel", Type = "Int", Value = 4, Min = 2, Max = 16 } GUI = { Ctl, ChMax } -- local active = MfxOffNotes.new() local Channel = 0 local floor = math.floor function SwitchCC( e ) if not e or not e.Num or (e.Num ~= Ctl.Value) then return e end Channel = floor( e.Val * ChMax.Value / 128 ) return nil end function OnInput(pqIn, pqOut) for i,e in ipairs(pqIn) do e = active.move(e, pqOut ) e = SwitchCC(e) if not e then elseif e.Vel then base = e:copy() e.Chan = Channel + 1 active.add(base, e) end pqOut.add(e) end end OnEvents = function ( From, To, pqIn, pqOut) OnInput(pqIn, pqOut) end Example : Filter by channelAZLU--[[ Filter all events except from specified channel AZ 2016 ]]-- local Channel = { Label = "Channel", Type = "Int", Value = 1, Min = 1, Max = 16 } GUI = { Channel } function OnInput(pqIn, pqOut) for i,e in ipairs(pqIn) do if e.Chan and e.Chan ~= Channel.Value then e = nil end pqOut.add(e) end end OnEvents = function ( From, To, pqIn, pqOut) OnInput(pqIn, pqOut) end Example : Apply Tempo MapAZLU--[[ OFFLINE PROCESSOR ONLY! Does not work as a filter. Apply tempo map to free played MIDI. AZ 2016 ]]-- local BPM = { Label = "Original BPM", Type = "Int", Value = 100, Min = 50, Max = 240 } local PPQ = Mfx.GetTimebase() local T2M = Mfx.TicksToMsecs local M2T = Mfx.MsecsToTicks local round = math.floor GUI = { BPM } -- function OnInput(pqIn, pqOut) -- original converter to Msec local k = 60000/BPM.Value/PPQ for i,e in ipairs(pqIn) do local ebegin = e.Time * k local eend = (e.Time + e.Duration) * k e.Time = M2T(round(ebegin)) e.Duration = M2T(round(eend)) - e.Time pqOut.add(e) end end OnEvents = function ( From, To, pqIn, pqOut) OnInput(pqIn, pqOut) end dExample : Portamento Fix(AZLU--[[ Extend some notes to make Portamento works on Yamaha synth. AZ, 2016 ]]-- function OnInput(pqIn, pqOut, To) local last_on = 0 for i,e in ipairs(pqIn) do if e.Type == NoteOn then last_on = e.Time elseif e.Type == NoteOff then if e.Time == last_on then e.Time = e.Time + 1 end elseif e.Type == Note then local next_on = To -- we do not know either some note will come after for ni = i + 1, #pqIn do -- find the first note, when available ne = pqIn[ni] if ne.Type == Note then next_on = ne.Time break end end if next_on <= e.Time + e.Duration then e.Duration = e.Duration + 1 end end pqOut.add(e) end end OnEvents = function ( From, To, pqIn, pqOut) OnInput(pqIn, pqOut, To) end Example : CC17AZLU--[[ Send CC1 and CC7 on playback start Use Controller to switch MIDI channel for Notes AZ 2016 ]]-- local CC1 = { Label = "CC1", Type = "Int", Value = 64 } local CC7 = { Label = "CC7", Type = "Int", Value = 64 } GUI = { CC1, CC7 } -- local cc17sent = false function OnStart( ) cc17sent = false end function OnInput(pqIn, pqOut) for i,e in ipairs(pqIn) do pqOut.add(e) end end function OutCC(pqOut, time, num, value) local e = MfxEvent.new( Control ) e.Time = time e.Num = num e.Val = value pqOut.add(e) end OnEvents = function ( From, To, pqIn, pqOut) if not cc17sent then OutCC(pqOut, From, 1, CC1.Value) OutCC(pqOut, From, 7, CC7.Value) cc17sent = true end OnInput(pqIn, pqOut) end @@