[SCM] calf/master: + MultiChorus: new effect added (incomplete)
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:37:47 UTC 2013
The following commit has been merged in the master branch:
commit 6a173e85df3d7603712c1eccd386257f712c2c18
Author: Krzysztof Foltman <kfoltman at ubuntu.(none)>
Date: Mon Oct 27 22:43:11 2008 +0000
+ MultiChorus: new effect added (incomplete)
diff --git a/src/calf/Makefile.am b/src/calf/Makefile.am
index 334ae1a..9050b5d 100644
--- a/src/calf/Makefile.am
+++ b/src/calf/Makefile.am
@@ -5,5 +5,5 @@ calf_HEADERS = audio_fx.h benchmark.h biquad.h buffer.h custom_ctl.h \
delay.h envelope.h fft.h fixed_point.h giface.h gui.h inertia.h \
jackhost.h lv2_event.h lv2_ui.h lv2_uri_map.h lv2-midiport.h lv2helpers.h lv2wrap.h \
main_win.h modules.h modules_dev.h modules_small.h modules_synths.h modulelist.h \
- onepole.h organ.h osc.h osctl.h osctlnet.h plugininfo.h preset.h \
+ multichorus.h onepole.h organ.h osc.h osctl.h osctlnet.h plugininfo.h preset.h \
preset_gui.h primitives.h synth.h utils.h wave.h
diff --git a/src/calf/audio_fx.h b/src/calf/audio_fx.h
index bd269d6..1bcf4ae 100644
--- a/src/calf/audio_fx.h
+++ b/src/calf/audio_fx.h
@@ -202,11 +202,10 @@ public:
class chorus_base: public modulation_effect
{
protected:
- int sample_rate, min_delay_samples, mod_depth_samples;
+ int min_delay_samples, mod_depth_samples;
float min_delay, mod_depth;
sine_table<int, 4096, 65536> sine;
public:
- fixed_point<unsigned int, 20> phase, dphase;
float get_min_delay() {
return min_delay;
}
diff --git a/src/calf/fixed_point.h b/src/calf/fixed_point.h
index 46aaf46..de5f289 100644
--- a/src/calf/fixed_point.h
+++ b/src/calf/fixed_point.h
@@ -60,6 +60,14 @@ public:
value = (T)(v*one());
}
+ /// Makes an instance from a representation value (ie. same type of value as is used for internal storage and get/set)
+ static inline fixed_point from_base(const T &v)
+ {
+ fixed_point result;
+ result.value = v;
+ return result;
+ }
+
inline T one() {
return (T)(1) << FracBits;
}
diff --git a/src/calf/modulelist.h b/src/calf/modulelist.h
index 09a226c..5f7f559 100644
--- a/src/calf/modulelist.h
+++ b/src/calf/modulelist.h
@@ -7,7 +7,7 @@
PER_MODULE_ITEM(organ, true, "organ")
PER_MODULE_ITEM(rotary_speaker, false, "rotaryspeaker")
PER_MODULE_ITEM(phaser, false, "phaser")
- PER_MODULE_ITEM(subsaw, false, "subsaw")
+ PER_MODULE_ITEM(multichorus, false, "multichorus")
#undef PER_MODULE_ITEM
#endif
#ifdef PER_SMALL_MODULE_ITEM
diff --git a/src/calf/modules.h b/src/calf/modules.h
index f6e3a53..1563abf 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -25,6 +25,7 @@
#include "biquad.h"
#include "inertia.h"
#include "audio_fx.h"
+#include "multichorus.h"
#include "giface.h"
namespace synth {
@@ -776,94 +777,56 @@ public:
static const char *get_label() { return "Rotary Speaker"; }
};
-class subsaw
-{
-public:
- dsp::onepole<float> antidc, amp;
- float last, state, last_amp;
- bool cnt;
-public:
- void set_sample_rate(uint32_t sr)
- {
- antidc.set_hp(10.0, sr);
- amp.set_lp(10.0, sr);
- state = 0;
- last = 0.f;
- last_amp = 0.f;
- cnt = false;
- }
- inline float process(float value)
- {
- if (last >= 0.f && value < 0.f) // && 0 == (cnt = !cnt))
- {
- if (amp.y1 < state)
- amp.y1 = state;
- state = 0;
- }
- else
- {
- state += fabs(value);
- last_amp = amp.process(0);
- }
-
- last = value;
- return antidc.process_hp(0.25f * state);
- }
-};
-
-// A sub-osc thingy
-class subsaw_audio_module: public null_audio_module
+// A multitap stereo chorus thing
+class multichorus_audio_module: public null_audio_module
{
public:
- enum { par_cutoff, param_count };
+ enum { par_delay, par_depth, par_rate, par_stereo, par_amount, param_count };
enum { in_count = 2, out_count = 2, rt_capable = true, support_midi = false };
float *ins[in_count];
float *outs[out_count];
float *params[param_count];
static const char *port_names[];
- dsp::biquad<float> filter_left, filter_right;
- dsp::biquad<float> filter2_left, filter2_right;
- dsp::biquad<float> filter3_left, filter3_right;
- subsaw state_left, state_right;
uint32_t srate;
+ dsp::multichorus<float, sine_multi_lfo<float, 6>, 2048> left, right;
+
static parameter_properties param_props[];
static synth::ladspa_plugin_info plugin_info;
public:
- subsaw_audio_module()
+ multichorus_audio_module()
{
}
void params_changed()
{
- filter_left.set_bp_rbj(*params[par_cutoff], 2, srate);
- filter_right.copy_coeffs(filter_left);
- filter2_left.set_lp_rbj(*params[par_cutoff], 0.7, srate);
- filter2_right.copy_coeffs(filter2_left);
+ // delicious copy-pasta from flanger module - it'd be better to keep it common or something
+ float dry = 1.0;
+ float wet = *params[par_amount];
+ float rate = *params[par_rate];
+ float min_delay = *params[par_delay] / 1000.0;
+ float mod_depth = *params[par_depth] / 1000.0;
+ left.set_dry(dry); right.set_dry(dry);
+ left.set_wet(wet); right.set_wet(wet);
+ left.set_rate(rate); right.set_rate(rate);
+ left.set_min_delay(min_delay); right.set_min_delay(min_delay);
+ left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
}
void activate() {
params_changed();
}
void set_sample_rate(uint32_t sr) {
srate = sr;
- state_left.set_sample_rate(sr);
- state_right.set_sample_rate(sr);
+ left.setup(sr);
+ right.setup(sr);
}
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
-// printf("sr=%d cutoff=%f res=%f mode=%f\n", srate, *params[par_cutoff], *params[par_resonance], *params[par_mode]);
- uint32_t ostate = 3;
- numsamples += offset;
- filter3_left.set_lp_rbj(clip<double>(20000.0 * state_left.last_amp, 20.0, srate * 0.48), 3, srate);
- filter3_right.set_lp_rbj(clip<double>(20000.0 * state_right.last_amp, 20.0, srate * 0.48), 3, srate);
- while(offset < numsamples) {
- outs[0][offset] = filter3_left.process_d1(state_left.process(filter2_left.process_d1(filter_left.process_d1(ins[0][offset]))));
- outs[1][offset] = filter3_right.process_d1(state_right.process(filter2_right.process_d1(filter_right.process_d1(ins[1][offset]))));
- offset ++;
- }
- return ostate;
+ left.process(outs[0] + offset, ins[0] + offset, numsamples);
+ right.process(outs[1] + offset, ins[1] + offset, numsamples);
+ return outputs_mask; // XXXKF allow some delay after input going blank
}
- static const char *get_id() { return "subsaw"; }
- static const char *get_name() { return "subsaw"; }
- static const char *get_label() { return "SubSaw"; }
+ static const char *get_id() { return "multichorus"; }
+ static const char *get_name() { return "multichorus"; }
+ static const char *get_label() { return "Multi Chorus"; }
};
extern std::string get_builtin_modules_rdf();
diff --git a/src/calf/multichorus.h b/src/calf/multichorus.h
index 42d64e5..8fccf1b 100644
--- a/src/calf/multichorus.h
+++ b/src/calf/multichorus.h
@@ -23,6 +23,108 @@
#include "audio_fx.h"
+namespace dsp {
+
+typedef fixed_point<unsigned int, 20> chorus_phase;
+
+template<class T, uint32_t Voices>
+class sine_multi_lfo
+{
+protected:
+ sine_table<int, 4096, 65536> sine;
+ enum { Multiplier = (65536 / Voices) << 16 };
+
+public:
+ chorus_phase phase, dphase;
+
+public:
+ inline uint32_t get_voices() const
+ {
+ return Voices;
+ }
+ inline chorus_phase get_phase(uint32_t voice) const {
+ return phase + chorus_phase::from_base(Multiplier * voice);
+ }
+ inline void step() {
+ phase += dphase;
+ }
+ inline T get_scale() const {
+ return 1.0 / Voices;
+ }
+ void reset() {
+ phase = 0.f;
+ }
+};
+
+/**
+ * Multi-tap chorus without feedback.
+ * Perhaps MaxDelay should be a bit longer!
+ */
+template<class T, class MultiLfo, int MaxDelay=512>
+class multichorus: public chorus_base
+{
+protected:
+ simple_delay<MaxDelay,T> delay;
+ MultiLfo lfo;
+public:
+ multichorus() {
+ rate = 0.63f;
+ dry = 0.5f;
+ wet = 0.5f;
+ min_delay = 0.005f;
+ mod_depth = 0.0025f;
+ setup(44100);
+ }
+ void reset() {
+ delay.reset();
+ lfo.reset();
+ }
+ void set_rate(float rate) {
+ chorus_base::set_rate(rate);
+ lfo.dphase = dphase;
+ }
+ virtual void setup(int sample_rate) {
+ printf("setting sample rate = %d\n", sample_rate);
+ modulation_effect::setup(sample_rate);
+ delay.reset();
+ lfo.reset();
+ set_min_delay(get_min_delay());
+ set_mod_depth(get_mod_depth());
+ }
+ template<class OutIter, class InIter>
+ void process(OutIter buf_out, InIter buf_in, int nsamples) {
+ int mds = min_delay_samples + mod_depth_samples * 1024 + 2*65536;
+ int mdepth = mod_depth_samples;
+ for (int i=0; i<nsamples; i++) {
+ phase += dphase;
+
+ float in = *buf_in++;
+
+ delay.put(in);
+ unsigned int nvoices = lfo.get_voices();
+ T out = 0.f;
+ // add up values from all voices, each voice tell its LFO phase and the buffer value is picked at that location
+ for (unsigned int v = 0; v < nvoices; v++)
+ {
+ chorus_phase phase = lfo.get_phase(v);
+ unsigned int ipart = phase.ipart();
+ int lfo = phase.lerp_by_fract_int<int, 14, int>(sine.data[ipart], sine.data[ipart+1]);
+ int v = mds + (mdepth * lfo >> 6);
+ int ifv = v >> 16;
+ T fd; // signal from delay's output
+ delay.get_interp(fd, ifv, (v & 0xFFFF)*(1.0/65536.0));
+ out += fd;
+ }
+ T sdry = in * gs_dry.get();
+ T swet = out * gs_wet.get() * lfo.get_scale();
+ *buf_out++ = sdry + swet;
+ lfo.step();
+ }
+ }
+};
+
+};
+
#endif
diff --git a/src/modules.cpp b/src/modules.cpp
index ffce0c2..41125d8 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -163,13 +163,17 @@ synth::ladspa_plugin_info monosynth_audio_module::plugin_info = { 0x8480, "Monos
////////////////////////////////////////////////////////////////////////////
-const char *subsaw_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+const char *multichorus_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
-parameter_properties subsaw_audio_module::param_props[] = {
- { 2000, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "cutoff", "Pre Cutoff" },
+parameter_properties multichorus_audio_module::param_props[] = {
+ { 0.1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "min_delay", "Minimum delay" },
+ { 0.5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "mod_depth", "Modulation depth" },
+ { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Modulation rate" },
+ { 0, 0, 360, 9, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "stereo", "Stereo phase" },
+ { 1, 0, 2, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "amount", "Amount" },
};
-synth::ladspa_plugin_info subsaw_audio_module::plugin_info = { 0x8500, "SubSaw", "Calf SubSaw", "Krzysztof Foltman", synth::calf_copyright_info, "UtilityPlugin" };
+synth::ladspa_plugin_info multichorus_audio_module::plugin_info = { 0x8501, "MultiChorus", "Calf MultiChorus", "Krzysztof Foltman", synth::calf_copyright_info, "ChorusPlugin" };
////////////////////////////////////////////////////////////////////////////
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list