Echo is a music-based puzzle game build entirely in Javascript/HTML5/CSS3 which runs on both desktop and mobile browsers as well as iOS (and soon Android) through WebViews. For us, Echo was an experiment to see if we could build a game with responsive graphics and audio all in Javascript; we think we were successful. Being a music game, it was crucial that it was both rhythmically accurate and sounded good and Web Audio gave us both of those things.

Targeting mobile browsers meant that we needed all of the animations and sounds to work smoothly without glitches and stutters, and, most importantly, stay in time. To achieve this, we focused on having no Javascript compute during key performance moments like when the pieces are bouncing back and forth. We accomplished this by preprocessing our graphics and audio so that lower-level code was handling all of the animation and audio without ever calling a Javascript update function which would has notoriously bad timing. In fact, if you open up the Chrome Profiler and record the animation sequence, you'll see there are no Javascript functions being called during animation.

The bouncing animation is created with CSS3 Keyframe Animations which are generated when users click the play button. These have very accurate timing which so that it lines up well with the audio loops even after it's been animating for a few seconds or minutes. The audio is all sample-based. To get the audio to loop forever without any Javascript callbacks, first, we extend the length of the AudioBuffer to be the length of the longest loop we used, then we set the AudioBufferSourceNode to loop and finally to start the loop, we set the duration parameter to the length of the desired loop. Like so:

source.start(startOffset, 0, loopDuration);

where startOffset is when the loop first trigger and loopDuration is the length of the looped phrase. To sweeten the sound and make it less jarring when samples were stopped, we built a Ping Pong delay similar to this one [link]. This effect is relatively inexpensive compared to reverb and gave us a nice cohesion between samples.

We've wrapped many of the audio techniques we've learned into a library called Tone.js which we are currently expanding to include more effects and synthesis as well as transport and metronome controls.