My apologies if this has been asked often, but I can’t seem to find whether one can reverse the playing direction of a loop. I tried setting a negative rate with softcut.rate(1, -1) but that did not work…

that should work. share script?

You are absolutely right, it works. Made a rookie’s mistake, I was storing the rates of the voices in a table, and forgot to update softcut.rate besides updating the table. First day diving into softcut :sweat_smile:

Having a blast though, thanks @zebra for this beautiful tool and @tehn for this encouraging quest!

4 Likes

tomorrow, saturday 2/29, 3-5pm EST i’ll be live-posting progress on my script here, for the curious. unless there are questions to answer, which i certainly hope there are— and we can get into whatever people are interested in. for example, if anyone needs a github tutorial?

deadline for submission is march 1 (sunday) end of day.

while it might feel too late if you’ve never written a script, this first prompt is structured to be as straightforward as possible with some flexibility for creativity. even if you don’t finish, wading through the steps of just editing a script will be a motivating start of the journey.

learning a new skill:

  • have a project that requires it
  • a deadline
  • somewhere to go for help

while circle is primarily an exercise in collective creation, it’s designed also to introduce new people to this incredibly empowering knowledge.

so, consider it! you can make something nobody thought of before.

12 Likes

thx for the supportive words!
Spent a while trying to figure out a question to start with. So a fun one—figuring out how to work with time in norns? For example, the scrubbing script was really fun to try with the provided samples; would be fun to automate the playback position and grain size. I.e. “evolve” could be a timed scrub forward through the material. First thought was to write a fast metro loop function? Unless perhaps there’s something like crow’s ASL in the norns api.
I’m not pulling my hair out over this as it feels just out of my scope of knowledge—It’s a cool experience to join in with you all though, getting deeper into monome-world over the past year has been really enlightening :pray:t2:

my loose plan is essentially to make several arrays of functions giving commands to softcut that are looped over inside a metro. it’s a pretty simple thing to implement and probably has a lot of expressive potential.

untested starting point !

loop_start = 0
loop_size = 0.05
scrub_rate = 0.001

m = metro.init(function()
    softcut.loop_start(1, loop_start)
    softcut.loop_end(1, loop_start + loop_size)
    loop_start = loop_start +  scrub_rate
end, 0.01):start()

combine that with something like technique above to mess with those variables, and maybe you’ve got yourself a world

2 Likes

I plan to work on this today. I have an idea that is fairly fun, should exercise a little softcut, and fit into the time I have. I also have no idea if it’ll work or not until I see it. So I’m going to start there. Also as with a lot of my Norns ideas, some of the idea is visual, so I’ll be chucking around some Vector2s.

I could say two words that would give the thing away, but I’ll wait until I hit the realisation of the idea first.

1 Like

Haven’t started on this, or the softcut studies, and not sure where to begin. (Currently/slowly working through the norns studies, with no previous code experience) Things are slowly making a bit of sense, but I’ll likely have to loop back to this in the coming weeks/months.

Just chiming in to say that this is such a cool thing for the community, and that I installed the script and am just listening to it drone and evolve and turn back and grin. Lovely, lovely.

I have the audio side of it almost where I want - I need to understand routing to finish it. My plan is to write a small standalone toy to practice, before I fiddle with my three drones any more, and hopefully come up with some feedback for the docs / studies.

As for the visual part, I’m at a loss right now.

See you later!

Nearly done with UI. Yes, it’s UI.

now onto sounds.

26 Likes

copy+paste worked brilliantly. I appreciate it so much! Can’t wait to go deeper.

@infovore that looks so cool

No clue how to vector. But I saw that png function in the API and want to mess with.

Good luck to all of you. See you back on earth in a few…

you can probably guess the two words that would have given the game away.

It’s fun to play, though.

Each world exists simultaneously.
Encoder 1 controls volume (and brightness of stars)
Encoder 2 controls “brightness” (filter / planetary body position)
Encoder 3 controls “density” (number of items in landscape)

Key 2 “evolves”, picking a new start point in the sample and reseeding the objects in the world.
Key 3 swaps worlds.

