score playing (bug)

by jmchen

HTML

<button id='test' style='margin:10px'>test</button>: c4, e4
<br/>
<button id='test2' style='margin:10px'>test2</button>: only last sound
<br/>
<button id='test3' style='margin:10px'>test3</button>: no sound

JavaScript

var noteTable = [{ note: 'c4', frequency: 261.63}, 
                 { note: 'e4', frequency: 329.63}];

/////////////////////////////////////////////////////////////////////
var ac = new(window.AudioContext || window.webkitAudioContext);

function Sound(frequency, type) {
    this.frequency = frequency || 440;
    this.type = type || 'triangle';
};

Sound.prototype.noteOn = function () {
    this.osc = ac.createOscillator();
    this.osc.connect(ac.destination);
    this.osc.frequency.value = this.frequency;
    this.osc.type = this.type;
    this.osc.start(0);
};

Sound.prototype.noteOff = function () {
    this.osc.stop(0);
};

// initialize sounds in the noteTable
var sounds = [];
for (var i = 0; i < noteTable.length; i++) {
    var ss = new Sound(noteTable[i].frequency);
    ss.name = noteTable[i].note;
    sounds.push(ss);
}

var score = [{time: 500, event: 'on', note: 'e4'},
             {time: 1200, event: 'off', note: 'e4'},
             {time: 1500, event: 'on', note: 'c4'},
             {time: 2500, event: 'off', note: 'c4'},
            ];


function FindSound (name) {
    for (var i = 0; i < sounds.length; i++) {
        if (sounds[i].name === name)
            return sounds[i];
    }
    return null;
}

//////////////////////////////////////////////////////////////////

$('#test').click(function () {
    // these (with anonymous functions) work
    setTimeout (function() {
        sounds[0].noteOn();
    }, 0);
    setTimeout (function() {
        sounds[0].noteOff();
   }, 500);

    setTimeout (function() {
        sounds[1].noteOn();
    }, 500);
    setTimeout (function() {
        sounds[1].noteOff();
   }, 1500);

/*
    // the following cannot work
    setTimeout (sounds[0].noteOn(), 0);
    setTimeout (sounds[0].noteOff(), 50);
*/    
});


// bug: only place the last note in score (c4)
// because both ss are c4 when timeout is executed ?!
$('#test2').click ( function() {
    for (var i = 0; i < score.length; i++) {
        var ss =...