Dear devs,
After a bug in Envelope was found I tried my hand at fixing it which brought
yet more issues to the surface.
I also tried to fix those but I'm not sure what this might now break so I'm
out of my depth.
Details and code are here;
http://electro-music.com/forum/viewtopic.php?p=142167#142167
Documentation of the various things that went wrong with the official
version are above that post.
A copy of what I arrived at follows below, I hope this is of some use, if my
code isn't I can at least say we now have a clearer image of exactly what
the issue is and I had some fun.
Yours,
Kas.
==================================================================
/***************************************************/
/*! \class Envelope
\brief STK envelope base class.
This class implements a simple envelope
generator which is capable of ramping to
a target value by a specified \e rate.
It also responds to simple \e keyOn and
\e keyOff messages, ramping to 1.0 on
keyOn and to 0.0 on keyOff.
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
----------------
This is a experimental "fixed" version by Kassen who doesn't speak C++.
Don't use this for anything important untill the official devs
have had a look at it, Don't say I didn't warn you.
this is a modification on ugen_stk.cpp for chuck 1.2.1.0,
which is covered by the GPL (and so so is this).
*/
/***************************************************/
#include
Envelope :: Envelope(void) : Stk()
{
target = (MY_FLOAT) 0.0;
value = (MY_FLOAT) 0.0;
rate = (MY_FLOAT) 0.001;
m_target = 1.0;
m_time = rate * Stk::sampleRate();
state = 0;
}
Envelope :: ~Envelope(void)
{
}
void Envelope :: keyOn(void)
{
target = (MY_FLOAT) m_target;
if (value != target) state = 1;
setTime( m_time );
}
void Envelope :: keyOff(void)
{
target = (MY_FLOAT) 0.0;
if (value != target) state = 1;
setTime( m_time );
}
void Envelope :: setRate(MY_FLOAT aRate)
{
if (aRate < 0.0) {
printf("[chuck](via Envelope): negative rates not allowed ...
correcting!\n");
rate = -aRate;
}
else
rate = aRate;
m_time = (target - value) / (rate * Stk::sampleRate());
if( m_time < 0.0 ) m_time = -m_time;
}
void Envelope :: setTime(MY_FLOAT aTime)
{
if (aTime < 0.0) {
printf("[chuck](via Envelope): negative times not allowed ...
correcting!\n");
rate = (target -value) / (-aTime * Stk::sampleRate());
}
else if( aTime == 0.0 )
rate = FLT_MAX;
else
rate = (target - value) / (aTime * Stk::sampleRate());
if (rate < 0.0 ) rate = -rate;
m_time = aTime;
if( m_time < 0.0 ) m_time = -m_time;
}
void Envelope :: setTarget(MY_FLOAT aTarget)
{
target = m_target = aTarget;
if (value != target) state = 1;
// set time
setTime( m_time );
}
void Envelope :: setValue(MY_FLOAT aValue)
{
state = 0;
target = aValue;
value = aValue;
}
int Envelope :: getState(void) const
{
return state;
}
MY_FLOAT Envelope :: tick(void)
{
if (state) {
if (target > value) {
value += rate;
if (value >= target) {
value = target;
state = 0;
}
}
else {
value -= rate;
if (value <= target) {
value = target;
state = 0;
}
}
}
return value;
}
MY_FLOAT *Envelope :: tick(MY_FLOAT *vec, unsigned int vectorSize)
{
for (unsigned int i=0; i