At the start, only World 1 has volume up.

Each world runs at a slightly different rate.

PR coming soon.

20 Likes

made my own version of seeker for finding combos of sample/rate/start/length and print them in lua table format. maybe perhaps helpful to someone that’s not me

--[[

* fun spots *

{ rate = 1.0, start = 3.73, len = 2.22, sample = 2, }

]]--

local tabutil = require 'tabutil'

mem = {}
voices = 1
scrub = 0.01
slew = 0.2
samples = { "bc", "dd", "eb" }

function init()
  mem = {
    rate = 1,
    start = 0,
    len = 0.1,
    sample = 1,
  }
  
  softcut.enable(1,1)
  softcut.buffer(1,1)
  softcut.level(1,1.0)
  softcut.loop(1,1)
  softcut.position(1,1)
  softcut.play(1,1)
  softcut.rate_slew_time(1, slew)
  
  loadsamp()
  upd8()
end

function printmem()
  local text = "{ "
  for k,v in pairs(mem) do
    text = text .. k .. " = " .. tostring(v) .. ", "
  end
  
  print(text .. "},")
end

function upd8()
    softcut.rate(1, mem.rate)
    softcut.loop_start(1, mem.start)
    softcut.loop_end(1, mem.start + mem.len)
    
    printmem()
  redraw()
end

function loadsamp()
  file = _path.code .. "nc01-drone/lib/" .. samples[mem.sample] .. ".wav"
  softcut.buffer_read_mono(file,0,0,-1,1,1)
end

function enc(n, d)
  if n == 1 then
    if d > 0 then 
      mem.rate = mem.rate * 2 
    elseif d < 0 then
      mem.rate = mem.rate * 0.5
    end
    
    upd8()
  elseif n == 2 then
    mem.start = mem.start + (d * scrub)
    
    upd8()
  elseif n == 3 then
    mem.len = mem.len + (d * scrub)
    
    upd8()
  end
end

function key(n, z)
  if z == 1 then
    if n == 3 then
      if mem.sample == #samples then
        mem.sample = 1
      else
        mem.sample = mem.sample + 1
      end
    elseif n == 2 then
      if mem.sample == 1 then
        mem.sample = #samples
      else
        mem.sample = mem.sample - 1
      end
    end
    
    loadsamp()
    upd8()
  end
end

function redraw()
  screen.clear()
  local i = 1
    
  for k,v in pairs(mem) do
    screen.move(4, i * 12)
    screen.text(k .. " " .. tostring(v))
    i = i + 1
  end
  
  screen.update()
end

in the end, I ended up doing nothing with vectors, and just using plain old line art and that’s about it. You’ll see in the code in due course!

2 Likes

will not be available from 3-5pm but willing to share my notes so far

global vol : E1
brightness: E2 “pitch”
density: E3 “delay time”
evolve: K2 “sequential read position”
worlds: K3 “rand read pos” + “rand loop length”?

no idea how i’ll represent this on screen or how to handle those controls yet
mabye by tomorrow if i can carve out time late tonight

