32 #include <boost/lexical_cast.hpp> 40 using std::regex_search;
41 using boost::lexical_cast;
65 Frames::parse (
string const& frameNumber, QuantR frameGrid)
67 static regex frameNr_parser{
"(?:^|[^\\d\\.\\-])(\\-?\\d+)#"};
69 if (regex_search (frameNumber, match, frameNr_parser))
70 return frameGrid.timeOf (lexical_cast<FrameCnt> (match[1]));
72 throw error::Invalid (
"unable to parse framecount \""+frameNumber+
"\"" 73 , LERR_(INVALID_TIMECODE));
78 Smpte::parse (
string const&, QuantR)
80 UNIMPLEMENTED(
"parsing SMPTE timecode");
85 Hms::parse (
string const&, QuantR)
87 UNIMPLEMENTED(
"parse a hours:mins:secs time specification");
113 Seconds::parse (
string const& seconds, QuantR grid)
115 static regex fracSecs_parser (
"(?:^|[^\\./\\d\\-])(\\-?\\d+)(?:([\\-\\+]\\d+)?/(\\d+))?sec");
118 #define SUB_EXPR(N) lexical_cast<int> (match[N]) 120 if (regex_search (seconds, match, fracSecs_parser))
121 if (match[2].matched)
124 FSecs fractionalPart (SUB_EXPR(2), SUB_EXPR(3));
125 int fullSeconds (SUB_EXPR(1));
126 return grid.timeOf (fullSeconds + fractionalPart);
129 if (match[3].matched)
132 return grid.timeOf (
FSecs (SUB_EXPR(1), SUB_EXPR(3)));
137 return grid.timeOf (
FSecs (SUB_EXPR(1)));
140 throw error::Invalid (
"unable to parse \""+seconds+
"\" as (fractional)seconds" 141 , LERR_(INVALID_TIMECODE));
153 frameNr.setValueRaw (quantiser.gridPoint (rawTime));
158 Frames::evaluate (
FrameNr const& frameNr, QuantR quantiser)
160 return quantiser.timeOf (frameNr);
172 tc.frames = quantiser.gridPoint (rawTime);
179 Smpte::evaluate (
SmpteTC const& tc, QuantR quantiser)
181 uint frameRate = tc.getFps();
182 int64_t gridPoint(tc.frames);
183 gridPoint += int64_t(tc.secs) * frameRate;
184 gridPoint += int64_t(tc.mins) * frameRate * 60;
185 gridPoint += int64_t(tc.hours) * frameRate * 60 * 60;
186 return quantiser.timeOf (tc.sgn * gridPoint);
203 Smpte::getFramerate (QuantR quantiser_,
TimeValue const& rawTime)
205 FrameCnt refCnt = quantiser_.gridPoint(rawTime);
206 FrameCnt newCnt = quantiser_.gridPoint(
Time(0,1) + rawTime);
207 FrameCnt effectiveFrames = newCnt - refCnt;
208 ENSURE (1000 > effectiveFrames);
209 ENSURE (0 < effectiveFrames);
210 return uint(effectiveFrames);
246 wrapFrames (
SmpteTC* thisTC,
int rawFrames)
248 Div scaleRelation = floorwrap<int> (rawFrames, thisTC->getFps());
249 thisTC->frames.setValueRaw (scaleRelation.rem);
250 thisTC->secs += scaleRelation.quot;
254 wrapSeconds (
SmpteTC* thisTC,
int rawSecs)
256 Div scaleRelation = floorwrap (rawSecs, 60);
257 thisTC->secs.setValueRaw (scaleRelation.rem);
258 thisTC->mins += scaleRelation.quot;
262 wrapMinutes (
SmpteTC* thisTC,
int rawMins)
264 Div scaleRelation = floorwrap (rawMins, 60);
265 thisTC->mins.setValueRaw (scaleRelation.rem);
266 thisTC->hours += scaleRelation.quot;
270 wrapHours (
SmpteTC* thisTC,
int rawHours)
272 thisTC->hours.setValueRaw (rawHours);
273 format::Smpte::applyRangeLimitStrategy (*thisTC);
278 using std::placeholders::_1;
295 FrameNr::FrameNr (
QuTime const& quantisedTime)
296 :
TCode(quantisedTime)
304 SmpteTC::SmpteTC (
QuTime const& quantisedTime)
305 :
TCode(quantisedTime)
306 , effectiveFramerate_(Format::getFramerate (*quantiser_, quantisedTime))
313 SmpteTC::SmpteTC (
SmpteTC const& o)
315 , effectiveFramerate_(o.effectiveFramerate_)
327 SmpteTC::operator= (
SmpteTC const& o)
329 if (not isSameObject (*
this, o))
331 TCode::operator= (o);
332 effectiveFramerate_ = o.effectiveFramerate_;
344 HmsTC::HmsTC (
QuTime const& quantisedTime)
345 :
TCode(quantisedTime)
351 Secs::Secs (
QuTime const& quantisedTime)
352 :
TCode(quantisedTime)
361 frames.setValueRaw(0);
362 secs.setValueRaw (0);
363 mins.setValueRaw (0);
364 hours.setValueRaw (0);
365 sgn.setValueRaw (+1);
372 TimeValue point = Format::evaluate (*
this, *quantiser_);
373 Format::rebuild (*
this, *quantiser_, point);
389 SmpteTC::invertOrientation()
398 if (f < fr) --s;
else f -= fr;
399 if (s < 60) --m;
else s -= 60;
400 if (m < 60) --h;
else m -= 60;
402 hours.setValueRaw(h);
410 SmpteTC::getFps()
const 412 return effectiveFramerate_;
417 SmpteTC::show()
const 433 SmpteTC::operator++ ()
440 SmpteTC::operator-- ()
448 HmsTC::getSecs()
const 455 HmsTC::getMins()
const 462 HmsTC::getHours()
const 469 HmsTC::getMillis()
const 471 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, based directly on the referee's memory identities. ...