ditty.bpm = 800;
const modSynth = synth.def((phase, env, tick, options) => {
let freq = midi_to_hz(options.note || 60);
let mod = Math.sin(tick * Math.PI * 2 * options.modRate) * options.modDepth;
let chaos = Math.sin(tick * options.chaosRate + Math.sin(tick * options.chaosRate2));
freq *= 1 + mod * chaos;
return Math.sin(phase * 2 * Math.PI * freq) * env.value * options.amp;
}, {
attack: 0.01,
release: 0.3,
duration: 1,
note: 60,
modRate: 0.3,
modDepth: 0.05,
chaosRate: 0.5,
chaosRate2: 1.2,
amp: 0.8
});
const pulseSynth = synth.def((phase, env, tick, options) => {
let p = phase % 1;
let threshold = 0.5 + 0.4 * Math.sin(tick * Math.PI * 2 * options.freqMod);
let pulse = (p < threshold) ? 1 : -1;
let smooth = Math.tanh(pulse * options.smoothFactor);
return smooth * env.value * options.amp;
}, {
attack: 0.005,
release: 0.2,
duration: 0.5,
freqMod: 0.2,
smoothFactor: 2,
amp: 0.6
});
const droneSynth = synth.def((phase, env, tick, options) => {
let s = Math.sin(phase * 2 * Math.PI);
let saw = 2 * (phase % 1) - 1;
let mix = 0.5 * s + 0.5 * saw;
mix = Math.tanh(mix * 2);
return mix * env.value * options.amp;
}, {
attack: 0.5,
release: 2.0,
duration: 16,
amp: 0.4
});
const randomClick = synth.def((phase, env, tick, options) => {
return (Math.random() > 0.95 ? 1 : -1) * env.value;
}, {
attack: 0.001,
release: 0.02,
duration: 0,
amp: 0.3
});
const modFilter = filter.def((input, options) => {
let cutoff = 0.5 + 0.5 * Math.sin(ditty.tick * 0.01);
return [input[0] * cutoff, input[1] * cutoff];
}, {});
loop(() => {
for (let i = 0; i < 32; i++) {
let note = 60 + Math.floor( 12 * ( Math.sin(2 * Math.PI * i / 32) + 0.5 * Math.cos(3 * Math.PI * i / 32) ) );
modSynth.play(note, {
pan: Math.sin(i * Math.PI / 16),
modRate: 0.3 + 0.1 * Math.cos(i),
chaosRate: 0.5 + 0.2 * Math.sin(i)
});
sleep(0.125 + Math.random() * 0.02);
}
}, {}).connect(modFilter.create());
loop((loopCount) => {
let dynamicNote = 48 + 12 * Math.sin(loopCount * 0.15);
pulseSynth.play(dynamicNote, {
amp: 0.6,
freqMod: 0.2 + 0.1 * Math.cos(loopCount * 0.2)
});
sleep(2 + Math.random() * 0.1);
}, {});
loop(() => {
if (Math.random() < 0.3) randomClick.play();
sleep(0.0625);
}, {});
loop(() => {
let note = 36 + Math.floor(12 * (0.5 + 0.5 * Math.sin(ditty.tick * 0.0008)));
droneSynth.play(note, {
pan: (tick, opts) => Math.sin(ditty.tick * 0.005)
});
sleep(16);
}, {});
loop(() => {
let density = Math.abs(Math.sin(ditty.tick * 0.002)) * 10;
for (let i = 0; i < density; i++) {
let note = 60 + Math.floor(24 * Math.sin(ditty.tick * 0.003 + i));
modSynth.play(note, {
pan: Math.cos(i),
modDepth: 0.05 + 0.02 * Math.abs(Math.sin(i))
});
sleep(0.0625);
}
sleep(0.5);
}, {});