1 Like
progress
collection1 = {
{ rate = 1.0, start = 3.73, len = 2.22, sample = 2, },
{ rate = 2.0, start = 8.7, len = 3.16, sample = 2, },
{ rate = 1.0, start = 21.29, len = 1.78, sample = 2, },
{ rate = 1.0, start = 24.39, len = 1.78, sample = 2, },
{ rate = 2.0, start = 28.86, len = 1.1, sample = 2, },
{ rate = 1.0, start = 30.32, len = 1.1, sample = 2, },
{ rate = 1.0, start = 31.47, len = 1.1, sample = 2, },
{ rate = 2.0, start = 31.47, len = 1.1, sample = 2, },
{ rate = 1.0, start = 32.62, len = 1.1, sample = 2, },
{ rate = 2.0, start = 32.55, len = 0.86000000000002, sample = 2, },
{ rate = 1.0, start = 32.55, len = 0.86000000000002, sample = 2, },
{ rate = 2.0, start = 38.91, len = 2.41, sample = 2, },
{ rate = 1.0, start = 41.77, len = 5.57, sample = 2, },
{ rate = 2.0, start = 46.96, len = 5.25, sample = 2, },
{ rate = 1.0, start = 47.64, len = 1.19, sample = 2, },
{ rate = 1.0, start = 54.31, len = 3.49, sample = 2, },
{ rate = 2.0, start = 59.28, len = 6.3300000000001, sample = 2, },
{ rate = 0.5, start = 66.090000000001, len = 5.5900000000001, sample = 2, },
{ rate = 1.0, start = 82.350000000002, len = 7.8100000000001, sample = 2, },
{ rate = 1.0, start = 100.91, len = 6.6800000000001, sample = 2, },
{ rate = 1.0, start = 103.69, len = 3.8100000000001, sample = 2, },
{ rate = 1.0, start = 111.17000000001, len = 4.9000000000001, sample = 2, },
{ rate = 1.0, start = 119.18000000001, len = 5.8500000000001, sample = 2, },
{ rate = 2.0, start = 119.18000000001, len = 5.8500000000001, sample = 2, },
{ rate = 1.0, start = 128.32000000001, len = 0.38000000000008, sample = 2, },
{ rate = 1.0, start = 133.67000000001, len = 0.010000000000083, sample = 2, },
{ rate = 1.0, start = 126.24000000001, len = 0.010000000000083, sample = 2, },
{ rate = 1.0, start = 125.49000000001, len = 0.010000000000083, sample = 2, },
{ rate = 1.0, start = 121.79000000001, len = 0.010000000000083, sample = 2, },
{ rate = 1.0, start = 113.14000000001, len = 0.010000000000083, sample = 2, },
{ rate = 1.0, start = 111.99000000001, len = 0.010000000000083, sample = 2, },
{ rate = 1.0, start = 112.12000000001, len = 0.18000000000008, sample = 2, },
{ rate = 2.0, start = 89.460000000004, len = 0.37000000000008, sample = 2, },
{ rate = 2.0, start = 83.210000000004, len = 0.32000000000008, sample = 2, },
{ rate = 1.0, start = 80.950000000004, len = 0.60000000000008, sample = 2, },
{ rate = 2.0, start = 80.710000000003, len = 0.60000000000008, sample = 2, },
{ rate = 1.0, start = 80.710000000003, len = 0.60000000000008, sample = 2, },
{ rate = 1.0, start = 78.970000000003, len = 0.73000000000008, sample = 2, },
{ rate = 1.0, start = 75.100000000003, len = 1.3200000000001, sample = 2, },
{ rate = 2.0, start = 72.180000000002, len = 1.3200000000001, sample = 2, },
{ rate = 2.0, start = 69.780000000002, len = 1.3200000000001, sample = 2, },
{ rate = 1.0, start = 68.680000000002, len = 1.4300000000001, sample = 2, },
{ rate = 1.0, start = 68.360000000002, len = 1.1800000000001, sample = 2, },
{ rate = 1.0, start = 68.360000000002, len = 1.1800000000001, sample = 2, },
{ rate = 1.0, start = 53.170000000002, len = 1.1700000000001, sample = 2, },
{ rate = 2.0, start = 47.860000000002, len = 1.3200000000001, sample = 2, },
{ rate = 1.0, start = 46.490000000002, len = 0.92000000000008, sample = 2, },
{ rate = 1.0, start = 45.480000000002, len = 0.92000000000008, sample = 2, },
{ rate = 1.0, start = 40.820000000002, len = 0.20000000000008, sample = 2, },
{ rate = 2.0, start = 31.150000000002, len = 1.6700000000001, sample = 2, },
{ rate = 1.0, start = 31.150000000002, len = 1.6700000000001, sample = 2, },
{ rate = 1.0, start = 29.510000000002, len = 1.6700000000001, sample = 2, },
{ rate = 2.0, start = 26.310000000002, len = 1.9800000000001, sample = 2, },
{ rate = 1.0, start = 22.800000000002, len = 1.9800000000001, sample = 2, },
{ rate = 1.0, start = 20.420000000002, len = 1.9800000000001, sample = 2, },
{ rate = 2.0, start = 18.360000000002, len = 0.44000000000008, sample = 2, },
{ rate = 2.0, start = 8.1300000000017, len = 0.42000000000008, sample = 2, },
{ rate = 1.0, start = 5.1600000000017, len = 0.42000000000008, sample = 2, },
{ rate = 2.0, start = 5.1600000000017, len = 0.42000000000008, sample = 2, },
{ rate = 1.0, start = 0.29000000000168, len = 0.42000000000008, sample = 2, },
{ rate = 1.0, start = 0.29000000000168, len = 0.42000000000008, sample = 2, },
}

