1 #ifndef _FractionalCircularBuffer_hpp_
2 #define _FractionalCircularBuffer_hpp_
10 template<
typename T =
float>
23 inline T
update(T previous, T current,
size_t i){
24 delta[i] = previous - current;
45 return abs(writepos-readpos) < 1;
49 size_t pos = (writepos-1+size) % size;
50 update(data[pos], value, writepos);
51 if(++writepos >= size)
56 T previous = data[(writepos-1+size) % size];
57 size_t rem = size-writepos;
59 for(
size_t i=writepos; i<size; ++i)
60 previous =
update(previous, *src++, i);
62 for(
size_t i=0; i<writepos; ++i)
63 previous =
update(previous, *src++, i);
67 for(; i<writepos; ++i)
68 previous =
update(previous, *src++, i);
73 size_t pos = (index-1+size) % size;
74 update(data[pos], value, index);
78 size_t idx = (size_t)readpos;
79 T current = data[idx];
81 float fraction = readpos-idx;
85 return current + fraction*diff;
88 void read(T* dst,
size_t len){
89 size_t idx = (size_t)readpos;
90 float fraction = 1 - (readpos-idx);
93 size_t rem = size-idx;
95 T* pdelta = delta+idx;
97 readpos += len - size;
98 for(
size_t i=idx; i<size; ++i)
99 *dst++ = *pdata++ + fraction*(*pdelta++);
100 idx = (size_t)readpos;
101 for(
size_t i=0; i<idx; ++i)
102 *dst++ = *pdata++ + fraction*(*pdelta++);
106 *dst++ = *pdata++ + fraction*(*pdelta++);
111 size_t idx = (size_t)index;
112 float fraction = 1 - (index-idx);
113 idx = (idx+1) % size;
114 return data[idx] + fraction*delta[idx];
122 writepos = pos % size;
126 return data+writepos;
140 readpos = fmodf(pos+size, size);
144 return data+(size_t)readpos;
162 return fmodf(writepos-readpos+size, size);
178 void delay(T* in, T* out,
size_t len,
float beginDelay,
float endDelay){
181 float incr = (len+endDelay-beginDelay)/len;
182 T previous = data[(writepos-1+size) % size];
183 size_t rem = size-writepos;
185 for(
size_t i=writepos; i<size; ++i){
186 previous =
update(previous, *in++, i);
191 for(
size_t i=0; i<writepos; ++i){
192 previous =
update(previous, *in++, i);
199 for(; i<writepos; ++i){
200 previous =
update(previous, *in++, i);
209 return (writepos + size - (
size_t)readpos) % size;
217 if(writepos < (
size_t)readpos)
218 return (
size_t)readpos - writepos;
220 return size - writepos;
224 if(writepos < (
size_t)readpos)
225 return size - (size_t)readpos;
227 return writepos - (size_t)readpos;
231 for(
size_t i=0; i<size; ++i){
238 readpos = writepos = 0;
FractionalCircularBuffer< int16_t > FractionalCircularShortBuffer
FractionalCircularBuffer< int32_t > FractionalCircularIntBuffer
FractionalCircularBuffer< float > FractionalCircularFloatBuffer
Circular buffer that keeps a delta table of differences for faster fractional delay lines.
void write(T *src, size_t len)
size_t getWriteCapacity()
size_t getContiguousReadCapacity()
FractionalCircularBuffer(T *data, T *delta, size_t size)
static FractionalCircularBuffer< T > * create(size_t len)
void read(T *dst, size_t len)
void setWriteIndex(size_t pos)
static void destroy(FractionalCircularBuffer< T > *obj)
T update(T previous, T current, size_t i)
Update an entry in the internal data and delta tables.
void setAll(const T value)
void setDelay(float samples)
Set the read index.
size_t getContiguousWriteCapacity()
void writeAt(size_t index, T value)
FractionalCircularBuffer()
void moveWriteHead(int samples)
void moveReadHead(float samples)
void delay(T *in, T *out, size_t len, float delay)
Write to buffer and read with a delay.
float getDelay()
Get the read index expressed as delay behind the write index.
void delay(T *in, T *out, size_t len, float beginDelay, float endDelay)
Write to buffer and read with a delay that ramps up or down from beginDelay to endDelay.
void setReadIndex(float pos)