Crow/norns/clock question

I am running into an issue with clock sync using crow with norns when norns is receiving midi clock via usb. Basically, in this configuration, clock pulses are getting dropped/skipped from crow. I have a Roland TR-8 sending clock out to an iConnectivity Mio4. All 4 midi din ports on the MIO4 are replicating the clock out, along with all USB ports. One of the USB ports is connected to norns, which sees it and displays the proper tempo. I’m selecting crow for clock output (port 4, but I’ve tried all crow outputs). The clock signal from crow is going into white whale. About one out of every 16 ticks is getting dropped, so the white whale loop gets more out of sync after each passing bar. When I choose internal clock on norns, crow outputs the sync signal perfectly. This is crow firmware 2.0 and the newest norns firmware. Any thoughts on how to correct this behavior when norns is synced to an external midi clock source?

Edit: It also tried midi over usb straight from the TR-8 to Norns with the same result.

Ive had a similar issue with Norns and Crow using an external clock source to feed crow a clock, mainly PNW.
Seems like crow drops a clock pulse now and then which could be one out of every 16 ticks which makes sequenced loops fall out of sync. This seems to only affect a few apps. Ive got most problems with Quence and Animator but theres probably more.
I know this is kinda the opposite of your issue but I feel they are linked. Something to do with crow sending/receiving clock pulses. It could be to do with the Norns clock system too. Im hoping this gets looked into. I feel like the Norns clock could be reworked a little and if it does I’d really like to see a reset option added via crow too.
Anyway I’m rambling a little…
Hopefully you get your issue sorted!

Yeah, I suspect our issues are somehow related.

hey y’all – sorry to hear about the trouble! i figured this could use a test script, so i whipped up one that should work for @hypnosapien’s trouble of MIDI clock -> crow misses.

crowtest.lua (1.1 KB)

basically:

  • choose your crow clock output
  • use a patch cable to route that output back into crow input 1
  • press K3 to start monitoring the clock

if a pulse is skipped, you’ll see a tick at the bottom of the screen. it’s normal for the script to start with a tick, because the script is checking for events with a clock tick distance greater than 1/16th. press K2 to clear the ticks, in case you start with a false positive.

if you get some positives, then that’s a good starting point for debugging clocks over MIDI!

@dan_derks, thank you for taking the time to put this together! This is the number of ticks I get for every 16 bars or so…

Edit: I can also confirm that there are no ticks appearing when norns clock is set to internal.

IMG_3116

@dan_derks, just checking in to see if there’s anything else I can do to help troubleshoot this. Thanks!

woop! very sorry to lose track!

rubber-ducking this:

  • sending clock through crow via the PARAMS menu when clocking norns via MIDI is causing missed pulses
  • this was confirmed by routing pulses generated by crow back into crow and tracking the number of missed pulses (measured by the times when the distance between pulses was much larger than 1 beat)
  • @cosmicsoundexplorer confirms that they’re also seeing missed pulses from crow when clocking norns externally (via crow or MIDI?)

so let's try a different test script
function init()
  params:set("clock_source",2)
  clock.run(ping)
  process = false
  last_one = clock.get_beats()
  skipped = 0
end

function ping()
  while true do
    clock.sync(1/4)
    process_change()
  end
end

function process_change()
  if process then
    print(clock.get_beats()%4)
    if clock.get_beats() - last_one > 0.3 then
      skipped = skipped + 1
    end
    last_one = clock.get_beats()
    redraw()
  end
end

function key(n,z)
  if n == 3 and z == 1 then
    process = not process
  elseif n == 2 and z == 1 then
    skipped = 0
  end
end

function redraw()
  screen.clear()
  screen.move(10,43)
  screen.font_size(20)
  screen.level(15)
  local show_me_beats = string.format("%.2f",(clock.get_beats() % 4)+1)
  screen.text(show_me_beats)
  screen.move(10,60)
  screen.font_size(10)
  for i = 1,skipped do
    screen.text("|")
  end
  screen.update()
end

with this version:

  • plug in your MIDI clock source + run the script
  • the script should switch the global clock to MIDI (just confirm to make sure)
  • make sure your device is sending norns MIDI clock (you should see the tempo sync to your external BPM)
  • press K3 to start test (no crow stuff here)
  • if a beat is skipped, a tick will appear
  • press K2 to clear ticks