collection2 = {
{ rate = 0.25, start = 0.59, len = 12.64, sample = 1, },
{ rate = 0.25, start = 5.01, len = 23.03, sample = 1, },
{ rate = 0.25, start = 5.01, len = 23.03, sample = 1, },
{ rate = 0.5, start = 9.46, len = 8.8499999999998, sample = 1, },
{ rate = 0.25, start = 9.46, len = 8.8499999999998, sample = 1, },
{ rate = 0.5, start = 107.94, len = 1.3699999999998, sample = 1, },
{ rate = 0.5, start = 108.91, len = 2.2299999999998, sample = 1, },
{ rate = 0.25, start = 111.62, len = 3.8799999999998, sample = 1, },
{ rate = 0.5, start = 118.37, len = 1.4099999999998, sample = 1, },
{ rate = 0.5, start = 110.92, len = 1.1799999999998, sample = 1, },
{ rate = 0.5, start = 150.11, len = 3.2899999999998, sample = 1, },
{ rate = 0.5, start = 152.95, len = 5.0699999999998, sample = 1, },
{ rate = 0.5, start = 156.94000000001, len = 6.8399999999998, sample = 1, },
{ rate = 0.25, start = 156.17000000001, len = 7.2199999999998, sample = 1, },
}

collection3 = {
  { rate = 1.0, start = 26.55, len = 0.21999999999977, sample = 1, },
  { rate = 0.5, start = 26.55, len = 0.22999999999977, sample = 1, },
  { rate = 1.0, start = 26.4, len = 1.0599999999998, sample = 1, },
  { rate = 1.0, start = 27.87, len = 2.4099999999998, sample = 1, },
  { rate = 1.0, start = 33.27, len = 2.4099999999998, sample = 1, },
  { rate = 1.0, start = 35.14, len = 1.3599999999998, sample = 1, },
  { rate = 1.0, start = 34.5, len = 0.039999999999769, sample = 1, },
  { rate = 1.0, start = 32.69, len = 0.039999999999769, sample = 1, },
  { rate = 0.5, start = 31.61, len = 0.53999999999977, sample = 1, },
  { rate = 1.0, start = 31.07, len = 0.53999999999977, sample = 1, },
  { rate = 0.5, start = 30.52, len = 0.53999999999977, sample = 1, },
  { rate = 1.0, start = 30.65, len = 0.53999999999977, sample = 1, },
  { rate = 1.0, start = 30.87, len = 0.53999999999977, sample = 1, },
  { rate = 1.0, start = 30.9, len = 0.53999999999977, sample = 1, },
  { rate = 1.0, start = 29.44, len = 0.53999999999977, sample = 1, },
  { rate = 1.0, start = 30.71, len = 0.53999999999977, sample = 1, },
  { rate = 1.0, start = 31.66, len = 1.1299999999998, sample = 1, },
  { rate = 1.0, start = 31.27, len = 1.1299999999998, sample = 1, },
  { rate = 0.5, start = 37.75, len = 0.68999999999977, sample = 1, },
  { rate = 0.5, start = 38.41, len = 0.85999999999977, sample = 1, },
  { rate = 0.5, start = 39.8, len = 0.85999999999977, sample = 1, },
  { rate = 0.25, start = 42.45, len = 0.85999999999977, sample = 1, },
  { rate = 0.5, start = 44.75, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 49.78, len = 0.25999999999977, sample = 1, },
  { rate = 1.0, start = 49.78, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 55.05, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 56.38, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 56.38, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 56.51, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 56.95, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 60.09, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 65.45, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 66.05, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 67.63, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 73.040000000001, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 76.140000000001, len = 0.25999999999977, sample = 1, },
  { rate = 0.5, start = 82.560000000002, len = 0.18999999999977, sample = 1, },
  { rate = 0.5, start = 83.720000000002, len = 0.18999999999977, sample = 1, },
  { rate = 0.5, start = 82.940000000002, len = 0.18999999999977, sample = 1, },
  { rate = 0.5, start = 89.030000000003, len = 0.18999999999977, sample = 1, },
  { rate = 0.5, start = 87.600000000002, len = 0.17999999999977, sample = 1, },
  { rate = 0.5, start = 89.990000000003, len = 1.4099999999998, sample = 1, },
  { rate = 0.5, start = 93.500000000003, len = 1.4099999999998, sample = 1, },
  { rate = 0.5, start = 92.180000000003, len = 2.3799999999998, sample = 1, },
  { rate = 1.0, start = 93.850000000003, len = 0.88999999999977, sample = 1, },
  { rate = 1.0, start = 98.430000000003, len = 1.5199999999998, sample = 1, },
}

