1 #include <stdlib.h>
2 #include "soundpipe.h"
3 
sp_tenv_create(sp_tenv ** p)4 int sp_tenv_create(sp_tenv **p)
5 {
6     *p = malloc(sizeof(sp_tenv));
7     sp_tenv *pp = *p;
8     sp_tevent_create(&pp->te);
9     return SP_OK;
10 }
11 
sp_tenv_destroy(sp_tenv ** p)12 int sp_tenv_destroy(sp_tenv **p)
13 {
14     sp_tenv *pp = *p;
15     sp_tevent_destroy(&pp->te);
16     free(*p);
17     return SP_OK;
18 }
19 
sp_tenv_reinit(void * ud)20 static void sp_tenv_reinit(void *ud)
21 {
22     sp_tenv *env = ud;
23     env->pos = 0;
24     env->atk_end = env->sr * env->atk;
25     env->rel_start = env->sr * (env->atk + env->hold);
26     env->atk_slp = 1.0 / env->atk_end;
27     env->rel_slp = -1.0 / (env->sr * env->rel);
28     env->totaldur = env->sr * (env->atk + env->hold + env->rel);
29 }
30 
sp_tenv_comp(void * ud,SPFLOAT * out)31 static void sp_tenv_comp(void *ud, SPFLOAT *out)
32 {
33     sp_tenv *env = ud;
34     SPFLOAT sig = 0;
35     uint32_t pos = env->pos;
36     *out = 0.0;
37     if(pos < env->atk_end){
38         sig = env->last + env->atk_slp;
39     }else if (pos < env->rel_start){
40         sig = 1.0;
41     }else if (pos < env->totaldur){
42         sig = env->last + env->rel_slp;
43     }else{
44         sig = 0.0;
45     }
46     sig = (sig > 1.0) ? 1.0 : sig;
47     sig = (sig < 0.0) ? 0.0 : sig;
48 
49     /* Internal input signal mode */
50     if(env->sigmode) {
51         *out = env->input * sig;
52     } else {
53         *out = sig;
54     }
55 
56 
57     env->pos++;
58     env->last = sig;
59 }
60 
sp_tenv_init(sp_data * sp,sp_tenv * p)61 int sp_tenv_init(sp_data *sp, sp_tenv *p)
62 {
63     p->pos = 0;
64     p->last = 0;
65     p->atk = 0.1;
66     p->hold = 0.3;
67     p->rel = 0.2;
68     p->sigmode = 0;
69     p->input = 0;
70 
71     p->sr = sp->sr;
72     p->atk_end = p->sr * p->atk;
73     p->rel_start = p->sr * (p->atk + p->hold);
74     p->atk_slp = 1.0 / p->atk_end;
75     p->rel_slp = -1.0 / (p->sr * p->rel);
76     p->totaldur = p->sr * (p->atk + p->hold + p->rel);
77     sp_tevent_init(sp, p->te, sp_tenv_reinit, sp_tenv_comp, p);
78     return SP_OK;
79 }
80 
sp_tenv_compute(sp_data * sp,sp_tenv * p,SPFLOAT * in,SPFLOAT * out)81 int sp_tenv_compute(sp_data *sp, sp_tenv *p, SPFLOAT *in, SPFLOAT *out)
82 {
83     sp_tevent_compute(sp, p->te, in, out);
84     return SP_OK;
85 }
86