midi-utils-0.1.0.0: src/Sound/MIDI/Utils/LiftMap.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Sound.MIDI.Utils.LiftMap
( slowTrack
, speedTrack
, liftMap
) where
import qualified Sound.MIDI.File as F
import qualified Sound.MIDI.File.Event as E
import qualified Data.EventList.Relative.TimeBody as T
import qualified Sound.MIDI.Message.Channel.Voice as V
import qualified Sound.MIDI.Message.Channel as C
type MIDI = F.T
type Voice = V.T
type MEvent = E.T
type MessageChan = C.T
mapElapsedTimeIntegral :: (Integer -> Integer) -> MIDI -> MIDI
mapElapsedTimeIntegral f = liftMap $ F.toElapsedTime . f . F.fromElapsedTime
slowTrack :: Integer -> MIDI -> MIDI
slowTrack n = mapElapsedTimeIntegral (*n)
speedTrack :: Integer -> MIDI -> MIDI
speedTrack n = mapElapsedTimeIntegral (`div`n)
mapPitch :: (V.Pitch -> V.Pitch) -> Voice -> Voice
mapPitch f (V.NoteOff p v) = V.NoteOff (f p) v
mapPitch f (V.NoteOn p v) = V.NoteOn (f p) v
mapPitch f (V.PolyAftertouch p pr) = V.PolyAftertouch (f p) pr
mapPitch _ v = v
mapVelocity :: (V.Velocity -> V.Velocity) -> Voice -> Voice
mapVelocity f (V.NoteOff p v) = V.NoteOff p (f v)
mapVelocity f (V.NoteOn p v) = V.NoteOn p (f v)
mapVelocity _ v = v
-- | Instances of @LiftMap a b@ can lift maps from @a -> a@ to @b -> b@.
class LiftMap a b where
liftMap :: (a -> a) -> b -> b
-- ElapsedTime
instance LiftMap F.ElapsedTime F.Track where
liftMap = T.mapTime
instance LiftMap F.ElapsedTime MIDI where
liftMap f = liftMap (liftMap f :: F.Track -> F.Track)
-- MessageChan
instance LiftMap MessageChan MEvent where
liftMap f (E.MIDIEvent e) = E.MIDIEvent (f e)
liftMap _ e = e
instance LiftMap MessageChan F.Track where
liftMap f = liftMap (liftMap f :: MEvent -> MEvent)
instance LiftMap MessageChan MIDI where
liftMap f = liftMap (liftMap f :: F.Track -> F.Track)
-- MEvent
instance LiftMap MEvent F.Track where
liftMap = T.mapBody
instance LiftMap MEvent MIDI where
liftMap f = liftMap (liftMap f :: F.Track -> F.Track)
-- Pitch
instance LiftMap V.Pitch Voice where
liftMap = mapPitch
instance LiftMap V.Pitch F.Track where
liftMap f = liftMap (liftMap f :: Voice -> Voice)
instance LiftMap V.Pitch MIDI where
liftMap f = liftMap (liftMap f :: F.Track -> F.Track)
-- Track
instance LiftMap F.Track MIDI where
liftMap = F.mapTrack
-- Voice
instance LiftMap Voice MEvent where
liftMap = E.mapVoice
instance LiftMap Voice F.Track where
liftMap f = liftMap (liftMap f :: MEvent -> MEvent)
instance LiftMap Voice MIDI where
liftMap f = liftMap (liftMap f :: F.Track -> F.Track)