41 #include <boost/lexical_cast.hpp> 49 using std::regex_search;
50 using boost::lexical_cast;
74 Frames::parse (
string const& frameNumber, QuantR frameGrid)
76 static regex frameNr_parser{
"(?:^|[^\\d\\.\\-])(\\-?\\d+)#"};
78 if (regex_search (frameNumber, match, frameNr_parser))
79 return frameGrid.timeOf (lexical_cast<FrameCnt> (match[1]));
81 throw error::Invalid (
"unable to parse framecount \""+frameNumber+
"\"" 82 , LERR_(INVALID_TIMECODE));
87 Smpte::parse (
string const&, QuantR)
89 UNIMPLEMENTED(
"parsing SMPTE timecode");
94 Hms::parse (
string const&, QuantR)
96 UNIMPLEMENTED(
"parse a hours:mins:secs time specification");
122 Seconds::parse (
string const& seconds, QuantR grid)
124 static regex fracSecs_parser (
"(?:^|[^\\./\\d\\-])(\\-?\\d+)(?:([\\-\\+]\\d+)?/(\\d+))?sec");
127 #define SUB_EXPR(N) lexical_cast<int> (match[N]) 129 if (regex_search (seconds, match, fracSecs_parser))
130 if (match[2].matched)
133 FSecs fractionalPart (SUB_EXPR(2), SUB_EXPR(3));
134 int fullSeconds (SUB_EXPR(1));
135 return grid.timeOf (fullSeconds + fractionalPart);
138 if (match[3].matched)
141 return grid.timeOf (
FSecs (SUB_EXPR(1), SUB_EXPR(3)));
146 return grid.timeOf (
FSecs (SUB_EXPR(1)));
149 throw error::Invalid (
"unable to parse \""+seconds+
"\" as (fractional)seconds" 150 , LERR_(INVALID_TIMECODE));
162 frameNr.setValueRaw (quantiser.gridPoint (rawTime));
167 Frames::evaluate (
FrameNr const& frameNr, QuantR quantiser)
169 return quantiser.timeOf (frameNr);
181 tc.frames = quantiser.gridPoint (rawTime);
188 Smpte::evaluate (
SmpteTC const& tc, QuantR quantiser)
190 uint frameRate = tc.getFps();
191 int64_t gridPoint(tc.frames);
192 gridPoint += int64_t(tc.secs) * frameRate;
193 gridPoint += int64_t(tc.mins) * frameRate * 60;
194 gridPoint += int64_t(tc.hours) * frameRate * 60 * 60;
195 return quantiser.timeOf (tc.sgn * gridPoint);
212 Smpte::getFramerate (QuantR quantiser_,
TimeValue const& rawTime)
214 FrameCnt refCnt = quantiser_.gridPoint(rawTime);
215 FrameCnt newCnt = quantiser_.gridPoint(
Time(0,1) + rawTime);
216 FrameCnt effectiveFrames = newCnt - refCnt;
217 ENSURE (1000 > effectiveFrames);
218 ENSURE (0 < effectiveFrames);
219 return uint(effectiveFrames);
255 wrapFrames (
SmpteTC* thisTC,
int rawFrames)
257 Div scaleRelation = floorwrap<int> (rawFrames, thisTC->getFps());
258 thisTC->frames.setValueRaw (scaleRelation.rem);
259 thisTC->secs += scaleRelation.quot;
263 wrapSeconds (
SmpteTC* thisTC,
int rawSecs)
265 Div scaleRelation = floorwrap (rawSecs, 60);
266 thisTC->secs.setValueRaw (scaleRelation.rem);
267 thisTC->mins += scaleRelation.quot;
271 wrapMinutes (
SmpteTC* thisTC,
int rawMins)
273 Div scaleRelation = floorwrap (rawMins, 60);
274 thisTC->mins.setValueRaw (scaleRelation.rem);
275 thisTC->hours += scaleRelation.quot;
279 wrapHours (
SmpteTC* thisTC,
int rawHours)
281 thisTC->hours.setValueRaw (rawHours);
282 format::Smpte::applyRangeLimitStrategy (*thisTC);
287 using std::placeholders::_1;
304 FrameNr::FrameNr (
QuTime const& quantisedTime)
305 :
TCode(quantisedTime)
313 SmpteTC::SmpteTC (
QuTime const& quantisedTime)
314 :
TCode(quantisedTime)
315 , effectiveFramerate_(Format::getFramerate (*quantiser_, quantisedTime))
322 SmpteTC::SmpteTC (
SmpteTC const& o)
324 , effectiveFramerate_(o.effectiveFramerate_)
336 SmpteTC::operator= (
SmpteTC const& o)
338 if (!isSameObject (*
this, o))
340 TCode::operator= (o);
341 effectiveFramerate_ = o.effectiveFramerate_;
353 HmsTC::HmsTC (
QuTime const& quantisedTime)
354 :
TCode(quantisedTime)
360 Secs::Secs (
QuTime const& quantisedTime)
361 :
TCode(quantisedTime)
370 frames.setValueRaw(0);
371 secs.setValueRaw (0);
372 mins.setValueRaw (0);
373 hours.setValueRaw (0);
374 sgn.setValueRaw (+1);
381 TimeValue point = Format::evaluate (*
this, *quantiser_);
382 Format::rebuild (*
this, *quantiser_, point);
398 SmpteTC::invertOrientation()
407 if (f < fr) --s;
else f -= fr;
408 if (s < 60) --m;
else s -= 60;
409 if (m < 60) --h;
else m -= 60;
411 hours.setValueRaw(h);
419 SmpteTC::getFps()
const 421 return effectiveFramerate_;
426 SmpteTC::show()
const 442 SmpteTC::operator++ ()
449 SmpteTC::operator-- ()
457 HmsTC::getSecs()
const 464 HmsTC::getMins()
const 471 HmsTC::getHours()
const 478 HmsTC::getMillis()
const 480 TODO (
"Frame-Quantisation");
int lumiera_time_hours(gavl_time_t time)
Extract the hour part of given time.
Classical Timecode value reminiscent to SMPTE format.
Common functions for handling of time values.
void installMutator(FUN mutate, THIS &self)
install an external functor to be applied on any new digxel value.
void setupComponentNormalisation(SmpteTC &thisTC)
bind the individual Digxel mutation functors to normalise raw component values
IDiv< I > floorwrap(I num, I den)
scale wrapping operation.
int lumiera_time_millis(gavl_time_t time)
Extract the milliseconds part of given time.
Implementation namespace for support and library code.
Lumiera's internal time value datatype.
Derived specific exceptions within Lumiera's exception hierarchy.
void castInto(TC &timecode) const
quantise into implicit grid, then rebuild the timecode
Timecode handling library This header defines the foundation interface TCode to represent a grid alig...
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A number element for building structured numeric displays.
Utilities for quantisation (grid alignment) and comparisons.
boost::rational< int64_t > FSecs
rational representation of fractional seconds
void invertOrientation()
flip the orientation of min, sec, and frames.
Support library to represent grid-aligned time specifications This is part of Lumiera's time and time...
Interface: fixed format timecode specification.
Lumiera public interface.
int lumiera_time_seconds(gavl_time_t time)
Extract the seconds part of given time.
int64_t FrameCnt
relative framecount or frame number.
A frame counting timecode value.
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.
grid aligned time specification, referring to a specific scale.
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.