[SCM] calf/master: + Multichorus: add Overlap parameter
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:39:27 UTC 2013
The following commit has been merged in the master branch:
commit 1d0ef3ab50304773ada44a25d80bca5128cc418d
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Wed Mar 11 23:15:31 2009 +0000
+ Multichorus: add Overlap parameter
diff --git a/gui/gui-multichorus.xml b/gui/gui-multichorus.xml
index 95e0974..a5d4641 100644
--- a/gui/gui-multichorus.xml
+++ b/gui/gui-multichorus.xml
@@ -12,6 +12,11 @@
<value param="mod_depth" />
</vbox>
<vbox border="10">
+ <label param="overlap" />
+ <knob param="overlap" />
+ <value param="overlap" />
+ </vbox>
+ <vbox border="10">
<label param="dry" />
<knob param="dry" />
<value param="dry" />
diff --git a/src/calf/metadata.h b/src/calf/metadata.h
index 334f3dd..733ce5e 100644
--- a/src/calf/metadata.h
+++ b/src/calf/metadata.h
@@ -87,7 +87,7 @@ public:
struct multichorus_metadata: public plugin_metadata<multichorus_metadata>
{
public:
- enum { par_delay, par_depth, par_rate, par_stereo, par_voices, par_vphase, par_amount, par_dryamount, par_freq, par_freq2, par_q, param_count };
+ enum { par_delay, par_depth, par_rate, par_stereo, par_voices, par_vphase, par_amount, par_dryamount, par_freq, par_freq2, par_q, par_overlap, param_count };
enum { in_count = 2, out_count = 2, rt_capable = true, support_midi = false, require_midi = false };
PLUGIN_NAME_ID_LABEL("multichorus", "multichorus", "Multi Chorus")
};
diff --git a/src/calf/modules.h b/src/calf/modules.h
index 7e3ea04..3a09447 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -752,6 +752,7 @@ public:
float rate = *params[par_rate];
float min_delay = *params[par_delay] / 1000.0;
float mod_depth = *params[par_depth] / 1000.0;
+ float overlap = *params[par_overlap];
left.set_dry(dry); right.set_dry(dry);
left.set_wet(wet); right.set_wet(wet);
left.set_rate(rate); right.set_rate(rate);
@@ -759,6 +760,7 @@ public:
left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
int voices = (int)*params[par_voices];
left.lfo.set_voices(voices); right.lfo.set_voices(voices);
+ left.lfo.set_overlap(overlap);right.lfo.set_overlap(overlap);
float vphase = *params[par_vphase] * (1.f / 360.f);
left.lfo.vphase = right.lfo.vphase = vphase * (4096 / std::max(voices - 1, 1));
float r_phase = *params[par_stereo] * (1.f / 360.f);
diff --git a/src/calf/multichorus.h b/src/calf/multichorus.h
index f4ab7ce..121eb98 100644
--- a/src/calf/multichorus.h
+++ b/src/calf/multichorus.h
@@ -44,10 +44,17 @@ public:
uint32_t voices;
/// Current scale (output multiplier)
T scale;
+ /// Per-voice offset unit (the value that says how much the voices are offset with respect to each other in non-100% 'overlap' mode), scaled so that full range = 131072
+ int32_t voice_offset;
+ /// LFO Range scaling for non-100% overlap
+ uint32_t voice_depth;
public:
sine_multi_lfo()
{
phase = dphase = vphase = 0.0;
+ voice_offset = 0;
+ voice_depth = 1U << 31;
+
set_voices(Voices);
}
inline uint32_t get_voices() const
@@ -60,6 +67,18 @@ public:
// use sqrt, because some phases will cancel each other - so 1 / N is usually too low
scale = sqrt(1.0 / voices);
}
+ inline void set_overlap(float overlap)
+ {
+ // If we scale the delay amount so that full range of a single LFO is 0..1, all the overlapped LFOs will cover 0..range
+ // How it's calculated:
+ // 1. First voice is assumed to always cover the range of 0..1
+ // 2. Each remaining voice contributes an interval of a width = 1 - overlap, starting from the end of the interval of the previous voice
+ // Coverage = non-overlapped part of the LFO range in the 1st voice
+ float range = 1.f + (1.f - overlap) * (voices - 1);
+ float scaling = 1.f / range;
+ voice_offset = (int)(131072 * (1 - overlap) / range);
+ voice_depth = (unsigned int)((1U << 30) * 1.0 * scaling);
+ }
/// Get LFO value for given voice, returns a values in range of [-65536, 65535] (or close)
inline int get_value(uint32_t voice) {
// find this voice's phase (= phase + voice * 360 degrees / number of voices)
@@ -69,7 +88,9 @@ public:
// interpolate (use 14 bits of precision - because the table itself uses 17 bits and the result of multiplication must fit in int32_t)
// note, the result is still -65535 .. 65535, it's just interpolated
// it is never reaching -65536 - but that's acceptable
- return voice_phase.lerp_by_fract_int<int, 14, int>(sine.data[ipart], sine.data[ipart+1]);
+ int intval = voice_phase.lerp_by_fract_int<int, 14, int>(sine.data[ipart], sine.data[ipart+1]);
+ // apply the voice offset/depth (rescale from -65535..65535 to appropriate voice's "band")
+ return -65535 + voice * voice_offset + ((voice_depth >> (30-13)) * (65536 + intval) >> 13);
}
inline void step() {
phase += dphase;
diff --git a/src/modules.cpp b/src/modules.cpp
index a5111e9..f297b65 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -200,6 +200,7 @@ CALF_PORT_PROPS(multichorus) = {
{ 100, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq", "Center Frq 1" },
{ 5000, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq2", "Center Frq 2" },
{ 0.125, 0.125, 8, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "q", "Q" },
+ { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "overlap", "Overlap" },
};
CALF_PLUGIN_INFO(multichorus) = { 0x8501, "MultiChorus", "Calf MultiChorus", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "ChorusPlugin" };
diff --git a/src/modules_dsp.cpp b/src/modules_dsp.cpp
index ac94491..e01e5e7 100644
--- a/src/modules_dsp.cpp
+++ b/src/modules_dsp.cpp
@@ -355,6 +355,7 @@ bool multichorus_audio_module::get_graph(int index, int subindex, float *data, i
{
if (!is_active)
return false;
+ int nvoices = (int)*params[par_voices];
if (index == par_delay && subindex < 3)
{
if (subindex < 2)
@@ -365,9 +366,15 @@ bool multichorus_audio_module::get_graph(int index, int subindex, float *data, i
}
return ::get_graph(*this, subindex, data, points);
}
- if (index == par_rate && !subindex) {
- for (int i = 0; i < points; i++)
- data[i] = 0.95 * sin(i * 2 * M_PI / points);
+ if (index == par_rate && subindex < nvoices) {
+ sine_multi_lfo<float, 8> &lfo = left.lfo;
+ for (int i = 0; i < points; i++) {
+ float phase = i * 2 * M_PI / points;
+ // original -65536 to 65535 value
+ float orig = subindex * lfo.voice_offset + ((lfo.voice_depth >> (30-13)) * 65536.0 * (0.95 * sin(phase) + 1)/ 8192.0) - 65536;
+ // scale to -1..1
+ data[i] = orig / 65536.0;
+ }
return true;
}
return false;
@@ -375,21 +382,27 @@ bool multichorus_audio_module::get_graph(int index, int subindex, float *data, i
bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
{
- if ((index != par_rate && index != par_depth) || subindex >= 2 * (int)*params[par_voices])
+ int voice = subindex >> 1;
+ int nvoices = (int)*params[par_voices];
+ if ((index != par_rate && index != par_depth) || voice >= nvoices)
return false;
+ float unit = (1 - *params[par_overlap]);
+ float scw = 1 + unit * (nvoices - 1);
set_channel_color(context, subindex);
sine_multi_lfo<float, 8> &lfo = (subindex & 1 ? right : left).lfo;
if (index == par_rate)
{
- x = (double)(lfo.phase + lfo.vphase * (subindex >> 1)) / 4096.0;
+ x = (double)(lfo.phase + lfo.vphase * voice) / 4096.0;
y = 0.95 * sin(x * 2 * M_PI);
+ y = (voice * unit + (y + 1) / 2) / scw * 2 - 1;
}
else
{
- double ph = (double)(lfo.phase + lfo.vphase * (subindex >> 1)) / 4096.0;
+ double ph = (double)(lfo.phase + lfo.vphase * voice) / 4096.0;
x = 0.5 + 0.5 * sin(ph * 2 * M_PI);
y = subindex & 1 ? -0.75 : 0.75;
+ x = (voice * unit + x) / scw;
}
return true;
}
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list