collection4 = {
  { rate = 0.25, start = 114.44, len = 1.9899999999998, sample = 1, },
  { rate = 0.25, start = 115.59, len = 1.7599999999998, sample = 1, },
  { rate = 0.5, start = 123.05000000001, len = 1.0499999999998, sample = 1, },
  { rate = 0.5, start = 124.98000000001, len = 0.22999999999977, sample = 1, },
  { rate = 0.5, start = 128.05000000001, len = 0.42999999999978, sample = 1, },
  { rate = 0.5, start = 131.71000000001, len = 0.15999999999977, sample = 1, },
  { rate = 0.5, start = 131.03000000001, len = 0.15999999999977, sample = 1, },
  { rate = 0.5, start = 130.85000000001, len = 0.15999999999977, sample = 1, },
  { rate = 0.5, start = 130.82, len = 0.15999999999977, sample = 1, },
  { rate = 0.5, start = 131.19, len = 0.30999999999977, sample = 1, },
  { rate = 0.5, start = 133.85000000001, len = 0.30999999999977, sample = 1, },
  { rate = 0.5, start = 137.49, len = -0.15000000000023, sample = 1, },
  { rate = 0.5, start = 140.08000000001, len = 0.66999999999978, sample = 1, },
  { rate = 0.5, start = 140.13000000001, len = -0.010000000000225, sample = 1, },
  { rate = 0.5, start = 146.25000000001, len = 0.30999999999977, sample = 1, },
}

collection5 = {
  { rate = 1.0, start = 38.03, len = 1.4399999999995, sample = 3, },
  { rate = 1.0, start = 40.39, len = -0.080000000000477, sample = 3, },
  { rate = 1.0, start = 41.6, len = 0.39999999999952, sample = 3, },
  { rate = 1.0, start = 42.16, len = 0.23999999999952, sample = 3, },
  { rate = 1.0, start = 42.31, len = 0.38999999999952, sample = 3, },
  { rate = 1.0, start = 46.72, len = 0.31999999999952, sample = 3, },
  { rate = 1.0, start = 47.67, len = 0.31999999999952, sample = 3, },
  { rate = 1.0, start = 48.84, len = 0.30999999999952, sample = 3, },
  { rate = 1.0, start = 47.34, len = 0.40999999999952, sample = 3, },
  { rate = 1.0, start = 48.8, len = 0.079999999999523, sample = 3, },
  { rate = 1.0, start = 50.48, len = 1.0499999999995, sample = 3, },
  { rate = 1.0, start = 54.63, len = 2.2099999999995, sample = 3, },
  { rate = 1.0, start = 57.08, len = 1.1399999999995, sample = 3, },
  { rate = 1.0, start = 62.01, len = 0.33999999999953, sample = 3, },
  { rate = 1.0, start = 64.25, len = -0.43000000000047, sample = 3, },
  { rate = 1.0, start = 64.05, len = -0.43000000000047, sample = 3, },
  { rate = 1.0, start = 66.12, len = -0.51000000000047, sample = 3, },
  { rate = 1.0, start = 68.28, len = 0.81999999999953, sample = 3, },
  { rate = 1.0, start = 73.540000000001, len = 0.55999999999953, sample = 3, },
}

