Duty Cycle Pulse Wave

HTML

<button id="mute">Mute</button><br>
<div class="control"><label>
    Volume <span id="volume-display">0.1</span><br />
    <input id="volume" type="range" min="0" max="1" step="0.02" value="0.1" />
</label></div>
<div class="control"><label>
    Frequency <span id="freq-display">100</span><br />
    <input id="freq" type="range" min="0" max="4" step="0.01" value="2" />
</label></div>
<div class="control"><label>
    Duty Cycle <span id="duty-display">0.1</span><br />
    <input id="duty" type="range" min="0" max="1" step="0.001" value="0.1" />
</label></div>
<p>
    <canvas id="oscilloscope"></canvas>
</p>

CSS

.control {
    display: inline-block;
}
#oscilloscope {
    background-color: #ddd;
}

JavaScript

var context = new webkitAudioContext();
var numCoeffs = 256;
var realCoeffs = new Float32Array(numCoeffs);
var imagCoeffs = new Float32Array(numCoeffs);

function setOscillatorDutyCycle(osc, dc) {
    realCoeffs[0] = dc;
    for (var i = 1; i < numCoeffs; i++) {
        var npi = i * Math.PI;
        realCoeffs[i] = 4 / npi * Math.sin(npi * dc);
    }
    var wave = context.createPeriodicWave(realCoeffs, imagCoeffs);
    osc.setPeriodicWave(wave);
}

var osc = context.createOscillator();
var gain = context.createGain();
setOscillatorDutyCycle(osc, 0.1);
osc.frequency.value = 100;
osc.connect(gain);
gain.connect(context.destination);
gain.gain.value = 0.1;
osc.start(0);


var q = "querySelector";

document[q]("#mute").addEventListener("click", function(e) {
    var volume = this.getAttribute("data-volume");
    if (volume !== null) { // unmute
        gain.gain.value = volume;
        this.removeAttribute("data-volume");
        this.textContent = "Mute";
    } else { // mute
        this.setAttribute("data-volume", gain.gain.value);
        gain.gain.value = 0;
        this.textContent = "Unmute";
    }
}, false);

document[q]("#volume").addEventListener("change", function(e) {
    gain.gain.value = this.value;
    document[q]("#volume-display").textContent = this.value;
}, false);

document[q]("#freq").addEventListener("change", function(e) {
    var f = Math.pow(10, this.value);
    osc.frequency.value = f;
    document[q]("#freq-display").textContent = f;
}, false);

document[q]("#duty").addEventListener("change", function(e) {
    var dc = this.value;
    setOscillatorDutyCycle(osc, dc);
    document[q]("#duty-display").textContent = dc;
}, false);

// Oscilloscope
var analyzerSamples = 512;
var canvas = document[q]("#oscilloscope");
var ctx = canvas.getContext("2d");
canvas.width = analyzerSamples;
canvas.height = 256;

var scriptNode = context.createScriptProcessor(analyzerSamples, 1, 1);
scriptNode.onaudioprocess = function(e) {
    var inp =...