diff --git a/plugins/ladspa_effect/caps/Amp.cc b/plugins/ladspa_effect/caps/Amp.cc index 52045e765..1d2a8a71b 100644 --- a/plugins/ladspa_effect/caps/Amp.cc +++ b/plugins/ladspa_effect/caps/Amp.cc @@ -84,15 +84,15 @@ template void AmpIII::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; - d_sample gain = getport(1); - d_sample temp = getport(2) * tube.scale; + sample_t gain = getport(1); + sample_t temp = getport(2) * tube.scale; drive = getport(3) * .5; i_drive = 1 / (1 - drive); - d_sample * d = ports[4]; + sample_t * d = ports[4]; *ports[5] = OVERSAMPLE; @@ -109,7 +109,7 @@ AmpIII::one_cycle (int frames) for (int i = 0; i < frames; ++i) { - register d_sample a = s[i]; + register sample_t a = s[i]; a = g * tube.transfer (a * temp); a = filter.process (a + normal); @@ -200,17 +200,17 @@ AmpIV::one_cycle (int frames) { double one_over_n = frames > 0 ? 1. / frames : 1; - d_sample * s = ports[0]; + sample_t * s = ports[0]; - d_sample gain = getport(1); - d_sample temp = getport(2) * tube.scale; + sample_t gain = getport(1); + sample_t temp = getport(2) * tube.scale; tone.start_cycle (ports + 3, one_over_n); drive = getport(7) * .5; i_drive = 1 / (1 - drive); - d_sample * d = ports[8]; + sample_t * d = ports[8]; *ports[9] = OVERSAMPLE; @@ -226,7 +226,7 @@ AmpIV::one_cycle (int frames) for (int i = 0; i < frames; ++i) { - register d_sample a = s[i] + normal; + register sample_t a = s[i] + normal; a = g * tube.transfer (a * temp); a = tone.process (a); @@ -337,9 +337,9 @@ template void AmpV::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; - d_sample gain = getport(1); + sample_t gain = getport(1); if (*ports[2] != cut) { @@ -359,10 +359,10 @@ AmpV::one_cycle (int frames) i_drive = 1 / (1 - drive); #define MAX_WATTS port_info[5].range.UpperBound - d_sample sag = (MAX_WATTS - getport(5)) / MAX_WATTS; + sample_t sag = (MAX_WATTS - getport(5)) / MAX_WATTS; sag = .6 * sag * sag; - d_sample * d = ports[6]; + sample_t * d = ports[6]; *ports[7] = OVERSAMPLE; @@ -382,8 +382,8 @@ AmpV::one_cycle (int frames) for (int i = 0; i < frames; ++i) { - register d_sample a = s[i]; - register d_sample v = 3 - supply; + register sample_t a = s[i]; + register sample_t v = 3 - supply; /* alternative curve: v = v * v * .1 + .1; */ v = v * v * .06 + .46; @@ -503,18 +503,18 @@ template void AmpVTS::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; tonestack.start_cycle (ports + 1, 2); - d_sample gain = getport(2); + sample_t gain = getport(2); drive = getport(6) * .5; i_drive = 1 / (1 - drive); - d_sample sag = 1 - max (0.0001, min (1, getport(7))); + sample_t sag = 1 - max (0.0001, min (1, getport(7))); sag = .6 * sag * sag; /* map to log space makes slider better */ - d_sample * d = ports[8]; + sample_t * d = ports[8]; *ports[9] = OVERSAMPLE; diff --git a/plugins/ladspa_effect/caps/Amp.h b/plugins/ladspa_effect/caps/Amp.h index aca536389..e06f7128f 100644 --- a/plugins/ladspa_effect/caps/Amp.h +++ b/plugins/ladspa_effect/caps/Amp.h @@ -49,7 +49,7 @@ class AmpStub public: DSP::TwelveAX7_3 tube; - d_sample drive, i_drive; + sample_t drive, i_drive; struct { /* gain (remember current setting and fade to port setting in run) */ @@ -78,7 +78,7 @@ class AmpStub void init (bool adjust_downsampler = false); - inline d_sample power_transfer (d_sample a) + inline sample_t power_transfer (sample_t a) { return i_drive * (a - drive * fabs (a) * a); } @@ -98,7 +98,7 @@ class PreampIII public: static PortInfo port_info[]; - d_sample adding_gain; + sample_t adding_gain; void init(); void activate() @@ -136,7 +136,7 @@ class AmpIII public: static PortInfo port_info[]; - d_sample adding_gain; + sample_t adding_gain; void init(); void activate() @@ -169,16 +169,16 @@ PreampBand; class ToneControls { public: - d_sample eq_gain[4]; + sample_t eq_gain[4]; DSP::Eq<4> eq; static PreampBand bands[4]; public: void init (double _fs); - void activate (d_sample **); + void activate (sample_t **); inline void - start_cycle (d_sample ** ports, double one_over_n) + start_cycle (sample_t ** ports, double one_over_n) { for (int i = 0; i < 4; ++i) { @@ -198,7 +198,7 @@ class ToneControls double get_band_gain (int i, double g); void set_band_gain (int i, float g); - inline d_sample process (d_sample x) + inline sample_t process (sample_t x) { return eq.process (x); } @@ -218,7 +218,7 @@ class PreampIV public: static PortInfo port_info[]; - d_sample adding_gain; + sample_t adding_gain; void init(); void activate(); @@ -248,7 +248,7 @@ class AmpIV public: static PortInfo port_info[]; - d_sample adding_gain; + sample_t adding_gain; void init(); void activate() @@ -284,16 +284,16 @@ class AmpV DSP::BiQuad filter[3]; - d_sample cut, tone; + sample_t cut, tone; /* supply voltage sag */ - d_sample supply; + sample_t supply; DSP::BiQuad power_cap[2]; public: static PortInfo port_info[]; - d_sample adding_gain; + sample_t adding_gain; void init(); void activate() @@ -336,16 +336,16 @@ class AmpVTS template void one_cycle (int frames); - d_sample cut, tone; + sample_t cut, tone; /* supply voltage sag */ - d_sample supply; + sample_t supply; DSP::BiQuad power_cap[2]; public: static PortInfo port_info[]; - d_sample adding_gain; + sample_t adding_gain; void init(); void activate() diff --git a/plugins/ladspa_effect/caps/CHANGES b/plugins/ladspa_effect/caps/CHANGES new file mode 100644 index 000000000..19c915d70 --- /dev/null +++ b/plugins/ladspa_effect/caps/CHANGES @@ -0,0 +1,206 @@ +0.4.5 + * Narrower plugin added + * fixed 'configure.py' to work with python3 + * fixed Sin, Roessler and Lorenz gain smoothing on activation + +0.4.4 + +0.4.3 + * basics.h cleanup / comments + * minor Makefile cleanup + * comment cosmetics + * Eq and Eq2x2 per-band Q changed to 1.414 (= 1 octave) + * Eq lowest band default value fixed to read 0 + * Niclas' fix for the bessel function implemented + * uninitialised plugin states eliminated thanks to Damon + * linker options for OSX added to the Makefile + +0.4.2 + * fixed the 'model' port index for AmpVTS in the RDF generator + +0.4.1 + * cleaned up Eq.h and Eq.cc (many g++ versions choke on the unused code + there) + * changed -O3 to -O2 in the g++ invocation + +0.4.0 + * ToneStack plugins, by David Yeh + * AmpV + Tone stack plugin, employing David Yeh's fine work + * comment cosmetics + * Amp* denormal protection fixed (or is it, Dave? ;) + * minor code cleanup in Amp.cc + * caps.rdf updated with plugin categories (thanks to Paul Winkler) + * caps.rdf Cabinet* RDF preset labels renamed + * AutoWah plugin + * DSP::RMS reworked, may affect Compress plugin + * DSP::Eq reworked for double precision and denormal protection + * ./configure.py checks SSE availability + * in case of SSE math denormal flush to zero activated for all plugins + * all plugins renamed C* .. instead of CAPS: .. + * Eq modified to play nice with ardour + * Eq2x2 + * introduced the Plugin base class, collecting common traits (normal etc) + * getport() -- read access to control ports which is clamped to port bounds + and maps inf and nan to 0 as well + * all LADSPA_HINT_SAMPLE_RATE ports changed to *_LOGARITHMIC because + of broken implementations (no surprise given the vagueness of ladspa.h + regarding this matter) -- this means changed default parameters of the + affected ports, too + * VCO* "latency" output ports removed + * actual activate() call is deferred to first run() after activate() + in order to prevent inadvertent parameter smoothing sweeps during the first + block of audio after activation, this should fix all problems with ardour + (except those caused by denormals or invalid audio input) + * caps.rdf installed by 'make install' + * fixed a bug in tools/make-ps.py that caused the spectrum plots to + be inaccurate for multi-channel plugins + +0.3.0 + * TwelveAX7_3 changed to clip slightly early in the upper lobe + * Scape plugin added + * plugin names rewritten, prefixed with "CAPS:" + * new ChorusII, StereoChorusII plugins + * Chorus, StereoChorus relabeled, appended 'I' suffix + * new PhaserII plugin (great stuff if I may say so) + * Phaser relabeled, appended 'I' suffix + * new AmpV plugin, based on AmpIII, emulates compression and distortion + modulation through power supply shortcomings, plus lots of fine-tuning + and an additional biquad. We're getting there! + * all Preamp and Amp models fitted with a new 12AX7 model, linear + interpolation of a sample table obtained from spice simulation + +0.2.4 + * feedback default reverted to 0 for the Chorus units + * fixed Cabinet to switch to correct gain at 'model' control change + * fixed 'model' control in Cabinet to work with a broader range of hosts + * Cabinet name changed to CabinetI + * CabinetII plugin: Cabinet with 32nd order IIR filters, more fidelity + to the original frequency responses, supplied coefficients for 4 of the + most used sample rates + * applied the gcc-4 enabling patch + * SweepVF renamed to SweepVFI + * new SweepVFII plugin, variant of SweepVFI with Q modulated by a + second Lorenz fractal + * dsp/exp2 dumped in favour of libm's exp2(3) + +0.2.3 + * StereoChorus denormal protection made functional + (Thanks again to S. Savolainen) + * Phaser denormal protected + +0.2.2 + * Build was _not_ fixed for g++-4.0. + * AmpIV gain control restored to operate as expected + * Chorus/StereoChorus denormal protection (thanks to S. Savolainen) + * a few cosmetic changes elsewhere + +0.2.1 + * Build fixed for g++-4.0, PPC and AMD64 + (Thanks to Niklas Werner, Andreas Jochens and Mario Lang) + * Reverb.* cosmetics + * AmpIV tone controls moved to after initial tube transfer + +0.2.0 + * denormal protection for Preamp*, Amp* + * Capitalized plugin Names + * PDF now lists audio in- and outputs as well as control inputs, only + gives average CPU rating + * AmpIV: PreampIV + power amp stage + * Plate2x2: Plate with 2-in, 2-out audio routing + * Plate damping and bandwidth controls changed to map to filter fc, fixes + behaviour in hosts that handle the log hint incorrectly + +0.1.13 + * AmpIII activate() resets the boost filter + +0.1.12 + * PreampIV band controls fixed to operate as expected + +0.1.11 + * amps changed back to old tube model :) but new temp & gain behaviour stays + * SweepVF, AmpIII default value adjustments + +0.1.10 + * HRTF recursion runs in doubles + * Cabinet recursion runs in doubles for much clearer sound + * all amps fitted with a common tube voltage mapping, dsp/TwelveAX7.h + * all amps: temperature and gain controls changed slightly + * all amps declared in one common Amp.h + * Pan echo fixed to be filtered independent of sample rate + * Cabinet cosmetics and activate() from port values fix + * SweepVF fixed to activate() from the current control settings + * rid all *amp* plugins of the initial hi-pass, not needed anymore + * PreampIII and AmpIII more authentic with an rbj lo-shelve, +6 dB > 1.2 kHz + as hinted by circuit analysis + * something_random() removed, stdlib for random generation + +0.1.9 + * Pan plugin + * 'make depend' instead of 'make dep', uses $(CC) -MM instead of 'makedepend' + * *Chorus, AmpIII, Plate defaults changed + * *Chorus optimizations, reintroduces funny zipper noise when 'feedback' is + non-zero and 't' is changed + * experimental HRTF plugin + * Plate 'blend' goes all the way to wet output only + * dsp/White offers a get_31() method for reduced number of bitshifts needed + * *Chorus delay line tapping changed to employ cubic interpolation, sounds + better + * SweepVF modulation mix algorithm changed to clamp if over-fed, makes + for wider sweeps + +0.1.8 + * all oversampling plugins use Kaiser windows instead of Blackman-Harris, + for much better performance + * SweepVF modulation range slightly increased + * Cabinet filter loop cosmetics (slight speedup) + * new AmpIII Plugin: Preamp plus power amp emulation + * lowered NOISE_FLOOR (equals 'renormal' number) + +0.1.7 + * connect ports to lower bound on instantiate() + * Plate delay line lengths raised, sound changed + * Eq activate() fixed to initialize from the current settings + * Preamp* cutoff reverted to 0.1.3 setting, thanks to Ben Saylor for + testing + * old IIR-based Preamp cleaned from the sources + * zipper-noise in *Chorus units for t changes with feedback > 0 eliminated + * all plugin constructor code moved to init() calls + +0.1.6 + * SweepVF modulation mix algorithm changed to maintain proportion, not + absolute value if x + y + z > 1, for better control + * create $(DEST) directory on make install, pointed out by Daniel James + +0.1.5 + * fixed delay line length miscalculation in ModLattice + +0.1.4 + * SweepVF modulation source can be mixed now + * latency port for VCO* + * Lorenz and Roessler get x, y, z mixing knobs + * PreampIV eq bands slightly tuned and coefficients moved into common struct + * Preamp*, VCO* downsampler filter cutoff lowered + * Clip downsampler filter cutoff lowered + * nonsensical audio output bounds removed + * simplified VCO* implementation + * JVRev rewritten for code clarity (funny enough, it also got quicker) + * fixed JVRev to reset its history on activate() + * added purpose, copyright and licensing information to all (i think) files. + * HACKING file + * CHANGES file + +0.1.3 + * fixed all compilation problems with gcc 3.3, with the patient help + of the lad mailing list community + * dsp/Eq.h SSE assembler code had to go (gcc > 3 doesn't like multi-line + asm, and efficiency and even reliability go down if we allow gcc to + intersperse its 'optimization' code with our asm) + +0.1.2 + * fixed more compilation problems with gcc >= 3.0 + +0.1.1 + * tried to (but didn't really) fix compilation problem with ladspa.h + +0.1.0 + * initial release diff --git a/plugins/ladspa_effect/caps/Cabinet.cc b/plugins/ladspa_effect/caps/Cabinet.cc index bf91ed460..e28b94538 100644 --- a/plugins/ladspa_effect/caps/Cabinet.cc +++ b/plugins/ladspa_effect/caps/Cabinet.cc @@ -101,21 +101,22 @@ void CabinetI::activate() { switch_model ((int) getport(1)); + gain = models[model].gain * DSP::db2lin (getport(2)); } template void CabinetI::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; int m = (int) getport (1); if (m != model) switch_model (m); - d_sample g = models[model].gain * DSP::db2lin (getport(2)); + sample_t g = models[model].gain * DSP::db2lin (getport(2)); double gf = pow (g / gain, 1 / (double) frames); - d_sample * d = ports[3]; + sample_t * d = ports[3]; for (int i = 0; i < frames; ++i) { @@ -227,15 +228,14 @@ template void CabinetII::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; int m = (int) getport (1); if (m != model) switch_model (m); - d_sample g = models[model].gain * DSP::db2lin (getport(2)); + sample_t g = models[model].gain * DSP::db2lin (getport(2)); double gf = pow (g / gain, 1 / (double) frames); - - d_sample * d = ports[3]; + sample_t * d = ports[3]; for (int i = 0; i < frames; ++i) { diff --git a/plugins/ladspa_effect/caps/Cabinet.h b/plugins/ladspa_effect/caps/Cabinet.h index 7bc82be9f..4b6f1957d 100644 --- a/plugins/ladspa_effect/caps/Cabinet.h +++ b/plugins/ladspa_effect/caps/Cabinet.h @@ -57,7 +57,7 @@ class CabinetI : public Plugin { public: - d_sample gain; + sample_t gain; static Model16 models []; int model; @@ -95,7 +95,7 @@ class CabinetII : public Plugin { public: - d_sample gain; + sample_t gain; static Model32 models44100 []; static Model32 models48000 []; @@ -116,7 +116,7 @@ class CabinetII public: static PortInfo port_info []; - d_sample adding_gain; + sample_t adding_gain; void init(); void activate(); diff --git a/plugins/ladspa_effect/caps/Chorus.cc b/plugins/ladspa_effect/caps/Chorus.cc index f752e315c..cf3afe4a8 100644 --- a/plugins/ladspa_effect/caps/Chorus.cc +++ b/plugins/ladspa_effect/caps/Chorus.cc @@ -34,7 +34,7 @@ template void ChorusI::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; double one_over_n = 1 / (double) frames; double ms = .001 * fs; @@ -56,13 +56,13 @@ ChorusI::one_cycle (int frames) double ff = getport(5); double fb = getport(6); - d_sample * d = ports[7]; + sample_t * d = ports[7]; DSP::FPTruncateMode truncate; for (int i = 0; i < frames; ++i) { - d_sample x = s[i]; + 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 @@ -153,7 +153,7 @@ template void StereoChorusI::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; double one_over_n = 1 / (double) frames; double ms = .001 * fs; @@ -181,8 +181,8 @@ StereoChorusI::one_cycle (int frames) double ff = getport(6); double fb = getport(7); - d_sample * dl = ports[8]; - d_sample * dr = ports[9]; + sample_t * dl = ports[8]; + sample_t * dr = ports[9]; /* to go sure (on i386) that the fistp instruction does the right thing * when looking up fractional sample indices */ @@ -190,7 +190,7 @@ StereoChorusI::one_cycle (int frames) for (int i = 0; i < frames; ++i) { - d_sample x = s[i]; + 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 @@ -201,8 +201,8 @@ StereoChorusI::one_cycle (int frames) delay.put (x + normal); - d_sample l = blend * x + ff * delay.get_cubic (t + w * left.lfo.get()); - d_sample r = blend * x + ff * delay.get_cubic (t + w * right.lfo.get()); + sample_t l = blend * x + ff * delay.get_cubic (t + w * left.lfo.get()); + sample_t r = blend * x + ff * delay.get_cubic (t + w * right.lfo.get()); F (dl, i, l, adding_gain); F (dr, i, r, adding_gain); @@ -281,7 +281,7 @@ template void ChorusII::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; double one_over_n = 1 / (double) frames; double ms = .001 * fs; @@ -303,13 +303,13 @@ ChorusII::one_cycle (int frames) double ff = getport(5); double fb = getport(6); - d_sample * d = ports[7]; + sample_t * d = ports[7]; DSP::FPTruncateMode truncate; for (int i = 0; i < frames; ++i) { - d_sample x = s[i]; + sample_t x = s[i]; x -= fb * delay.get_cubic (t); @@ -389,7 +389,7 @@ template void StereoChorusII::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; double one_over_n = 1 / (double) frames; double ms = .001 * fs; @@ -410,8 +410,8 @@ StereoChorusII::one_cycle (int frames) double ff = getport(5); double fb = getport(6); - d_sample * dl = ports[7]; - d_sample * dr = ports[8]; + sample_t * dl = ports[7]; + sample_t * dr = ports[8]; /* to go sure (on i386) that the fistp instruction does the right thing * when looking up fractional sample indices */ @@ -419,7 +419,7 @@ StereoChorusII::one_cycle (int frames) for (int i = 0; i < frames; ++i) { - d_sample x = s[i]; + 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 @@ -432,9 +432,9 @@ StereoChorusII::one_cycle (int frames) double m; m = left.lfo_lp.process (left.fractal.get()); - d_sample l = blend * x + ff * delay.get_cubic (t + w * m); + sample_t l = blend * x + ff * delay.get_cubic (t + w * m); m = right.lfo_lp.process (right.fractal.get()); - d_sample r = blend * x + ff * delay.get_cubic (t + w * m); + sample_t r = blend * x + ff * delay.get_cubic (t + w * m); F (dl, i, l, adding_gain); F (dr, i, r, adding_gain); diff --git a/plugins/ladspa_effect/caps/Chorus.h b/plugins/ladspa_effect/caps/Chorus.h index 8627a1d53..03ed256ec 100644 --- a/plugins/ladspa_effect/caps/Chorus.h +++ b/plugins/ladspa_effect/caps/Chorus.h @@ -41,7 +41,7 @@ class ChorusStub : public Plugin { public: - d_sample time, width, rate; + sample_t time, width, rate; }; class ChorusI @@ -92,8 +92,8 @@ class StereoChorusI : public ChorusStub { public: - d_sample rate; - d_sample phase; + sample_t rate; + sample_t phase; DSP::Delay delay; @@ -161,14 +161,14 @@ class FracTap f2.init (.001, frandom()); } - void set_rate (d_sample r) + void set_rate (sample_t r) { f1.set_rate (r * FRACTAL_RATE); f2.set_rate (3.3 * r * FRACTAL_RATE); } /* t = time, w = width, should inline nicely */ - d_sample get (DSP::Delay & d, double t, double w) + sample_t get (DSP::Delay & d, double t, double w) { double m = lp.process (f1.get() + .3 * f2.get()); return d.get_cubic (t + w * m); @@ -190,7 +190,7 @@ class ChorusII template void one_cycle (int frames); - void set_rate (d_sample r) + void set_rate (sample_t r) { rate = r; for (int i = 0; i < Taps; ++i) @@ -237,8 +237,8 @@ class StereoChorusII : public ChorusStub { public: - d_sample rate; - d_sample phase; + sample_t rate; + sample_t phase; DSP::Delay delay; @@ -251,7 +251,7 @@ class StereoChorusII template void one_cycle (int frames); - void set_rate (d_sample r) + void set_rate (sample_t r) { rate = r; left.fractal.set_rate (rate * FRACTAL_RATE); @@ -262,7 +262,7 @@ class StereoChorusII public: static PortInfo port_info []; - d_sample adding_gain; + sample_t adding_gain; void init() { diff --git a/plugins/ladspa_effect/caps/Click.cc b/plugins/ladspa_effect/caps/Click.cc index 764410f4e..d862c55f4 100644 --- a/plugins/ladspa_effect/caps/Click.cc +++ b/plugins/ladspa_effect/caps/Click.cc @@ -46,10 +46,10 @@ void ClickStub::one_cycle (int frames) { bpm = getport(0); - d_sample gain = getport(1) * *ports[1]; + sample_t gain = getport(1) * *ports[1]; lp.set (1 - *ports[2]); - d_sample * d = ports[3]; + sample_t * d = ports[3]; while (frames) { @@ -67,7 +67,7 @@ ClickStub::one_cycle (int frames) for (int i = 0; i < n; ++i) { - d_sample x = gain * wave [played + i] + normal; + sample_t x = gain * wave [played + i] + normal; F (d, i, lp.process (x), adding_gain); normal = -normal; } diff --git a/plugins/ladspa_effect/caps/Click.h b/plugins/ladspa_effect/caps/Click.h index 1526c484b..feb5bc7a5 100644 --- a/plugins/ladspa_effect/caps/Click.h +++ b/plugins/ladspa_effect/caps/Click.h @@ -35,7 +35,7 @@ class ClickStub : public Plugin { public: - d_sample bpm; + sample_t bpm; float * wave; int N; /* number of samples in wave */ diff --git a/plugins/ladspa_effect/caps/Clip.cc b/plugins/ladspa_effect/caps/Clip.cc index 75cfc5ceb..20349144b 100644 --- a/plugins/ladspa_effect/caps/Clip.cc +++ b/plugins/ladspa_effect/caps/Clip.cc @@ -62,8 +62,8 @@ Clip::init() up.c[i] *= s; } -inline d_sample -Clip::clip (d_sample a) +inline sample_t +Clip::clip (sample_t a) { if (a < threshold[0]) return threshold[0]; @@ -76,7 +76,7 @@ template void Clip::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; double g = getport (1); double gf; @@ -85,16 +85,16 @@ Clip::one_cycle (int frames) else { gain_db = g; - d_sample g = DSP::db2lin (gain_db); + sample_t g = DSP::db2lin (gain_db); gf = pow (g / gain, 1 / (double) frames); } - d_sample * d = ports[2]; + sample_t * d = ports[2]; *ports[3] = OVERSAMPLE; for (int i = 0; i < frames; ++i) { - register d_sample a = gain * s[i]; + register sample_t a = gain * s[i]; a = down.process (clip (up.upsample (a))); diff --git a/plugins/ladspa_effect/caps/Clip.h b/plugins/ladspa_effect/caps/Clip.h index 26030f980..1be21bc3b 100644 --- a/plugins/ladspa_effect/caps/Clip.h +++ b/plugins/ladspa_effect/caps/Clip.h @@ -37,9 +37,9 @@ class Clip : public Plugin { public: - d_sample gain, gain_db; + sample_t gain, gain_db; - d_sample threshold[2]; + sample_t threshold[2]; enum { OVERSAMPLE = 8, @@ -53,7 +53,7 @@ class Clip template void one_cycle (int frames); - inline d_sample clip (d_sample x); + inline sample_t clip (sample_t x); public: static PortInfo port_info[]; diff --git a/plugins/ladspa_effect/caps/Compress.cc b/plugins/ladspa_effect/caps/Compress.cc index 078f60b0c..3d9725a64 100644 --- a/plugins/ladspa_effect/caps/Compress.cc +++ b/plugins/ladspa_effect/caps/Compress.cc @@ -35,10 +35,10 @@ template void Compress::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; - d_sample range = DSP::db2lin (getport(1)); - d_sample ratio = (*ports[2] - 1) / getport(2); + sample_t range = DSP::db2lin (getport(1)); + sample_t ratio = (*ports[2] - 1) / getport(2); /* sc1 has lookup tables here, and they're only 40 % used (400 ms/1 s). * thus, sc1's attack/release controls are a bit coarse due to truncation @@ -54,16 +54,16 @@ Compress::one_cycle (int frames) double ga = exp (-1 / (fs * getport(3))); double gr = exp (-1 / (fs * getport(4))); - d_sample threshold = getport(5); - d_sample knee = getport(6); + sample_t threshold = getport(5); + sample_t knee = getport(6); - d_sample * d = ports[7]; + sample_t * d = ports[7]; - d_sample knee0 = DSP::db2lin (threshold - knee); - d_sample knee1 = DSP::db2lin (threshold + knee); + sample_t knee0 = DSP::db2lin (threshold - knee); + sample_t knee1 = DSP::db2lin (threshold + knee); - d_sample ef_a = ga * .25; - d_sample ef_ai = 1 - ef_a; + sample_t ef_a = ga * .25; + sample_t ef_ai = 1 - ef_a; for (int i = 0; i < frames; ++i) { diff --git a/plugins/ladspa_effect/caps/Compress.h b/plugins/ladspa_effect/caps/Compress.h index c322824a5..2bd722c7e 100644 --- a/plugins/ladspa_effect/caps/Compress.h +++ b/plugins/ladspa_effect/caps/Compress.h @@ -36,10 +36,10 @@ class Compress { public: double fs; - d_sample f; + sample_t f; DSP::RMS rms; - d_sample sum, amp, env, gain, gain_t; + sample_t sum, amp, env, gain, gain_t; int count; diff --git a/plugins/ladspa_effect/caps/Descriptor.h b/plugins/ladspa_effect/caps/Descriptor.h index ecbd145b7..12c5d1c88 100644 --- a/plugins/ladspa_effect/caps/Descriptor.h +++ b/plugins/ladspa_effect/caps/Descriptor.h @@ -1,12 +1,12 @@ /* Descriptor.h - Copyright 2004-9 Tim Goetze + Copyright 2004-10 Tim Goetze http://quitte.de/dsp/ Creating a LADSPA_Descriptor for a CAPS plugin via a C++ template, - saves us a virtual function call compared to the usual method used + saving a virtual function call compared to the usual method used for C++ plugins in a C context. Descriptor

expects P to declare some common methods, like init(), @@ -130,7 +130,7 @@ class Descriptor LADSPA_PortRangeHint * ranges = ((Descriptor *) d)->ranges; plugin->ranges = ranges; - plugin->ports = new d_sample * [n]; + plugin->ports = new sample_t * [n]; /* connect to lower bound as a safety measure */ for (int i = 0; i < n; ++i) @@ -159,7 +159,7 @@ class Descriptor * plugin's activate() method for the first run() after * the host called in here. * - * It's simplest way to prevent a parameter smoothing sweep + * It's the simplest way to prevent a parameter smoothing sweep * in the first audio block after activation. plugin->activate(); */ diff --git a/plugins/ladspa_effect/caps/Eq.cc b/plugins/ladspa_effect/caps/Eq.cc index 6503c5323..dabd1b183 100644 --- a/plugins/ladspa_effect/caps/Eq.cc +++ b/plugins/ladspa_effect/caps/Eq.cc @@ -70,7 +70,7 @@ template void Eq::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; /* evaluate band gain changes and compute recursion factor to prevent * zipper noise */ @@ -78,7 +78,7 @@ Eq::one_cycle (int frames) for (int i = 0; i < 10; ++i) { - d_sample g = getport (1 + i); + sample_t g = getport (1 + i); if (g == gain[i]) { /* no gain factoring */ @@ -91,11 +91,11 @@ Eq::one_cycle (int frames) eq.gf[i] = pow (want / eq.gain[i], one_over_n); } - d_sample * d = ports[11]; + sample_t * d = ports[11]; for (int i = 0; i < frames; ++i) { - d_sample x = s[i]; + sample_t x = s[i]; x = eq.process (x); F (d, i, x, adding_gain); } @@ -230,13 +230,13 @@ Eq2x2::one_cycle (int frames) for (int c = 0; c < 2; ++c) { - d_sample + sample_t * s = ports[c], * d = ports[12 + c]; for (int i = 0; i < frames; ++i) { - d_sample x = s[i]; + sample_t x = s[i]; x = eq[c].process (x); F (d, i, x, adding_gain); } diff --git a/plugins/ladspa_effect/caps/Eq.h b/plugins/ladspa_effect/caps/Eq.h index d6b83dc62..3532b958f 100644 --- a/plugins/ladspa_effect/caps/Eq.h +++ b/plugins/ladspa_effect/caps/Eq.h @@ -37,7 +37,7 @@ class Eq : public Plugin { public: - d_sample gain[10]; + sample_t gain[10]; DSP::Eq<10> eq; int block; @@ -67,7 +67,7 @@ class Eq2x2 : public Plugin { public: - d_sample gain[10]; + sample_t gain[10]; DSP::Eq<10> eq[2]; template diff --git a/plugins/ladspa_effect/caps/HRTF.cc b/plugins/ladspa_effect/caps/HRTF.cc index 56d995414..70190b699 100644 --- a/plugins/ladspa_effect/caps/HRTF.cc +++ b/plugins/ladspa_effect/caps/HRTF.cc @@ -71,13 +71,13 @@ template void HRTF::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; int p = (int) getport(1); if (p != pan) set_pan (p); - d_sample * dl = ports[2]; - d_sample * dr = ports[3]; + sample_t * dl = ports[2]; + sample_t * dr = ports[3]; double l, r; diff --git a/plugins/ladspa_effect/caps/Lorenz.cc b/plugins/ladspa_effect/caps/Lorenz.cc index 77759e59c..95d74619a 100644 --- a/plugins/ladspa_effect/caps/Lorenz.cc +++ b/plugins/ladspa_effect/caps/Lorenz.cc @@ -1,7 +1,7 @@ /* Lorenz.cc - Copyright 2002-7 Tim Goetze + Copyright 2002-11 Tim Goetze http://quitte.de/dsp/ @@ -48,9 +48,9 @@ Lorenz::one_cycle (int frames) double g = (gain == *ports[4]) ? 1 : pow (getport(4) / gain, 1. / (double) frames); - d_sample * d = ports[5]; + sample_t * d = ports[5]; - d_sample x, sx = getport(1), sy = getport(2), sz = getport(3); + sample_t x, sx = getport(1), sy = getport(2), sz = getport(3); for (int i = 0; i < frames; ++i) { @@ -73,7 +73,7 @@ Lorenz::port_info [] = { "h", INPUT | CONTROL, - {BOUNDED, 0, 1} + {BOUNDED | DEFAULT_LOW, 0, 1} }, { "x", INPUT | CONTROL, diff --git a/plugins/ladspa_effect/caps/Lorenz.h b/plugins/ladspa_effect/caps/Lorenz.h index b386d9cd4..6407f923e 100644 --- a/plugins/ladspa_effect/caps/Lorenz.h +++ b/plugins/ladspa_effect/caps/Lorenz.h @@ -1,7 +1,7 @@ /* Lorenz.h - Copyright 2004-5 Tim Goetze + Copyright 2004-11 Tim Goetze http://quitte.de/dsp/ @@ -34,7 +34,7 @@ class Lorenz : public Plugin { public: - d_sample h, gain; + sample_t h, gain; DSP::Lorenz lorenz; @@ -45,7 +45,8 @@ class Lorenz static PortInfo port_info []; void init(); - void activate() {} + void activate() + { gain = getport(4); } void run (int n) { diff --git a/plugins/ladspa_effect/caps/Pan.cc b/plugins/ladspa_effect/caps/Pan.cc index 24e992cf0..0449f616b 100644 --- a/plugins/ladspa_effect/caps/Pan.cc +++ b/plugins/ladspa_effect/caps/Pan.cc @@ -1,11 +1,12 @@ /* Pan.cc - Copyright 2002-7 Tim Goetze + Copyright 2002-11 Tim Goetze http://quitte.de/dsp/ - panorama with width control + panorama with width control, + stereo image width reduction */ /* @@ -41,11 +42,11 @@ Pan::activate() { delay.reset(); tap.reset (400 / fs); - set_pan (*ports[1]); + set_pan (getport (1)); } inline void -Pan::set_pan (d_sample p) +Pan::set_pan (sample_t p) { pan = p; @@ -59,13 +60,13 @@ template void Pan::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; if (pan != *ports[1]) set_pan (getport(1)); - d_sample g = getport(2); - d_sample + sample_t g = getport(2); + sample_t width_l = g * gain_r, width_r = g * gain_l; @@ -73,10 +74,10 @@ Pan::one_cycle (int frames) bool mono = getport(4); - d_sample * dl = ports[5]; - d_sample * dr = ports[6]; + sample_t * dl = ports[5]; + sample_t * dr = ports[6]; - d_sample x, xt; + sample_t x, xt; if (mono) for (int i = 0; i < frames; ++i) { @@ -93,7 +94,7 @@ Pan::one_cycle (int frames) normal = -normal; } - else for (int i = 0; i < frames; ++i) + else /* stereo */ for (int i = 0; i < frames; ++i) { x = s[i]; @@ -159,3 +160,92 @@ Descriptor::setup() autogen(); } +/* //////////////////////////////////////////////////////////////////////// */ + +void +Narrower::init() +{ +} + +void +Narrower::activate() +{ +} + +template +void +Narrower::one_cycle (int frames) +{ + sample_t * sl = ports[0]; + sample_t * sr = ports[1]; + + if (strength != *ports[2]) + strength = *ports[2]; + + sample_t * dl = ports[3]; + sample_t * dr = ports[4]; + + double xl, xr, m; + double dry = 1 - strength, wet = strength; + + for (int i = 0; i < frames; ++i) + { + xl = sl[i]; + xr = sr[i]; + + m = wet * (xl + xr) * .5; + + xl *= dry; + xr *= dry; + + xl += m; + xr += m; + + F (dl, i, xl, adding_gain); + F (dr, i, xr, adding_gain); + } +} + +/* //////////////////////////////////////////////////////////////////////// */ + +PortInfo +Narrower::port_info [] = +{ + { + "in:l", + INPUT | AUDIO, + {0} + }, { + "in:r", + INPUT | AUDIO, + {0} + }, { + "strength", + INPUT | CONTROL, + {BOUNDED | DEFAULT_LOW, 0, 1} + }, { + "out:l", + OUTPUT | AUDIO, + {0} + }, { + "out:r", + OUTPUT | AUDIO, + {0} + } +}; + +template <> void +Descriptor::setup() +{ + UniqueID = 2595; + Label = "Narrower"; + Properties = HARD_RT; + + Name = CAPS "Narrower - Stereo image width reduction"; + Maker = "Tim Goetze "; + Copyright = "GPL, 2011"; + + /* fill port info and vtable */ + autogen(); +} + diff --git a/plugins/ladspa_effect/caps/Pan.h b/plugins/ladspa_effect/caps/Pan.h index 61176be5b..469ccb192 100644 --- a/plugins/ladspa_effect/caps/Pan.h +++ b/plugins/ladspa_effect/caps/Pan.h @@ -1,11 +1,12 @@ /* Pan.h - Copyright 2004-5 Tim Goetze + Copyright 2004-11 Tim Goetze http://quitte.de/dsp/ - panorama with width control + panorama with width control, + stereo image width reduction */ /* @@ -37,7 +38,7 @@ class PanTap int t; DSP::OnePoleLP damper; - d_sample get (DSP::Delay & delay) + sample_t get (DSP::Delay & delay) { return damper.process (delay[t]); } @@ -53,9 +54,9 @@ class Pan : public Plugin { public: - d_sample pan; + sample_t pan; - d_sample gain_l, gain_r; + sample_t gain_l, gain_r; DSP::Delay delay; PanTap tap; @@ -63,7 +64,7 @@ class Pan template void one_cycle (int frames); - inline void set_pan (d_sample); + inline void set_pan (sample_t); public: static PortInfo port_info []; @@ -82,4 +83,32 @@ class Pan } }; +/* stereo width reduction */ +class Narrower +: public Plugin +{ + public: + sample_t strength; + + template + void one_cycle (int frames); + + public: + static PortInfo port_info []; + + void init(); + void activate(); + + void run (int n) + { + one_cycle (n); + } + + void run_adding (int n) + { + one_cycle (n); + } + +}; + #endif /* _PAN_H_ */ diff --git a/plugins/ladspa_effect/caps/Phaser.cc b/plugins/ladspa_effect/caps/Phaser.cc index 817434e6b..b0116b448 100644 --- a/plugins/ladspa_effect/caps/Phaser.cc +++ b/plugins/ladspa_effect/caps/Phaser.cc @@ -37,7 +37,7 @@ template void PhaserI::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; if (rate != *ports[1]) { @@ -49,7 +49,7 @@ PhaserI::one_cycle (int frames) double spread = 1 + getport(3); double fb = getport(4); - d_sample * dst = ports[5]; + sample_t * dst = ports[5]; while (frames) { @@ -67,8 +67,8 @@ PhaserI::one_cycle (int frames) for (int i = 0; i < n; ++i) { - d_sample x = s[i]; - d_sample y = x + y0 * fb + normal; + sample_t x = s[i]; + sample_t y = x + y0 * fb + normal; for (int j = 5; j >= 0; --j) y = ap[j].process (y); @@ -138,7 +138,7 @@ template void PhaserII::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; lorenz.set_rate (getport(1) * .08); @@ -146,7 +146,7 @@ PhaserII::one_cycle (int frames) double spread = 1 + getport(3); double fb = getport(4); - d_sample * dst = ports[5]; + sample_t * dst = ports[5]; while (frames) { @@ -164,8 +164,8 @@ PhaserII::one_cycle (int frames) for (int i = 0; i < n; ++i) { - d_sample x = s[i]; - d_sample y = x + y0 * fb + normal; + sample_t x = s[i]; + sample_t y = x + y0 * fb + normal; for (int j = 5; j >= 0; --j) y = ap[j].process (y); diff --git a/plugins/ladspa_effect/caps/Phaser.h b/plugins/ladspa_effect/caps/Phaser.h index dd30e8cc7..c79b93053 100644 --- a/plugins/ladspa_effect/caps/Phaser.h +++ b/plugins/ladspa_effect/caps/Phaser.h @@ -36,7 +36,7 @@ class PhaserAP { public: - d_sample a, m; + sample_t a, m; PhaserAP() { @@ -48,9 +48,9 @@ class PhaserAP a = (1 - delay) / (1 + delay); } - d_sample process (d_sample x) + sample_t process (sample_t x) { - register d_sample y = -a * x + m; + register sample_t y = -a * x + m; m = a * y + x; return y; @@ -64,8 +64,8 @@ class PhaserI PhaserAP ap[6]; DSP::Sine lfo; - d_sample rate; - d_sample y0; + sample_t rate; + sample_t y0; struct { double bottom, range; @@ -117,8 +117,8 @@ class PhaserII PhaserAP ap[6]; DSP::Lorenz lorenz; - d_sample rate; - d_sample y0; + sample_t rate; + sample_t y0; struct { double bottom, range; diff --git a/plugins/ladspa_effect/caps/Preamp.cc b/plugins/ladspa_effect/caps/Preamp.cc index 79a416b65..3a1b903c8 100644 --- a/plugins/ladspa_effect/caps/Preamp.cc +++ b/plugins/ladspa_effect/caps/Preamp.cc @@ -42,10 +42,10 @@ template void PreampIII::one_cycle (int frames) { - d_sample * s = ports[0]; - d_sample gain = getport(1); - d_sample temp = getport(2) * tube.scale; - d_sample * d = ports[3]; + sample_t * s = ports[0]; + sample_t gain = getport(1); + sample_t temp = getport(2) * tube.scale; + sample_t * d = ports[3]; *ports[4] = OVERSAMPLE; double g = current.g; @@ -62,7 +62,7 @@ PreampIII::one_cycle (int frames) for (int i = 0; i < frames; ++i) { - register d_sample a = s[i] + normal; + register sample_t a = s[i] + normal; a = g * tube.transfer (a * temp); a = filter.process (a); @@ -145,13 +145,13 @@ PreampIV::one_cycle (int frames) { double one_over_n = frames > 0 ? 1. / frames : 1; - d_sample * s = ports[0]; - d_sample gain = getport(1); - d_sample temp = getport(2) * tube.scale; + sample_t * s = ports[0]; + sample_t gain = getport(1); + sample_t temp = getport(2) * tube.scale; tone.start_cycle (ports + 3, one_over_n); - d_sample * d = ports[7]; + sample_t * d = ports[7]; *ports[8] = OVERSAMPLE; double g = current.g; @@ -166,7 +166,7 @@ PreampIV::one_cycle (int frames) for (int i = 0; i < frames; ++i) { - register d_sample a = tone.process (s[i] + normal); + register sample_t a = tone.process (s[i] + normal); a = g * tube.transfer (a * temp); diff --git a/plugins/ladspa_effect/caps/Reverb.cc b/plugins/ladspa_effect/caps/Reverb.cc index 33627f7ad..9061daaf5 100644 --- a/plugins/ladspa_effect/caps/Reverb.cc +++ b/plugins/ladspa_effect/caps/Reverb.cc @@ -89,7 +89,7 @@ JVRev::init() } void -JVRev::set_t60 (d_sample t) +JVRev::set_t60 (sample_t t) { t60 = t; @@ -118,19 +118,19 @@ template void JVRev::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; if (t60 != *ports[1]) set_t60 (getport(1)); double wet = getport(2), dry = 1 - wet; - d_sample * dl = ports[3]; - d_sample * dr = ports[4]; + sample_t * dl = ports[3]; + sample_t * dr = ports[4]; for (int i = 0; i < frames; ++i) { - d_sample x = s[i], a = x + normal; + sample_t x = s[i], a = x + normal; x *= dry; @@ -140,7 +140,7 @@ JVRev::one_cycle (int frames) a = allpass[2].process (a, -apc); /* tank */ - d_sample t = 0; + sample_t t = 0; a -= normal; for (int j = 0; j < 4; ++j) @@ -254,7 +254,7 @@ PlateStub::init() } inline void -PlateStub::process (d_sample x, d_sample decay, d_sample * _xl, d_sample * _xr) +PlateStub::process (sample_t x, sample_t decay, sample_t * _xl, sample_t * _xr) { x = input.bandwidth.process (x); @@ -267,8 +267,8 @@ PlateStub::process (d_sample x, d_sample decay, d_sample * _xl, d_sample * _xr) x = input.lattice[3].process (x, indiff2); /* summation point */ - register d_sample xl = x + decay * tank.delay[3].get(); - register d_sample xr = x + decay * tank.delay[1].get(); + register sample_t xl = x + decay * tank.delay[3].get(); + register sample_t xr = x + decay * tank.delay[1].get(); /* lh */ xl = tank.mlattice[0].process (xl, dediff1); @@ -311,20 +311,20 @@ template void Plate::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; input.bandwidth.set (exp (-M_PI * (1. - getport(1)))); - d_sample decay = getport(2); + sample_t decay = getport(2); double damp = exp (-M_PI * getport(3)); tank.damping[0].set (damp); tank.damping[1].set (damp); - d_sample blend = getport(4), dry = 1 - blend; + sample_t blend = getport(4), dry = 1 - blend; - d_sample * dl = ports[5]; - d_sample * dr = ports[6]; + sample_t * dl = ports[5]; + sample_t * dr = ports[6]; /* the modulated lattices interpolate, which needs truncated float */ DSP::FPTruncateMode _truncate; @@ -332,9 +332,9 @@ Plate::one_cycle (int frames) for (int i = 0; i < frames; ++i) { normal = -normal; - d_sample x = s[i] + normal; + sample_t x = s[i] + normal; - d_sample xl, xr; + sample_t xl, xr; PlateStub::process (x, decay, &xl, &xr); @@ -402,21 +402,21 @@ template void Plate2x2::one_cycle (int frames) { - d_sample * sl = ports[0]; - d_sample * sr = ports[1]; + sample_t * sl = ports[0]; + sample_t * sr = ports[1]; input.bandwidth.set (exp (-M_PI * (1. - getport(2)))); - d_sample decay = getport(3); + sample_t decay = getport(3); double damp = exp (-M_PI * getport(4)); tank.damping[0].set (damp); tank.damping[1].set (damp); - d_sample blend = getport(5), dry = 1 - blend; + sample_t blend = getport(5), dry = 1 - blend; - d_sample * dl = ports[6]; - d_sample * dr = ports[7]; + sample_t * dl = ports[6]; + sample_t * dr = ports[7]; /* the modulated lattices interpolate, which needs truncated float */ DSP::FPTruncateMode _truncate; @@ -424,9 +424,9 @@ Plate2x2::one_cycle (int frames) for (int i = 0; i < frames; ++i) { normal = -normal; - d_sample x = (sl[i] + sr[i] + normal) * .5; + sample_t x = (sl[i] + sr[i] + normal) * .5; - d_sample xl, xr; + sample_t xl, xr; PlateStub::process (x, decay, &xl, &xr); xl = blend * xl + dry * sl[i]; diff --git a/plugins/ladspa_effect/caps/Reverb.h b/plugins/ladspa_effect/caps/Reverb.h index e7a15a316..568f1c558 100644 --- a/plugins/ladspa_effect/caps/Reverb.h +++ b/plugins/ladspa_effect/caps/Reverb.h @@ -59,10 +59,10 @@ class Lattice : public DSP::Delay { public: - inline d_sample - process (d_sample x, double d) + inline sample_t + process (sample_t x, double d) { - d_sample y = get(); + sample_t y = get(); x -= d * y; put (x); return d * x + y; @@ -76,8 +76,8 @@ class JVComb public: float c; - inline d_sample - process (d_sample x) + inline sample_t + process (sample_t x) { x += c * get(); put (x); @@ -90,7 +90,7 @@ class JVRev { public: static int default_length[9]; - d_sample t60; + sample_t t60; Lattice allpass [3]; JVComb comb[4]; @@ -104,7 +104,7 @@ class JVRev int length [9]; - void set_t60 (d_sample t); + void set_t60 (sample_t t); public: static PortInfo port_info []; @@ -147,11 +147,11 @@ class ModLattice tap.reset(); } - inline d_sample - process (d_sample x, double d) + inline sample_t + process (sample_t x, double d) { /* TODO: try all-pass interpolation */ - d_sample y = delay.get_at (n0 + width * lfo.get()); + sample_t y = delay.get_at (n0 + width * lfo.get()); x += d * y; delay.put (x); return y - d * x; /* note sign */ @@ -162,9 +162,9 @@ class PlateStub : public Plugin { public: - d_sample f_lfo; + sample_t f_lfo; - d_sample indiff1, indiff2, dediff1, dediff2; + sample_t indiff1, indiff2, dediff1, dediff2; struct { DSP::OnePoleLP bandwidth; @@ -202,8 +202,8 @@ class PlateStub tank.mlattice[1].lfo.set_f (1.2, fs, .5 * M_PI); } - inline void process (d_sample x, d_sample decay, - d_sample * xl, d_sample * xr); + inline void process (sample_t x, sample_t decay, + sample_t * xl, sample_t * xr); }; /* /////////////////////////////////////////////////////////////////////// */ diff --git a/plugins/ladspa_effect/caps/Roessler.cc b/plugins/ladspa_effect/caps/Roessler.cc index b7ac1f321..b82a620b7 100644 --- a/plugins/ladspa_effect/caps/Roessler.cc +++ b/plugins/ladspa_effect/caps/Roessler.cc @@ -1,7 +1,7 @@ /* Roessler.cc - Copyright 2002-7 Tim Goetze + Copyright 2002-11 Tim Goetze http://quitte.de/dsp/ @@ -48,9 +48,9 @@ Roessler::one_cycle (int frames) double g = (gain == getport(4)) ? 1 : pow (getport(4) / gain, 1. / (double) frames); - d_sample * d = ports[5]; + sample_t * d = ports[5]; - d_sample x, + sample_t x, sx = .043 * getport(1), sy = .051 * getport(2), sz = .018 * getport(3); @@ -79,7 +79,7 @@ Roessler::port_info [] = { "h", INPUT | CONTROL, - {BOUNDED, 0, 1} + {BOUNDED | DEFAULT_LOW, 0, 1} }, { "x", INPUT | CONTROL, diff --git a/plugins/ladspa_effect/caps/Roessler.h b/plugins/ladspa_effect/caps/Roessler.h index 845b77dd9..897ad1fde 100644 --- a/plugins/ladspa_effect/caps/Roessler.h +++ b/plugins/ladspa_effect/caps/Roessler.h @@ -1,7 +1,7 @@ /* Roessler.h - Copyright 2004-5 Tim Goetze + Copyright 2004-11 Tim Goetze http://quitte.de/dsp/ @@ -34,7 +34,7 @@ class Roessler : public Plugin { public: - d_sample h, gain; + sample_t h, gain; DSP::Roessler roessler; @@ -44,10 +44,11 @@ class Roessler public: static PortInfo port_info []; - d_sample adding_gain; + sample_t adding_gain; void init(); - void activate() {} + void activate() + { gain = getport(4); } void run (int n) { diff --git a/plugins/ladspa_effect/caps/Scape.cc b/plugins/ladspa_effect/caps/Scape.cc index 0df250115..be9e5a879 100644 --- a/plugins/ladspa_effect/caps/Scape.cc +++ b/plugins/ladspa_effect/caps/Scape.cc @@ -61,7 +61,7 @@ template void Scape::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; // double one_over_n = 1 / (double) frames; @@ -76,8 +76,8 @@ Scape::one_cycle (int frames) dry = dry * dry; double blend = getport(5); - d_sample * dl = ports[6]; - d_sample * dr = ports[7]; + sample_t * dl = ports[6]; + sample_t * dr = ports[7]; DSP::FPTruncateMode truncate; @@ -116,10 +116,10 @@ Scape::one_cycle (int frames) /* sample loop */ for (int i = 0; i < n; ++i) { - d_sample x = s[i] + normal; + sample_t x = s[i] + normal; - d_sample x1 = delay.get_at (t1); - d_sample x2 = delay.get_at (t2); + sample_t x1 = delay.get_at (t1); + sample_t x2 = delay.get_at (t2); delay.put (x + fb * x1 + normal); x = dry * x + .2 * svf[0].process (x) + .6 * svf[3].process(x); @@ -130,7 +130,7 @@ Scape::one_cycle (int frames) x1 = hipass[1].process (x1); x2 = hipass[2].process (x2); - d_sample x1l, x1r, x2l, x2r; + sample_t x1l, x1r, x2l, x2r; x1l = fabs (lfo[0].get()); x1r = 1 - x1l; x2r = fabs (lfo[1].get()); diff --git a/plugins/ladspa_effect/caps/Scape.h b/plugins/ladspa_effect/caps/Scape.h index dfbb9b19b..25cca9a1e 100644 --- a/plugins/ladspa_effect/caps/Scape.h +++ b/plugins/ladspa_effect/caps/Scape.h @@ -41,7 +41,7 @@ class Scape : public Plugin { public: - d_sample time, fb; + sample_t time, fb; double period; DSP::Lorenz lfo[2]; diff --git a/plugins/ladspa_effect/caps/Sin.cc b/plugins/ladspa_effect/caps/Sin.cc index 3f45196f2..150ddf88b 100644 --- a/plugins/ladspa_effect/caps/Sin.cc +++ b/plugins/ladspa_effect/caps/Sin.cc @@ -47,7 +47,7 @@ Sin::one_cycle (int frames) double g = (gain == *ports[1]) ? 1 : pow (getport(1) / gain, 1. / (double) frames); - d_sample * d = ports[2]; + sample_t * d = ports[2]; for (int i = 0; i < frames; ++i) { diff --git a/plugins/ladspa_effect/caps/Sin.h b/plugins/ladspa_effect/caps/Sin.h index 02051012e..fd540aa4d 100644 --- a/plugins/ladspa_effect/caps/Sin.h +++ b/plugins/ladspa_effect/caps/Sin.h @@ -1,7 +1,7 @@ /* Sin.h - Copyright 2004-5 Tim Goetze + Copyright 2004-11 Tim Goetze http://quitte.de/dsp/ @@ -34,7 +34,7 @@ class Sin : public Plugin { public: - d_sample f, gain; + sample_t f, gain; DSP::Sine sin; @@ -45,7 +45,8 @@ class Sin static PortInfo port_info []; void init(); - void activate() {} + void activate() + { gain = getport(1); } void run (int n) { diff --git a/plugins/ladspa_effect/caps/SweepVF.cc b/plugins/ladspa_effect/caps/SweepVF.cc index 50ea1dc31..95921c258 100644 --- a/plugins/ladspa_effect/caps/SweepVF.cc +++ b/plugins/ladspa_effect/caps/SweepVF.cc @@ -54,7 +54,7 @@ template void SweepVFI::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; int blocks = frames / BLOCK_SIZE; if (frames & (BLOCK_SIZE - 1)) @@ -69,7 +69,7 @@ SweepVFI::one_cycle (int frames) lorenz.set_rate (getport(7)); - d_sample * d = ports[8]; + sample_t * d = ports[8]; while (frames) { @@ -183,7 +183,7 @@ template void SweepVFII::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; int blocks = frames / BLOCK_SIZE; if (frames & (BLOCK_SIZE - 1)) @@ -199,7 +199,7 @@ SweepVFII::one_cycle (int frames) lorenz1.set_rate (getport(7)); lorenz2.set_rate (getport(11)); - d_sample * d = ports[12]; + sample_t * d = ports[12]; while (frames) { @@ -354,7 +354,7 @@ template void AutoWah::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; int blocks = frames / BLOCK_SIZE; if (frames & (BLOCK_SIZE - 1)) @@ -367,7 +367,7 @@ AutoWah::one_cycle (int frames) double scale = getport(3); - d_sample * d = ports[4]; + sample_t * d = ports[4]; while (frames) { @@ -389,7 +389,7 @@ AutoWah::one_cycle (int frames) for (int i = 0; i < n; ++i) { - d_sample x = s[i] + normal; + sample_t x = s[i] + normal; /* A stacked SVF in bandpass mode is rather quiet, which is * compensated here */ F (d, i, 2 * svf.process (x), adding_gain); diff --git a/plugins/ladspa_effect/caps/SweepVF.h b/plugins/ladspa_effect/caps/SweepVF.h index 780ca34af..f25a0008b 100644 --- a/plugins/ladspa_effect/caps/SweepVF.h +++ b/plugins/ladspa_effect/caps/SweepVF.h @@ -49,7 +49,7 @@ class SweepVFI double fs; /* svf parameters */ - d_sample f, Q; + sample_t f, Q; /* needs to be a power of two */ enum { @@ -84,7 +84,7 @@ class SweepVFII { public: /* svf parameters */ - d_sample f, Q; + sample_t f, Q; /* needs to be a power of two */ enum { @@ -124,7 +124,7 @@ class AutoWah double fs; /* svf parameters */ - d_sample f, Q; + sample_t f, Q; /* needs to be a power of two */ enum { diff --git a/plugins/ladspa_effect/caps/ToneControls.cc b/plugins/ladspa_effect/caps/ToneControls.cc index ea4c71cdf..1c08d22d5 100644 --- a/plugins/ladspa_effect/caps/ToneControls.cc +++ b/plugins/ladspa_effect/caps/ToneControls.cc @@ -62,7 +62,7 @@ ToneControls::set_band_gain (int i, float g) } void -ToneControls::activate (d_sample ** ports) +ToneControls::activate (sample_t ** ports) { for (int i = 0; i < 4; ++i) set_band_gain (i, *ports[i]); diff --git a/plugins/ladspa_effect/caps/ToneStack.cc b/plugins/ladspa_effect/caps/ToneStack.cc index 510d79378..4005f1851 100644 --- a/plugins/ladspa_effect/caps/ToneStack.cc +++ b/plugins/ladspa_effect/caps/ToneStack.cc @@ -76,13 +76,13 @@ template void ToneStack::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; tonestack.start_cycle (ports + 1); - d_sample * d = ports[5]; + sample_t * d = ports[5]; for (int i = 0; i < frames; ++i) { - register d_sample a = s[i]; + register sample_t a = s[i]; a = tonestack.process (a + normal); F (d, i, a, adding_gain); } @@ -140,13 +140,13 @@ template void ToneStackLT::one_cycle (int frames) { - d_sample * s = ports[0]; + sample_t * s = ports[0]; tonestack.updatecoefs (ports + 1); - d_sample * d = ports[4]; + sample_t * d = ports[4]; for (int i = 0; i < frames; ++i) { - register d_sample a = s[i]; + register sample_t a = s[i]; a = tonestack.process (a + normal); F (d, i, a, adding_gain); } diff --git a/plugins/ladspa_effect/caps/VCO.cc b/plugins/ladspa_effect/caps/VCO.cc index 0e62ba5fb..45bb6a9c9 100644 --- a/plugins/ladspa_effect/caps/VCO.cc +++ b/plugins/ladspa_effect/caps/VCO.cc @@ -8,6 +8,8 @@ an oversampled triangle/saw/square oscillator, and a combination of two such oscillators with hard sync. + TODO: optimize for phase clamping like this: + phi -= floor (phi); */ /* This program is free software; you can redistribute it and/or @@ -63,7 +65,7 @@ VCOs::one_cycle (int frames) double g = (gain == *ports[3]) ? 1 : pow (getport(3) / gain, 1. / (double) frames); - d_sample * d = ports[4]; + sample_t * d = ports[4]; for (int i = 0; i < frames; ++i) { @@ -160,7 +162,7 @@ VCOd::one_cycle (int frames) double g = (gain == *ports[8]) ? 1 : pow (getport(8) / gain, 1. / (double) frames); - d_sample * d = ports[9]; + sample_t * d = ports[9]; for (int i = 0; i < frames; ++i) { diff --git a/plugins/ladspa_effect/caps/VCO.h b/plugins/ladspa_effect/caps/VCO.h index b37dfd3e2..c6b06f378 100644 --- a/plugins/ladspa_effect/caps/VCO.h +++ b/plugins/ladspa_effect/caps/VCO.h @@ -40,7 +40,7 @@ class VCOs : public Plugin { public: - d_sample f, gain; + sample_t f, gain; /* ok to just change these as you please, 4/32 works ok, sortof. */ enum { @@ -89,7 +89,7 @@ class VCOd { public: double fs; - d_sample f, gain; + sample_t f, gain; /* ok to just change these as you please, 4/32 works ok, sortof. */ enum { diff --git a/plugins/ladspa_effect/caps/White.cc b/plugins/ladspa_effect/caps/White.cc index 00e80113d..28b2c3643 100644 --- a/plugins/ladspa_effect/caps/White.cc +++ b/plugins/ladspa_effect/caps/White.cc @@ -37,7 +37,7 @@ White::one_cycle (int frames) double g = (gain == *ports[0]) ? 1 : pow (getport(0) / gain, 1. / (double) frames); - d_sample * d = ports[1]; + sample_t * d = ports[1]; for (int i = 0; i < frames; ++i) { diff --git a/plugins/ladspa_effect/caps/White.h b/plugins/ladspa_effect/caps/White.h index ea7a56c31..5633599e8 100644 --- a/plugins/ladspa_effect/caps/White.h +++ b/plugins/ladspa_effect/caps/White.h @@ -34,7 +34,7 @@ class White : public Plugin { public: - d_sample gain; + sample_t gain; DSP::White white; @@ -46,9 +46,7 @@ class White void init() {} void activate() - { - gain = .5; - } + { gain = getport(0); } void run (int n) { diff --git a/plugins/ladspa_effect/caps/basics.h b/plugins/ladspa_effect/caps/basics.h index c2adc259f..df24e8c05 100644 --- a/plugins/ladspa_effect/caps/basics.h +++ b/plugins/ladspa_effect/caps/basics.h @@ -94,21 +94,20 @@ typedef struct { LADSPA_PortRangeHint range; } PortInfo; -typedef LADSPA_Data d_sample; -typedef double d_float; +typedef LADSPA_Data sample_t; typedef unsigned long ulong; /* flavours for sample store functions run() and run_adding() */ -typedef void (*sample_func_t) (d_sample *, int, d_sample, d_sample); +typedef void (*sample_func_t) (sample_t *, int, sample_t, sample_t); inline void -store_func (d_sample * s, int i, d_sample x, d_sample gain) +store_func (sample_t * s, int i, sample_t x, sample_t gain) { s[i] = x; } inline void -adding_func (d_sample * s, int i, d_sample x, d_sample gain) +adding_func (sample_t * s, int i, sample_t x, sample_t gain) { s[i] += gain * x; } @@ -175,24 +174,24 @@ class Plugin { double adding_gain; /* for run_adding() */ int first_run; /* 1st block after activate(), do no parameter smoothing */ - d_sample normal; /* renormal constant */ + sample_t normal; /* renormal constant */ - d_sample ** ports; + sample_t ** ports; LADSPA_PortRangeHint * ranges; /* for getport() below */ public: /* get port value, mapping inf or nan to 0 */ - inline d_sample getport_unclamped (int i) + inline sample_t getport_unclamped (int i) { - d_sample v = *ports[i]; + sample_t v = *ports[i]; return (isinf (v) || isnan(v)) ? 0 : v; } /* get port value and clamp to port range */ - inline d_sample getport (int i) + inline sample_t getport (int i) { LADSPA_PortRangeHint & r = ranges[i]; - d_sample v = getport_unclamped (i); + sample_t v = getport_unclamped (i); return clamp (v, r.LowerBound, r.UpperBound); } }; diff --git a/plugins/ladspa_effect/caps/caps.html b/plugins/ladspa_effect/caps/caps.html new file mode 100644 index 000000000..329886a00 --- /dev/null +++ b/plugins/ladspa_effect/caps/caps.html @@ -0,0 +1,1715 @@ + + + The CAPS Audio Plugin Suite + + + + +

+
+ +

The CAPS Audio Plugin Suite

+ + + + + + + + + + + +
+ Release 0.4.5 + + http://quitte.de/dsp/caps.html + + Tim Goetze +
+ March 26, 2011 + tim@quitte.de +
+ + + +  
+ +

Front Matter

+

+ CAPS, the C* Audio Plugin Suite, is a collection of + refined LADSPA audio plugins capable of (and mainly + intended for) realtime operation. The suite includes DSP units emulating + instrument amplifiers, stomp-box classics, + versatile 'virtual analogue' oscillators, + fractal oscillation, reverb, equalization and more. +

+

+ My favourite user's quote: + “... if your amps beat your plugins, they + are *very good* amps.. ;-)” – Thanks, Pete! +

+

+ Most of the suite is of my own invention, + while some plugins are rewrites of + existing designs, included for + excellence or interest. + Inspiring code was authored by + (in no particular order): + Andrew Simper, Perry Cook, Gary Scavone, + Steve Harris, Richard Dobson, Bram de Jong, + Robert Bristow-Johnson and others. +

+

+ The ToneStack plugins and the + tone controls of the AmpVTS unit + have been designed and implemented by + David Yeh at + CCRMA. +

+

+ Invaluable suggestions, bug hunting and fixing and + numerous patient reminders + of the sorry state of affairs + have been graciously + provided by (among others and in no particular order) + Sampo Savolainen, Damon Chaplin, Paul Winkler and Niclas Wretström. +

+

+ All of CAPS is free software and distributed + in source code. +

+  
+ +
* What's with the C?
+

+ So what does the C in the name stand for? Honestly, I don't know. +

+

+ Complete? Not yet.
+ C as in the programming language? The source is C++.
+ Crap? Heaven forbid!
+ Cute? Why not ...
+ Common? Not bad either.
+ C, the latin numeral for one-hundred? Some more to go, but I + like the idea. +

+

+ I've got it! C as in The Caps Audio Plugin Suite! + A classic. +

+ +  
+ +

Download

+

+ CAPS is distributed under the + GNU General Public License. Other licensing terms + can be arranged if you wish, please feel free to contact me. +

+ +
No Guarantee
+

+ While I have bred all the plugins in the suite with the greatest care, + there is no guarantee + that they will all retain perfect manners under all possible + circumstances. Take, for example, the Lorenz + plugin, which models + a fractal system. How am I to guarantee its + output will never go out of range, if people far more knowledgeable + about this fractal than me assert its unpredictable behaviour? +

+ +

+ This collection is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +

+ +

+ Download the latest release + here, it is caps_0.4.5.tar.gz (772 kB). +

+ +  
+ +

Installation

+ +

+ Provided you run Linux, + installation is simply: +

+ +
+$ tar xvfz caps_0.4.5.tar.gz 
+$ cd caps-0.4.5 
+$ ./configure.py
+$ make
+$ su
+# make install
+ +

+ The configure.py step is optional on Linux but recommended + for optimum performance. +

+

+ You should now be able use the plugins from the collection + in any LADSPA-aware host program, + like the wonderful pd with + the plugin~ + external, + the inimitable jack-rack, + the impressive ardour, + the versatile ecasound, + the classic snd, + and numerous other applications large and small. +

+ +

+ You don't run Linux? Why not + downgrade now? +

+ +
OSX
+

+ configure.py should detect an OSX build and prepare the + relevant flags for Apple's different-thinking ld + implementation. + Mind you, this is untested by me and + not guaranteed to actually work. If it does, please + tell me. Thanks! +

+ +
Troubleshooting
+

+ With no external dependencies, compiling CAPS + should rarely fail on a Linux box. If it + does on your machine, please send the output of the make + command so we can try and fix the problem. +

+ +
Bugs
+

+ If any of the plugins in the suite do not work with your host program + of choice, or don't work as advertised, please + send a bug report. +

+ +  
+ +

What You Should Know

+ +
Parameter Smoothing
+

+ To prevent zipper noise, many plugin control inputs are subject + to internal parameter smoothing where the effort seems justified. + This is achieved by sweeping parameters internal to the plugin. + The duration of this sweep will vary with the audio system setup. + For realtime use and most known LADSPA hosts it is equal to the audio + block size (in jackd terms: the "frames per period"). +

+ +
Sample Rate
+

+ The CAPS plugins are designed to be used at + sample rates of 44.1 kHz or higher. Operation at lower sample rates + is generally possible but untested. + Especially the resonant filters in the + SweepVFI, + SweepVFII, + AutoWah and + Scape plugins can self-oscillate out of + bounds at low sample rates and high filter cutoff frequency settings. + It is a wise idea to do some silent test runs testing + the entire parameter range to see if + the plugin works as expected before relying on its operation at + sample rates below 44.1 kHz. +

+

+ In the plugin listing, for every unit you'll see a note like + All sample rates. This means that the plugin should sound the + same no matter what sample rate it is run at. If it doesn't, holler at + me. + A note like 44.1 kHz only means you + can still run the plugin at other sample rates without having to fear + for your life, but the sonic experience may differ from what is + advertised. +

+

+ Usage at sample rates of 176 kHz or higher may cause problems with some + plugins. We recommend not exceeding 100 kHz for all applications. +

+ +
Realtime Use
+

+ All of the plugins in the suite are hard-realtime capable. In some + cases, parameter smoothing will take a marginal number of + extra CPU cycles when a control value is changed, as well as when the + plugin is starting or resuming operation. +

+ +
In-Place and Mixing/Replacing Operation
+

+ All of the plugins in the suite support any combination of in-place, + mixing and replacing operation. +

+ +
Denormals
+

+ Denormal numbers + (wikipedia) + are the bane of DSP on common computer systems because they seriously + slow down computing speed. In CAPS, various approaches are employed to + prevent this problem from arising. Most of the plugins add an inaudible + signal (-266 dB) at the Nyquist + (wikipedia) + or at a fixed lower frequency which keeps calculations out of the critical + zone around zero. In addition, if you run configure.py prior + to building CAPS, SSE extensions will be employed to aid in this task if + they are available on the build system. +

+ +
I'd love to hear from you. Really!
+

+ You like something about CAPS? Don't like it? + Either way, tell me – otherwise + I'll never be able to improve it! +

+ +
Known Bugs and Limitations
+
    +
  • + CPU usage figures, if given, may be inaccurate or even off by an + order of magnitude. +
  • +
  • + 8x oversampling consumes a lot of CPU power. +
  • +
  • + Since version 0.4.0, CAPS cannot be compiled with gcc 2.95 any more. +
  • +
  • + Processing blocks larger than 231 - 1 aren't supported. +
  • +
  • + Old jack-rack host versions have some crazy ideas about the + default control parameters of the CAPS plugins – they're all + over the place. +
  • +
  • + Sample rates in excess of 100 kHz may cause some plugins to develop + problems. +
  • +
  • + The White plugin + actually produces a slightly purplish signal despite the rather + boastful claims of signal purity made elsewhere. +
  • +
+ +  
+

Give me a Guitar Setup Already!

+ +

+ Start your guitar signal chain with an + AmpVTS, followed by a + CabinetII and finish with a + Plate reverb. + Season to taste, done. +

+ Additional effects like + chorus, + phaser or + auto wah would drop in right before or right after + the Cabinet (I usually prefer the latter). +

+ +  
+ +

The Plugins

+ +

Generic

+ +

Eq

+

+ A ten-band, octave-spread equalizer. Based on a traditional analogue + design and about as faithful as digital IIR filtering allows. + Individual band filters are 6 dB / octave. +

+

+ All sample rates (bands beyond Nyquist are disabled). +

+
    +
  • 31 Hz, 63 Hz, 125 Hz, 250 Hz, 500 Hz, 1 kHz, 2 kHz, 4 kHz, 8 kHz, 16 kHz
  • + control the gain in dB for the respective band.

    +
+ +

Eq2x2

+

+ By popular demand, a stereo-in, stereo-out version of the + Eq unit. + Same controls as Eq. +

+ +

Compress

+ +

+ A mono compressor, based on the SC1 design by + Steve Harris (in other words, a ripoff) + with minor tweaks. Be + careful with the gain and ratio controls, the output signal can easily + exceed 0 dB. +

+

+ All sample rates. +

+
    +
  • gain (dB)

    + controls the maximum gain applied by the unit.

  • +
  • ratio (1:n)

    + controls the overall gain.

  • +
  • attack (s)

    + controls the speed at which the circuit acts on a rising input signal + envelope.

  • +
  • release (s)

    + controls the speed at which the circuit acts on a decaying input signal + envelope.

  • +
  • threshold (dB)

    + sets the envelope level that the compressor starts acting at.

  • +
  • knee radius (dB)

    + controls the softness of the transition between unaltered and + compressed signal.

  • +
+ +

Pan

+

+ Places a monaural source in the stereo field. For some extra spicing, + the unit can also add a low-pass filtered echo at the far + ends of the stereo field to make the signal sound 'wider' (recreating + the old doubling effect with a twist). You can + (and should!) control the loudness and timing of the echo; what's best + depends largely on the source signal. +

+

+ No parameter smoothing. +

+

+ All sample rates. +

+
    +
  • pan

    + position

  • +
  • width

    + echo volume

  • +
  • t

    + delay in milliseconds

  • +
  • mono

    + if non-zero, causes the unit to mix the stereo output back down to mono + and output that (on both outbound ports). + The purpose is to check for mono + compatibility of the output.

  • +
+ +

Narrower

+

+ Reduces the width of a stereophonic signal. + Very useful for headphone listeners. +

+

+ No parameter smoothing. +

+

+ All sample rates. +

+
    +
  • strength

    + amount of width reduction

  • +
+ + +

Emulation

+ +

PreampIII

+

+ One further step in the evolution of my + tube preamplifier emulation. This one + uses conventional polyphase FIR filters for 8x oversampling, + which helps make the unit sound a good deal cleaner than the + IIR-based predecessor. +

+

+ The first steps towards this unit were based on a spice model + of the preamplifier circuit in a Fender 5F4 design ('Super' tube amp, + a close relative of the famed 'Bassman', which is the ancestor of the + Marshall lineage). Further evolution was + based on measurements of my 'Super 60' (mid-1980s) amp and, of course, + personal preference. + The plugin offers a softer kind of preamp clipping + than the actual circuit, though it can be made to clip as harsh as the + original thing if given enough gain. +

+

+ A word of caution: at high 'temperature' settings, an input + signal peaking above 0 dB can drive + the first 'tube' stage into hard clipping. Since this stage of the + circuit is run at the nominal sample rate, aliasing and thus sound + quality degradation will occur. + Do not overdrive the input, instead use the 'gain' knob for + harsh distortion, it offers more than enough of it. This applies to all + Preamp and Amp units. +

+

All sample rates.

+
    +
  • gain

    + controls the level of saturation. For a balanced (0 dB max.) + input signal, + hard clipping will not occur below a gain value of 1. +

  • +
  • temperature

    + emulates the level of the input signal, thus how much the first + preamplifier tube will colour the signal. + The effect is very subtle.

  • +
+ +

PreampIV

+

+ A variation on PreampIII with added tone controls + before the clipping stage. The tone controls have the same + flaws as their analog counterparts (phase cancellation at high band + gains). But exactly because they are not linear-phase, they are quite + useful in altering the distortion characteristics of the circuit. +

+

All sample rates.

+

+ Same parameters as PreampIII, plus the following + (all in dB units): +

+
    +
  • bass

    + 80 Hz band

  • +
  • mid

    + 300 Hz band

  • +
  • treble

    + 1200 Hz band

  • +
  • hi

    + 4800 Hz band

  • +
+ +

ToneStack

+

+ A close model of the tone stack of a traditional instrument + amplifier (of Fender origin), designed and implemented by David Yeh, + discussed in [2] + (see his project page at CCRMA). +

+ This is the 'procedural' implementation which uses a direct form II filter, + adapts to the actual sample rate and offers the choice of model + from a selection of several classic tone stacks. + (The AC-30 is a crude approximation for which David isn't to blame. I + simply dropped in the parameters although the circuit doesn't + match the one David modeled.) +

+

All sample rates.

+
    +
  • model

    + 0 - '59 Bassman
    + 1 - '69 Twin Reverb
    + 2 - '64 Princeton
    + 3 - '59/'81 JCM 800
    + 4 - '78 Club & Country
    + 5 - '59/'86 AC-30 of sorts +

  • +
  • bass
  • +
  • mid
  • +
  • treble
  • +
+ +

ToneStackLT

+

+ This version of David Yeh's ToneStack replaces + the procedural approach and direct form II filter + with a lattice filter and operation on + precalculated simulation data. It's a fixed implementation of the + '59 Bassman model. +

+

44.1 kHz

+
    +
  • bass
  • +
  • mid
  • +
  • treble
  • +
+ + +

AmpIII

+

+ A PreampIII circuit plus a tube power amplifier + emulation giving that smooth drive. +

+

+ We recommend you use AmpVTS instead. +

+

All sample rates.

+

+ Same controls as PreampIII, plus: +

+
    +
  • drive

    + controls the 'master volume' of the circuit, i.e. how much + coloring and compression the emulated power amplifier produces.

  • +
+ +

AmpIV

+

+ A PreampIV with the same output amp stage + emulation that AmpIII employs. Controls are the + same as on PreampIV, plus the 'drive' inherited + from AmpIII. +

+

+ We recommend you use AmpVTS instead. +

+

All sample rates.

+ +

AmpV

+

+ This circuit is loosely based on the AmpIII design. + The preamplifier stage has been augmented and tuned + to provide a warmer frequency response as well as slightly different + clipping characteristics. But more significantly, AmpV emulates the + shortcomings of an unregulated power supply and their effect on the + total gain of the circuit, the operating point of the tubes and the + clipping response. +

+ AmpV's forte is a mellow sound at the transition from clean to rough, + at lowish 'gain' settings and moderate 'watts'. +

+

+ We recommend you use AmpVTS instead. +

+

All sample rates.

+
    +
  • gain

    + controls the amount of edge added in the preamplifier stage. The + parameter mapping has been optimized for fine control in the clean to + medium-rough range. +

  • +
  • bass

    + controls the attenuation or amplification of low frequencies + before the preamp tube (the value is expressed in dB). + Technically, a low-shelving equalizer filter. +

  • +
  • tone

    + controls post-preamplifier circuit filtering. At the zero setting, + the effect is turned off. At its maximum, there is some resonance + quite high in the spectrum. +

  • +
  • drive

    + controls power-amplification stage saturation, which gives a fair bit + of warmth and some compression. +

  • +
  • watts

    + controls how capable the emulated power supply is. At its minimum + setting, the effects of supply voltage modulation are + the most pronounced. + At the maximum setting, they are effectively removed (which is + recommended for high-'gain' setups). +

  • +
+ +

AmpVTS

+

+ An AmpV with the tone controls replaced with + the fine ToneStack by David Yeh. And a ton of + other modifications (most notably the availability of an extra 28 dB + of gain). +

+

All sample rates.

+ + +

CabinetI

+ +

+ A collection of filters emulating the frequency response + of various guitar combo amps or speaker cabinets, using the + method outlined + here. +

+

+ You'll find a more exact, but also a lot more cycle-hungry and + latency-inflicting rendering of + these responses in + Steve Harris' collection, from which + they were borrowed. +

+

+ We recommend you use the successor unit CabinetII + instead. +

+

+ 44.1 kHz (48 kHz gives a slightly different, but still usable frequency response.) +

+
    +
  • model

    + 0 - identity filter (what goes in, goes out).
    + 1 - 'unmatched', as I still like to call it. A Matchless Chieftain.
    + 2 - the same, but the recording was taken with the microphone on-axis.
    + 3 - Superchamp (a Fender, isn't it?)
    + 4 - Fender Vibrolux 68
    + 5 - Marshall 'Plexi' +

  • +
  • gain (dB)

    + volume control.

  • +
+ +

CabinetII

+ +

+ A refined version of CabinetI. + This version offers a much more + faithful rendering of the original speaker cabinet frequency responses + due to a modified filter approximation, double the filter order and + (limited) adaptability to sample rate. +

+ Unlike conventional impulse response emulators who rely on brute-force + convolution, FFT-based algorithms or the patent-encumbered zero-latency + variant of the latter, the Cabinet units employ IIR filters for + truly resonant behaviour. As a result, their sound is more lively. +

+ Same controls as CabinetI. +

+

+ 44.1, 48, 88.2 and 96 kHz (nearest match chosen at runtime) +
+

+ +

Clip

+

+ A spin-off of the PreampIII effort. + 8x oversampled hard clipping (sometimes called 'diode' or + 'transistor' clipping). + The clip threshold is fixed at -1 dB (overshoot + from the up- and downsampling filters could exceed 0 dB were the threshold + higher). +

+

+ All sample rates. +

+
    +
  • gain (dB)

    + controls pre-clipping amplification.

  • +
+ +

Effects

+ +

ChorusI

+ +

+ Mono version, with a feedback circuit. The parameter range suits more + subtle effects as well as all-out flanging. Modifying the 't' parameter + when 'feedback' is non-zero will cause zipper noise. +

+

+ All sample rates. +

+
    +
  • t (ms)

    + delay time.

  • +
  • width (ms)

    + controls the amount of pitch change.

  • +
  • rate (Hz)

    + the speed of the pitch modulation.

  • +
  • blend

    + the amount of dry and fed-back signal in the output.

  • +
  • feedforward

    + amount of modulated signal in the output.

  • +
  • feedback

    + amount of signal with fixed delay in the modulation input.

  • +
+ +

StereoChorusI

+ +

+ Two ChorusI circuits in parallel, + sharing the same input (and delay + line). Same parameters as the mono version, plus one. +

+

+ All sample rates. +

+
    +
  • phase
  • + controls the relation of the two LFOs. 0 means in-phase, 0.5 is + quadrature, and 1 is anti-phase.

    + +
+ +

ChorusII

+ +

+ A variation on the ChorusI unit; this one employs + a Roessler fractal to steer the signal modulation, resulting in less + predictable and thus more interesting sound. +

+

+ All sample rates. +

+
    +
  • t (ms)

    + delay time.

  • +
  • width (ms)

    + controls the amount of pitch change.

  • +
  • rate

    + the speed of the pitch modulation.

  • +
  • blend

    + the amount of dry and fed-back signal in the output.

  • +
  • feedforward

    + amount of modulated signal in the output.

  • +
  • feedback

    + amount of signal with fixed delay in the modulation input.

  • +
+ +

StereoChorusII

+ +

+ Two ChorusII circuits in parallel, + sharing the same input (and delay + line). Same parameters as the mono version. +

+

+ All sample rates. +

+ +

PhaserI

+ +

+ Nothing out of the ordinary, just a phaser like I like to have them. + A phaser unit works by sweeping notches in the frequency response; this one + has six comb filters, for six notches. +

+

+ All sample rates. +

+
    +
  • rate (Hz)

    + controls the speed of the modulation.

  • +
  • depth

    + the strength of the effect.

  • +
  • spread

    + the distance of the notched frequency bands.

  • +
  • feedback

    + controls the amount of resonance.

  • +
+ +

PhaserII

+ +

+ A variation of the PhaserI circuit which relies + on a Lorenz fractal for the modulation source, improving hugely on + output sound variation. +

+

+ All sample rates. +

+
    +
  • rate

    + controls the speed of the modulation.

  • +
  • depth

    + the strength of the effect.

  • +
  • spread

    + the distance of the notched frequency bands.

  • +
  • feedback

    + controls the amount of resonance.

  • +
+ +

SweepVFI

+ +

+ A resonant filter whose cutoff frequency is swept by a + Lorenz fractal. With the default parameters + (moderate Q, cutoff around 800 Hz and band pass mode) + it makes a nice Wah effect if you lower the 'h' parameter by a fair amount. +

+

+ Another idea is to set it to very high Q and frequency in low pass mode + and filter some noise, for synthetic bird chirping (high h value) + or theremin-like sounds (low h, lower frequency). +

+

+ Please note that the most useful settings for the 'h' parameter + are very low, around 0.01 - 0.09. Unfortunately there's no way + to provide a default setting as low as this without compromising + the range of the control. +

+

+ And be careful, high Q resonance can peak at up to +18 dB. +

+

+ All sample rates (modulation rate and character are sample rate dependent). +

+
    +
  • f

    + cutoff frequency (band center for band pass filtering).

  • +
  • Q

    + filter resonance.

  • +
  • mode

    + 0 - low pass
    + 1 - band pass

  • +
  • depth:x
  • +
  • depth:y
  • +
  • depth:z

    + control how the modulation is mixed from the state of the attractor.

  • +
  • h

    + step size of the fractal.

  • +
+ +

SweepVFII

+ +

+ A variation on SweepVFI, + with the filter Q (bandwidth/resonance) + modulated by a second Lorenz fractal. +

+

+ Please note that the most useful settings for the 'h' parameter + are very low, around 0.01 - 0.09. Unfortunately there's no way + to provide a default setting as low as this without compromising + the range of the control. +

+

+ And be careful, high Q resonance can peak at up to +18 dB. +

+

+ All sample rates (modulation rate and character are sample rate dependent). +

+
    +
  • f

    + cutoff frequency (band center for band pass filtering).

  • +
  • Q

    + filter resonance.

  • +
  • mode

    + 0 - low pass
    + 1 - band pass

  • +
  • f:depth:x
  • +
  • f:depth:y
  • +
  • f:depth:z

    + control how the filter cutoff modulation is mixed + from the state of the attractor.

  • +
  • f:h

    + step size of the fractal modulating the cutoff.

  • +
  • Q:depth:x
  • +
  • Q:depth:y
  • +
  • Q:depth:z

    + control how the filter Q modulation is mixed + from the state of the attractor.

  • +
  • Q:h

    + step size of the fractal modulating filter Q.

  • +
+ +

AutoWah

+

+ The same resonant filter as used by the SweepVFI + and SweepVFII units, the difference being that + the filter is hard-wired for bandpass operation and + the band centre frequency is modulated by an envelope-following circuit. + In short, an effect commonly known and esteemed as an automatic wah, + or AutoWah. Probably most useful with instruments allowing fine control over + dynamics at all times. +

+

+ Be careful with the Q parameter, high resonance can peak at up to +18 dB. +

+

+ All sample rates (modulation rate and character may be sample rate dependent). +

+
    +
  • f

    + filter band centre frequency.

  • +
  • Q

    + resonance.

  • +
  • depth

    + strength of the modulation.

  • +
+ + +

Scape

+ +

+ This plugin will generate quite expansive soundscapes from even the + most modest input signals. +

+

+ Technically, 'Scape' is a + stereo delay, with the panning of the echo modulated by a pair of + fractals. + The delay times are adjustable through + a 'bpm' knob, augmented by a beat division parameter. + The input as well as the delayed signals are processed by a + collection of resonant filters, with frequency and cutoff modulated + in sync to the current tempo. +

+

+ All sample rates. +

+
    +
  • bpm

    + beats per minute.

  • +
  • divider

    + controls whether the groove is ternary or binary.

  • +
  • feedback

    + controls the length of the delay tail.

  • +
  • dry

    + the amount of dry signal mixed to the outputs.

  • +
  • blend

    + the amount of wet signal mixed to the outputs.

  • +
+ + + +

Generators

+ +

VCOs

+ +

+ An oscillator capable of producing the standard + triangle, sawtooth and square waveforms of analog fame, + and almost any conceivable blend + thereof. 8x oversampled, thus needs a lot of cycles. Sorry about that, + but you don't get the flexibility and fat sound for free. +

+

+ About the morphing controls: +

+
    +
  • For a triangle wave, set both tri .. saw and + ~ .. square to 0 (this is the default setting).
  • +
  • To morph into a sawtooth, pull up tri .. saw.
  • +
  • For a square wave instead, pull up ~ .. square. When + the value reaches 1, tri .. saw fully controls the pulse + width.
  • +
+

+ For a more intuitive approach, thinking of both controls + in terms of 'dull .. sharp' for a start + can't hurt. +

+

+ All sample rates. +

+
    +
  • f

    + the frequency.

  • +
  • tri .. saw

    + controls the morph between triangle and sawtooth, and the pulse + width of square oscillation.

  • +
  • ~ .. square

    + controls the morph between triangle/sawtooth and square wave.

  • +
  • volume
  • +
+ +

VCOd

+ +

+ A combination of two VCOs units. + The second oscillator + offers a separate tuning knob. It can also be made + to 'hard sync' + to the first unit, which means that when the first has completed + a wave cycle, the second is forced to restart its wave cycle + together with the first. +

+

+ All sample rates. +

+
    +
  • f

    + the frequency.

  • +
  • 1: tri .. saw
  • +
  • 1: ~ .. square

    + waveform morph controls for the first oscillator.

  • +
  • 2: tri .. saw
  • +
  • 2: ~ .. square

    + waveform morph controls for the second oscillator.

  • +
  • 2: tune

    + controls the interval between the two oscillator frequencies, in + units of (fractional) semitones.

  • +
  • sync

    + if non-zero, puts the second oscillator into 'hard sync' mode, and + determines the forced-restart offset into its wave cycle.

  • +
  • blend

    + controls how the waveforms from the two oscillators are mixed. + A value of 0 means only oscillator one is heard, a value of either + 1 or -1 tilts the balance fully towards oscillator two. The sign + of the blend value determines if the signals are added or + subtracted.

  • +
  • volume
  • +
+ +

CEO

+ +

+ The Chief Executive Oscillator forever repeats the word 'money'. +

+

+ 44.1 kHz. +

+
    +
  • mpm

    + moneys per minute.

  • +
  • volume
  • +
  • damping

    + moderates the CEO.

  • +
+ +

Sin

+ +

+ The old friend, indispensable for testing and tuning. +

+

+ All sample rates. +

+
    +
  • f

    + the frequency.

  • +
  • volume
  • +
+ +

White

+ +

+ White noise (actually slightly pinkish, sorry). +

+

+ All sample rates. +

+
    +
  • volume
  • +
+ +

Lorenz

+ +

+ A Lorenz attractor is a fractal system. It produces a very + own character of noisz that will hardly repeat in the course of your + lifetime. +

+

+ Sound varies with sample rate. +

+
    +
  • h

    + controls the step size of the state progression, and, indirectly, the + perceived frequency of the sound.

  • +
  • x
  • +
  • y
  • +
  • z

    + control how the signal is mixed from the state of the attractor.

  • +
  • volume
  • +
+

+ For more information on the + Lorenz and Roessler attractors, visit + Paul Bourke's resourceful site. +

+ +

Roessler

+ +

+ Another fractal system. This one lends itself + particularly well to sweeping the 'h' parameter. +

+

+ Sound varies with sample rate. +

+
    +
  • h

    + controls the step size of the state progression.

  • +
  • x
  • +
  • y
  • +
  • z

    + control how the signal is mixed from the state of the attractor.

  • +
  • volume
  • +
+

+ For more information on the + Lorenz and Roessler attractors, visit + Paul Bourke's resourceful site. +

+ +

Reverb

+ +

JVRev

+ +

+ A traditional Chowning/Moorer/Schroeder reverb. It sounds quite good + for a reverberation unit with such a comparatively small footprint + (I still remember the times when your average personal computer wasn't + even capable of computing this in realtime). A quite + straight-forward rewrite of a unit found in + CCRMA's + STK (Synthesis Toolkit), + with minor tweaks. +

+

+ All sample rates. +

+
    +
  • t60 (s)

    + controls the time until the reverb tail is supposed to fade + to -60 dB.

  • +
  • blend

    + controls dry/wet mixing ratio.

  • +
+ +

Plate

+ +

+ A reverberation unit based on the design discussed + in [1]. + Unlike the reference, the unit employs cubic instead of + allpass interpolation to modulate the reverb 'tank' delay lines. +

+

+ All sample rates. +

+
    +
  • bandwidth

    + controls damping of the input signal before it enters the + delay circuits.

  • +
  • tail

    + controls the length of the reverb tail.

  • +
  • damping

    + controls attenuation of high frequency components within the reverb 'tank' + (decay stage).

  • +
  • blend

    + dry/wet mixing ratio (default should be 1/8, not 1/4).

  • +
+ +

Plate2x2

+ +

+ By popular demand, a stereo-in, stereo-out version of the + Plate reverb unit. Same controls, same sound. +

+

+ All sample rates. +

+ +

Others

+ +

Click

+ +

+ A sample-accurate metronome. Timing is exact at any sample rate, but + the pitch of the click (being a recorded sample) will vary. (The click + also lends well for testing reverb plugins.) +

+

+ 44.1 kHz. +

+
    +
  • bpm

    + beats per minute.

  • +
  • volume
  • +
  • damping

    + controls the softness of the click sound.

  • +
+ +

Dirac

+ +

+ This plugin produces periodic impulses of exactly one sample width + (as long as the 'damping' control is left at the default 0 setting). + It's probably only useful for testing and basic impulse response + retrieval; don't use this plugin if you don't know what you're doing, + your amplification hardware and speakers will thank you. + The 'volume' control defaults to silent output to spare you nasty + surprises. +

+

+ All sample rates. +

+
    +
  • ppm

    + pulses per minute.

  • +
  • volume
  • +
  • damping
  • +
+ +

HRTF

+ +

+ Applying the head-related transfer function to a signal makes it appear + to come from a specific direction in space. This plugin applies the + HRTF with custom-shaped IIR filters. + Tell me how it works for you (you should + have pretty good headphones to get the full effect). +

+

+ The HRTF impulse response data has been collected and prepared + by MIT's Media Lab. +

+

+ This unit only utilizes the 0-elevation set (sound source is level + with the listener). +

+

+ 44.1 kHz. +

+
    +
  • pan

    + The position, in integer steps. Some noteworthy settings: +

      +
    • + 0 = in front
    • +
    • +18 = left,
    • +
    • -18 = right, and
    • +
    • -36 = +36 = behind the listener.
    • +
    +
  • +
+ +  
+ +

Appendix

+ +

Plugin Data Sheets

+ +

+ The CAPS data sheets collect the following information from + the plugins: +

+
    +
  • the plugin ID
  • +
  • normalized sample output from the plugin + with default parameter settings + (in the filter case, this is an impulse response)
  • +
  • a frequency magnitude plot for the sample output
  • +
  • estimated CPU usage on my box (usually wildly inaccurate)
  • +
  • latency information if applicable
  • +
  • audio routing information
  • +
  • the control inputs on the plugin
  • +
+

+ You can fetch the data sheet compilation + here, it is caps-0.4.5.pdf (287 kB). +

+ +

Changelog

+ +
+0.4.5
+  * Narrower plugin added
+  * fixed 'configure.py' to work with python3
+  * fixed Sin, Roessler and Lorenz gain smoothing on activation
+
+0.4.4
+  
+0.4.3
+  * basics.h cleanup / comments
+  * minor Makefile cleanup
+  * comment cosmetics
+  * Eq and Eq2x2 per-band Q changed to 1.414 (= 1 octave)
+  * Eq lowest band default value fixed to read 0
+  * Niclas' fix for the bessel function implemented
+  * uninitialised plugin states eliminated thanks to Damon
+  * linker options for OSX added to the Makefile
+
+0.4.2
+  * fixed the 'model' port index for AmpVTS in the RDF generator
+
+0.4.1
+  * cleaned up Eq.h and Eq.cc (many g++ versions choke on the unused code
+    there)
+  * changed -O3 to -O2 in the g++ invocation
+
+0.4.0
+  * ToneStack plugins, by David Yeh
+  * AmpV + Tone stack plugin, employing David Yeh's fine work
+  * comment cosmetics
+  * Amp* denormal protection fixed (or is it, Dave? ;)
+  * minor code cleanup in Amp.cc
+  * caps.rdf updated with plugin categories (thanks to Paul Winkler)
+  * caps.rdf Cabinet* RDF preset labels renamed
+  * AutoWah plugin
+  * DSP::RMS reworked, may affect Compress plugin
+  * DSP::Eq reworked for double precision and denormal protection
+  * ./configure.py checks SSE availability
+  * in case of SSE math denormal flush to zero activated for all plugins
+  * all plugins renamed C* .. instead of CAPS: ..
+  * Eq modified to play nice with ardour 
+  * Eq2x2
+  * introduced the Plugin base class, collecting common traits (normal etc)
+  * getport() -- read access to control ports which is clamped to port bounds
+    and maps inf and nan to 0 as well
+  * all LADSPA_HINT_SAMPLE_RATE ports changed to *_LOGARITHMIC because
+    of broken implementations (no surprise given the vagueness of ladspa.h
+    regarding this matter) -- this means changed default parameters of the 
+    affected ports, too
+  * VCO* "latency" output ports removed
+  * actual activate() call is deferred to first run() after activate() 
+    in order to prevent inadvertent parameter smoothing sweeps during the first 
+    block  of audio after activation, this should fix all problems with ardour
+    (except those caused by denormals or invalid audio input)
+  * caps.rdf installed by 'make install'
+  * fixed a bug in tools/make-ps.py that caused the spectrum plots to 
+    be inaccurate for multi-channel plugins
+
+0.3.0
+  * TwelveAX7_3 changed to clip slightly early in the upper lobe
+  * Scape plugin added
+  * plugin names rewritten, prefixed with "CAPS:"
+  * new ChorusII, StereoChorusII plugins
+  * Chorus, StereoChorus relabeled, appended 'I' suffix
+  * new PhaserII plugin (great stuff if I may say so)
+  * Phaser relabeled, appended 'I' suffix
+  * new AmpV plugin, based on AmpIII, emulates compression and distortion
+    modulation through power supply shortcomings, plus lots of fine-tuning
+    and an additional biquad. We're getting there!
+  * all Preamp and Amp models fitted with a new 12AX7 model, linear
+    interpolation of a sample table obtained from spice simulation
+
+0.2.4
+  * feedback default reverted to 0 for the Chorus units
+  * fixed Cabinet to switch to correct gain at 'model' control change
+  * fixed 'model' control in Cabinet to work with a broader range of hosts
+  * Cabinet name changed to CabinetI
+  * CabinetII plugin: Cabinet with 32nd order IIR filters, more fidelity
+    to the original frequency responses, supplied coefficients for 4 of the
+    most used sample rates
+  * applied the gcc-4 enabling patch
+  * SweepVF renamed to SweepVFI
+  * new SweepVFII plugin, variant of SweepVFI with Q modulated by a 
+    second Lorenz fractal
+  * dsp/exp2 dumped in favour of libm's exp2(3)
+
+0.2.3
+  * StereoChorus denormal protection made functional 
+    (Thanks again to S. Savolainen)
+  * Phaser denormal protected
+  
+0.2.2
+  * Build was _not_ fixed for g++-4.0.
+  * AmpIV gain control restored to operate as expected
+  * Chorus/StereoChorus denormal protection (thanks to S. Savolainen)
+  * a few cosmetic changes elsewhere
+  
+0.2.1
+  * Build fixed for g++-4.0, PPC and AMD64 
+    (Thanks to Niklas Werner, Andreas Jochens and Mario Lang)
+  * Reverb.* cosmetics
+  * AmpIV tone controls moved to after initial tube transfer
+
+0.2.0
+  * denormal protection for Preamp*, Amp*
+  * Capitalized plugin Names
+  * PDF now lists audio in- and outputs as well as control inputs, only
+    gives average CPU rating
+  * AmpIV: PreampIV + power amp stage
+  * Plate2x2: Plate with 2-in, 2-out audio routing
+  * Plate damping and bandwidth controls changed to map to filter fc, fixes
+    behaviour in hosts that handle the log hint incorrectly
+
+0.1.13
+  * AmpIII activate() resets the boost filter
+
+0.1.12
+  * PreampIV band controls fixed to operate as expected
+
+0.1.11
+  * amps changed back to old tube model :) but new temp & gain behaviour stays
+  * SweepVF, AmpIII default value adjustments
+
+0.1.10
+  * HRTF recursion runs in doubles
+  * Cabinet recursion runs in doubles for much clearer sound
+  * all amps fitted with a common tube voltage mapping, dsp/TwelveAX7.h
+  * all amps: temperature and gain controls changed slightly
+  * all amps declared in one common Amp.h
+  * Pan echo fixed to be filtered independent of sample rate
+  * Cabinet cosmetics and activate() from port values fix
+  * SweepVF fixed to activate() from the current control settings
+  * rid all *amp* plugins of the initial hi-pass, not needed anymore
+  * PreampIII and AmpIII more authentic with an rbj lo-shelve, +6 dB > 1.2 kHz
+    as hinted by circuit analysis
+  * something_random() removed, stdlib for random generation
+
+0.1.9
+  * Pan plugin
+  * 'make depend' instead of 'make dep', uses $(CC) -MM instead of 'makedepend'
+  * *Chorus, AmpIII, Plate defaults changed
+  * *Chorus optimizations, reintroduces funny zipper noise when 'feedback' is
+    non-zero and 't' is changed
+  * experimental HRTF plugin
+  * Plate 'blend' goes all the way to wet output only
+  * dsp/White offers a get_31() method for reduced number of bitshifts needed
+  * *Chorus delay line tapping changed to employ cubic interpolation, sounds
+    better
+  * SweepVF modulation mix algorithm changed to clamp if over-fed, makes
+    for wider sweeps
+  
+0.1.8
+  * all oversampling plugins use Kaiser windows instead of Blackman-Harris,
+    for much better performance
+  * SweepVF modulation range slightly increased
+  * Cabinet filter loop cosmetics (slight speedup)
+  * new AmpIII Plugin: Preamp plus power amp emulation
+  * lowered NOISE_FLOOR (equals 'renormal' number)
+  
+0.1.7
+  * connect ports to lower bound on instantiate()
+  * Plate delay line lengths raised, sound changed
+  * Eq activate() fixed to initialize from the current settings
+  * Preamp* cutoff reverted to 0.1.3 setting, thanks to Ben Saylor for
+    testing
+  * old IIR-based Preamp cleaned from the sources
+  * zipper-noise in *Chorus units for t changes with feedback > 0 eliminated
+  * all plugin constructor code moved to init() calls
+
+0.1.6
+  * SweepVF modulation mix algorithm changed to maintain proportion, not
+    absolute value if x + y + z > 1, for better control
+  * create $(DEST) directory on make install, pointed out by Daniel James
+
+0.1.5
+  * fixed delay line length miscalculation in ModLattice
+
+0.1.4
+  * SweepVF modulation source can be mixed now
+  * latency port for VCO*
+  * Lorenz and Roessler get x, y, z mixing knobs
+  * PreampIV eq bands slightly tuned and coefficients moved into common struct
+  * Preamp*, VCO* downsampler filter cutoff lowered
+  * Clip downsampler filter cutoff lowered 
+  * nonsensical audio output bounds removed
+  * simplified VCO* implementation
+  * JVRev rewritten for code clarity (funny enough, it also got quicker)
+  * fixed JVRev to reset its history on activate()
+  * added purpose, copyright and licensing information to all (i think) files.
+  * HACKING file
+  * CHANGES file
+  
+0.1.3
+  * fixed all compilation problems with gcc 3.3, with the patient help
+    of the lad mailing list community
+  * dsp/Eq.h SSE assembler code had to go (gcc > 3 doesn't like multi-line 
+    asm, and efficiency and even reliability go down if we allow gcc to 
+    intersperse its 'optimization' code with our asm)
+  
+0.1.2
+  * fixed more compilation problems with gcc >= 3.0
+  
+0.1.1
+  * tried to (but didn't really) fix compilation problem with ladspa.h
+  
+0.1.0
+  * initial release
+	
+ + + +
+  
+ +
+ tim@quitte.de, March 26 2011. +
+ + diff --git a/plugins/ladspa_effect/caps/caps.rdf b/plugins/ladspa_effect/caps/caps.rdf new file mode 100644 index 000000000..dbcfcc566 --- /dev/null +++ b/plugins/ladspa_effect/caps/caps.rdf @@ -0,0 +1,447 @@ + + + + + + + ] +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/ladspa_effect/caps/configure.py b/plugins/ladspa_effect/caps/configure.py new file mode 100755 index 000000000..227a1328f --- /dev/null +++ b/plugins/ladspa_effect/caps/configure.py @@ -0,0 +1,30 @@ +#! /usr/bin/env python +import os + +CFLAGS = [] +OSX_LDFLAGS = "-bundle -undefined suppress -flat_namespace" + +def we_have_sse(): + try: return 'sse' in open ('/proc/cpuinfo').read().split() + except: return 0 +def we_have_ssse3(): + try: return 'ssse3' in open ('/proc/cpuinfo').read().split() + except: return 0 + +def we_think_so_different_dude(): + try: return 'Darwin' == os.popen ('uname -s').read().strip() + except: return 0 + +def store(): + f = open ('defines.make', 'w') + f.write ("_CFLAGS=" + ' '.join (CFLAGS) + "\n") + if we_think_so_different_dude(): + f.write ("_LDFLAGS=" + OSX_LDFLAGS + "\n") + f.write ("STRIP = echo\n") + +if __name__ == '__main__': + if we_have_sse(): + CFLAGS += ('-msse', '-mfpmath=sse') + if we_have_ssse3(): + CFLAGS += ('-msse3',) + store() diff --git a/plugins/ladspa_effect/caps/dsp/BiQuad.h b/plugins/ladspa_effect/caps/dsp/BiQuad.h index a0a7fb065..c56272022 100644 --- a/plugins/ladspa_effect/caps/dsp/BiQuad.h +++ b/plugins/ladspa_effect/caps/dsp/BiQuad.h @@ -34,21 +34,24 @@ class BiQuad { public: /* coefficients */ - d_sample a[3], b[3]; + sample_t a[3], b[3]; /* history */ int h; - d_sample x[2], y[2]; + sample_t x[2], y[2]; BiQuad() { - /* initialize to unity */ - a[0] = 1; - a[1] = a[2] = b[0] = b[1] = b[2] = 0; - + unity(); reset(); } + void unity() + { + a[0] = 1; + a[1] = a[2] = b[0] = b[1] = b[2] = 0; + } + void copy (BiQuad & bq) { for (int i = 0; i < 3; ++i) @@ -72,11 +75,11 @@ class BiQuad y[i] = 0; } - inline d_sample process (d_sample s) + inline sample_t process (sample_t s) { register int z = h; - register d_sample r = s * a[0]; + register sample_t r = s * a[0]; r += a[1] * x[z]; r += b[1] * y[z]; @@ -96,11 +99,11 @@ class BiQuad /* Following are additional methods for using the biquad to filter an * upsampled signal with 0 padding -- some terms reduce to 0 in this * case */ - inline d_sample process_0_1() + inline sample_t process_0_1() { register int z = h; - register d_sample r = 0; + register sample_t r = 0; r += a[1] * x[z]; r += b[1] * y[z]; @@ -117,11 +120,11 @@ class BiQuad return r; } - inline d_sample process_0_2() + inline sample_t process_0_2() { register int z = h; - register d_sample r = 0; + register sample_t r = 0; r += b[1] * y[z]; @@ -137,11 +140,11 @@ class BiQuad return r; } - inline d_sample process_0_3() + inline sample_t process_0_3() { register int z = h; - register d_sample r = 0; + register sample_t r = 0; r += b[1] * y[z]; diff --git a/plugins/ladspa_effect/caps/dsp/Delay.h b/plugins/ladspa_effect/caps/dsp/Delay.h index 3703e7f03..a9aa517ec 100644 --- a/plugins/ladspa_effect/caps/dsp/Delay.h +++ b/plugins/ladspa_effect/caps/dsp/Delay.h @@ -1,11 +1,11 @@ /* dsp/Delay.h - Copyright 2003-4 Tim Goetze + Copyright 2003-4, 2010 Tim Goetze http://quitte.de/dsp/ - delay lines with fractional (linear or cubica interpolation) lookup + delay lines with fractional (linear or cubic interpolation) lookup and an allpass interpolating tap (which needs more work). delay line storage is aligned to powers of two for simplified wrapping @@ -41,7 +41,7 @@ class Delay { public: int size; - d_sample * data; + sample_t * data; int read, write; Delay() @@ -58,46 +58,46 @@ class Delay void init (int n) { size = next_power_of_2 (n); - data = (d_sample *) calloc (sizeof (d_sample), size); + data = (sample_t *) calloc (sizeof (sample_t), size); size -= 1; write = n; } void reset() { - memset (data, 0, (size + 1) * sizeof (d_sample)); + memset (data, 0, (size + 1) * sizeof (sample_t)); } - d_sample & + sample_t & operator [] (int i) { return data [(write - i) & size]; } inline void - put (d_sample x) + put (sample_t x) { data [write] = x; write = (write + 1) & size; } - inline d_sample + inline sample_t get() { - d_sample x = data [read]; + sample_t x = data [read]; read = (read + 1) & size; return x; } - inline d_sample - putget (d_sample x) + inline sample_t + putget (sample_t x) { put (x); return get(); } /* fractional lookup, linear interpolation */ - inline d_sample + inline sample_t get_at (float f) { int n; @@ -108,24 +108,24 @@ class Delay } /* fractional lookup, cubic interpolation */ - inline d_sample + inline sample_t get_cubic (float f) { int n; fistp (f, n); /* see FPTruncateMode */ f -= n; - d_sample x_1 = (*this) [n - 1]; - d_sample x0 = (*this) [n]; - d_sample x1 = (*this) [n + 1]; - d_sample x2 = (*this) [n + 2]; + sample_t x_1 = (*this) [n - 1]; + sample_t x0 = (*this) [n]; + sample_t x1 = (*this) [n + 1]; + sample_t x2 = (*this) [n + 2]; - /* d_sample (32bit) quicker than double here */ - register d_sample a = + /* sample_t (32bit) quicker than double here */ + register sample_t a = (3 * (x0 - x1) - x_1 + x2) * .5; - register d_sample b = + register sample_t b = 2 * x1 + x_1 - (5 * x0 + x2) * .5; - register d_sample c = + register sample_t c = (x1 - x_1) * .5; return x0 + (((a * f) + b) * f + c) * f; @@ -137,7 +137,7 @@ class Delay class DelayTapA { public: - d_sample x1, y1; + sample_t x1, y1; DelayTapA() { @@ -149,16 +149,16 @@ class DelayTapA x1 = y1 = 0; } - d_sample get (Delay & d, float f) + sample_t get (Delay & d, float f) { int n; - fistp (f, n); /* read: i = (int) f; relies on FPTruncateMode */ + fistp (f, n); /* read: n = (int) f; relies on FPTruncateMode */ f -= n; if (0 && f < .5) f += 1, n -= 1; - d_sample x = d[n]; + sample_t x = d[n]; f = (1 - f) / (1 + f); y1 = x1 + f * x - f * y1; x1 = x; diff --git a/plugins/ladspa_effect/caps/dsp/FIR.h b/plugins/ladspa_effect/caps/dsp/FIR.h index 5c07e7cdf..8cb69ef0f 100644 --- a/plugins/ladspa_effect/caps/dsp/FIR.h +++ b/plugins/ladspa_effect/caps/dsp/FIR.h @@ -1,7 +1,7 @@ /* dsp/FIR.h - Copyright 2003-4 Tim Goetze + Copyright 2003-10 Tim Goetze http://quitte.de/dsp/ @@ -32,9 +32,9 @@ namespace DSP { -/* brute-force FIR filter with downsampling method. +/* brute-force FIR filter with downsampling method (decimating). * - * CAVEAT: constructing it from another FIR makes the filter use that very + * CAVEAT: constructing it from another FIR makes the filter share the other's * kernel data set. IOW, the other FIR must be valid throughout the lifetime * of this instance. */ @@ -45,7 +45,7 @@ class FIR int n, m; /* coefficients, history */ - d_sample * c, * x; + sample_t * c, * x; bool borrowed_kernel; /* history index */ @@ -63,7 +63,7 @@ class FIR init (fir.n); } - FIR (int n, d_sample * kernel) + FIR (int n, sample_t * kernel) { c = 0; init (n); @@ -82,18 +82,16 @@ class FIR n = N; /* keeping history size a power of 2 makes it possible to wrap the - * history pointer by binary & instead of %, saving huge amounts of - * cpu cycles. - */ + * history pointer by & instead of %, saving a few cpu cycles. */ m = next_power_of_2 (n); if (c) borrowed_kernel = true; else borrowed_kernel = false, - c = (d_sample *) malloc (n * sizeof (d_sample)); + c = (sample_t *) malloc (n * sizeof (sample_t)); - x = (d_sample *) malloc (m * sizeof (d_sample)); + x = (sample_t *) malloc (m * sizeof (sample_t)); m -= 1; @@ -103,11 +101,11 @@ class FIR void reset() { h = 0; - memset (x, 0, n * sizeof (d_sample)); + memset (x, 0, n * sizeof (sample_t)); } /* TODO: write an SSE-enabled version */ - inline d_sample process (d_sample s) + inline sample_t process (sample_t s) { x[h] = s; @@ -126,7 +124,7 @@ class FIR * a FIRUpsampler instead. */ template - inline d_sample upsample (d_sample s) + inline sample_t upsample (sample_t s) { x[h] = s; @@ -144,7 +142,7 @@ class FIR } /* used in downsampling */ - inline void store (d_sample s) + inline void store (sample_t s) { x[h] = s; h = (h + 1) & m; @@ -169,7 +167,7 @@ class FIRUpsampler int over; /* coefficients, history */ - d_sample * c, * x; + sample_t * c, * x; /* history index */ int h; @@ -184,7 +182,7 @@ class FIRUpsampler { c = x = 0; init (fir.n, _over); - memcpy (c, fir.c, n * sizeof (d_sample)); + memcpy (c, fir.c, n * sizeof (sample_t)); } ~FIRUpsampler() @@ -206,8 +204,8 @@ class FIRUpsampler */ m = next_power_of_2 ((n + over - 1) / over); - c = (d_sample *) malloc (n * sizeof (d_sample)); - x = (d_sample *) malloc (m * sizeof (d_sample)); + c = (sample_t *) malloc (n * sizeof (sample_t)); + x = (sample_t *) malloc (m * sizeof (sample_t)); m -= 1; @@ -217,11 +215,11 @@ class FIRUpsampler void reset() { h = 0; - memset (x, 0, (m + 1) * sizeof (d_sample)); + memset (x, 0, (m + 1) * sizeof (sample_t)); } /* upsample the given sample */ - inline d_sample upsample (d_sample s) + inline sample_t upsample (sample_t s) { x[h] = s; @@ -236,11 +234,10 @@ class FIRUpsampler } /* upsample a zero sample (interleaving), Z being the time, in samples, - * since the last non-0 sample. - */ - inline d_sample pad (int Z) + * since the last non-0 sample. */ + inline sample_t pad (int Z) { - d_sample s = 0; + sample_t s = 0; for (int z = h - 1; Z < n; --z, Z += over) s += c[Z] * x[z & m]; diff --git a/plugins/ladspa_effect/caps/dsp/LatFilt.h b/plugins/ladspa_effect/caps/dsp/LatFilt.h index a304959fe..0ba4d0999 100644 --- a/plugins/ladspa_effect/caps/dsp/LatFilt.h +++ b/plugins/ladspa_effect/caps/dsp/LatFilt.h @@ -70,7 +70,7 @@ class LatFilt vcoef[ORDER] = 0; } - d_sample process (d_sample s) { + sample_t process (sample_t s) { double tmp; int i = ORDER-1; @@ -85,7 +85,7 @@ class LatFilt state[0] = tmp; y = y + vcoef[0]*tmp; - return (d_sample) y; + return (sample_t) y; } inline void set_vi(double coef, int i) { diff --git a/plugins/ladspa_effect/caps/dsp/Lorenz.h b/plugins/ladspa_effect/caps/dsp/Lorenz.h index 19e512631..bb57a7cc3 100644 --- a/plugins/ladspa_effect/caps/dsp/Lorenz.h +++ b/plugins/ladspa_effect/caps/dsp/Lorenz.h @@ -70,7 +70,7 @@ class Lorenz h = _h; } - d_sample get() + sample_t get() { step(); return .5 * get_y() + get_z(); diff --git a/plugins/ladspa_effect/caps/dsp/OnePole.h b/plugins/ladspa_effect/caps/dsp/OnePole.h index fe6dd9c8a..9a3178053 100644 --- a/plugins/ladspa_effect/caps/dsp/OnePole.h +++ b/plugins/ladspa_effect/caps/dsp/OnePole.h @@ -33,7 +33,7 @@ namespace DSP { class OnePoleLP { public: - d_sample a0, b1, y1; + sample_t a0, b1, y1; OnePoleLP (double d = 1.) { @@ -53,11 +53,11 @@ class OnePoleLP inline void set (double d) { - a0 = (d_sample) d; - b1 = (d_sample) 1. - d; + a0 = (sample_t) d; + b1 = (sample_t) 1. - d; } - inline d_sample process (d_sample x) + inline sample_t process (sample_t x) { return y1 = a0 * x + b1 * y1; } @@ -79,7 +79,7 @@ class OnePoleLP class OnePoleHP { public: - d_sample a0, a1, b1, x1, y1; + sample_t a0, a1, b1, x1, y1; OnePoleHP (double d = 1.) { @@ -94,12 +94,12 @@ class OnePoleHP inline void set (double d) { - a0 = (d_sample) ((1. + d) / 2.); - a1 = (d_sample) ((1. + d) / -2.); + a0 = (sample_t) ((1. + d) / 2.); + a1 = (sample_t) ((1. + d) / -2.); b1 = d; } - inline d_sample process (d_sample x) + inline sample_t process (sample_t x) { y1 = a0 * x + a1 * x1 + b1 * y1; x1 = x; diff --git a/plugins/ladspa_effect/caps/dsp/RBJ.h b/plugins/ladspa_effect/caps/dsp/RBJ.h index 229b7f092..0a1db6b39 100644 --- a/plugins/ladspa_effect/caps/dsp/RBJ.h +++ b/plugins/ladspa_effect/caps/dsp/RBJ.h @@ -1,7 +1,9 @@ /* dsp/RBJ.h - Copyright 2004 Tim Goetze , 1998 Robert Bristow-Johnson + Copyright + 1998 Robert Bristow-Johnson + 2004-10 Tim Goetze biquad prototypes according to the eq cookbook. easy-to-use, nice, predictable filters. thanks rbj! @@ -26,6 +28,8 @@ #ifndef _DSP_RBJ_H_ #define _DSP_RBJ_H_ +#include "BiQuad.h" + namespace DSP { namespace RBJ { @@ -33,12 +37,14 @@ namespace RBJ { class RBJ { public: - double alpha, sin, cos; + double Q, alpha, sin, cos; double a[3], b[3]; public: - RBJ (double f, double Q) + RBJ (double f, double _Q) { + Q = _Q; + double w = 2 * M_PI * f; sin = ::sin (w); @@ -74,9 +80,15 @@ class LP : public RBJ { public: + LP (double f, double Q, BiQuad & bq) : RBJ (f, Q) + { ab (bq.a, bq.b); } + template - LP (double f, double Q, T * ca, T * cb) - : RBJ (f, Q) + LP (double f, double Q, T * ca, T * cb) : RBJ (f, Q) + { ab (ca, cb); } + + template + void ab (T * ca, T * cb) { b[0] = (1 - cos) * .5; b[1] = (1 - cos); @@ -94,9 +106,15 @@ class BP : public RBJ { public: + BP (double f, double Q, BiQuad & bq) : RBJ (f, Q) + { ab (bq.a, bq.b); } + template - BP (double f, double Q, T * ca, T * cb) - : RBJ (f, Q) + BP (double f, double Q, T * ca, T * cb) : RBJ (f, Q) + { ab (ca, cb); } + + template + void ab (T * ca, T * cb) { b[0] = Q * alpha; b[1] = 0; @@ -114,9 +132,15 @@ class HP : public RBJ { public: + HP (double f, double Q, BiQuad & bq) : RBJ (f, Q) + { ab (bq.a, bq.b); } + template - HP (double f, double Q, T * ca, T * cb) - : RBJ (f, Q) + HP (double f, double Q, T * ca, T * cb) : RBJ (f, Q) + { ab (ca, cb); } + + template + void ab (T * ca, T * cb) { b[0] = (1 + cos) * .5; b[1] = -(1 + cos); @@ -134,9 +158,15 @@ class Notch : public RBJ { public: + Notch (double f, double Q, BiQuad & bq) : RBJ (f, Q) + { ab (bq.a, bq.b); } + template - Notch (double f, double Q, T * ca, T * cb) - : RBJ (f, Q) + Notch (double f, double Q, T * ca, T * cb) : RBJ (f, Q) + { ab (ca, cb); } + + template + void ab (T * ca, T * cb) { b[0] = 1; b[1] = -2 * cos; @@ -150,7 +180,7 @@ class Notch } }; -/* shelving and peaking dept. */ +/* shelving and peaking dept. ////////////////////////////////////////////// */ class PeakShelve : public RBJ @@ -172,9 +202,17 @@ class LoShelve : public PeakShelve { public: + LoShelve (double f, double Q, double dB, BiQuad & bq) + : PeakShelve (f, Q, dB) + { ab (bq.a, bq.b); } + template LoShelve (double f, double Q, double dB, T * ca, T * cb) : PeakShelve (f, Q, dB) + { ab (ca, cb); } + + template + void ab (T * ca, T * cb) { double Ap1 = A + 1, Am1 = A - 1; double beta_sin = beta * sin; @@ -195,9 +233,17 @@ class PeakingEQ : public PeakShelve { public: + PeakingEQ (double f, double Q, double dB, BiQuad & bq) + : PeakShelve (f, Q, dB) + { ab (bq.a, bq.b); } + template PeakingEQ (double f, double Q, double dB, T * ca, T * cb) : PeakShelve (f, Q, dB) + { ab (ca, cb); } + + template + void ab (T * ca, T * cb) { b[0] = 1 + alpha * A; b[1] = -2 * cos; @@ -215,9 +261,17 @@ class HiShelve : public PeakShelve { public: + HiShelve (double f, double Q, double dB, BiQuad & bq) + : PeakShelve (f, Q, dB) + { ab (bq.a, bq.b); } + template HiShelve (double f, double Q, double dB, T * ca, T * cb) : PeakShelve (f, Q, dB) + { ab (ca, cb); } + + template + void ab (T * ca, T * cb) { double Ap1 = A + 1, Am1 = A - 1; double beta_sin = beta * sin; diff --git a/plugins/ladspa_effect/caps/dsp/RMS.h b/plugins/ladspa_effect/caps/dsp/RMS.h index 920ac507e..3b7806729 100644 --- a/plugins/ladspa_effect/caps/dsp/RMS.h +++ b/plugins/ladspa_effect/caps/dsp/RMS.h @@ -33,7 +33,7 @@ namespace DSP { class RMS { protected: - d_sample buffer[64]; + sample_t buffer[64]; int write; public: @@ -52,20 +52,20 @@ class RMS } /* caution: pass in the *squared* sample value */ - void store (d_sample x) + void store (sample_t x) { sum -= buffer[write]; sum += (buffer[write] = x); write = (write + 1) & 63; } - d_sample process (d_sample x) + sample_t process (sample_t x) { store (x); return rms(); } - d_sample rms() + sample_t rms() { /* fabs it before sqrt, just in case ... */ return sqrt (fabs (sum) / 64); diff --git a/plugins/ladspa_effect/caps/dsp/Roessler.h b/plugins/ladspa_effect/caps/dsp/Roessler.h index 6da5cfe78..e4ec86303 100644 --- a/plugins/ladspa_effect/caps/dsp/Roessler.h +++ b/plugins/ladspa_effect/caps/dsp/Roessler.h @@ -66,7 +66,7 @@ class Roessler get(); } - d_sample get() + sample_t get() { int J = I ^ 1; diff --git a/plugins/ladspa_effect/caps/dsp/SVF.h b/plugins/ladspa_effect/caps/dsp/SVF.h index 56327a731..ccd5734ab 100644 --- a/plugins/ladspa_effect/caps/dsp/SVF.h +++ b/plugins/ladspa_effect/caps/dsp/SVF.h @@ -80,11 +80,11 @@ class SVF { protected: /* loop parameters */ - d_sample f, q, qnorm; + sample_t f, q, qnorm; /* outputs (peak and notch left out) */ - d_sample lo, band, hi; - d_sample * out; + sample_t lo, band, hi; + sample_t * out; public: /* the type of filtering to do. */ @@ -125,13 +125,13 @@ class SVF out = &hi; } - void one_cycle (d_sample * s, int frames) + void one_cycle (sample_t * s, int frames) { for (int i = 0; i < frames; ++i) s[i] = process (s[i]); } - d_sample process (d_sample x) + sample_t process (sample_t x) { x = qnorm * x; @@ -176,7 +176,7 @@ class StackedSVF svf[i].set_f_Q (f, Q); } - d_sample process (d_sample x) + sample_t process (sample_t x) { for (int i = 0; i < STACKED; ++i) x = svf[i].process (x); diff --git a/plugins/ladspa_effect/caps/dsp/Sine.h b/plugins/ladspa_effect/caps/dsp/Sine.h index fd3336ab8..a54c66161 100644 --- a/plugins/ladspa_effect/caps/dsp/Sine.h +++ b/plugins/ladspa_effect/caps/dsp/Sine.h @@ -34,8 +34,8 @@ class Sine { protected: int z; - d_float y[2]; - d_float b; + double y[2]; + double b; public: Sine() diff --git a/plugins/ladspa_effect/caps/dsp/TDFII.h b/plugins/ladspa_effect/caps/dsp/TDFII.h index 3212ee4a2..0252bc47a 100644 --- a/plugins/ladspa_effect/caps/dsp/TDFII.h +++ b/plugins/ladspa_effect/caps/dsp/TDFII.h @@ -62,7 +62,7 @@ class TDFII /* per-band recursion: * y = 2 * (a * (x - x[-2]) + c * y[-1] - b * y[-2]) */ - d_sample process (d_sample s) + sample_t process (sample_t s) { double y = h[0] + b[0] * s; @@ -71,7 +71,7 @@ class TDFII h[Order - 1] = b[Order] * s - a[Order] * y; - return (d_sample) y; + return (sample_t) y; } }; diff --git a/plugins/ladspa_effect/caps/dsp/ToneStack.h b/plugins/ladspa_effect/caps/dsp/ToneStack.h index d406073c4..6fea203f7 100644 --- a/plugins/ladspa_effect/caps/dsp/ToneStack.h +++ b/plugins/ladspa_effect/caps/dsp/ToneStack.h @@ -92,13 +92,13 @@ class ToneStack c = 2 * _fs; } - void activate (d_sample ** ports) + void activate (sample_t ** ports) { filter.reset(); } /* pass in pointer to ports and relative index of first eq band control */ - void start_cycle (d_sample ** ports, int bassindex = 1) + void start_cycle (sample_t ** ports, int bassindex = 1) { int m = clamp ((int) *ports[0], 0, n_presets - 1); if (m != model) @@ -151,7 +151,7 @@ class ToneStack filter.reset(); } - inline void updatecoefs (d_sample ** ports) + inline void updatecoefs (sample_t ** ports) { /* range checks on input */ double b = clamp (*ports[0], 0, 1); @@ -185,7 +185,7 @@ class ToneStack } // actualy do the DFII filtering, one sample at a time - inline d_sample process (d_sample x) + inline sample_t process (sample_t x) { return filter.process (x); } @@ -224,7 +224,7 @@ class ToneStackLT void init (double _fs) { } - void activate (d_sample ** ports) + void activate (sample_t ** ports) { filter.reset(); } @@ -237,7 +237,7 @@ class ToneStackLT bp = blah; } - void updatecoefs (d_sample ** ports) + void updatecoefs (sample_t ** ports) { double b = min (Steps - 1, max (*ports[0] * (Steps - 1), 0)); double m = min (Steps - 1, max (*ports[1] * (Steps - 1), 0)); @@ -258,7 +258,7 @@ class ToneStackLT } // actualy do the DFII filtering, one sample at a time - inline d_sample process (d_sample x) + inline sample_t process (sample_t x) { return filter.process (x); } diff --git a/plugins/ladspa_effect/caps/dsp/TwelveAX7.h b/plugins/ladspa_effect/caps/dsp/TwelveAX7.h index fbd3bd1c7..a4e9d7e7f 100644 --- a/plugins/ladspa_effect/caps/dsp/TwelveAX7.h +++ b/plugins/ladspa_effect/caps/dsp/TwelveAX7.h @@ -31,7 +31,7 @@ namespace DSP { #include "r12ax7.h" -typedef d_sample tube_sample; +typedef sample_t tube_sample; /* this is the original tube model from caps < 0.1.9 or preamp.so, put * back into use in 0.1.11; the replacement (below) is too strong in diff --git a/plugins/ladspa_effect/caps/dsp/VCO.h b/plugins/ladspa_effect/caps/dsp/VCO.h index 6f797dea7..d5b5347f1 100644 --- a/plugins/ladspa_effect/caps/dsp/VCO.h +++ b/plugins/ladspa_effect/caps/dsp/VCO.h @@ -1,7 +1,7 @@ /* dsp/VCO.h - Copyright 2004 Tim Goetze + Copyright 2004, 2010 Tim Goetze oscillators for triangle/sawtooth/square waves, and a combination for detuning and hard sync. @@ -74,7 +74,7 @@ class TriSaw inline float get() { phase += inc; - + /* the good thing is that tri is always > .5, which implies * that this first conditional is true more often than not. */ if (phase <= tri) @@ -151,13 +151,14 @@ class TriSawSquare st2 = s * tri; } - /* advance and return 1 sample. a pity we need so many conditionals, - * seeing that this is run at 352 k. + /* advance and return 1 sample. + * many branching instructions but on this intel chip faster than + * a version using floor() to keep the phase within [0..1]. */ inline float get() { phase += inc; - + if (phase <= tri) first_half: /* raw version: diff --git a/plugins/ladspa_effect/caps/dsp/White.h b/plugins/ladspa_effect/caps/dsp/White.h index e3ff17066..1a9fe6ea7 100644 --- a/plugins/ladspa_effect/caps/dsp/White.h +++ b/plugins/ladspa_effect/caps/dsp/White.h @@ -48,30 +48,30 @@ class White b = (uint32) (f * (float) 0x1fff7777); } - d_sample abs() + sample_t abs() { return fabs (get()); } /* 32-bit version */ - d_sample get() + sample_t get() { # define BIT(y) ((b << (31 - y)) & 0x80000000) b = ((BIT (28) ^ BIT (27) ^ BIT (1) ^ BIT (0))) | (b >> 1); - return (4.6566128730773926e-10 * (d_sample) b) - 1; + return (4.6566128730773926e-10 * (sample_t) b) - 1; # undef BIT } /* 31-bit version, at least 6 instructions less / sample. probably only * pays off on a processor not providing a decent binary shift. */ - d_sample get_31() + sample_t get_31() { # define BIT(y) ((b << (30 - y)) & 0x40000000) b = ((BIT (3) ^ BIT (0))) | (b >> 1); - return (9.3132257461547852e-10 * (d_sample) b) - 1; + return (9.3132257461547852e-10 * (sample_t) b) - 1; # undef BIT } diff --git a/plugins/ladspa_effect/caps/dsp/sinc.h b/plugins/ladspa_effect/caps/dsp/sinc.h index d40842232..b002f234d 100644 --- a/plugins/ladspa_effect/caps/dsp/sinc.h +++ b/plugins/ladspa_effect/caps/dsp/sinc.h @@ -35,7 +35,7 @@ namespace DSP { /* sample sinc() with step size omega into s[], centered around s + n / 2 */ inline void -sinc (double omega, d_sample * s, int n) +sinc (double omega, sample_t * s, int n) { /* initial phase */ double phi = (n / 2) * -omega; diff --git a/plugins/ladspa_effect/caps/dsp/windows.h b/plugins/ladspa_effect/caps/dsp/windows.h index 35a4d6430..949a95818 100644 --- a/plugins/ladspa_effect/caps/dsp/windows.h +++ b/plugins/ladspa_effect/caps/dsp/windows.h @@ -1,7 +1,7 @@ /* dsp/windows.h - Copyright 2004-9 Tim Goetze + Copyright 2004-11 Tim Goetze http://quitte.de/dsp/ @@ -31,27 +31,26 @@ namespace DSP { /* prototypes for window value application ... */ -typedef void (*window_sample_func_t) (d_sample &, d_sample); +typedef void (*window_sample_func_t) (sample_t &, sample_t); /* ... which go as template parameters for the window calculation below */ inline void -store_sample (d_sample & d, d_sample s) +store_sample (sample_t & d, sample_t s) { d = s; } inline void -apply_window (d_sample &d, d_sample s) +apply_window (sample_t &d, sample_t s) { d *= s; } template void -hanning (d_sample * s, int n) +hanning (sample_t * s, int n) { - /* TODO: speed up by using DSP::Sine */ - + /* could speed up by using DSP::Sine but we rarely use this window */ for (int i = 0; i < n; ++i) { register double f = (double) i / n - 1; @@ -61,7 +60,7 @@ hanning (d_sample * s, int n) template void -blackman (d_sample * s, int n) +blackman (sample_t * s, int n) { register float w = n; @@ -79,7 +78,7 @@ blackman (d_sample * s, int n) template void -blackman_harris (d_sample * s, int n) +blackman_harris (sample_t * s, int n) { register double w1 = 2.f * M_PI / (n - 1); register double w2 = 2.f * w1; @@ -138,7 +137,7 @@ besseli (double x) template void -kaiser (d_sample * s, int n, double beta) +kaiser (sample_t * s, int n, double beta) { double bb = besseli (beta); int si = 0; diff --git a/plugins/ladspa_effect/caps/interface.cc b/plugins/ladspa_effect/caps/interface.cc index b374e9441..d0289d934 100644 --- a/plugins/ladspa_effect/caps/interface.cc +++ b/plugins/ladspa_effect/caps/interface.cc @@ -1,13 +1,13 @@ /* interface.cc - Copyright 2004-9 Tim Goetze + Copyright 2004-11 Tim Goetze http://quitte.de/dsp/ LADSPA descriptor factory, host interface. - */ +*/ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -24,6 +24,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA or point your web browser to http://www.gnu.org. */ +/* + LADSPA ID ranges 1761 - 1800 and 2581 - 2660 + (2541 - 2580 donated to artemio@kdemail.net) +*/ #include @@ -51,7 +55,7 @@ #include "Descriptor.h" -#define N 38 +#define N 39 static DescriptorStub * descriptors [N]; /*static inline void @@ -74,6 +78,7 @@ void _init() *d++ = new Descriptor(); *d++ = new Descriptor(); *d++ = new Descriptor(); + *d++ = new Descriptor(); *d++ = new Descriptor(); *d++ = new Descriptor();