Backbeat experiment

Just some funky rhythms

Log in to post a comment.

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) - 1;

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' });

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});