summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2012-04-20 17:52:42 +0000
committerCarl Hetherington <carl@carlh.net>2012-04-20 17:52:42 +0000
commit842bddde1ec9943501e3d5d547aed8b809762e97 (patch)
treea674061a268bb490e10cb24b472bcfc6d52beaf6 /libs/ardour
parentffe5a6c5c2c46df6cc8723219529970ff17d84a9 (diff)
Fix linear interpolator to avoid error accumulation.
git-svn-id: svn://localhost/ardour2/branches/3.0@12044 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/interpolation.cc18
-rw-r--r--libs/ardour/test/interpolation_test.cc16
2 files changed, 14 insertions, 20 deletions
diff --git a/libs/ardour/interpolation.cc b/libs/ardour/interpolation.cc
index 20ab584885..ccaaca7e76 100644
--- a/libs/ardour/interpolation.cc
+++ b/libs/ardour/interpolation.cc
@@ -10,21 +10,18 @@ framecnt_t
LinearInterpolation::interpolate (int channel, framecnt_t nframes, Sample *input, Sample *output)
{
// index in the input buffers
- framecnt_t i = 0;
+ framecnt_t i = 0;
- double acceleration;
- double distance = 0.0;
+ double acceleration = 0;
if (_speed != _target_speed) {
acceleration = _target_speed - _speed;
- } else {
- acceleration = 0.0;
}
- distance = phase[channel];
for (framecnt_t outsample = 0; outsample < nframes; ++outsample) {
- i = floor(distance);
- Sample fractional_phase_part = distance - i;
+ double const d = phase[channel] + outsample * (_speed + acceleration);
+ i = floor(d);
+ Sample fractional_phase_part = d - i;
if (fractional_phase_part >= 1.0) {
fractional_phase_part -= 1.0;
i++;
@@ -36,12 +33,11 @@ LinearInterpolation::interpolate (int channel, framecnt_t nframes, Sample *input
input[i] * (1.0f - fractional_phase_part) +
input[i+1] * fractional_phase_part;
}
- distance += _speed + acceleration;
}
+ double const distance = phase[channel] + nframes * (_speed + acceleration);
i = floor(distance);
- phase[channel] = distance - floor(distance);
-
+ phase[channel] = distance - i;
return i;
}
diff --git a/libs/ardour/test/interpolation_test.cc b/libs/ardour/test/interpolation_test.cc
index 0bbb697b85..23789f826f 100644
--- a/libs/ardour/test/interpolation_test.cc
+++ b/libs/ardour/test/interpolation_test.cc
@@ -54,15 +54,13 @@ InterpolationTest::linearInterpolationTest ()
result = linear.interpolate (0, NUM_SAMPLES, input, output);
CPPUNIT_ASSERT_EQUAL ((framecnt_t)(NUM_SAMPLES * linear.speed()), result);
- /* This one fails due too error accumulation
- cout << "\nSpeed: 0.002";
- linear.reset();
- linear.set_speed (0.002);
- linear.set_target_speed (linear.speed());
- result = linear.interpolate (0, NUM_SAMPLES, input, output);
- linear.speed();
- CPPUNIT_ASSERT_EQUAL ((framecnt_t)(NUM_SAMPLES * linear.speed()), result);
- */
+// cout << "\nSpeed: 0.002";
+ linear.reset();
+ linear.set_speed (0.002);
+ linear.set_target_speed (linear.speed());
+ result = linear.interpolate (0, NUM_SAMPLES, input, output);
+ linear.speed();
+ CPPUNIT_ASSERT_EQUAL ((framecnt_t)(NUM_SAMPLES * linear.speed()), result);
// cout << "\nSpeed: 2.0";
linear.reset();