62 #include <boost/rational.hpp> 63 #include <boost/lexical_cast.hpp> 70 using boost::rational_cast;
71 using boost::lexical_cast;
82 extern const std::string FAILURE_INDICATOR;
87 const gavl_time_t TimeValue::SCALE = GAVL_TIME_SCALE;
91 const Time
Time::MAX ( TimeValue::buildRaw_(+std::numeric_limits<gavl_time_t>::max() / 30) );
92 const Time Time::MIN ( TimeValue::buildRaw_(-_raw(
Time::MAX) ) );
93 const Time Time::ZERO;
95 const Time Time::ANYTIME(Time::MIN);
98 const Offset Offset::ZERO (Time::ZERO);
102 Literal DIAGNOSTIC_FORMAT{
"%s%01d:%02d:%02d.%03d"};
109 #define TIME_SCALE_MS (lib::time::TimeValue::SCALE / 1000) 122 Time::Time (
long millis
139 Offset::Offset (
FSecs const& delta_in_secs)
148 TimeValue::operator string()
const 151 int64_t millis, seconds;
152 bool negative = (time < 0);
154 if (negative) time = -time;
156 millis = time % 1000;
157 seconds = time / 1000;
159 return string (negative ?
"-" :
"")
160 + (seconds>0 or time==0? lexical_cast<
string> (seconds)+
"s" :
"")
161 + (millis>0? lexical_cast<
string> (millis)+
"ms" :
"")
173 Time::operator string()
const 176 int millis, seconds, minutes, hours;
177 bool negative = (time < 0);
183 millis = time % 1000;
200 Offset::operator string()
const 202 return (
t_< 0?
"" :
"∆")
203 + TimeValue::operator string();
206 Duration::operator string()
const 208 return "≺"+TimeValue::operator string()+
"≻";
211 TimeSpan::operator string()
const 213 return string (start())
214 + string (duration());
219 template<
typename RAT>
221 renderFraction (RAT
const& frac,
Literal postfx) noexcept
223 std::ostringstream buffer;
224 if (1 == frac.denominator() or 0 == frac.numerator())
225 buffer << frac.numerator() << postfx;
227 buffer << frac <<postfx;
231 {
return meta::FAILURE_INDICATOR; }
235 FrameRate::operator string()
const 237 return renderFraction (*
this,
"FPS");
247 return reinterpret_cast<TimeValue const&
> (raw);
254 const FrameRate FrameRate::NTSC (30000,1001);
257 const FrameRate FrameRate::HALTED (1,std::numeric_limits<int>::max());
266 throw error::Logic (
"Impossible to quantise to an zero spaced frame grid" 267 , error::LUMIERA_ERROR_BOTTOM_VALUE);
277 const uint
RATE_LIMIT{std::numeric_limits<uint>::max() / 1024};
285 boost::rational<uint>
288 const double UPPER_LIMIT = int64_t(
RATE_LIMIT*1024) << 31;
289 const int64_t HAZARD = util::ilog2(
RATE_LIMIT);
291 double doo = limited (1.0, fabs(fps) *
RATE_LIMIT + 0.5, UPPER_LIMIT);
293 util::Rat quantised{boo
297 int64_t num = quantised.numerator();
298 int64_t toxic = util::ilog2(abs(num));
299 toxic = util::max (0, toxic - HAZARD);
301 int64_t base = quantised.denominator();
304 base = util::max (base >> toxic, 1);
305 num = util::reQuant (num, quantised.denominator(), base);
316 boost::rational<uint>
319 boost::rational<uint64_t> quot{cnt,
_raw(timeReference)};
323 ,uint(quot.denominator())
336 boost::rational<int64_t> distance (this->
t_);
338 gavl_time_t microTicks = floordiv (distance.numerator(), distance.denominator());
347 double distance(this->
t_);
349 gavl_time_t microTicks = floor (distance);
370 return reinterpret_cast<Duration const&
> (maxDelta);
373 const TimeSpan TimeSpan::ALL {Time::MIN, Duration::MAX};
381 return lib::time::renderFraction (val,
"sec");
397 int milliseconds, seconds, minutes, hours;
398 bool negative = (time < 0);
404 milliseconds = time % 1000;
413 negative ?
"-" :
"", hours, minutes, seconds, milliseconds);
415 ENSURE(buffer != NULL);
425 if (
abs(fractionalSeconds) > lib::time::FSEC_MAX)
426 return (fractionalSeconds < 0? -1:+1)
427 * std::numeric_limits<int64_t>::max();
429 return gavl_time_t(util::reQuant (fractionalSeconds.numerator()
430 ,fractionalSeconds.denominator()
439 boost::rational<uint64_t> framerate (fps.numerator(), fps.denominator());
448 throw error::Logic (
"Impossible to quantise to an zero spaced frame grid" 449 , error::LUMIERA_ERROR_BOTTOM_VALUE);
451 FSecs duration = 1 / fps;
459 calculate_quantisation (gavl_time_t
time, gavl_time_t origin, gavl_time_t grid)
462 return floordiv (time,grid);
466 calculate_quantisation (gavl_time_t time, gavl_time_t origin, uint framerate, uint framerate_divisor=1)
469 REQUIRE (framerate_divisor);
471 const int64_t limit_num = std::numeric_limits<gavl_time_t>::max() / framerate;
472 const int64_t limit_den = std::numeric_limits<gavl_time_t>::max() / framerate_divisor;
476 if (
abs(time) < limit_num and microScale < limit_den)
480 return floordiv (time*framerate, microScale*framerate_divisor);
486 gavl_time_t frameDuration = microScale / framerate;
487 return calculate_quantisation (time,origin, frameDuration);
496 return calculate_quantisation (time, origin, grid);
500 lumiera_quantise_frames_fps (gavl_time_t
time, gavl_time_t origin, uint framerate)
502 return calculate_quantisation (time, origin, framerate);
508 int64_t count = calculate_quantisation (time, origin, grid);
509 gavl_time_t alignedTime = count * grid;
516 gavl_time_t offset = nr * grid;
517 return origin + offset;
524 gavl_time_t time = millis
527 + 1000 * 60 * 60 * hours;
535 gavl_time_t time = 1000LL * frames/fps
538 + 1000 * 60 * 60 * hours;
570 REQUIRE (fps < uint(std::numeric_limits<int>::max()));
582 const uint FRAMES_PER_10min = 10*60 * 30000/1001;
583 const uint FRAMES_PER_1min = 1*60 * 30000/1001;
584 const uint DISCREPANCY = (1*60 * 30) - FRAMES_PER_1min;
595 int64_t frameNr = calculate_quantisation (time, 0, 30000, 1001);
598 lldiv_t tenMinFrames = lldiv (frameNr, FRAMES_PER_10min);
603 int64_t remainingMinutes = (tenMinFrames.rem - DISCREPANCY) / FRAMES_PER_1min;
605 int64_t dropIncidents = (10-1) * tenMinFrames.quot + remainingMinutes;
606 return frameNr + 2*dropIncidents;
637 uint64_t total_mins = 60 * hours + mins;
638 uint64_t total_frames = 30*60*60 * hours
642 - 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.