Synthesised clocks (dvbcss.clock)

Module: dvbcss.clock

The dvbcss.clock module provides software synthesised clock objects that can be chained together into dependent hierarchies. Use in conjunction with dvbcss.task to sleep and run code at set times on these clocks.

Introduction

The classes in this module implement software synthesised clocks from which you can query a current time value. A clock counts in whole numbers of ticks (unlike the standard library time.time() function which counts in seconds and fractions of a second) and has a tick rate (expresed in ticks per second).

To use clocks as timers or to schedule code to run later, you must use them with the functions of the dvbcss.task module.

To use clocks begin with a root clock that is based on a underlying timing source. The following root clocks are provided:

Other dependent clocks can then be created that have the underlying clock as their parent. and further dependent clocks can be created with those dependents as their parents, creating chains of clocks, each based on their parent and leading back to an underlying clock. The following dependent clocks are provided:

  • CorrelatedClock is a fixed tick rate clock where you define the point of correlation between it and its parent.
  • OffsetClock ** is a clock that is the same as its parent but with an offset amount of root time. Useful to calibrate for rendering pipeline delays.
  • TunableClock is a clock that can have its tick count tweaked and its frequency slewed on the fly.
  • RangleCorrelatedClock is a clock where the relationship to the parent is determined from two points of correlation.

Dependent clocks can have a different tick rate to their parent and count their ticks from a different starting point.

Dependent clocks allow their relationship to its parent clock to be changed dynamically - e.g. the absolute value, or the rate at which the clock ticks. If your code needs to be notified of such a change, it can bind itself as a dependent to that clock.

The base ClockBase class defines the set of methods common to all clocks (both underlying and dependent)

Limitations on tick resolution (precision)

The Clock objects here do not run a thread that counts individual ticks. Instead, to determine the current tick value they query the parent clock for its current tick value and then calculate what the tick value should be.

A clock is therefore limited in the precision and resolution of its tick value by its parents. SysClock, for example, is limited by the resolution of the underlying time source provided to it by dvbcss.monotonic_time module’s dvbcss.monotonic_time.time() function. And this will be operating system dependent. SysClock also outputs ticks as integer values.

If a parent of a clock only reports whole number (integer) tick values then that also limits the resolution of any clocks that depend on it. For example, a clock that counts in integer ticks only at 25 ticks per second will cause a clock descended from it, with a tick rate of 100 ticks per second, to report tick values that increment 4 ticks at a time … or worse if a parent of both has an even lower tick rate.

With the clocks provided by this module, only SysClock limits itself to integer numbers of ticks. CorrelatedClock and TunableClock are capable of fractional numbers of ticks provided that the parameters provided to them (e.g. the tickRate) are passed as floating point values (this will force python to do the maths in floating point instead of integer maths).

Timers and Sleep functions

Use the functions of the dvbcss.task in conjunction with Clock objects to create code that sleeps, or which triggers callbacks, based on time as measured by these clocks.

Accounting for error (dispersion)

These clocks also support tracking and calculating error bounds on the values they report. This is known as dispersion. It is useful if, for example, a clock hierarchy is being used to estimate time based on imperfect measurements - such as when a companion tries to estimate the Wall Clock of a TV.

Each clock in a hierarchy makes its own contribution to the overall dispersion. When a clock is asked to calculate dispersion (using the dispersionAtTime() method), the answer it gives is the sum of the error contributions from itself and its parents, all the way back up to the root system clock.

A system clock has error bounds determined by the precision with which it can be measured (the smallest amount by which its values change).

When using a dependent clock, such as a CorrelatedClock, the correlation being used to set its relationship to its parent might also have some uncertainty in it. This information can be included in the Correlation. Uncertainty based on measurements/estimates can grow over time - e.g. because the clocks in a TV and companion gradually drift. So there are two parameters that you can provide in a Correlation - the initial error and the growth rate. As time passes, the error for the clock using this correlation is calculated as the initial error plus the growth rate multiplied by how much time has passed since the point of correlation.

Usage examples

Simple hierarchies of clocks

Here is a simple example where a clock represents a timeline and another represents a timeline related to the first by a correlation:

from dvbcss.clock import SysClock
from dvbcss.clock import CorrelatedClock
from dvbcss.clock import Correlation

# create a clock based on dvbcss.monotonic_time.time() that ticks in milliseconds
sysClock = SysClock(tickRate=1000)

# create a clock to represent a timeline 
corr = Correlation(parentTicks=0, childTicks=0)
baseTimeline = CorrelatedClock(parentClock=sysClock, tickRate=25, correlation=corr)

# create a clock representing another timeline, where time zero corresponds to time 100
# on the parent timeline
corr2 = Correlation(parentTicks=100, childTicks=0)
subTimeline = CorrelatedClock(parentClock=baseTimeline, tickRate=25, correlation=corr2)

At some point later in time during the program, we query the values of all the clocks, confirming that the sub timeline is always 100 ticks ahead of the base timeline.

def printTimes():
    sys  = sysClock.ticks()
    base = baseTimeline.ticks()
    sub  = subTimeline.ticks()
    print "SysClock      ticks = %d", sys
    print "Base timeline ticks = %d", base
    print "Sub timeline  ticks = %d", sub
    
>>> printTimes()
SysClock      ticks = 20000
Base timeline ticks = 500
Sub timeline  ticks = 600 

Note that in these examples, for clarity, the tick count on the sysClock is artificially low. It would likely be a much larger value.

We then change the correlation for the base timeline, declaring tick 25 on its baseline to correspond to tick 0 on its parent timeline, and both the base timeline and the sub timeline reflect this:

>>> baseTimeline.correlation = Correlation(0,25)
>>> printTimes()
SysClock      ticks = 30000
Base timeline ticks = 775
Sub timeline  ticks = 875 

Clock speed adjustment

All clocks have a speed property. Normally this is 1.0. Some clock classes support changing this value. This scales the rate at which the clock ticks relative to its parent. For example, 0.5 corresponds to half speed; 2.0 = double speed, 0 = frozen and -1.0 = reverse.

Clocks will take speed into account when returning their current tick position or converting it to or from the tick value of a parent clock. However it does not alter the tickRate property. A child clock will similarly ignore the speed property of a parent clock. In this way, the speed property can be used to tweak the speed of time, or to emulate speed control (fast forward, rewind, pause) for a media timeline.

Here is an example where we create 3 clocks in a chain and all tick initially at 100 ticks per second:

>>> import time
>>> baseClock = Sysclock(tickRate=100)
>>> clock1 = TunableClock(parent=baseClock, tickRate=100)
>>> clock2 = TunableClock(parent=clock1, tickRate=100)

We confirm that both clock1 and its child - clock2 - tick at 100 ticks per second:

>>> print clock1.ticks; time.sleep(1.0); print clock1.ticks
5023
5123
>>> print clock2.ticks; time.sleep(1.0); print clock2.ticks
2150
2250

If we change the tick rate of clock1 this affects clock1, but its child - clock2 - continues to tick at 100 ticks every second:

