Skip to content

Instantly share code, notes, and snippets.

@catfact
Last active January 30, 2025 19:00
Show Gist options
  • Save catfact/484d275eee2110484d36c2a1099c8dcd to your computer and use it in GitHub Desktop.
Save catfact/484d275eee2110484d36c2a1099c8dcd to your computer and use it in GitHub Desktop.
minimal stereo looper to test softcut voice drift
--- test softcut voice sync
--- extremely basic stereo looper
---
--- K2: toggle recording
--- K3: reset to loop start
local s = softcut
local BUFFER_OFFSET = 0.1
state = {
loop_set = false,
recording = false,
loop_end = s.BUFFER_SIZE - BUFFER_OFFSET - 0.1
}
function softcut_setup()
s.buffer_clear()
s.enable(1, 1)
s.enable(2, 1)
s.buffer(1, 1)
s.level_input_cut(1, 1, 1)
s.level_input_cut(2, 1, 0)
s.pan(1, -1)
s.rate(1, 1)
s.loop(1, 0)
s.buffer(2, 2)
s.level_input_cut(2, 2, 1)
s.level_input_cut(1, 2, 0)
s.pan(2, 1)
s.rate(2, 1)
s.loop(2, 0)
s.pre_level(1, 0)
s.pre_level(2, 0)
s.rec_level(1, 0)
s.rec_level(2, 0)
s.rec(1, 1)
s.rec(2, 1)
s.play(1, 1)
s.play(2, 1)
s.level(1, 1)
s.level(2, 1)
s.loop_start(1, BUFFER_OFFSET)
s.loop_start(2, BUFFER_OFFSET)
s.loop_end(1, state.loop_end)
s.loop_end(2, state.loop_end)
end
function toggle_record()
if state.recording then
finish_recording()
else
begin_recording()
end
end
function reset_position()
s.position(1, BUFFER_OFFSET)
s.position(2, BUFFER_OFFSET)
print("reset")
end
function begin_recording()
s.position(1, BUFFER_OFFSET)
s.position(2, BUFFER_OFFSET)
s.rec_level(1, 1)
s.rec_level(2, 1)
state.start_time = util.time()
state.recording = true
print("begin_recording...")
redraw()
end
function finish_recording()
s.rec_level(1, 0)
s.rec_level(2, 0)
s.pre_level(1, 1)
s.pre_level(2, 1)
local dt = util.time() - state.start_time
state.loop_end = BUFFER_OFFSET + dt
s.loop_end(1, state.loop_end)
s.loop_end(2, state.loop_end)
s.loop(1, 1)
s.loop(2, 1)
s.position(1, BUFFER_OFFSET)
s.position(2, BUFFER_OFFSET)
state.recording = false
state.loop_set = true
redraw()
end
------------------------------------
-- norns API bindings
init = function()
softcut_setup()
end
key = function(n,z)
if z == 1 then
if n == 2 then
toggle_record()
end
if n == 3 then
reset_position()
end
end
end
redraw = function()
screen.clear()
screen.level(15)
screen.move(10, 10)
if state.recording then
screen.text("recording...")
elseif state.loop_set then
screen.text("loop set; duration: ")
screen.move(10, 20)
screen.text(state.loop_end - BUFFER_OFFSET)
else
screen.text("ready")
end
screen.update()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment