Thank you, I think that’s good advice!
I, too, thought it was a clever approach. It looks so straightforward, so the question still is: Why does it de-sync at all, and why does it the way it does?
Here’s a 4 operator fm voice:
The patch selection is at the bottom of the post, but you’ll need Stoermelders strip++ to load it.
It doesn’t really make sense does it. In theory if the poly voct are integers we would expect exactly doubled frequency for each channel. So I cannot explain why they de-sync. Perhaps I am oversimplifying things.
Two identical digital oscillators running at the same frequency, (identical code, identical initial conditions, etc.) will not get out of sync.
But two identical digital oscillators running at different frequencies will (almost?) always get out of sync, even if one frequency is an even multiple of the other. That is because floating point operations have limited precision - the miniscule inaccuracies compound each other over time. When identical oscillators run at the same frequency, they always perform the same computations, resulting in the same cumulative inaccuracy, and they remain in sync. But when running at different frequencies, the inaccuracies no longer align, and they get out of sync.
I suppose there may be some frequency relationships where everything aligns with the VCV sample rate, and align with floating point operations in a way that allow all calculations to be exact. But I imagine they are few and far between, (if they exist at all).
Two different digital oscillators running at the same frequency will typically get out of sync because they don’t compute the output exactly the same way. Even if theoretically the math should give the same result, the floating point inaccuracies will likely not be in sync.
Don’t want to disrupt the useful thread here, but this recent ‘news’ immediately came to mind.
Makes sense, thank you much for explaining !
I suppose that if I was a developer (which I am not), floating point errors with whole numbers would give me a lot of headaches .
Thank you, this is so much fun to play with and can produce such great sounds! Well done!
I wish one could make the octave knobs in PatchMaster snap to position.
I also wish one could lock select (not all) modules in place permanently, as I constantly move around the PatchMaster units accidentally when turning the knobs.
That is why we have decimal datatypes. Why oh why use floats where rounding errors are bad?
this is actually quite relevant in rack programming, I believe most modules (including the fundamental modules) will use float
types generally
However, you can use the double
types higher precision to reduce the inaccuracies that build up over time, the trade off is of course more memory usage
I have seen some module code (can’t remember which module now…) that performs a periodic “reset” of loop accumulators to try to avoid digital inaccuracy drifting
I found that I had to use the double
type in my Time Lord module to maintain accurate timekeeping
Even a decimal data type will have a limited precision. Imagine you have an oscillator running at 100 Hz and you want another oscillator running at the third of this frequency, you will get 33.333333… Hz. So there will always be an “error”, or better call it an end of precision.
Thank you!
Yes, I totally agree, that would be great!
you are correct, had not properly taken that into account…
Like @Ahornberg says the floating-point data types, also have a precision limit, and in the end these are internally binary numbers with an exponent (hence 2-base). A decimal (10-base) number like 0.1 cannot be accurately/precise described in binary (2-base) form. Converting (10-base) 0.1 to binary, the value will be: 0.0001100110011 … where the last “0011” will repeat forever.
Thank you for the knowledge. You explanation makes plenty of sense. It is a bummer because I really liked this setup for a poly clock because each channel could be fine-tuned (for example I could have quarter-note triplets on one channel and half-note quintuplets on another) and I could easily add noise to the poly cv to create the effect of human timing. I will need to go back to the drawing board for a poly construct that will do all of this the way I like.
Two mutually exclusive gates
Starting out with two given gate patterns (here: from Eugene by Rare Breeds), the patch assures that each pattern only plays (gate high) if the other is not playing (gate low), so they are mutually exclusive.
Therefore, when gates are high in both patterns at the same time, both gate outputs are low, i.e. neither pattern is playing.
Employs logic gate modules by Submarine for each arm: NG-106 as a NOT gate and AG-104 for the AND gate. A SampleDelays module (Grande) compensates for the sample delay caused by different path lengths.
Can use to create non-overlapping gate patterns from two sources, e.g. for percussion.
Two mutually exclusive gates_20250120.vcvs (11.5 KB)
ADDENDUM:
Alternatively, two 2-Bit Truth Tables (Lunetta Modula) can also be used, but will take up more space.