Fixing my GPU PRNG implementation for S&H
Captain's Log: Stardate 77434.9
Bugs... so many bugs...
Today I implemented sample & hold for the LFOs (and audio oscillators why not). This led me down a rabbit hole of discovering that the PRNG I had implemented on the GPU earlier for white noise and mallet attack noise was actually super broken. It's really strange -- at audio frequency it sounded fine, but once you slowed it down for sample & hold it was really obvious how non-random it was.
My original approach was a linear congruential generator, which I knew was bad, but figured it was good enough. This is very wrong -- LCGs are truly awful. I tried a bunch of parameters and none of them were satisfying. So then I moved to a Galois LFSR. These are pretty good, but I didn't realize that they really only generate 1 bit at at time. Finally I ended up using the xorshift64* algorithm, which works extremely well. It's a few more instructions than the other approaches, but it is worth it for the much better results.
I spent most of the day on that boondoggle, but figured I'd do something "easy" with the remaining time I had. I looked up a quick TODO item for replacing the collision shape in the GUI for the little 3D gears that represent modulators. They were using a sphere, but a cylinder is obviously better. The actual collision logic is already implemented, so this was just a 3 line change. But... BUGS! I discovered that my cylinder collision code detected more of a "pill" shape -- a cylinder with hemispherical ends. I never noticed this before, because the only thing that used cylinders was the springs, and their radius is small, but also their ends are inside the masses. So you never see that clicking near the ends does the wrong thing.
Anyway, cylinder collisions are fixed now, and the clickable volume for modulators is much better. 🙂