31#include <boost/lexical_cast.hpp>
39using std::regex_search;
40using boost::lexical_cast;
66 static regex frameNr_parser{
"(?:^|[^\\d\\.\\-])(\\-?\\d+)#"};
68 if (regex_search (frameNumber, match, frameNr_parser))
69 return frameGrid.timeOf (lexical_cast<FrameCnt> (match[1]));
71 throw error::Invalid (
"unable to parse framecount \""+frameNumber+
"\""
72 ,
LERR_(INVALID_TIMECODE));
79 UNIMPLEMENTED(
"parsing SMPTE timecode");
86 UNIMPLEMENTED(
"parse a hours:mins:secs time specification");
114 static regex fracSecs_parser (
"(?:^|[^\\./\\d\\-])(\\-?\\d+)(?:([\\-\\+]\\d+)?/(\\d+))?sec");
117 #define SUB_EXPR(N) lexical_cast<int> (match[N])
119 if (regex_search (seconds, match, fracSecs_parser))
120 if (match[2].matched)
125 return grid.timeOf (fullSeconds + fractionalPart);
128 if (match[3].matched)
139 throw error::Invalid (
"unable to parse \""+seconds+
"\" as (fractional)seconds"
140 ,
LERR_(INVALID_TIMECODE));
152 frameNr.
setValueRaw (quantiser.gridPoint (rawTime));
159 return quantiser.timeOf (frameNr);
171 tc.
frames = quantiser.gridPoint (rawTime);
181 int64_t gridPoint(tc.
frames);
182 gridPoint += int64_t(tc.
secs) * frameRate;
183 gridPoint += int64_t(tc.
mins) * frameRate * 60;
184 gridPoint += int64_t(tc.
hours) * frameRate * 60 * 60;
185 return quantiser.timeOf (tc.
sgn * gridPoint);
204 FrameCnt refCnt = quantiser_.gridPoint(rawTime);
205 FrameCnt newCnt = quantiser_.gridPoint(
Time(0,1) + rawTime);
206 FrameCnt effectiveFrames = newCnt - refCnt;
207 ENSURE (1000 > effectiveFrames);
208 ENSURE (0 < effectiveFrames);
209 return uint(effectiveFrames);
247 Div scaleRelation = floorwrap<int> (rawFrames, thisTC->
getFps());
249 thisTC->
secs += scaleRelation.quot;
255 Div scaleRelation = floorwrap (rawSecs, 60);
257 thisTC->
mins += scaleRelation.quot;
263 Div scaleRelation = floorwrap (rawMins, 60);
265 thisTC->
hours += scaleRelation.quot;
277 using std::placeholders::_1;
295 :
TCode(quantisedTime)
304 :
TCode(quantisedTime)
305 , effectiveFramerate_(
Format::getFramerate (*quantiser_, quantisedTime))
307 setupComponentNormalisation (*
this);
314 , effectiveFramerate_(o.effectiveFramerate_)
316 setupComponentNormalisation (*
this);
328 if (not isSameObject (*
this, o))
330 TCode::operator= (o);
344 :
TCode(quantisedTime)
351 :
TCode(quantisedTime)
397 if (f < fr) --s;
else f -= fr;
398 if (s < 60) --m;
else s -= 60;
399 if (m < 60) --h;
else m -= 60;
454 return (_raw (
tpoint_) / TIME_SCALE_sec) % 60;
461 return (_raw (
tpoint_) / TIME_SCALE_sec / 60) % 60;
468 return _raw (
tpoint_) / TIME_SCALE_sec / 60 / 60;
475 return (_raw (
tpoint_) / TIME_SCALE_ms) % 1000;
A number element for building structured numeric displays.
void setValueRaw(NUM newVal)
digxel::CBuf show() const
void installMutator(FUN mutate, THIS &self)
install an external functor to be applied on any new digxel value.
A frame counting timecode value.
FrameNr(QuTime const &quantisedTime)
HmsTC(QuTime const &quantisedTime)
grid aligned time specification, referring to a specific scale.
void castInto(TC &timecode) const
quantise into implicit grid, then rebuild the timecode
Secs(QuTime const &quantisedTime)
Classical Timecode value reminiscent to SMPTE format.
virtual string show() const
void invertOrientation()
flip the orientation of min, sec, and frames.
SmpteTC & operator=(SmpteTC const &)
SmpteTC(QuTime const &quantisedTime)
Interface: fixed format timecode specification.
basic constant internal time value.
static const raw_time_64 SCALE
Number of micro ticks (µs) per second as basic time scale.
Lumiera's internal time value datatype.
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
const auto TIME_SCALE_sec
void wrapFrames(SmpteTC *thisTC, int rawFrames)
void wrapMinutes(SmpteTC *thisTC, int rawMins)
void wrapSeconds(SmpteTC *thisTC, int rawSecs)
void setupComponentNormalisation(SmpteTC &thisTC)
bind the individual Digxel mutation functors to normalise raw component values
void wrapHours(SmpteTC *thisTC, int rawHours)
int64_t FrameCnt
relative framecount or frame number.
boost::rational< int64_t > FSecs
rational representation of fractional seconds
Implementation namespace for support and library code.
LumieraError< LERR_(INVALID)> Invalid
Lumiera public interface.
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee's memory identities.
IDiv< I > floorwrap(I num, I den)
scale wrapping operation.
OBJ * unConst(const OBJ *)
shortcut to save some typing when having to define const and non-const variants of member functions
helper to treat int or long division uniformly
Timecode handling library This header defines the foundation interface TCode to represent a grid alig...
Support library to represent grid-aligned time specifications This is part of Lumiera's time and time...
a family of time value like entities and their relationships.
Utilities for quantisation (grid alignment) and comparisons.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...