JSFiddle - React, Tailwind, and code Playground

HTML

<input type="text" class="note" value="200">
<input type="text" class="note" value="220">
<input type="text" class="note" value="230">
<input type="text" class="note" value="240">
<input type="button" id="start" value="start">
<input type="button" id="stop" value="stop">
<input type="text" id="step_ms" value="250">

CSS

input[type="text"] {
    display: block;
}

JavaScript

// Comments wrt chrome Chrome 20.0.1132.57, Ubuntu 12.04
var ctx = new webkitAudioContext();
//var node = ctx.createJavaScriptNode(512); // Timing wanders
//var node = ctx.createJavaScriptNode(1024); // Timing wanders
var node = ctx.createJavaScriptNode(4096); // Won't init faster than ~250ms step
var node = ctx.createJavaScriptNode(2048); // Seems to keep timing-accuracy
var osc = ctx.createOscillator();

var notes = [];
var step_ms = $('#step_ms')[0].value;
var elapsed = 0;
var step = 0;
osc.frequency.value = $('.note')[0].value;
node.onaudioprocess = function(evt) {
    osc.frequency.value = notes[step];
    if (elapsed >= step_ms) {
        elapsed = 0;
        osc.disconnect();
        step = (step + 1) % notes.length;
        osc.frequency.value = notes[step];  
        osc.connect(ctx.destination);
    }
    elapsed += evt.outputBuffer.duration * 1000;
};

$('.note').each(function(idx, el) {
    notes[idx] = this.value;
    $(this).on('change', function(evt) {
        notes[idx] = this.value;
    });
});
$('#start').on('click', function(evt) {
    node.connect(ctx.destination);
    osc.connect(ctx.destination);
});
$('#stop').on('click', function(evt) {
    osc.disconnect();
    node.disconnect();
});
$('#step_ms').on('change', function(evt) {
    step_ms = this.value;
});