53 #include <boost/rational.hpp> 54 #include <boost/lexical_cast.hpp> 61 using boost::rational_cast;
62 using boost::lexical_cast;
73 extern const std::string FAILURE_INDICATOR;
78 const gavl_time_t TimeValue::SCALE = GAVL_TIME_SCALE;
82 const Time
Time::MAX ( TimeValue::buildRaw_(+std::numeric_limits<gavl_time_t>::max() / 30) );
83 const Time Time::MIN ( TimeValue::buildRaw_(-_raw(
Time::MAX) ) );
84 const Time Time::ZERO;
86 const Time Time::ANYTIME(Time::MIN);
89 const Offset Offset::ZERO (Time::ZERO);
93 Literal DIAGNOSTIC_FORMAT{
"%s%01d:%02d:%02d.%03d"};
100 #define TIME_SCALE_MS (lib::time::TimeValue::SCALE / 1000) 113 Time::Time (
long millis
130 Offset::Offset (
FSecs const& delta_in_secs)
139 TimeValue::operator string()
const 142 int64_t millis, seconds;
143 bool negative = (time < 0);
145 if (negative) time = -time;
147 millis = time % 1000;
148 seconds = time / 1000;
150 return string (negative ?
"-" :
"")
151 + (seconds>0 or time==0? lexical_cast<
string> (seconds)+
"s" :
"")
152 + (millis>0? lexical_cast<
string> (millis)+
"ms" :
"")
164 Time::operator string()
const 167 int millis, seconds, minutes, hours;
168 bool negative = (time < 0);
174 millis = time % 1000;
191 Offset::operator string()
const 193 return (
t_< 0?
"" :
"∆")
194 + TimeValue::operator string();
197 Duration::operator string()
const 199 return "≺"+TimeValue::operator string()+
"≻";
202 TimeSpan::operator string()
const 204 return string (start())
205 + string (duration());
210 template<
typename RAT>
212 renderFraction (RAT
const& frac,
Literal postfx) noexcept
214 std::ostringstream buffer;
215 if (1 == frac.denominator() or 0 == frac.numerator())
216 buffer << frac.numerator() << postfx;
218 buffer << frac <<postfx;
222 {
return meta::FAILURE_INDICATOR; }
226 FrameRate::operator string()
const 228 return renderFraction (*
this,
"FPS");
238 return reinterpret_cast<TimeValue const&
> (raw);
245 const FrameRate FrameRate::NTSC (30000,1001);
248 const FrameRate FrameRate::HALTED (1,std::numeric_limits<int>::max());
257 throw error::Logic (
"Impossible to quantise to an zero spaced frame grid" 258 , error::LUMIERA_ERROR_BOTTOM_VALUE);
268 const uint
RATE_LIMIT{std::numeric_limits<uint>::max() / 1024};
276 boost::rational<uint>
279 const double UPPER_LIMIT = int64_t(
RATE_LIMIT*1024) << 31;
280 const int64_t HAZARD = util::ilog2(
RATE_LIMIT);
282 double doo = limited (1.0, fabs(fps) *
RATE_LIMIT + 0.5, UPPER_LIMIT);
284 util::Rat quantised{boo
288 int64_t num = quantised.numerator();
289 int64_t toxic = util::ilog2(abs(num));
290 toxic = util::max (0, toxic - HAZARD);
292 int64_t base = quantised.denominator();
295 base = util::max (base >> toxic, 1);
296 num = util::reQuant (num, quantised.denominator(), base);
307 boost::rational<uint>
310 boost::rational<uint64_t> quot{cnt,
_raw(timeReference)};
314 ,uint(quot.denominator())
327 boost::rational<int64_t> distance (this->
t_);
329 gavl_time_t microTicks = floordiv (distance.numerator(), distance.denominator());
338 double distance(this->
t_);
340 gavl_time_t microTicks = floor (distance);
361 return reinterpret_cast<Duration const&
> (maxDelta);
364 const TimeSpan TimeSpan::ALL {Time::MIN, Duration::MAX};
372 return lib::time::renderFraction (val,
"sec");
388 int milliseconds, seconds, minutes, hours;
389 bool negative = (time < 0);
395 milliseconds = time % 1000;
404 negative ?
"-" :
"", hours, minutes, seconds, milliseconds);
406 ENSURE(buffer != NULL);
416 if (
abs(fractionalSeconds) > lib::time::FSEC_MAX)
417 return (fractionalSeconds < 0? -1:+1)
418 * std::numeric_limits<int64_t>::max();
420 return gavl_time_t(util::reQuant (fractionalSeconds.numerator()
421 ,fractionalSeconds.denominator()
430 boost::rational<uint64_t> framerate (fps.numerator(), fps.denominator());
439 throw error::Logic (
"Impossible to quantise to an zero spaced frame grid" 440 , error::LUMIERA_ERROR_BOTTOM_VALUE);
442 FSecs duration = 1 / fps;
450 calculate_quantisation (gavl_time_t
time, gavl_time_t origin, gavl_time_t grid)
453 return floordiv (time,grid);
457 calculate_quantisation (gavl_time_t time, gavl_time_t origin, uint framerate, uint framerate_divisor=1)
460 REQUIRE (framerate_divisor);
462 const int64_t limit_num = std::numeric_limits<gavl_time_t>::max() / framerate;
463 const int64_t limit_den = std::numeric_limits<gavl_time_t>::max() / framerate_divisor;
467 if (
abs(time) < limit_num and microScale < limit_den)
471 return floordiv (time*framerate, microScale*framerate_divisor);
477 gavl_time_t frameDuration = microScale / framerate;
478 return calculate_quantisation (time,origin, frameDuration);
487 return calculate_quantisation (time, origin, grid);
491 lumiera_quantise_frames_fps (gavl_time_t
time, gavl_time_t origin, uint framerate)
493 return calculate_quantisation (time, origin, framerate);
499 int64_t count = calculate_quantisation (time, origin, grid);
500 gavl_time_t alignedTime = count * grid;
507 gavl_time_t offset = nr * grid;
508 return origin + offset;
515 gavl_time_t time = millis
518 + 1000 * 60 * 60 * hours;
526 gavl_time_t time = 1000LL * frames/fps
529 + 1000 * 60 * 60 * hours;
561 REQUIRE (fps < uint(std::numeric_limits<int>::max()));
573 const uint FRAMES_PER_10min = 10*60 * 30000/1001;
574 const uint FRAMES_PER_1min = 1*60 * 30000/1001;
575 const uint DISCREPANCY = (1*60 * 30) - FRAMES_PER_1min;
586 int64_t frameNr = calculate_quantisation (time, 0, 30000, 1001);
589 lldiv_t tenMinFrames = lldiv (frameNr, FRAMES_PER_10min);
594 int64_t remainingMinutes = (tenMinFrames.rem - DISCREPANCY) / FRAMES_PER_1min;
596 int64_t dropIncidents = (10-1) * tenMinFrames.quot + remainingMinutes;
597 return frameNr + 2*dropIncidents;
628 uint64_t total_mins = 60 * hours + mins;
629 uint64_t total_frames = 30*60*60 * hours
633 - 2 * (total_mins - total_mins / 10);
I floordiv(I num, I den)
floor function for integer arithmetics.
int lumiera_time_ntsc_drop_frames(gavl_time_t time)
Extract the frame part of given time, using NTSC drop-frame timecode.
static const Duration MAX
maximum possible temporal extension
int lumiera_time_hours(gavl_time_t time)
Extract the hour part of given time.
gavl_time_t lumiera_build_time(long millis, uint secs, uint mins, uint hours)
Build a time value by summing up the given components.
Common functions for handling of time values.
Rational number support, based on boost::rational.
gavl_time_t lumiera_framecount_to_time(uint64_t frameCount, FrameRate const &fps)
Converts a frame count into Lumiera's internal time scale.
Framerate specified as frames per second.
inline string literal This is a marker type to indicate that
static const gavl_time_t SCALE
Number of micro ticks (µs) per second as basic time scale.
Offset stretchedByRationalFactor(boost::rational< int64_t >) const
int lumiera_time_ntsc_drop_seconds(gavl_time_t time)
Extract the second part of given time, using NTSC drop-frame timecode.
int64_t calculate_drop_frame_number(gavl_time_t time)
reverse the drop-frame calculation
int64_t lumiera_quantise_frames(gavl_time_t time, gavl_time_t origin, gavl_time_t grid)
Quantise the given time into a fixed grid, relative to the origin.
int lumiera_time_frames(gavl_time_t time, uint fps)
Extract the remaining frame part of given time.
gavl_time_t lumiera_build_time_ntsc_drop(uint frames, uint secs, uint mins, uint hours)
Builds a time value by summing up the given components.
Round robin temporary buffers.
A front-end for using printf-style formatting.
int lumiera_time_millis(gavl_time_t time)
Extract the milliseconds part of given time.
static const Duration NIL
constant to indicate "no duration"
#define MAX(A, B)
the inevitable MAX macro, sometimes still necessary in template code
Implementation namespace for support and library code.
Time(int)
suppress possible direct conversions
Derived specific exceptions within Lumiera's exception hierarchy.
static const FrameRate STEP
1 frame per second
Duration abs() const
interpret the distance given by this offset as a time duration
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
static TimeValue buildRaw_(gavl_time_t)
Utilities for quantisation (grid alignment) and comparisons.
boost::rational< int64_t > FSecs
rational representation of fractional seconds
#define TIME_SCALE_MS
scale factor used locally within this implementation header.
Duration duration() const
duration of one frame
int lumiera_time_ntsc_drop_hours(gavl_time_t time)
Extract the hour part of given time, using NTSC drop-frame timecode.
gavl_time_t lumiera_quantise_time(gavl_time_t time, gavl_time_t origin, gavl_time_t grid)
Similar to lumiera_quantise_frames, but returns a grid aligned relative time.
gavl_time_t lumiera_time_of_gridpoint(int64_t nr, gavl_time_t origin, gavl_time_t grid)
Calculate time of a grid point (frame start)
Lumiera error handling (C++ interface).
Offset measures a distance in time.
Duration is the internal Lumiera time metric.
boost::rational< uint > __framerate_approximation(double fps)
NUM constexpr limited(NB lowerBound, NUM val, NB upperBound)
force a numeric to be within bounds, inclusively
int lumiera_time_seconds(gavl_time_t time)
Extract the seconds part of given time.
A time interval anchored at a specific point in time.
int64_t FrameCnt
relative framecount or frame number.
a family of time value like entities and their relationships.
int lumiera_time_minutes(gavl_time_t time)
Extract the minute part of given time.
basic constant internal time value.
gavl_time_t lumiera_rational_to_time(FSecs const &fractionalSeconds)
Offset stretchedByFloatFactor(double) const
gavl_time_t t_
the raw (internal) time value used to implement the time types
friend gavl_time_t _raw(TimeValue const &time)
const uint RATE_LIMIT
a rather arbitrary safety limit imposed on internal numbers used to represent a frame rate...
gavl_time_t lumiera_frame_duration(FrameRate const &fps)
Calculates the duration of one frame in Lumiera time units.
int lumiera_time_ntsc_drop_minutes(gavl_time_t time)
Extract the minute part of given time, using NTSC drop-frame timecode.
gavl_time_t lumiera_build_time_fps(uint fps, uint frames, uint secs, uint mins, uint hours)
Builds a time value by summing up the given components.
static const FrameRate PAL
predefined constant for PAL framerate
char * lumiera_tmpbuf_print_time(gavl_time_t time)
char * lumiera_tmpbuf_snprintf(size_t size, const char *fmt,...)
Construct a string in a tmpbuf.