From ee350362d38922760d47516fab79797f425683e3 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 28 Jun 2022 03:01:41 +0200 Subject: [PATCH] Debug loop range squishing When the loop-range is defined in BeatTime, the disk-reader encounters rounding issues due to time-domain mismatches. With a simple session fixed BPM at 120, 48kHz. looping 1 bar exactly 2 sec at the start of the session: ``` Range::squish start: b0 end: b7680 squish: a113554560 Range::squish using modulo: b45 = a661500 Range::squish using modulo in TD: a5760 Range::squish using earlier(): a658560 ``` The correct answer is a113554560 - 2 * 56448000 [SC/sec] = a658560 Calculating the modulo iteratively is not great, however usually only one iteration is required. --- libs/temporal/range.cc | 42 ++++++++++++++++++++++++++++++++++ libs/temporal/temporal/range.h | 7 +----- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/libs/temporal/range.cc b/libs/temporal/range.cc index 3cd3948175..2eb42ba4b5 100644 --- a/libs/temporal/range.cc +++ b/libs/temporal/range.cc @@ -16,6 +16,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef NDEBUG +#include +#endif + #include "temporal/range.h" using namespace Temporal; @@ -96,6 +100,44 @@ Range::subtract (RangeList & sub) const return result; } +timepos_t +Range::squish (timepos_t const & t) const +{ + if (t < _end) { + return t; + } +#if 1 +#ifndef NDEBUG + std::stringstream dbg; + dbg << "Range::squish start: " << _start << " end: " << _end << " squish: " << t << "\n"; +#endif + + timepos_t rv = t; + while (rv >= _end) { + rv = rv.earlier (length ()); + } + +#ifndef NDEBUG + timepos_t sq = _start + (_start.distance (t) % length()); + dbg << "Range::squish using modulo: " << sq << " = "; + sq.set_time_domain (t.time_domain()); + dbg << sq << "\n"; + + timepos_t start = _start; + start.set_time_domain (t.time_domain()); + timepos_t sqt = start + (start.distance (t) % length()); + + dbg << "Range::squish using modulo in TD: " << sqt << "\n"; + dbg << "Range::squish using earlier(): " << rv << "\n"; + std::cout << dbg.str (); +#endif + + return rv; +#else + return _start + (_start.distance (t) % length()); +#endif +} + template<> OverlapType Temporal::coverage_exclusive_ends (int64_t sa, int64_t eaE, int64_t sb, int64_t ebE) { /* convert end positions to inclusive */ diff --git a/libs/temporal/temporal/range.h b/libs/temporal/temporal/range.h index 7b7894abf6..cce5dd7b73 100644 --- a/libs/temporal/temporal/range.h +++ b/libs/temporal/temporal/range.h @@ -169,12 +169,7 @@ class LIBTEMPORAL_API Range { * looping). If the argument is earlier than or equal to the end of * this range, do nothing. */ - timepos_t squish (timepos_t const & t) const { - if (t >= _end) { - return _start + (_start.distance (t) % length()); - } - return t; - } + timepos_t squish (timepos_t const & t) const; /* end is exclusive */ OverlapType coverage (timepos_t const & s, timepos_t const & e) const {