2010-12-21 02:05:13 +01:00
|
|
|
|
/*
|
|
|
|
|
|
Quantiser - aligning time values to a time grid
|
|
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
Copyright (C)
|
|
|
|
|
|
2010, Hermann Vosseler <Ichthyostega@web.de>
|
2010-12-21 02:05:13 +01:00
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
**Lumiera** is free software; you can redistribute it and/or modify it
|
|
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
|
|
Free Software Foundation; either version 2 of the License, or (at your
|
|
|
|
|
|
option) any later version. See the file COPYING for further details.
|
2010-12-21 02:05:13 +01:00
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
* *****************************************************************/
|
2010-12-21 02:05:13 +01:00
|
|
|
|
|
|
|
|
|
|
|
2016-11-03 18:22:31 +01:00
|
|
|
|
/** @file quantiser.cpp
|
2016-11-07 16:22:04 +01:00
|
|
|
|
** Implementation of support functions to create grid-aligned time and timecode values
|
2016-11-03 18:20:10 +01:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-04 01:45:11 +01:00
|
|
|
|
#include "lib/time/quantiser.hpp"
|
2010-12-21 02:05:13 +01:00
|
|
|
|
#include "lib/time/timevalue.hpp"
|
2011-01-05 18:15:44 +01:00
|
|
|
|
#include "lib/time/timequant.hpp"
|
2011-01-06 13:31:13 +01:00
|
|
|
|
#include "lib/time.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <boost/rational.hpp>
|
|
|
|
|
|
|
|
|
|
|
|
using boost::rational_cast;
|
2010-12-21 02:05:13 +01:00
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-06 13:31:13 +01:00
|
|
|
|
namespace error = lumiera::error;
|
|
|
|
|
|
|
2010-12-21 02:05:13 +01:00
|
|
|
|
namespace lib {
|
|
|
|
|
|
namespace time {
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-06-05 00:10:37 +02:00
|
|
|
|
PQuant
|
|
|
|
|
|
getDefaultGridFallback()
|
|
|
|
|
|
{
|
|
|
|
|
|
static PQuant globalDefaultGrid (new FixedFrameQuantiser(1));
|
|
|
|
|
|
return globalDefaultGrid; ///////////////////////TICKET #810
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-06 13:31:13 +01:00
|
|
|
|
|
2011-01-15 03:49:35 +01:00
|
|
|
|
Grid::~Grid() { } // hint to emit the VTable here...
|
2011-01-06 04:21:18 +01:00
|
|
|
|
|
2011-01-06 13:31:13 +01:00
|
|
|
|
|
2012-12-01 07:46:49 +01:00
|
|
|
|
/* Note: the ctor QuTime(TimeValue, Symbol) and the static function
|
|
|
|
|
|
* PQuant Quantiser::retrieve (Symbol) are defined in common-services.cpp
|
|
|
|
|
|
* To use this special convenience shortcuts, you need to link against liblumieracore.so
|
|
|
|
|
|
* This allows to use the Advice-system to retrieve grid definitions directly from the session
|
2011-01-16 23:58:42 +01:00
|
|
|
|
*/
|
2011-01-05 18:15:44 +01:00
|
|
|
|
|
|
|
|
|
|
|
2011-01-16 23:58:42 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* build a quantised time value by explicitly specifying a
|
|
|
|
|
|
* grid alignment facility and without any hidden reference
|
|
|
|
|
|
* to the Lumiera session. This is mainly intended for
|
|
|
|
|
|
* debugging and unit testing.
|
|
|
|
|
|
*/
|
2011-01-15 00:52:02 +01:00
|
|
|
|
QuTime::QuTime (TimeValue raw, PQuant quantisation_to_use)
|
2011-01-13 23:56:52 +01:00
|
|
|
|
: Time(raw)
|
2011-01-15 00:52:02 +01:00
|
|
|
|
, quantiser_(quantisation_to_use)
|
2011-01-05 18:15:44 +01:00
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-06 13:31:13 +01:00
|
|
|
|
/** Create a quantiser based on a fixed constant spaced grid, rooted at the reference point
|
|
|
|
|
|
* as origin of the scale. Quantisation then means to determine the grid interval containing
|
|
|
|
|
|
* a given raw time value. Here, the grid interval number zero \em starts at the origin;
|
|
|
|
|
|
* each interval includes its lower bound and excludes its upper bound.*/
|
2011-01-09 04:56:46 +01:00
|
|
|
|
FixedFrameQuantiser::FixedFrameQuantiser (FrameRate const& frames_per_second, TimeValue referencePoint)
|
2011-01-06 13:31:13 +01:00
|
|
|
|
: origin_(referencePoint)
|
2011-01-09 11:41:08 +01:00
|
|
|
|
, raster_(__ensure_nonzero(frames_per_second.duration()))
|
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
FixedFrameQuantiser::FixedFrameQuantiser (Duration const& frame_duration, TimeValue referencePoint)
|
|
|
|
|
|
: origin_(referencePoint)
|
|
|
|
|
|
, raster_(__ensure_nonzero(frame_duration))
|
2011-01-05 18:15:44 +01:00
|
|
|
|
{ }
|
|
|
|
|
|
|
2010-12-21 02:05:13 +01:00
|
|
|
|
|
|
|
|
|
|
|
2011-05-05 19:05:48 +02:00
|
|
|
|
|
|
|
|
|
|
/** convenience shortcut: \em materialise a raw time value
|
|
|
|
|
|
* based on this grid or time axis, but returning a raw time value.
|
2023-05-29 04:43:10 +02:00
|
|
|
|
* Implemented as combination of the #gridPoint and #timeOf operations,
|
2011-05-05 19:05:48 +02:00
|
|
|
|
* i.e. we quantise into this scale, but transform the result back onto
|
2023-01-02 23:45:55 +01:00
|
|
|
|
* the global raw time value scale.
|
2011-05-05 19:05:48 +02:00
|
|
|
|
* @warning this operation incurs information loss. Values may be rounded
|
|
|
|
|
|
* and / or clipped, according to the grid used. And, contrary to
|
|
|
|
|
|
* a QuTime value, the information about the actual grid is
|
2023-05-31 03:27:13 +02:00
|
|
|
|
* discarded. Please resist the temptation to abuse this
|
|
|
|
|
|
* operation to "just get a simple number", without
|
|
|
|
|
|
* understanding what quantisation means!
|
2011-05-05 19:05:48 +02:00
|
|
|
|
*/
|
|
|
|
|
|
TimeValue
|
|
|
|
|
|
Quantiser::materialise (TimeValue const& raw) const
|
|
|
|
|
|
{
|
|
|
|
|
|
return timeOf (gridPoint (raw));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-12-05 01:05:23 +01:00
|
|
|
|
/** grid quantisation (alignment).
|
|
|
|
|
|
* Determine the next lower grid interval start point,
|
|
|
|
|
|
* using a simple constant spaced time grid defined by
|
|
|
|
|
|
* origin and framerate stored within this quantiser.
|
|
|
|
|
|
* @warning returned frame count might exceed the valid
|
|
|
|
|
|
* range when converting back into a TimeValue.
|
|
|
|
|
|
* @see #lumiera_quantise_frames
|
|
|
|
|
|
*/
|
|
|
|
|
|
FrameCnt
|
|
|
|
|
|
FixedFrameQuantiser::gridPoint (TimeValue const& rawTime) const
|
|
|
|
|
|
{
|
|
|
|
|
|
return lumiera_quantise_frames (_raw(rawTime), _raw(origin_), _raw(raster_));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** transform into the local time scale grid aligned.
|
2011-01-06 13:31:13 +01:00
|
|
|
|
* 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
|
2022-12-05 01:05:23 +01:00
|
|
|
|
* containing the rawTime, _relative to the origin_
|
2011-01-06 13:31:13 +01:00
|
|
|
|
* of the time scale used by this quantiser.
|
|
|
|
|
|
* @warning returned time values are limited by the
|
2011-01-13 23:56:52 +01:00
|
|
|
|
* valid range of lumiera::Time
|
2011-01-06 13:31:13 +01:00
|
|
|
|
* @see #lumiera_quantise_time
|
|
|
|
|
|
*/
|
|
|
|
|
|
TimeValue
|
2022-12-05 01:05:23 +01:00
|
|
|
|
FixedFrameQuantiser::gridLocal (TimeValue const& rawTime) const
|
2011-01-06 04:21:18 +01:00
|
|
|
|
{
|
2011-01-09 04:56:46 +01:00
|
|
|
|
return TimeValue (lumiera_quantise_time (_raw(rawTime), _raw(origin_), _raw(raster_)));
|
2011-01-06 04:21:18 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-14 05:33:50 +01:00
|
|
|
|
/** 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
|
|
|
|
|
|
* valid range of lumiera::Time
|
|
|
|
|
|
*/
|
|
|
|
|
|
TimeValue
|
2013-11-18 00:01:43 +01:00
|
|
|
|
FixedFrameQuantiser::timeOf (FrameCnt gridPoint) const
|
2011-01-14 05:33:50 +01:00
|
|
|
|
{
|
|
|
|
|
|
return TimeValue (lumiera_time_of_gridpoint (gridPoint, _raw(origin_), _raw(raster_)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-01-13 23:56:52 +01:00
|
|
|
|
|
2011-01-15 03:49:35 +01:00
|
|
|
|
/** calculate time coordinates of a time spec relative to this quantised time scale
|
|
|
|
|
|
* @param gridTime seconds relative to the origin of this scale
|
|
|
|
|
|
* @param gridOffset additional offset in grid intervals (frames)
|
|
|
|
|
|
* @return time point measured in Lumiera internal time
|
|
|
|
|
|
* @warning returned time values are limited by the
|
|
|
|
|
|
* valid range of lumiera::Time
|
|
|
|
|
|
*/
|
|
|
|
|
|
TimeValue
|
|
|
|
|
|
FixedFrameQuantiser::timeOf (FSecs gridTime, int gridOffset) const
|
|
|
|
|
|
{
|
|
|
|
|
|
Time gt(gridTime);
|
|
|
|
|
|
TimeVar timePoint = gt + origin_;
|
2011-06-08 02:12:38 +02:00
|
|
|
|
timePoint += gridOffset * Offset(raster_);
|
2011-01-15 03:49:35 +01:00
|
|
|
|
return timePoint;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-13 23:56:52 +01:00
|
|
|
|
|
2010-12-21 02:05:13 +01:00
|
|
|
|
|
2011-01-04 01:45:11 +01:00
|
|
|
|
LUMIERA_ERROR_DEFINE (UNKNOWN_GRID, "referring to an undefined grid or scale in value quantisation");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-12-21 02:05:13 +01:00
|
|
|
|
}} // lib::time
|
2011-01-06 13:31:13 +01:00
|
|
|
|
|