Wierd

First trial

Log in to post a comment.

//
// Similar Dittytoy script
// Reference: https://Dittytoy.net/syntax
// Example user ditties: https://dittytoy.net/user/Dittytoy
//

// ------------------ Reverb Filter ------------------
class Imprint {
    constructor(freq, absorption, weight=1) {
        this.x = 0;
        this.v = 0;
        this.a = 0;
        this.weight = weight;
        this.freq = freq;
        this.absorption = absorption;
    }
    sample(s) {
        // Add some randomness for an airy reverb tail
        this.v *= this.absorption;
        this.v += s + (Math.random() - 0.5);
        this.v -= this.x;
        this.x += this.v * this.freq;
        return this.x * this.weight;
    }
}

let reverb = filter.def(class {
    constructor(options) {
        this.mem = [];
        this.maxWeight = 0;
        for (let i = 0; i < 512; i++) {
            let freq = Math.random() * options.freq / 44100;
            let weight = Math.random();
            this.maxWeight += weight;
            this.mem.push(new Imprint(freq, 1 - options.decay, weight));
        }
    }
    process(input) {
        const s = input[0];
        let out = 0;
        for (let imprint of this.mem) {
            out += imprint.sample(s);
        }
        out /= this.maxWeight;
        return [out, out];
    }
});

// ------------------ Synth Definition ------------------
const wave = synth.def(
    class {
        constructor() {
            this.phase = 0;
        }
        process(note, env, tick, options) {
            // Create a simple “squirrely” saw wave
            const freq = midi_to_hz(note);
            // Add a tiny random detuning for a less static tone
            this.phase += freq * ditty.dt + Math.random() * 0.00001;
            return ((this.phase) % 2 - 1) * env.value;
        }
    }
);

// ------------------ BPM & Globals ------------------
ditty.bpm = 95; // set a slower groove

// ------------------ Patterns / Combos ------------------
//
// Each combo is a function that plays some notes,
// followed by a list of possible "next states" to pick from
//
let combos = [
    [
        () => {
            // A repeating two-note motif
            wave.play(c4,  {attack: 0.01, release: 0.5, duration: 0.25});
            sleep(0.5);
            wave.play(g4,  {attack: 0.01, release: 0.5, duration: 0.25});
            sleep(0.5);
            wave.play(ds4, {attack: 0.01, release: 0.5, duration: 0.25});
            sleep(0.5);
            wave.play(as4, {attack: 0.01, release: 0.75, duration: 0.25});
            sleep(0.5);
        },
        [1, 2] // possible transitions
    ],
    [
        () => {
            // A simple ascending phrase
            wave.play(c4,  {attack: 0.01, release: 0.3, duration: 0.25});
            sleep(0.25);
            wave.play(ds4, {attack: 0.01, release: 0.3, duration: 0.25});
            sleep(0.25);
            wave.play(f4,  {attack: 0.01, release: 0.3, duration: 0.25});
            sleep(0.25);
            wave.play(gs4, {attack: 0.01, release: 1,   duration: 0.25});
            sleep(1);
        },
        [0, 2, 3] // possible transitions
    ],
    [
        () => {
            // Descending line
            wave.play(as4, {attack: 0.01, release: 0.5, duration: 0.25});
            sleep(0.5);
            wave.play(g4,  {attack: 0.01, release: 0.5, duration: 0.25});
            sleep(0.5);
            wave.play(f4,  {attack: 0.01, release: 0.75, duration: 0.25});
            sleep(0.5);
            wave.play(ds4, {attack: 0.01, release: 1.5, duration: 0.25});
            sleep(1);
        },
        [0, 1] // possible transitions
    ],
    [
        () => {
            // Bass figure
            wave.play(c3,  {attack: 0.02, release: 0.5, duration: 0.25});
            sleep(0.75);
            wave.play(as2, {attack: 0.02, release: 0.75, duration: 0.25});
            sleep(0.75);
            wave.play(g2,  {attack: 0.02, release: 0.5, duration: 0.25});
            sleep(0.75);
            wave.play(ds3, {attack: 0.02, release: 1,   duration: 0.25});
            sleep(1);
        },
        [1, 2, 0] // possible transitions
    ]
];

// ------------------ Utility to pick random next combo ------------------
function pickRandom(arr) {
    return arr[Math.floor(Math.random() * arr.length)];
}

// ------------------ Main Loop #1 ------------------
let state = 0;
loop(() => {
    combos[state][0](); 
    // Move to next state from possible transitions
    state = pickRandom(combos[state][1]);
}, { name: 'Melodic Loop' })
.connect(
    reverb.create({freq: 2000, decay: 0.0005})
);

// ------------------ Main Loop #2 ------------------
loop(() => {
    // Alternate a short phrase
    wave.play(c2,  {attack: 0.01, release: 0.5, duration: 0.25});
    sleep(0.5);
    wave.play(ds2, {attack: 0.01, release: 0.5, duration: 0.25});
    sleep(0.5);
    wave.play(g2,  {attack: 0.01, release: 0.5, duration: 0.25});
    sleep(1.0);
}, { name: 'Bass Loop' })
.connect(
    reverb.create({freq: 2000, decay: 0.001})
);