what i’m looking for is a way to determine where the hiccup is happening – i was going to originally send a test script that clocked crow from the MIDI clock through a coroutine and I realized that’s exactly what’s happening when you set crow out in the PARAMS. so, if we can prove that things are getting borked when you clock from MIDI generally, then i think that helps narrow a bit!

I can confirm that Norns is receiving midi clock and tracking tempo after running the script. I’m only getting a tick on start, no other ticks. I let it run for several minutes with a few clears and stops and the occasional tempo change.

ok, cool! so we’ve confirmed that MIDI clock drives events regularly, which means that the only thing left to test is what happens when we attach a crow pulse to the MIDI clock.

here's a third test
function init()
  params:set("clock_source",2)
  clock.run(ping)
  process = false
  last_one = clock.get_beats()
  skipped = 0
  crow.input[1].mode("change", 2.0, 0.25, "rising")
  crow.input[1].change = process_change
  crow.output[1].action = "pulse(0.05,8)"
end

function ping()
  while true do
    clock.sync(1/4)
    crow.output[1]()
  end
end

function process_change(v)
  if v == 1 and process then
    print(clock.get_beats()%4)
    if clock.get_beats() - last_one > 0.3 then
      skipped = skipped + 1
    end
    last_one = clock.get_beats()
    redraw()
  end
end

function key(n,z)
  if n == 3 and z == 1 then
    process = not process
  elseif n == 2 and z == 1 then
    skipped = 0
  end
end

function redraw()
  screen.clear()
  screen.move(10,43)
  screen.font_size(20)
  screen.level(15)
  local show_me_beats = string.format("%.2f",(clock.get_beats() % 4)+1)
  screen.text(show_me_beats)
  screen.move(10,60)
  screen.font_size(10)
  for i = 1,skipped do
    screen.text("|")
  end
  screen.update()
end

with this version:

  • disable crow clock output from the global clock menu
  • plug in your MIDI clock source + run the script
  • the script should switch the global clock to MIDI (just confirm to make sure)
  • make sure your device is sending norns MIDI clock (you should see the tempo sync to your external BPM)
  • connect crow output 1 to crow input 1
  • press K3 to start test
  • if a beat is skipped, a tick will appear
  • press K2 to clear ticks

this is essentially the same exact thing as what should be happening when you choose all this from the params, but just more direct. we’re using the MIDI clock to pulse crow’s output and we’re reading those pulses back – i’m curious if you get the same skips as the first test tho.

When I run the third script, I get:

norns.script.load("code/clocktest2/clocktest2.lua")
# script load: /home/we/dust/code/clocktest2/clocktest2.lua
# cleanup
# script clear
### SCRIPT ERROR: load fail
/home/we/dust/code/clocktest2/clocktest2.lua:1: unexpected symbol near '{'
stack traceback:
/home/we/norns/lua/core/norns.lua:136: in function </home/we/norns/lua/core/norns.lua:136>
[C]: in function 'dofile'
/home/we/norns/lua/core/script.lua:172: in function </home/we/norns/lua/core/script.lua:172>
[C]: in function 'xpcall'
/home/we/norns/lua/core/norns.lua:137: in field 'try'
/home/we/norns/lua/core/script.lua:172: in function 'core/script.load'
(...tail calls...)
# script clear
<ok>
clock: ignoring resumption of canceled clock (no coroutine)
clock: ignoring resumption of canceled clock (no coroutine)

looks like you’ve got a stray character somewhere or a mis-copy/paste. can you share a screenshot and/or your code?

@dan_derks @tyleretters I must have copied/pasted something incorrectly. I got the script to run now, but when I press K3, nothing happens. I’m not super adept with the code, so I still could be doing something wrong…

1 Like

totally not you, i ran into the same troubles myself until a crow.clear()

so, i’m seeing some WEIRD stuff.

  • turn off crow out from PARAMS
  • attach a MIDI clock to norns and verify it’s connected + transmitting in PARAMS
  • try running each of the following scripts
  • plug crow output 1 into crow input 1 (if you want to see the ticks, otherwise you can just drive any external sequencer and hear if things get wiggly)
  • if you chose to feed crow back to itself, press K3 to start up visual monitoring
  • confirm you experience the skipping on the skip script and not skipping on the other?

