module Music.Time.Internal.Transform (
module Music.Time.Types,
Transformable(..),
transformed,
whilst,
whilstL,
whilstLT,
whilstLD,
onSpan,
delaying,
undelaying,
stretching,
compressing,
delay,
undelay,
stretch,
compress,
) where
import Control.Applicative
import Control.Lens hiding (Indexable, Level, above,
below, index, inside, parts,
reversed, transform, (<|), (|>))
import Data.AffineSpace
import Data.AffineSpace.Point
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Ratio
import Data.Semigroup
import Data.Semigroup.Instances ()
import Data.Sequence (Seq)
import qualified Data.Sequence as Seq
import Data.Set (Set)
import qualified Data.Set as Set
import Data.VectorSpace hiding (Sum (..))
import Music.Time.Types
class Transformable a where
transform :: Span -> a -> a
instance Transformable () where
transform _ = id
instance Transformable Bool where
transform _ = id
instance Transformable Ordering where
transform _ = id
instance Transformable Char where
transform _ = id
instance Transformable Int where
transform _ = id
instance Transformable Integer where
transform _ = id
instance Transformable a => Transformable (Ratio a) where
transform _ = id
instance Transformable Float where
transform _ = id
instance Transformable Double where
transform _ = id
instance Transformable Duration where
(view onsetAndDuration -> (_, d1)) `transform` d2 = d1 * d2
instance Transformable Time where
(view onsetAndDuration -> (t1, d1)) `transform` t2 = t1 ^+^ d1 *^ t2
instance Transformable Span where
transform = (<>)
instance Transformable a => Transformable (Maybe a) where
transform s = fmap (transform s)
instance Transformable a => Transformable (Option a) where
transform s = fmap (transform s)
instance Transformable a => Transformable (Last a) where
transform s = fmap (transform s)
instance Transformable a => Transformable (Sum a) where
transform s = fmap (transform s)
instance Transformable a => Transformable (Product a) where
transform s = fmap (transform s)
instance Transformable a => Transformable (b, a) where
transform t = fmap (transform t)
instance Transformable a => Transformable [a] where
transform t = fmap (transform t)
instance Transformable a => Transformable (Seq a) where
transform t = fmap (transform t)
instance (Ord a, Transformable a) => Transformable (Set a) where
transform t = Set.map (transform t)
instance (Ord k, Transformable a) => Transformable (Map k a) where
transform t = Map.map (transform t)
instance (Transformable a, Transformable b) => Transformable (a -> b) where
transform t = (`whilst` negateV t)
where
f `whilst` t = over (transformed t) f
transformed :: (Transformable a, Transformable b) => Span -> Iso a b a b
transformed s = iso (transform s) (transform $ negateV s)
whilst :: (Transformable a, Transformable b) => (a -> b) -> Span -> a -> b
f `whilst` t = over (transformed t) f
delayed :: (Transformable a, Transformable b) => Time -> Iso a b a b
delayed = transformed . delayingTime
stretched :: (Transformable a, Transformable b) => Duration -> Iso a b a b
stretched = transformed . stretching
delaying :: Duration -> Span
delaying x = (0 .+^ x) >-> 1
delayingTime :: Time -> Span
delayingTime x = x >-> 1
stretching :: Duration -> Span
stretching x = 0 >-> x
undelaying :: Duration -> Span
undelaying x = delaying (negate x)
compressing :: Duration -> Span
compressing x = stretching (recip x)
delay :: Transformable a => Duration -> a -> a
delay = transform . delaying
undelay :: Transformable a => Duration -> a -> a
undelay = transform . undelaying
stretch :: Transformable a => Duration -> a -> a
stretch = transform . stretching
compress :: Transformable a => Duration -> a -> a
compress = transform . compressing
dofoo :: Functor f => (x -> s -> a) -> (x -> b -> t) -> LensLike f (x,s) (x,t) a b
dofoo v w = \f (s,a) -> (s,) <$> w s <$> f ((v s) a)
dobar :: Functor f => (x -> LensLike f a' b' a b) -> LensLike f s t a' b' -> LensLike f (x,s) (x,t) a b
dobar q l = \f (s,a) -> (s,) <$> (l (q s f)) a
whilstL :: (Functor f, Transformable a, Transformable b)
=> LensLike f s t a b
-> LensLike f (Span,s) (Span,t) a b
whilstL l = dobar transformed l
whilstLT :: (Functor f, Transformable a, Transformable b)
=> LensLike f s t a b
-> LensLike f (Time,s) (Time,t) a b
whilstLT = dobar delayed
whilstLD :: (Functor f, Transformable a, Transformable b)
=> LensLike f s t a b
-> LensLike f (Duration,s) (Duration,t) a b
whilstLD = dobar stretched
whilstDelay :: (Transformable a, Transformable b) => (a -> b) -> Time -> a -> b
whilstDelay = flip (flip whilst . delaying . (.-. 0))
whilstStretch :: (Transformable a, Transformable b) => (a -> b) -> Duration -> a -> b
whilstStretch = flip (flip whilst . stretching)
conjugateS :: Span -> Span -> Span
conjugateS t1 t2 = negateV t1 <> t2 <> t1
onSpan :: (Transformable s, Transformable t, Functor f)
=> LensLike f s t a b -> Span -> LensLike f s t a b
f `onSpan` s = transformed (negateV s) . f