1 /*
2  * LPF18
3  *
4  * This code has been extracted from the Csound opcode "lpf18".
5  * It has been modified to work as a Soundpipe module.
6  *
7  * Original Author(s): John ffitch, Josep Comajuncosas
8  * Year: 2000
9  * Location: Opcodes/pitch.c
10  *
11  */
12 
13 #include <math.h>
14 #include <stdlib.h>
15 #include "soundpipe.h"
16 
sp_lpf18_create(sp_lpf18 ** p)17 int sp_lpf18_create(sp_lpf18 **p)
18 {
19     *p = malloc(sizeof(sp_lpf18));
20     return SP_OK;
21 }
22 
sp_lpf18_destroy(sp_lpf18 ** p)23 int sp_lpf18_destroy(sp_lpf18 **p)
24 {
25     free(*p);
26     return SP_OK;
27 }
28 
sp_lpf18_init(sp_data * sp,sp_lpf18 * p)29 int sp_lpf18_init(sp_data *sp, sp_lpf18 *p)
30 {
31     p->cutoff = 1000;
32     p->res = 0.8;
33     p->dist = 2;
34 
35     p->ay1 = 0.0;
36     p->ay2 = 0.0;
37     p->aout = 0.0;
38     p->lastin = 0.0;
39     p->onedsr = 1.0 / sp->sr;
40     return SP_OK;
41 }
42 
sp_lpf18_compute(sp_data * sp,sp_lpf18 * p,SPFLOAT * in,SPFLOAT * out)43 int sp_lpf18_compute(sp_data *sp, sp_lpf18 *p, SPFLOAT *in, SPFLOAT *out)
44 {
45     SPFLOAT ay1 = p->ay1;
46     SPFLOAT ay2 = p->ay2;
47     SPFLOAT aout = p->aout;
48     SPFLOAT lastin = p->lastin;
49     double value = 0.0;
50     int   flag = 1;
51     SPFLOAT lfc=0, lrs=0, kres=0, kfcn=0, kp=0, kp1=0,  kp1h=0;
52     double lds = 0.0;
53 
54     SPFLOAT fco, res, dist;
55     SPFLOAT ax1  = lastin;
56     SPFLOAT ay11 = ay1;
57     SPFLOAT ay31 = ay2;
58     fco = p->cutoff;
59     res = p->res;
60     dist = p->dist;
61 
62     if (fco != lfc || flag) {
63         lfc = fco;
64         kfcn = 2.0 * fco * p->onedsr;
65         kp = ((-2.7528 * kfcn + 3.0429) * kfcn +
66                 1.718) * kfcn - 0.9984;
67         kp1 = kp + 1.0;
68         kp1h = 0.5 * kp1;
69         flag = 1;
70     }
71 
72     if (res != lrs || flag) {
73         lrs = res;
74         kres = res * (((-2.7079 * kp1 + 10.963) * kp1
75                            - 14.934) * kp1 + 8.4974);
76         flag = 1;
77     }
78 
79     if (dist != lds || flag) {
80         lds = dist;
81         value = 1.0 + (dist * (1.5 + 2.0 * res * (1.0 - kfcn)));
82     }
83 
84     flag = 0;
85     lastin = *in - tanh(kres*aout);
86     ay1 = kp1h * (lastin + ax1) - kp * ay1;
87     ay2 = kp1h * (ay1 + ay11) - kp * ay2;
88     aout = kp1h * (ay2 + ay31) - kp * aout;
89 
90     *out = tanh(aout * value);
91 
92     p->ay1 = ay1;
93     p->ay2 = ay2;
94     p->aout = aout;
95     p->lastin = lastin;
96     return SP_OK;
97 }
98