>>> clock1.tickRate = 200
>>> print clock1.ticks; time.sleep(1.0); print clock1.ticks
5440
5640
>>> print clock2.ticks; time.sleep(1.0); print clock2.ticks
4103
4203

But if we instead change the speed multiplier of clock1 then this not only affects the ticking rate of clock1 but also of its child - clock2:

>>> clock1.tickRate = 100
>>> clock1.speed = 2.0
>>> print clock1.ticks; time.sleep(1.0); print clock1.ticks
5740
5940
>>> print clock2.ticks; time.sleep(1.0); print clock2.ticks
4603
4803

Translating tick values between clocks

The clock classes provide mechanisms to translate a tick value from one clock to a tick value of another clock such that it still represents the same moment in time. So long as both clocks share a common ancestor clock, the conversion will be possible.

toParentTicks() and fromParentTicks() converts tick values for a clock to/from its parent clock. toOtherClockTicks() will convert a tick value for this clock to the corresponding tick value for any other clock with a common ancestor to this one.

from dvbcss.clock import SysClock
from dvbcss.clock import CorrelatedClock
from dvbcss.clock import Correlation

# create a clock based on dvbcss.monotonic_time.time() that ticks in milliseconds
sysClock = SysClock(tickRate=1000)

#                                       +------------+
#                                   .-- | mediaClock |
# +----------+     +-----------+ <--'   +------------+
# | sysClock | <-- | wallClock | 
# +----------+     +-----------+ <--.   +-----------------+
#                                   '-- | otherMediaClock |
#                                       +-----------------+

wallClock = CorrelatedClock(parentClock=sysClock, tickRate=1000000000, correlation=Correlation(0,0))
mediaClock = CorrelatedClock(parentClock=wallClock, tickRate=25, correlation=Correlation(500021256, 0))
otherMediaClock = CorrelatedClock(parentClock=wallClock, tickRate=30, correlation=Correlation(21093757, 0))

# calculate wall clock time 'w' corresponding to a mediaClock time 1582:
t = 1582
w = mediaClock.toParentTicks(t)    
print "When MediaClock ticks =", t, " wall clock ticks =", w

# calculate mediaClock time 'm' corresponding to wall clock time 1920395
w = 1920395
m = mediaClock.fromParentTicks(w)
print "When wall clock ticks =", w, " media clock ticks =", m

# calculate other media clock time corresponding to media clock time 2248
t = 2248
o = mediaClock.toOtherClockTicks(otherMediaClock, t)
print "When MediaClock ticks =", t, " other media clock ticks =", o

Let us now suppose that the wall clock is actually an estimate of a Wall Clock on another device. When we set the correlation we therefore include error information that is calculated from the proces by which the Wall Clock of the other device is estimated:

wallClock.correlation = Correlation(24524535, 34342, initialError=0.012, errorGrowthRate=0.00005)

Here we are saying that the error bounds of the estimate at the point in time represented by the correlation is +/- 0.012 seconds. This will grow by 0.00005 seconds for every tick of the parent clock.

print "Dispersion is +/-", wallClock.dispersionAtTime(wallClock.ticks), "seconds"

print "In 1000 ticks from now, dispersion will be +/-", wallClock.dispersionAtTime(wallClock.ticks + 1000), "seconds"

Implementing new clocks

Implement a new clock class by subclassing ClockBase and implementing the stub methods.

For example, here is a clock that is the same as its parent (same tick rate) except that its current tick value differs by a fixed offset.

from dvbcss.clock import ClockBase

class FixedTicksOffsetClock(ClockBase):

    def __init__(self, parent, offset):
        super(FixedTicksOffsetClock,self).__init__()
        self._parent = parent
        self._offset = offset
        
    def calcWhen(self, ticksWhen):
        return self._parent.calcWhen(ticksWhen - self._offset)
        
    def fromParentTicks(self, ticks):
        return ticks + self._offset
        
    def getParent(self):
        return self._parent
        
    @property
    def tickRate(self):
        return self._parent.tickRate
    
    @property
    def ticks(self)
        return self._parent.ticks + self._offset
        
    def toParentTicks(self, ticks):
        return ticks - self._offset

    def _errorAtTime(self,t):
        return 0

In use:

>>> f = FixedTicksOffsetClock(parentClock, 100)
>>> print parentClock.ticks, f.ticks
216 316

When doing this, you must decide whether to allow the speed to be adjusted. If you do, then it must be taken into account in the calculations for the methods: calcWhen(), fromParentTicks() and toParentTicks().

Not a number (nan)

“Not a number” value of a float. Check if a value is NaN like this:

>>> import math
>>> math.isnan(nanValue)
True

Converting tick values to a parent clock or to the root clock may result in this value being returned if one or more of the clocks involved has speed zero.

Functions

measurePrecision - estimate measurement precision of a clock

dvbcss.clock.measurePrecision(clock, sampleSize=10000)[source]

Do a very rough experiment to work out the precision of the provided clock.

Works by empirically looking for the smallest observable difference in the tick count.

Parameters:sampleSize – (int) Number of iterations (sample size) to estimate the precision over
Returns:(float) estimate of clock measurement precision (in seconds)

Classes

ClockBase - base class for clocks

class dvbcss.clock.ClockBase(**kwargs)[source]

Base class for all clock classes.

By default, adjusting tickRate and speed are not permitted unless a subclass overrides and implements a property setter.

bind(dependent)[source]

Bind for notification if this clock changes.

Parameters:dependent – When this clock changes, the notify() method of this dependent will be called, passing a single argument that is this clock.
calcWhen(ticksWhen)[source]
Return:“when” in terms of the underlying clock behind the root clock implementation (e.g. monotonic_time.time() in the case of SysClock). Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

This is a stub for this method. Sub-classes should implement it.

clockDiff(otherClock)[source]

Calculate the potential for difference between this clock and another clock.

Parameters:otherClock – The clock to compare with.
Returns:The potential difference in units of seconds. If effective speeds or tick rates differ, this will always be float (“+inf”).

If the clocks differ in effective speed or tick rate, even slightly, then this means that the clocks will eventually diverge to infinity, and so the returned difference will equal +infinity.

New in version 0.4.

dispersionAtTime(t)[source]

Calculates the dispersion (maximum error bounds) at the specified clock time. This takes into account the contribution to error of this clock and its ancestors.

Returns:Dispersion (in seconds) at the specified clock time.

New in version 0.4.

fromParentTicks(ticks)[source]

This is a stub for this method. Sub-classes should implement it.

Method to convert from a tick value for this clock’s parent to the equivalent tick value (representing the same point in time) for this clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

Returns:The specified tick value for the parent clock converted to the timescale of this clock.
Throws StopIteration:
 if this clock has no parent
fromRootTicks(t)[source]

Return the time for this clock corresponding to a given time of the root clock.

Parameters:t – Tick value of the root clock.
Returns:Corresponding tick value of this clock.

New in version 0.4.

getAncestry()[source]

Retrieve the ancestry of this clock as a list.

Returns:A list of clocks, starting with this clock, and proceeding to its parent, then its parent’s parent etc, ending at the root clock.

