const PI = 3.1415926;
const sin = Math.sin;
const cos = Math.cos;
const abs = Math.abs;
const rnd = () => Math.random() * 2 - 1;
function sinsaw(p,f) {
p = p%1;
return (1-p) * sin(2*PI*f*p);
}
const tri = (p) => 2*abs(p%1 - 0.5) - 0.5;
function softsat(x) {
x = clamp(x,-1,1);
return x*(3-x*x)/2;
}
const ssaw = synth.def(
(p,e,t,o) => sinsaw(p,o.f)*e.value,
{attack:1e-3, release:0.2, duration:0.0, f:5}
);
const kick = synth.def(
(p,e,t,o) => softsat(o.a*tri(o.f0*t*(2*o.d-t))*clamp01(o.d-t)),
{f0:500,d:0.2,a:6}
);
ditty.bpm = 150;
loop( (i) => {
//let f = 5**(1-cos(2*PI*i/64));
let f = 10**((i/64)%1);
let amp = 3 - abs((i%4)-2);
f *= amp/3;
ssaw.play(a2, {f:f, amp:amp, pan:rnd()});
ssaw.play(a2, {f:f+rnd(), amp:amp, pan:rnd()});
ssaw.play(a1, {f:2 + f/4, amp:amp});
sleep(0.25);
}, { name: 'bass', amp: 0.5});
loop( (i) => {
let pattern = "kk....kk.kk...k.";
if(pattern.charAt(i%16) == "k") {
let r = 1.0 + 0.1*rnd();
kick.play(c4, {f0:20,d:1.0,a:1.0}); // bass
//sine.play((t) => a1 + 3*(0.5-t), {attack:0.0, release:0.2, duration:0.5});
kick.play(c4, {f0:300*r,d:0.2,a:6}); // thump
kick.play(c4, {f0:1e8*r,d:0.01,a:20}); // click
kick.play(c4, {f0:1e7*r,d:0.05,a:3}); // click, softer
}
sleep(0.25);
}, {name:'kick', amp:1});
loop( (i) => {
let pattern = "..SS.ss.SssSssSS";
if(pattern.charAt(i%16) == "S") {
let r = 1.0 + 0.1*rnd();
kick.play(c4, {f0:600*r,d:0.2,a:2}); // thump
kick.play(c4, {f0:1e7,d:0.2,a:6*r,amp:0.3}); // noise
kick.play(c4, {f0:6e7*r,d:0.02,a:30,amp:0.7}); // click
} else if (pattern.charAt(i%16) == "s") {
let r = 1.0 + 0.5*rnd();
kick.play(c4, {f0:300*r,d:0.2,a:1}); // thump
kick.play(c4, {f0:1e7,d:0.2,a:3*r,amp:0.1}); // noise
kick.play(c4, {f0:6e7*r,d:0.02,a:30,amp:0.2}); // click
}
sleep(0.25);
}, {name:"snare"});
loop( (i) => {
let pattern = 'k.k.s.kskskks.ks';
for(let j=0; j<pattern.length; j++) {
let r = 1.0 + 0.2*rnd();
switch(pattern.charAt(j)) {
case 'k':
kick.play(c4, {f0:200*r,d:0.3,a:20,amp:0.3,pan:rnd()}); // thump
kick.play(c4, {f0:1e6*r,d:0.2,a:3,amp:0.1,pan:rnd()}); // noise
break;
case 's':
kick.play(c4, {f0:300*r,d:0.3,a:20,amp:0.07,pan:rnd()}); // thump
kick.play(c4, {f0:1.5e6*r,d:0.3,a:3,amp:0.15,pan:rnd()}); // noise
break;
}
let d = 0.25;
d += 0.05 * ((j%2==0) ? 1 : -1);
sleep(d);
}
}, {name:"backbeat"});
loop((i) => {
kick.play(c4, {f0:5e6,d:0.05,a:30,amp:0.1,pan:rnd()}); // click, softer
let d1 = 0.52*0.5;
sleep(d1);
kick.play(c4, {f0:1.5e6,d:0.1,a:30,amp:0.1,pan:rnd()}); // click, softer
sleep(0.5-d1);
}, {name:"hat"});
loop( (i) => {
let padChords = [
[e3,a3,d4,e4,a4,b4,d5,e5],
[d3,b3,e4,f4,a4,b4,e5,f5]
];
let ch = padChords.ring(i);
for(let j=0; j<ch.length; j++) {
let off = rnd();
ssaw.play(ch[j], {
f:(t)=>1.5+cos(PI*t*0.5+off),
amp:(t)=>1-0.6*cos(PI*(t%1)),
attack:0.5, release:2, duration:16,
pan:(t)=>cos(PI*t+j)
});
}
sleep(16);
}, {name:"pad", amp:0.1});