1 #include <stdlib.h>
2 #include "soundpipe.h"
3 
4 #ifndef max
5 #define max(a, b) ((a > b) ? a : b)
6 #endif
7 
8 #ifndef min
9 #define min(a, b) ((a < b) ? a : b)
10 #endif
11 
12 
13 int sp_smoothdelay_create(sp_smoothdelay **p)
14 {
MergeOperator(final long nativeHandle)15     *p = malloc(sizeof(sp_smoothdelay));
16     return SP_OK;
17 }
18 
19 int sp_smoothdelay_destroy(sp_smoothdelay **p)
20 {
21     sp_smoothdelay *pp = *p;
22     sp_auxdata_free(&pp->buf1);
23     sp_auxdata_free(&pp->buf2);
24     free(*p);
25     return SP_OK;
26 }
27 
28 int sp_smoothdelay_init(sp_data *sp, sp_smoothdelay *p,
29         SPFLOAT maxdel, uint32_t interp)
30 {
31     uint32_t n = (int32_t)(maxdel * sp->sr)+1;
32     p->sr = sp->sr;
33     p->del = maxdel * 0.5;
34     p->pdel = -1;
35     p->maxdel = maxdel;
36     p->feedback = 0;
37     p->maxbuf = n - 1;
38     p->maxcount = interp;
39 
40     sp_auxdata_alloc(&p->buf1, n * sizeof(SPFLOAT));
41     p->bufpos1 = 0;
42     p->deltime1 = (uint32_t) (p->del * sp->sr);
43 
44     sp_auxdata_alloc(&p->buf2, n * sizeof(SPFLOAT));
45     p->bufpos2 = 0;
46     p->deltime2 = p->deltime1;
47 
48     p->counter = 0;
49     p->curbuf = 0;
50     return SP_OK;
51 }
52 
53 static SPFLOAT delay_sig(SPFLOAT *buf,
54         uint32_t *bufpos,
55         uint32_t deltime,
56         SPFLOAT fdbk,
57         SPFLOAT in)
58 {
59     SPFLOAT delay = buf[*bufpos];
60     SPFLOAT sig = (delay * fdbk) + in;
61     buf[*bufpos] = sig;
62     *bufpos = (*bufpos + 1) % deltime;
63     return delay;
64 }
65 
66 int sp_smoothdelay_compute(sp_data *sp, sp_smoothdelay *p, SPFLOAT *in, SPFLOAT *out)
67 {
68     *out = 0;
69     if(p->del != p->pdel && p->counter == 0) {
70         uint32_t dels = min((uint32_t)(p->del * sp->sr), p->maxbuf);
71 
72         /* initial delay time sets time for both buffers */
73 
74         if(p->pdel < 0) {
75             p->deltime1 = dels;
76             p->deltime2 = dels;
77         }
78 
79         p->pdel = p->del;
80 
81         if(dels == 0) dels = 1;
82 
83         if(p->curbuf == 0) {
84             p->curbuf = 1;
85             p->deltime2 = dels;
86         } else {
87             p->curbuf = 0;
88             p->deltime1 = dels;
89         }
90         p->counter = p->maxcount;
91     }
92 
93 
94 
95     SPFLOAT *buf1 = (SPFLOAT *)p->buf1.ptr;
96     SPFLOAT *buf2 = (SPFLOAT *)p->buf2.ptr;
97     SPFLOAT it = (SPFLOAT)p->counter / p->maxcount;
98     if(p->counter != 0) p->counter--;
99 
100     SPFLOAT del1 = delay_sig(buf1, &p->bufpos1,
101             p->deltime1, p->feedback, *in);
102 
103     SPFLOAT del2 = delay_sig(buf2, &p->bufpos2,
104             p->deltime2, p->feedback, *in);
105 
106     if(p->curbuf == 0) {
107         /* 1 to 2 */
108         *out = (del1 * it) + (del2 * (1 - it));
109     } else {
110         /* 2 to 1 */
111         *out = (del2 * it) + (del1 * (1 - it));
112     }
113     return SP_OK;
114 }
115