From 13adc56f34de1d00302099286c471b19ce2a53d7 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 5 Dec 2022 01:05:23 +0100 Subject: [PATCH] Library: rectify confusingly named function on the Grid API The APIs for time quantisation were drafted in an early stage of the project and then never followed-up. Especially Grid::gridAlign has no real-world usage yet, and is only massaged in some tests. When looking at QuantiserBasics_test, I was puzzled and led astray, since this function suggests to materialise a continuous time into a quantised time -- which it doesn't (there is another dedicated function Quantiser::materialise() to that end); so, without engaging into the discussion if this function is of any use, I'll hereby choose a name better reflecting what it does. --- src/lib/time.h | 2 +- src/lib/time/grid.hpp | 2 +- src/lib/time/quantiser.cpp | 38 +++--- src/lib/time/quantiser.hpp | 4 +- tests/basics/time/quantiser-basics-test.cpp | 112 +++++++++--------- .../asset/meta/time-grid-basics-test.cpp | 2 +- wiki/thinkPad.ichthyo.mm | 48 ++++++-- 7 files changed, 118 insertions(+), 90 deletions(-) diff --git a/src/lib/time.h b/src/lib/time.h index e23747a01..7ba20798b 100644 --- a/src/lib/time.h +++ b/src/lib/time.h @@ -111,7 +111,7 @@ int64_t lumiera_quantise_frames_fps (gavl_time_t time, gavl_time_t origin, uint framerate); /** - * Similar to #lumiera_quantise_frames, but returns a grid aligned \em time value + * Similar to #lumiera_quantise_frames, but returns a grid aligned _relative time._ * @return time of start of the grid interval containing the given time, * but measured relative to the origin * @warning because the resulting value needs to be limited to fit into a 64bit long, diff --git a/src/lib/time/grid.hpp b/src/lib/time/grid.hpp index f87dc0793..fa9f18f7b 100644 --- a/src/lib/time/grid.hpp +++ b/src/lib/time/grid.hpp @@ -71,7 +71,7 @@ namespace time { virtual FrameCnt gridPoint (TimeValue const& raw) const =0; - virtual TimeValue gridAlign (TimeValue const& raw) const =0; + virtual TimeValue gridLocal (TimeValue const& raw) const =0; virtual TimeValue timeOf (FrameCnt gridPoint) const =0; virtual TimeValue timeOf (FSecs gridTime, int=0) const =0; }; diff --git a/src/lib/time/quantiser.cpp b/src/lib/time/quantiser.cpp index a2ed4372e..1fea6dcab 100644 --- a/src/lib/time/quantiser.cpp +++ b/src/lib/time/quantiser.cpp @@ -114,25 +114,6 @@ namespace time { - /** alignment to a simple fixed size grid. - * The actual calculation first determines the number - * of the grid interval containing the given rawTime, - * then followed by multiplying this interval number - * with the grid spacing. - * @return time of the start point of the grid interval - * containing the rawTime, relative to the origin - * of the time scale used by this quantiser. - * @warning returned time values are limited by the - * valid range of lumiera::Time - * @see #lumiera_quantise_time - */ - TimeValue - FixedFrameQuantiser::gridAlign (TimeValue const& rawTime) const - { - return TimeValue (lumiera_quantise_time (_raw(rawTime), _raw(origin_), _raw(raster_))); - } - - /** grid quantisation (alignment). * Determine the next lower grid interval start point, * using a simple constant spaced time grid defined by @@ -148,6 +129,25 @@ namespace time { } + /** transform into the local time scale grid aligned. + * The actual calculation first determines the number + * of the grid interval containing the given rawTime, + * then followed by multiplying this interval number + * with the grid spacing. + * @return time of the start point of the grid interval + * containing the rawTime, _relative to the origin_ + * of the time scale used by this quantiser. + * @warning returned time values are limited by the + * valid range of lumiera::Time + * @see #lumiera_quantise_time + */ + TimeValue + FixedFrameQuantiser::gridLocal (TimeValue const& rawTime) const + { + return TimeValue (lumiera_quantise_time (_raw(rawTime), _raw(origin_), _raw(raster_))); + } + + /** calculate time value of a grid interval (frame) start point * @return time point measured in Lumiera internal time * @warning returned time values are limited by the diff --git a/src/lib/time/quantiser.hpp b/src/lib/time/quantiser.hpp index fc0464f89..904f89dda 100644 --- a/src/lib/time/quantiser.hpp +++ b/src/lib/time/quantiser.hpp @@ -123,7 +123,7 @@ namespace time { //------Grid-API---------------------------------------------- virtual FrameCnt gridPoint (TimeValue const& raw) const =0; - virtual TimeValue gridAlign (TimeValue const& raw) const =0; + virtual TimeValue gridLocal (TimeValue const& raw) const =0; virtual TimeValue timeOf (FrameCnt gridPoint) const =0; virtual TimeValue timeOf (FSecs, int =0) const =0; }; @@ -152,7 +152,7 @@ namespace time { FixedFrameQuantiser (Duration const& frame_duration, TimeValue referencePoint =TimeValue(0)); FrameCnt gridPoint (TimeValue const&) const; - TimeValue gridAlign (TimeValue const&) const; + TimeValue gridLocal (TimeValue const&) const; TimeValue timeOf (FrameCnt gridPoint) const; TimeValue timeOf (FSecs, int =0) const; diff --git a/tests/basics/time/quantiser-basics-test.cpp b/tests/basics/time/quantiser-basics-test.cpp index cfe544735..8f3700778 100644 --- a/tests/basics/time/quantiser-basics-test.cpp +++ b/tests/basics/time/quantiser-basics-test.cpp @@ -99,7 +99,7 @@ namespace test{ CHECK (Time( frames *F25) <= rawTime); CHECK (Time((frames+1)*F25) > rawTime); - Time quantTime (fixQ.gridAlign (rawTime)); + Time quantTime (fixQ.gridLocal (rawTime)); CHECK (Time(frames*F25) == quantTime); } @@ -118,7 +118,7 @@ namespace test{ int quant (int testPoint) { - TimeVar quantised = this->gridAlign(TimeValue(testPoint)); + TimeVar quantised = this->gridLocal(TimeValue(testPoint)); return int(quantised); } }; @@ -162,48 +162,48 @@ namespace test{ { // origin at lower end of the time range FixedFrameQuantiser case1 (1, Time::MIN); - CHECK (secs(0) == case1.gridAlign(Time::MIN )); - CHECK (secs(0) == case1.gridAlign(Time::MIN +TimeValue(1) )); - CHECK (secs(1) == case1.gridAlign(Time::MIN +secs(1) )); - CHECK (Time::MAX -secs(1) > case1.gridAlign( secs(-1) )); - CHECK (Time::MAX -secs(1) <= case1.gridAlign( secs (0) )); - CHECK (Time::MAX > case1.gridAlign( secs (0) )); - CHECK (Time::MAX == case1.gridAlign( secs(+1) )); - CHECK (Time::MAX == case1.gridAlign( secs(+2) )); + CHECK (secs(0) == case1.gridLocal(Time::MIN )); + CHECK (secs(0) == case1.gridLocal(Time::MIN +TimeValue(1) )); + CHECK (secs(1) == case1.gridLocal(Time::MIN +secs(1) )); + CHECK (Time::MAX -secs(1) > case1.gridLocal( secs(-1) )); + CHECK (Time::MAX -secs(1) <= case1.gridLocal( secs (0) )); + CHECK (Time::MAX > case1.gridLocal( secs (0) )); + CHECK (Time::MAX == case1.gridLocal( secs(+1) )); + CHECK (Time::MAX == case1.gridLocal( secs(+2) )); // origin at upper end of the time range FixedFrameQuantiser case2 (1, Time::MAX); - CHECK (secs( 0) == case2.gridAlign(Time::MAX )); - CHECK (secs(-1) == case2.gridAlign(Time::MAX -TimeValue(1) )); // note: next lower frame - CHECK (secs(-1) == case2.gridAlign(Time::MAX -secs(1) )); // i.e. the same as a whole frame down - CHECK (Time::MIN +secs(1) < case2.gridAlign( secs(+2) )); - CHECK (Time::MIN +secs(1) >= case2.gridAlign( secs(+1) )); - CHECK (Time::MIN < case2.gridAlign( secs(+1) )); - CHECK (Time::MIN == case2.gridAlign( secs( 0) )); // note: because of downward truncating, - CHECK (Time::MIN == case2.gridAlign( secs(-1) )); // resulting values will already exceed - CHECK (Time::MIN == case2.gridAlign( secs(-2) )); // allowed range and thus will be clipped + CHECK (secs( 0) == case2.gridLocal(Time::MAX )); + CHECK (secs(-1) == case2.gridLocal(Time::MAX -TimeValue(1) )); // note: next lower frame + CHECK (secs(-1) == case2.gridLocal(Time::MAX -secs(1) )); // i.e. the same as a whole frame down + CHECK (Time::MIN +secs(1) < case2.gridLocal( secs(+2) )); + CHECK (Time::MIN +secs(1) >= case2.gridLocal( secs(+1) )); + CHECK (Time::MIN < case2.gridLocal( secs(+1) )); + CHECK (Time::MIN == case2.gridLocal( secs( 0) )); // note: because of downward truncating, + CHECK (Time::MIN == case2.gridLocal( secs(-1) )); // resulting values will already exceed + CHECK (Time::MIN == case2.gridLocal( secs(-2) )); // allowed range and thus will be clipped // use very large frame with size of half the time range Duration hugeFrame(Time::MAX); FixedFrameQuantiser case3 (hugeFrame); - CHECK (Time::MIN == case3.gridAlign(Time::MIN )); - CHECK (Time::MIN == case3.gridAlign(Time::MIN +TimeValue(1) )); - CHECK (Time::MIN == case3.gridAlign( secs(-1) )); - CHECK (TimeValue(0) == case3.gridAlign( secs( 0) )); - CHECK (TimeValue(0) == case3.gridAlign( secs(+1) )); - CHECK (TimeValue(0) == case3.gridAlign(Time::MAX -TimeValue(1) )); - CHECK (Time::MAX == case3.gridAlign(Time::MAX )); + CHECK (Time::MIN == case3.gridLocal(Time::MIN )); + CHECK (Time::MIN == case3.gridLocal(Time::MIN +TimeValue(1) )); + CHECK (Time::MIN == case3.gridLocal( secs(-1) )); + CHECK (TimeValue(0) == case3.gridLocal( secs( 0) )); + CHECK (TimeValue(0) == case3.gridLocal( secs(+1) )); + CHECK (TimeValue(0) == case3.gridLocal(Time::MAX -TimeValue(1) )); + CHECK (Time::MAX == case3.gridLocal(Time::MAX )); // now displacing this grid by +1sec.... FixedFrameQuantiser case4 (hugeFrame, secs(1)); - CHECK (Time::MIN == case4.gridAlign(Time::MIN )); - CHECK (Time::MIN == case4.gridAlign(Time::MIN +TimeValue(1) )); // clipped... - CHECK (Time::MIN == case4.gridAlign(Time::MIN +secs(1) )); // but now exact (unclipped) - CHECK (Time::MIN == case4.gridAlign( secs(-1) )); - CHECK (Time::MIN == case4.gridAlign( secs( 0) )); - CHECK (TimeValue(0) == case4.gridAlign( secs(+1) )); //.....now exactly the frame number zero - CHECK (TimeValue(0) == case4.gridAlign(Time::MAX -TimeValue(1) )); - CHECK (TimeValue(0) == case4.gridAlign(Time::MAX )); //.......still truncated down to frame #0 + CHECK (Time::MIN == case4.gridLocal(Time::MIN )); + CHECK (Time::MIN == case4.gridLocal(Time::MIN +TimeValue(1) )); // clipped... + CHECK (Time::MIN == case4.gridLocal(Time::MIN +secs(1) )); // but now exact (unclipped) + CHECK (Time::MIN == case4.gridLocal( secs(-1) )); + CHECK (Time::MIN == case4.gridLocal( secs( 0) )); + CHECK (TimeValue(0) == case4.gridLocal( secs(+1) )); //.....now exactly the frame number zero + CHECK (TimeValue(0) == case4.gridLocal(Time::MAX -TimeValue(1) )); + CHECK (TimeValue(0) == case4.gridLocal(Time::MAX )); //.......still truncated down to frame #0 // think big... Duration superHuge{secs(12345) + hugeFrame}; @@ -212,34 +212,34 @@ namespace test{ // Time::MAX < superHuge < Duration::Max is possible, but we can accommodate only one FixedFrameQuantiser case5 (superHuge); - CHECK (TimeValue(0) == case5.gridAlign(Time::MAX )); - CHECK (TimeValue(0) == case5.gridAlign(Time::MAX -TimeValue(1) )); - CHECK (TimeValue(0) == case5.gridAlign( secs( 1) )); - CHECK (TimeValue(0) == case5.gridAlign( secs( 0) )); - CHECK (Time::MIN == case5.gridAlign( secs(-1) )); - CHECK (Time::MIN == case5.gridAlign(Time::MIN +TimeValue(1) )); - CHECK (Time::MIN == case5.gridAlign(Time::MIN )); + CHECK (TimeValue(0) == case5.gridLocal(Time::MAX )); + CHECK (TimeValue(0) == case5.gridLocal(Time::MAX -TimeValue(1) )); + CHECK (TimeValue(0) == case5.gridLocal( secs( 1) )); + CHECK (TimeValue(0) == case5.gridLocal( secs( 0) )); + CHECK (Time::MIN == case5.gridLocal( secs(-1) )); + CHECK (Time::MIN == case5.gridLocal(Time::MIN +TimeValue(1) )); + CHECK (Time::MIN == case5.gridLocal(Time::MIN )); // now with offset FixedFrameQuantiser case6 (superHuge, Time::MAX-secs(1)); - CHECK (TimeValue(0) == case6.gridAlign(Time::MAX )); - CHECK (TimeValue(0) == case6.gridAlign(Time::MAX -TimeValue(1) )); - CHECK (TimeValue(0) == case6.gridAlign(Time::MAX -secs(1) )); - CHECK (Time::MIN == case6.gridAlign(Time::MAX -secs(2) )); - CHECK (Time::MIN == case6.gridAlign( secs( 1) )); - CHECK (Time::MIN == case6.gridAlign( secs(-12345) )); - CHECK (Time::MIN == case6.gridAlign( secs(-12345-1) )); - CHECK (Time::MIN == case6.gridAlign( secs(-12345-2) )); // this would be one frame lower, but is clipped - CHECK (Time::MIN == case6.gridAlign(Time::MIN +TimeValue(1) )); - CHECK (Time::MIN == case6.gridAlign(Time::MIN )); // same... unable to represent time points before Time::MIN + CHECK (TimeValue(0) == case6.gridLocal(Time::MAX )); + CHECK (TimeValue(0) == case6.gridLocal(Time::MAX -TimeValue(1) )); + CHECK (TimeValue(0) == case6.gridLocal(Time::MAX -secs(1) )); + CHECK (Time::MIN == case6.gridLocal(Time::MAX -secs(2) )); + CHECK (Time::MIN == case6.gridLocal( secs( 1) )); + CHECK (Time::MIN == case6.gridLocal( secs(-12345) )); + CHECK (Time::MIN == case6.gridLocal( secs(-12345-1) )); + CHECK (Time::MIN == case6.gridLocal( secs(-12345-2) )); // this would be one frame lower, but is clipped + CHECK (Time::MIN == case6.gridLocal(Time::MIN +TimeValue(1) )); + CHECK (Time::MIN == case6.gridLocal(Time::MIN )); // same... unable to represent time points before Time::MIN // maximum frame size is spanning the full time range FixedFrameQuantiser case7 (extraHuge, Time::MIN+secs(1)); - CHECK (TimeValue(0) == case7.gridAlign(Time::MAX )); // rounded down one frame, i.e. to origin - CHECK (TimeValue(0) == case7.gridAlign( secs( 0) )); - CHECK (TimeValue(0) == case7.gridAlign(Time::MIN+secs(2) )); - CHECK (TimeValue(0) == case7.gridAlign(Time::MIN+secs(1) )); // exactly at origin - CHECK (Time::MIN == case7.gridAlign(Time::MIN )); // one frame further down, but clipped to Time::MIN + CHECK (TimeValue(0) == case7.gridLocal(Time::MAX )); // rounded down one frame, i.e. to origin + CHECK (TimeValue(0) == case7.gridLocal( secs( 0) )); + CHECK (TimeValue(0) == case7.gridLocal(Time::MIN+secs(2) )); + CHECK (TimeValue(0) == case7.gridLocal(Time::MIN+secs(1) )); // exactly at origin + CHECK (Time::MIN == case7.gridLocal(Time::MIN )); // one frame further down, but clipped to Time::MIN // even larger frames aren't possible Duration not_really_larger(secs(10000) + extraHuge); diff --git a/tests/core/steam/asset/meta/time-grid-basics-test.cpp b/tests/core/steam/asset/meta/time-grid-basics-test.cpp index 70578ebdc..63e8fd52b 100644 --- a/tests/core/steam/asset/meta/time-grid-basics-test.cpp +++ b/tests/core/steam/asset/meta/time-grid-basics-test.cpp @@ -109,7 +109,7 @@ namespace test { ASSERT (0 < dirt); Time dirty(point + Time(dirt)); - CHECK (point == TEST_ORIGIN + myGrid->gridAlign(dirty)); + CHECK (point == TEST_ORIGIN + myGrid->gridLocal(dirty)); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index a18f551bd..ee4cd81ae 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -41108,7 +41108,7 @@ - + @@ -41150,19 +41150,46 @@ - + - - + + + + + + + + +

+ TimeValue Quantiser::materialise(TimeValue const& raw) { return timeOf (gridPoint (raw)); } +

+ +
- - + + + + + + +
    +
  • + weil die Rechnung komplett auf Implementierungs-Ebene passiert, mit int64_t +
  • +
  • + unter der Maßgabe daß die auftretenden Werte dahingehend limititert sind, und daher auch noch die Summe zum Origin ohne wrap-around berechnet werden kann +
  • +
+ +
- - - - + + + + + + @@ -58042,6 +58069,7 @@ +