Paul Adenot (@padenot), Mozilla, JSConf.Asia 2015
My simpl(e|istic) definition.
A note each beat for a quarter beat, 140 times a minute
A4 - B4 - E4 - A3 - B3
Harsh - pure - pitched - metallic - vocal - bowed
AudioContext
+ AudioNode
+ AudioParam
partial interface AudioContext { readonly attribute AudioNode destination; readonly attribute double currentTime; // play audio buffers AudioBufferSourceNode createBufferSource(); // change volume GainNode createGain(); // play simple wave forms (sine, square, etc.) OscillatorNode createOscillator(); // filter the sounds BiquadFilterNode createBiquadFilter(); }
partial interface OscillatorNode { AudioNode connect(AudioNode node); void disconnect(AudioNode node); readonly AudioParam frequency; readonly AudioParam detune; enum OscillatorType type; void start(double startTime); void stop(double stopTime); }
partial interface AudioParam { attribute float value; void setValueAtTime(float value, double time); void exponentialRampToValueAtTime(float value, double time); void linearRampToValueAtTime(float value, double time); void setTargetAtTime(float value, double time, float constant); }
var osc = ac.createOscillator(); var gain = ac.createGain(); osc.type = "sine"; osc.frequency.value = 440.; // A4 input1.oninput = (e) => osc.frequency.value = e.target.value input2.oninput = (e) => gain.gain.value = e.target.value osc.connect(gain); gain.connect(ac.destination); osc.start();
var osc = ac.createOscillator(); osc.frequency.value = 100; var gain = ac.createGain(); osc.connect(gain); gain.connect(ac.destination) osc.start(); setInterval(function() { gain.gain.setValueAtTime(1.0, ac.currentTime); gain.gain.setTargetAtTime(0.0, ac.currentTime, 0.3); }, 500);
var osc = ac.createOscillator(); var gain = ac.createGain(); osc.connect(gain); gain.connect(ac.destination) osc.start(); setInterval(function() { gain.gain.setValueAtTime(1.0, ac.currentTime); gain.gain.setTargetAtTime(0.0, ac.currentTime, 0.12); osc.frequency.setValueAtTime(100.0, ac.currentTime); osc.frequency.setTargetAtTime(45.0, ac.currentTime, 0.07); }, 300);
var osc1 = ac.createOscillator(); var osc2 = ac.createOscillator(); osc1.type = "sawtooth"; osc2.type = "sawtooth"; osc1.frequency.value = osc2.frequency.value = 80; input1.oninput = (e) => osc2.detune.value = e.target.value input2.oninput = (e) => osc1.frequency.value = osc2.frequency.value = e.target.value osc1.connect(ac.destination); osc2.connect(ac.destination); osc1.start(); osc2.start();
var osc = ac.createOscillator(); var gain = ac.createGain(); osc.type = "sine"; osc.frequency.value = 440.; // A4 input1.oninput = (e) => osc.frequency.value = e.target.value input2.oninput = (e) => gain.gain.value = e.target.value osc.connect(gain); gain.connect(ac.destination); osc.start();
var osc = ac.createOscillator(); var osc2 = ac.createOscillator(); var gain = ac.createGain(); var biquad = ac.createBiquadFilter(); osc.type = "sawtooth"; osc.frequency.value = osc1.frequency.value = 110.; // A2 osc2.detune.value = 30; biquad.type = "lowpass"; input1.oninput = (e) => biquad.frequency.value = e.target.value input2.oninput = (e) => biquad.gain.value = e.target.value input3.oninput = (e) => biquad.Q.value = e.target.value option.onchange = (e) => biquad.type = e.target.value osc.connect(gain).connect(biquad).connect(ac.destination); osc.start(); osc2.start();
var source = ac.createBufferSource(); var buffer = ac.createBuffer(1, 1 * ac.sampleRate, ac.sampleRate); var channel = buffer.getChannelData(0); /* [-1, 1] */ for (var i = 0; i < channel.length; i++) { channel[i] = Math.random() * 2 - 1; } source.loop = true; source.buffer = buffer; source.connect(ac.destination); source.start();
fetch('clap.ogg').then((response) => { response.arrayBuffer().then((arraybuffer) => { ac.decodeAudioData(arraybuffer).then((buffer) => { var source = ac.createBufferSource(); source.buffer = buffer; source.loop = true; source.connect(ac.destination); source.start(); }); }); });
(More or less) the live coded program in literate style:
https://padenot.github.io/litsynth
Search for "Synths secrets" to learn more about synthesis !
{Twitter, GitHub}: @padenot
<padenot@mozilla.com>