Commit 7dd19b12 authored by Jaromír Mikeš's avatar Jaromír Mikeš

Imported Upstream version 0.9.16

parent 73b6db3a
......@@ -120,7 +120,7 @@ AmpVTS::subcycle (uint frames, Over & over)
/* roughly correcting for loudness increase */
float makeup = (.086-.06*y)/(11.6+exp((12.1-5*y)*(.81-.08*y-x)))+0.00032+.0026*y;
makeup = 0 ? 1 : .0006/makeup;
makeup = 0 ? 1 : .0006/makeup; /* debug switch for makeup */
float lowcut = .1 + 342*getport(10);
DSP::RBJ::HP (lowcut*over_fs, .7, hp);
......@@ -205,7 +205,7 @@ AmpVTS::port_info [] =
{ "squash", CTRL_IN, {DEFAULT_MID, 0, 1} },
/* 10 */
{ "low cut", CTRL_IN | GROUP, {DEFAULT_HIGH, 0, 1} },
{ "lowcut", CTRL_IN | GROUP, {DEFAULT_HIGH, 0, 1} },
{ "in", INPUT | AUDIO },
{ "out", OUTPUT | AUDIO },
......
......@@ -93,10 +93,10 @@ AutoFilter::subsubcycle (uint frames, SVF & svf, Over & over)
float env = getport(7);
lorenz.set_rate (3e-05*fs * .6*sq(getport(8)));
float x = getport(9), z = 1-x;
float x=.9, z=.1;;
sample_t * s = ports[10];
sample_t * d = ports[11];
sample_t * s = ports[9];
sample_t * d = ports[10];
while (frames)
{
......@@ -201,14 +201,13 @@ AutoFilter::port_info [] =
"{0:'breathy',1:'fat A',2:'fat B',3:'fat C',4:'fat D'}", },
{ "gain (dB)", CTRL_IN, {DEFAULT_LOW, 0, 24} },
/* 4 */
{ "f (Hz)", CTRL_IN | GROUP, {LOG | DEFAULT_LOW, 43, 3743} },
{ "f (Hz)", CTRL_IN | GROUP, {LOG | DEFAULT_HIGH, 20, 3000} },
{ "Q", CTRL_IN, {DEFAULT_0, 0, 1} },
/* 6 */
{ "range", CTRL_IN | GROUP, {DEFAULT_1, 0, 1} },
{ "range", CTRL_IN | GROUP, {DEFAULT_HIGH, 0, 1} },
{ "lfo/env", CTRL_IN, {DEFAULT_LOW, 0, 1} },
{ "rate", CTRL_IN | GROUP, {DEFAULT_LOW, 0, 1} },
{ "x/z", CTRL_IN, {DEFAULT_1, 0, 1} },
/* 10 */
{ "rate", CTRL_IN, {DEFAULT_LOW, 0, 1} },
/* 9 */
{ "in", AUDIO_IN},
{ "out", AUDIO_OUT}
};
......@@ -218,7 +217,7 @@ Descriptor<AutoFilter>::setup()
{
Label = "AutoFilter";
Name = CAPS "AutoFilter - Resonant automodulating filter";
Name = CAPS "AutoFilter - Modulated filter cascade";
Maker = "Tim Goetze <tim@quitte.de>";
Copyright = "2004-13";
......
0.9.16
* NoiseGate simplified, sped up, gain lowpassed, click bug eliminated
* Sin smoothened, defaults updated
* PhaserII defaults updated
* Fractal defaults updated
* documentation polish
0.9.15
* no-vector-arithmetic compilation fixed
0.9.14
* AutoFilter x/y parameter eliminated
* Fractal hp changed to be configurable, attractors recalibrated
* documentation polish
0.9.13
* Eq4p softens drastic parameter changes by crossfading static filters
* Eq4p employing single v4f filter, slightly quicker
* Eq4p 'off' filter mode
* documentation and interface polish
0.9.12
* non-SSE compilation fixed
0.9.11
* DSP::Roessler instantly initialises to useful state
* Logarithmic port bounds and values fixed to reflect actual intent,
affecting Spice, AutoFilter and ChorusI
* clicking automatic gain fade on activate() eliminated in Saturate
* Dirac merged into Click
* Lorenz and Roessler merged into Fractal
* JVRev removed
* running plugins for zero frames returns without touching state
* CabinetII and III removed
* PhaserII sine LFO and LFO choice port added
* PhaserII fractal modulation extensively revised
* ChorusI rate lower bound slightly increased
* ChorusI delay line length adjusted to accommodate full t+width range
* all Chorus and Phaser plugins removed save for ChorusI and PhaserII
* major documentation revision
* Eq4p parametric equaliser plugin
* RBJ shelving filter prototype implementation fixed
* "2x2" stereo plugin label postfix changed to "X2"
* Eq renamed Eq10
* SIMD implementation updates
* DSP::RBJ coefficient calculation rearranged
* Click bpm range changed, default lowered substantially
0.9.10
* DSP::RMS protected against negative sum of squares
* documentation updates
......
......@@ -404,7 +404,7 @@ Descriptor<CabinetIV>::setup()
{
Label = "CabinetIV";
Name = CAPS "CabinetIV - Idealised loudspeaker cabinet emulation";
Name = CAPS "CabinetIV - Idealised loudspeaker cabinet";
Maker = "Tim Goetze <tim@quitte.de>";
Copyright = "2012";
......
......@@ -30,32 +30,47 @@
#include "Chorus.h"
#include "Descriptor.h"
void
ChorusI::activate()
{
setrate (getport(0));
time = 0;
width = 0;
delay.reset();
}
void
ChorusI::setrate (float r)
{
if (r == rate) return;
rate = r;
lfo.sine.set_f (rate, fs, lfo.sine.get_phase());
}
template <yield_func_t F>
void
ChorusI::one_cycle (int frames)
{
sample_t * s = ports[0];
float one_over_n = 1/(float)frames;
float ms = fs*.001;
double one_over_n = 1 / (double) frames;
double ms = .001 * fs;
float t = time;
time = getport(0)*ms;
float dt = (time - t)*one_over_n;
double t = time;
time = getport(1) * ms;
double dt = (time - t) * one_over_n;
double w = width;
width = getport(2) * ms;
float w = width;
width = getport(1)*ms;
/* clamp, or we need future samples from the delay line */
if (width >= t - 3) width = t - 3;
double dw = (width - w) * one_over_n;
float dw = (width - w) * one_over_n;
if (rate != *ports[3])
lfo.set_f (max (rate = getport(3), .000001), fs, lfo.get_phase());
double blend = getport(4);
double ff = getport(5);
double fb = getport(6);
setrate (getport(2));
float blend = getport(3);
float ff = getport(4);
float fb = getport(5);
sample_t * s = ports[6];
sample_t * d = ports[7];
DSP::FPTruncateMode truncate;
......@@ -64,26 +79,13 @@ ChorusI::one_cycle (int frames)
{
sample_t x = s[i];
/* truncate the feedback tap to integer, better quality for less
* cycles (just a bit of zipper when changing 't', but it does sound
* interesting) */
int ti;
fistp (t, ti);
x -= fb * delay[ti];
x -= fb*delay[ti];
delay.put (x + normal);
# if 0
/* allpass delay sounds a little cleaner for a chorus
* but sucks big time when flanging. */
x = blend * x + ff * tap.get (delay, t + w * lfo.get());
# elif 0
/* linear interpolation */
x = blend * x + ff * delay.get_at (t + w * lfo.get());
# else
/* cubic interpolation */
x = blend * x + ff * delay.get_cubic (t + w * lfo.get());
# endif
x = blend*x + ff*delay.get_cubic (t + w*lfo.sine.get());
F (d, i, x, adding_gain);
......@@ -97,13 +99,16 @@ ChorusI::one_cycle (int frames)
PortInfo
ChorusI::port_info [] =
{
{ "t (ms)", CTRL_IN, {LOG | DEFAULT_MID, 2.5, 40} },
{ "width (ms)", CTRL_IN, {DEFAULT_LOW, .5, 10} },
{ "rate (Hz)", CTRL_IN | GROUP, {DEFAULT_LOW, 0.001, 5} },
{ "blend", CTRL_IN | GROUP, {DEFAULT_1, 0, 1} },
{ "feedforward", CTRL_IN, {DEFAULT_LOW, 0, 1} },
{ "feedback", CTRL_IN, {DEFAULT_0, 0, 1} },
{ "in", INPUT | AUDIO },
{ "t (ms)", CTRL_IN, {BOUNDED | LOG | DEFAULT_LOW, 2.5, 40} },
{ "width (ms)", CTRL_IN, {BOUNDED | DEFAULT_LOW, .5, 10} },
{ "rate (Hz)", CTRL_IN | GROUP, {BOUNDED | DEFAULT_LOW, 0, 5} },
{ "blend", CTRL_IN, {BOUNDED | DEFAULT_1, 0, 1} },
{ "feedforward", CTRL_IN | GROUP, {BOUNDED | DEFAULT_LOW, 0, 1} },
{ "feedback", CTRL_IN, {BOUNDED | DEFAULT_0, 0, 1} },
{ "out", OUTPUT | AUDIO }
};
......@@ -120,220 +125,4 @@ Descriptor<ChorusI>::setup()
autogen();
}
/* //////////////////////////////////////////////////////////////////////// */
template <yield_func_t F>
void
ChorusII::cycle (uint frames)
{
sample_t * s = ports[0];
double over_n = 1 / (double) frames;
double ms = .001 * fs;
double t = time;
time = getport(1) * ms;
double dt = (time - t) * over_n;
double w = width;
width = getport(2) * ms;
/* clamp, lest we need future samples from the delay line */
if (width >= t - 3) width = t - 3;
double dw = (width - w) * over_n;
float r = getport(3);
if (r != rate)
set_rate (r);
double blend = getport(4);
double ff = getport(5);
double fb = getport(6);
sample_t * d = ports[7];
DSP::FPTruncateMode truncate;
for (uint i = 0; i < frames; ++i)
{
sample_t x = s[i];
x = hp.process (x+normal);
x -= fb * delay.get_cubic (t);
delay.put (x);
double a = 0;
for (int j = 0; j < Taps; ++j)
a += taps[j].get (delay, t, w);
x = blend * x + ff * a;
F (d, i, x, adding_gain);
t += dt;
w += dw;
}
}
/* //////////////////////////////////////////////////////////////////////// */
PortInfo
ChorusII::port_info [] =
{
{ "in", INPUT | AUDIO },
{ "t (ms)", CTRL_IN, {LOG | DEFAULT_LOW, 2.5, 25} },
{ "width (ms)", CTRL_IN, {DEFAULT_LOW, .5, 10} },
{ "rate", CTRL_IN | GROUP, {DEFAULT_LOW, 0, 1} },
{ "blend", CTRL_IN, {DEFAULT_MID, 0, 1} },
{ "feedforward", CTRL_IN | GROUP, {DEFAULT_MID, 0, 1} },
{ "feedback", CTRL_IN, {DEFAULT_0, 0, 1} },
{ "out", OUTPUT | AUDIO }
};
template <> void
Descriptor<ChorusII>::setup()
{
Label = "ChorusII";
Name = CAPS "ChorusII - Multivoice chorus modulated by a fractal";
Maker = "Tim Goetze <tim@quitte.de>";
Copyright = "2004-12";
/* fill port info and vtable */
autogen();
}
/* //////////////////////////////////////////////////////////////////////// */
void
StereoChorusII::set_rate (sample_t r)
{
rate = r;
r *= FRACTAL_RATE * 44100 * over_fs;
left.fractal.set_rate (r);
right.fractal.set_rate (1.1*r);
left.lfo_lp.set_f (3 * over_fs);
right.lfo_lp.set_f (3 * over_fs);
}
template <yield_func_t F>
void
StereoChorusII::cycle (uint frames, int mode)
{
double one_over_n = 1 / (double) frames;
double ms = .001 * fs;
double t = time;
time = getport(0) * ms;
double dt = (time - t) * one_over_n;
double w = width;
width = getport(1) * ms;
/* clamp, lest we need future samples from the delay line */
if (width >= t - 1) width = t - 1;
double dw = (width - w) * one_over_n;
set_rate (getport(2));
double blend = getport(3);
double ff = getport(4);
double fb = getport(5);
/* mode is Mono = 0 or Stereo = 1 */
sample_t * sl = ports[6];
sample_t * sr = ports[6+mode];
sample_t * dl = ports[7+mode];
sample_t * dr = ports[8+mode];
/* ensure i386's fistp instruction truncates */
DSP::FPTruncateMode truncate;
for (uint i = 0; i < frames; ++i)
{
sample_t xl = sl[i], xr = sr[i], x = .5*(xl + xr);
x = hp.process (x+normal);
/* truncate the feedback tap to integer, better quality for less
* cycles (just a bit of zipper when changing 't') */
int ti;
fistp (t, ti);
x -= fb * delay[ti];
delay.put (x);
double m;
m = left.lfo_lp.process (left.fractal.get());
sample_t l = blend * xl + ff * delay.get_cubic (t + w * m);
m = right.lfo_lp.process (right.fractal.get());
sample_t r = blend * xr + ff * delay.get_cubic (t + w * m);
F (dl, i, l, adding_gain);
F (dr, i, r, adding_gain);
t += dt;
w += dw;
}
}
/* //////////////////////////////////////////////////////////////////////// */
PortInfo
StereoChorusII::port_info [] =
{
{ "t (ms)", CTRL_IN, {DEFAULT_LOW, 2.5, 25} },
{ "width (ms)", CTRL_IN, {DEFAULT_LOW, .5, 10} },
{ "rate", CTRL_IN | GROUP, {DEFAULT_LOW, 0, 1} },
{ "blend", CTRL_IN, {DEFAULT_LOW, 0, 1} },
{ "feedforward", CTRL_IN | GROUP, {DEFAULT_1, 0, 1} },
{ "feedback", CTRL_IN, {DEFAULT_MID, 0, 1} },
{ "in", INPUT | AUDIO },
{ "out.l", OUTPUT | AUDIO },
{ "out.r", OUTPUT | AUDIO }
};
template <> void
Descriptor<StereoChorusII>::setup()
{
Label = "StereoChorusII";
Name = CAPS "StereoChorusII - Stereo chorus modulated by a fractal";
Maker = "Tim Goetze <tim@quitte.de>";
Copyright = "2004-12";
/* fill port info and vtable */
autogen();
}
/* //////////////////////////////////////////////////////////////////////// */
PortInfo
StereoChorusII2x2::port_info [] =
{
{ "t (ms)", CTRL_IN, {DEFAULT_LOW, 2.5, 25} },
{ "width (ms)", CTRL_IN, {DEFAULT_LOW, .5, 10} },
{ "rate", CTRL_IN | GROUP, {DEFAULT_LOW, 0, 1} },
{ "blend", CTRL_IN, {DEFAULT_LOW, 0, 1} },
{ "feedforward", CTRL_IN | GROUP, {DEFAULT_1, 0, 1} },
{ "feedback", CTRL_IN, {DEFAULT_MID, 0, 1} },
{ "in.l", INPUT | AUDIO },
{ "in.r", INPUT | AUDIO },
{ "out.l", OUTPUT | AUDIO },
{ "out.r", OUTPUT | AUDIO }
};
template <> void
Descriptor<StereoChorusII2x2>::setup()
{
Label = "StereoChorusII2x2";
Name = CAPS "StereoChorusII2x2 - Stereo chorus modulated by a fractal";
Maker = "Tim Goetze <tim@quitte.de>";
Copyright = "2004-12";
/* fill port info and vtable */
autogen();
}
......@@ -34,58 +34,46 @@
#include "dsp/BiQuad.h"
#include "dsp/RBJ.h"
class ChorusStub
class ChorusI
: public Plugin
{
public:
DSP::OnePoleHP<sample_t> hp;
sample_t time, width, rate;
};
float time, width, rate;
struct {
DSP::Sine sine;
} lfo;
class ChorusI
: public ChorusStub
{
public:
DSP::Sine lfo;
DSP::Delay delay;
template <yield_func_t>
void one_cycle (int frames);
void setrate (float r);
public:
static PortInfo port_info [];
void init()
{
rate = .15;
delay.init ((int) (.040 * fs));
lfo.sine.set_f (rate, fs, 0);
delay.init ((int) (.050 * fs));
}
void activate()
{
time = 0;
width = 0;
rate = *ports[3];
delay.reset();
lfo.set_f (rate, fs, 0);
}
void activate();
void run (int n)
{
one_cycle<store_func> (n);
}
{ one_cycle<store_func> (n); }
void run_adding (int n)
{
one_cycle<adding_func> (n);
}
{ one_cycle<adding_func> (n); }
};
/* ///////////////////////////////////////////////////////////////////////// */
#if 0
#define FRACTAL_RATE 0.004
class FracTap
......@@ -164,62 +152,5 @@ class ChorusII
void run_adding (uint n) { cycle<adding_func> (n); }
};
class StereoChorusII
: public ChorusStub
{
public:
sample_t rate;
sample_t phase;
DSP::Delay delay;
struct {
DSP::Roessler fractal;
DSP::OnePoleLP<sample_t> lfo_lp;
} left, right;
enum {Mono=0,Stereo=1};
template <yield_func_t>
void cycle (uint frames, int mode=Mono);
void set_rate (sample_t r);
public:
static PortInfo port_info [];
sample_t adding_gain;
void init()
{
hp.set_f (350*over_fs);
delay.init ((int) (.025 * fs));
left.fractal.init (.001, frandom());
right.fractal.init (.001, frandom());
}
void activate()
{
time = 0;
width = 0;
hp.reset();
delay.reset();
set_rate (*ports[3]);
}
void run (uint n) { cycle<store_func> (n,Mono); }
void run_adding (uint n) { cycle<adding_func> (n,Mono); }
};
class StereoChorusII2x2
: public StereoChorusII
{
public:
static PortInfo port_info [];
void run (uint n) { cycle<store_func> (n,Stereo); }
void run_adding (uint n) { cycle<adding_func> (n,Stereo); }
};
#endif
#endif /* _CHORUS_H_ */
......@@ -226,6 +226,14 @@ Click::initsine()
initwave (2, click, m);
}
void
Click::initdirac()
{
int16 * dirac = new int16[1];
*dirac = 32767;
initwave (3, dirac, 1);
}
template <> void
Descriptor<Click>::setup()
{
......@@ -244,8 +252,9 @@ Descriptor<Click>::setup()
PortInfo
Click::port_info [] =
{
{ "model", CTRL_IN, {INTEGER | DEFAULT_1, 0, 2}, "{0:'box',1:'stick',2:'beep'}" },
{ "bpm", CTRL_IN | GROUP, {DEFAULT_LOW, 4, 384} },
{ "model", CTRL_IN, {INTEGER | DEFAULT_1, 0, 3},
"{0:'box',1:'stick',2:'beep',3:'dirac'}" },
{ "bpm", CTRL_IN | GROUP, {DEFAULT_LOW, 4, 240} },
{ "volume", CTRL_IN | GROUP, {DEFAULT_HIGH, 0, 1} },
{ "damping", CTRL_IN, {DEFAULT_HIGH, 0, 1} },
{ "out", OUTPUT | AUDIO}
......@@ -275,7 +284,7 @@ CEO::init()
int16 * wave = new int16 [n];
DSP::BiQuad<sample_t> lp;
/* suppress aliasing with an additional lowpass */
/* suppress aliasing with an additional lowpass; also slight gain at 3 kHz */
DSP::RBJ::LP (3000*over_fs,1.5,lp);
#if 1 /* linear */
float x = 0;
......@@ -288,7 +297,7 @@ CEO::init()
wave[i] = (int16) a;
x += dx;
}
#else /* cubic */
#else /* cubic, unneeded */
float x = 0;
for (int i=0; i < n; ++i, x+=dx)
{
......@@ -327,36 +336,4 @@ Descriptor<CEO>::setup()
autogen();
}
/* //////////////////////////////////////////////////////////////////////// */
PortInfo
Dirac::port_info [] =
{
{ "ppm", CTRL_IN, {DEFAULT_LOW, 2, 360} },
{ "volume", CTRL_IN | GROUP, {DEFAULT_HIGH, 0, 1} },
{ "damping", CTRL_IN, {DEFAULT_0, 0, 1} },
{ "out", OUTPUT | AUDIO}
};
void
Dirac::init()
{
int16 * dirac = new int16[1];
*dirac = 32767;
initwave (0, dirac, 1);
}
template <> void
Descriptor<Dirac>::setup()
{
Label = "Dirac";
Name = CAPS "Dirac - One-sample impulse generator";
Maker = "Tim Goetze <tim@quitte.de>";
Copyright = "2004-7";
/* fill port info and vtable */
autogen();
}
......@@ -78,27 +78,21 @@ class ClickStub
};
class Click
: public ClickStub<3>
: public ClickStub<4>
{
public:
void init() { initsimple(); initparfilt(); initsine(); }
void initsimple();
void initparfilt();
void initsine();
void initdirac();
static PortInfo port_info [];
};
class CEO
: public ClickStub<1>
{
public:
void init();
void init()
{ initsimple(); initparfilt(); initsine(); initdirac(); }
static PortInfo port_info [];
};
class Dirac
class CEO
: public ClickStub<1>
{
public:
......
......@@ -134,7 +134,7 @@ Compress::port_info [] =
{ "measure", CTRL_IN, {INTEGER | DEFAULT_0, 0, 1},
"{0:'peak',1:'rms'}" },
{ "mode", CTRL_IN | GROUP, {INTEGER | DEFAULT_1, 0, 3},
"{0:'linear',1:'saturating 2x',2:'saturating 4x',3:'saturating 4x128'}" },
"{0:'no limiting',1:'saturating 2x',2:'saturating 4x',3:'saturating 4x128'}" },
{ "threshold", CTRL_IN | GROUP, {DEFAULT_0, 0, 1} },
{ "strength", CTRL_IN, {DEFAULT_LOW, 0, 1} },
{ "attack", CTRL_IN | GROUP, {DEFAULT_0, 0, 1} },
......@@ -160,7 +160,7 @@ Descriptor<Compress>::setup()
/* //////////////////////////////////////////////////////////////////////// */
PortInfo
Compress2x2::port_info [] =
CompressX2::port_info [] =
{
{ "measure", CTRL_IN, {INTEGER | DEFAULT_0, 0, 1},
"{0:'peak',1:'rms'}" },
......@@ -178,11 +178,11 @@ Compress2x2::port_info [] =
};
template <> void
Descriptor<Compress2x2>::setup()
Descriptor<CompressX2>::setup()
{
Label = "Compress2x2";
Label = "CompressX2";
Name = CAPS "Compress2x2 - Stereo compressor and saturating limiter";
Name = CAPS "CompressX2 - Stereo compressor and saturating limiter";
Maker = "Tim Goetze <tim@quitte.de>";
Copyright = "2011-13";
......