i was thinking about the rounding errors with this a lot too - i noticed that the clock out drifts from the grid of the static clock output now already
the ext clock sync input is also bound to really fun/strange if you have an unreliable clock, or if you feed in a sequence that isn't straight.
hopefully this isn't annoying/super obvious, but i'll dump my thoughts just in case they are of interest @tehn
basically, i thought there could be some sort of execution stack with times between events based off the last 2 ext clock trigs received. this stack would launch every time the clock trig is received... basically breaking the sequences up into launchable chunks. will outline a few different cases here for clarity's sake:
WITH A STRAIGHT EXT CLOCK SIGNAL (easy stuff, just to outline how it works)
let's say the last two clocks were 100ms apart. pattern 1 is 3x multiplied, all notes on.
when the clock trig is received, the execution stack that launches would be (using teletype script - using 'trig' to signify any event... could be cv change or gate time change, etc):
del 33 : trig
del 33 : trig
then it would wait until the next clock sync. by launching a stack with each ext clock trig, the rounding would never be more than a few ms off by the end of each chunk. also by recalculating the delay time based on the last two external clocks, we can create all sorts of weird rhythmic geometries and swings. light clock jitter could really humanize a pattern
you could just make kria count [clock divisor #] of triggers before launching the execution stack for that pattern
tt script per trigger would be:
if eq 3 x : x 0
if eq 0 x : trig
x add x 1
x would have to be set to 0 when the clock division is initiated
if pattern is both multiplied and divided:
subdivide everything into smaller slices and figure out how much of a 'remainder' delay there is between an external clock trig and the first pattern event.
so say the last two ext clock trigs were 100 ms apart, and the pattern is multiplied by 5 and divided by 7. not putting this in teletype script because it's messy but the logic is as such:
\\execute remainder delay + first event
first event would land on the grid with the external clock trig, so launch with no delay
\\calculate # subsequent events + remainder after
time between events is 7/5 of the time between external clock hits, so there would be no more events until the next ext clock trig. the accumulated remainder would be 2/5 of the time between ext clock trigs. would be good to keep this as a fraction until the next ext clock trig, as the timing could have shifted and we could recalculate delays then.
\\execute subsequent events
since there are no more events until the next ext clock trig, do nothing. of course there are some clock settings where multiple events would occur in one chunk (such as mul 12 / div 5), so this is where we execute those extra events.
how the new clock settings initiate would be an interesting facet of playing the instrument. right now the kria seems to accumulate the remainder delays, so we could actually use two variables, one that is a global 'accumulation' (calculated/accrued when clock settings are changed), and one that is just for keeping track of where we are in the clock cycle against the external clock grid.
i was going to elaborate on how this works with an unsteady clock but i think everything is explained here enough and i worry i'm just being obvious/redundant already. simply recalculate all of the delay times between events using the time between current ext clock trig and previous ext clock trig. this will allow for all sorts of shifting fluid grids- weird slow downs and speedups, fractal swings, who knows what. probably not even that game changing, but got me excited, especially since there are so many different kinds of events on this sequencer