blob: eaf1117a4a62692e233f33b94c144c63179d1cff (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
/*
idelay~ - interpolating delay using flext layer
Copyright (c) 2002 Thomas Grill (xovo@gmx.net)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
*/
#ifndef _IDELAY_DELAY_H
#define _IDELAY_DELAY_H
#include <math.h>
#include <string.h>
#define F float
#define S t_sample
#define I int
#define V void
template <class T>
class DelayLine
{
public:
DelayLine(): buf(NULL),len(0),wpos(0) {}
DelayLine(I smps): buf(NULL),len(0),wpos(0) { SetLen(smps); }
~DelayLine() { if(buf) delete[] buf; }
V SetLen(I smps);
V Put(T s);
T Get(F delsmps);
T *buf; I dim;
I wpos,len;
};
template <class T>
V DelayLine<T>::SetLen(I smps)
{
if(len != smps) {
if(buf) delete[] buf;
len = smps;
buf = new T[dim = (len+4)]; // some more samples for interpolation
memset(buf,0,dim*sizeof(T));
wpos = 4;
}
}
template <class T>
V DelayLine<T>::Put(T s)
{
if(!len) return;
buf[wpos] = s;
if(wpos >= len) buf[wpos-len] = s; // initialize interpolation security zone
if(++wpos == dim) wpos -= len;
}
template <class T>
T DelayLine<T>::Get(F delsmps)
{
if(!len) return 0;
if(delsmps < 0)
return buf[wpos-1];
else {
if(delsmps > len-1) delsmps = (F)len-1;
I idelsmps = (I)delsmps;
if(idelsmps == 0) {
const T *bp = buf+wpos;
const F r = 1.f-delsmps;
return (F)(r*(r-1)*bp[-3]/2.+(1-r*r)*bp[-2]+r*(r+1)*bp[-1]/2.);
}
else {
const T *bp = buf+wpos-idelsmps;
if(bp < (const T *)buf+4) bp += len;
const F r = 1.f-(delsmps - (F)idelsmps);
return (F)(
((2-r)*(r-1)*r*bp[-3])/6. +
((r-2)*(r*r-1)*bp[-2])/2. +
((2-r)*r*(r+1)*bp[-1])/2. +
((r*r-1)*r*bp[0])/6.
);
}
}
}
#endif
|