* 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.
155 lines
5 KiB
C++
155 lines
5 KiB
C++
/*
|
||
QUANTISER.hpp - aligning time values to a time grid
|
||
|
||
Copyright (C)
|
||
2010, Hermann Vosseler <Ichthyostega@web.de>
|
||
|
||
**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.
|
||
|
||
*/
|
||
|
||
|
||
/** @file quantiser.hpp
|
||
** Library functions to support the formation of grid-aligned time values.
|
||
** This is a crucial part of Lumiera's time and time handling framework; it
|
||
** serves as link between the precise internal time representation and various
|
||
** grid-aligned external standard time representations. The underlying theme is,
|
||
** by forcing all conversions to go through this central set of library functions,
|
||
** the notorious act of frame-aligning / grid-aligning time values, which can not
|
||
** be avoided, will at least be performed in a reproducible and predictable way.
|
||
** Moreover, the time handling library was built in a way such as to encourage
|
||
** use of the internal, abstracted yet precise time entities, so that the
|
||
** inevitable conversion to the imprecise but well-established external
|
||
** entities (frame numbers, SMPTE, drop frame, HMS) happens as late as possible.
|
||
*/
|
||
|
||
|
||
#ifndef LIB_TIME_QUANTISER_H
|
||
#define LIB_TIME_QUANTISER_H
|
||
|
||
#include "lib/error.hpp"
|
||
#include "lib/time/grid.hpp"
|
||
#include "lib/time/formats.hpp"
|
||
#include "lib/time/timevalue.hpp"
|
||
#include "lib/iter-adapter.hpp"
|
||
|
||
#include <vector>
|
||
#include <string>
|
||
#include <cmath>
|
||
|
||
|
||
namespace lib {
|
||
namespace time {
|
||
|
||
LUMIERA_ERROR_DECLARE (UNKNOWN_GRID); ///< referring to an undefined grid or scale in value quantisation
|
||
|
||
|
||
namespace { // stashed here for later
|
||
|
||
template<typename NUM>
|
||
struct ValTrait;
|
||
|
||
template<>
|
||
struct ValTrait<int>
|
||
{
|
||
static int asInt (int val) { return val; }
|
||
static double asDouble (int val) { return val; }
|
||
};
|
||
|
||
template<>
|
||
struct ValTrait<double>
|
||
{
|
||
static int asInt (double val) { return std::floor(0.5+val); } ///< in accordance with Lumiera's time handling RfC
|
||
static double asDouble (double val) { return val; }
|
||
};
|
||
|
||
}
|
||
|
||
|
||
|
||
/** @todo placeholder for accessing
|
||
* a current or default session grid.
|
||
* To be implemented later.
|
||
*/
|
||
PQuant getDefaultGridFallback(); ///////////////////////TICKET #810
|
||
|
||
|
||
|
||
|
||
|
||
/**
|
||
* Facility to create grid-aligned time values.
|
||
* Effectively, a quantiser exposes the value Grid API, but
|
||
* additionally also manages a set of supported (display) formats or
|
||
* "time code" formats. Plus there is an static API to fetch a suitable
|
||
* quantiser instance by-name; actually this utilises a hidden link to
|
||
* the Lumiera session. Time quantisation and timecode handling explicitly
|
||
* relies on this Quantiser interface.
|
||
*
|
||
*/
|
||
class Quantiser
|
||
: public virtual Grid
|
||
{
|
||
protected:
|
||
format::Supported supportedFormats_;
|
||
|
||
Quantiser()
|
||
: supportedFormats_(format::SupportStandardTimecode())
|
||
{ }
|
||
|
||
public:
|
||
template<class FMT>
|
||
bool
|
||
supports() const
|
||
{
|
||
return supportedFormats_.check<FMT>();
|
||
}
|
||
|
||
static PQuant retrieve (Symbol gridID); ///< @note defined in common-services.cpp
|
||
TimeValue materialise (TimeValue const& raw) const;
|
||
|
||
|
||
//------Grid-API----------------------------------------------
|
||
virtual FrameCnt gridPoint (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;
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
/**
|
||
* Simple stand-alone Quantiser implementation based on a constant sized gird.
|
||
* This is a self-contained quantiser implementation without any implicit referral
|
||
* to the Lumiera session. As such it is suited for simplified unit testing.
|
||
* @warning real Stage and Steam-Layer code should always fetch a quantiser from the
|
||
* Session, referring to a pre defined TimeGrid. Basically, the overall purpose of
|
||
* the time-quantisation framework is to enforce such a link to a distinct time scale
|
||
* and quantisation, so to prevent "wild and uncoordinated" rounding attempts.
|
||
*/
|
||
class FixedFrameQuantiser
|
||
: public Quantiser
|
||
{
|
||
Time origin_;
|
||
Duration raster_;
|
||
|
||
public:
|
||
FixedFrameQuantiser (FrameRate const& frames_per_second, TimeValue referencePoint =TimeValue(0));
|
||
FixedFrameQuantiser (Duration const& frame_duration, TimeValue referencePoint =TimeValue(0));
|
||
|
||
FrameCnt gridPoint (TimeValue const&) const;
|
||
TimeValue gridLocal (TimeValue const&) const;
|
||
TimeValue timeOf (FrameCnt gridPoint) const;
|
||
TimeValue timeOf (FSecs, int =0) const;
|
||
|
||
};
|
||
|
||
|
||
|
||
}} // lib::time
|
||
#endif
|