summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour
diff options
context:
space:
mode:
authorHans Baier <hansfbaier@googlemail.com>2009-01-10 08:42:07 +0000
committerHans Baier <hansfbaier@googlemail.com>2009-01-10 08:42:07 +0000
commitb7715419f2ae85af70a0d78722798a5b0ea16263 (patch)
tree44b193e0870a7693dc5bd76ad79e0c6c178851c2 /libs/ardour/ardour
parentbfbae251be8b67b33ad1c95b56e30da0cb537ec5 (diff)
* wrong calculation of frames_moved in Session::process_*, resulting in drift against any Slaves when transport speed != 1.0
git-svn-id: svn://localhost/ardour2/branches/3.0@4397 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r--libs/ardour/ardour/audio_diskstream.h42
-rw-r--r--libs/ardour/ardour/session.h6
2 files changed, 48 insertions, 0 deletions
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index f918655f98..0db44709f8 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -150,6 +150,48 @@ class AudioDiskstream : public Diskstream
XMLNode* deprecated_io_node;
+ /**
+ * Calculate the playback distance during varispeed playback.
+ * Important for Session::process to know exactly, how many frames
+ * were passed by.
+ */
+ static nframes_t calculate_varispeed_playback_distance(
+ nframes_t nframes,
+ uint64_t& the_last_phase,
+ uint64_t& the_phi,
+ uint64_t& the_target_phi)
+ {
+ // calculate playback distance in the same way
+ // as in AudioDiskstream::process_varispeed_playback
+ uint64_t phase = the_last_phase;
+ int64_t phi_delta;
+ nframes_t i = 0;
+
+ const int64_t fractional_part_mask = 0xFFFFFF;
+ const Sample binary_scaling_factor = 16777216.0f;
+
+ if (the_phi != the_target_phi) {
+ phi_delta = ((int64_t)(the_target_phi - the_phi)) / nframes;
+ } else {
+ phi_delta = 0;
+ }
+
+ Sample fractional_phase_part;
+
+ i = 0;
+ phase = the_last_phase;
+
+ for (nframes_t outsample = 0; outsample < nframes; ++outsample) {
+ i = phase >> 24;
+ fractional_phase_part = (phase & fractional_part_mask) / binary_scaling_factor;
+ phase += the_phi + phi_delta;
+ }
+
+ the_last_phase = (phase & fractional_part_mask);
+ the_phi = the_target_phi;
+ return i; // + 1;
+ }
+
protected:
friend class Session;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 9d12aa79b8..8b45dad958 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1025,6 +1025,12 @@ class Session : public PBD::StatefulDestructible
bool _silent;
volatile double _transport_speed;
double _last_transport_speed;
+ // fixed point transport speed for varispeed playback
+ uint64_t phi;
+ // fixed point target transport speed for varispeed playback when tempo changes
+ uint64_t target_phi;
+ // fixed point phase for varispeed playback
+ uint64_t phase;
bool auto_play_legal;
nframes_t _last_slave_transport_frame;
nframes_t maximum_output_latency;