kripken/emscripten — pull request #2651 by juj (2014-08-11 16:30:16+00:00)
Title: requestAnimationFrame-based SDL audio queue.

This set of commit aims to improve the SDL buffered audio support:
- Remove code that implemented the Mozilla Audio Data API playback, since Firefox has killed support for that a long time ago.
- Remove the previous attempt where we'd use ScriptProcessorNode to drive the audio. That proved to be too flaky in practice, since it depends on an unspecified audio context sampling rate, and requires maintaining two paths.
- Try to improve the SDL audio queueing stability by calling the audio callback *also* in the main `requestAnimationFrame` loop. Since it fires (ideally) at each 16msecs, this should provide a good stable granularity for feeding new audio data to Web Audio API. The issue with just using setTimeout() like the previous code is that browsers seem to have very wild jitter with that function, on the order of hundreds of msecs. With this PR, audio is pulled with both `rAF` and `setTimeout`. The reason why `setTimeout` is retained is that there might be SDL applications that don't need to call `emscripten_set_main_loop` and therefore don't have a `rAF` loop running at all in the application.

This was tested to improve audio quality with the JSMESS codebase, although they have migrated to using a custom JS audio backend since.

One existing issue with the SDL audio model is that it is inherently pull-based. This means that there is the audio callback which is periodically called to fetch new audio samples from the application. However when we invoke the SDL audio callback, we don't really know if the application has yet been able to generate enough audio data to play back, and it may end up giving us silent frames. This could be fixed with a custom extension to the SDL API, but that's a separate discussion and pull request. This push vs pull issue is one of the reasons that codebases are probably better off implementing streaming audio on top of OpenAL rather than SDL, since with OpenAL one needs to always push the audio data, vs SDL api, which always pulls. So with OpenAL, a codebase will avoid this problem that SDL has.