[SCM] calf/master: + Envelope code: added Doxygen documentation

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:37:45 UTC 2013


The following commit has been merged in the master branch:
commit 644c65f4ea9b1cebfd0cd87da51f615ae6fa8189
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Thu Oct 16 22:13:58 2008 +0000

    + Envelope code: added Doxygen documentation
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@336 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/src/calf/Makefile.am b/src/calf/Makefile.am
index ba6fed5..334ae1a 100644
--- a/src/calf/Makefile.am
+++ b/src/calf/Makefile.am
@@ -2,7 +2,7 @@ calfdir = $(includedir)/calf
 
 calf_HEADERS = audio_fx.h benchmark.h biquad.h buffer.h custom_ctl.h \
     ctl_curve.h ctl_keyboard.h \
-    delay.h fft.h fixed_point.h giface.h gui.h inertia.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 \
diff --git a/src/calf/envelope.h b/src/calf/envelope.h
new file mode 100644
index 0000000..4f0c375
--- /dev/null
+++ b/src/calf/envelope.h
@@ -0,0 +1,185 @@
+/* Calf DSP Library
+ * ADSR envelope class (and other envelopes in future)
+ *
+ * Copyright (C) 2007-2008 Krzysztof Foltman
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __CALF_ENVELOPE_H
+#define __CALF_ENVELOPE_H
+
+#include "primitives.h"
+
+namespace synth {
+
+/// Rate-based ADSR 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.
+class adsr
+{
+public:
+    enum env_state { 
+        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)
+        RELEASE, ///< release - fall from sustain (or pre-sustain) level to 0
+        LOCKDECAY  ///< locked decay 
+    };
+    
+    /// Current envelope stage
+    env_state state;
+    /// @note these are *rates*, not times
+    double attack, decay, sustain, release;
+    /// Requested release time (not the rate!) in frames, used for recalculating the rate if sustain is changed
+    double release_time;
+    /// Current envelope (output) level
+    double value;
+    /// Release rate used for the current note (calculated from this note's sustain level, and not the current sustain level,
+    /// which may have changed after note has been released)
+    double thisrelease;
+    /// Sustain level used for the current note (used to calculate release rate if sustain changed during release stage
+    /// of the current note)
+    double thiss;
+    
+    adsr()
+    {
+        attack = decay = sustain = release = thisrelease = thiss = 0.f;
+        reset();
+    }
+    /// Stop (reset) the envelope
+    inline void reset()
+    {
+        value = 0.f;
+        thiss = 0.f;
+        state = STOP;
+    }
+    /// Set the envelope parameters (updates rate member variables based on values passed)
+    /// @param a attack time
+    /// @param d decay time
+    /// @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)
+    {
+        attack = 1.0 / (a * er);
+        decay = (1 - s) / (d * er);
+        sustain = s;
+        release_time = r * er;
+        release = s / release_time;
+        // in release:
+        // lock thiss setting (start of release for current note) and unlock thisrelease setting (current note's release rate)
+        if (state != RELEASE)
+            thiss = s;
+        else
+            thisrelease = thiss / release_time;
+    }
+    /// @retval true if envelope is in released state (forced decay, release or stopped)
+    inline bool released() const
+    {
+        return state == LOCKDECAY || state == RELEASE || state == STOP;
+    }
+    /// @retval true if envelope is stopped (has not been started or has run till its end)
+    inline bool stopped() const
+    {
+        return state == STOP;
+    }
+    /// Start the envelope
+    inline void note_on()
+    {
+        state = ATTACK;
+        thiss = sustain;
+    }
+    /// Release the envelope
+    inline void note_off()
+    {
+        // Do nothing if envelope is already stopped
+        if (state == STOP)
+            return;
+        // XXXKF what if envelope is already released? (doesn't happen in any current synth, but who knows?)
+        // Raise sustain value if it has been changed... I'm not sure if it's needed
+        thiss = std::max(sustain, value);
+        // Calculate release rate from sustain level
+        thisrelease = thiss / release_time;
+        // we're in attack or decay, and if decay is faster than release
+        if (value > sustain && decay > thisrelease) {
+            // use standard release time later (because we'll be switching at sustain point)
+            thisrelease = release;
+            state = LOCKDECAY;
+        } else {
+            // in attack/decay, but use fixed release time
+            // in case value fell below sustain, assume it didn't (for the purpose of calculating release rate only)
+            state = RELEASE;
+        }
+    }
+    /// Calculate next envelope value
+    inline void advance()
+    {
+        // XXXKF This may use a state array instead of a switch some day (at least for phases other than attack and possibly sustain)
+        switch(state)
+        {
+        case ATTACK:
+            value += attack;
+            if (value >= 1.0) {
+                value = 1.0;
+                state = DECAY;
+            }
+            break;
+        case DECAY:
+            value -= decay;
+            if (value < sustain)
+            {
+                value = sustain;
+                state = SUSTAIN;
+            }
+            break;
+        case LOCKDECAY:
+            value -= decay;
+            if (value < sustain)
+            {
+                if (value < 0.f)
+                    value = 0.f;
+                state = RELEASE;
+                thisrelease = release;
+            }
+            break;
+        case SUSTAIN:
+            value = sustain;
+            if (value < 0.00001f) {
+                value = 0;
+                state = STOP;
+            }
+            break;
+        case RELEASE:
+            value -= thisrelease;
+            if (value <= 0.f) {
+                value = 0.f;
+                state = STOP;
+            }
+            break;
+        case STOP:
+            value = 0.f;
+            break;
+        }
+    }
+};
+
+};
+
+#endif
+
+
diff --git a/src/calf/synth.h b/src/calf/synth.h
index ef3622d..c2c58cc 100644
--- a/src/calf/synth.h
+++ b/src/calf/synth.h
@@ -182,10 +182,17 @@ public:
 /// @todo it would make sense to support all notes off controller too
 struct basic_synth {
 protected:
+    /// Current sample rate
     int sample_rate;
-    bool hold, sostenuto;
+    /// Hold pedal state
+    bool hold;
+    /// Sostenuto pedal state
+    bool sostenuto;
+    /// Voices currently playing
     std::list<synth::voice *> active_voices;
+    /// Voices allocated, but not used
     std::stack<synth::voice *> unused_voices;
+    /// Gate values for all 128 MIDI notes
     std::bitset<128> gate;
 
     void kill_note(int note, int vel, bool just_one);
@@ -209,124 +216,6 @@ public:
     virtual ~basic_synth();
 };
 
-// temporarily here, will be moved to separate file later
-// this is a weird envelope and perhaps won't turn out to
-// be a good idea in the long run, still, worth trying
-class adsr
-{
-public:
-    enum env_state { STOP, ATTACK, DECAY, SUSTAIN, RELEASE, LOCKDECAY };
-    
-    env_state state;
-    // note: these are *rates*, not times
-    double attack, decay, sustain, release, release_time;
-    double value, thisrelease, thiss;
-    
-    adsr()
-    {
-        attack = decay = sustain = release = thisrelease = thiss = 0.f;
-        reset();
-    }
-    inline void reset()
-    {
-        value = 0.f;
-        thiss = 0.f;
-        state = STOP;
-    }
-    inline void set(float a, float d, float s, float r, float er)
-    {
-        attack = 1.0 / (a * er);
-        decay = (1 - s) / (d * er);
-        sustain = s;
-        release_time = r * er;
-        release = s / release_time;
-        // in release:
-        // lock thiss setting (start of release for current note) and unlock thisrelease setting (current note's release rate)
-        if (state != RELEASE)
-            thiss = s;
-        else
-            thisrelease = thiss / release_time;
-    }
-    inline bool released() const
-    {
-        return state == LOCKDECAY || state == RELEASE || state == STOP;
-    }
-    inline bool stopped() const
-    {
-        return state == STOP;
-    }
-    inline void note_on()
-    {
-        state = ATTACK;
-        thiss = sustain;
-    }
-    inline void note_off()
-    {
-        if (state == STOP)
-            return;
-        thiss = std::max(sustain, value);
-        thisrelease = thiss / release_time;
-        // we're in attack or decay, and if decay is faster than release
-        if (value > sustain && decay > thisrelease) {
-            // use standard release time later (because we'll be switching at sustain point)
-            thisrelease = release;
-            state = LOCKDECAY;
-        } else {
-            // in attack/decay, but use fixed release time
-            // in case value fell below sustain, assume it didn't (for the purpose of calculating release rate only)
-            state = RELEASE;
-        }
-    }
-    inline void advance()
-    {
-        switch(state)
-        {
-        case ATTACK:
-            value += attack;
-            if (value >= 1.0) {
-                value = 1.0;
-                state = DECAY;
-            }
-            break;
-        case DECAY:
-            value -= decay;
-            if (value < sustain)
-            {
-                value = sustain;
-                state = SUSTAIN;
-            }
-            break;
-        case LOCKDECAY:
-            value -= decay;
-            if (value < sustain)
-            {
-                if (value < 0.f)
-                    value = 0.f;
-                state = RELEASE;
-                thisrelease = release;
-            }
-            break;
-        case SUSTAIN:
-            value = sustain;
-            if (value < 0.00001f) {
-                value = 0;
-                state = STOP;
-            }
-            break;
-        case RELEASE:
-            value -= thisrelease;
-            if (value <= 0.f) {
-                value = 0.f;
-                state = STOP;
-            }
-            break;
-        case STOP:
-            value = 0.f;
-            break;
-        }
-    }
-};
-
 
 }
 

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list