--- interface.cc 2013-01-10 14:19:44.000000000 +0100 +++ /home/tim/caps/interface.cc 2013-01-17 10:15:33.000000000 +0100 @@ -89,6 +89,7 @@ *d++ = new Descriptor(2603); #endif + *d++ = new Descriptor(1767); *d++ = new Descriptor(2583); *d++ = new Descriptor(2584); *d++ = new Descriptor(2605); --- Chorus.h 2013-01-11 11:38:57.000000000 +0100 +++ /home/tim/caps/Chorus.h 2013-01-17 10:15:54.000000000 +0100 @@ -69,6 +69,52 @@ } }; +class ChorusI +: public ChorusStub +{ + public: + DSP::Sine lfo; + DSP::Delay delay; + DSP::DelayTapA tap; + + template + void one_cycle (int frames); + + public: + static PortInfo port_info []; + + void init() + { + rate = .15; + delay.init ((int) (.040 * fs)); + } + + void activate() + { + time = 0; + width = 0; + + rate = *ports[3]; + + delay.reset(); + tap.reset(); + + lfo.set_f (rate, fs, 0); + } + + void run (int n) + { + one_cycle (n); + } + + void run_adding (int n) + { + one_cycle (n); + } +}; + +/* ///////////////////////////////////////////////////////////////////////// */ + class ChorusII : public ChorusStub { --- Chorus.cc 2013-01-11 11:35:11.000000000 +0100 +++ /home/tim/caps/Chorus.cc 2013-01-17 10:24:28.000000000 +0100 @@ -32,6 +32,99 @@ template void +ChorusI::one_cycle (int frames) +{ + sample_t * s = ports[0]; + + double one_over_n = 1 / (double) frames; + double ms = .001 * fs; + + double t = time; + time = getport(1) * ms; + double dt = (time - t) * one_over_n; + + double w = width; + width = getport(2) * ms; + /* clamp, or we need future samples from the delay line */ + if (width >= t - 3) width = t - 3; + double dw = (width - w) * one_over_n; + + if (rate != *ports[3]) + lfo.set_f (max (rate = getport(3), .000001), fs, lfo.get_phase()); + + double blend = getport(4); + double ff = getport(5); + double fb = getport(6); + + sample_t * d = ports[7]; + + DSP::FPTruncateMode truncate; + + for (int i = 0; i < frames; ++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 + * interesting) */ + int ti; + fistp (t, ti); + x -= fb * delay[ti]; + + delay.put (x + normal); + +# if 0 + /* allpass delay sounds a little cleaner for a chorus + * but sucks big time when flanging. */ + x = blend * x + ff * tap.get (delay, t + w * lfo.get()); +# elif 0 + /* linear interpolation */ + x = blend * x + ff * delay.get_at (t + w * lfo.get()); +# else + /* cubic interpolation */ + x = blend * x + ff * delay.get_cubic (t + w * lfo.get()); +# endif + + F (d, i, x, adding_gain); + + t += dt; + w += dw; + } +} + +/* //////////////////////////////////////////////////////////////////////// */ + +PortInfo +ChorusI::port_info [] = +{ + { "in", INPUT | AUDIO }, + { "t (ms)", CTRL_IN, {BOUNDED | LOG | DEFAULT_LOW, 2.5, 40} }, + { "width (ms)", CTRL_IN, {BOUNDED | DEFAULT_1, .5, 10} }, + { "rate (Hz)", CTRL_IN | GROUP, {BOUNDED | DEFAULT_LOW, 0, 5} }, + { "blend", CTRL_IN, {BOUNDED | DEFAULT_1, 0, 1} }, + { "feedforward", CTRL_IN | GROUP, {BOUNDED | DEFAULT_LOW, 0, 1} }, + { "feedback", CTRL_IN, {BOUNDED | DEFAULT_0, 0, 1} }, + { "out", OUTPUT | AUDIO } +}; + +template <> void +Descriptor::setup() +{ + Label = "ChorusI"; + Properties = HARD_RT; + + Name = CAPS "ChorusI - Mono chorus/flanger"; + Maker = "Tim Goetze "; + Copyright = "GPL, 2004-13"; + + /* fill port info and vtable */ + autogen(); +} + +/* //////////////////////////////////////////////////////////////////////// */ + +template +void ChorusII::cycle (uint frames) { sample_t * s = ports[0]; @@ -190,12 +283,12 @@ PortInfo StereoChorusII::port_info [] = { - { "t (ms)", INPUT | CONTROL, {DEFAULT_LOW, 2.5, 25} }, - { "width (ms)", INPUT | CONTROL, {DEFAULT_1, .5, 10} }, - { "rate", INPUT | CONTROL | GROUP, {DEFAULT_LOW, 0, 1} }, - { "blend", INPUT | CONTROL, {DEFAULT_LOW, 0, 1} }, - { "feedforward", INPUT | CONTROL | GROUP, {DEFAULT_1, 0, 1} }, - { "feedback", INPUT | CONTROL, {DEFAULT_MID, 0, 1} }, + { "t (ms)", CTRL_IN, {DEFAULT_LOW, 2.5, 25} }, + { "width (ms)", CTRL_IN, {DEFAULT_1, .5, 10} }, + { "rate", CTRL_IN | GROUP, {DEFAULT_LOW, 0, 1} }, + { "blend", CTRL_IN, {DEFAULT_LOW, 0, 1} }, + { "feedforward", CTRL_IN | GROUP, {DEFAULT_1, 0, 1} }, + { "feedback", CTRL_IN, {DEFAULT_MID, 0, 1} }, { "in", INPUT | AUDIO }, { "out.l", OUTPUT | AUDIO }, { "out.r", OUTPUT | AUDIO } @@ -219,12 +312,12 @@ PortInfo StereoChorusII2x2::port_info [] = { - { "t (ms)", INPUT | CONTROL, {DEFAULT_LOW, 2.5, 25} }, - { "width (ms)", INPUT | CONTROL, {DEFAULT_1, .5, 10} }, - { "rate", INPUT | CONTROL | GROUP, {DEFAULT_LOW, 0, 1} }, - { "blend", INPUT | CONTROL, {DEFAULT_LOW, 0, 1} }, - { "feedforward", INPUT | CONTROL | GROUP, {DEFAULT_1, 0, 1} }, - { "feedback", INPUT | CONTROL, {DEFAULT_MID, 0, 1} }, + { "t (ms)", CTRL_IN, {DEFAULT_LOW, 2.5, 25} }, + { "width (ms)", CTRL_IN, {DEFAULT_1, .5, 10} }, + { "rate", CTRL_IN | GROUP, {DEFAULT_LOW, 0, 1} }, + { "blend", CTRL_IN, {DEFAULT_LOW, 0, 1} }, + { "feedforward", CTRL_IN | GROUP, {DEFAULT_1, 0, 1} }, + { "feedback", CTRL_IN, {DEFAULT_MID, 0, 1} }, { "in.l", INPUT | AUDIO }, { "in.r", INPUT | AUDIO }, { "out.l", OUTPUT | AUDIO },