1 #include <stdlib.h>
2 #include <math.h>
3 #include "soundpipe.h"
4 
5 #ifndef max
6 #define max(a,b) (((a) > (b)) ? (a) : (b))
7 #endif
8 
9 #ifndef min
10 #define min(a,b) (((a) < (b)) ? (a) : (b))
11 #endif
12 
13 #ifndef dB
14 /* if below -100dB, set to -100dB to prevent taking log of zero */
15 #define dB(x) 20.0 * ((x) > 0.00001 ? log10(x) : log10(0.00001))
16 #endif
17 
18 #ifndef dB2lin
19 #define dB2lin(x)           pow( 10.0, (x) / 20.0 )
20 #endif
21 
sp_peaklim_create(sp_peaklim ** p)22 int sp_peaklim_create(sp_peaklim **p)
23 {
24     *p = malloc(sizeof(sp_peaklim));
25     return SP_OK;
26 }
27 
sp_peaklim_destroy(sp_peaklim ** p)28 int sp_peaklim_destroy(sp_peaklim **p)
29 {
30     free(*p);
31     return SP_OK;
32 }
33 
sp_peaklim_init(sp_data * sp,sp_peaklim * p)34 int sp_peaklim_init(sp_data *sp, sp_peaklim *p)
35 {
36     p->a1_r = 0;
37     p->b0_r = 1;
38     p->a1_a = 0;
39     p->b0_a = 1;
40     p->atk = 0.1;
41     p->rel = 0.1;
42     p->patk = -100;
43     p->prel = -100;
44     p->level = 0;
45     return SP_OK;
46 }
47 
sp_peaklim_compute(sp_data * sp,sp_peaklim * p,SPFLOAT * in,SPFLOAT * out)48 int sp_peaklim_compute(sp_data *sp, sp_peaklim *p, SPFLOAT *in, SPFLOAT *out)
49 {
50 
51     SPFLOAT db_gain = 0;
52     SPFLOAT gain = 0;
53 
54     /* change coefficients, if needed */
55 
56     if(p->patk != p->atk) {
57         p->patk = p->atk;
58 		p->a1_a = exp( -1.0 / ( p->rel * sp->sr ) );
59 		p->b0_a = 1 - p->a1_a;
60     }
61 
62     if(p->prel != p->rel) {
63         p->prel = p->rel;
64 		p->a1_r = exp( -1.0 / ( p->rel * sp->sr ) );
65 		p->b0_r = 1 - p->a1_r;
66     }
67 
68 
69     if ( fabs(*in) > p->level)
70         p->level += p->b0_a * ( fabs(*in) - p->level);
71     else
72         p->level += p->b0_r * ( fabs(*in) - p->level);
73 
74     db_gain = min(0.0, dB(dB2lin(p->thresh)/p->level));
75     gain = dB2lin(db_gain);
76 
77     *out = *in * gain;
78 
79     return SP_OK;
80 }
81