From 43340cd37ce91752f80b776d905e1b0d103c89ef Mon Sep 17 00:00:00 2001 From: Hans Baier Date: Wed, 10 Jun 2009 00:03:47 +0000 Subject: * Refactor varispeed playback into own class, replace fixed-point arithmetic by double, fix unit tests for libardour git-svn-id: svn://localhost/ardour2/branches/3.0@5145 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/interpolation.cc | 46 +++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'libs/ardour/interpolation.cc') diff --git a/libs/ardour/interpolation.cc b/libs/ardour/interpolation.cc index 7aece6453c..066507283b 100644 --- a/libs/ardour/interpolation.cc +++ b/libs/ardour/interpolation.cc @@ -1,43 +1,41 @@ #include #include "ardour/interpolation.h" +using namespace ARDOUR; + nframes_t LinearInterpolation::interpolate (nframes_t nframes, Sample *input, Sample *output) { - // the idea behind phase is that when the speed is not 1.0, we have to + // the idea is that when the speed is not 1.0, we have to // interpolate between samples and then we have to store where we thought we were. // rather than being at sample N or N+1, we were at N+0.8792922 - // so the "phase" element, if you want to think about this way, - // varies from 0 to 1, representing the "offset" between samples - uint64_t phase = last_phase; - - // acceleration - int64_t phi_delta; - - // phi = fixed point speed - if (phi != target_phi) { - phi_delta = ((int64_t)(target_phi - phi)) / nframes; - } else { - phi_delta = 0; - } // index in the input buffers nframes_t i = 0; + + double acceleration; + double distance = 0.0; + + if (_speed != _target_speed) { + acceleration = _target_speed - _speed; + } else { + acceleration = 0.0; + } for (nframes_t outsample = 0; outsample < nframes; ++outsample) { - i = phase >> 24; - Sample fractional_phase_part = (phase & fractional_part_mask) / binary_scaling_factor; + i = distance; + Sample fractional_phase_part = distance - i; - // Linearly interpolate into the output buffer - // using fixed point math - output[outsample] = - input[i] * (1.0f - fractional_phase_part) + - input[i+1] * fractional_phase_part; - phase += phi + phi_delta; + if (input && output) { + // Linearly interpolate into the output buffer + output[outsample] = + input[i] * (1.0f - fractional_phase_part) + + input[i+1] * fractional_phase_part; + } + distance += _speed + acceleration; } - - last_phase = (phase & fractional_part_mask); + i = (distance + 0.5L); // playback distance return i; } -- cgit v1.2.3