const delay = filter.def(class { constructor(options) { this.index = 0; this.length = options.interval * ditty.sampleRate * 60 / ditty.bpm | 0; this.left = new Float32Array(this.length); this.right = new Float32Array(this.length); } process(input, options) { if (input) { const s = options.strength; this.index = (this.index + 1) % this.length; const hist = (this.index + 1) % this.length; this.left [this.index] = input[1] + s * this.right[hist]; this.right[this.index] = input[0] + s * this.left [hist]; return [ this.left[this.index], this.right[this.index] ]; } } }, { interval: 1/3, strength: 0.25 }); loop((i) => { sine.play([c3,c4,c3,c5,c3,c4,f3,g5, c3,c4,c3,c5,c3,c4,g5,d5 ][i%16] + (i/32|0)%2*2, { attack: 0.05 * Math.random(), release: 0.2, pan: 0.5 + Math.random() }); sleep(0.5); }, { name: '📢' }) .connect( delay.create( { interval: 1.25, strength: 0.25 }) ) .connect( delay.create( { interval: 2/3, strength: 0.15 }) ) .connect( delay.create( { interval: 1/2, strength: 0.25 }) ) .connect( delay.create( { interval: 1.5, strength: 0.33 }) )