Based on gist.github.com/samaaron/3f41f913bf6d1b6bf036 by @samaaron
#Bizet
Log in to post a comment.
ditty.bpm = 130;
const noise = synth.def( (phase, env, tick, options) => (Math.random() * 2 - 1) * env.value, { attack: 0.0125, release: 0.15, env: adsr2 });
const kick = synth.def( (phase, env, tick, options) => Math.sin(phase * 2 * Math.PI * (1.5 - tick * 4)) * env.value, { attack: 0.025, release: 0.15, amp: 1, env: adsr2 });
const tri = synth.def( (phase, env, tick, options) => { const v = (phase % 1) * 4; return (v < 2 ? v - 1 : 3 - v) * env.value }, { attack: 0.025, release: 0.5, amp: .8, env: adsr2 });
const lowpass = filter.def(class {
constructor(options) {
this.hist0 = [0, 0];
this.hist1 = [0, 0];
}
process(input, options) {
const alpha = options.cutoff;
if (input) {
for (let i = 0; i < 2; i++) {
this.hist0[i] += alpha * (input[i] - this.hist0[i]);
this.hist1[i] += alpha * (this.hist0[i] - this.hist1[i]);
}
return this.hist1;
}
}
}, {cutoff: 1});
const delay = filter.def(class {
constructor(options) {
this.index = 0;
this.length = options.interval * ditty.sampleRate * 60 / ditty.bpm | 0;
this.left = new Float32Array(this.length);
this.right = new Float32Array(this.length);
}
process(input, options) {
if (input) {
this.index = (this.index + 1) % this.length;
const hist = (this.index + 1) % this.length;
const s = options.strength;
this.left [this.index] = input[1] + s * this.right[hist];
this.right[this.index] = input[0] + s * this.left [hist];
return [ this.left[this.index], this.right[this.index] ];
}
}
}, { interval: 3 / 4, strength: 0.15 });
loop( (loopCount) => {
if ((loopCount % 16) < 12) kick.play(c3);
}, { sync: 1, name: 'kick', amp: 1.6 });
loop( (loopCount, options) => {
sleep(1);
noise.play(c3, { amp: .7, pan: Math.random() - .5});
sleep(1);
}, { name: 'snare' })
.connect( delay.create( {} ) )
.connect( lowpass.create( { cutoff: .3 } ) );
loop( () => {
noise.play(c3, { amp: 0.02 + 0.02 * Math.random() });
sleep(0.25);
}, { name: 'hi-hat' });
loop( () => {
sine.play(d3, { attack: 0.025, release: 24, amp: (tick, options) => .6 + .5 * Math.sin(tick * Math.PI * 4) });
for (let i=0; i<6; i++) {
[d3, 0, 0, a3, f4, 0, a3, 0].forEach( note => {
if (note) tri.play(note, { pan: (tick, options) => Math.sin(ditty.time)});
sleep(.25);
});
}
sine.play(g3, { attack: 0.025, release: 8, amp: (tick, options) => .6 + .5 * Math.sin(tick * Math.PI * 4) });
for (let i=0; i<2; i++) {
[d3, 0, 0, Bb3, g4, 0, Bb3, 0].forEach( note => {
if (note) tri.play(note, { pan: (tick, options) => Math.sin(ditty.time)});
sleep(.25);
});
}
}, { name: 'melody' })
.connect( delay.create( {} ) )
.connect( lowpass.create( { cutoff: () => .4 + .3 * Math.sin(ditty.time) } ) );