Commit 31eb243b authored by Jonathan Wilkes's avatar Jonathan Wilkes

Merge branch 'port-disis_munger'

parents 02a88eda ecada8c2
#include "ADSR.h"
t_float stk_ADSR_tick(t_stk_ADSR *x)
{
switch (x->state)
{
case ATTACK:
x->value += x->attackRate;
if (x->value >= x->target)
{
x->value = x->target;
x->target = x->sustainLevel;
x->state = DECAY;
}
break;
case DECAY:
if (x->value > x->sustainLevel)
{
x->value -= x->decayRate;
if (x->value <= x->sustainLevel)
{
x->value = x->sustainLevel;
x->state = SUSTAIN;
}
}
else
{
x->value += x->decayRate; // attack target < sustain level
if (x->value >= x->sustainLevel)
{
x->value = x->sustainLevel;
x->state = SUSTAIN;
}
}
break;
case RELEASE:
x->value -= x->releaseRate;
if (x->value <= 0.0)
{
x->value = 0.0;
x->state = IDLE;
}
}
return x->value;
}
void stk_ADSR_init(t_stk_ADSR *x)
{
x->target = 0.0;
x->value = 0.0;
x->attackRate = 0.001;
x->decayRate = 0.001;
x->releaseRate = 0.005;
x->releaseTime = -1.0;
x->sustainLevel = 0.5;
x->state = IDLE;
x->sampleRate = 44100;
}
t_env_state stk_ADSR_getState(t_stk_ADSR *x)
{
return x->state;
}
void stk_ADSR_sampleRateChanged(t_stk_ADSR *x, t_float newRate,
t_float oldRate)
{
x->attackRate = oldRate * x->attackRate / newRate;
x->decayRate = oldRate * x->decayRate / newRate;
x->releaseRate = oldRate * x->releaseRate / newRate;
}
void stk_ADSR_setSampleRate(t_stk_ADSR *x, t_float newRate)
{
x->sampleRate = newRate;
}
void stk_ADSR_keyOn(t_stk_ADSR *x)
{
if (x->target <= 0.0) x->target = 1.0;
x->state = ATTACK;
}
void stk_ADSR_keyOff(t_stk_ADSR *x)
{
x->target = 0.0;
x->state = RELEASE;
// FIXED October 2010 - Nick Donaldson
// Need to make release rate relative to current value!!
// Only update if we have set a TIME rather than a RATE,
// in which case releaseTime will be -1
if (x->releaseTime > 0.0)
x->releaseRate = x->value / (x->releaseTime * x->sampleRate);
}
void stk_ADSR_setAttackRate(t_stk_ADSR *x, t_float rate)
{
if (rate < 0.0)
fprintf(stderr, "stk_ADSR_setAttackRate: argument must be >= 0.0!");
x->attackRate = rate;
}
void stk_ADSR_setAttackTarget(t_stk_ADSR *x, t_float target)
{
if (target < 0.0)
{
fprintf(stderr, "ADSR::setAttackTarget: negative target not allowed!");
}
x->target = target;
}
void stk_ADSR_setDecayRate(t_stk_ADSR *x, t_float rate)
{
if (rate < 0.0)
fprintf(stderr, "ADSR::setDecayRate: negative rates not allowed!");
x->decayRate = rate;
}
void stk_ADSR_setSustainLevel(t_stk_ADSR *x, t_float level)
{
if (level < 0.0)
fprintf(stderr, "ADSR::setSustainLevel: negative level not allowed!");
x->sustainLevel = level;
}
void stk_ADSR_setReleaseRate(t_stk_ADSR *x, t_float rate)
{
if (rate < 0.0)
fprintf(stderr, "ADSR::setReleaseRate: negative rates not allowed!");
x->releaseRate = rate;
// Set to negative value so we don't update the release rate on keyOff()
x->releaseTime = -1.0;
}
void stk_ADSR_setAttackTime(t_stk_ADSR *x, t_float time)
{
if (time <= 0.0)
fprintf(stderr,
"ADSR::setAttackTime: negative or zero times not allowed!");
x->attackRate = 1.0 / (time * x->sampleRate);
}
void stk_ADSR_setDecayTime(t_stk_ADSR *x, t_float time)
{
if (time <= 0.0)
fprintf(stderr,
"ADSR::setDecayTime: negative or zero times not allowed!");
x->decayRate = (1.0 - x->sustainLevel) / (time * x->sampleRate);
}
void stk_ADSR_setReleaseTime(t_stk_ADSR *x, t_float time)
{
if (time <= 0.0)
fprintf(stderr,
"ADSR::setReleaseTime: negative or zero times not allowed!");
x->releaseRate = x->sustainLevel / (time * x->sampleRate);
x->releaseTime = time;
}
void stk_ADSR_setAllTimes(t_stk_ADSR *x, t_float aTime, t_float dTime,
t_float sLevel, t_float rTime)
{
stk_ADSR_setAttackTime(x, aTime);
stk_ADSR_setSustainLevel(x, sLevel);
stk_ADSR_setDecayTime(x, dTime);
stk_ADSR_setReleaseTime(x, rTime);
}
void stk_ADSR_setTarget(t_stk_ADSR *x, t_float target)
{
if (target < 0.0)
fprintf(stderr, "ADSR::setTarget: negative target not allowed!");
x->target = target;
stk_ADSR_setSustainLevel(x, x->target);
if (x->value < x->target) x->state = ATTACK;
if (x->value > x->target) x->state = DECAY;
}
void stk_ADSR_setValue(t_stk_ADSR *x, t_float value)
{
x->state = SUSTAIN;
x->target = value;
x->value = value;
stk_ADSR_setSustainLevel(x, value);
}
#include "m_pd.h"
/* port of stk's ADSR class to C */
/* original class notes */
/***************************************************/
/*! \class ADSR
\brief STK ADSR envelope class.
This class implements a traditional ADSR (Attack, Decay, Sustain,
Release) envelope. It responds to simple keyOn and keyOff
messages, keeping track of its state. The \e state = ADSR::IDLE
before being triggered and after the envelope value reaches 0.0 in
the ADSR::RELEASE state. All rate, target and level settings must
be non-negative. All time settings are in seconds and must be
positive.
by Perry R. Cook and Gary P. Scavone, 1995--2017.
*/
/***************************************************/
/* ADSR envelope states. */
typedef enum {
ATTACK, /* Attack */
DECAY, /* Decay */
SUSTAIN, /* Sustain */
RELEASE, /* Release */
IDLE /* Before attack / after release */
} t_env_state;
typedef struct _stk_ADSR {
t_env_state state;
t_float value;
t_float target;
t_float attackRate;
t_float decayRate;
t_float releaseRate;
t_float releaseTime;
t_float sustainLevel;
// Currently setting this is dsp_add routine...
t_float sampleRate;
} t_stk_ADSR;
/* initialize the struct members to sane values */
void stk_ADSR_init(t_stk_ADSR *x);
/* set the sample rate */
void stk_ADSR_setSampleRate(t_stk_ADSR *x, t_float newRate);
/* Set target = 1, state = ATTACK. */
void stk_ADSR_keyOn(t_stk_ADSR *x);
/* Set target = 0, state = RELEASE. */
void stk_ADSR_keyOff(t_stk_ADSR *x);
/* Set the attack rate (gain / sample). */
void stk_ADSR_setAttackRate(t_stk_ADSR *x, t_float rate);
/* Set the target value for the attack (default = 1.0). */
void stk_ADSR_setAttackTarget(t_stk_ADSR *x, t_float target);
/* Set the decay rate (gain / sample). */
void stk_ADSR_setDecayRate(t_stk_ADSR *x, t_float rate);
/* Set the sustain level. */
void stk_ADSR_setSustainLevel(t_stk_ADSR *x, t_float level);
/* Set the release rate (gain / sample). */
void stk_ADSR_setReleaseRate(t_stk_ADSR *x, t_float rate);
/* Set the attack rate based on a time duration (seconds). */
void stk_ADSR_setAttackTime(t_stk_ADSR *x, t_float time);
/* Set the decay rate based on a time duration (seconds). */
void stk_ADSR_setDecayTime(t_stk_ADSR *x, t_float time);
/* Set the release rate based on a time duration (seconds). */
void stk_ADSR_setReleaseTime(t_stk_ADSR *x, t_float time);
/* Set sustain level and attack, decay, and release time durations (seconds). */
void stk_ADSR_setAllTimes(t_stk_ADSR *x, t_float aTime, t_float dTime,
t_float sLevel, t_float rTime);
/* Set a sustain target value and attack or decay from current value
to target. */
void stk_ADSR_setTarget(t_stk_ADSR *x, t_float target);
/* Return the current envelope state (ATTACK, DECAY, SUSTAIN, RELEASE, IDLE).*/
t_env_state stk_ADSR_getState(t_stk_ADSR *x);
/* Set to state = ADSR::SUSTAIN with current and target values of value. */
void stk_ADSR_setValue(t_stk_ADSR *x, t_float value);
/* Compute and return one output sample. */
t_float stk_ADSR_tick(t_stk_ADSR *x);
This diff is collapsed.
This diff is collapsed.
......@@ -3,6 +3,7 @@
lib.name = disis
class.sources = disis_phasor~.c
disis_munger~.class.sources = disis_munger.c ADSR.c
define forLinux
class.sources += disis_netsend.c disis_netreceive.c
disis_wiimote.class.sources = disis_wiimote.c
......@@ -12,7 +13,7 @@ define forDarwin
class.sources += disis_netsend.c disis_netreceive.c
endef
datafiles = disis_phasor~-help.pd disis_netsend-help.pd disis_netreceive-help.pd disis_wiimote-help.pd disis_wiimote_legacy.pd README patch_name-help.pd patch_name.pd disis-meta.pd
datafiles = disis_munger~-help.pd disis_phasor~-help.pd disis_netsend-help.pd disis_netreceive-help.pd disis_wiimote-help.pd disis_wiimote_legacy.pd README patch_name-help.pd patch_name.pd disis-meta.pd
# IMPORTANT! disis_wiimote requires a custom L2Ork version of cwiid library
# For the time being we statically link to a L2Ork version of cwiid library
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment