summaryrefslogtreecommitdiff
path: root/libs/ardour/interpolation.cc
diff options
context:
space:
mode:
authorHans Baier <hansfbaier@googlemail.com>2009-06-23 09:50:02 +0000
committerHans Baier <hansfbaier@googlemail.com>2009-06-23 09:50:02 +0000
commitf42f577bedbffcd2465341e033afac0a0326a491 (patch)
tree3499d135da2d870010a8231389fb040a22c02218 /libs/ardour/interpolation.cc
parentdef335e427f46513436884bf81d10caf96d7c482 (diff)
Interpolation: First working but buggy version using libsamplerate
git-svn-id: svn://localhost/ardour2/branches/3.0@5255 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/interpolation.cc')
-rw-r--r--libs/ardour/interpolation.cc93
1 files changed, 64 insertions, 29 deletions
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 <stdint.h>
+
#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;
}