TEnv
Overview
Triggerable linear envelope generator with attack, hold, and release. Ported from Soundpipe.
This is a bit of a mess at the moment.
Top Files
<<tenv.h>>=
#ifndef SK_TENV_H
#define SK_TENV_H
#ifndef SKFLT
#define SKFLT float
#endif
<<typedefs>>
#ifdef SK_TENV_PRIV
<<structs>>
#endif
<<funcdefs>>
#endif
<<tenv.c>>=
#define SK_TENV_PRIV
#include "tenv.h"
<<funcs>>
Struct and Initialization
<<typedefs>>=
typedef struct sk_tenv sk_tenv;
<<structs>>=
struct sk_tenv {
unsigned long pos, atk_end, rel_start, totaldur;
SKFLT atk, rel, hold;
SKFLT atk_slp, rel_slp;
SKFLT last;
int sigmode;
SKFLT input;
int started;
int sr;
};
<<funcdefs>>=
void sk_tenv_init(sk_tenv *te, int sr);
<<funcs>>=
void sk_tenv_init(sk_tenv *te, int sr)
{
te->pos = 0;
te->last = 0;
te->atk = 0.1;
te->hold = 0.3;
te->rel = 0.2;
te->sigmode = 0;
te->input = 0;
te->sr = sr;
te->atk_end = te->sr * te->atk;
te->rel_start = te->sr * (te->atk + te->hold);
te->atk_slp = 1.0 / te->atk_end;
te->rel_slp = -1.0 / (te->sr * te->rel);
te->totaldur = sr * (te->atk + te->hold + te->rel);
te->started = 0;
}
Compute
<<funcdefs>>=
SKFLT sk_tenv_tick(sk_tenv *te, SKFLT trig);
<<funcs>>=
<<reinit>>
<<envelope>>
SKFLT sk_tenv_tick(sk_tenv *te, SKFLT trig)
{
SKFLT out;
out = 0;
if (trig != 0) {
reinit(te);
te->started = 1;
}
if (te->started) out = envelope(te);
return out;
}
<<envelope>>=
static SKFLT envelope(sk_tenv *env)
{
SKFLT sig;
unsigned long pos;
SKFLT out;
out = 0;
sig = 0;
pos = env->pos;
if (pos < env->atk_end) {
sig = env->last + env->atk_slp;
} else if (pos < env->rel_start) {
sig = 1.0;
} else if (pos < env->totaldur) {
sig = env->last + env->rel_slp;
} else{
sig = 0.0;
}
sig = (sig > 1.0) ? 1.0 : sig;
sig = (sig < 0.0) ? 0.0 : sig;
/* Internal input signal mode */
if (env->sigmode) {
out = env->input * sig;
} else {
out = sig;
}
env->pos++;
env->last = sig;
return out;
}
<<reinit>>=
static void reinit(sk_tenv *te)
{
te->pos = 0;
te->atk_end = te->sr * te->atk;
te->rel_start = te->sr * (te->atk + te->hold);
te->atk_slp = 1.0 / te->atk_end;
te->rel_slp = -1.0 / (te->sr * te->rel);
te->totaldur = te->sr * (te->atk + te->hold + te->rel);
}
Parameters
<<funcdefs>>=
void sk_tenv_attack(sk_tenv *te, SKFLT atk);
<<funcs>>=
void sk_tenv_attack(sk_tenv *te, SKFLT atk)
{
te->atk = atk;
}
<<funcdefs>>=
void sk_tenv_hold(sk_tenv *te, SKFLT hold);
<<funcs>>=
void sk_tenv_hold(sk_tenv *te, SKFLT hold)
{
te->hold = hold;
}
<<funcdefs>>=
void sk_tenv_release(sk_tenv *te, SKFLT rel);
<<funcs>>=
void sk_tenv_release(sk_tenv *te, SKFLT rel)
{
te->rel = rel;
}