diff --git a/libs/ardour/ardour/disk_io.h b/libs/ardour/ardour/disk_io.h index d1ae059038..6c3e4dc807 100644 --- a/libs/ardour/ardour/disk_io.h +++ b/libs/ardour/ardour/disk_io.h @@ -27,7 +27,6 @@ #include "pbd/ringbufferNPT.h" #include "pbd/rcu.h" -#include "ardour/interpolation.h" #include "ardour/midi_buffer.h" #include "ardour/processor.h" #include "ardour/rt_midibuffer.h" diff --git a/libs/ardour/ardour/interpolation.h b/libs/ardour/ardour/interpolation.h deleted file mode 100644 index c03b8e903b..0000000000 --- a/libs/ardour/ardour/interpolation.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2009-2010 Carl Hetherington - * Copyright (C) 2009-2011 David Robillard - * Copyright (C) 2009-2017 Paul Davis - * Copyright (C) 2009 Hans Baier - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include - -#include "ardour/libardour_visibility.h" -#include "ardour/types.h" - -#ifndef __interpolation_h__ -#define __interpolation_h__ - -namespace ARDOUR { - -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; - -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 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< - * Copyright (C) 2009-2012 Carl Hetherington - * Copyright (C) 2009-2017 Paul Davis - * Copyright (C) 2009 Hans Baier - * Copyright (C) 2013-2017 Robin Gareus - * - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include - -#include - -#include "ardour/interpolation.h" -#include "ardour/midi_buffer.h" - -using namespace ARDOUR; -using std::cerr; -using std::endl; - -CubicInterpolation::CubicInterpolation () - : valid_z_bits (0) -{ -} - -samplecnt_t -CubicInterpolation::interpolate (int channel, samplecnt_t input_samples, Sample *input, samplecnt_t & output_samples, Sample *output) -{ - assert (input_samples > 0); - assert (output_samples > 0); - assert (input); - assert (output); - assert (phase.size () > std::vector::size_type (channel)); - - _speed = fabs (_speed); - - if (invalid (0)) { - - /* z[0] not set. Two possibilities - * - * 1) we have just been constructed or ::reset() - * - * 2) we were only given 1 sample after construction or - * ::reset, and stored it in z[1] - */ - - if (invalid (1)) { - - /* first call after construction or after ::reset */ - - switch (input_samples) { - case 1: - /* store one sample for use next time. We don't - * have enough points to interpolate or even - * compute the first z[0] value, but keep z[1] - * around. - */ - z[1] = input[0]; validate (1); - output_samples = 0; - return 0; - case 2: - /* store two samples for use next time, and - * compute a value for z[0] that will maintain - * the slope of the first actual segment. We - * still don't have enough samples to interpolate. - */ - z[0] = input[0] - (input[1] - input[0]); validate (0); - z[1] = input[0]; validate (1); - z[2] = input[1]; validate (2); - output_samples = 0; - return 0; - default: - /* We have enough samples to interpolate this time, - * but don't have a valid z[0] value because this is the - * first call after construction or ::reset. - * - * First point is based on a requirement to maintain - * the slope of the first actual segment - */ - z[0] = input[0] - (input[1] - input[0]); validate (0); - break; - } - } else { - - /* at least one call since construction or - * after::reset, since we have z[1] set - * - * we can now compute z[0] as required - */ - - z[0] = z[1] - (input[0] - z[1]); validate (0); - - /* we'll check the number of samples we've been given - in the next switch() statement below, and either - just save some more samples or actual interpolate - */ - } - - assert (is_valid (0)); - } - - switch (input_samples) { - case 1: - /* one more sample of input. find the right vX to store - it in, and decide if we're ready to interpolate - */ - if (invalid (1)) { - z[1] = input[0]; validate (1); - /* still not ready to interpolate */ - output_samples = 0; - return 0; - } else if (invalid (2)) { - /* still not ready to interpolate */ - z[2] = input[0]; validate (2); - output_samples = 0; - return 0; - } else if (invalid (3)) { - z[3] = input[0]; validate (3); - /* ready to interpolate */ - } - break; - case 2: - /* two more samples of input. find the right vX to store - them in, and decide if we're ready to interpolate - */ - if (invalid (1)) { - z[1] = input[0]; validate (1); - z[2] = input[1]; validate (2); - /* still not ready to interpolate */ - output_samples = 0; - return 0; - } else if (invalid (2)) { - z[2] = input[0]; validate (2); - z[3] = input[1]; validate (3); - /* ready to interpolate */ - } else if (invalid (3)) { - z[3] = input[0]; validate (3); - /* ready to interpolate */ - } - break; - - default: - /* caller has given us at least enough samples to interpolate a - single value. - */ - z[1] = input[0]; validate (1); - z[2] = input[1]; validate (2); - z[3] = input[2]; validate (3); - } - - /* ready to interpolate using z[0], z[1], z[2] and z[3] */ - - assert (is_valid (0)); - assert (is_valid (1)); - assert (is_valid (2)); - assert (is_valid (3)); - - /* we can use up to (input_samples - 2) of the input, so compute the - * maximum number of output samples that represents. - * - * Remember that the expected common case here is to be given - * input_samples that is substantially larger than output_samples, - * thus allowing us to always compute output_samples in one call. - */ - - const samplecnt_t output_from_input = floor ((input_samples - 2) / _speed); - - /* limit output to either the caller's requested number or the number - * determined by the input size. - */ - - const samplecnt_t limit = std::min (output_samples, output_from_input); - - samplecnt_t outsample = 0; - double distance = phase[channel]; - samplecnt_t used = floor (distance); - samplecnt_t i = 0; - - while (outsample < limit) { - - i = floor (distance); - - /* this call may stop the loop from being vectorized */ - float fractional_phase_part = fmod (distance, 1.0); - - /* Cubically interpolate into the output buffer */ - output[outsample++] = z[1] + 0.5f * fractional_phase_part * - (z[2] - z[0] + fractional_phase_part * (4.0f * z[2] + 2.0f * z[0] - 5.0f * z[1] - z[3] + - fractional_phase_part * (3.0f * (z[1] - z[2]) - z[0] + z[3]))); - - distance += _speed; - - z[0] = z[1]; - z[1] = input[i]; - z[2] = input[i+1]; - z[3] = input[i+2]; - } - - output_samples = outsample; - phase[channel] = fmod (distance, 1.0); - return i - used; -} - -void -CubicInterpolation::reset () -{ - Interpolation::reset (); - valid_z_bits = 0; -} - -samplecnt_t -CubicInterpolation::distance (samplecnt_t nsamples) -{ - assert (phase.size () > 0); - return floor (floor (phase[0]) + (_speed * nsamples)); -} diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 4743a4eb75..bb52ce4379 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -106,7 +106,6 @@ libardour_sources = [ 'instrument_info.cc', 'internal_return.cc', 'internal_send.cc', - 'interpolation.cc', 'io.cc', 'io_plug.cc', 'io_processor.cc',