this script skips beats
function init()
  crow.clear()
  params:set("clock_source",2)
  clock.run(ping)
  process = false
  last_one = clock.get_beats()
  skipped = 0
  crow.input[1].change = process_change
  crow.input[1].mode("change", 2.0, 0.25, "rising")
  crow.output[1].action = "pulse(0.05,8)"
end

function ping()
  while true do
    clock.sync(1/4)
    crow.output[1]()
    -- crow.output[2]()
  end
end

function process_change(v)
  if v == 1 and process then
    -- print(clock.get_beats()%4)
    if clock.get_beats() - last_one > 0.3 then
      skipped = skipped + 1
    end
    last_one = clock.get_beats()
    redraw()
  end
end

function key(n,z)
  if n == 3 and z == 1 then
    process = not process
  elseif n == 2 and z == 1 then
    skipped = 0
  end
end

function redraw()
  screen.clear()
  screen.move(10,43)
  screen.font_size(20)
  screen.level(15)
  local show_me_beats = string.format("%.2f",(clock.get_beats() % 4)+1)
  screen.text(show_me_beats)
  screen.move(10,60)
  screen.font_size(10)
  for i = 1,skipped do
    screen.text("|")
  end
  screen.update()
end
this script DOESN'T
function init()
  crow.clear()
  params:set("clock_source",2)
  clock.run(ping)
  process = false
  last_one = clock.get_beats()
  skipped = 0
  crow.input[1].change = process_change
  crow.input[1].mode("change", 2.0, 0.25, "rising")
  crow.output[1].action = "pulse(0.05,8)"
end

function ping()
  while true do
    clock.sync(1/4)
    crow.output[1]()
    crow.output[2]()
  end
end

function process_change(v)
  if v == 1 and process then
    -- print(clock.get_beats()%4)
    if clock.get_beats() - last_one > 0.3 then
      skipped = skipped + 1
    end
    last_one = clock.get_beats()
    redraw()
  end
end

function key(n,z)
  if n == 3 and z == 1 then
    process = not process
  elseif n == 2 and z == 1 then
    skipped = 0
  end
end

function redraw()
  screen.clear()
  screen.move(10,43)
  screen.font_size(20)
  screen.level(15)
  local show_me_beats = string.format("%.2f",(clock.get_beats() % 4)+1)
  screen.text(show_me_beats)
  screen.move(10,60)
  screen.font_size(10)
  for i = 1,skipped do
    screen.text("|")
  end
  screen.update()
end

the difference between the two is that the working script includes one extra line: crow.output[2]()
the output isn’t even defined, but including it in the clock-synced ping keeps everything steady.


if you can confirm this is happening on your side as well, then we (finally, thank you for your patience!) have a good repro case!

(@Galapagoose + @artfwo any thoughts on this? seems friggin’ weird but i’m woke-up-at-4am-tired.)

Yes, this is also happening for me. The first script gets ticks, the second does not. Thanks!

1 Like

So I just synced Norns to Ableton link for the first time, and with this setup, crow clock output works perfectly! I can even change tempo in Live and both Norns and crow teach the tempo changes without missing a beat! This solves the issue for me, at least for now.

1 Like

yeah, i found this only reproducible with midi clock, so i’m glad you have a setup that works for you! still curious why this is happening with midi :confused:

Yeah, ultimately I would prefer to clock Norns from a midi source so I don’t have to have live running all the time, but I’ll take this as a win for now!

2 Likes

Need to bring this topic back to life. I’m experiencing an extremely “swingy” clock when syncing via midi. As @hypnosapien said, Ableton Link seem to work much better. I have a Novation Peak hooked up to recieve the outgoing clock and the reading on it (for 120) is jumping up and down from 120-ish to 160. Not sure if this is a Crow issue as I can hear the off-beat in the scripts aswell.

Edit: I Found this topic where a related / similar issue has been discussed.

ah, i was about to link to the github issue – glad you found it, though!

MIDI clocking trouble has been logged and is receiving attention: clock: crow + MIDI external clock sources double-trigger clock.sync(1) · Issue #1273 · monome/norns · GitHub

2 Likes

Thank you @dan_derks, I’ll work with Link in the meantime.