[chuck-dev] Envelope fixing

Kassen signal.automatique at gmail.com
Sun Sep 30 11:48:12 EDT 2007


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 <stdio.h>

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<vectorSize; i++)
    vec[i] = tick();

  return vec;
}

MY_FLOAT Envelope :: lastOut(void) const
{
  return value;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cs.princeton.edu/pipermail/chuck-dev/attachments/20070930/3443e087/attachment.htm 


More information about the chuck-dev mailing list