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 =...