OpenWareLaboratory
InterpolatingCircularBuffer.h
Go to the documentation of this file.
1 #ifndef _InterpolatingCircularBuffer_hpp_
2 #define _InterpolatingCircularBuffer_hpp_
3 
4 #include <stdint.h>
5 #include "CircularBuffer.h"
6 #include "Interpolator.h"
7 
8 template<InterpolationMethod im = LINEAR_INTERPOLATION>
10 protected:
11  float delay_samples = 0;
12 public:
18 
23  void writeAt(float index, float value);
24 
29  float readAt(float index);
30 
35  void read(float* out, size_t len, float startpos, float rate){
36  float pos = startpos;
37  while(len--){
38  *out++ = readAt(pos);
39  pos += rate;
40  }
41  readpos = fmodf(pos + size, size);
42  empty = readpos == writepos;
43  }
44 
46  return delay_samples;
47  }
48 
52  void delay(float* out, size_t len, float delay){
53  // float pos = fmodf(writepos-delay+size, size);
54  float pos = writepos - delay + size;
55  while(len--){
56  *out++ = readAt(pos);
57  pos += 1;
58  }
60  }
61 
66  void delay(float* in, float* out, size_t len, float readDelay){
67  write(in, len);
68  delay(out, len, readDelay + len); // set delay relative to where we started writing
69  }
70 
75  void delay(float* out, size_t len, float beginDelay, float endDelay){
76  // float pos = fmodf(writepos-beginDelay+size, size);
77  float pos = writepos - beginDelay + size;
78  float incr = (len+endDelay-beginDelay)/len;
79  // incr = clamp(incr, 0.5, 2);
80  // delay_samples = beginDelay + incr*len - len;
81  delay_samples = endDelay;
82  while(len--){
83  *out++ = readAt(pos);
84  pos += incr;
85  }
86  }
87 
93  void delay(float* in, float* out, size_t len, float beginDelay, float endDelay){
94  write(in, len);
95  delay(out, len, beginDelay + len, endDelay + len); // set delays relative to where we started writing
96  }
97 
100  obj->clear();
101  return obj;
102  }
103 
105  delete[] obj->data;
106  delete obj;
107  }
108 };
109 
110 template<>
112  size_t idx = (size_t)roundf(index);
113  return CircularFloatBuffer::readAt(idx);
114 }
115 
116 template<>
118  size_t idx = (size_t)index;
119  float low = CircularFloatBuffer::readAt(idx);
120  float high = CircularFloatBuffer::readAt(idx+1);
121  float frac = index - idx;
122  return Interpolator::linear(low, high, frac);
123 }
124 
125 template<>
127  size_t idx = (size_t)index;
128  float low = CircularFloatBuffer::readAt(idx);
129  float high = CircularFloatBuffer::readAt(idx+1);
130  float frac = index - idx;
131  writeAt(idx, low + (value-low)*frac);
132  writeAt(idx+1, value + (high-value)*frac);
133 }
134 
135 template<>
137  size_t idx = (size_t)index;
138  float low = CircularFloatBuffer::readAt(idx);
139  float high = CircularFloatBuffer::readAt(idx+1);
140  float frac = index - idx;
141  return Interpolator::cosine(low, high, frac);
142 }
143 
144 template<>
146  size_t idx = (size_t)index;
147  float y0 = CircularFloatBuffer::readAt(idx-1);
148  float y1 = CircularFloatBuffer::readAt(idx);
149  float y2 = CircularFloatBuffer::readAt(idx+1);
150  return Interpolator::cubic(y0, y1, y2, index - idx);
151 }
152 
153 template<>
155  size_t idx = (size_t)index;
156  float y0 = CircularFloatBuffer::readAt(idx-1);
157  float y1 = CircularFloatBuffer::readAt(idx);
158  float y2 = CircularFloatBuffer::readAt(idx+1);
159  float y3 = CircularFloatBuffer::readAt(idx+2);
160  return Interpolator::cubic(y0, y1, y2, y3, index - idx);
161 }
162 
163 template<>
165  size_t idx = (size_t)index;
166  float y0 = CircularFloatBuffer::readAt(idx-1);
167  float y1 = CircularFloatBuffer::readAt(idx);
168  float y2 = CircularFloatBuffer::readAt(idx+1);
169  float y3 = CircularFloatBuffer::readAt(idx+2);
170  return Interpolator::cubicSmooth(y0, y1, y2, y3, index - idx);
171 }
172 
173 template<>
175  size_t idx = (size_t)index;
176  float y0 = CircularFloatBuffer::readAt(idx-1);
177  float y1 = CircularFloatBuffer::readAt(idx);
178  float y2 = CircularFloatBuffer::readAt(idx+1);
179  float y3 = CircularFloatBuffer::readAt(idx+2);
180  return Interpolator::hermite(y0, y1, y2, y3, index - idx);
181 }
182 
183 #endif /* _InterpolatingCircularBuffer_hpp_ */
float readAt(size_t index)
static void destroy(InterpolatingCircularFloatBuffer< im > *obj)
void delay(float *in, float *out, size_t len, float beginDelay, float endDelay)
Write to buffer and read with a delay that ramps up or down from.
static InterpolatingCircularFloatBuffer< im > * create(size_t len)
void delay(float *out, size_t len, float beginDelay, float endDelay)
Read with a delay that ramps up or down from.
void writeAt(float index, float value)
Interpolated write at sub-sample index.
void delay(float *in, float *out, size_t len, float readDelay)
Write to buffer and read with a fractional delay.
void delay(float *out, size_t len, float delay)
Read with a fractional delay.
void read(float *out, size_t len, float startpos, float rate)
Interpolated read at fractional rate.
float readAt(float index)
Interpolated read at sub-sample index.
InterpolatingCircularFloatBuffer(float *data, size_t size)
static float cubic(float y0, float y1, float y2, float mu)
Three-point cubic interpolation of point between y1 and y2 ref: http://www.ebyte.it/library/codesnipp...
Definition: Interpolator.h:19
static float hermite(float y0, float y1, float y2, float y3, float mu, float tension=0, float bias=0)
Definition: Interpolator.h:54
static float linear(float y1, float y2, float mu)
Definition: Interpolator.h:8
static float cosine(float y1, float y2, float mu)
Definition: Interpolator.h:11
static float cubicSmooth(float y0, float y1, float y2, float y3, float mu)
Definition: Interpolator.h:38