Breakpoint demolog, days 51-55: fixing framework bugs, and composing a song too
Thanks to a series of very fortunate findings, I happened to fix the two bugs that made my synths sound horrible when running on top of iq's 64k framework, and even worse, in Release mode. There were two problems, firstly with the noise functions and second with the rounding to integer functions.
The framework has several noise functions, intended to be fast, very fast. But for some reason they also generate NaN values from time to time (1.#QNAN00 in Visual Studio's jargon), and this was making things go crazy whenever one of those values appeared (read: distorted). I solved this using another noise function, from this article that dario_phong mentioned a few weeks ago:
seed *= 16807;
return ((float)seed) / (float)0x80000000;
This one doesn't produce any NaN values and seems reasonably fast.
Funnily, the same article gave me somehow a hint as to why the synth sounded awful when in release. It seems the framework uses the /QIfist compiler option in release and that produced a very rough float to int conversion, hence the cranky sound when in release. But if I removed the option, the compiler complained about a missing _ftol function. So I solved my problem in a slightly slow and cumbersome, and probably not very elegant way, which was to add a new function using the assembler implementation provided in the same article:
inline long floorSSE(double x) {
__asm cvttsd2si eax,x
}
It actually is in my MathUtils class, as MathUtils::floor. So everywhere that was a construct like this:
int v = (int) (floatVariable);
I changed it into
int v = (int) Math::floor(floatVariable);
I am unsure as to whether this is a good idea or not, but the synth sounds properly now and the performance doesn't seem to have increased or decreased, so I assume that at least is OK.
The only minor issue is that the assembler instruction belongs to the SSE instruction set so old processors (<1999) might not have it, although they probably won't be able to run the rest of the code anyway (performance wise speaking, it is a bit of an unoptimised resource hog :P). Also, I haven't tried to compile these last changes with gcc, so I don't know whether it will be OK with this inline assembler syntax. I think it should be fine and won't ask me to use the AT&T syntax instead, which I find pretty horrible by the way. But there's something for sure, I'll have to look for an alternative if I want to compile this in my PowerPC powered PowerBook :)
On the composing side, I've got about 2 minutes of raw, unpolished and unadorned song. It's turning out to be quite weird and a quite bit "in my style", so if there are any supersole fans in the audience they might easily recognise the song even without looking at the screen at all, haha!
I'd love to finish the song tomorrow, fingers crossed!