Title:
Description:
// Welcome to Dittytoy!
//
// Dittytoy is a community for creative coding. We believe the joy 
// is in the craft. 
//
// ---------------------------------------------------------------
// A NOTE ON AI:
// Please do not publish code entirely generated by AI. 
// We want to see YOUR creativity, your mistakes, and your logic. 
// If you use AI to learn, try to rewrite the code yourself before 
// sharing, so others can learn from your human approach.
// ---------------------------------------------------------------
//
// API Reference: https://dittytoy.net/syntax
// Example ditties: https://dittytoy.net/user/Dittytoy

ditty.bpm = 120;

// Triangle synth
const triangle = synth.def( (phase, env) => (Math.abs(phase % 1 - .5) * 4 - 1) * env.value );

// Example of a simple stereo low-pass filter
const lpf = filter.def(class {
    constructor(options) {
        this.l = 0;
        this.r = 0;
    }
    process(input, options) {
        this.l += (input[0] - this.l) * options.cutoff;
        this.r += (input[1] - this.r) * options.cutoff;
        return [this.l, this.r];
    }
}, { cutoff: 0.1 });

// Main loop, connected to the filter we just created
loop( () => {

    for (let i=0; i<4; i++) {
        triangle.play(c4, { attack: 0.01, release: 0.25,  duration: 0.125, pan: Math.random() * 2 - 1 });
        sleep( 0.25 ); // sleep in ticks
    }

    triangle.play(d4, { attack: 0.01, release: 0.25,  duration: 0.25 }); // attack and release in seconds, duration in ticks
    sleep(0.5);

    triangle.play(f4, { attack: 0.01, release: 0.75,  duration: 0.25 });
    sleep(0.5);

}, { name: 'My first loop' }).connect(lpf.create());