module Music.Time.Track (
Track,
track,
delayeds,
singleDelayed,
) where
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.Set (Set)
import qualified Data.Set as Set
import Data.VectorSpace
import Music.Time.Delayed
import Music.Time.Reverse
import Music.Time.Split
import Control.Applicative
import Control.Lens hiding (Indexable, Level, above, below,
index, inside, parts, reversed,
transform, (<|), (|>))
import Control.Monad
import Control.Monad.Compose
import Control.Monad.Plus
import Data.Foldable (Foldable)
import qualified Data.Foldable as Foldable
import Data.Traversable (Traversable)
import qualified Data.Traversable as T
import Data.Typeable
import Music.Time.Internal.Util
newtype Track a = Track { getTrack :: TrackList (TrackEv a) }
deriving (Functor, Foldable, Traversable, Semigroup, Monoid, Typeable, Show, Eq)
type TrackList = []
type TrackEv a = Delayed a
trackEv :: Iso (Delayed a) (Delayed b) (TrackEv a) (TrackEv b)
trackEv = id
instance Applicative Track where
pure = return
(<*>) = ap
instance Alternative Track where
(<|>) = (<>)
empty = mempty
instance Monad Track where
return = view _Unwrapped . return . return
xs >>= f = view _Unwrapped $ (view _Wrapped . f) `mbind` view _Wrapped xs
instance Wrapped (Track a) where
type Unwrapped (Track a) = (TrackList (TrackEv a))
_Wrapped' = iso getTrack Track
instance Rewrapped (Track a) (Track b)
instance Transformable (Track a) where
transform s = over _Wrapped' (transform s)
instance HasPosition (Track a) where
_onset = safeMinimum . fmap _onset . view _Wrapped'
_offset = safeMaximum . fmap _offset . view _Wrapped'
safeMinimum xs = if null xs then 0 else minimum xs
safeMaximum xs = if null xs then 0 else maximum xs
instance HasDuration (Track a) where
_duration x = _offset x .-. _onset x
instance Splittable a => Splittable (Track a) where
instance Reversible a => Reversible (Track a) where
track :: Getter [Delayed a] (Track a)
track = from unsafeTrack
delayeds :: Lens (Track a) (Track b) [Delayed a] [Delayed b]
delayeds = unsafeTrack
singleDelayed :: Prism' (Track a) (Delayed a)
singleDelayed = unsafeTrack . single
unsafeTrack :: Iso (Track a) (Track b) [Delayed a] [Delayed b]
unsafeTrack = _Wrapped