The first reference was the “play” button on musescore.com. When playing the song, the web page also highlights the current measure being played. This information may be obvious to experienced musicians, but super helpful to newcomers like myself trying to decipher sheet music. With this highlight tool, I could see which measures are played and the patterns in which they repeat to build the Nyan Cat song.
The second reference was the existing “mario” song on the badge, which showed one way to organize a song in code. Each measure is in its own array, and music playback consists of making calls to play measures in a particular sequence. I built on top of this idea and built another array
nyancat_measures around them for convenient indexing. Then a separate array
nyancat_sequence was created to track the order in which to play the measures. Playing the song would then be a matter of walking the sequence array in order and play each indexed measure as we go.
And finally – it’s time to put the sights and sounds together! The Nyan Cat badge app runs in a tight infinite loop checking the time via the
millis() API. The video playback speed is controlled by one variable
time_for_next_frame tracking the time for the next frame, and now music playback will be tracked with
Is this perfect? No.
Unpacking and rendering a frame of animation takes a few tens of milliseconds. Occasionally this overlaps with a desired music start time, causing a note to end up playing a touch too long. The converse is also true – if music processing is underway at a desired animation frame time, there will be a brief animation glitch.
But it’s good enough for a badge hack.
(Cross-posted to NewScrewdriver.com)