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>
170 void process (
const ProcessContext& context)
noexcept
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)
204 if constexpr (std::is_same_v<InterpolationType, DelayLineInterpolationTypes::None>)
206 auto index = (readPos[(size_t) channel] + delayInt) % totalSize;
207 return bufferData.
getSample (channel, index);
209 else if constexpr (std::is_same_v<InterpolationType, DelayLineInterpolationTypes::Linear>)
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);
225 else if constexpr (std::is_same_v<InterpolationType, DelayLineInterpolationTypes::Lagrange3rd>)
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);
258 else if constexpr (std::is_same_v<InterpolationType, DelayLineInterpolationTypes::Thiran>)
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()
282 if constexpr (std::is_same_v<InterpolationType, DelayLineInterpolationTypes::Lagrange3rd>)
284 if (delayFrac < (SampleType) 2.0 && delayInt >= 1)
290 else if constexpr (std::is_same_v<InterpolationType, DelayLineInterpolationTypes::Thiran>)
292 if (delayFrac < (SampleType) 0.618 && delayInt >= 1)
298 alpha = (1 - delayFrac) / (1 + delayFrac);
306 AudioBuffer<SampleType> bufferData;
307 std::vector<SampleType> v;
308 std::vector<int> writePos, readPos;
309 SampleType delay = 0.0, delayFrac = 0.0;
310 int delayInt = 0, totalSize = 4;
311 SampleType alpha = 0.0;