Thug Hunter #2

.

Log in to post a comment.

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);
}, {});