diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index ad3b1adde2..55cb747a4c 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -146,7 +146,7 @@ class AudioDiskstream : public Diskstream } } - Interpolation interpolation; + LibSamplerateInterpolation interpolation; XMLNode* deprecated_io_node; diff --git a/libs/ardour/ardour/interpolation.h b/libs/ardour/ardour/interpolation.h index d0ba3c48bc..cec951c841 100644 --- a/libs/ardour/ardour/interpolation.h +++ b/libs/ardour/ardour/interpolation.h @@ -8,20 +8,20 @@ namespace ARDOUR { -class Interpolation { +class LibSamplerateInterpolation { protected: double _speed; - SRC_STATE* state; - std::vector data; + std::vector state; + std::vector data; int error; void reset_state (); public: - Interpolation (); - ~Interpolation (); + LibSamplerateInterpolation (); + ~LibSamplerateInterpolation (); void set_speed (double new_speed); void set_target_speed (double new_speed) {} diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 5c2c32655f..8b291dd75b 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1008,10 +1008,10 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable bool _silent; // varispeed playback - volatile double _transport_speed; - double _last_transport_speed; - double _target_transport_speed; - Interpolation interpolation; + volatile double _transport_speed; + double _last_transport_speed; + double _target_transport_speed; + LibSamplerateInterpolation interpolation; bool auto_play_legal; nframes_t _last_slave_transport_frame; diff --git a/libs/ardour/interpolation.cc b/libs/ardour/interpolation.cc index 444183a2b1..3d2f754da9 100644 --- a/libs/ardour/interpolation.cc +++ b/libs/ardour/interpolation.cc @@ -4,74 +4,92 @@ using namespace ARDOUR; -Interpolation::Interpolation() : _speed (1.0L), state (0) +LibSamplerateInterpolation::LibSamplerateInterpolation() : _speed (1.0L), state (0) { } -Interpolation::~Interpolation() +LibSamplerateInterpolation::~LibSamplerateInterpolation() { - 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); + for (int i = 0; i < state.size(); i++) { + state[i] = src_delete (state[i]); } } void -Interpolation::add_channel_to (int input_buffer_size, int output_buffer_size) +LibSamplerateInterpolation::set_speed (double new_speed) +{ + _speed = new_speed; + for (int i = 0; i < state.size(); i++) { + src_set_ratio (state[i], 1.0/_speed); + } +} + +void +LibSamplerateInterpolation::reset_state () { - SRC_DATA newdata; + printf("INTERPOLATION: reset_state()\n"); + for (int i = 0; i < state.size(); i++) { + if (state[i]) { + src_reset (state[i]); + } else { + state[i] = src_new (SRC_SINC_FASTEST, 1, &error); + } + } +} + +void +LibSamplerateInterpolation::add_channel_to (int input_buffer_size, int output_buffer_size) +{ + SRC_DATA* newdata = new SRC_DATA; /* Set up sample rate converter info. */ - newdata.end_of_input = 0 ; + newdata->end_of_input = 0 ; - newdata.input_frames = input_buffer_size; - newdata.output_frames = output_buffer_size; + newdata->input_frames = input_buffer_size; + newdata->output_frames = output_buffer_size; - newdata.input_frames_used = 0 ; - newdata.output_frames_gen = 0 ; + newdata->input_frames_used = 0 ; + newdata->output_frames_gen = 0 ; - newdata.src_ratio = 1.0/_speed; + newdata->src_ratio = 1.0/_speed; data.push_back (newdata); + state.push_back (0); reset_state (); } void -Interpolation::remove_channel_from () +LibSamplerateInterpolation::remove_channel_from () { + delete data.back (); data.pop_back (); + delete state.back (); + state.pop_back (); reset_state (); } nframes_t -Interpolation::interpolate (int channel, nframes_t nframes, Sample *input, Sample *output) +LibSamplerateInterpolation::interpolate (int channel, nframes_t nframes, Sample *input, Sample *output) { - data[channel].data_in = input; - data[channel].data_out = output; + if (!data.size ()) { + printf ("ERROR: trying to interpolate with no channels\n"); + return 0; + } - data[channel].input_frames = nframes * _speed; - data[channel].output_frames = nframes; - data[channel].src_ratio = 1.0/_speed; + data[channel]->data_in = input; + data[channel]->data_out = output; + + data[channel]->input_frames = nframes * _speed; + data[channel]->output_frames = nframes; + data[channel]->src_ratio = 1.0/_speed; - if ((error = src_process (state, &data[channel]))) { + if ((error = src_process (state[channel], data[channel]))) { printf ("\nError : %s\n\n", src_strerror (error)); exit (1); } - - return data[channel].input_frames_used; + + //printf("INTERPOLATION: channel %d input_frames_used: %d\n", channel, data[channel]->input_frames_used); + + return data[channel]->input_frames_used; }