From f42f577bedbffcd2465341e033afac0a0326a491 Mon Sep 17 00:00:00 2001 From: Hans Baier Date: Tue, 23 Jun 2009 09:50:02 +0000 Subject: Interpolation: First working but buggy version using libsamplerate git-svn-id: svn://localhost/ardour2/branches/3.0@5255 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/interpolation.cc | 93 ++++++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 29 deletions(-) (limited to 'libs/ardour/interpolation.cc') diff --git a/libs/ardour/interpolation.cc b/libs/ardour/interpolation.cc index 066507283b..a4a4b08872 100644 --- a/libs/ardour/interpolation.cc +++ b/libs/ardour/interpolation.cc @@ -1,41 +1,76 @@ #include + #include "ardour/interpolation.h" using namespace ARDOUR; -nframes_t -LinearInterpolation::interpolate (nframes_t nframes, Sample *input, Sample *output) +Interpolation::Interpolation() : _speed (1.0L), state (0) +{ +} + +Interpolation::~Interpolation() +{ + state = src_delete (state); +} + +void +Interpolation::set_speed (double new_speed) +{ + _speed = new_speed; + src_set_ratio (state, 1.0/_speed); +} + +void +Interpolation::reset_state () +{ + if (state) { + src_reset (state); + } else { + state = src_new (SRC_LINEAR, 1, &error); + } +} + +void +Interpolation::add_channel_to (int input_buffer_size, int output_buffer_size) { - // 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 + SRC_DATA newdata; - // index in the input buffers - nframes_t i = 0; + /* Set up sample rate converter info. */ + newdata.end_of_input = 0 ; + + newdata.input_frames = input_buffer_size; + newdata.output_frames = output_buffer_size; + + newdata.input_frames_used = 0 ; + newdata.output_frames_gen = 0 ; + + newdata.src_ratio = 1.0/_speed; - double acceleration; - double distance = 0.0; + data.push_back (newdata); - if (_speed != _target_speed) { - acceleration = _target_speed - _speed; - } else { - acceleration = 0.0; - } + reset_state (); +} - for (nframes_t outsample = 0; outsample < nframes; ++outsample) { - i = distance; - Sample fractional_phase_part = distance - i; - - 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; - } +void +Interpolation::remove_channel_from () +{ + data.pop_back (); + reset_state (); +} + +nframes_t +Interpolation::interpolate (int channel, nframes_t nframes, Sample *input, Sample *output) +{ + data[channel].data_in = input; + data[channel].data_out = output; - i = (distance + 0.5L); - // playback distance - return i; + data[channel].output_frames = nframes; + data[channel].src_ratio = 1.0/_speed; + + if ((error = src_process (state, &data[channel]))) { + printf ("\nError : %s\n\n", src_strerror (error)); + exit (1); + } + + return data[channel].input_frames_used; } -- cgit v1.2.3