I combined Spacetime with @burn’s KarplusRings engine. I also made it so that button 2 resets all steps to default.
-- spacetime with rings
-- norns study 3
--
-- ENC 1 - change brightness
-- ENC 2 - select edit position
-- ENC 3 - choose command
-- KEY 2 - return commands to default
-- KEY 3 - randomize command set
--
-- spacetime is a weird function sequencer.
-- it plays a note on each step
-- each step is a symbol for the action.
-- + = increase note
-- - = decrease note
-- < = go to bottom note
-- > = go to top note
-- * = random note
-- M = fast metro
-- m = slow metro
-- # = jump random position
--
-- augment/change this script
-- with new functions!
-- this mod adds burn's
-- excellent KarplusRings
-- engine
engine.name = "KarplusRings"
local cs = require 'controlspec'
note = 40
position = 1
step = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}
STEPS = 16
edit = 1
function inc() note = util.clamp(note + 5, 40, 120) end
function dec() note = util.clamp(note - 5, 40, 120) end
function bottom() note = 40 end
function top() note = 120 end
function rand() note = math.random(80) + 40 end
function metrofast() counter.time = 0.125 end
function metroslow() counter.time = 0.25 end
function positionrand() position = math.random(STEPS) end
act = {inc, dec, bottom, top, rand, metrofast, metroslow, positionrand}
COMMANDS = 8
label = {"+", "-", "<", ">", "*", "M", "m", "#"}
function init()
cs.AMP = cs.new(0,1,'lin',0,0.75,'')
params:add_control("amp",cs.AMP)
params:set_action("amp",
function(x) engine.amp(x) end)
engine.amp(0.75)
cs.DECAY = cs.new(0.1,15,'lin',0,3.6,'s')
params:add_control("damping",cs.DECAY)
params:set_action("damping",
function(x) engine.decay(x) end)
cs.COEF = cs.new(0,1,'lin',0,0.11,'')
params:add_control("brightness",cs.COEF)
params:set_action("brightness",
function(x) engine.coef(x) end)
cs.LPF_FREQ = cs.new(100,10000,'lin',0,3600,'')
params:add_control("lpf_freq",cs.LPF_FREQ)
params:set_action("lpf_freq",
function(x) engine.lpf_freq(x) end)
engine.lpf_freq(3600.0)
cs.LPF_GAIN = cs.new(0,3.2,'lin',0,0.5,'')
params:add_control("lpf_gain",cs.LPF_GAIN)
params:set_action("lpf_gain",
function(x) engine.lpf_gain(x) end)
cs.BPF_FREQ = cs.new(100,10000,'lin',0,1200,'')
params:add_control("bpf_freq",cs.BPF_FREQ)
params:set_action("bpf_freq",
function(x) engine.bpf_freq(x) end)
engine.bpf_freq(1200.0)
cs.BPF_RES = cs.new(0,4,'lin',0,0.5,'')
params:add_control("bpf_res",cs.BPF_RES)
params:set_action("bpf_res",
function(x) engine.bpf_res(x) end)
counter = metro.alloc(count, 0.125, -1)
counter:start()
end
function count()
position = (position % STEPS) + 1
act[step[position]]()
engine.hz(midi_to_hz(note))
redraw()
end
function redraw()
screen.clear()
for i = 1,16 do
screen.level((i == edit) and 15 or 2)
screen.move(i*8-8,40)
screen.text(label[step[i]])
if i == position then
screen.move(i*8-8, 45)
screen.line_rel(6,0)
screen.stroke()
end
end
screen.update()
end
function enc(n,d)
if n == 1 then
params:delta("brightness", d)
elseif n == 2 then
edit = util.clamp(edit + d, 1, STEPS)
elseif n ==3 then
step[edit] = util.clamp(step[edit]+d, 1, COMMANDS)
end
redraw()
end
function key(n,z)
if n == 2 and z == 1 then
init_steps()
end
if n == 3 and z == 1 then
randomize_steps()
end
end
function midi_to_hz(note)
return (440/32) * (2 ^ ((note - 9) / 12))
end
function randomize_steps()
for i= 1,16 do
step[i] = math.random(COMMANDS)
end
end
function init_steps()
for i= 1,16 do
step[i] = 1
end
end