Rio
Rio

Reputation: 14882

Web Audio scheduling instead plays back immediately

I'm trying to play notes from Web Audio in a way that is set by the tempo, much like the Google Chromium Shiny Drum Machine example. Notes play subsequently going downwards, and each row contains two octaves of notes (to demo, go here and click on Sticky before selecting notes, then click Start)

enter image description here

I have a start button:

$("#start").click(function () {
    noteTime = 0.0;
    startTime = audioCtx.currentTime + 0.005;
    schedule();
});

a schedule function:

function schedule() { var currentTime = audioCtx.currentTime;

currentTime -= startTime;

while (noteTime < currentTime + 0.200) {
    var contextPlayTime = noteTime + startTime;

    for (var i = 0; i < theArray.length; i++) {
        if ($("." + rhythmIndex + ".bar" + i).hasClass("selected")) {
            $("." + rhythmIndex + ".bar" + i).effect("highlight", {}, 10);
            playSound($("." + rhythmIndex + ".bar" + i).attr("freq"), 400, contextPlayTime);
        }
    }
    advanceNote();
}

timeoutId = setTimeout("schedule()", 0);

}

and advance note function which selects the next playing note:

function advanceNote() {
    // Advance time by a 16th note...
    var secondsPerBeat = 60.0 / $("#tempo").slider("option", "value");

    rhythmIndex++;

    if (rhythmIndex == loopLength) {
        rhythmIndex = 0;
    }

    noteTime = secondsPerBeat;
}

and finally my sound player:

function playSound(x, y, quick, noteTime) {
    if (soundBuffer) {
        var sound = audioCtx.createBufferSource();
        var gain = audioCtx.createGainNode();
        sound.buffer = soundBuffer;
        sound.playbackRate.value = x / canvas.width * 2;
        sound.connect(gain);
        gain.connect(audioCtx.destination);

        var volume = 0.5;
        gain.gain.value = volume;

        if (quick) {
            sound.noteGrainOn(0., .2, .4);
        } else {
            sound.noteOn(noteTime);
        }
    }
}

The problem is that as soon as you hit start, it plays each note simultaneously without any consideration of timing or tempo. It all ends up overloading the browser when the sound just continues playing every second, and I have no idea what could be wrong. What is amiss here?

Thanks in advance!

Upvotes: 0

Views: 238

Answers (1)

Rio
Rio

Reputation: 14882

Never mind! The fix was that noteTime is incremental, so noteTime = secondsPerBeat should have been noteTime += secondsPerBeat;

Upvotes: 2

Related Questions