diff options
author | Carl Hetherington <carl@carlh.net> | 2012-04-20 17:52:42 +0000 |
---|---|---|
committer | Carl Hetherington <carl@carlh.net> | 2012-04-20 17:52:42 +0000 |
commit | 842bddde1ec9943501e3d5d547aed8b809762e97 (patch) | |
tree | a674061a268bb490e10cb24b472bcfc6d52beaf6 /libs/ardour/interpolation.cc | |
parent | ffe5a6c5c2c46df6cc8723219529970ff17d84a9 (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.cc | 18 |
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; } |