module Music.Time.Onset (
HasDuration(..),
HasOnset(..),
HasOffset(..),
HasPreOnset(..),
HasPostOnset(..),
HasPostOffset(..),
durationDefault,
onsetDefault,
offsetDefault,
AddOffset(..),
) where
import Data.Semigroup
import Data.VectorSpace
import Data.AffineSpace
import Music.Time.Pos
import Music.Time.Time
import Music.Time.Duration
import Music.Time.Delayable
import Music.Time.Stretchable
class HasDuration s where
duration :: s a -> Duration s
class HasOnset s where
onset :: s a -> Time s
class HasOffset s where
offset :: s a -> Time s
class HasPreOnset s where
preOnset :: s a -> Time s
class HasPostOnset s where
postOnset :: s a -> Time s
class HasPostOffset s where
postOffset :: s a -> Time s
durationDefault :: (AffineSpace (Time s), HasOffset s, HasOnset s) => s a -> Duration s
durationDefault x = offset x .-. onset x
onsetDefault :: (AffineSpace (Time s), HasOffset s, HasDuration s) => s a -> Time s
onsetDefault x = offset x .-^ duration x
offsetDefault :: (AffineSpace (Time s), HasOnset s, HasDuration s) => s a -> Time s
offsetDefault x = onset x .+^ duration x
newtype AddOffset t s a = AddOffset (t, s a)
type instance Time (AddOffset t s) = t
instance (Delayable a, t ~Time a) => Delayable (AddOffset t a) where
delay d (AddOffset (t,a)) = AddOffset (t, delay d a)
instance (Stretchable a, t ~Time a) => Stretchable (AddOffset t a) where
stretch d (AddOffset (t,a)) = AddOffset (t, stretch d a)
instance (HasOnset a, t ~Time a) => HasOnset (AddOffset t a) where
onset (AddOffset (t,a)) = onset a
instance HasOffset (AddOffset t s) where
offset (AddOffset (t,_)) = t