2008-06-19 00:57:47 +02:00
|
|
|
|
/*
|
|
|
|
|
|
time.h - Utilities for handling time
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
2008, Christian Thaeter <ct@pipapo.org>
|
2008-06-19 00:57:47 +02: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.
|
2008-06-19 00:57:47 +02:00
|
|
|
|
*/
|
|
|
|
|
|
|
2011-01-09 02:13:58 +01:00
|
|
|
|
/** @file time.h
|
|
|
|
|
|
** Common functions for handling of time values.
|
|
|
|
|
|
** Working with time values in sexagesimal format, quantising time and converting
|
|
|
|
|
|
** to/from common timecode formats can be tricky to get right. Thus the goal is
|
|
|
|
|
|
** to concentrate the actual bits of math for these operations into a small number
|
|
|
|
|
|
** of library functions, which are easy to test thoroughly in isolation.
|
|
|
|
|
|
**
|
|
|
|
|
|
** Built on top of that, the actual time handling in the GUI and within the Lumiera
|
|
|
|
|
|
** session is mostly confined to use the opaque lib::time::Time wrapper objects.
|
2022-10-30 23:12:34 +01:00
|
|
|
|
** When time values actually need to be _quantised_ (aligned to a frame grid),
|
2011-01-09 02:13:58 +01:00
|
|
|
|
** this is expressed at the API through using the lib::time::QuTime type, which
|
2022-10-30 23:12:34 +01:00
|
|
|
|
** then in turn can be materialised into a number of _timecode formats_.
|
2011-01-09 02:13:58 +01:00
|
|
|
|
** These definitions ensure that whenever an actual quantisation (rounding)
|
|
|
|
|
|
** operation is performed, the link to the appropriate time grid is available,
|
|
|
|
|
|
** so that multiple output or rendering operations can use differing time origins
|
|
|
|
|
|
** and frame rates simultaneously on the same model.
|
|
|
|
|
|
**
|
2018-11-15 21:13:52 +01:00
|
|
|
|
** The Lumiera Vault Layer functions mostly operate on raw frame counts, which in
|
|
|
|
|
|
** this model are defined to be a special kind of timecode, and thus dependent on
|
|
|
|
|
|
** a preceding time quantisation.
|
2011-01-09 02:13:58 +01:00
|
|
|
|
**
|
2025-05-17 23:12:47 +02:00
|
|
|
|
** @deprecated 2025 this should not be a "simple" C library set aside from the Lumiera
|
|
|
|
|
|
** time handling framework, rather it should be clarified that these are
|
|
|
|
|
|
** implementation helpers and must not be used by any application code.
|
|
|
|
|
|
** It should be checked which of these functions actually need to be
|
|
|
|
|
|
** exposed through an interface header, since these are typically
|
|
|
|
|
|
** used to implement parts of the time handling framework.
|
2011-01-09 02:13:58 +01:00
|
|
|
|
**
|
|
|
|
|
|
** @see lib::time::Time
|
|
|
|
|
|
** @see timequant.hpp
|
|
|
|
|
|
** @see TimeValue_test
|
|
|
|
|
|
**
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-06-19 00:57:47 +02:00
|
|
|
|
#ifndef LUMIERA_TIME_H
|
|
|
|
|
|
#define LUMIERA_TIME_H
|
|
|
|
|
|
|
|
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
|
|
2011-01-09 02:13:58 +01:00
|
|
|
|
#ifdef __cplusplus /*=================== C++ facilities ===================== */
|
|
|
|
|
|
#include "lib/time/timevalue.hpp"
|
|
|
|
|
|
|
2025-05-17 23:12:47 +02:00
|
|
|
|
using lib::time::raw_time_64;
|
|
|
|
|
|
|
2011-01-09 02:13:58 +01:00
|
|
|
|
|
2008-06-19 00:57:47 +02:00
|
|
|
|
/**
|
2011-01-09 02:13:58 +01:00
|
|
|
|
* Converts a fraction of seconds to Lumiera's internal opaque time scale.
|
|
|
|
|
|
* @param fractionalSeconds given as rational number
|
2011-01-09 04:56:46 +01:00
|
|
|
|
* @note inconsistent with Lumiera's general quantisation behaviour,
|
|
|
|
|
|
* here negative fractional micro-ticks are truncated towards zero.
|
|
|
|
|
|
* This was deemed irrelevant in practice.
|
2011-01-09 02:13:58 +01:00
|
|
|
|
*/
|
2025-05-17 23:12:47 +02:00
|
|
|
|
raw_time_64
|
2011-01-09 04:56:46 +01:00
|
|
|
|
lumiera_rational_to_time (lib::time::FSecs const& fractionalSeconds);
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-05-13 04:04:02 +02:00
|
|
|
|
/**
|
|
|
|
|
|
* Converts a frame count into Lumiera's internal time scale.
|
|
|
|
|
|
* based on a framerate given as rational number (e.g. NTSC)
|
|
|
|
|
|
* @note handles only positive frame counts and assumes the
|
|
|
|
|
|
* origin to be at zero.
|
|
|
|
|
|
*/
|
2025-05-17 23:12:47 +02:00
|
|
|
|
raw_time_64
|
2011-05-13 04:04:02 +02:00
|
|
|
|
lumiera_framecount_to_time (uint64_t frameCount, lib::time::FrameRate const& fps);
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-09 04:56:46 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Calculates the duration of one frame in Lumiera time units.
|
|
|
|
|
|
* @param framerate underlying framerate as rational number
|
|
|
|
|
|
* @throw error::Logic on zero framerate
|
|
|
|
|
|
*/
|
2025-05-17 23:12:47 +02:00
|
|
|
|
raw_time_64
|
2011-01-09 04:56:46 +01:00
|
|
|
|
lumiera_frame_duration (lib::time::FrameRate const& fps);
|
2011-01-09 02:13:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" { /* ===================== C interface ======================== */
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-06 13:30:27 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Quantise the given time into a fixed grid, relative to the origin.
|
|
|
|
|
|
* The time grid used for quantisation is comprised of equally spaced intervals,
|
|
|
|
|
|
* rooted at the given origin. The interval starting with the origin is numbered
|
|
|
|
|
|
* as zero. Each interval includes its lower bound, but excludes its upper bound.
|
2025-05-17 23:12:47 +02:00
|
|
|
|
* @param grid spacing of the grid intervals, measured in TimeValue::Scale (µ-ticks)
|
2011-01-06 13:30:27 +01:00
|
|
|
|
* @return number of the grid interval containing the given time.
|
2022-10-30 01:31:25 +02:00
|
|
|
|
* @warning the resulting value is limited to (Time::Min, Time::MAX)
|
2011-01-06 13:30:27 +01:00
|
|
|
|
*/
|
2011-03-31 18:43:50 +02:00
|
|
|
|
int64_t
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_quantise_frames (raw_time_64 time, raw_time_64 origin, raw_time_64 grid);
|
2011-01-06 13:30:27 +01:00
|
|
|
|
|
2011-05-21 06:58:15 +02:00
|
|
|
|
int64_t
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_quantise_frames_fps (raw_time_64 time, raw_time_64 origin, uint framerate);
|
2011-05-21 06:58:15 +02:00
|
|
|
|
|
2011-01-06 13:30:27 +01:00
|
|
|
|
/**
|
2025-04-26 23:59:29 +02:00
|
|
|
|
* Similar to #lumiera_quantise_frames, but returns a grid aligned _relative time_.
|
2022-10-30 01:31:25 +02:00
|
|
|
|
* @return time of start of the grid interval containing the given time,
|
2011-01-06 13:30:27 +01:00
|
|
|
|
* but measured relative to the origin
|
|
|
|
|
|
* @warning because the resulting value needs to be limited to fit into a 64bit long,
|
|
|
|
|
|
* the addressable time range can be considerably reduced. For example, if
|
2011-01-09 02:13:58 +01:00
|
|
|
|
* origin = Time::MIN, then all original time values above zero will be
|
2022-10-30 01:31:25 +02:00
|
|
|
|
* clipped, because the result, relative to origin, needs to be <= Time::MAX
|
2011-01-06 13:30:27 +01:00
|
|
|
|
*/
|
2025-05-17 23:12:47 +02:00
|
|
|
|
raw_time_64
|
|
|
|
|
|
lumiera_quantise_time (raw_time_64 time, raw_time_64 origin, raw_time_64 grid);
|
2011-01-06 13:30:27 +01:00
|
|
|
|
|
2011-01-14 05:33:50 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Calculate time of a grid point (frame start)
|
|
|
|
|
|
* @param nr index number of the grid point (0 is at origin)
|
2025-05-17 23:12:47 +02:00
|
|
|
|
* @param grid spacing of the grid intervals, measured in TimeValue::Scale (µ-ticks)
|
2011-01-14 05:33:50 +01:00
|
|
|
|
* @return time point (frame start) on the Lumiera internal time scale
|
|
|
|
|
|
*/
|
2025-05-17 23:12:47 +02:00
|
|
|
|
raw_time_64
|
|
|
|
|
|
lumiera_time_of_gridpoint (int64_t nr, raw_time_64 origin, raw_time_64 grid);
|
2011-01-14 05:33:50 +01:00
|
|
|
|
|
2009-07-12 22:51:04 +02:00
|
|
|
|
/**
|
2011-05-21 06:58:15 +02:00
|
|
|
|
* Build a time value by summing up the given components.
|
2010-12-13 18:16:15 +01:00
|
|
|
|
* @param millis number of milliseconds
|
|
|
|
|
|
* @param secs number of seconds
|
|
|
|
|
|
* @param mins number of minutes
|
|
|
|
|
|
* @param hours number of hours
|
2009-07-12 22:51:04 +02:00
|
|
|
|
*/
|
2025-05-17 23:12:47 +02:00
|
|
|
|
raw_time_64
|
2009-07-12 22:51:04 +02:00
|
|
|
|
lumiera_build_time (long millis, uint secs, uint mins, uint hours);
|
|
|
|
|
|
|
2010-12-06 16:18:54 +01:00
|
|
|
|
/**
|
2010-12-13 18:16:15 +01:00
|
|
|
|
* Builds a time value by summing up the given components.
|
2011-05-21 06:58:15 +02:00
|
|
|
|
* @param fps framerate (frames per second)
|
|
|
|
|
|
* @param frames number of additional frames
|
|
|
|
|
|
* @param secs number of seconds
|
|
|
|
|
|
* @param mins number of minutes
|
|
|
|
|
|
* @param hours number of hours
|
2010-12-06 16:18:54 +01:00
|
|
|
|
*/
|
2025-05-17 23:12:47 +02:00
|
|
|
|
raw_time_64
|
2011-05-21 06:58:15 +02:00
|
|
|
|
lumiera_build_time_fps (uint fps, uint frames, uint secs, uint mins, uint hours);
|
2010-12-06 16:18:54 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
2010-12-13 18:22:12 +01:00
|
|
|
|
* Builds a time value by summing up the given components.
|
|
|
|
|
|
* The components are interpreted as a NTSC drop-frame timecode.
|
2011-01-19 11:32:03 +01:00
|
|
|
|
* @warning take care not to specify time codes that are illegal NTSC drop-frame times.
|
2010-12-06 16:18:54 +01:00
|
|
|
|
*/
|
2025-05-17 23:12:47 +02:00
|
|
|
|
raw_time_64
|
2010-12-13 18:22:12 +01:00
|
|
|
|
lumiera_build_time_ntsc_drop (uint frames, uint secs, uint mins, uint hours);
|
|
|
|
|
|
|
2011-01-19 11:32:03 +01:00
|
|
|
|
|
|
|
|
|
|
/** Extract the hour part of given time. */
|
2010-12-13 18:16:15 +01:00
|
|
|
|
int
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_time_hours (raw_time_64 time);
|
2010-12-06 16:18:54 +01:00
|
|
|
|
|
2011-01-19 11:32:03 +01:00
|
|
|
|
|
|
|
|
|
|
/** Extract the minute part of given time. */
|
2010-12-13 18:16:15 +01:00
|
|
|
|
int
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_time_minutes (raw_time_64 time);
|
2010-12-06 16:18:54 +01:00
|
|
|
|
|
2011-01-19 11:32:03 +01:00
|
|
|
|
|
|
|
|
|
|
/** Extract the seconds part of given time. */
|
2010-12-13 18:16:15 +01:00
|
|
|
|
int
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_time_seconds (raw_time_64 time);
|
2010-12-06 16:18:54 +01:00
|
|
|
|
|
2011-01-19 11:32:03 +01:00
|
|
|
|
|
|
|
|
|
|
/** Extract the milliseconds part of given time. */
|
2010-12-13 18:16:15 +01:00
|
|
|
|
int
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_time_millis (raw_time_64 time);
|
2010-12-06 16:18:54 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
2011-05-21 06:58:15 +02:00
|
|
|
|
* Extract the remaining frame part of given time.
|
|
|
|
|
|
* @param fps frame rate (frames per second)
|
2010-12-06 16:18:54 +01:00
|
|
|
|
*/
|
2010-12-13 18:16:15 +01:00
|
|
|
|
int
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_time_frames (raw_time_64 time, uint fps);
|
2010-12-10 12:53:39 +01:00
|
|
|
|
|
2010-12-13 18:22:12 +01:00
|
|
|
|
/**
|
2011-01-19 11:32:03 +01:00
|
|
|
|
* Extract the frame part of given time, using NTSC drop-frame timecode.
|
2010-12-13 18:22:12 +01:00
|
|
|
|
*/
|
|
|
|
|
|
int
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_time_ntsc_drop_frames (raw_time_64 time);
|
2010-12-13 18:22:12 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
2011-01-19 11:32:03 +01:00
|
|
|
|
* Extract the second part of given time, using NTSC drop-frame timecode.
|
2010-12-13 18:22:12 +01:00
|
|
|
|
*/
|
|
|
|
|
|
int
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_time_ntsc_drop_seconds (raw_time_64 time);
|
2010-12-13 18:22:12 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
2011-01-19 11:32:03 +01:00
|
|
|
|
* Extract the minute part of given time, using NTSC drop-frame timecode.
|
2010-12-13 18:22:12 +01:00
|
|
|
|
*/
|
|
|
|
|
|
int
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_time_ntsc_drop_minutes (raw_time_64 time);
|
2010-12-13 18:22:12 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
2011-01-19 11:32:03 +01:00
|
|
|
|
* Extract the hour part of given time, using NTSC drop-frame timecode.
|
2010-12-13 18:22:12 +01:00
|
|
|
|
*/
|
|
|
|
|
|
int
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_time_ntsc_drop_hours (raw_time_64 time);
|
2010-12-06 16:18:54 +01:00
|
|
|
|
|
2008-06-19 00:57:47 +02:00
|
|
|
|
|
2013-11-18 00:01:43 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* @internal Diagnostics helper: render time value in H:MM:SS.mmm format.
|
|
|
|
|
|
* @return `safeclib` temporary buffer containing formatted time string
|
|
|
|
|
|
* @note any time output for real should go through quantisation followed
|
|
|
|
|
|
* by rendering into a suitable timecode format.
|
|
|
|
|
|
*/
|
|
|
|
|
|
char*
|
2025-05-17 23:12:47 +02:00
|
|
|
|
lumiera_tmpbuf_print_time (raw_time_64 time);
|
2013-11-18 00:01:43 +01:00
|
|
|
|
|
|
|
|
|
|
|
2011-01-09 02:13:58 +01:00
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
}//extern "C"
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
2011-01-19 11:32:03 +01:00
|
|
|
|
|