Karya, built on 2020-11-26T21:03:17 (patch 23b5be2d53a9e8e7d6136cda5aae2849abe5cded)

Derive.Warp

Contents

Description

Functions for the Warp.

Synopsis

# Documentation

data Warp Source #

The Warp keeps track of the ScoreTime -> RealTime function, as well as its inverse.

This treats linear warps specially, since they're common and allow some optimizations.

The main transformation is compose, but shift and stretch are shortcuts for composing with f(x) = y + shift or f(x) = y * stretch, respectively.

The confusing thing is that shift and stretch compose with the *input* of the function, so shift n is (compose shift n identity). This means that shift 1 . stretch 2 is actually (*2) . (+1), which makes compositions look backwards. It turns out this is more convenient since Deriver level shift and stretch go in left-to-right order since monadic effects go left to right:

Reader.runReader (Reader.local (+1) . Reader.local (*2) \$ Reader.ask) 0

is 2, not 1.

There is probably some kind of theory to do with positive position or negative position or some such thing, but my tiny brain can't quite get a handle on it, so all I can say is that this is the way that makes things work out right.

#### Instances

Instances details
 # Instance detailsDefined in Derive.Warp MethodsshowsPrec :: Int -> Warp -> ShowS #show :: Warp -> String #showList :: [Warp] -> ShowS # # I can't really rnf functions, but maybe there will be data in here someday. Instance detailsDefined in Derive.Warp Methodsrnf :: Warp -> () # # Instance detailsDefined in Derive.Warp MethodsformatList :: [Warp] -> Doc Source #

data Linear Source #

Constructors

 Linear Fields

#### Instances

Instances details
 # Instance detailsDefined in Derive.Warp MethodsshowsPrec :: Int -> Linear -> ShowS #showList :: [Linear] -> ShowS #

The inverse of warp. I originally would fail when the RealTime doesn't occur in the Warp, but now I extend it in the same way as warp. Failing caused awkwardness with events at the end of the score.

1:1 identity warp. Previously I could detect this to optimize it away, but since compose is cheap now, I might not need that anymore.

Create a Warp from a signal and its inverse. This assumes the signal is monotonically increasing.

Times <0 always pass through unchanged. This is because warps start at 0, since tracks start at 0, but events may be moved before it. Since there's no tempo data there, I need to make something up, and I might as well make up id. TODO error on empty signal? or id?

"See Warp.

See Warp.

Previously, this would disallow <=0 stretch, but it turns out to be useful to stretch events to 0, and to negative durations.