61 #include <boost/rational.hpp> 62 #include <boost/lexical_cast.hpp> 68 using boost::rational_cast;
69 using boost::lexical_cast;
78 extern const std::string FAILURE_INDICATOR;
83 const gavl_time_t TimeValue::SCALE = GAVL_TIME_SCALE;
87 const Time
Time::MAX ( TimeValue::buildRaw_(+std::numeric_limits<gavl_time_t>::max() / 30) );
88 const Time Time::MIN ( TimeValue::buildRaw_(-_raw(
Time::MAX) ) );
89 const Time Time::ZERO;
91 const Time Time::ANYTIME(Time::MIN);
94 const Offset Offset::ZERO (Time::ZERO);
98 Literal DIAGNOSTIC_FORMAT{
"%s%01d:%02d:%02d.%03d"};
105 #define TIME_SCALE_MS (lib::time::TimeValue::SCALE / 1000) 118 Time::Time (
long millis
135 Offset::Offset (
FSecs const& delta_in_secs)
144 TimeValue::operator string()
const 147 int64_t millis, seconds;
148 bool negative = (time < 0);
150 if (negative) time = -time;
152 millis = time % 1000;
153 seconds = time / 1000;
155 return string (negative ?
"-" :
"")
156 + (seconds>0 or time==0? lexical_cast<
string> (seconds)+
"s" :
"")
157 + (millis>0? lexical_cast<
string> (millis)+
"ms" :
"")
169 Time::operator string()
const 172 int millis, seconds, minutes, hours;
173 bool negative = (time < 0);
179 millis = time % 1000;
196 Offset::operator string()
const 198 return (
t_< 0?
"" :
"∆")
199 + TimeValue::operator string();
202 Duration::operator string()
const 204 return "≺"+TimeValue::operator string()+
"≻";
207 TimeSpan::operator string()
const 209 return string (start())
210 + string (duration());
215 template<
typename RAT>
217 renderFraction (RAT
const& frac,
Literal postfx) noexcept
219 std::ostringstream buffer;
220 if (1 == frac.denominator() or 0 == frac.numerator())
221 buffer << frac.numerator() << postfx;
223 buffer << frac <<postfx;
227 {
return meta::FAILURE_INDICATOR; }
231 FrameRate::operator string()
const 233 return renderFraction (*
this,
"FPS");
243 return reinterpret_cast<TimeValue const&
> (raw);
250 const FrameRate FrameRate::NTSC (30000,1001);
252 const FrameRate FrameRate::HALTED (1,std::numeric_limits<int>::max());
261 throw error::Logic (
"Impossible to quantise to an zero spaced frame grid" 262 , error::LUMIERA_ERROR_BOTTOM_VALUE);
273 boost::rational<int64_t> distance (this->
t_);
275 gavl_time_t microTicks = floordiv (distance.numerator(), distance.denominator());
281 Offset::stretchedByFloatFactor (
double factor)
const 283 double distance(this->
t_);
285 gavl_time_t microTicks = floor (distance);
306 return reinterpret_cast<Duration const&
> (maxDelta);
309 const TimeSpan TimeSpan::ALL {Time::MIN, Duration::MAX};
317 return lib::time::renderFraction (val,
"sec");
333 int milliseconds, seconds, minutes, hours;
334 bool negative = (time < 0);
340 milliseconds = time % 1000;
349 negative ?
"-" :
"", hours, minutes, seconds, milliseconds);
351 ENSURE(buffer != NULL);
361 if (
abs(fractionalSeconds) > lib::time::FSEC_MAX)
362 return (fractionalSeconds < 0? -1:+1)
363 * std::numeric_limits<int64_t>::max();
365 return gavl_time_t(util::reQuant (fractionalSeconds.numerator()
366 ,fractionalSeconds.denominator()
375 boost::rational<uint64_t> framerate (fps.numerator(), fps.denominator());
384 throw error::Logic (
"Impossible to quantise to an zero spaced frame grid" 385 , error::LUMIERA_ERROR_BOTTOM_VALUE);
387 FSecs duration = 1 / fps;
395 calculate_quantisation (gavl_time_t
time, gavl_time_t origin, gavl_time_t grid)
398 return floordiv (time,grid);
402 calculate_quantisation (gavl_time_t time, gavl_time_t origin, uint framerate, uint framerate_divisor=1)
405 REQUIRE (framerate_divisor);
407 const int64_t limit_num = std::numeric_limits<gavl_time_t>::max() / framerate;
408 const int64_t limit_den = std::numeric_limits<gavl_time_t>::max() / framerate_divisor;
412 if (
abs(time) < limit_num and microScale < limit_den)
416 return floordiv (time*framerate, microScale*framerate_divisor);
422 gavl_time_t frameDuration = microScale / framerate;
423 return calculate_quantisation (time,origin, frameDuration);
432 return calculate_quantisation (time, origin, grid);
436 lumiera_quantise_frames_fps (gavl_time_t
time, gavl_time_t origin, uint framerate)
438 return calculate_quantisation (time, origin, framerate);
444 int64_t count = calculate_quantisation (time, origin, grid);
445 gavl_time_t alignedTime = count * grid;
452 gavl_time_t offset = nr * grid;
453 return origin + offset;
460 gavl_time_t time = millis
463 + 1000 * 60 * 60 * hours;
471 gavl_time_t time = 1000LL * frames/fps
474 + 1000 * 60 * 60 * hours;
506 REQUIRE (fps < uint(std::numeric_limits<int>::max()));
518 const uint FRAMES_PER_10min = 10*60 * 30000/1001;
519 const uint FRAMES_PER_1min = 1*60 * 30000/1001;
520 const uint DISCREPANCY = (1*60 * 30) - FRAMES_PER_1min;
531 int64_t frameNr = calculate_quantisation (time, 0, 30000, 1001);
534 lldiv_t tenMinFrames = lldiv (frameNr, FRAMES_PER_10min);
539 int64_t remainingMinutes = (tenMinFrames.rem - DISCREPANCY) / FRAMES_PER_1min;
541 int64_t dropIncidents = (10-1) * tenMinFrames.quot + remainingMinutes;
542 return frameNr + 2*dropIncidents;
573 uint64_t total_mins = 60 * hours + mins;
574 uint64_t total_frames = 30*60*60 * hours
578 - 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.
Duration abs() const
interpret the distance given by this offset as a time duration
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.
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)
gavl_time_t t_
the raw (internal) time value used to implement the time types
friend gavl_time_t _raw(TimeValue const &time)
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.