Dear devs,<br><br>After a bug in Envelope was found I tried my hand at fixing it which brought yet more issues to the surface.<br><br>I also tried to fix those but I&#39;m not sure what this might now break so I&#39;m out of my depth.
<br><br>Details and code are here;<br><a href="http://electro-music.com/forum/viewtopic.php?p=142167#142167">http://electro-music.com/forum/viewtopic.php?p=142167#142167</a><br>Documentation of the various things that went wrong with the official version are above that post.
<br><br>A copy of what I arrived at follows below, I hope this is of some use, if my code isn&#39;t I can at least say we now have a clearer image of exactly what the issue is and I had some fun.<br><br>Yours,<br>Kas.<br>
<br>==================================================================<br>/***************************************************/
<br>
/*! \class Envelope
<br>
&nbsp; &nbsp; \brief STK envelope base class.
<br>

<br>
&nbsp; &nbsp; This class implements a simple envelope
<br>
&nbsp; &nbsp; generator which is capable of ramping to
<br>
&nbsp; &nbsp; a target value by a specified \e rate.
<br>
&nbsp; &nbsp; It also responds to simple \e keyOn and
<br>
&nbsp; &nbsp; \e keyOff messages, ramping to 1.0 on
<br>
&nbsp; &nbsp; keyOn and to 0.0 on keyOff.
<br>

<br>
&nbsp; &nbsp; by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
<br>
----------------
<br>
&nbsp; &nbsp;This is a experimental &quot;fixed&quot; version by Kassen who doesn&#39;t speak C++.
<br>
&nbsp; &nbsp;Don&#39;t use this for anything important untill the official devs
<br>
&nbsp; &nbsp; have had a look at it, Don&#39;t say I didn&#39;t warn you.
<br>
&nbsp; &nbsp;this is a modification on ugen_stk.cpp for chuck <a href="http://1.2.1.0">1.2.1.0</a>,
<br>
&nbsp; &nbsp;which is covered by the GPL (and so so is this).
<br>

<br>

<br>
*/
<br>
/***************************************************/
<br>

<br>
#include &lt;stdio.h&gt;
<br>

<br>
Envelope :: Envelope(void) : Stk()
<br>
{
<br>
&nbsp; target = (MY_FLOAT) 0.0;
<br>
&nbsp; value = (MY_FLOAT) 0.0;
<br>
&nbsp; rate = (MY_FLOAT) 0.001;
<br>
&nbsp; m_target = 1.0;
<br>
&nbsp; m_time = rate * Stk::sampleRate();
<br>
&nbsp; state = 0;
<br>
}
<br>

<br>
Envelope :: ~Envelope(void)
<br>
{&nbsp; &nbsp; 
<br>
}
<br>

<br>
void Envelope :: keyOn(void)
<br>
{
<br>
&nbsp; target = (MY_FLOAT) m_target;
<br>
&nbsp; if (value != target) state = 1;
<br>
&nbsp; setTime( m_time );
<br>
}
<br>

<br>
void Envelope :: keyOff(void)
<br>
{
<br>
&nbsp; target = (MY_FLOAT) 0.0;
<br>
&nbsp; if (value != target) state = 1;
<br>
&nbsp; setTime( m_time );
<br>
}
<br>

<br>
void Envelope :: setRate(MY_FLOAT aRate)
<br>
{
<br>
&nbsp; if (aRate &lt; 0.0) {
<br>
&nbsp; &nbsp; printf(&quot;[chuck](via Envelope): negative rates not allowed ... correcting!\n&quot;);
<br>
&nbsp; &nbsp; rate = -aRate;
<br>
&nbsp; }
<br>
&nbsp; else
<br>
&nbsp; &nbsp; rate = aRate;
<br>
&nbsp; &nbsp; 
<br>
&nbsp; m_time = (target - value) / (rate * Stk::sampleRate());
<br>
&nbsp; if( m_time &lt; 0.0 ) m_time = -m_time;
<br>
}
<br>

<br>
void Envelope :: setTime(MY_FLOAT aTime)
<br>
{
<br>
&nbsp; if (aTime &lt; 0.0) {
<br>
&nbsp; &nbsp; printf(&quot;[chuck](via Envelope): negative times not allowed ... correcting!\n&quot;);
<br>
&nbsp; &nbsp; rate = (target -value) / (-aTime * Stk::sampleRate());
<br>
&nbsp; }
<br>
&nbsp; else if( aTime == 0.0 )
<br>
&nbsp; &nbsp; rate = FLT_MAX;
<br>
&nbsp; else
<br>
&nbsp; &nbsp; rate = (target - value) / (aTime * Stk::sampleRate());
<br>
&nbsp; &nbsp; if (rate &lt; 0.0 )&nbsp; rate = -rate; 
<br>

<br>
&nbsp; m_time = aTime;
<br>
&nbsp; if( m_time &lt; 0.0 ) m_time = -m_time;
<br>
}
<br>

<br>
void Envelope :: setTarget(MY_FLOAT aTarget)
<br>
{
<br>
&nbsp; target = m_target = aTarget;
<br>
&nbsp; if (value != target) state = 1;
<br>
&nbsp; 
<br>
&nbsp; // set time
<br>
&nbsp; setTime( m_time );
<br>
}
<br>

<br>
void Envelope :: setValue(MY_FLOAT aValue)
<br>
{
<br>
&nbsp; state = 0;
<br>
&nbsp; target = aValue;
<br>
&nbsp; value = aValue;
<br>
}
<br>

<br>
int Envelope :: getState(void) const
<br>
{
<br>
&nbsp; return state;
<br>
}
<br>

<br>
MY_FLOAT Envelope :: tick(void)
<br>
{
<br>
&nbsp; if (state) {
<br>
&nbsp; &nbsp; if (target &gt; value) {
<br>
&nbsp; &nbsp; &nbsp; value += rate;
<br>
&nbsp; &nbsp; &nbsp; if (value &gt;= target) {
<br>
&nbsp; &nbsp; &nbsp; &nbsp; value = target;
<br>
&nbsp; &nbsp; &nbsp; &nbsp; state = 0;
<br>
&nbsp; &nbsp; &nbsp; }
<br>
&nbsp; &nbsp; }
<br>
&nbsp; &nbsp; else {
<br>
&nbsp; &nbsp; &nbsp; value -= rate;
<br>
&nbsp; &nbsp; &nbsp; if (value &lt;= target) {
<br>
&nbsp; &nbsp; &nbsp; &nbsp; value = target;
<br>
&nbsp; &nbsp; &nbsp; &nbsp; state = 0;
<br>
&nbsp; &nbsp; &nbsp; }
<br>
&nbsp; &nbsp; }
<br>
&nbsp; }
<br>
&nbsp; return value;
<br>
}
<br>

<br>
MY_FLOAT *Envelope :: tick(MY_FLOAT *vec, unsigned int vectorSize)
<br>
{
<br>
&nbsp; for (unsigned int i=0; i&lt;vectorSize; i++)
<br>
&nbsp; &nbsp; vec[i] = tick();
<br>

<br>
&nbsp; return vec;
<br>
}
<br>

<br>
MY_FLOAT Envelope :: lastOut(void) const
<br>
{
<br>
&nbsp; return value;
<br>
}
<br>