desc:Colored noise generator 1
//tags: analysis generator synthesis
//author: Tale

// Copyright (C) 2014-2019 Theo Niessink
// License: LGPL - http://www.gnu.org/licenses/lgpl.html

// This effect generates different "colors" of noise. Apart from the listed
// colors it can also generate "black" noise. To do so select white noise
// and lower the density. Note that density affects only white noise, and is
// ignored for other colors.

slider1:5<0,5,1{Brown,Pink,White,Blue,Violet,Grey}>Color
slider2:1.0<0.0,1.0,0.001>Density
slider3:0<0,1,1{Mono,Stereo}>Mode
slider4:0.0<-150.0,24.0,0.1>Dry (dB)
slider5:-3.52183<-150.0,24.0,0.1>Wet (dB)
slider6:0<0,4,1{Bypass,Low-Pass,Band-Pass,High-Pass,Notch>Filter
slider7:20.0<20.0,20000.0,1.0>Cutoff (Hz)
slider8:0.01<0.01,8.0,0.01>Q

in_pin:Left
in_pin:Right

out_pin:Left
out_pin:Right

import noise.jsfx-inc
import rc_filter.jsfx-inc
import zdf_filter.jsfx-inc

@init

function pow4(x) ( x*x*x*x );
function cache(x) ( x != this ? ( this = x; 1; ); );

function gain(db, inf)
(
  db <= inf ? 0 : exp(/* log(10)/20 */ 0.11512925464970228 * db);
);

smooth.rc_set(0.0033);

function smooth()
(
  smooth.lp = this.smooth;
  this.smooth = smooth.rc_lp(this);
);

min_inf = -150.0;
dry.smooth = gain(slider4, min_inf);
wet.smooth = gain(slider5, min_inf);

// rms = 0;
rms[0] = 0.075;
rms[1] = 1/3;
rms[2] = 1;
rms[3] = 0.56;
rms[4] = sqrt(0.5);
rms[5] = 0.125;

ratio = 6;
ratio[3] = srate * 1/44100;
ratio[5] =
ratio[2] = sqrt(ratio[3]);
ratio[4] = ratio[2] * ratio[3];
ratio[0] = 1 / ratio[2];
ratio[1] = 1;

@slider

color = slider1|0;
gain = rms[color] * ratio[color];

rng0.lcg_density(color < 0 || color > 5 ? 0 : pow4(slider2));
rng1.lcg_density(rng0.density);

stereo.cache(slider3 >= 0.5) ? (
  rng0.lcg_init(2147483646);
  stereo ? rng1.lcg_init(1518500249);
);

dry = gain(slider4, min_inf);
wet = gain(slider5, min_inf);

filter = max(slider6|0, 0);
filter > 4 ? filter = 0;

filter ? (
  fc = max(20, slider7);
  q = max(0.01, slider8);

  filter == 1 ? zdf0.zdf_lp(fc, q) :
  filter == 2 ? zdf0.zdf_bp(fc, q) :
  filter == 3 ? zdf0.zdf_hp(fc, q) :
  /* filter == 4 ? */ zdf0.zdf_bs(fc, q);

  stereo ? (
    zdf1.cb = zdf0.cb; zdf1.ch = zdf0.ch; zdf1.cl = zdf0.cl;
    zdf1.g = zdf0.g; zdf1.h = zdf0.h; zdf1.r2 = zdf0.r2;
  );
);

@sample

color == 0 ? (
  left = rng0.lcg_brown();
  stereo ? right = rng1.lcg_brown();
) :

color == 1 ? (
  left = rng0.lcg_pink();
  stereo ? right = rng1.lcg_pink();
) :

color == 3 ? (
  left = rng0.lcg_blue();
  stereo ? right = rng1.lcg_blue();
) :

color == 4 ? (
  left = rng0.lcg_violet();
  stereo ? right = rng1.lcg_violet();
) :

color == 5 ? (
  left = rng0.lcg_grey();
  stereo ? right = rng1.lcg_grey();
) :

/* color == 2 ? */ (
  left = rng0.lcg_black();
  stereo ? right = rng1.lcg_black();
);

left *= gain;
stereo ? right *= gain : right = left;

filter ? (
  left = zdf0.zdf_svf(left);
  right = stereo ? zdf1.zdf_svf(right) : left;
);

//spl0 = dry.smooth() * spl0 + wet.smooth() * left;
//spl1 = dry.smooth * spl1 + wet.smooth * right;

spl0 = (CEIL( dry.smooth() * spl0 + wet.smooth() * left )-.5)*2;
spl1 = (CEIL( dry.smooth() * spl1 + wet.smooth() * right)-.5)*2;
