diff options
author | Hans Baier <hansfbaier@googlemail.com> | 2009-06-10 00:03:47 +0000 |
---|---|---|
committer | Hans Baier <hansfbaier@googlemail.com> | 2009-06-10 00:03:47 +0000 |
commit | 43340cd37ce91752f80b776d905e1b0d103c89ef (patch) | |
tree | a4aa17688238e96d686ba7435e88eccfa4000ff9 /libs/ardour/interpolation.cc | |
parent | f284d28d5306114e9badc9077835683e541420e0 (diff) |
* 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
Diffstat (limited to 'libs/ardour/interpolation.cc')
-rw-r--r-- | libs/ardour/interpolation.cc | 46 |
1 files changed, 22 insertions, 24 deletions
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 <stdint.h> #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; } |