summaryrefslogtreecommitdiff
path: root/libs/ardour/interpolation.cc
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/interpolation.cc
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/interpolation.cc')
-rw-r--r--libs/ardour/interpolation.cc18
1 files changed, 7 insertions, 11 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;
}