summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r--libs/ardour/ardour/audio_diskstream.h2
-rw-r--r--libs/ardour/ardour/interpolation.h97
-rw-r--r--libs/ardour/ardour/session.h2
3 files changed, 87 insertions, 14 deletions
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 55cb747a4c..ecced007cf 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -146,7 +146,7 @@ class AudioDiskstream : public Diskstream
}
}
- LibSamplerateInterpolation interpolation;
+ FixedPointLinearInterpolation interpolation;
XMLNode* deprecated_io_node;
diff --git a/libs/ardour/ardour/interpolation.h b/libs/ardour/ardour/interpolation.h
index cec951c841..deb0204794 100644
--- a/libs/ardour/ardour/interpolation.h
+++ b/libs/ardour/ardour/interpolation.h
@@ -8,18 +8,90 @@
namespace ARDOUR {
-class LibSamplerateInterpolation {
-protected:
- double _speed;
-
- std::vector<SRC_STATE*> state;
- std::vector<SRC_DATA*> data;
-
- int error;
-
- void reset_state ();
+class Interpolation {
+ protected:
+ double _speed, _target_speed;
+
+ public:
+ Interpolation () { _speed = 1.0; }
+
+ void set_speed (double new_speed) { _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) {}
+ void remove_channel_from () {}
+
+ nframes_t interpolate (int channel, nframes_t nframes, Sample* input, Sample* output) {}
+ void reset () {}
+};
+
+// 40.24 fixpoint math
+#define FIXPOINT_ONE 0x1000000
+
+class FixedPointLinearInterpolation : public Interpolation {
+ protected:
+ /// speed in fixed point math
+ uint64_t phi;
+
+ /// target speed in fixed point math
+ uint64_t target_phi;
+
+ std::vector<uint64_t> last_phase;
+
+ // Fixed point is just an integer with an implied scaling factor.
+ // In 40.24 the scaling factor is 2^24 = 16777216,
+ // so a value of 10*2^24 (in integer space) is equivalent to 10.0.
+ //
+ // The advantage is that addition and modulus [like x = (x + y) % 2^40]
+ // have no rounding errors and no drift, and just require a single integer add.
+ // (swh)
-public:
+ static const int64_t fractional_part_mask = 0xFFFFFF;
+ static const Sample binary_scaling_factor = 16777216.0f;
+
+ public:
+ FixedPointLinearInterpolation () : phi (FIXPOINT_ONE), target_phi (FIXPOINT_ONE) {}
+
+ void set_speed (double new_speed) {
+ target_phi = (uint64_t) (FIXPOINT_ONE * fabs(new_speed));
+ phi = target_phi;
+ }
+
+ void add_channel_to (int input_buffer_size, int output_buffer_size);
+ void remove_channel_from ();
+
+ nframes_t interpolate (int channel, nframes_t nframes, Sample* input, Sample* output);
+ void reset ();
+};
+
+ class LinearInterpolation : public Interpolation {
+ protected:
+ // 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<double> phase;
+
+ public:
+ void add_channel_to (int input_buffer_size, int output_buffer_size);
+ void remove_channel_from ();
+
+ nframes_t interpolate (int channel, nframes_t nframes, Sample* input, Sample* output);
+ void reset ();
+ };
+
+class LibSamplerateInterpolation : public Interpolation {
+ protected:
+ std::vector<SRC_STATE*> state;
+ std::vector<SRC_DATA*> data;
+
+ int error;
+
+ void reset_state ();
+
+ public:
LibSamplerateInterpolation ();
~LibSamplerateInterpolation ();
@@ -31,8 +103,9 @@ public:
void remove_channel_from ();
nframes_t interpolate (int channel, nframes_t nframes, Sample* input, Sample* output);
+ void reset() { reset_state (); }
};
} // namespace ARDOUR
-#endif \ No newline at end of file
+#endif
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 8b291dd75b..1dd40affdb 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1011,7 +1011,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
volatile double _transport_speed;
double _last_transport_speed;
double _target_transport_speed;
- LibSamplerateInterpolation interpolation;
+ FixedPointLinearInterpolation interpolation;
bool auto_play_legal;
nframes_t _last_slave_transport_frame;