Snare playground

I was experimenting with synthesised drum sounds, snare in particular. Still some way to go.

Log in to post a comment.

// Play around with the sliders to create different types of snare sounds
// Enjoy!

const sin = Math.sin;
const TAU = 2*Math.PI;
ditty.bpm = 120;

input.note = 38.0; // min=1, max=100, step=0.5
input.add = 1.6; // min=0, max=10, step=0.1
input.spd = 8.4; // min=1, max=20, step=0.1
input.mul = 3.0; // min=0, max=100, step=0.50
input.iom = 2.5; // min=0, max=100, step=0.50
input.limit = 100; // min=1, max=400, step=1
input.mix = 0.5; // min=0, max=1, step=0.05

const SnareTest = synth.def(class { // use sustain: 0
    constructor(opt) {
        this.t = 0;
        this.noise_decay = 8; // higher values will make the noise-part decay faster
        // how to mix partials
        this.fm_gain = input.mix;
        this.noise_gain = 1 - this.fm_gain;
    }
    add_fm(carrier) {
        // modulator frequency
        const fm = carrier * input.mul;
        let mod = sin(TAU*this.t*fm);
        return sin(TAU*this.t*carrier + input.iom*mod);
    }
    add_noise() {
        return 1 - 2*Math.random();
    }
    clamp(x) {
        return (x <= -1) ? -1 : (x >= 1) ? 1 : x; 
    }
    process(note, env, tick, opt) {
        this.t += ditty.dt;
        const freq = midi_to_hz(note);
        // frequency to start from 
        const f2 = freq*input.add;
        // scale time, lower values in the 2nd arg decrease drum pitch
        const t = lerp(0, 4, this.t);
        // add decreasing offset to the fm carrier
        const offset = t * input.spd * f2;
        // limit how much offset it applied, lower values make it less "drummy"
        const f = (offset < input.limit) ? (freq + f2) - offset : 0; 

        // add body
        let x = this.add_fm(f) * this.fm_gain * Math.exp(-1, t);
        
        // add noise
        //x += this.add_noise() * lerp(this.noise_gain, 0, this.noise_decay * this.t);
        x += this.add_noise() * this.noise_gain * Math.exp(-1.8, t); 
        
        let i = x * env.value;
        debug.probe("Waveform", i, 1, 1 );

        return i;
    }
});

loop( () => {
    // attack and release in seconds, duration in ticks
    SnareTest.play(input.note, { 
        attack: 0, release: 0.3,  duration: 0.2, curve: -7,
        //mul: 51.5, iom: 48.0
    }); 
    sleep(1); // sleep in ticks

}, { name: 'Snare' });