collection6 = {
  { rate = 1.0, start = 183.39, len = 1.8599999999994, sample = 3, },
  { rate = 1.0, start = 182.21, len = 1.1999999999994, sample = 3, },
  { rate = 0.5, start = 181.85, len = 1.6299999999994, sample = 3, },
  { rate = 1.0, start = 182.25, len = 0.58999999999945, sample = 3, },
  { rate = 1.0, start = 182.08, len = 0.70999999999945, sample = 3, },
  { rate = 1.0, start = 182.69, len = 0.60999999999945, sample = 3, },
  { rate = 1.0, start = 182.69, len = 0.60999999999945, sample = 3, },
  { rate = 0.5, start = 181.55, len = 0.91999999999945, sample = 3, },
  { rate = 0.5, start = 183.17, len = 1.1799999999994, sample = 3, },
  { rate = 2.0, start = 181.72, len = 1.9899999999994, sample = 3, },
  { rate = 2.0, start = 181.8, len = 0.64999999999945, sample = 3, },
  { rate = 2.0, start = 182.39, len = 0.80999999999945, sample = 3, },
  { rate = 2.0, start = 181.71, len = 1.1799999999994, sample = 3, },
  { rate = 1.0, start = 182.94, len = 2.2899999999995, sample = 3, },
  { rate = 1.0, start = 181.81, len = 2.0499999999995, sample = 3, },
  { rate = 1.0, start = 182.26, len = 2.0399999999995, sample = 3, },
  { rate = 2.0, start = 212.82, len = 0.63999999999947, sample = 3, },
  { rate = 2.0, start = 214.33, len = 0.46999999999947, sample = 3, },
  { rate = 2.0, start = 214.92, len = 0.24999999999947, sample = 3, },
  { rate = 2.0, start = 215.8, len = 1.1399999999995, sample = 3, },
  { rate = 1.0, start = 214.88, len = 0.45999999999947, sample = 3, },
  { rate = 2.0, start = 214.21, len = 0.54999999999947, sample = 3, },
  { rate = 1.0, start = 211.87, len = 0.29999999999947, sample = 3, },
  { rate = 2.0, start = 212.47, len = 0.93999999999947, sample = 3, },
  { rate = 2.0, start = 214.31, len = 0.44999999999947, sample = 3, },
}

I made a big ol database of loops that I like. might go with 6 voices which randomly select loops from each collection based on a selection process catered to each voice/collection

so, way too ambitious for my day probably , , as usual ,

4 Likes

I overdid it during the day and am totally spent now :frowning:

I’m missing brightness and density, for which I need to understand routing.
For now I have

E1: volume
K2: biome / radius (random position + length)
K3: world (cycle)

My sample cycle implementation is horrendous, I think - I fade between an active and standby voice, and preload the next cycle in what has just become “standby”. I’m sure there’s a more elegant way to do it.

Current code is at https://github.com/pfig/nc01-drone/blob/master/pfig-lander.lua

I will try a last push tomorrow morning if I wake up in a functional state.

1 Like

This is super cool! Are you thinking about getting a play date? Actually Norns might be a better play date!

2 Likes

super super impressive screen visuals from everyone!

for those not sure what to do, don’t overthink it. drawing some simple shapes is totally gratifying— i expect my visuals are going to be pretty minimal (yet hopefully engaging).

mining my last loops now… tons of rich territory in all of these samples

4 Likes

oooo I like the idea of worlds being different parts of the mix

might go that route

1 Like