Skip to content

Instantly share code, notes, and snippets.

@timothy-taylor
Last active December 29, 2022 18:03
Show Gist options
  • Save timothy-taylor/b7cd40a10c8b52647a0f7c6b27103347 to your computer and use it in GitHub Desktop.
Save timothy-taylor/b7cd40a10c8b52647a0f7c6b27103347 to your computer and use it in GitHub Desktop.
sequencers for monome crow
--- aleatoric palindrome sequencer
-- in 1 : clock
-- in 2 : refresh sequence
-- out 1 : primary pitch (locked sequence)
-- out 2 : primary ENV
-- out 3 : secondary ENV
-- out 4 : secondary pitch (random sequence)
public.scale = { 0, 2, 3, 5, 7, 9, 10 }
public.length = 16
public.max = 33
local i = 1
local seq = {}
local rest_a = 0
local rest_b = 0
local function rand_seq()
rest_a = math.random(public.max, 1)
rest_b = math.random(public.max, 1)
local spacer = math.random((public.length / 2) + 1, 1)
for n = 1, (public.length / 4) do
local note = math.random(public.max, 1)
seq[n] = note
seq[(n + spacer)] = note
end
end
local function play_seq()
local ENV = ar(0.1, 0.5, 5, "expo")
if seq[i] == rest_a or seq[i] == rest_b or seq[i] == nil then
output[4].volts = math.random(21, 1) / 12
output[3](ENV)
else
output[1].volts = (seq[i] / 12)
output[2](ENV)
end
i = (i % public.length) + 1
end
function init()
for n = 1, 2 do
input[n].mode("change")
end
output[1].scale = { public.scale }
output[4].scale = { public.scale }
rand_seq()
end
input[1].change = play_seq
input[2].change = rand_seq
--- rotating harmonic sampling quantizer
-- input[1] voltage to be sampled
-- input[2] trigger/gate in
-- output[1-4] chromatical cv out with rotation & harmonic relation
-- helper functions
local function scale_outputs(x)
for n = 1, 4 do
output[n].scale(x)
end
end
local function update_buffer(root)
local new_buffer = {
root,
root + public.interval[1],
root + public.interval[2],
root + public.interval[3],
}
return new_buffer
end
local function rotate_buffer(old_buffer)
local new_buffer = {
old_buffer[2],
old_buffer[3],
old_buffer[4],
old_buffer[1],
}
return new_buffer
end
local function round(num, decimals)
local mult = 10 ^ (decimals or 0)
return math.floor(num * mult + 0.5) / mult
end
-- public vars
-- add post s&h quantization if desired
public({ { output_scale = {} } }):action(scale_outputs)
-- four presets
public({ one = { 1, 2, 3 } })
public({ two = { 7 / 12, 14 / 12, 21 / 12 } })
public({ three = { 4 / 12, 19 / 12, 26 / 12 } })
public({ four = { 3 / 12, 19 / 12, 22 / 12 } })
-- choose active preset
public.interval = public.one
-- and action
DEFAULT = input[1].volts
BUFFER = update_buffer(DEFAULT)
PREV_SAMPLE = DEFAULT
function init()
input[2]({ mode = "change", direction = "rising" })
scale_outputs(public.output_scale)
end
-- main action
input[2].change = function()
local sample = input[1].volts
-- remove the "noise" so it can accurately tell
-- if the voltage has changed or not
local sample_r = round(sample / 12, 2)
local prev_sample_r = round(PREV_SAMPLE / 12, 2)
if sample_r == prev_sample_r then
BUFFER = rotate_buffer(BUFFER)
else
BUFFER = update_buffer(sample)
PREV_SAMPLE = sample
end
output[1].volts = BUFFER[1]
output[2].volts = BUFFER[2]
output[3].volts = BUFFER[3]
output[4].volts = BUFFER[4]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment