Last active
May 4, 2022 16:22
-
-
Save nattog/841bcfb813aefdc751cacf0d4b79f4ab to your computer and use it in GitHub Desktop.
Drummer :: sequencer for Monome Crow + Druid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- drummer | |
-- 4 track pattern sequencer | |
-- pattern notation looks like this 'x---x---x---x---' | |
-- update sequence track with set(track, pattern) | |
-- | |
-- queue a new sequence | |
-- progress(seq table, period - by default 16) | |
-- | |
-- control transport | |
-- start() stop() reset() | |
counter = 0 -- used to get index by modulo of seq items | |
seq = {"", "", "", ""} | |
pause = false | |
preset = {'x---', '----x---', '--x-', 'xx--x--'} | |
queued = {} | |
wait = 0 | |
function init() | |
-- set up input modes | |
input[1].mode("change", 1, 0.1, "rising") | |
input[2].mode("change", 1, 0.1, "rising") | |
input[1].change = function() if pause == false then step() end end | |
input[2].change = reset | |
-- set up output modes | |
for i = 1, 4 do | |
output[i].action = pulse(0.02,8) | |
end | |
end | |
-- resets counter variable to initial value | |
function reset() | |
counter = 0 | |
end | |
-- update counter and trigger for each 'x' found at index of each seq | |
function step() | |
local to_print = "" | |
for chan = 1, #seq do | |
if chan <= 4 then | |
if #seq[chan] > 0 then | |
local step_idx = math.floor(counter % #seq[chan]) + 1 | |
local step_value = seq[chan]:sub(step_idx, step_idx) | |
if step_value == 'x' then | |
output[chan]() | |
end | |
to_print = to_print .. (step_value == 'x' and step_value or "_") .. " " | |
else | |
to_print = to_print .. "_ " | |
end | |
end | |
end | |
-- increments counter | |
counter = counter + 1 | |
if #queued > 0 then | |
-- countdown wait if queue has elements | |
if wait > 0 then | |
wait = wait - 1 | |
else | |
-- can set the queue | |
seq = queued | |
wait = 0 | |
queued = {} | |
end | |
end | |
print(to_print) | |
end | |
function set(idx, val) | |
-- sets all tracks to same val | |
local to_print = '' | |
if idx == "*" then | |
for i = 1, #seq do | |
seq[i] = #val > 0 and val or '' | |
to_print = 'SET ALL TO ' .. string.upper(seq[1]) | |
end | |
-- only set sequences for valid output indexes | |
elseif idx < 5 and idx > 0 then | |
seq[idx] = #val > 0 and val or '' | |
to_print = 'SET ' .. idx .. ' TO ' .. string.upper(seq[idx]); | |
end | |
print('\n' .. to_print .. '\n') | |
end | |
function stop() | |
pause = true | |
end | |
function start() | |
pause = false | |
end | |
function progress(tab, period) | |
local progress_on = period or 16 | |
if tab == nil then | |
print('no input') | |
return | |
end | |
-- if input is empty table, set all channels to empty strings | |
local new_seq = #tab < 1 and {"", "", "", ""} or table.shallow_copy(tab) | |
-- if running then a wait period is necessary | |
if pause == false then | |
wait_period = progress_on % counter | |
-- add seq to queue | |
if wait_period ~= 0 then | |
queued = new_seq | |
wait = wait_period | |
else | |
seq = new_seq | |
end | |
else | |
-- update seq | |
seq = new_seq | |
reset() | |
end | |
end | |
function table.shallow_copy(t) | |
local t2 = {} | |
for k,v in pairs(t) do | |
t2[k] = v | |
end | |
return t2 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment