34namespace DelayLineInterpolationTypes
91template <
typename SampleType,
typename InterpolationType = DelayLineInterpolationTypes::Linear>
100 explicit DelayLine (
int maximumDelayInSamples);
104 void setDelay (SampleType newDelayInSamples);
140 void pushSample (
int channel, SampleType sample);
159 SampleType
popSample (
int channel, SampleType delayInSamples = -1,
bool updateReadPointer =
true);
169 template <
typename ProcessContext>
172 const auto& inputBlock = context.getInputBlock();
173 auto& outputBlock = context.getOutputBlock();
174 const auto numChannels = outputBlock.getNumChannels();
175 const auto numSamples = outputBlock.getNumSamples();
177 jassert (inputBlock.getNumChannels() == numChannels);
178 jassert (inputBlock.getNumChannels() == writePos.
size());
179 jassert (inputBlock.getNumSamples() == numSamples);
181 if (context.isBypassed)
183 outputBlock.copyFrom (inputBlock);
187 for (
size_t channel = 0; channel < numChannels; ++channel)
189 auto* inputSamples = inputBlock.getChannelPointer (channel);
190 auto* outputSamples = outputBlock.getChannelPointer (channel);
192 for (
size_t i = 0; i < numSamples; ++i)
195 outputSamples[i] =
popSample ((
int) channel);
202 SampleType interpolateSample (
int channel)
206 auto index = (readPos[(
size_t) channel] + delayInt) % totalSize;
207 return bufferData.
getSample (channel, index);
211 auto index1 = readPos[(
size_t) channel] + delayInt;
212 auto index2 = index1 + 1;
214 if (index2 >= totalSize)
220 auto value1 = bufferData.
getSample (channel, index1);
221 auto value2 = bufferData.
getSample (channel, index2);
223 return value1 + delayFrac * (value2 - value1);
227 auto index1 = readPos[(
size_t) channel] + delayInt;
228 auto index2 = index1 + 1;
229 auto index3 = index2 + 1;
230 auto index4 = index3 + 1;
232 if (index4 >= totalSize)
242 auto value1 = samples[index1];
243 auto value2 = samples[index2];
244 auto value3 = samples[index3];
245 auto value4 = samples[index4];
247 auto d1 = delayFrac - 1.f;
248 auto d2 = delayFrac - 2.f;
249 auto d3 = delayFrac - 3.f;
251 auto c1 = -d1 * d2 * d3 / 6.f;
252 auto c2 = d2 * d3 * 0.5f;
253 auto c3 = -d1 * d3 * 0.5f;
254 auto c4 = d1 * d2 / 6.f;
256 return value1 * c1 + delayFrac * (value2 * c2 + value3 * c3 + value4 * c4);
260 auto index1 = readPos[(
size_t) channel] + delayInt;
261 auto index2 = index1 + 1;
263 if (index2 >= totalSize)
269 auto value1 = bufferData.
getSample (channel, index1);
270 auto value2 = bufferData.
getSample (channel, index2);
272 auto output =
approximatelyEqual (delayFrac, (SampleType) 0) ? value1 : value2 + alpha * (value1 - v[(
size_t) channel]);
273 v[(
size_t) channel] = output;
280 void updateInternalVariables()
284 if (delayFrac < (SampleType) 2.0 && delayInt >= 1)
292 if (delayFrac < (SampleType) 0.618 && delayInt >= 1)
298 alpha = (1 - delayFrac) / (1 + delayFrac);
306 AudioBuffer<SampleType> bufferData;
309 SampleType delay = 0.0, delayFrac = 0.0;
310 int delayInt = 0, totalSize = 4;
311 SampleType alpha = 0.0;
Type getSample(int channel, int sampleIndex) const noexcept
Returns a sample from the buffer.
const Type * getReadPointer(int channelNumber) const noexcept
Returns a pointer to an array of read-only samples in one of the buffer's channels.
A delay line processor featuring several algorithms for the fractional delay calculation,...
void prepare(const ProcessSpec &spec)
Initialises the processor.
int getMaximumDelayInSamples() const noexcept
Gets the maximum possible delay in samples.
void setDelay(SampleType newDelayInSamples)
Sets the delay in samples.
SampleType popSample(int channel, SampleType delayInSamples=-1, bool updateReadPointer=true)
Pops a single sample from one channel of the delay line.
DelayLine()
Default constructor.
void setMaximumDelayInSamples(int maxDelayInSamples)
Sets a new maximum delay in samples.
SampleType getDelay() const
Returns the current delay in samples.
void process(const ProcessContext &context) noexcept
Processes the input and output samples supplied in the processing context.
void reset()
Resets the internal state variables of the processor.
void pushSample(int channel, SampleType sample)
Pushes a single sample into one channel of the delay line.
Successive samples in the delay line will be interpolated using a 3rd order Lagrange interpolator.
Successive samples in the delay line will be linearly interpolated.
No interpolation between successive samples in the delay line will be performed.
Successive samples in the delay line will be interpolated using 1st order Thiran interpolation.
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
Returns true if the two floating-point numbers are approximately equal.
This structure is passed into a DSP algorithm's prepare() method, and contains information about vari...