Topic: Technical Documentation - Part 1: Architecture Overview

Here is a brief high-level overview of the technical architecture.  It's really simple and so it shouldn't take too many words to describe. All code is version-controlled by SVN.  Once you register as a developing community member, you will have full access to the code repository.

The WebApp is driven almost entirely by JavaScript. The sole exception is the use of Scott Schiller's Flash plugin to play actual sounds.  If anybody has a better solution that is more cross-browser than this, I am happy to hear it.  In the meanwhile, it would be good to figure out how to incorporate multiple voices (as in different instruments), get notes to sound better, with less tacky audio.

I won't be describing 3rd party JS components here, namely, the slider bar (slider.js), mouse-over bubble help (tooltips.js), or Scott Schiller's soundmanager JS, for which there is already excellent documentation at his site.

The only remaining JS files are (control.js, carnatic.js and notes.js) and so I'll say a few words about them below.  Hopefully the programs are sufficiently self-documenting and easy enough to read that they make sense on your first perusal.  If not, I'm always here to answer questions about them.

Scale Selection:  See the paper ( … .1.18.9659) cited in carnatic.js for the algorithm used to derive the notes from the Raga name.  It's implemented in a fairly straightforward way in the setScale(ragaNumber) function in carnatic.js.  The onChange() method of the raga selection drop-down is tied to the scale changing function setRaga().  The initial idea is that the scale will be global and chosen once for all of the tracks.  This will set the values of piano key notes attached to each of the 7 notes Sa through Ni. 

After much deliberation, I decided that the best way to get the notes to play was to generate sounds under Linux in the back-end using the open-source "tone" program and store them as individual mp3 files.  You can find all these tones in the directory ( along with the Linux shell script (make-notes) that I used to generate them. As you can see, the JS file notes.js pre-loads all of these mp3s and assigns them soundManager identifiers that we will invoke during play-time.  A subtlety here is that the tone program simply generates raw beeps (sinusoids) for us.  When I play the notes, I decided to progressively attenuate the sound to 0 dB using a series of JS setTimeouts(), which makes the beep sound less harsh, and more like a bell.  Interestingly, this effect was a purely unintended by-product of my as yet unsuccessful attempt to fix the clicking sound when a note was stopped.  I mistakenly assumed it to be caused by the hard truncation of the sinusoid and hence attempted to attenuate the wave before trunctation.  But alas, that was not the case, the awful click remains, but the pleasant morph to bell-like quality was born :-)

When the "Play All Tracks" button is clicked, the function "ProcessAllTracks()" is called.  This will simply iterate through the div element labeled "tracks", sequentially process each of the nested divs within it that have a text-area labeled "notes".  The processing of any one such track involves the parsing of the contents, and identifying individual notes to be played from it in sequence, along with their durations.  Each such note is entered into a vector of notes, which itself is stored in a global array of vectors called NotesByTrack[].

At play time, the program iterates through all of the vectors stored in NotesByTrack[], and plays each note in each track, setting a timeout for the next note in sequence to start playing just as the current note finishes.