Karya, built on 2018-05-31T02:46:59 (patch 0a1a35479c514820d77330ae8a978975ba22a47a)

Safe HaskellNone

Perform.RealTime

Contents

Description

RealTime represents seconds, as opposed to ScoreTime, which is in abstract units. Everything eventually is transformed into RealTime to be performed.

This type has switched from floating point to decimal and back again. The problem is that floating point is not exact, but there are a few operations that require events that have the same ScoreTime to be grouped with each other once they reach RealTime. For instance, controls are clipped to the note boundaries, and a note is required to have a pitch at exactly its starting time. While the event that produces the pitch signal may have the same ScoreTime as the note it belongs to, if imprecision has caused it to drift a little by the time it gets to performance, the note may wind up with no initial pitch, or pick up the pitch of the next note as a pitch bend.

An example of how imprecision can accumulate is a block call with pitch set in the caller. If the sub-block has a note at 0 this should line up with the start of the block call in the super-block and hence with a pitch at the same time. But the sub-block has its own warp which is a composition of the its tempo and the super-block's tempo. In theory the sub-block's warp should be shifted so its 0 starts at the calling point in the super-block, but in practice this is a number of floating point operations (addition, linear interpolation, ...) and the value may very well be slightly different.

Unfortunately switching RealTime to a lower-precision decimal type has the same problem because it introduces even more imprecision due to the ScoreTime -> RealTime -> ScoreTime conversion (this happens during warp composition, for instance, since shift and stretch are in ScoreTime). And I think it's ultimately not quite right because rounding will still produce incorrect results if the imprecise value falls at a rounding boundary.

Eventually, for MIDI at least, everything is rounded down to milliseconds so hopefully any imprecision can be accounted for by the operations that care about it and eventually be removed from the final result.

Synopsis

Documentation

data RealTime Source #

A concrete unit of time.

This must have negative values because it's used for signals, which are used for the warp map, which is oriented with zero at the note start. If a note wants to get the real time before it, it must look up a negative RealTime.

Instances
Eq RealTime # 
Instance details

Defined in Perform.RealTime

Fractional RealTime # 
Instance details

Defined in Perform.RealTime

Num RealTime # 
Instance details

Defined in Perform.RealTime

Ord RealTime # 
Instance details

Defined in Perform.RealTime

Read.Read RealTime # 
Instance details

Defined in Perform.RealTime

Real RealTime # 
Instance details

Defined in Perform.RealTime

RealFrac RealTime # 
Instance details

Defined in Perform.RealTime

Methods

properFraction :: Integral b => RealTime -> (b, RealTime) #

truncate :: Integral b => RealTime -> b #

round :: Integral b => RealTime -> b #

ceiling :: Integral b => RealTime -> b #

floor :: Integral b => RealTime -> b #

Show RealTime # 
Instance details

Defined in Perform.RealTime

Storable RealTime # 
Instance details

Defined in Perform.RealTime

DeepSeq.NFData RealTime # 
Instance details

Defined in Perform.RealTime

Methods

rnf :: RealTime -> () #

C.CStorable RealTime # 
Instance details

Defined in Perform.RealTime

CRC32.CRC32 RealTime # 
Instance details

Defined in Perform.RealTime

ToJSON RealTime # 
Instance details

Defined in Perform.RealTime

FromJSON RealTime # 
Instance details

Defined in Perform.RealTime

ApproxEq.ApproxEq RealTime # 
Instance details

Defined in Perform.RealTime

Methods

eq :: Double -> RealTime -> RealTime -> Bool Source #

Pretty RealTime # 
Instance details

Defined in Perform.RealTime

Serialize.Serialize RealTime # 
Instance details

Defined in Perform.RealTime

ShowVal.ShowVal RealTime # 
Instance details

Defined in Perform.RealTime

ShowVal.ShowVal Function # 
Instance details

Defined in Derive.Typecheck

ShowVal.ShowVal TypedFunction # 
Instance details

Defined in Derive.Typecheck

ToVal RealTime # 
Instance details

Defined in Derive.RestrictedEnviron

Methods

to_val :: RealTime -> Val Source #

Time RealTime # 
Instance details

Defined in Derive.Deriver.Internal

TypecheckNum RealTime # 
Instance details

Defined in Derive.Typecheck

ToVal RealTime # 
Instance details

Defined in Derive.Typecheck

Methods

to_val :: RealTime -> Val Source #

Typecheck RealTime # 
Instance details

Defined in Derive.Typecheck

Typecheck Function # 
Instance details

Defined in Derive.Typecheck

Typecheck TypedFunction # 
Instance details

Defined in Derive.Typecheck

div :: RealTime -> Double -> RealTime infixl 7 Source #

mul :: RealTime -> Double -> RealTime infixl 7 Source #

large :: RealTime Source #

A large RealTime as a stand-in for "forever" in signals.

I tried Infinity, but a constant signal starting at -Infinity will have an integral ending at (Infinity, Infinity) (or (Infinity, NaN) in practice), at which point I lost the slope.

1e10 is recognizable in debugging output as a special value, and still quite far away from 2^53 (9e15), which is where integers can no longer be represented exactly in a 64 bit Double. This means I can take the integral at a steep slope and I should still be in the realm of exact integers, which means the slope should stay accurate.

larger :: RealTime Source #

Comfortably bigger than large, so it won't cross large given normal amonuts of time shift.

show_units :: RealTime -> Text Source #

Show RealTime as hours, minutes, seconds.

convert from

convert to

misc

eta :: RealTime Source #

Eta for comparison. Since RealTimes are seconds, this amount of time is definitely unnoticeable.

(==) :: RealTime -> RealTime -> Bool Source #

RealTimes are imprecise, so compare them with this instead of (==).