Norns: clock

I’m curious about that, too.

I noticed that external clock values are always rounded to set the “clock_tempo” param, which is updated every 1 s:

Link transport control?

docs say:

remote start/stop events can be generated by link or external midi.

but how do you do that?

I have these functions setup, but don’t get any transport start/stop from link. Do I need something else?

function clock.transport.start()
  print("transport.start")
  id = clock.run(pulse)
end
function clock.transport.stop()
  print("transport.stop")
  clock.cancel(id)
end

EDIT - top post says: no start/stop synchronization in link

Has this been added since then or is it still not functional?

Is this little delay related to this Github item

starting coroutines inside transport callbacks may be a bit tricky. it’s safe to assume that clock.sync(1/4) in your couroutine will wake up at 0.25 beats, and not at 0 beats as expected.

it might help to start the coroutine with the engine.hz call as follows:

function sequencer()
  engine.hz(get_note())

  while true do
    clock.sync(1/4)
    engine.hz(get_note())
  end
end

or wait for 1 or more whole beats before you start your norns sequencer:

function sequencer()
  clock.sync(1)

  while true do
    engine.hz(get_note())
    clock.sync(1/4)
  end
end

we’re working on fixing the syncing behaviour on transport start, but for now i don’t recommend relying on it for all use cases.

2 Likes

clock.get_tempo() returns a float. so the answer to your question really depends on what you want to show in your script. if you want to round the number down to n digits, use string.format.

clock_tempo parameter is updated every 1 second so it’s in sync with the external source tempo. the value is rounded indeed (parameter type is number and can only be increased/decreased by 1).

should work (but see the transport quirk described above). do you also get the tempo and beats synchronized via link? does your other link client show the norns node in “links” counter?

1 Like

I am getting tempo control just fine. Just not start/stop.

I see 2 Links in the Ableton top left corner. Is that the norns node thingy?

EDIT - where can I debug the start/stop from Link? I don’t see anything super obvious in clock.lua

testing with: Torii

yes, it’s alright.

do you have link start/stop sync enabled in the ableton client?

the relevant code is in matron/clocks/clock_link.c

1 Like

Oho… I don’t see this as a preference. Is this perhaps a Live 10 feature? (I am on Live 9.7.7 Suite)

looks like thats it:

Link currently provides tempo sync and a grid to which apps can align. In Live 9, there are no Song Position or Start/Stop messages sent via Link, nor can any other MIDI data be sent. In Live 10 the feature “Start Stop Sync” additionally shares Transport Start and Stop Commands.

Might call for a FAQ item (alerting señior @dan_derks)

1 Like

sounds good - thanks for the thorough insight!

2 posts were merged into an existing topic: Different MIDI in/out devices Norns

I’m getting some weird behavior with clock.sync

when x = 2, I get a beat pattern of 2,2,1,3 in lengths. when x = 1, I get the expected pattern of 2,2,1,1. I’m assuming it’s an issue of the first sync after the loop missing the sync.

function test()
  while true do
    clock.sync(2)
    engine.trig(0)
    clock.sync(2)
    engine.trig(0)
    clock.sync(1)
    engine.trig(0)
    clock.sync(x)
    engine.trig(0)
  end
end
1 Like

Right, this is a known issue that has now been fixed and the fix will be released with the next update.

4 Likes

What’s the ETA of the next release?

So I’m building a good old fashioned sequencer, and I came onto this “issue” which is probably just a design mishap on my part…

Say I have two sequences, both 16 steps long and running at 1/4 rate with each step playing its note after a clock.sync(1/4). I want to change one of them to 1/2, run it a while and then go back to 1/4. I noticed that if I change the rate to one of them it gets out of sync, as if the clock was clearing and restarting. It could be snapping to the nearest 1/4 pulse but it sounds like it’s smaller than the 1/4 step length.

Two possible solutions I can think of:

  1. sync the rate change to a master clock that always runs. Can I target a specific clock routine once it has been associated to a global var somewhere else in my script?
  2. Use only a master clock for all sequences and bang the note events at specific time “intersections“ using % - that would ensure a strict adhesion of all sequences to the global grid.

What do you think? I should be able to extract the portion of code from the rest of the script and post it here if needed.

well, the point of clock.sync is to ensure that your code stays synchronized with the beat, so it mustn’t get out of sync :slight_smile: (not even if you restart the coroutines or change sync rates on the fly). but i’m not sure i understand your issue correctly, it would be good if you could provide a minimal code sample where it can be reproduced.

Thanks! I hope this makes it clearer:

so i press button 3 and get no sound, how exactly can i reproduce the issue?

press button 2 to randomize the pattern first! otherwise no notes in the pattern :sweat_smile: oopsie

for example:

  1. key2 to randomize tr.1
  2. change track with enc1, then key2 to randomize tr.2
  3. set both patterns’ step length to 0.5 with enc2
  4. press key3 to play
  5. change step length of tr.1 to 0.333, then back to 0.5
  6. patterns seem to have different start times than before

Example 2:
Two sequences are set with rates of 0.5 and 0.25, press key3 to toggle play a few times. They get synced slightly differently each time, but the notes should be overlapping every time (sequence 1 should play one note every two notes of sequence 2).

1 Like

ok, so it seems that you’re misusing clock.sync here.

since note_on is not a coroutine, clock.sync will indirectly cause the external coroutine (in your case step) to suspend again, potentially causing the issue you described. double syncing seems to be unnecessary here.

i haven’t looked deeper in the code, but removing sync call from line 82 seems to resolve the issue for me. hope this helps!

2 Likes