Optimisation #2 (didn't work): precompute all the music buffers

An interesting observation that we got with the first optimisation was that the music computation time, which has to be fast, is mostly dominated by filling a buffer. And this buffer is used later on. Therefore, one "simple" optimisation here it to precompute the buffers of all the music events, and then when playing a music event, simply pass the relevant one to openAL. This would fix the issue of uncontrolled variance between music being played.

This failed for two reasons. The first one is due to startup load time. After the optimisation described above, computing the buffer for a music event takes about 20ms on chrome. For a song like Etude as dur - op25 - 01 from Chopin - which is not even a long song - we are talking of 1209 music events. This multiplied by approximately 20ms, means the loading time would be about 24 seconds. This is simply unacceptable. Circumventing this issue could be done by having one thread computing the buffers running in parallel to the one consuming them. Since the one consuming the event needs to wait between music_events, it is pretty much guaranteed that it will never need to wait (except for the very first event) to get a buffer to pass to openAL.

The second issue is related to memory usage. I capped the memory usage of the wasm application at 120 MiB which I already think is a lot. Each buffer here take 44100 * sizeof(uint16_t) * 6 bytes which is slightly above half-megabyte. For the Chopin music sheet from above, this would mean using 2GiB of memory just for the music data, which I consider unacceptable.

It would be possible to circumvent this by capping the number of buffers available to never run out of the 120MiB of memory (which includes the memory used by the app itself for everything else). On firefox, I could use about 100 buffers before the app crashes with an out-of-memory errorm. It was approximately 80 on chrome. Now comes the issue of finding out how many buffers can be allocated before the app crashes. One way would be to simply keep allocating buffers, and catch the std::bad_alloc exception when reaching the limit. Unfortunately the memory allocator on wasm doesn't throw std::bad_alloc, instead it simply panics. This means that relying on this behaviour is not feasible. Ultimately, I decided not to try to get this optimisation working as the benefits were not worth the cost when it would work anyway. It would allow for about 2 seconds of pre computed music only. If a music sheet is fast paced enough to require music computed in less than 20ms (the slowest time on chrome), this 2 second time window won't probably help much to hide the slowness issue from the user, only delay it a bit.