We worked to limit audio layers, but with full narration, a sound effects layer, and an orchestral score performed by the NZSO, we still ended up with a lot of audio. The sound designers really worked hard to meet us on our constraints, working up a nice system of fading feature segments in and out of loopable ‘vamps’ that filled the gaps.
We ended up with a pretty declarative API that let us write, in our scene sequencing modules, things like this:
this.sound.onceThenLoop(
Layer.Music, "sound", "loopSound",
{fadeOut: 1}, // immediate fade specs
{cross: 0.5} // fade specs for transition into "loopSound"
);
this.sound.loop(Layer.SFX, "atmos");
Our main issue was that for the precise mixing and timing we needed (for example, scheduling a cross-fade into a new track just before the end of the current track) we wanted to use the WebAudio API. The Howler library was a great solution here, giving us a pretty decent fallback to HTML5 audio for Internet Explorer 11. However, WebAudio likes audio to be decoded eagerly and held in buffers, and with the amount of audio we were managing we found ourselves hitting memory limits and crashing the browser on many devices.
We managed to squeeze everything in with a couple of careful delayed loads and manual unloads, but we’re still looking at finding places to mix-down SFX and music into a single layer to ease some of that memory pressure.