LUMIERA.clone/src/lib/time/quantiser.hpp
Ichthyostega 806db414dd 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

155 lines
5 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
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