ref: 6a7c384764bf6d69450037b1fb2ff3dd96b5e81c
dir: /modules/tenv.c/
/* This code is placed in the public domain. */
#include <stdlib.h>
#include "soundpipe.h"
int sp_tenv_create(sp_tenv **p)
{
*p = malloc(sizeof(sp_tenv));
return SP_OK;
}
int sp_tenv_destroy(sp_tenv **p)
{
free(*p);
return SP_OK;
}
static void sp_tenv_reinit(void *ud)
{
sp_tenv *env = ud;
env->pos = 0;
env->atk_end = env->sr * env->atk;
env->rel_start = env->sr * (env->atk + env->hold);
env->atk_slp = 1.0 / env->atk_end;
env->rel_slp = -1.0 / (env->sr * env->rel);
env->totaldur = env->sr * (env->atk + env->hold + env->rel);
}
static void sp_tenv_comp(void *ud, SPFLOAT *out)
{
sp_tenv *env = ud;
SPFLOAT sig = 0;
uint32_t pos = env->pos;
*out = 0.0;
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;
}
int sp_tenv_init(sp_data *sp, sp_tenv *p)
{
p->pos = 0;
p->last = 0;
p->atk = 0.1;
p->hold = 0.3;
p->rel = 0.2;
p->sigmode = 0;
p->input = 0;
p->sr = sp->sr;
p->atk_end = p->sr * p->atk;
p->rel_start = p->sr * (p->atk + p->hold);
p->atk_slp = 1.0 / p->atk_end;
p->rel_slp = -1.0 / (p->sr * p->rel);
p->totaldur = p->sr * (p->atk + p->hold + p->rel);
p->started = 0;
return SP_OK;
}
int sp_tenv_compute(sp_data *sp, sp_tenv *p, SPFLOAT *in, SPFLOAT *out)
{
if (*in) {
sp_tenv_reinit(p);
p->started = 1;
}
if (p->started) sp_tenv_comp(p, out);
else *out = 0;
return SP_OK;
}