Fork: Wide snare

I modified slightly the sound generation of Ollerich's snare to improve the click and the body, and add distortion and a slight "fake compression" effect for increased tension.

Log in to post a comment.

// Forked from "Wide snare" by Ollerich
// https://dittytoy.net/ditty/3358aafcb7


const TAU = Math.PI * 2;
const sin = Math.sin;

ditty.bpm = 120;

input.note = 53; // min=35, max=80, step=0.5
input.wide = 0; // min=0, max=1, step=1

const rand = () => 2*Math.random()-1;
function smoothstep(a,b,x) {
    let y = (x-a)/(b-a);
    if(y < 0) { return 0; }
    if(y > 1) { return 1; }
    return 2*y*y*(1.5-y);
}

const Snare = synth.def(class {
    constructor(options) {
        this.t = 0; Math.random();
    }
    fm(fc, fm, iom, t) {
        return sin(fc*TAU*t + iom*sin(fm*TAU*t));
    }
    snare(f, t) {
        let sig = 0;
        // click
        // I changed this to a white noise impulse
        sig += rand() * 0.3 * Math.exp(-300*t);

        // body
        // I like to use a rather small iom for snares
        // and a modulator frequency of 2*fb so that we hear the third harmonic
        // (in fact, since we use distortion later on, we could simply use a sine or triangle wave)
        const df = -f*1.5 * t;
        const fb = f+df;
        const iom = 1.0*Math.exp(-10*t); // iom goes from 1.0 to 0.0
        sig += this.fm(fb, fb*2, iom, t) * 0.5 * Math.exp(-35*t);

        // noise
        // This could be changed to a "colored noise" (bandlimited noise)
        // for more character ; but we can also simply stick with white noise
        sig += rand() * 0.3 * Math.exp(-20*t);
        
        // distortion
        // I like to add some distortion to the snare drum, to make the different elements interact.
        // This has the effect of enriching the body spectrum, and modulating the noise a bit,
        // but it can also kill the click if overused.
        let sig2 = 0.5 * sig; // larger number = more distortion
        sig2 = clamp(sig2, -1, 1);
        sig *= 1 - sig2*sig2;
        
        // envelope
        // Use a fake compression effect: in modern music drum sounds are often compressed,
        // here we achieve this simply by adding an envelope which turns down the middle part of the sound
        // while letting the click and final resonance through.
        // Counter-intuitively, although it turns *down* the sound, it makes the drum sound *more* present and energic.
        let env = smoothstep(0.01, 0.0, t) /* let some attack through */ + smoothstep(0.0, 0.2, t); /*and some body at the end */
        env = lerp(env, 1.0, 0.4); // larger mix value = less compression
        sig *= env;
        return sig;
    }
    process(note, env, tick, options) {
        const f = midi_to_hz(input.note);
        this.t += ditty.dt;

        let l,r = 0;
        if (input.wide) {
            l = this.snare(f, this.t*1.01);
            r = this.snare(f, this.t*0.99);
        } else {
            l = this.snare(f, this.t);
            r = l;
        }
        //sig += this.snare(f, this.t);

        return [l,r];
    }
});

loop( () => {
    Snare.play();
    sleep(2);

}, { name: 'Snare' });