module Music.Time.Note (
Note,
note,
notee,
durationNote,
) where
import Control.Applicative
import Control.Lens hiding (Indexable, Level, above, below,
index, inside, parts, reversed,
transform, (<|), (|>))
import Data.Bifunctor
import Data.Foldable (Foldable)
import qualified Data.Foldable as Foldable
import Data.Functor.Couple
import Data.String
import Data.Typeable
import Data.VectorSpace
import Music.Dynamics.Literal
import Music.Pitch.Literal
import Music.Time.Reverse
import Music.Time.Split
newtype Note a = Note { getNote :: Duration `Couple` a }
deriving (
Eq,
Ord,
Typeable,
Foldable,
Traversable,
Functor,
Applicative,
Monad,
Num,
Fractional,
Floating,
Real,
RealFrac
)
instance (Show a, Transformable a) => Show (Note a) where
show x = show (x^.from note) ++ "^.note"
instance Wrapped (Note a) where
type Unwrapped (Note a) = (Duration, a)
_Wrapped' = iso (getCouple . getNote) (Note . Couple)
instance Rewrapped (Note a) (Note b)
instance Transformable (Note a) where
transform t = over (from note . _1) (transform t)
instance HasDuration (Note a) where
_duration = _duration . view (from note)
instance IsString a => IsString (Note a) where
fromString = pure . fromString
instance IsPitch a => IsPitch (Note a) where
fromPitch = pure . fromPitch
instance IsInterval a => IsInterval (Note a) where
fromInterval = pure . fromInterval
instance IsDynamics a => IsDynamics (Note a) where
fromDynamics = pure . fromDynamics
note :: Iso (Duration, a) (Duration, b) (Note a) (Note b)
note = _Unwrapped
notee :: (Transformable a, Transformable b) => Lens (Note a) (Note b) a b
notee = _Wrapped `dependingOn` (transformed . stretching)
durationNote :: Iso' Duration (Note ())
durationNote = iso (\d -> (d,())^.note) (^.duration)
noteComplement :: Note a -> Note a
noteComplement (Note (Couple (d,x))) = Note $ Couple (negateV d, x)
dependingOn :: Lens s t (x,a) (x,b) -> (x -> Lens a b c d) -> Lens s t c d
dependingOn l depending f = l (\ (x,a) -> (x,) <$> depending x f a)