New in version 0.4.

getEffectiveSpeed()[source]

Returns the ‘effective speed’ of this clock.

This is equal to multiplying together the speed properties of this clock and all of the parents up to the root clock.

getParent()[source]

This is a stub for this method. Sub-classes should implement it.

Returns:ClockBase representing the immediate parent of this clock, or None if it is a root clock.
getRoot()[source]
Returns:The root clock for this clock (or itself it has no parent).

New in version 0.4.

getRootMaxFreqError()[source]

Return potential error of underlying clock (e.g. system clock).

Returns:The maximum potential frequency error (in parts-per-million) of the underlying root clock.

This is a partial stub method. It must be re-implemented by root clocks.

For a clock that is not the root clock, this method will pass through the call to the same method of the root clock.

New in version 0.4.

isAvailable()[source]

Returns whether this clock is available, taking into account the availability of any (parent) clocks on which it depends.

Returns:True if available, otherwise False.

New in version 0.4.

nanos[source]

(read only) The tick count of this clock, but converted to units of nanoseconds, based on the current tick rate (but ignoring the speed property).

nanosToTicks(nanos)[source]

Convert the supplied nanosecond to number of ticks given the current tick rate of this clock (but ignoring the speed property).

Parameters:nanos – nanoseconds value
Returns:number of ticks equivalent to the supplied nanosecond value
notify(cause)[source]

Call to notify this clock that the clock on which it is based (its parent) has changed relative to the underlying timing source.

Parameters:cause – The clock that is calling this method.

Will notify all dependents of this clock (entities that have registered themselves by calling bind()).

setAvailability(availability)[source]

Set the availability of this clock.

Parameters:availability – True if this clock is available, otherwise False.

If setting the availability of this clock changes the overall availability of this clock (as returned by isAvailable()) then dependents will be notified of the change.

New in version 0.4.

setParent(newParent)[source]

This is a stub for this method. Sub-classes should implement it.

Change the parent of this clock (if supported). Will generate a notification of change.

speed[source]

(read/write float) The speed at which the clock is running. Does not change the reported tickRate value, but will affect how ticks are calculated from parent clock ticks. Default = 1.0 = normal tick rate.

tickRate[source]

(read only)The tick rate (in ticks per second) of this clock.

This is a stub for this method. Sub-classes should implement it.

ticks[source]

(read only) The tick count for this clock.

This is a stub for this method. Sub-classes should implement it.

toOtherClockTicks(otherClock, ticks)[source]

Converts a tick value for this clock into a tick value corresponding to the timescale of another clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:
  • otherClock – A clock object representing another clock.
  • ticks – A time (tick value) for this clock
Returns:

The tick value of the otherClock that represents the same moment in time, or Not a number (nan)

Throws NoCommonClock:
 

