[SCM] calf/master: + organ: removed rotary speaker emulation altogether, might get back some day as B3-style vibrato/chorus, decreased default master volume, increased foldover point (sounded bad previously!), set 1' stop to 0.3 + rotaryspeaker: new effect, unoptimized so far, I want to make it good-sounding first (pretty close!)
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:36:50 UTC 2013
The following commit has been merged in the master branch:
commit 6f9bac53330482e3bef2d7934335a4e246819853
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date: Fri Dec 28 00:11:41 2007 +0000
+ organ: removed rotary speaker emulation altogether, might get back some day as B3-style vibrato/chorus, decreased default master volume, increased foldover point (sounded bad previously!), set 1' stop to 0.3
+ rotaryspeaker: new effect, unoptimized so far, I want to make it good-sounding first (pretty close!)
git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@51 78b06b96-2940-0410-b7fc-879d825d01d8
diff --git a/src/calf/delay.h b/src/calf/delay.h
index f3a4b0c..e33ff05 100644
--- a/src/calf/delay.h
+++ b/src/calf/delay.h
@@ -98,6 +98,22 @@ struct simple_delay {
odata = lerp(data[ppos], data[pppos], udelay);
}
+ /** Read one C-channel sample at fractional position.
+ * This version can be used for modulated delays, because
+ * it uses linear interpolation.
+ * @param odata value to write into
+ * @param delay delay relative to current writing pos
+ * @param udelay fractional delay (0..1)
+ */
+ inline T get_interp_1616(unsigned int delay) {
+ float udelay = (float)((delay & 0xFFFF) * (1.0 / 65536.0));
+ delay = delay >> 16;
+// assert(delay >= 0 && delay < N-1);
+ int ppos = wrap_around<N>(pos + N - delay);
+ int pppos = wrap_around<N>(ppos + N - 1);
+ return lerp(data[ppos], data[pppos], udelay);
+ }
+
/**
* Comb filter. Feedback delay line with given delay and feedback values
* @param in input signal
diff --git a/src/calf/modules_dev.h b/src/calf/modules_dev.h
index 0724d97..2345504 100644
--- a/src/calf/modules_dev.h
+++ b/src/calf/modules_dev.h
@@ -40,7 +40,7 @@ public:
using drawbar_organ::note_off;
using drawbar_organ::control_change;
enum { par_drawbar1, par_drawbar2, par_drawbar3, par_drawbar4, par_drawbar5, par_drawbar6, par_drawbar7, par_drawbar8, par_drawbar9, par_foldover,
- par_percmode, par_percharm, par_vibrato, par_master, param_count };
+ par_percmode, par_percharm, par_master, param_count };
enum { in_count = 0, out_count = 2, support_midi = true, rt_capable = true };
static const char *port_names[];
float *ins[in_count];
@@ -60,7 +60,6 @@ public:
void params_changed() {
for (int i = 0; i < param_count; i++)
((float *)&par_values)[i] = *params[i];
- set_vibrato();
}
void activate() {
setup(srate);
@@ -75,6 +74,127 @@ public:
};
+class rotary_speaker_audio_module: public null_audio_module
+{
+public:
+ enum { par_speed, param_count };
+ enum { in_count = 2, out_count = 2, support_midi = true, rt_capable = true };
+ static const char *port_names[];
+ float *ins[in_count];
+ float *outs[out_count];
+ float *params[param_count];
+ float phase_h, dphase_h;
+ float phase_l, dphase_l;
+ dsp::simple_delay<4096, float> delay;
+ dsp::biquad<float> crossover1l, crossover1r, crossover2l, crossover2r;
+ dsp::simple_delay<8, float> phaseshift;
+ uint32_t srate;
+ int vibrato_mode;
+ static parameter_properties param_props[];
+ float mwhl_value, hold_value;
+
+ rotary_speaker_audio_module()
+ {
+ mwhl_value = hold_value = 0.f;
+ phase_h = phase_l = 0.f;
+ }
+ void set_sample_rate(uint32_t sr) {
+ srate = sr;
+ setup();
+ }
+ void setup()
+ {
+ crossover1l.set_lp_rbj(800.f, 0.7, (float)srate);
+ crossover1r.set_lp_rbj(800.f, 0.7, (float)srate);
+ crossover2l.set_hp_rbj(800.f, 0.7, (float)srate);
+ crossover2r.set_hp_rbj(800.f, 0.7, (float)srate);
+ set_vibrato();
+ }
+ void params_changed() {
+ set_vibrato();
+ }
+ void activate() {
+ phase_h = phase_l = 0.f;
+ setup();
+ }
+ void deactivate() {
+ }
+ void set_vibrato()
+ {
+ vibrato_mode = fastf2i_drm(*params[par_speed]);
+ if (!vibrato_mode)
+ return;
+ float speed = vibrato_mode - 1;
+ if (vibrato_mode == 3)
+ speed = hold_value;
+ if (vibrato_mode == 4)
+ speed = mwhl_value;
+ speed = (speed < 0.5f) ? 0 : 1;
+ float speed_h = 48 + (400-48) * speed;
+ float speed_l = 40 + (342-40) * speed;
+ dphase_h = 2 * PI * speed_h / (60 * srate);
+ dphase_l = 2 * PI * speed_l / (60 * srate);
+ }
+ uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask)
+ {
+ if (vibrato_mode)
+ {
+ for (unsigned int i = 0; i < nsamples; i++) {
+ float in_l = ins[0][i + offset], in_r = ins[1][i + offset];
+ float in_mono = 0.5f * (in_l + in_r);
+
+ // XXXKF this is of course criminal, but I'm working on sound, not performance at this stage
+ int xl = (int)(10000 * cos(phase_l)), yl = (int)(10000 * sin(phase_l));
+ int xh = (int)(10000 * cos(phase_h)), yh = (int)(10000 * sin(phase_h));
+ phase_l += dphase_l;
+ phase_h += dphase_h;
+
+ float out_hi_l = delay.get_interp_1616(500000 + 40 * xh) + 0.0001 * xh * delay.get_interp_1616(500000 - 40 * yh) - delay.get_interp_1616(800000 - 60 * xh);
+ float out_hi_r = delay.get_interp_1616(550000 - 48 * yh) - 0.0001 * yh * delay.get_interp_1616(700000 + 46 * xh) - delay.get_interp_1616(1000000 + 76 * yh);
+
+ float out_lo_l = 0.5f * in_mono + delay.get_interp_1616(400000 + 34 * xl) + delay.get_interp_1616(600000 - 18 * yl);
+ float out_lo_r = 0.5f * in_mono + delay.get_interp_1616(600000 - 50 * xl) - delay.get_interp_1616(900000 + 15 * yl);
+
+ out_hi_l = crossover2l.process_d2(out_hi_l);
+ out_hi_r = crossover2r.process_d2(out_hi_r);
+ out_lo_l = crossover1l.process_d2(out_lo_l);
+ out_lo_r = crossover1r.process_d2(out_lo_r);
+
+ float out_l = out_hi_l + out_lo_l;
+ float out_r = out_hi_r + out_lo_r;
+
+ in_mono += 0.06f * (out_l + out_r);
+
+ outs[0][i + offset] = out_l;
+ outs[1][i + offset] = out_r;
+ delay.put(in_mono);
+ }
+ phase_l = fmod(phase_l, (float)(2 * PI));
+ phase_h = fmod(phase_h, (float)(2 * PI));
+ } else
+ {
+ memcpy(outs[0] + offset, ins[0] + offset, sizeof(float) * nsamples);
+ memcpy(outs[1] + offset, ins[1] + offset, sizeof(float) * nsamples);
+ }
+ return outputs_mask;
+ }
+ virtual void control_change(int ctl, int val)
+ {
+ if (vibrato_mode == 3 && ctl == 64)
+ {
+ hold_value = val / 127.f;
+ set_vibrato();
+ return;
+ }
+ if (vibrato_mode == 4 && ctl == 1)
+ {
+ mwhl_value = val / 127.f;
+ set_vibrato();
+ return;
+ }
+ }
+};
+
};
#endif
diff --git a/src/calf/organ.h b/src/calf/organ.h
index 5fb65ff..04cca28 100644
--- a/src/calf/organ.h
+++ b/src/calf/organ.h
@@ -32,13 +32,11 @@ struct organ_parameters {
float foldover;
float percussion_mode;
float harmonic;
- float vibrato_mode;
float master;
inline bool get_foldover() { return foldover >= 0.5f; }
inline int get_percussion_mode() { return dsp::fastf2i_drm(percussion_mode); }
inline int get_harmonic() { return dsp::fastf2i_drm(harmonic); }
- inline int get_vibrato_mode() { return dsp::fastf2i_drm(vibrato_mode); }
};
class organ_voice_base
@@ -86,7 +84,7 @@ public:
void calc_foldover() {
h4 = 4, h6 = 6, h8 = 8, h10 = 10, h12 = 12, h16 = 16;
if (!parameters->get_foldover()) return;
- const int foc = 108, foc2 = 108 + 12, foc3 = 108 + 24;
+ const int foc = 120, foc2 = 120 + 12, foc3 = 120 + 24;
if (note + 24 >= foc) h4 = 2;
if (note + 24 >= foc2) h4 = 1;
if (note + 36 >= foc) h8 = 4;
@@ -189,17 +187,10 @@ public:
struct drawbar_organ: public synth::basic_synth {
organ_parameters *parameters;
percussion_voice percussion;
- // chorus instead of rotary speaker is, well, cheesy
- // let me think of something better some day
- dsp::simple_flanger<float, 4096> chorus, chorus2;
- dsp::biquad<float> crossover1, crossover2;
- dsp::simple_delay<8, float> phaseshift;
- float mwhl_value, hold_value;
drawbar_organ(organ_parameters *_parameters)
: parameters(_parameters)
, percussion(_parameters) {
- mwhl_value = hold_value = 0.f;
}
void render_to(float *output[], int nsamples)
{
@@ -209,20 +200,6 @@ struct drawbar_organ: public synth::basic_synth {
if (percussion.get_active())
percussion.render_to(buf, nsamples);
float gain = parameters->master;
- if (parameters->get_vibrato_mode())
- {
- float chorus_buffer[4096];
- float chorus_buffer2[4096];
- chorus.process(chorus_buffer, buf, nsamples);
- chorus2.process(chorus_buffer2, buf, nsamples);
- for (int i=0; i<nsamples; i++) {
- float lower_drum = crossover1.process_d2(chorus_buffer[i]);
- float upper_drum = crossover2.process_d2(chorus_buffer2[i]);
- output[0][i] = gain*(buf[i] + lower_drum - upper_drum);
- output[1][i] = gain*(buf[i] - phaseshift.process(lower_drum - upper_drum, 7));
- }
- }
- else
for (int i=0; i<nsamples; i++) {
output[0][i] = gain*buf[i];
output[1][i] = gain*buf[i];
@@ -236,54 +213,7 @@ struct drawbar_organ: public synth::basic_synth {
}
virtual void setup(int sr) {
basic_synth::setup(sr);
- crossover1.set_lp_rbj(800.f, 0.7, (float)sr);
- crossover2.set_hp_rbj(800.f, 0.7, (float)sr);
- set_vibrato();
- chorus.setup(sr);chorus2.setup(sr);
- chorus.set_min_delay(0.0041f);chorus2.set_min_delay(0.0025f);
- chorus.set_mod_depth(0.0024f);chorus2.set_mod_depth(0.0034f);
-
- chorus.set_rate(0.63f);chorus2.set_rate(0.63f);
- chorus.set_wet(0.5f);chorus2.set_wet(0.5f);
- chorus.set_dry(0.0f);chorus2.set_dry(0.0f);
percussion.setup(sr);
- mwhl_value = hold_value = 0.f;
- }
- virtual void control_change(int ctl, int val)
- {
- int mode = parameters->get_vibrato_mode();
- if (mode == 3 && ctl == 64)
- {
- hold_value = val / 127.f;
- set_vibrato();
- return;
- }
- if (mode == 4 && ctl == 1)
- {
- mwhl_value = val / 127.f;
- set_vibrato();
- return;
- }
- synth::basic_synth::control_change(ctl, val);
- }
- void set_vibrato()
- {
- int mode = parameters->get_vibrato_mode();
- if (!mode)
- return;
- float speed = mode - 1;
- if (mode == 3)
- speed = hold_value;
- if (mode == 4)
- speed = mwhl_value;
- chorus.set_mod_depth(0.002f - 0.0015f*speed);
- chorus2.set_mod_depth(0.0025f - 0.002f*speed);
- chorus.set_min_delay(0.0061f);
- chorus2.set_min_delay(0.0085f);
- chorus.set_rate((40.0 + (342 - 40)*speed) / 60.0);
- chorus2.set_rate((48.0 + (400 - 48)*speed) / 60.0);
- chorus.set_fb(0.3f);
- chorus2.set_fb(-0.3f);
}
};
diff --git a/src/jackhost.cpp b/src/jackhost.cpp
index a35e690..a7304ae 100644
--- a/src/jackhost.cpp
+++ b/src/jackhost.cpp
@@ -59,6 +59,8 @@ jack_host_base *synth::create_jack_host(const char *effect_name)
#ifdef ENABLE_EXPERIMENTAL
else if (!strcmp(effect_name, "organ"))
return new jack_host<organ_audio_module>();
+ else if (!strcmp(effect_name, "rotaryspeaker"))
+ return new jack_host<rotary_speaker_audio_module>();
#endif
else
return NULL;
@@ -174,7 +176,7 @@ int main(int argc, char *argv[])
jack_host_base *jh = create_jack_host(names[i].c_str());
if (!jh) {
#ifdef ENABLE_EXPERIMENTAL
- fprintf(stderr, "Unknown plugin name; allowed are: reverb, flanger, filter, vintagedelay, monosynth, organ\n");
+ fprintf(stderr, "Unknown plugin name; allowed are: reverb, flanger, filter, vintagedelay, monosynth, organ, rotaryspeaker\n");
#else
fprintf(stderr, "Unknown plugin name; allowed are: reverb, flanger, filter, vintagedelay, monosynth\n");
#endif
diff --git a/src/modules.cpp b/src/modules.cpp
index 80756fa..300d3be 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -141,7 +141,6 @@ const char *organ_audio_module::port_names[] = {"Out L", "Out R"};
const char *organ_percussion_mode_names[] = { "Off", "Short", "Long" };
const char *organ_percussion_harmonic_names[] = { "2nd", "3rd" };
-const char *organ_vibrato_speed_names[] = { "Off", "Swell", "Tremolo", "HoldPedal", "ModWheel" };
parameter_properties organ_audio_module::param_props[] = {
{ 0.3, 0, 1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h1", "16'" },
@@ -152,14 +151,13 @@ parameter_properties organ_audio_module::param_props[] = {
{ 0, 0, 1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h8", "2'" },
{ 0, 0, 1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h10", "1 3/5'" },
{ 0, 0, 1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h12", "1 1/3'" },
- { 0, 0, 1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h16", "1'" },
+ { 0.3, 0, 1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h16", "1'" },
{ 1, 0, 1, 1.01, PF_BOOL | PF_CTL_TOGGLE, NULL, "foldover", "Foldover" },
{ 1, 0, 2, 1.01, PF_ENUM | PF_CTL_COMBO, organ_percussion_mode_names, "perc_mode", "Perc. mode" },
{ 3, 2, 3, 1.01, PF_ENUM | PF_CTL_COMBO, organ_percussion_harmonic_names, "perc_hrm", "Perc. harmonic" },
- { 1, 0, 4, 1.01, PF_ENUM | PF_CTL_COMBO, organ_vibrato_speed_names, "vib_speed", "Vibrato mode" },
- { 0.2, 0, 1, 1.01, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB, NULL, "amount", "Amount" },
+ { 0.1, 0, 1, 1.01, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB, NULL, "amount", "Amount" },
};
static synth::ladspa_info organ_info = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", copyright, "SynthesizerPlugin" };
@@ -168,6 +166,22 @@ static synth::ladspa_info organ_info = { 0x8481, "Organ", "Calf Organ", "Krzyszt
static synth::ladspa_wrapper<organ_audio_module> organ(organ_info);
#endif
+////////////////////////////////////////////////////////////////////////////
+
+const char *rotary_speaker_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+
+const char *rotary_speaker_speed_names[] = { "Off", "Swell", "Tremolo", "HoldPedal", "ModWheel" };
+
+parameter_properties rotary_speaker_audio_module::param_props[] = {
+ { 2, 0, 4, 1.01, PF_ENUM | PF_CTL_COMBO, rotary_speaker_speed_names, "vib_speed", "Speed Mode" },
+};
+
+static synth::ladspa_info rotary_speaker_info = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", copyright, "SimulationPlugin" };
+
+#if USE_LADSPA
+static synth::ladspa_wrapper<rotary_speaker_audio_module> rotary_speaker(rotary_speaker_info);
+#endif
+
#endif
////////////////////////////////////////////////////////////////////////////
@@ -189,6 +203,9 @@ const LADSPA_Descriptor *ladspa_descriptor(unsigned long Index)
case 1: return &::flanger.descriptor;
case 2: return &::reverb.descriptor;
case 3: return &::vintage_delay.descriptor;
+#ifdef ENABLE_EXPERIMENTAL
+ case 4: return &::rotary_speaker.descriptor;
+#endif
default: return NULL;
}
}
@@ -208,6 +225,7 @@ const DSSI_Descriptor *dssi_descriptor(unsigned long Index)
case 4: return &::vintage_delay.dssi_descriptor;
#ifdef ENABLE_EXPERIMENTAL
case 5: return &::organ.dssi_descriptor;
+ case 6: return &::rotary_speaker.dssi_descriptor;
#endif
default: return NULL;
}
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list