[SCM] calf/master: Implement a naive simulation of osc sync in Monosynth (Osc1 Stretch).
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:40:13 UTC 2013
The following commit has been merged in the master branch:
commit 89aa6c9134331623fbb4eb6aead7c8a08c99cc6f
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Sat May 8 18:42:12 2010 +0100
Implement a naive simulation of osc sync in Monosynth (Osc1 Stretch).
diff --git a/gui/gui-monosynth.xml b/gui/gui-monosynth.xml
index b0a547a..af0313a 100644
--- a/gui/gui-monosynth.xml
+++ b/gui/gui-monosynth.xml
@@ -45,6 +45,11 @@
<if cond="directlink">
<line-graph param="o1_wave" refresh="1" width="80" height="80" expand="0" fill="0"/>
</if>
+ <vbox>
+ <label param="o1_stretch" text="Stretch"/>
+ <knob param="o1_stretch"/>
+ <value param="o1_stretch"/>
+ </vbox>
</hbox>
</frame>
<frame label="Oscillator 2">
diff --git a/src/calf/metadata.h b/src/calf/metadata.h
index 4637afa..4254b45 100644
--- a/src/calf/metadata.h
+++ b/src/calf/metadata.h
@@ -109,6 +109,7 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
par_lforate, par_lfodelay, par_lfofilter, par_lfopitch, par_lfopw, par_mwhl_lfo, par_scaledetune,
par_env2tocutoff, par_env2tores, par_env2toamp,
par_env2attack, par_env2decay, par_env2sustain, par_env2fade, par_env2release,
+ par_stretch1,
param_count };
enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
enum { step_size = 64, step_shift = 6 };
@@ -133,6 +134,7 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
moddest_o2detune,
moddest_o1pw,
moddest_o2pw,
+ moddest_o1stretch,
moddest_count,
};
PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth")
diff --git a/src/calf/modules_synths.h b/src/calf/modules_synths.h
index 63e72ed..6f11e7f 100644
--- a/src/calf/modules_synths.h
+++ b/src/calf/modules_synths.h
@@ -69,6 +69,8 @@ public:
int32_t last_pwshift1;
/// Last value of phase shift for pulse width emulation for OSC2
int32_t last_pwshift2;
+ /// Last value of stretch for osc sync emulation for OSC1
+ int32_t last_stretch1;
int queue_note_on, stop_count, modwheel_value_int;
int legato;
dsp::adsr envelope1, envelope2;
diff --git a/src/calf/osc.h b/src/calf/osc.h
index ba01a2f..85af5e6 100644
--- a/src/calf/osc.h
+++ b/src/calf/osc.h
@@ -245,12 +245,12 @@ struct waveform_oscillator: public simple_oscillator
{
waveform = NULL;
}
+
+ /// Get the value from single oscillator at current position
inline float get()
{
uint32_t wpos = phase >> (32 - SIZE_BITS);
- float value = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
- phase += phasedelta;
- return value;
+ return dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
}
/// Add/substract two phase-shifted values
inline float get_phaseshifted(uint32_t shift, float mix)
@@ -259,9 +259,23 @@ struct waveform_oscillator: public simple_oscillator
float value1 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
wpos = (phase + shift) >> (32 - SIZE_BITS);
float value2 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], ((phase + shift) & (SCALE - 1)) * (1.0f / SCALE));
- float value = value1 + mix * value2;
+ return value1 + mix * value2;
+ }
+ /// Get the value of a hard synced osc (65536 = 1:1 ratio)
+ inline float get_phasedist(uint32_t sync, uint32_t shift, float mix)
+ {
+ uint32_t phase_mod = (uint64_t(phase) * sync >> 16);
+
+ uint32_t wpos = phase_mod >> (32 - SIZE_BITS);
+ float value1 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
+ wpos = (phase_mod + shift) >> (32 - SIZE_BITS);
+ float value2 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], ((phase + shift) & (SCALE - 1)) * (1.0f / SCALE));
+ return value1 + mix * value2;
+ }
+ /// One step
+ inline void advance()
+ {
phase += phasedelta;
- return value;
}
};
diff --git a/src/metadata.cpp b/src/metadata.cpp
index f7d5a41..bd3cca3 100644
--- a/src/metadata.cpp
+++ b/src/metadata.cpp
@@ -633,7 +633,7 @@ CALF_PORT_PROPS(monosynth) = {
{ 0, -2400, 2400, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "filter_sep", "Separation" },
{ 8000, -10800,10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "env2cutoff", "Env->Cutoff" },
{ 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "env2res", "Env->Res" },
- { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "env2amp", "Env->Amp" },
+ { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "env2amp", "Env->Amp" },
{ 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_a", "EG1 Attack" },
{ 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_d", "EG1 Decay" },
@@ -663,13 +663,15 @@ CALF_PORT_PROPS(monosynth) = {
{ 0, -10800,10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "adsr2_cutoff", "EG2->Cutoff" },
{ 0.3, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "adsr2_res", "EG2->Res" },
- { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "adsr2_amp", "EG2->Amp" },
+ { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "adsr2_amp", "EG2->Amp" },
{ 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_a", "EG2 Attack" },
{ 100, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_d", "EG2 Decay" },
{ 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr2_s", "EG2 Sustain" },
{ 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_f", "EG2 Fade" },
{ 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_r", "Release" },
+
+ { 1, 1, 16, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "o1_stretch", "Osc1 Stretch" },
};
////////////////////////////////////////////////////////////////////////////
diff --git a/src/monosynth.cpp b/src/monosynth.cpp
index 682fbb9..41011c5 100644
--- a/src/monosynth.cpp
+++ b/src/monosynth.cpp
@@ -32,8 +32,10 @@ static const char *monosynth_mod_src_names[] = {
"Velocity",
"Pressure",
"ModWheel",
- "Envelope",
- "LFO",
+ "Envelope 1",
+ "Envelope 2",
+ "LFO 1",
+ "LFO 2",
NULL
};
@@ -47,6 +49,7 @@ static const char *monosynth_mod_dest_names[] = {
"O2: Detune [ct]",
"O1: PW (%)",
"O2: PW (%)",
+ "O1: Stretch",
NULL
};
@@ -73,6 +76,7 @@ void monosynth_audio_module::activate() {
filter2.reset();
stack.clear();
last_pwshift1 = last_pwshift2 = 0;
+ last_stretch1 = 65536;
}
waveform_family<MONOSYNTH_WAVE_BITS> *monosynth_audio_module::waves;
@@ -220,7 +224,12 @@ bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int
wave = wave_saw;
float *waveform = waves[wave].original;
for (int i = 0; i < points; i++)
- data[i] = (sign * waveform[i * S / points] + waveform[(i * S / points + shift) & (S - 1)]) / (sign == -1 ? 1 : 2);
+ {
+ int pos = i * S / points;
+ if (index == par_wave1)
+ pos = int(pos * 1.0 * last_stretch1 / 65536.0 ) % S;
+ data[i] = (sign * waveform[pos] + waveform[(pos + shift) & (S - 1)]) / (sign == -1 ? 1 : 2);
+ }
return true;
}
if (index == par_filtertype) {
@@ -250,15 +259,20 @@ void monosynth_audio_module::calculate_buffer_oscs(float lfo)
{
int flag1 = (wave1 == wave_sqr);
int flag2 = (wave2 == wave_sqr);
+
int32_t shift1 = last_pwshift1;
int32_t shift2 = last_pwshift2;
+ int32_t stretch1 = last_stretch1;
int32_t shift_target1 = (int32_t)(0x78000000 * dsp::clip11(*params[par_pw1] + lfo * *params[par_lfopw] + 0.01f * moddest[moddest_o1pw]));
int32_t shift_target2 = (int32_t)(0x78000000 * dsp::clip11(*params[par_pw2] + lfo * *params[par_lfopw] + 0.01f * moddest[moddest_o2pw]));
+ int32_t stretch_target1 = (int32_t)(65536 * dsp::clip(*params[par_stretch1] + 0.01f * moddest[moddest_o1stretch], 1.f, 16.f));
int32_t shift_delta1 = ((shift_target1 >> 1) - (last_pwshift1 >> 1)) >> (step_shift - 1);
int32_t shift_delta2 = ((shift_target2 >> 1) - (last_pwshift2 >> 1)) >> (step_shift - 1);
+ int32_t stretch_delta1 = ((stretch_target1 >> 1) - (last_stretch1 >> 1)) >> (step_shift - 1);
last_lfov = lfo;
last_pwshift1 = shift_target1;
last_pwshift2 = shift_target2;
+ last_stretch1 = stretch_target1;
shift1 += (flag1 << 31);
shift2 += (flag2 << 31);
@@ -270,12 +284,13 @@ void monosynth_audio_module::calculate_buffer_oscs(float lfo)
for (uint32_t i = 0; i < step_size; i++)
{
- float osc1val = osc1.get_phaseshifted(shift1, mix1);
- float osc2val = osc2.get_phaseshifted(shift2, mix2);
- float wave = osc1val + (osc2val - osc1val) * cur_xfade;
- buffer[i] = wave;
+ //buffer[i] = lerp(osc1.get_phaseshifted(shift1, mix1), osc2.get_phaseshifted(shift2, mix2), cur_xfade);
+ buffer[i] = lerp(osc1.get_phasedist(stretch1, shift1, mix1), osc2.get_phaseshifted(shift2, mix2), cur_xfade);
+ osc1.advance();
+ osc2.advance();
shift1 += shift_delta1;
shift2 += shift_delta2;
+ stretch1 += stretch_delta1;
cur_xfade += xfade_step;
}
last_xfade = new_xfade;
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list