if there is no common ancestor clock (meaning it is not possible to convert

toParentTicks(ticks)[source]

This is a stub for this method. Sub-classes should implement it.

Method to convert from a tick value for this clock to the equivalent tick value (representing the same point in time) for the parent clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

Returns:The specified tick value of this clock converted to the timescale of the parent clock.
Throws StopIteration:
 if this clock has no parent
toRootTicks(t)[source]

Return the time for the root clock corresponding to a given time of this clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:t – Tick value for this clock.
Returns:Corresponding tick value of the root clock, or Not a number (nan)

New in version 0.4.

unbind(dependent)[source]

Unbind from notification if this clock changes.

Parameters:dependent – The dependent to unbind from receiving notifications.

SysClock - Clock based on time module

class dvbcss.clock.SysClock(tickRate=1000000, maxFreqErrorPpm=500, **kwargs)[source]

A clock based directly on the standard library timer function monotonic_time.time(). Returns integer ticks when its ticks property is queried.

The default tick rate is 1 million ticks per second, but a different tick rate can be chosen during initialisation.

Parameters:
  • tickRate – Optional (default=1000000). The tick rate of this clock (ticks per second).
  • maxFreqErrorPpm – Optional (default=500). The maximum frequency error (in units of parts-per-million) of the clock, or an educated best-estimate of it.

The precision is automatically estimated using the measurePrecision() function when this clock is created. So creating a SysClock, particularly one with a low tickrate, may incur a noticeable delay at initialisation.

The measured precision is then reported as the dispersion of this clock.

It is not permitted to change the tickRate or speed property of this clock because it directly represents a system clock.

Parameters:tickRate – (int) tick rate for this clock (in ticks per second)
bind(dependent)[source]

Bind for notification if this clock changes.

Parameters:dependent – When this clock changes, the notify() method of this dependent will be called, passing a single argument that is this clock.
calcWhen(ticksWhen)[source]
Return:“when” in terms of the underlying clock behind the root clock implementation (e.g. monotonic_time.time() in the case of SysClock). Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

(Documentation inherited from ClockBase)

clockDiff(otherClock)[source]

Calculate the potential for difference between this clock and another clock.

Parameters:otherClock – The clock to compare with.
Returns:The potential difference in units of seconds. If effective speeds or tick rates differ, this will always be float (“+inf”).

If the clocks differ in effective speed or tick rate, even slightly, then this means that the clocks will eventually diverge to infinity, and so the returned difference will equal +infinity.

New in version 0.4.

dispersionAtTime(t)[source]

Calculates the dispersion (maximum error bounds) at the specified clock time. This takes into account the contribution to error of this clock and its ancestors.

Returns:Dispersion (in seconds) at the specified clock time.

New in version 0.4.

fromParentTicks(ticks)[source]

Method to convert from a tick value for this clock’s parent to the equivalent tick value (representing the same point in time) for this clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

returns:The specified tick value for the parent clock converted to the timescale of this clock.
throws StopIteration:
 if this clock has no parent

(Documentation inherited from ClockBase)

fromRootTicks(t)[source]

Return the time for this clock corresponding to a given time of the root clock.

Parameters:t – Tick value of the root clock.
Returns:Corresponding tick value of this clock.

New in version 0.4.

getAncestry()[source]

Retrieve the ancestry of this clock as a list.

Returns:A list of clocks, starting with this clock, and proceeding to its parent, then its parent’s parent etc, ending at the root clock.

New in version 0.4.

getEffectiveSpeed()[source]

Returns the ‘effective speed’ of this clock.

This is equal to multiplying together the speed properties of this clock and all of the parents up to the root clock.

getParent()[source]
returns:ClockBase representing the immediate parent of this clock, or None if it is a root clock.

(Documentation inherited from ClockBase)

getRoot()[source]
Returns:The root clock for this clock (or itself it has no parent).

New in version 0.4.

getRootMaxFreqError()[source]

Return potential error of underlying clock (e.g. system clock).

returns:The maximum potential frequency error (in parts-per-million) of the underlying root clock.

This is a partial stub method. It must be re-implemented by root clocks.

For a clock that is not the root clock, this method will pass through the call to the same method of the root clock.

New in version 0.4.

(Documentation inherited from ClockBase)

isAvailable()[source]

Returns whether this clock is available, taking into account the availability of any (parent) clocks on which it depends.

Returns:True if available, otherwise False.

New in version 0.4.

nanos[source]

(read only) The tick count of this clock, but converted to units of nanoseconds, based on the current tick rate (but ignoring the speed property).

nanosToTicks(nanos)[source]

Convert the supplied nanosecond to number of ticks given the current tick rate of this clock (but ignoring the speed property).

Parameters:nanos – nanoseconds value
Returns:number of ticks equivalent to the supplied nanosecond value
notify(cause)[source]

Call to notify this clock that the clock on which it is based (its parent) has changed relative to the underlying timing source.

Parameters:cause – The clock that is calling this method.

Will notify all dependents of this clock (entities that have registered themselves by calling bind()).

setAvailability(availability)[source]

SysClock is always available, and so availability cannot be set.

Raises:NotImplementedError – Always raised.

New in version 0.4.

setParent(newParent)[source]

This is a stub for this method. Sub-classes should implement it.

Change the parent of this clock (if supported). Will generate a notification of change.

speed[source]

(read/write float) The speed at which the clock is running. Does not change the reported tickRate value, but will affect how ticks are calculated from parent clock ticks. Default = 1.0 = normal tick rate.

tickRate[source]

(read only)The tick rate (in ticks per second) of this clock.

(Documentation inherited from ClockBase)

ticks[source]

(read only) The tick count for this clock.

(Documentation inherited from ClockBase)

toOtherClockTicks(otherClock, ticks)[source]

Converts a tick value for this clock into a tick value corresponding to the timescale of another clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:
  • otherClock – A clock object representing another clock.
  • ticks – A time (tick value) for this clock
Returns:

The tick value of the otherClock that represents the same moment in time, or Not a number (nan)

Throws NoCommonClock:
 

if there is no common ancestor clock (meaning it is not possible to convert

toParentTicks(ticks)[source]

Method to convert from a tick value for this clock to the equivalent tick value (representing the same point in time) for the parent clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

returns:The specified tick value of this clock converted to the timescale of the parent clock.
throws StopIteration:
 if this clock has no parent

(Documentation inherited from ClockBase)

toRootTicks(t)[source]

Return the time for the root clock corresponding to a given time of this clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:t – Tick value for this clock.
Returns:Corresponding tick value of the root clock, or Not a number (nan)

New in version 0.4.

unbind(dependent)[source]

Unbind from notification if this clock changes.

Parameters:dependent – The dependent to unbind from receiving notifications.

CorrelatedClock - Clock correlated to another clock

class dvbcss.clock.CorrelatedClock(parentClock, tickRate, correlation=Correlation(parentTicks=0, childticks=0, initialError=0, errorGrowthRate=0), speed=1.0, **kwargs)[source]

A clock locked to the tick count of the parent clock by a correlation and frequency setting.

Correlation is either a Correlation object or a simple tuple (parentTicks, selfTicks). The object form also allows you to specify error bounds information that this clock will track and propagate to other clocks.

When the parent clock ticks property has the value parentTicks, the ticks property of this clock shall have the value selfTicks.

This relationship can be illustrated as follows:

_images/correlated-clock.png

You can alter the correlation and tickRate and speed of this clock dynamically. Changes to tickRate and speed will not shift the point of correlation. This means that a change in tickRate or speed will probably cause the current tick value of the clock to jump. The amount it jumps by will be proportional to the distance the current time is from the point of correlation:

_images/correlated-clock-speed-change-issue.png

If you want a speed change to only affect the ticks from a particular point (e.g. the current tick value) onwards then you must re-base the correlation. There is a function provided to do that in some circumstances:

c = CorrelatedClock(parentClock=parent, tickRate=1000, correlation=(50,78))

   ... time passes ...
   
# now freeze the clock AT ITS CURRENT TICK VALUE

c.rebaseCorrelationAtTicks(c.ticks)
c.speed = 0

# now resume the clock but at half speed, but again without the tick value jumping
c.correlation = Correlation( parent.ticks, c.ticks )
c.speed = 0.5

Note

The maths to calculate and convert tick values will be performed, by default, as integer maths unless the parameters controlling the clock (tickRate etc) are floating point, or the ticks property of the parent clock supplies floating point values.

Parameters:
  • parentClock – The parent clock for this clock.
  • tickRate – (int) tick rate for this clock (in ticks per second)
  • correlation – (Correlation) or tuple (parentTicks, selfTicks). The intial correlation for this clock.
  • speed – Initial speed for this clock.
bind(dependent)[source]

Bind for notification if this clock changes.

Parameters:dependent – When this clock changes, the notify() method of this dependent will be called, passing a single argument that is this clock.
calcWhen(ticksWhen)[source]
Return:“when” in terms of the underlying clock behind the root clock implementation (e.g. monotonic_time.time() in the case of SysClock). Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

(Documentation inherited from ClockBase)

clockDiff(otherClock)[source]

Calculate the potential for difference between this clock and another clock.

Parameters:otherClock – The clock to compare with.
Returns:The potential difference in units of seconds. If effective speeds or tick rates differ, this will always be float (“+inf”).

If the clocks differ in effective speed or tick rate, even slightly, then this means that the clocks will eventually diverge to infinity, and so the returned difference will equal +infinity.

New in version 0.4.

correlation[source]

Read or change the correlation of this clock to its parent clock.

Assign a new Correlation object to change the correlation.

You can also pass a tuple (parentTicks, selfTicks) which will be converted to a correlation automatically. Reading this property after setting it with a tuple will return the equivalent Correlation.

dispersionAtTime(t)[source]

Calculates the dispersion (maximum error bounds) at the specified clock time. This takes into account the contribution to error of this clock and its ancestors.

Returns:Dispersion (in seconds) at the specified clock time.

New in version 0.4.

fromParentTicks(ticks)[source]

Method to convert from a tick value for this clock’s parent to the equivalent tick value (representing the same point in time) for this clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

returns:The specified tick value for the parent clock converted to the timescale of this clock.
throws StopIteration:
 if this clock has no parent

(Documentation inherited from ClockBase)

fromRootTicks(t)[source]

Return the time for this clock corresponding to a given time of the root clock.

Parameters:t – Tick value of the root clock.
Returns:Corresponding tick value of this clock.

New in version 0.4.

getAncestry()[source]

Retrieve the ancestry of this clock as a list.

Returns:A list of clocks, starting with this clock, and proceeding to its parent, then its parent’s parent etc, ending at the root clock.

New in version 0.4.

getEffectiveSpeed()[source]

Returns the ‘effective speed’ of this clock.

This is equal to multiplying together the speed properties of this clock and all of the parents up to the root clock.

getParent()[source]
returns:ClockBase representing the immediate parent of this clock, or None if it is a root clock.

(Documentation inherited from ClockBase)

getRoot()[source]
Returns:The root clock for this clock (or itself it has no parent).

New in version 0.4.

getRootMaxFreqError()[source]

Return potential error of underlying clock (e.g. system clock).

Returns:The maximum potential frequency error (in parts-per-million) of the underlying root clock.

This is a partial stub method. It must be re-implemented by root clocks.

For a clock that is not the root clock, this method will pass through the call to the same method of the root clock.

New in version 0.4.

isAvailable()[source]

Returns whether this clock is available, taking into account the availability of any (parent) clocks on which it depends.

Returns:True if available, otherwise False.

New in version 0.4.

isChangeSignificant(newCorrelation, newSpeed, thresholdSecs)[source]

Returns True if the potential for difference in tick values of this clock (using a new correlation and speed) exceeds a specified threshold.

Parameters:
Returns:

True if the potential difference can/will eventually exceed the threshold.

This is implemented by applying a threshold to the output of quantifyChange().

New in version 0.4.

nanos[source]

(read only) The tick count of this clock, but converted to units of nanoseconds, based on the current tick rate (but ignoring the speed property).

nanosToTicks(nanos)[source]

Convert the supplied nanosecond to number of ticks given the current tick rate of this clock (but ignoring the speed property).

Parameters:nanos – nanoseconds value
Returns:number of ticks equivalent to the supplied nanosecond value
notify(cause)[source]

Call to notify this clock that the clock on which it is based (its parent) has changed relative to the underlying timing source.

Parameters:cause – The clock that is calling this method.

Will notify all dependents of this clock (entities that have registered themselves by calling bind()).

quantifyChange(newCorrelation, newSpeed)[source]

Calculate the potential for difference in tick values of this clock if a different correlation and speed were to be used.

Parameters:
Returns:

The potential difference in units of seconds. If speeds differ, this will always be float (“+inf”).

If the new speed is different, even slightly, then this means that the ticks reported by this clock will eventually differ by infinity, and so the returned value will equal +infinity. If the speed is unchanged then the returned value reflects the difference between old and new correlations.

New in version 0.4.

rebaseCorrelationAtTicks(tickValue)[source]

Changes the correlation property to an equivalent correlation (that does not change the timing relationship between parent clock and this clock) where the tick value for this clock is the provided tick value.

setAvailability(availability)[source]

Set the availability of this clock.

Parameters:availability – True if this clock is available, otherwise False.

If setting the availability of this clock changes the overall availability of this clock (as returned by isAvailable()) then dependents will be notified of the change.

New in version 0.4.

setCorrelationAndSpeed(newCorrelation, newSpeed)[source]

Set both the correlation and the speed to new values in a single operation. Generates a single notification for descendents as a result.

Parameters:
  • newCorrelation – A Correlation representing the new correlation. Or a tuple (parentTicks, selfTicks) representing the correlation.
  • newSpeed – New speed as a float.

New in version 0.4.

setParent(newParent)[source]
Change the parent of this clock (if supported). Will generate a notification of change.

(Documentation inherited from ClockBase)

speed[source]
(read/write float) The speed at which the clock is running.
Does not change the reported tickRate value, but will affect how ticks are calculated from parent clock ticks. Default = 1.0 = normal tick rate.

(Documentation inherited from ClockBase)

tickRate[source]

Read or change the tick rate (in ticks per second) of this clock. The value read is not affected by the value of the speed property.

ticks[source]

(read only) The tick count for this clock.

(Documentation inherited from ClockBase)

toOtherClockTicks(otherClock, ticks)[source]

Converts a tick value for this clock into a tick value corresponding to the timescale of another clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:
  • otherClock – A clock object representing another clock.
  • ticks – A time (tick value) for this clock
Returns:

The tick value of the otherClock that represents the same moment in time, or Not a number (nan)

Throws NoCommonClock:
 

if there is no common ancestor clock (meaning it is not possible to convert

toParentTicks(ticks)[source]

Method to convert from a tick value for this clock to the equivalent tick value (representing the same point in time) for the parent clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

returns:The specified tick value of this clock converted to the timescale of the parent clock.
throws StopIteration:
 if this clock has no parent

(Documentation inherited from ClockBase)

toRootTicks(t)[source]

Return the time for the root clock corresponding to a given time of this clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:t – Tick value for this clock.
Returns:Corresponding tick value of the root clock, or Not a number (nan)

New in version 0.4.

unbind(dependent)[source]

Unbind from notification if this clock changes.

Parameters:dependent – The dependent to unbind from receiving notifications.

OffsetClock - A clock that is offset by a fixed amount of root time

class dvbcss.clock.OffsetClock(parentClock, offset=0)[source]

A clock that applies an offset such that reading it is the same as reading its parent, but as if the current time is slightly offset by an amount ahead (+ve offset) or behind (-ve offset).

OffsetClock inherits the tick rate of its parent. Its speed is always 1. It takes the effective speed into account when applying the offset, so it should always represent the same amount of time according to the root clock. In practice this means it will be a constant offset amount of real-world time.

This can be used to compensate for rendering delays. If it takes N seconds to render some content and display it, then a positive offset of N seconds will mean that the rendering code thinks time is N seconds ahead of where it is. It will then render the correct content that is needed to be displayed in N seconds time.

For example: A correlated clock (the “media clock”) represents the time position a video player needs to currently be at.

The video player has a 40 milisecond (0.040 second) delay between when it renders a frame and the light being emitted by the display. We therefore need the video player to render 40 milliseconds in advance of when the frame is to be displayed. An OffsetClock is used to offset time in this way and is passed to the video player:

mediaClock = CorrelatedClock(...)

PLAYER_DELAY_SECS = 0.040
oClock = OffsetClock(parent=mediaClock, offset=PLAYER_DELAY_SECS)

videoPlayer.syncToClock(oClock)

If needed, the offset can be altered at runtime, by setting the offset property. For example, perhaps it needs to be changed to a 50 millisecond offset:

oClock.offset = 0.050

Both positive and negative offsets can be used.

bind(dependent)[source]

Bind for notification if this clock changes.

Parameters:dependent – When this clock changes, the notify() method of this dependent will be called, passing a single argument that is this clock.
calcWhen(ticksWhen)[source]
Return:“when” in terms of the underlying clock behind the root clock implementation (e.g. monotonic_time.time() in the case of SysClock). Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

This is a stub for this method. Sub-classes should implement it.

clockDiff(otherClock)[source]

Calculate the potential for difference between this clock and another clock.

Parameters:otherClock – The clock to compare with.
Returns:The potential difference in units of seconds. If effective speeds or tick rates differ, this will always be float (“+inf”).

If the clocks differ in effective speed or tick rate, even slightly, then this means that the clocks will eventually diverge to infinity, and so the returned difference will equal +infinity.

New in version 0.4.

dispersionAtTime(t)[source]

Calculates the dispersion (maximum error bounds) at the specified clock time. This takes into account the contribution to error of this clock and its ancestors.

Returns:Dispersion (in seconds) at the specified clock time.

New in version 0.4.

fromParentTicks(ticks)[source]

Method to convert from a tick value for this clock’s parent to the equivalent tick value (representing the same point in time) for this clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

returns:The specified tick value for the parent clock converted to the timescale of this clock.
throws StopIteration:
 if this clock has no parent

(Documentation inherited from ClockBase)

fromRootTicks(t)[source]

Return the time for this clock corresponding to a given time of the root clock.

Parameters:t – Tick value of the root clock.
Returns:Corresponding tick value of this clock.

New in version 0.4.

getAncestry()[source]

Retrieve the ancestry of this clock as a list.

Returns:A list of clocks, starting with this clock, and proceeding to its parent, then its parent’s parent etc, ending at the root clock.

New in version 0.4.

getEffectiveSpeed()[source]

Returns the ‘effective speed’ of this clock.

This is equal to multiplying together the speed properties of this clock and all of the parents up to the root clock.

getParent()[source]
returns:ClockBase representing the immediate parent of this clock, or None if it is a root clock.

(Documentation inherited from ClockBase)

getRoot()[source]
Returns:The root clock for this clock (or itself it has no parent).

New in version 0.4.

getRootMaxFreqError()[source]

Return potential error of underlying clock (e.g. system clock).

Returns:The maximum potential frequency error (in parts-per-million) of the underlying root clock.

This is a partial stub method. It must be re-implemented by root clocks.

For a clock that is not the root clock, this method will pass through the call to the same method of the root clock.

New in version 0.4.

isAvailable()[source]

Returns whether this clock is available, taking into account the availability of any (parent) clocks on which it depends.

Returns:True if available, otherwise False.

New in version 0.4.

nanos[source]

(read only) The tick count of this clock, but converted to units of nanoseconds, based on the current tick rate (but ignoring the speed property).

nanosToTicks(nanos)[source]

Convert the supplied nanosecond to number of ticks given the current tick rate of this clock (but ignoring the speed property).

Parameters:nanos – nanoseconds value
Returns:number of ticks equivalent to the supplied nanosecond value
notify(cause)[source]

Call to notify this clock that the clock on which it is based (its parent) has changed relative to the underlying timing source.

Parameters:cause – The clock that is calling this method.

Will notify all dependents of this clock (entities that have registered themselves by calling bind()).

offset[source]

Read or change the number of seconds by which this clock is ahead (the offset).

setAvailability(availability)[source]

Set the availability of this clock.

Parameters:availability – True if this clock is available, otherwise False.

If setting the availability of this clock changes the overall availability of this clock (as returned by isAvailable()) then dependents will be notified of the change.

New in version 0.4.

setParent(newParent)[source]
Change the parent of this clock (if supported). Will generate a notification of change.

(Documentation inherited from ClockBase)

speed[source]

Read the clock’s speed. It is always 1.

tickRate[source]

Read the tick rate (in ticks per second) of this clock. The tick rate is always that of the parent clock.

ticks[source]

(read only) The tick count for this clock.

(Documentation inherited from ClockBase)

toOtherClockTicks(otherClock, ticks)[source]

Converts a tick value for this clock into a tick value corresponding to the timescale of another clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:
  • otherClock – A clock object representing another clock.
  • ticks – A time (tick value) for this clock
Returns:

The tick value of the otherClock that represents the same moment in time, or Not a number (nan)

Throws NoCommonClock:
 

if there is no common ancestor clock (meaning it is not possible to convert

toParentTicks(ticks)[source]

Method to convert from a tick value for this clock to the equivalent tick value (representing the same point in time) for the parent clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

returns:The specified tick value of this clock converted to the timescale of the parent clock.
throws StopIteration:
 if this clock has no parent

(Documentation inherited from ClockBase)

toRootTicks(t)[source]

Return the time for the root clock corresponding to a given time of this clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:t – Tick value for this clock.
Returns:Corresponding tick value of the root clock, or Not a number (nan)

New in version 0.4.

unbind(dependent)[source]

Unbind from notification if this clock changes.

Parameters:dependent – The dependent to unbind from receiving notifications.

TunableClock - Clock with dynamically adjustable frequency and tick offset

class dvbcss.clock.TunableClock(parentClock, tickRate, ticks=0, **kwargs)[source]

A clock whose tick offset and speed can be adjusted on the fly. Must be based on another clock.

Advancement of time of this clock is based on the tick count and rates reported by the supplied parent clock.

If you adjust the tickRate or speed, then the change is applied going forward from the moment it is made. E.g. if you are observing the rate of increase of the ticks property, then doubling the speed wil cause the ticks property to start increasing faster but will not cause it to suddenly jump value.

Changed in version 0.4: TunableClock has been reimplemented as a subclass of CorrelatedClock. The behaviour is the same as before, however it now also includes all the methods defined for CorrelatedClock too.

The maths to calculate and convert tick values will be performed, by default, as integer maths unless the parameters controlling the clock (tickRate etc) are floating point, or the ticks property of the parent clock supplies floating point values.

Parameters:
  • parentClock – The parent clock for this clock.
  • tickRate – The tick rate (ticks per second) for this clock.
  • ticks – The starting tick value for this clock.

The specified starting tick value applies from the moment this object is initialised.

adjustTicks(offset)[source]

Change the tick count of this clock by the amount specified.

bind(dependent)[source]

Bind for notification if this clock changes.

Parameters:dependent – When this clock changes, the notify() method of this dependent will be called, passing a single argument that is this clock.
calcWhen(ticksWhen)[source]
Return:“when” in terms of the underlying clock behind the root clock implementation (e.g. monotonic_time.time() in the case of SysClock). Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

(Documentation inherited from ClockBase)

clockDiff(otherClock)[source]

Calculate the potential for difference between this clock and another clock.

Parameters:otherClock – The clock to compare with.
Returns:The potential difference in units of seconds. If effective speeds or tick rates differ, this will always be float (“+inf”).

If the clocks differ in effective speed or tick rate, even slightly, then this means that the clocks will eventually diverge to infinity, and so the returned difference will equal +infinity.

New in version 0.4.

correlation[source]

Read or change the correlation of this clock to its parent clock.

Assign a new Correlation object to change the correlation.

You can also pass a tuple (parentTicks, selfTicks) which will be converted to a correlation automatically. Reading this property after setting it with a tuple will return the equivalent Correlation.

dispersionAtTime(t)[source]

Calculates the dispersion (maximum error bounds) at the specified clock time. This takes into account the contribution to error of this clock and its ancestors.

Returns:Dispersion (in seconds) at the specified clock time.

New in version 0.4.

fromParentTicks(ticks)[source]

Method to convert from a tick value for this clock’s parent to the equivalent tick value (representing the same point in time) for this clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

returns:The specified tick value for the parent clock converted to the timescale of this clock.
throws StopIteration:
 if this clock has no parent

(Documentation inherited from ClockBase)

fromRootTicks(t)[source]

Return the time for this clock corresponding to a given time of the root clock.

Parameters:t – Tick value of the root clock.
Returns:Corresponding tick value of this clock.

New in version 0.4.

getAncestry()[source]

Retrieve the ancestry of this clock as a list.

Returns:A list of clocks, starting with this clock, and proceeding to its parent, then its parent’s parent etc, ending at the root clock.

New in version 0.4.

getEffectiveSpeed()[source]

Returns the ‘effective speed’ of this clock.

This is equal to multiplying together the speed properties of this clock and all of the parents up to the root clock.

getParent()[source]
returns:ClockBase representing the immediate parent of this clock, or None if it is a root clock.

(Documentation inherited from ClockBase)

(Documentation inherited from CorrelatedClock)

getRoot()[source]
Returns:The root clock for this clock (or itself it has no parent).

New in version 0.4.

getRootMaxFreqError()[source]

Return potential error of underlying clock (e.g. system clock).

Returns:The maximum potential frequency error (in parts-per-million) of the underlying root clock.

This is a partial stub method. It must be re-implemented by root clocks.

For a clock that is not the root clock, this method will pass through the call to the same method of the root clock.

New in version 0.4.

isAvailable()[source]

Returns whether this clock is available, taking into account the availability of any (parent) clocks on which it depends.

Returns:True if available, otherwise False.

New in version 0.4.

isChangeSignificant(newCorrelation, newSpeed, thresholdSecs)[source]

Returns True if the potential for difference in tick values of this clock (using a new correlation and speed) exceeds a specified threshold.

Parameters:
Returns:

True if the potential difference can/will eventually exceed the threshold.

This is implemented by applying a threshold to the output of quantifyChange().

New in version 0.4.

nanos[source]

(read only) The tick count of this clock, but converted to units of nanoseconds, based on the current tick rate (but ignoring the speed property).

nanosToTicks(nanos)[source]

Convert the supplied nanosecond to number of ticks given the current tick rate of this clock (but ignoring the speed property).

Parameters:nanos – nanoseconds value
Returns:number of ticks equivalent to the supplied nanosecond value
notify(cause)[source]

Call to notify this clock that the clock on which it is based (its parent) has changed relative to the underlying timing source.

Parameters:cause – The clock that is calling this method.

Will notify all dependents of this clock (entities that have registered themselves by calling bind()).

quantifyChange(newCorrelation, newSpeed)[source]

Calculate the potential for difference in tick values of this clock if a different correlation and speed were to be used.

Parameters:
Returns:

The potential difference in units of seconds. If speeds differ, this will always be float (“+inf”).

If the new speed is different, even slightly, then this means that the ticks reported by this clock will eventually differ by infinity, and so the returned value will equal +infinity. If the speed is unchanged then the returned value reflects the difference between old and new correlations.

New in version 0.4.

rebaseCorrelationAtTicks(tickValue)[source]

Changes the correlation property to an equivalent correlation (that does not change the timing relationship between parent clock and this clock) where the tick value for this clock is the provided tick value.

setAvailability(availability)[source]

Set the availability of this clock.

Parameters:availability – True if this clock is available, otherwise False.

If setting the availability of this clock changes the overall availability of this clock (as returned by isAvailable()) then dependents will be notified of the change.

New in version 0.4.

setCorrelationAndSpeed(newCorrelation, newSpeed)[source]

Set both the correlation and the speed to new values in a single operation. Generates a single notification for descendents as a result.

Parameters:
  • newCorrelation – A Correlation representing the new correlation. Or a tuple (parentTicks, selfTicks) representing the correlation.
  • newSpeed – New speed as a float.

New in version 0.4.

setError(current, growthRate=0)[source]

Set the current error bounds of this clock and the rate at which it grows per tick of the parent clock.

Parameters:
  • current – Potential error (in seconds) of the clock at this time.
  • growthRate – Amount by which error will grow for every tick of the parent clock.

New in version 0.4.

setParent(newParent)[source]
Change the parent of this clock (if supported). Will generate a notification of change.

(Documentation inherited from ClockBase)

slew[source]

This is an alternative method of querying or adjusting the speed property.

The slew (in ticks per second) currently applied to this clock.

Setting this property will set the speed property to correspond to the specified slew.

For example: for a clock with tickRate of 100, then a slew of -25 corresponds to a speed of 0.75

speed[source]
(read/write float) The speed at which the clock is running.
Does not change the reported tickRate value, but will affect how ticks are calculated from parent clock ticks. Default = 1.0 = normal tick rate.

(Documentation inherited from ClockBase)

tickRate[source]

Read or change the tick rate (in ticks per second) of this clock. The value read is not affected by the value of the speed property.

ticks[source]

(read only) The tick count for this clock.

(Documentation inherited from ClockBase)

toOtherClockTicks(otherClock, ticks)[source]

Converts a tick value for this clock into a tick value corresponding to the timescale of another clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:
  • otherClock – A clock object representing another clock.
  • ticks – A time (tick value) for this clock
Returns:

The tick value of the otherClock that represents the same moment in time, or Not a number (nan)

Throws NoCommonClock:
 

if there is no common ancestor clock (meaning it is not possible to convert

toParentTicks(ticks)[source]

Method to convert from a tick value for this clock to the equivalent tick value (representing the same point in time) for the parent clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

returns:The specified tick value of this clock converted to the timescale of the parent clock.
throws StopIteration:
 if this clock has no parent

(Documentation inherited from ClockBase)

toRootTicks(t)[source]

Return the time for the root clock corresponding to a given time of this clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:t – Tick value for this clock.
Returns:Corresponding tick value of the root clock, or Not a number (nan)

New in version 0.4.

unbind(dependent)[source]

Unbind from notification if this clock changes.

Parameters:dependent – The dependent to unbind from receiving notifications.

RangeCorrelatedClock - Clock correlated to another clock

class dvbcss.clock.RangeCorrelatedClock(parentClock, tickRate, correlation1, correlation2, **kwargs)[source]

A clock locked to the tick count of the parent clock by two different points of correlation.

This relationship can be illustrated as follows:

_images/range-correlated-clock.png

The tickRate you set is purely advisory - it is the tickRate reported to clocks that use this clock as the parent, and may differ from what the reality of the two correlations represents!

Parameters:
  • parentClock – The parent clock for this clock.
  • tickRate – The advisory tick rate (ticks per second) for this clock.
  • correlation1 – (Correlation) or tuple (parentTicks, selfTicks). The first point of correlation for this clock.
  • correlation2 – (Correlation) or tuple (parentTicks, selfTicks). The second point of correlation for this clock.
bind(dependent)[source]

Bind for notification if this clock changes.

Parameters:dependent – When this clock changes, the notify() method of this dependent will be called, passing a single argument that is this clock.
calcWhen(ticksWhen)[source]
Return:“when” in terms of the underlying clock behind the root clock implementation (e.g. monotonic_time.time() in the case of SysClock). Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

(Documentation inherited from ClockBase)

clockDiff(otherClock)[source]

Calculate the potential for difference between this clock and another clock.

Parameters:otherClock – The clock to compare with.
Returns:The potential difference in units of seconds. If effective speeds or tick rates differ, this will always be float (“+inf”).

If the clocks differ in effective speed or tick rate, even slightly, then this means that the clocks will eventually diverge to infinity, and so the returned difference will equal +infinity.

New in version 0.4.

correlation1[source]

Read or change the first correlation of this clock to its parent clock.

Assign a new Correlation or tuple (parentTicks, childTicks) to change the correlation.

correlation2[source]

Read or change the first correlation of this clock to its parent clock.

Assign a new Correlation to change the correlation.

dispersionAtTime(t)[source]

Calculates the dispersion (maximum error bounds) at the specified clock time. This takes into account the contribution to error of this clock and its ancestors.

Returns:Dispersion (in seconds) at the specified clock time.

New in version 0.4.

fromParentTicks(ticks)[source]

Method to convert from a tick value for this clock’s parent to the equivalent tick value (representing the same point in time) for this clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

returns:The specified tick value for the parent clock converted to the timescale of this clock.
throws StopIteration:
 if this clock has no parent

(Documentation inherited from ClockBase)

fromRootTicks(t)[source]

Return the time for this clock corresponding to a given time of the root clock.

Parameters:t – Tick value of the root clock.
Returns:Corresponding tick value of this clock.

New in version 0.4.

getAncestry()[source]

Retrieve the ancestry of this clock as a list.

Returns:A list of clocks, starting with this clock, and proceeding to its parent, then its parent’s parent etc, ending at the root clock.

New in version 0.4.

getEffectiveSpeed()[source]

Returns the ‘effective speed’ of this clock.

This is equal to multiplying together the speed properties of this clock and all of the parents up to the root clock.

getParent()[source]
returns:ClockBase representing the immediate parent of this clock, or None if it is a root clock.

(Documentation inherited from ClockBase)

getRoot()[source]
Returns:The root clock for this clock (or itself it has no parent).

New in version 0.4.

getRootMaxFreqError()[source]

Return potential error of underlying clock (e.g. system clock).

Returns:The maximum potential frequency error (in parts-per-million) of the underlying root clock.

This is a partial stub method. It must be re-implemented by root clocks.

For a clock that is not the root clock, this method will pass through the call to the same method of the root clock.

New in version 0.4.

isAvailable()[source]

Returns whether this clock is available, taking into account the availability of any (parent) clocks on which it depends.

Returns:True if available, otherwise False.

New in version 0.4.

nanos[source]

(read only) The tick count of this clock, but converted to units of nanoseconds, based on the current tick rate (but ignoring the speed property).

nanosToTicks(nanos)[source]

Convert the supplied nanosecond to number of ticks given the current tick rate of this clock (but ignoring the speed property).

Parameters:nanos – nanoseconds value
Returns:number of ticks equivalent to the supplied nanosecond value
notify(cause)[source]

Call to notify this clock that the clock on which it is based (its parent) has changed relative to the underlying timing source.

Parameters:cause – The clock that is calling this method.

Will notify all dependents of this clock (entities that have registered themselves by calling bind()).

setAvailability(availability)[source]

Set the availability of this clock.

Parameters:availability – True if this clock is available, otherwise False.

If setting the availability of this clock changes the overall availability of this clock (as returned by isAvailable()) then dependents will be notified of the change.

New in version 0.4.

setParent(newParent)[source]
Change the parent of this clock (if supported). Will generate a notification of change.

(Documentation inherited from ClockBase)

speed[source]
(read/write float) The speed at which the clock is running.
Does not change the reported tickRate value, but will affect how ticks are calculated from parent clock ticks. Default = 1.0 = normal tick rate.

(Documentation inherited from ClockBase)

tickRate[source]

Read the tick rate (in ticks per second) of this clock. The value read is not affected by the value of the speed property.

ticks[source]

(read only) The tick count for this clock.

(Documentation inherited from ClockBase)

toOtherClockTicks(otherClock, ticks)[source]

Converts a tick value for this clock into a tick value corresponding to the timescale of another clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:
  • otherClock – A clock object representing another clock.
  • ticks – A time (tick value) for this clock
Returns:

The tick value of the otherClock that represents the same moment in time, or Not a number (nan)

Throws NoCommonClock:
 

if there is no common ancestor clock (meaning it is not possible to convert

toParentTicks(ticks)[source]

Method to convert from a tick value for this clock to the equivalent tick value (representing the same point in time) for the parent clock.

Implementations should use the parent clock’s tickRate and speed properties when performing the conversion.

returns:The specified tick value of this clock converted to the timescale of the parent clock.
throws StopIteration:
 if this clock has no parent

(Documentation inherited from ClockBase)

toRootTicks(t)[source]

Return the time for the root clock corresponding to a given time of this clock.

Will return Not a number (nan) if the conversion is not possible (e.g. when current speed is zero and ticksWhen does not match the current correlation.childTicks).

Parameters:t – Tick value for this clock.
Returns:Corresponding tick value of the root clock, or Not a number (nan)

New in version 0.4.

unbind(dependent)[source]

Unbind from notification if this clock changes.

Parameters:dependent – The dependent to unbind from receiving notifications.

Correlation - represents a Correlation

class dvbcss.clock.Correlation(parentTicks, childTicks, initialError=0, errorGrowthRate=0)[source]

Immutable object representing a correlation. This can also optionally include bounds for the potential for error if the correlation is used to model a clock.

The correlation (parentTicks, ticks) represents a relationship between a (child) clock and its parent. The time parentTicks of the parent corresponds to the time ticks of the child.

Parameters:
  • parentTicks – Time of the parent clock.
  • childTcks – Corresponding time of the clock using this correlation.
  • initialError – Optional (default=0). The amount of potential error (in seconds) at the moment represented by the correlation.
  • errorGrowthRate – Optional (default=0). The rate of growth of error (e.g. how many seconds error increases by per second of the parent clock)

This class is intended to be immutable. Instead of modifying a correlation, create a new one based on an existing one. The butWith() method is designed to assist with this.

..note:

For backwards compatibility with pydvbcss v0.3 and earlier, this object can
also be treated as if it is a tuple (parentTicks, childTicks), for example:

..code-block:: python

    c = Correlation(1,5, 0.1, 0.005)
    
    # unapacking using an expression assignment
    parentTicks, childTicks = c
    
    # accessing by index
    parentTicks = c[0]
    childTicks = c[1]

New in version 0.4.

butWith(parentTicks=None, childTicks=None, initialError=None, errorGrowthRate=None)[source]

Return a new correlation the same as this one but with the specified changes.

Parameters:
  • parentTicks – Optional. A new Time of the parent clock.
  • childTcks – Optional. The corresponding time of the clock using this correlation.
  • initialError – Optional. The amount of potential error (in seconds) at the moment represented by the correlation.
  • errorGrowthRate – Optional. The rate of growth of error (e.g. how many seconds error increases by per second of the parent clock)
Returns:

New Correlation based on this one, but with the changes specified by the parameters.

If a parameter is set to None or not provided, then the existing value is taken from this correlation object.

childTicks[source]

Number representing a time of the child clock, that corresponds to the parentTicks time of the parent clock.

errorGrowthRate[source]

Number representing the amount that the potential for error will grow by (in units of seconds) for every tick of the parent clock. Default value is 0 if not set.

initialError[source]

Number representing the amount of potential error (in units of seconds) at the moment represented by the correlation. Default value is 0 if not set.

parentTicks[source]

Number representing a time of the parent clock.