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; });