Norns 2.0: softcut

a thread to discuss softcut on norns 2.0

replaces: Norns 1.0: softcut

now that we have a Norns 2.0 beta, looks like a lot of great stuff has changed with softcut! particularly excited that it’s now system-level, which allows it run alongside other audio engines.

I tried updating cranes last night, but I think the combo of the changes and my prior misunderstandings of the original syntax did not make for successful translation.

@zebra, if syntax is not expected to change drastically along the beta phase, would you be able to share a quick ‘getting started’ for scripting with softcut?


check out /norns/lua/softcut/halfsecond.lua

i can help look at cranes with you also.


dope, ty :hugs:.

for the curious:

-- half sec loop 75% decay

local sc = {}

function sc.init()
  print("starting softcut/halfsecond")
	softcut.level_input_cut(1, 1, 1.0)
	softcut.level_input_cut(1, 2, 1.0)
	softcut.pan(1, 0.5), 1)
	softcut.rate(1, 1)
	softcut.loop_start(1, 1)
	softcut.loop_end(1, 1.5)
	softcut.loop(1, 1)
	softcut.fade_time(1, 0.1)
	softcut.rec(1, 1)
	softcut.rec_level(1, 1)
	softcut.pre_level(1, 0.75)
	softcut.position(1, 1)
	softcut.enable(1, 1)

	softcut.filter_dry(1, 0.125);
	softcut.filter_fc(1, 1200);
	softcut.filter_lp(1, 0);
	softcut.filter_bp(1, 1.0);
	softcut.filter_rq(1, 2.0);

  local p = softcut.params()

return sc

I was looking at halfsecond last night, but couldn’t get any action when I tried running it. will revisit tonight and likely will DM.

E, you’re off the hook!


this file (and the other in lua/softcut/) don’t get run directly. they get included into other scripts.

you can live-add these like this

h = require 'halfsecond'

basically the important part is this initialization, a series of softcut commands (i’ve annotated with comments):

	audio.level_cut(1.0) -- softcut master level (same as in LEVELS screen)
	audio.level_adc_cut(1) -- adc to softcut input
	audio.level_ext_cut(1) -- ext (sc) to softcut input
    softcut.level(1,1.0) -- softcut voice 1 output level
	softcut.level_input_cut(1, 1, 1.0) -- softcut input level ch 1
	softcut.level_input_cut(1, 2, 1.0) -- softcut input level ch 2
	softcut.pan(1, 0.5) -- softcut voice 1 pan center, 1) -- voice 1 play on
	softcut.rate(1, 1) -- voice 1 rate 1.0
	softcut.loop_start(1, 1) -- voice 1 loop start @ 1.0s
	softcut.loop_end(1, 1.5) -- voice 1 loop end @ 1.5s
	softcut.loop(1, 1) -- voice 1 enable loop
	softcut.fade_time(1, 0.1) -- voice 1 fade time
	softcut.rec(1, 1) -- voice 1 enable record
	softcut.rec_level(1, 1) -- voice 1 record level
	softcut.pre_level(1, 0.75) -- voice 1 prerec (overdub) level 0.75
	softcut.position(1, 1) -- voice 1 set position 1.0s
	softcut.enable(1, 1) -- enable voice 1

	softcut.filter_dry(1, 0.125); -- voice 1 filter settings...
	softcut.filter_fc(1, 1200);
	softcut.filter_lp(1, 0);
	softcut.filter_bp(1, 1.0);
	softcut.filter_rq(1, 2.0);

oh, for sure – apologies, I wasn’t clear. I took the meaty init bits and threw them into a simple script, but couldn’t get things moving. I’ll revisit, as it was a 10:30pm couch sesh. not always conducive to my best coding work :wink:

also, dang, thank you for the annotations! that is immensely helpful. <3

when you have maiden running check out norns.local/docs and i did some similar/loose comments on the entire softcut API (in case i missed something above)

we’re (@ppqq @okyeron @jasonw22) working on a “programming reference” similar to the TT reference sheets. and i’m hoping to get together a new norns study devoted to softcut soon.

just to say, softcut+lua is an total dream come true— it was the guiding design goal for the entire norns project. now that it’s been optimized and refined i’m pretty ecstatic @zebra

time for new sounds!+++++++


is it possible to address 2 softcut voices with one command in the maiden repl?

you’d have to make your own multi-voice functions ie

function both_positions(x)

but you could also just do:

for v=1,2 do

where 1,2 are the start/end voice numbers, x is the position/value


New softcut is rad. I thought putting echo on a piano was corny but as a varispeed loop pedal with rec/play toggles it’s pretty rad. Recorded a little thing starting with the halfsecond lib and fussing around with maiden params. I think I need a MIDI foot pedal board now.


i don’t know if norns will recognize it but i use an HID usb footswitch with my expert sleepers fh-1 and its great and VERY cheap: 35 euros for dual footswitch! its from scythe, you can find it easily on amazon or similar.

all HID devices should be usable though you may need trial+error to determine correct event codes for a particular device
[ ]

this looks interesting too:

If you want to grab my HID demo scripts, you can plug in the footswitch and run the hid-events.lua script and look at the output in Maiden (while triggering the switch). This should get you started to figure out the code the switch is sending. :slight_smile:


Does this look correct? I get a loud buzz when its turned to 1 in the param menu. Would it be better to just turn the volume of the voices down?

 function both_enables(x)

params:add{type = "number", id = "both_enables", name = "enables",
  min=0, max=1, default = 1,
  action = function(x) both_enables(x) end}

well, did you do anything else to set the parameters of those voices, as in the halfsecond lib/example? is this on top of halfsecond?

use enable flag if you want to completely stop/start processing per voice (consume no CPU when off). the param mapping looks plausibly correct, but it is probably not something you want to modulate (hard clicks will occur.)

1 Like

@rdfm you’ll need to set a bunch of default param values. just enabling it will mean it’s in a somewhat unknown state.

1 Like

i’m not sure when this thread was created, stuff merged &c, but i’m seeing a lot of recent reactions to older posts. so, wanted to point out that all my statements before march 2019 refer to a completely different and more limited version of softcut than the current one. specific references to implementation details no longer apply.

see here for current lua syntax to control softcut parameters
[ ]

these map pretty directly to OSC commands understood by the crone audio process:
[ ]


Say I wanted to add ‘halfsecond’ or something similar to a script, but didn’t want it to immediately start up, but wanted to be able to selectively turn it on/off.

How would I go about this?


softcut is a lot of fun! excited for some docs on the parameters, but just changing values and commenting things in and out is a little treasure hunt. here is a super minimal multi-tap ping-pong delay based on halfsecond.

brass synth pulse from a repeating ableton clip running into norns

-- multitap delay using softcut

function init_sc()

  for i=1,3 do
    softcut.level(i, 1.0), 1)
  	softcut.rate(i, 1)
  	softcut.position(i, 1 + (.2 * i))
  	softcut.pan(i, -.5 + (.5 * i))
  	softcut.enable(i, 1)

function init()

EDIT: just wanted to say this relied on some setup code that half-second had which I didn’t realize I needed. Resetting audio will make this script not work. I’m working on a more sophisticated multi-tap thing right now…will share when that’s finished.