function Melody(str, tempo) { this.tempo = tempo; this.notes = []; this.octave = 4; this.lastNote = null; // parse the melody string... var l = str.length; var cCode = 'C' str = str.toUpperCase(); for (var i = 0; i < l; ++i) { var c = str.charAt(i); if (c >= 'A' && c <= 'G') { if (this.lastNote != null) { this.notes[this.notes.length] = this.octave * 12 + this.lastNote - 48; } var noteInOctave; switch (c) { case 'C': noteInOctave = 0; break; case 'D': noteInOctave = 2; break; case 'E': noteInOctave = 4; break; case 'F': noteInOctave = 5; break; case 'G': noteInOctave = 7; break; case 'A': noteInOctave = 9; break; case 'B': noteInOctave = 11; break; } this.lastNote = noteInOctave; } else if (c >= '0' && c <= '9') { this.octave = parseInt(c); } else if (c == '+' || c == '#') { this.lastNote++; } else if (c == '-') { this.lastNote--; } else { // any other char is counted as a rest this.lastNote == null; } } this.notes[this.notes.length] = this.octave * 12 + this.lastNote - 48; } Melody.prototype.noteFrequency = function (noteNum) { return 440 * Math.pow(2, (noteNum-9)/12); } Melody.prototype.getCurrentFrequency = function (t) { var currentBeat = Math.floor(t * this.tempo / 60); return this.noteFrequency(this.notes[currentBeat]); } Melody.prototype.length = function () { // returns score length in seconds return this.notes.length * 60 / this.tempo; }