Skip to content

Instantly share code, notes, and snippets.

@hoch
Last active February 3, 2017 19:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hoch/5d2bfc3d7d6ee009ac2c to your computer and use it in GitHub Desktop.
Save hoch/5d2bfc3d7d6ee009ac2c to your computer and use it in GitHub Desktop.
Gist Repository for Canopy app - http://hoch.github.io/canopy/
// What can I say? THX(TM) runs deep!
// @channels 2
// @duration 8
var targets = [
29.0, 87.5, 116.0, 175.0, 233.0,
350.0, 524.0, 880.0, 1048, 1760,
29.0, 87.5, 116.0, 175.0, 233.0,
350.0, 524.0, 880.0, 1048, 1760,
29.0, 87.5, 116.0, 175.0, 233.0,
350.0, 524.0, 880.0, 1048, 1760
];
var initials = [];
var saws = [];
var amps = [];
var pans = [];
for (var i = 0; i < 30; i++) {
initials[i] = Math.random() * 600 + 200;
saws[i] = context.createOscillator();
amps[i] = context.createGain();
pans[i] = context.createStereoPanner();
saws[i].type = 'sawtooth';
saws[i].frequency.setValueAtTime(initials[i], 0.0);
pans[i].pan.setValueAtTime(Math.random() * 2 - 1, 0.0);
amps[i].gain.setValueAtTime(0.125, 0.0);
saws[i].connect(amps[i]);
amps[i].connect(pans[i]);
pans[i].connect(context.destination);
saws[i].start();
saws[i].frequency.exponentialRampToValueAtTime(targets[i], 3.0);
pans[i].pan.linearRampToValueAtTime(Math.random() * 2 - 1, 3.0);
amps[i].gain.setValueAtTime(0.125, 6.0);
amps[i].gain.linearRampToValueAtTime(0.0, 7.5);
}
// Using two BufferSourceNodes as a phasor (unipolar sawtooth oscillator).
var phasorNode = context.createBufferSource();
var phasorBuffer = context.createBuffer(1, context.sampleRate, context.sampleRate);
var phasorChannelData = phasorBuffer.getChannelData(0);
var dcNode = context.createBufferSource();
var dcBuffer = context.createBuffer(1, context.sampleRate, context.sampleRate);
var dcChannelData = dcBuffer.getChannelData(0);
var acc = 0, step = 1 / context.sampleRate, i;
for (i = 0; i < phasorChannelData.length; i++) {
phasorChannelData[i] = (acc % 1);
acc += step;
}
for (i = 0; i < dcChannelData.length; i++) {
dcChannelData[i] = 200;
}
phasorNode.buffer = phasorBuffer;
phasorNode.loop = true;
dcNode.buffer = dcBuffer;
dcNode.loop = true;
dcNode.connect(phasorNode.playbackRate);
phasorNode.connect(context.destination);
dcNode.start();
phasorNode.start();
// @channels 1
// @duration 1.0
// @sampleRate 44100
// Replace the file name.
loadAudioFile('audiofile.m4a', function (buffer) {
var c = buffer.getChannelData(0);
// To make start/end points visible.
c[0] = 1.0;
c[c.length-1] = 1.0;
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start();
context.resume();
}, function (error) {
console.log(error);
});
context.suspend(0);
function loadAudioFile(url, onload, onerror) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function () {
context.decodeAudioData(request.response, onload, onerror);
};
request.send();
}
// requires('foa-spatializer.js', 'pcm-exporter.js')
//
// @channels 2
// @duration 10
var streamSource;
var rotator;
var phaseMatchedFilter;
var virtualSpeakers = [];
var speakerData = [{
name: 'E35.26_A45', // <0.5774,0.5774,-0.5774>
url: 'data/symmetric_cube/E35.26_A45_D1.4.wav',
coef: [.1250, 0.216494623077544, 0.216529812402237, -0.216494623077545]
}, {
name: 'E35.26_A-45', // <0.5774,-0.5774,-0.5774>
url: 'data/symmetric_cube/E35.26_A-45_D1.4.wav',
coef: [.1250, 0.216494623077544, -0.216529812402236, -0.216494623077544],
}, {
name: 'E35.26_A-135', // <-0.5774,-0.5774,-0.5774>
url: 'data/symmetric_cube/E35.26_A-135_D1.4.wav',
coef: [.1250, -0.216494623077544, -0.216529812402236, -0.216494623077545],
}, {
name: 'E35.26_A135', // <-0.5774,0.5774,-0.5774>
url: 'data/symmetric_cube/E35.26_A135_D1.4.wav',
coef: [.1250, -0.216494623077545, 0.216529812402237, -0.216494623077545],
}, {
name: 'E-35.26_A45', // <0.5774,0.5774,0.5774>
url: 'data/symmetric_cube/E-35.26_A45_D1.4.wav',
coef: [.1250, 0.216494623077544, 0.216529812402237, 0.216494623077545],
}, {
name: 'E-35.26_A-45', // <0.5774,-0.5774,0.5774>
url: 'data/symmetric_cube/E-35.26_A-45_D1.4.wav',
coef: [.1250, 0.216494623077544, -0.216529812402236, 0.216494623077545],
}, {
name: 'E-35.26_A-135', // <-0.5774,-0.5774,0.5774>
url: 'data/symmetric_cube/E-35.26_A-135_D1.4.wav',
coef: [.1250, -0.216494623077544, -0.216529812402237, 0.216494623077545],
}, {
name: 'E-35.26_A135', // <-0.5774,0.5774,0.5774>
url: 'data/symmetric_cube/E-35.26_A135_D1.4.wav',
coef: [.1250, -0.216494623077545, 0.216529812402237, 0.216494623077545]
}, {
name: 'stream-source',
url: 'data/4ch_B_FuMaNorm_FuMaOrd_speech.wav'
}];
function initialize(buffers) {
streamSource = context.createBufferSource();
streamSource.buffer = buffers.get('stream-source');
rotator = FOASpatializer.createRotator(context);
phaseMatchedFilter = FOASpatializer.createPhaseMatchedFilter(context, {
frequency: 700,
coefficients: [1.4142, 0.8166, 0.8166, 0.8166]
});
streamSource.connect(rotator.input);
rotator.output.connect(phaseMatchedFilter.input);
for (var i = 0; i < speakerData.length - 1; ++i) {
virtualSpeakers[i] = FOASpatializer.createVirtualSpeaker(context, {
coefficients: speakerData[i].coef,
IR: buffers.get(speakerData[i].name),
gain: 22.0
});
phaseMatchedFilter.output.connect(virtualSpeakers[i].input);
}
streamSource.start();
context.resume();
}
context.suspend(0);
context.loadAudioFiles(speakerData).then(initialize);
// Hello Canopy!
var sin = new OscillatorNode(context);
var amp = new GainNode(context);
sin.connect(amp).connect(context.destination);
amp.gain.value = 0.707;
sin.start();
// A basic example of enveloping.
var sin = context.createOscillator();
var amp = context.createGain();
sin.connect(amp);
amp.connect(context.destination);
amp.gain.setValueAtTime(0.0, 0);
amp.gain.linearRampToValueAtTime(1.0, 1);
amp.gain.linearRampToValueAtTime(0.0, 2);
sin.start();
// An example of using oncomplete event handler.
// @channels 1
// @sampleRate 12800
// @duration 0.5
var osc = context.createOscillator();
osc.type = 'sawtooth';
osc.connect(context.destination);
osc.start();
context.oncomplete = function (event) {
console.log(event.renderedBuffer.length);
};
// A simple FM synthesis example.
var osc1 = context.createOscillator();
var modGain = context.createGain();
var osc2 = context.createOscillator();
osc1.connect(modGain);
modGain.connect(osc2.frequency);
osc2.connect(context.destination);
osc1.frequency.value = 31;
modGain.gain.value = 113;
osc2.frequency.value = 97;
osc1.start();
osc2.start();
// Sine sweep.
var osc = context.createOscillator();
osc.connect(context.destination);
osc.frequency.setValueAtTime(1, 0.0);
osc.frequency.linearRampToValueAtTime(22050, 3.0);
osc.start();
// Smile! But lower your volume first...
//
// @duration 1.25
var osc1 = context.createOscillator();
osc1.frequency.setValueAtTime(11000, 0.1);
osc1.frequency.exponentialRampToValueAtTime(9000, 0.15);
osc1.frequency.exponentialRampToValueAtTime(11000, 0.2);
osc1.connect(context.destination);
osc1.start(0.1);
osc1.stop(0.2);
var osc2 = context.createOscillator();
osc2.frequency.setValueAtTime(15000, 0.1);
osc2.frequency.exponentialRampToValueAtTime(15500, 0.12);
osc2.frequency.exponentialRampToValueAtTime(15000, 0.14);
osc2.connect(context.destination);
osc2.start(0.1);
osc2.stop(0.14);
var osc3 = context.createOscillator();
osc3.frequency.setValueAtTime(15000, 0.16);
osc3.frequency.exponentialRampToValueAtTime(15500, 0.18);
osc3.frequency.exponentialRampToValueAtTime(15000, 0.2);
osc3.connect(context.destination);
osc3.start(0.16);
osc3.stop(0.2);
var osc4 = context.createOscillator();
osc4.frequency.setValueAtTime(12500, 0.07);
osc4.frequency.exponentialRampToValueAtTime(20000, 0.09);
osc4.frequency.setValueAtTime(20000, 0.21);
osc4.frequency.exponentialRampToValueAtTime(12500, 0.23);
osc4.connect(context.destination);
osc4.start(0.07);
osc4.stop(0.23);
var osc5 = context.createOscillator();
osc5.frequency.setValueAtTime(12500, 0.07);
osc5.frequency.exponentialRampToValueAtTime(5000, 0.09);
osc5.frequency.setValueAtTime(5000, 0.21);
osc5.frequency.exponentialRampToValueAtTime(12500, 0.23);
osc5.connect(context.destination);
osc5.start(0.07);
osc5.stop(0.23);
// An example of multichannel rendering.
// @channels 3
var sin = context.createOscillator();
var saw = context.createOscillator();
var sqr = context.createOscillator();
var merger = context.createChannelMerger(3);
saw.type = 'sawtooth';
sqr.type = 'square';
sin.frequency.value = 60;
saw.frequency.value = 60;
sqr.frequency.value = 60;
sin.connect(merger, 0, 0);
saw.connect(merger, 0, 1);
sqr.connect(merger, 0, 2);
merger.connect(context.destination);
sin.start();
saw.start();
sqr.start();
// The 80's time warp sound example with a resonant LPF and a sawtooth oscillator.
var saw = context.createOscillator();
var lfo = context.createOscillator();
var lfoDepth = context.createGain();
var lpf = context.createBiquadFilter();
var amp = context.createGain();
saw.connect(lpf);
lfo.connect(lfoDepth);
lfoDepth.connect(saw.frequency);
lfoDepth.connect(lpf.frequency);
lpf.connect(amp);
amp.connect(context.destination);
saw.type = 'sawtooth';
lpf.frequency.value = 2000;
lpf.Q.value = 8;
amp.gain.value = 0.5;
lfo.frequency.setValueAtTime(1, 0.0);
lfo.frequency.exponentialRampToValueAtTime(20, 3.0);
lfoDepth.gain.setValueAtTime(0.1, 0.0);
lfoDepth.gain.linearRampToValueAtTime(1900, 3.0);
saw.start();
lfo.start();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment