Norns 2.0: softcut

I wonder if it’s the same quirk that produces the strange behavior that when I import a clip that’s length is tempo synced to MLR’s set tempo, it still plays at slightly different speed resulting in a slightly different pitch (very slightly, a semi tone or close I think) which means I then have to dial down the pitch to go back to the right tempo / tune (rendering the tempo sync of MLR kind of pointless)

we are work on this right this very minute!


Peeeeeerfect timing, then :slight_smile:

This kind of thing just makes this community feel like a warm, welcoming place.


Something weird happened between 2.0.1 and 2.1.0, loop points are off, reason is unclear, i willl hunt it down ASAP (tonight/tomorrow)


And I’m back with another newbie question. I’m assuming the answer is no (given the current softcut docs), but is there a way of applying a slew time to pan like you can with level and rate ?

hm, this is an oversight.

there are slew controls on softcut voice pan, as well as on all mixing route levels.

somehow i didn’t add commands to change any of those slew times from lua, but will do so.


Great! Thanks for clarifying @zebra

Me again :sweat_smile: I’m exploring adding a param to my softcut script for manipulating rate, and despite everything working just fine (to my ears, anyways), I’m getting the following error when I call a function specific to my script intended to change the rate:

/home/we/norns/lua/core/softcut.lua:49: bad argument #3 to 'cut_param' (number expected, got nil)
stack traceback:
	[C]: in field 'cut_param'
	/home/we/norns/lua/core/softcut.lua:49: in function 'core/softcut.rate'
	/home/we/dust/code/dunes/dunes-cut-2.lua:54: in field '?'
	/home/we/dust/code/dunes/dunes-cut-2.lua:145: in field 'event'
	/home/we/norns/lua/core/metro.lua:165: in function </home/we/norns/lua/core/metro.lua:162>

I followed that path to lua/core/softcut, line 49:

SC.rate = function(voice,value) _norns.cut_param("rate",voice,value) end

And for context, the error is triggered when I call this specific function in my script:

function rateN() for i=1,2 do softcut.rate(i,params:set("RATE",math.random(1,4)))

Is there something specific I need to do when creating my param in order to assign something to the value variable in cut_param?

Does params:set return a value here? If not, assign the rate to a variable and set it first, then use the variable in softcut.rate()?

Or maybe - do you have an action assigned for the "rate" param? (also confused by “rate” vs “RATE” - not sure if that needs to be consistent case or not)

1 Like

Thanks @okyeron ! I’ll fully admit that my params work this morning was sloppy. I’ll take another crack at this today with your ideas in mind.

I may not actually know what I’m talking about here since I’ve not worked with softcut much - so please take my advice/ideas with a grain of salt. :laughing:

Yeah, this one definitely has me stumped, especially because my code is having its intended effect. I have a variable in my script that I’m assigning the changing rate values to, which works just fine. I only started seeing this error when I implemented the param. I think I’ll swim back to shallow waters, at least for now!

can you show the code where you declare the parameter?

anyway, broadly speaking the problem is that params don’t work that way and param:set() returns nil.

when you create a param, you assign an “action” function to it, and this will be executed when you call :set on that param.

this adds two parameters for rate:

for i=1,2 do
  local param_fn = function(val) softcut.rate(i, val) end
  params:add{type="control", id="RATE_"..i, controlspec=cs_RATE, action=param_fn}

and then the randomizing function:

function rateN() 
  for i=1,2 do
    params:set("RATE_"..i, math.random(1,4)

the parameter actions are automatically invoked.


@zebra First off, thanks again for helping out. Here’s the (probably confusing/messy) code where I declare the param:

params:set_action("rate", function(x) rate = rates[x]  end)

I’m using a table in my script (rates) to store specific rate values (i.e. 0.5, 1, 2, 4, etc.), and the general idea was to use the param to select an index in that table. In my limited understanding of params, I didn’t catch that param:set would execute the function associated with set_action.

Anywho, your explanation and code examples clarify things. I’ll give this another spin.

here’s an alternative take/syntax:

function init()
  params:add{id="rate12", name="rate12", type="control",,4.0,'lin',0,1,""),

rates = {0.5,1,2,4}

function rateN()
  params:set("rate12", rates[math.random(1,4))

Thanks! I think this is doing the trick.


I’m trying to get my head around the wonderful norns.

Coming to it from a background of using Supercollider, primarily for the processing of live audio, I’m looking right now at whether I can actually simply use softcut and lua.

I have a few - hopefully simple - questions.

Am I right in thinking that 1.0 as a softcut.position / softcut.loop_start is actually 0.0 seconds in terms of the soundfile ? In your annotation soft cut.loop_start(1,1) is noted as start @ 1.0s, similarly for position. But when I use these values my file plays from the top, not one second in.

How does one get information on the soundfile ? I’ve tried using audio.file_info but get blank values, e.g. duration: nan sec

Is fade the equivalent of attack and release times on an envelope ?

I’ve tried experiments to determine the answer to these questions but am still not quite sure !





A question about modulating level:

I’m trying to modulate a voice’s level from 0 to 1.0 over a period of time. I assumed that softcut.level_slew_time would do this in the same way that softcut.rate_slew_time modulates between two rates (as in softcut studies 2-multi.lua).

Is this correct ? I can’t get it to work.