basic quantisation now working and covered by unit test

This commit is contained in:
Fischlurch 2011-01-09 11:41:08 +01:00
parent e2cab1f512
commit debe032f49
4 changed files with 84 additions and 41 deletions

View file

@ -40,15 +40,7 @@ namespace time {
namespace { // implementation helpers...
template<typename NUM>
inline NUM
__ensure_notZero (NUM n)
{
if (!n)
throw error::Logic ("Impossible to quantise to an zero spaced grid"
, error::LUMIERA_ERROR_BOTTOM_VALUE);
return n;
}
///////////TODO superfluous??
}//(End) implementation helpers
@ -76,7 +68,12 @@ namespace time {
* each interval includes its lower bound and excludes its upper bound.*/
FixedFrameQuantiser::FixedFrameQuantiser (FrameRate const& frames_per_second, TimeValue referencePoint)
: origin_(referencePoint)
, raster_(frames_per_second.duration())
, raster_(__ensure_nonzero(frames_per_second.duration()))
{ }
FixedFrameQuantiser::FixedFrameQuantiser (Duration const& frame_duration, TimeValue referencePoint)
: origin_(referencePoint)
, raster_(__ensure_nonzero(frame_duration))
{ }

View file

@ -107,6 +107,7 @@ namespace time {
public:
FixedFrameQuantiser (FrameRate const& frames_per_second, TimeValue referencePoint =TimeValue(0));
FixedFrameQuantiser (Duration const& frame_duration, TimeValue referencePoint =TimeValue(0));
TimeValue gridAlign (TimeValue const&);

View file

@ -366,7 +366,7 @@ namespace time {
inline NUM
__ensure_nonzero (NUM n)
{
if (!n)
if (n == 0)
throw error::Logic ("Zero spaced grid not allowed"
, error::LUMIERA_ERROR_BOTTOM_VALUE);
return n;
@ -415,7 +415,7 @@ namespace time {
{
return boost::rational_cast<double> (*this);
}

View file

@ -22,25 +22,15 @@
#include "lib/test/run.hpp"
//#include "lib/test/test-helper.hpp"
//#include "lib/time/timequant.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/time/quantiser.hpp"
//#include "lib/time/display.hpp"
#include "lib/util.hpp"
#include <cstdlib>
#include <boost/lexical_cast.hpp>
//#include <boost/algorithm/string/join.hpp>
#include <iostream>
//#include <cstdlib>
using boost::lexical_cast;
using lumiera::error::LUMIERA_ERROR_BOTTOM_VALUE;
using util::isnil;
//using util::contains;
//using std::rand;
using std::cout;
using std::endl;
using std::rand;
//using boost::algorithm::join;
namespace lib {
@ -52,17 +42,27 @@ namespace test{
const uint MAX_FRAMES = 25*500;
const uint MAX_DIRT = 50;
const FSecs F25(1,25);
const FSecs F25(1,25); // duration of one PAL frame
}
/********************************************************
* @test cover the basic Quantiser API.
* This test uses a special quantiser implementation
* with hard coded behaviour to demonstrate and verify
* the usage of a quantiser entity in isolation.
* This test uses a standalone quantiser implementation
* to demonstrate and verify the basic behaviour
* and the usage corner cases of a quantiser.
*
* In this most simple form, a quantiser is defined
* by the time reference point (origin) to use, and
* the frame rate (grid spacing). For each raw time
* value, the quantiser yields a time value aligned
* at the next lower frame bound. Besides that,
* time values are confined to be within
* the interval (Time::MIN, Time::Max)
*
* @see TimeQuantisation_test
*/
class QuantiserBasics_test : public Test
{
@ -84,8 +84,9 @@ namespace test{
uint frames = (rand() % MAX_FRAMES);
FSecs dirt = (F25 / (rand() % MAX_DIRT));
Time rawTime = FSecs(frames, 25) + dirt;
CHECK (Time( frames*F25) <= rawTime);
Time rawTime = dirt + frames*F25;
CHECK (Time( frames *F25) <= rawTime);
CHECK (Time((frames+1)*F25) > rawTime);
Time quantTime (fixQ.gridAlign (rawTime));
@ -149,15 +150,59 @@ namespace test{
void
coverQuantisationCornerCases()
{
// origin at lower end of the time range
FixedFrameQuantiser case1 (1, Time::MIN);
CHECK (Time(0) == case1.gridAlign(Time::MIN));
CHECK (Time(0) == case1.gridAlign(Time::MIN + TimeValue(1) ));
CHECK (Time(1) == case1.gridAlign(Time::MIN + Time(1) ));
CHECK (Time::MAX - Time(1) > case1.gridAlign( Time(-1) ));
CHECK (Time::MAX - Time(1) <= case1.gridAlign( Time (0) ));
CHECK (Time::MAX > case1.gridAlign( Time (0) ));
CHECK (Time::MAX == case1.gridAlign( Time(+1) ));
CHECK (Time::MAX == case1.gridAlign( Time(+2) ));
CHECK (Time(0) == case1.gridAlign(Time::MIN ));
CHECK (Time(0) == case1.gridAlign(Time::MIN +TimeValue(1) ));
CHECK (Time(1) == case1.gridAlign(Time::MIN +Time(1) ));
CHECK (Time::MAX -Time(1) > case1.gridAlign( Time(-1) ));
CHECK (Time::MAX -Time(1) <= case1.gridAlign( Time (0) ));
CHECK (Time::MAX > case1.gridAlign( Time (0) ));
CHECK (Time::MAX == case1.gridAlign( Time(+1) ));
CHECK (Time::MAX == case1.gridAlign( Time(+2) ));
// origin at upper end of the time range
FixedFrameQuantiser case2 (1, Time::MAX);
CHECK (Time( 0) == case2.gridAlign(Time::MAX ));
CHECK (Time(-1) == case2.gridAlign(Time::MAX -TimeValue(1) )); // note: next lower frame
CHECK (Time(-1) == case2.gridAlign(Time::MAX -Time(1) )); // i.e. the same as a whole frame down
CHECK (Time::MIN +Time(1) < case2.gridAlign( Time(+2) ));
CHECK (Time::MIN +Time(1) >= case2.gridAlign( Time(+1) ));
CHECK (Time::MIN < case2.gridAlign( Time(+1) ));
CHECK (Time::MIN == case2.gridAlign( Time( 0) )); // note: because of downward truncating,
CHECK (Time::MIN == case2.gridAlign( Time(-1) )); // resulting values will already exceed
CHECK (Time::MIN == case2.gridAlign( Time(-2) )); // allowed range and thus will be clipped
// maximum frame size is half the time range
Duration hugeFrame(Offset(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( Time(-1) ));
CHECK (Time(0) == case3.gridAlign( Time( 0) ));
CHECK (Time(0) == case3.gridAlign( Time(+1) ));
CHECK (Time(0) == case3.gridAlign(Time::MAX -TimeValue(1) ));
CHECK (Time::MAX == case3.gridAlign(Time::MAX ));
// now displacing this grid by +1sec....
FixedFrameQuantiser case4 (hugeFrame, Time(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 +Time(1) )); // but now exact (unclipped)
CHECK (Time::MIN == case4.gridAlign( Time(-1) ));
CHECK (Time::MIN == case4.gridAlign( Time( 0) ));
CHECK (Time(0) == case4.gridAlign( Time(+1) )); //.....now exactly the frame number zero
CHECK (Time(0) == case4.gridAlign(Time::MAX -TimeValue(1) ));
CHECK (Time(0) == case4.gridAlign(Time::MAX )); //.......still truncated down to frame #0
// larger frames aren't possible
Duration not_really_larger(Time(10000) + hugeFrame);
CHECK (hugeFrame == not_really_larger);
// frame sizes below the time micro grid get trapped
long subAtomic = 2*GAVL_TIME_SCALE; // too small for this universe...
VERIFY_ERROR (BOTTOM_VALUE, FixedFrameQuantiser quark(subAtomic) );
VERIFY_ERROR (BOTTOM_VALUE, FixedFrameQuantiser quark(Duration (FSecs (1,subAtomic))) );
}
};