# Tempoclock scheduling and a floating point modulo issue

Hi everyone,

I’m diving into using the tempo clock right now. I’m doing this by creating a Euclidean sequencer. I want to be able to change the tempo of this sequencer relative to the tempo clock, so I can have multiple sequencers with drifting tempos and suddenly snap them back in sync with each other.

At first, I did this by scheduling a `step` function on the tempo clock, and having this function return the time a step should take. The issue with this method, was the “snapping back in sync”. Example: we have a sequencer running at a tempo of 0.25, and between beat 10.0 and 10.25, the tempo is changed to 0.5. At beat 10.25, the next step is played, and the tempo is returned. This causes the next step to be scheduled for 10.75, while snapping back in sync requires this step to be scheduled on a beat that is a multiple of 0.5.

Now, the solution I thought of was not to return the tempo, but to schedule the next onset by finding the next value for beats that is divisible by the current tempo. My solution for this was the following code:

``````nextOnset = this.tempoClock.beats + this.tempo - (this.tempoClock.beats % this.tempo);
tempoClock.schedAbs(nextOnset, { this.step; nil; });
``````

Let’s say the current value for `beats` is 10.25, and `tempo` is 0.5. Then 10.25 + 0.5 - (10.25 % 0.5) = 10.25 + 0.5 - 0.25 = 10.5, which is a multiple of 10. Seems like a good idea, right?

Well… It would be, were it not that I wanted to be able to enter any number for the tempo. Unfortunately, I ran into problems when testing `tempo = 0.3451`. This quickly filled up the tempo clock’s queue. I found the culprit to be the modulo in the code posted above.

0.3451 * 46 = 15.8746, and 15.8746 / 46 = 0.3451.
This would lead to the conclusion that:
15.8746 % 0.3451 = 0.0
However, it turns out that 15.8746 % 0.3451 evaluates to 0.3451. This causes the two lines of code that schedule the next step in the sequencer to schedule it for the current value for `beats`, which in turn causes an infinite loop of infinite step scheduling.

I suspect this issue is caused by floating point precision? Though I’m not sure.

Anyone have an idea for a solution or workaround for this issue?

Yes this seems like floating point error:

``````15.8746 % 0.3451 // -> 0.3451
0.3451*46 % 0.3451 // -> 0.0
(15.8746 - (0.3451*46)) // -> -1.7763568394003e-15
``````

I’m not sure if there’s an elegant way around this if you’re using arbitrary floating point numbers… this problem could be easily solved if you use rational numbers instead (there’s a quark for that). If you do still want to use floating point, you could write a custom mod function that tests for near-equality and if so wraps around to 0:

``````(
~fuzzyMod = { |a, b|
var division = a / b;
var result = a - (division.floor * b);
if (result.fuzzyEqual(b, 0.000001) > 0) {
result = 0.0
};
result;
};
)

15.8746 % 0.3451
~fuzzyMod.(15.8746, 0.3451)
``````

“Go to the next higher multiple of t” is `roundUp`.

``````f = { |x, t(0.3451)|
x + t - (x % t)
};

f.(15.8746)
-> 15.8746  // nope

f = { |x, t(0.3451)|
(x + t).roundUp(t)
};

f.(15.8746)
-> 16.2197
``````

roundUp is defined (in the C++ source code) as `(x / quant).ceil * quant` which avoids precision issues with addition/subtraction.

hjh

The standard library has SimpleNumber method equalWithPrecision

``````	equalWithPrecision { |that, precision = 0.0001, relativePrecision = 0|
^if(relativePrecision > 0) {
absdif(this, that) < max(precision, relativePrecision * min(abs(this), abs(that)))
} {
absdif(this, that) < precision
}
}
``````

It’s not a very elegant solution. Try to use rational numbers and see how it goes.

Check the Rational Quark. It is well integrated into the supercollider class system as far as a quark can be.

Given the polymorphism in supercollider and its dynamic typing character, which defers type/class checks until necessary, rational numbers could be even more integrated into the dynamically typed polymorphism and used without conversion to floats in Patterns or the Synthdef DSL. It would be cool. But right now, sometimes you need to convert them to float (deferring until necessary).

You could do all the algebra as musical values (rational numbers). This way, you will be sure there is no loss of precision in that part of the code. However, sometimes you need to convert to float at the very end. (I’m saying this cause it’s not 100% clear your workflow, and I’m unsure of your context)

The issue in the original case is with the subtraction: the beats value and the mod value are at different (binary) orders of magnitude, thus a few bits from the number with the smaller order of magnitude will be lost.

The `ceil` approach is better because it’s working fully in the multiply/divide domain (where floats are generally more comfortable) – IMO this is better than doing the subtraction and `fuzzyEqual` checking it after the precision has been lost.

hjh

It’s true. Multiplication and division will mitigate the most trivial floating-point errors. They can still happen, but with the typical differences in magnitudes, the kind of material music theory works with, and with rounding and checking, it’s mostly safe.

In any case, rational numbers avoid these issues entirely for precise arithmetic operations, which are found in music theory. They are not just less risky, but guaranteed to be precise, which is different.

Knowing that part of your code is safe in programming is very helpful. That would be the case here. That’s the same reason that good code would, for example, try to separate pure operations from side effects. They are both in the same program, but in different parts of the code.

Thanks for telling me your thoughts everyone!

The roundUp method seems like a more elegant solution to what I’m trying to achieve. I’m trying that later today.