FFT-based audio clip comparison for golden tests
Captain's Log: Stardate 77921.4
MacOS support (using deprecated OpenGL and OpenCL) is straight-up working. I implemented a less-fragile audio clip comparison algorithm this morning, and now 78 / 93 of the goldens tests pass on MacOS. I listened to all the remaining clips, and they are producing correct sounds, but for whatever reason there are very slightly audible differences. The diffs are large enough that I don't think I can reasonably loosen the comparison threshold. I'm not sure how I'll handle this -- possibly I'll have to add platform-specific goldens for a handful of cases.
The clip comparison algorithm is the simplest thing I could think of: break the clips into small chunks (e.g. 256 samples) and compute the DFT for each of them, and then take the L2 distance between the FFT buckets for each clip. The maximum L2 distance is returned, and compared to a threshold. This works surprisingly well. I'm using the max distance to be very conservative, but you could imagine looking at the 90%th percentile or something like that, too.
The goldens found a bug on MacOS, which is cool. It turns out that OpenCL 1.2 doesn't really allow NULL pointers, even though NULL is defined in the headers. It turns out that the implementation can place things at address 0. On my NVIDIA hardware, this is not the case, and so using pointer==NULL works like you'd expect. But on MacOS, it happily sticks private objects at &object == NULL. I changed the code to indicate absence via a side-channel bool instead of NULL, and it fixed the issue.
So now, everything works. I hooked up a MIDI keyboad to my Macbook and played stuff, and it did what I expected. Performance with OpenCL is usable but not great, but that's what I expected since it's deprecated and is translated to Metal behind the scenes. Just another reason that I have to do the Metal port.