mund4ne

melodic flows of variable tone and loudness

Log in to post a comment.

const MAIN = class
{
  constructor()
  {
    this.period = 0;
    this.time = 0;
    this.reverb = new REV();
  }
  vio_fl_mn()
  {
    let time = this.time;
    let dpm = 0;
    dpm = (mod(time, 8.) < 2 ? .3 : (cos(time) * .7 + .7)) * softkn(4. * supbassA(.5, 4 * time), 1.5);
    dpm += dpuncvio((mod(time, 14.) > 8 ? 1 : 0) + time) + pflute(time)
    dpm += dsynth(time);
    return dpm;
  }
  subbs_mn()
  {
    let time = this.time;
    let subslw = 0;
    let pmx = [];
    subslw = supbass(1.5, .5 * time) + supbass(1, .5 * time)
     subslw += .5 * softkn(4. * supbassA(.5, .5 * time), 1.5);
    pmx = [
        (sin(time)*.5+.5)*softkn(4. * supbassA(.5, .5 * time), 1.5), 
        (cos(time)*.5+.5)*softkn(4. * supbassA(.5, .5 * time), 1.5)];
    
    return [pmx[0] + subslw, pmx[1] + subslw];
  }
  dsarr_chor_st()
  {
    let time = this.time;
    return [(mod(time, 12.) > 6 ? 2 : 1) * dsynth(mod(1.0016 * time, [1, 4].ring(.25 * time))), (mod(time, 12.) > 6 ? 2 : 1) * dsynth(mod(1.008 * time, [1, 4].ring(.25 * time)))];
  }
  process()
  {
    this.time = ((this.period += 1) / 44100.);
    return [
        2 * (this.vio_fl_mn() + this.subbs_mn()[0] + this.dsarr_chor_st()[0]) + .32 * this.reverb.process(this.subbs_mn()[0] + 1.4*this.dsarr_chor_st()[0] + 1.5 * this.vio_fl_mn())[0], 
        2 * (this.vio_fl_mn() + this.subbs_mn()[1] + this.dsarr_chor_st()[1]) + .32 * this.reverb.process(this.subbs_mn()[1] + 1.4*this.dsarr_chor_st()[1] + 1.5 * this.vio_fl_mn())[1]
    ]
  }
}
const REV = class
{
  constructor()
  {
    this.zn = Array(8).fill().map(() => Array(4628).fill(0));
    this.dcBlockState = Array(8).fill().map(() => Array(2).fill(0));
    this.period = 0;
  }
  process(mono_xin)
  { 
    let  rv = [0, 0], y = [0, 0, 0, 0, 0, 0, 0, 0];
    const hmt = [1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1];
    const dt = [2876, 2226, 2823, 4627, 3186, 1319, 3189, 4546];
    this.period = (this.period+1) | 0;
    const g1 = 0.97;
    for (let i = 0; i < 8; i++) {
      const it4 = i % 4;
      const ip4 = i % 4 + 4;
      const dlR = (this.period%dt[it4]);
      const dlL = (this.period%dt[ip4]);
      y[it4] = this.zn[it4][dlR] + hmt[i % 4 + 0] * mono_xin;
      y[ip4] = this.zn[ip4][dlL] + hmt[i % 4 + 4] * mono_xin;
      this.zn[it4][dlR] = this.dcblock(g1 * y[it4], .997, it4);
      this.zn[ip4][dlL] = this.dcblock(g1 * y[ip4], .997, ip4);
      rv[0] = hmt[i % 8 + 0] * (y[0] + y[2] + y[4] + y[6]);
      rv[1] = hmt[i % 8 + 8] * (y[1] + y[3] + y[5] + y[7]);
      rv[0] *= .25;
      rv[1] *= .25;
    }
    return rv;
  }
  dcblock(xin, at, instnc)
  {
    let state = this.dcBlockState[instnc];
    let y0 = xin - state[0] + at * state[1];
    state[0] = xin;
    state[1] = y0;
    return y0;
  }
}

