wobbulator

main
Michael Murtaugh 1 month ago
parent f6b3f603f5
commit 539f6262a7

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Untitled</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<p>A remake (2024) of <a href="https://webaudio.prototyping.bbc.co.uk/wobbulator/">this artcle on the wobbulator from the BBC Radiophonic workshop</a>.</p>
<input type="checkbox" id="power">
<input type="range" id="modfreq" min="0" max="50" value="10" step="1">
<input type="range" id="moddepth" min="0" max="200" value="100" step="1">
<input type="range" id="freq" min="50" max="5000" value="440" step="1">
<input type="range" id="vol" min="0" max="1" value="1" step="0.01">
<select id="waveform">
<option>sine</option>
<option>square</option>
<option>sawtooth</option>
</select>
<script src="wobbulator.js"></script>
</body>
</html>

@ -0,0 +1,50 @@
let ac = new AudioContext();
// There are four main audio nodes in our webaudio API patchbay
// The primary oscillator + the modulating oscillator.
// The amplitude of the modulation oscillator (its 'depth') is modified by passing the output through a GainNode.
// Another GainNode controls the main volume.
let oscillator = ac.createOscillator();
let modulator = ac.createOscillator();
let modulation_gain = ac.createGain();
let main_gain = ac.createGain();
// Make the patches!
modulator.connect(modulation_gain);
modulation_gain.connect(oscillator.frequency);
oscillator.connect(main_gain);
main_gain.connect(ac.destination);
// Once an OscillatorNode is stopped it cannot be restarted.
// We turn both oscillators on from the beginning,
// and achieve the on/off effect by modifying the main gain.
oscillator.start(0);
modulator.start(0);
// inputs
let freq_input = document.querySelector("#freq");
let modfreq_input = document.querySelector("#modfreq")
let moddepth_input = document.querySelector("#moddepth")
let vol_input = document.querySelector("#vol");
let power_checkbox = document.querySelector("#power");
let waveform_select = document.querySelector("#waveform");
oscillator.frequency.value = freq_input.value;
modulation_gain.gain.value = moddepth_input.value;
modulator.frequency.value = modfreq_input.value;
main_gain.gain.value = power_checkbox.checked ? vol_input.value : 0;
freq_input.addEventListener("input", e => { oscillator.frequency.value = freq_input.value; });
power_checkbox.addEventListener("change", e => {
main_gain.gain.value = power_checkbox.checked ? vol_input.value : 0;
// check if context is in suspended state (autoplay policy)
if (ac.state === "suspended") { ac.resume(); }
});
modfreq_input.addEventListener("input", e => { modulator.frequency.value = modfreq_input.value });
moddepth_input.addEventListener("input", e => { modulation_gain.gain.value = moddepth_input.value });
vol_input.addEventListener("input", e => { main_gain.gain.value = power_checkbox.checked ? vol_input.value : 0 });
oscillator.type = waveform_select.value;
waveform_select.addEventListener("input", e => {
oscillator.type = waveform_select.value;
});
Loading…
Cancel
Save