From 842bddde1ec9943501e3d5d547aed8b809762e97 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 20 Apr 2012 17:52:42 +0000 Subject: Fix linear interpolator to avoid error accumulation. git-svn-id: svn://localhost/ardour2/branches/3.0@12044 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/interpolation.cc | 18 +++++++----------- libs/ardour/test/interpolation_test.cc | 16 +++++++--------- 2 files changed, 14 insertions(+), 20 deletions(-) (limited to 'libs') 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(); -- cgit v1.2.3