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