X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Finterpolation.h;h=488a5fe5b40c7a1c287131d546c2547e8435e349;hb=7a524285385d4581ad3f1e085629379e32f82fda;hp=98b6e7e775caf52fc07f18859f2d9bd7ead677dc;hpb=16b964020fdf9deda6262e7dd9048e36acc0912e;p=ardour.git diff --git a/libs/ardour/ardour/interpolation.h b/libs/ardour/ardour/interpolation.h index 98b6e7e775..488a5fe5b4 100644 --- a/libs/ardour/ardour/interpolation.h +++ b/libs/ardour/ardour/interpolation.h @@ -1,6 +1,26 @@ +/* + Copyright (C) 1999-2010 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + #include #include +#include "ardour/libardour_visibility.h" #include "ardour/types.h" #ifndef __interpolation_h__ @@ -8,58 +28,53 @@ namespace ARDOUR { -class Interpolation { - protected: - double _speed, _target_speed; - - // 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 - std::vector phase; - - - public: - Interpolation () { _speed = 1.0; _target_speed = 1.0; } - ~Interpolation () { phase.clear(); } - - void set_speed (double new_speed) { _speed = new_speed; _target_speed = new_speed; } - void set_target_speed (double new_speed) { _target_speed = new_speed; } - - double target_speed() const { return _target_speed; } - double speed() const { return _speed; } - - void add_channel_to (int input_buffer_size, int output_buffer_size) { phase.push_back (0.0); } - void remove_channel_from () { phase.pop_back (); } - - void reset () { - for (size_t i = 0; i < phase.size(); i++) { - phase[i] = 0.0; - } - } -}; +class LIBARDOUR_API Interpolation { +protected: + double _speed; + double _target_speed; + + // 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 + std::vector phase; -class LinearInterpolation : public Interpolation { - protected: - - public: - nframes_t interpolate (int channel, nframes_t nframes, Sample* input, Sample* output); +public: + Interpolation () { _speed = 1.0; _target_speed = 1.0; } + virtual ~Interpolation() {} + + void set_speed (double new_speed) { _speed = new_speed; _target_speed = new_speed; } + void set_target_speed (double new_speed) { _target_speed = new_speed; } + + double target_speed() const { return _target_speed; } + double speed() const { return _speed; } + + void add_channel () { phase.push_back (0.0); } + void remove_channel () { phase.pop_back (); } + + virtual void reset () { + for (size_t i = 0; i < phase.size(); i++) { + phase[i] = 0.0; + } + } }; -class CubicInterpolation : public Interpolation { - protected: - // shamelessly ripped from Steve Harris' swh-plugins (ladspa-util.h) - static inline float cube_interp(const float fr, const float inm1, const float - in, const float inp1, const float inp2) - { - return in + 0.5f * fr * (inp1 - inm1 + - fr * (4.0f * inp1 + 2.0f * inm1 - 5.0f * in - inp2 + - fr * (3.0f * (in - inp1) - inm1 + inp2))); - } - - public: - nframes_t interpolate (int channel, nframes_t nframes, Sample* input, Sample* output); +class LIBARDOUR_API CubicInterpolation : public Interpolation { + public: + CubicInterpolation (); + samplecnt_t interpolate (int channel, samplecnt_t input_samples, Sample* input, samplecnt_t & output_samples, Sample* output); + samplecnt_t distance (samplecnt_t nframes); + void reset (); + + private: + Sample z[4]; + char valid_z_bits; + + bool is_valid (int n) const { return valid_z_bits & (1<