Browse Source

Fixed an edge-case error in the LaGrange and Catmull-Rom interpolators when the ratio changes to exactly 1.0

tags/2021-05-28
jules 7 years ago
parent
commit
37a92aec63
2 changed files with 40 additions and 70 deletions
  1. +8
    -8
      modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp
  2. +32
    -62
      modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp

+ 8
- 8
modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp View File

@@ -27,13 +27,13 @@ struct CatmullRomAlgorithm
{
static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept
{
const float y0 = inputs[3];
const float y1 = inputs[2];
const float y2 = inputs[1];
const float y3 = inputs[0];
auto y0 = inputs[3];
auto y1 = inputs[2];
auto y2 = inputs[1];
auto y3 = inputs[0];
const float halfY0 = 0.5f * y0;
const float halfY3 = 0.5f * y3;
auto halfY0 = 0.5f * y0;
auto halfY3 = 0.5f * y3;
return y1 + offset * ((0.5f * y2 - halfY0)
+ (offset * (((y0 + 2.0f * y2) - (halfY3 + 2.5f * y1))
@@ -48,8 +48,8 @@ void CatmullRomInterpolator::reset() noexcept
{
subSamplePos = 1.0;
for (int i = 0; i < numElementsInArray (lastInputSamples); ++i)
lastInputSamples[i] = 0;
for (auto& s : lastInputSamples)
s = 0;
}
int CatmullRomInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept


+ 32
- 62
modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp View File

@@ -49,97 +49,67 @@ namespace
}
template <typename InterpolatorType>
static int interpolate (float* lastInputSamples, double& subSamplePos, const double actualRatio,
const float* in, float* out, const int numOut) noexcept
static int interpolate (float* lastInputSamples, double& subSamplePos, double actualRatio,
const float* in, float* out, int numOut) noexcept
{
if (actualRatio == 1.0)
auto pos = subSamplePos;
if (actualRatio == 1.0 && pos == 1.0)
{
memcpy (out, in, (size_t) numOut * sizeof (float));
pushInterpolationSamples (lastInputSamples, in, numOut);
return numOut;
}
const float* const originalIn = in;
double pos = subSamplePos;
int numUsed = 0;
if (actualRatio < 1.0)
while (numOut > 0)
{
for (int i = numOut; --i >= 0;)
while (pos >= 1.0)
{
if (pos >= 1.0)
{
pushInterpolationSample (lastInputSamples, *in++);
pos -= 1.0;
}
*out++ = InterpolatorType::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
}
}
else
{
for (int i = numOut; --i >= 0;)
{
while (pos < actualRatio)
{
pushInterpolationSample (lastInputSamples, *in++);
pos += 1.0;
}
pos -= actualRatio;
*out++ = InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos));
pushInterpolationSample (lastInputSamples, in[numUsed++]);
pos -= 1.0;
}
*out++ = InterpolatorType::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
--numOut;
}
subSamplePos = pos;
return (int) (in - originalIn);
return numUsed;
}
template <typename InterpolatorType>
static int interpolateAdding (float* lastInputSamples, double& subSamplePos, const double actualRatio,
const float* in, float* out, const int numOut, const float gain) noexcept
static int interpolateAdding (float* lastInputSamples, double& subSamplePos, double actualRatio,
const float* in, float* out, int numOut, const float gain) noexcept
{
if (actualRatio == 1.0)
auto pos = subSamplePos;
if (actualRatio == 1.0 && pos == 1.0)
{
FloatVectorOperations::addWithMultiply (out, in, gain, numOut);
pushInterpolationSamples (lastInputSamples, in, numOut);
return numOut;
}
const float* const originalIn = in;
double pos = subSamplePos;
int numUsed = 0;
if (actualRatio < 1.0)
while (numOut > 0)
{
for (int i = numOut; --i >= 0;)
while (pos >= 1.0)
{
if (pos >= 1.0)
{
pushInterpolationSample (lastInputSamples, *in++);
pos -= 1.0;
}
*out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
}
}
else
{
for (int i = numOut; --i >= 0;)
{
while (pos < actualRatio)
{
pushInterpolationSample (lastInputSamples, *in++);
pos += 1.0;
}
pos -= actualRatio;
*out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos));
pushInterpolationSample (lastInputSamples, in[numUsed++]);
pos -= 1.0;
}
*out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
--numOut;
}
subSamplePos = pos;
return (int) (in - originalIn);
return numUsed;
}
}
@@ -186,8 +156,8 @@ void LagrangeInterpolator::reset() noexcept
{
subSamplePos = 1.0;
for (int i = 0; i < numElementsInArray (lastInputSamples); ++i)
lastInputSamples[i] = 0;
for (auto& s : lastInputSamples)
s = 0;
}
int LagrangeInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept


Loading…
Cancel
Save