lumiera_/src/lib/time/timequant.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

166 lines
6 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.

/*
TIMEQUANT.hpp - quantised (grid aligned) time values
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 timequant.hpp
** Support library to represent grid-aligned time specifications
** This is part of Lumiera's time and time code handling framework.
** The QuTime entity represents the link between the internal precise
** time specifications and external representation formatted according
** to some well established time code format: QuTime both holds a precise
** internal time::TimeValue entry, plus a reference to the _time grid_ to
** be used, when it comes to _quantising_ (grid-aligning) those values.
** And it offers a dedicated API to "materialise" this (still complete and
** precise) time value into an external representation.
**
** # Collaborations
**
** lib::time::Time is the ubiquitous yet opaque internal time "instant" used
** in Lumiera to designate time points (and by extension also a TimeSpan).
** What such an _internal time instant_ actually means, depends on the context,
** yet it is the implementation's (not the user's) responsibility to keep that
** meaning straight.
**
** However, by creating a [Quantised Time](\ref lib::time::QuTime), the association
** to some time scale or time grid is made explicit; the time value within QuTime
** is stored in full precision though, without performing any "rounding" yet.
**
** Only by building or casting into a _time code,_ the actual quantisation is
** performed, which means to align the time value to the next grid point and
** discard excess timing information. There are several [time formats](\ref formats.hpp)
** available to choose from, like Hour-Minute-Second, or SMPTE (h-m-s + frame) or
** fractional seconds or just a frame count with implicit frame rate.
**
** How the _quantisation_ or _grid alignment_ is actually performed is up to the
** discretion of the lib::time::Quantiser; an actually Quantiser instance also
** represents a common notion of some specific time grid, together with a usage
** context. Notably, a "25 fps grid" means to start timing when the playback
** starts, and to proceed in steps of 1/25sec. Conceptually (not-yet-implemented
** as of 11/2022) a frame grid could also imply to anchor the time at some global
** time zone, allowing to integrate _live content_ into the timeline -- and the
** actual link to wall-clock time would be made explicit by some _placement_
** somewhere on the actual timeline.
**
*/
#ifndef LIB_TIME_TIMEQUANT_H
#define LIB_TIME_TIMEQUANT_H
#include "lib/time/timevalue.hpp"
#include "lib/time/quantiser.hpp"
#include "lib/time/timecode.hpp"
#include "lib/symbol.hpp"
//#include <boost/operators.hpp>
#include <string>
namespace lib {
namespace time {
using lib::Symbol;
/**
* grid aligned time specification, referring to a specific scale.
* A quantised time value allows to access the time specification
* as numeric value in one of the supported timecode formats, and
* relative to the defined time scale. Usually this time scale
* exists already in the Lumiera session and is referred simply
* by symbolic ID, it will be fetched on demand through the
* [advice system](\ref advice.hpp).
*
* By creating a QuTime value, the relation to such a predefined
* time scale is made explicit. This doesn't change the internal
* time value, but the actual creation of a timecode formatted
* value (#formatAs) usually implies to quantise or grid align
* the time to the frame grid specific to this time scale.
*/
class QuTime
: public Time
{
PQuant quantiser_;
public:
QuTime (TimeValue raw, Symbol gridID); ///< @note defined in common-services.cpp
QuTime (TimeValue raw, PQuant quantisation_to_use);
operator PQuant() const; ///< @return `shared-ptr` to the associated time grid (or time scale)
template<class FMT>
bool supports() const; ///< does our implicit time grid support building that timecode format?
template<class FMT>
typename format::Traits<FMT>::TimeCode
formatAs() const; ///< create new time code instance, then #castInto
template<class TC>
void
castInto (TC& timecode) const; ///< quantise into implicit grid, then rebuild the timecode
/** receive change message, which
might cause re-quantisation */
void accept (Mutation const&);
};
/* == implementation == */
inline
QuTime::operator PQuant() const
{
ASSERT (quantiser_);
return quantiser_;
}
template<class FMT>
inline bool
QuTime::supports() const
{
return quantiser_->supports<FMT>();
}
template<class FMT>
inline typename format::Traits<FMT>::TimeCode
QuTime::formatAs() const
{
using TC = typename format::Traits<FMT>::TimeCode;
return TC(*this);
}
/**
* @tparam TC the kind of time code to use as target
* @param timecode existing instance of that timecode, to be overwritten
* @remark this is the basic operation to convert an (internal) time value
* into a time code format. QuTime is already associated with some
* _time grid_ for quantisation, but the internal value is precise.
* This operation creates a quantised (frame aligned) transient copy,
* and uses this to adjust/modify the fields in the given timecode.
*/
template<class TC>
inline void
QuTime::castInto (TC& timecode) const
{
using Format = typename TC::Format;
REQUIRE (supports<Format>());
Format::rebuild (timecode, *quantiser_, TimeValue(*this));
}
}} // lib::time
#endif