How we implemented a rather playful web site menu that not only knows a bit of music theory, but also makes a solid effort at a few rock and pop songs.
First, a comic (click it to zoom if you can't read it)
Its a true story - you can even click over here to see the final menu (by "menu" I am referring to the alphabet menu under Select a band by First Letter). To soak up the bluesy vibe of The Lemon Song, see the Led Zeppelin page (or finish this article).
Actually, I did take a few "artistic liberties" with the comic. It wasn't 4 people – it was just me and a conversation in my head. This was a "personal project" and it was actually me that wanted a menu that played scales and music. It wasn't really The Lemon Song in particular that I wanted it to play - that song just made the comic funnier.
So, playing sounds on a web page is hardly new - and I'm sure the scale thing has been done. Perhaps even playing full songs has been done (links to any appreciated). But I suspect my approach was somewhat unique, so I'll quickly break it down here:
Firstly, I used the Web Audio API to generate the sounds. Audio has (finally) come a long way on the web, and this API really gives those who want control over their sounds the access they've been waiting for. For this project, I used a periodic waveform generated from an OscillatorNode. This results in quality sound with just a few lines of code and no sending of audio data required. I went with standard sine waves because I like how they sound, but you can specify a custom periodic waveform if you wish to use more complex tones.
Next, I shaped the amplitude of each tone using animation. This is certainly not the recommended mechanism (I have not seen it discussed anywhere online) - but I was curious how it would sound, and it sounded great, so I kept it.
The concept is this: instead of using the standard ADSR approach to controlling amplitude of individual notes, I controlled their amplitude with a simple animation function.
For those not familiar with the internals of animation - it generally involves tweening over a range of values over time. This is most often a visual effect - like moving an image from a starting point to an ending point. But the technique can be used to vary anything, including the amplitude of sounds.
Furthermore, easing functions allow you to specify different acceleration curves across the range for more realistic or interesting movement. The easeOutBounce easing proved particularly interesting for the amplitude of the notes, giving them a reverb sound without the need for an additional reverb processing node.
Musical scales are a set of notes based around a fundamental pitch. The classic western scale (think of "Do Re Mi" - as sung in Sound of Music) is referred to as the "Major Scale". But there are many other scales that suggest different moods and originate from different parts of the world, including mixolydian.
It is not hard to find wind chimes that are tuned to specific scale, which creates a particular mood whenever the wind blows across them. In a similar fashion I wanted a menu that would play various scales and create a specific mood as you used it.
While playing with the musical menu on WhatsInABandName.com, hover over the musical note icon (♫) on the right side to reveal the scale currently assigned. Click the note icon to change the scale assigned.
I hear what you are saying to me - you are saying "Yes, but tones and scales are tinker toys! I was promised a full on rock anthem with more sexual innuendo than a sex farm!"
Next, I just had to interpret the MIDI data, extract notes and times, and trigger the appropriate menu item.
For this, I turned to the jasmid project which helps extract the data from the MIDI file. I then converted the data into a series of notes and their durations, as well as tempo change events. I then walk through the timeline and trigger the notes, highlight the menu item for some visual fun, and respond to tempo changes.
There were certainly some non-trivial aspects to getting it all working and sounding good - particularly with regard to timing.
But it was all worth it.