module EuterpeaUtils ( -- re-exporting Euterpea things module Export -- conversion from/to Euterpea datatype , patternToMusic, musicToPattern ) where import Euterpea.Music as Export hiding (Rest, Note, pitch) import qualified Euterpea.Music as M import Types -- | Convert our Pattern datatype to Euterpea's music datatype. patternToMusic :: Pattern -> Music AbsPitch patternToMusic = line . fmap convert . withDurations where withDurations :: Pattern -> [(MIDI, Time)] withDurations ps = zip (pitch ps) (durations ps ++ [4]) convert :: (MIDI, Time) -> Music AbsPitch convert (m, tt) = Prim $ M.Note (toRational tt) (fromInteger m) -- | Convert from Euterpea's music datatype to our pattern datatype. musicToPattern :: ToMusic1 a => Music a -> Pattern musicToPattern = withDurations . convert . fmap (absPitch . fst) . toMusic1 where convert :: Music AbsPitch -> [Either Time Note] convert (n :+: ns) = convert n ++ convert ns convert (n :=: _) = convert n convert (Modify _ n) = convert n convert (Prim prim) = case prim of M.Rest r -> [Left $ fromRational r] M.Note dr p -> [Right $ Note (fromRational dr) (toInteger p)] withDurations :: [Either Time Note] -> [Note] withDurations = snd . foldl go (0.0, []) where go :: (Double, [Note]) -> Either Time Note -> (Double, [Note]) go (acc, ns) (Left tt) = (acc + tt, ns) go (acc, ns) (Right (Note tt m)) = (acc', ns ++ [Note acc m]) where acc' = acc + tt