Using WebGL + Web Audio. Takes a bit to load. Sorry about that.
hey there
@supersole
var ac = new AudioContext();
"instance factory"
var oscillator = ac.createOscillator();
var gain = ac.createGain();
// etc...
introducing the most important method in nodes
connect()
var oscillator = ac.createOscillator();
oscillator.connect(ac.destination);
var osc1 = ac.createOscillator();
osc1.connect(ac.destination);
var osc2 = ac.createOscillator();
osc2.connect(ac.destination);
var osc3 = ac.createOscillator();
osc3.connect(ac.destination);
// ...
var gain = ac.createGain();
var osc1 = ac.createOscillator();
var filter1 = ac.createBiquadFilter();
osc1.connect(filter1);
filter1.connect(gain);
var osc2 = ac.createOscillator();
var filter2 = ac.createBiquadFilter();
osc2.connect(filter2);
filter2.connect(gain);
// ...
gain.connect(ac.destination);
or...
instead of connecting node to node,
adds node output to node param
but sound sources only output [-1, 1]
is barely audible in most contexts!
multiply input by gain value
var gain = ac.createGain();
var osc = ac.createOscillator();
var gain = ac.createGain();
osc.connect(gain);
gain.connect(ac.destination);
gain.gain.value = 100;
// osc out [-100, 100] now
window.addEventListener('mousemove', function(e) {
var v = e.clientY / window.innerHeight;
gain.gain.setValueAtTime(v, ac.currentTime);
});
gain value as f(mouseY)
var lfOsc = ac.createOscillator();
var lfGain = ac.createGain();
lfOsc.connect(lfGain);
lfGain.gain.setValueAtTime(10, now);
// lfGain outputs [-10, 10]
var osc = ac.createOscillator();
lfGain.connect(osc.frequency);
osc.frequency.setValueAtTime(100, now);
// osc oscillates at [90, 110]
You can build rich and complex graphs...
but how?
events = (mostly) value changes
osc.start(2.0);
osc.frequency.setValueAtTime(440, 3.5);
osc.frequency.linearRampToValueAtTime(880, 13.5);
gain.gain.exponentialRampToValueAtTime(0, 13.5);
(to avoid memory leaks)
(so they're disposed of)
Load binary sample data
Decode
Use it!
var req = new XMLHttpRequest();
req.open('get', samplePath, true);
req.responseType = 'arraybuffer';
req.addEventListener('load', function() {
var response = req.response;
});
context.decodeAudioData(response,
function(decodedBuffer) {
// ...
}, function(error) {
// urgh
});
var bufferSource = ac.createBufferSource();
bufferSource.buffer = decodedBuffer;
bufferSource.connect(ac);
bufferSource.start();
bufferSource.playbackRate
var now = ac.currentTime;
var y = getMouseY();
bufferSource.playbackRate.setValueAtTime(y, now);
var osc = ac.createOscillator();
var stereoPanner = ac.createStereoPanner();
osc.connect(stereoPanner);
// left
stereoPanner.pan.setValueAtTime(-1, now);
// or right
stereoPanner.pan.setValueAtTime(1, now);
ac.listener
var panned = ac.createPanner();
osc.connect(panned);
ac.listener.setPosition(100, 0, 0);
panned.setPosition(0, 0, 0);
var filter = ac.createBiquadFilter();
filter.type = 'lowpass';
filter.connect(ac.destination);
bufferSource.connect(filter);
bufferSource.start();
var analyser = ac.createAnalyser();
bufferSource.connect(analyser);
analyser.connect(ac.destination);
var results = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(results);
(London/Berlin/NY/Philadelphia)
github.com/sole/howa