From 399ae691704d91f7e491755649b4b9ab0976062a Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Mon, 9 Mar 2009 22:03:59 +0000 Subject: [PATCH] + Wavetable: add Fade phase to envelopes --- gui/gui-wavetable.xml | 37 ++++++++++++++++++++++--------------- src/calf/envelope.h | 24 ++++++++++++++++++------ src/calf/metadata.h | 6 +++--- src/modules.cpp | 5 ++++- src/wavetable.cpp | 2 +- 5 files changed, 48 insertions(+), 26 deletions(-) diff --git a/gui/gui-wavetable.xml b/gui/gui-wavetable.xml index b697037..2591e15 100644 --- a/gui/gui-wavetable.xml +++ b/gui/gui-wavetable.xml @@ -39,7 +39,7 @@ - +
diff --git a/src/calf/envelope.h b/src/calf/envelope.h index a6fd843..7b213ab 100644 --- a/src/calf/envelope.h +++ b/src/calf/envelope.h @@ -25,7 +25,7 @@ namespace dsp { -/// Rate-based ADSR envelope class. Note that if release rate is slower than decay +/// Rate-based ADSFR envelope class. Note that if release rate is slower than decay /// rate, this envelope won't use release rate until output level falls below sustain level /// it's different to what certain hardware synth companies did, but it prevents the very /// un-musical (IMHO) behaviour known from (for example) SoundFont 2. @@ -36,15 +36,15 @@ public: STOP, ///< envelope is stopped ATTACK, ///< attack - rise from 0 to 1 DECAY, ///< decay - fall from 1 to sustain level - SUSTAIN, ///< sustain - remain at sustain level (unless sustain is 0 - then it gets stopped) + SUSTAIN, ///< sustain - remain at sustain level (unless sustain is 0 - then it gets stopped); with fade != 0 it goes towards 0% (positive fade) or 100% (negative fade) RELEASE, ///< release - fall from sustain (or pre-sustain) level to 0 - LOCKDECAY ///< locked decay + LOCKDECAY, ///< locked decay }; /// Current envelope stage env_state state; /// @note these are *rates*, not times - double attack, decay, sustain, release; + double attack, decay, sustain, release, fade; /// Requested release time (not the rate!) in frames, used for recalculating the rate if sustain is changed double release_time; /// Current envelope (output) level @@ -76,13 +76,18 @@ public: /// @param s sustain level /// @param r release time /// @param er Envelope (update) rate - inline void set(float a, float d, float s, float r, float er) + /// @param f fade time (if applicable) + inline void set(float a, float d, float s, float r, float er, float f = 0.f) { attack = 1.0 / (a * er); decay = (1 - s) / (d * er); sustain = s; release_time = r * er; release = s / release_time; + if (fabs(f) > small_value()) + fade = 1.0 / (f * er); + else + fade = 0.0; // in release: // lock thiss setting (start of release for current note) and unlock thisrelease setting (current note's release rate) if (state != RELEASE) @@ -161,7 +166,14 @@ public: } break; case SUSTAIN: - value = sustain; + if (fade != 0.f) + { + value -= fade; + if (value > 1.f) + value = 1.f; + } + else + value = sustain; if (value < 0.00001f) { value = 0; state = STOP; diff --git a/src/calf/metadata.h b/src/calf/metadata.h index 04cb704..334f3dd 100644 --- a/src/calf/metadata.h +++ b/src/calf/metadata.h @@ -268,9 +268,9 @@ struct wavetable_metadata: public plugin_metadata enum { par_o1wave, par_o1offset, par_o1transpose, par_o1detune, par_o1level, par_o2wave, par_o2offset, par_o2transpose, par_o2detune, par_o2level, - par_eg1attack, par_eg1decay, par_eg1sustain, par_eg1release, par_eg1velscl, - par_eg2attack, par_eg2decay, par_eg2sustain, par_eg2release, par_eg2velscl, - par_eg3attack, par_eg3decay, par_eg3sustain, par_eg3release, par_eg3velscl, + par_eg1attack, par_eg1decay, par_eg1sustain, par_eg1fade, par_eg1release, par_eg1velscl, + par_eg2attack, par_eg2decay, par_eg2sustain, par_eg2fade, par_eg2release, par_eg2velscl, + par_eg3attack, par_eg3decay, par_eg3sustain, par_eg3fade, par_eg3release, par_eg3velscl, param_count }; enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true }; enum { step_size = 64 }; diff --git a/src/modules.cpp b/src/modules.cpp index 5b8e422..a5111e9 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -559,19 +559,22 @@ CALF_PORT_PROPS(wavetable) = { { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_a", "EG1 Attack" }, { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_d", "EG1 Decay" }, { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr_s", "EG1 Sustain" }, + { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_f", "EG1 Fade" }, { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_r", "EG1 Release" }, { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr_v", "EG1 VelMod" }, { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr2_a", "EG2 Attack" }, { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | 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_KNOB | PF_UNIT_MSEC, NULL, "adsr2_f", "EG2 Fade" }, { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr2_r", "EG2 Release" }, { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr2_v", "EG2 VelMod" }, { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_a", "EG3 Attack" }, { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_d", "EG3 Decay" }, { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr3_s", "EG3 Sustain" }, - { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_r", "EG3 Release" }, + { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_f", "EG3 Fade" }, + { 50, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_r", "EG3 Release" }, { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr3_v", "EG3 VelMod" }, }; diff --git a/src/wavetable.cpp b/src/wavetable.cpp index b11cfdb..98b94f9 100644 --- a/src/wavetable.cpp +++ b/src/wavetable.cpp @@ -94,7 +94,7 @@ void wavetable_voice::render_block() float scl[EnvCount]; for (int j = 0; j < EnvCount; j++) { int o = j*espc; - envs[j].set(*params[md::par_eg1attack + o] * s, *params[md::par_eg1decay + o] * s, *params[md::par_eg1sustain + o], *params[md::par_eg1release + o] * s, sample_rate / BlockSize); + envs[j].set(*params[md::par_eg1attack + o] * s, *params[md::par_eg1decay + o] * s, *params[md::par_eg1sustain + o], *params[md::par_eg1release + o] * s, sample_rate / BlockSize, *params[md::par_eg1fade + o] * s); scl[j] = dsp::lerp(1.f, velocity, *params[md::par_eg1velscl + o]);; } -- 2.11.4.GIT