synth.def(MAIN).play(1,{
    amp: .12, /* forgot to set it to 1 while programming */
    duration: 500});

function subsm(mx, t, sx, sy, ez, ew) {
  const tt = mx * fract(t);
  const s = sin(1000 * [1, 2, 3, 2].ring(t) * tt);
  const m = smoothstep(sx, sy, abs(s)) * env_ad(fract(tt), ez, ew);
  const y = cos(s + 2. * m + 4. * t) * env_lin(fract(t), 7);
  return y;
}
function supbass(mx, t) {
  return 3 * subsm(mx, t, 1., 0.75, .2, .43);
}
function supbassA(mx, t) {
  return 1.7 * subsm(mx, t, 1., 0.25, .2, .6);
}
function dpuncvio(t) {
  const rt = 2. * t;
  const tt = [.5, .59, .59, .66].ring(.25 * rt) * .125 * fract(rt);
  const s = sin(1. - mod(8. * 1000 * (([1, 2, 3, 2, 3.4, 1, 2, 1].ring(rt) * tt)), tau));
  const gt = min(5 * fract(rt), .25);
  const m = smoothstep(1., 0., abs((s + gt)));
  const y = max(m, sin(s * 3. + 6. * rt)) * env_ad(fract(rt), .12, .67);
  return 2 * y;
}
function pflute(t) {
  const rt = 2. * t;
  const tt = (mod(t, 14) > 8 ? 1 : [.5, 1].ring(rt)) * [.5, .4, .446, .335].ring(.25 * rt) * .125 * fract(rt);
  const gt = min(5 * fract(rt), .5);
  const s = sin(2. * mod(8. * 1000 * [1, 2, 3, 2, 5, 2, 3, 2].ring(rt) * tt, tau)) * env_ad(fract(rt), .25, .7) * env_d(fract(rt), 3);
  const m = smoothstep(1.5, 0.75, abs(s + gt));
  const y = dpuncvio(.5 + .5 * rt) + 1.5 * min(m, sin(s * 3 + 6. * rt)) * env_ad(fract(rt), .12, .67);
  return 1.5 * y;
}
function dsynth(t) {
  const rt = 2 * t;
  const tt = [0.5, 0.59, 0.59, 0.66].ring(0.25 * rt) * 0.125 * fract(rt);
  const s = sin(1 - 2 * mod(2000 * ([1, 2, 3, 2, 3.4, 1, 2, 1].ring(rt) * tt), tau));
  const gt = min(2 * fract(rt), 0.25);
  const m = smoothstep(1, 0, abs(s + gt));
  const n = max(0, msat(min(m, cos(s * 3 + 6 * rt)), 0.5)) * env_ad(fract(rt), .5, 1);
  const ou = msat((sin(3 * rt) * 0.7 + 0.7) * pflute((sin(rt) * 0.01 + 0.01) + rt) * env_ad(fract(rt), 0.3, 0.63), 0.51);
  const y = 0.5 * n + (mod(t, 8) < 4 ? 0 : ou);
  return 2.4 * y;
}
// utilities 
const{PI,floor,sin,abs,max,min,exp,cos} = Math;
const msat = (x, a) => 0.5 * (abs(x + a) - abs(x - a));
const osc_tri = x => (1 - abs(2. - mod(1. + 2. + x, 4)));
const env_lin = (x, a) => osc_tri(x) * min(1., a * x) * max(0., 1. - x);
const env_d = (t, d) => exp(-t * 5.436563 / d);
const env_ad = (t, a, d) => min(t / max(1e-5, a), env_d((t - a), d));
const softkn = (x, kn) => x / (kn * abs(x) + 1.0);
const tau = PI * 2.0;
const fract = (x) => (x - floor(x));
const mod = (x, y) => (x - floor(x / y) * y);
const smoothstep = (e0, e1, value) => {const x = max(0, min(1, (value - e0) / (e1 - e0)));return x * x * (3 - 2 * x);};