module Music.Prelude.Inspectable (
Inspectable(..),
display,
audify,
displayAndAudify,
) where
import qualified System.Process
import Music.Prelude.Standard hiding (open,play)
import qualified Music.Score
import qualified System.Process
import qualified System.Info
import Data.Ini
data Conf
= Conf
String
String
String
String
defaultConf = Conf
"timidity"
"timidity -Ow"
"open -a audacity"
"lilypond"
ucat :: (Monoid a, Semigroup a, HasParts a a, Music.Score.Part a ~ Part) => [a] -> a
ucat xs = if allDistinct ps
then pcat xs
else pcat $ zipWith (set parts') (divide (length xs) p) xs
where
ps = concatMap (toListOf parts') xs
p = foldr1 largestPart ps
class Inspectable a where
inspectableToMusic :: a -> Music
displayAndAudify :: Inspectable a => a -> IO ()
displayAndAudify x = display x >> audify x
instance Inspectable (Score StandardNote) where
inspectableToMusic = id
display :: Inspectable a => a -> IO ()
audify :: Inspectable a => a -> IO ()
display = display' . inspectableToMusic
audify = audify' . inspectableToMusic
display' = openLilypond
where
openLilypond' options sc = do
writeLilypond' options "test.ly" sc
runLilypond >> cleanLilypond >> runOpen
where
runLilypond = void $ System.Process.runCommand
"lilypond -f pdf test.ly 2>/dev/null" >>= System.Process.waitForProcess
cleanLilypond = void $ System.Process.runCommand
"rm -f test-*.tex test-*.texi test-*.count test-*.eps test-*.pdf test.eps"
runOpen = void $ System.Process.runCommand
$ openCommand ++ " test.pdf"
openCommand :: String
openCommand = case System.Info.os of
"darwin" -> "open"
"linux" -> "xdg-open"
audify' = play_
where
play_ x = do
writeMidi "test.mid" x
System.Process.system "timidity test.mid 2>/dev/null >/dev/null"
return ()
instance Inspectable a => Inspectable (Maybe a) where
inspectableToMusic = maybe mempty id . fmap inspectableToMusic
instance Inspectable (Score Pitch) where
inspectableToMusic = inspectableToMusic . asScore . fmap fromPitch''
instance Inspectable (Voice StandardNote) where
inspectableToMusic = inspectableToMusic . renderAlignedVoice . aligned 0 0
instance Inspectable (Voice Pitch) where
inspectableToMusic = inspectableToMusic . asScore . renderAlignedVoice . aligned 0 0 . fmap fromPitch''
instance Inspectable (Voice ()) where
inspectableToMusic = inspectableToMusic . set pitches (c::Pitch)
instance Inspectable (Ambitus Pitch) where
inspectableToMusic x = let (m,n) = x^.from ambitus in glissando $ fromPitch'' m |> fromPitch'' n
instance Inspectable [Chord Pitch] where
inspectableToMusic = scat . fmap inspectableToMusic
instance Inspectable (Mode Pitch) where
inspectableToMusic = inspectableToMusic . modeToScale c
instance Inspectable (Scale Pitch) where
inspectableToMusic = fmap fromPitch'' . scat . map (\x -> pure x :: Score Pitch) . scaleToList
instance Inspectable (Function Pitch) where
inspectableToMusic = inspectableToMusic . functionToChord c
instance Inspectable (Chord Pitch) where
inspectableToMusic = fmap fromPitch'' . pcat . map (\x -> pure x :: Score Pitch) . chordToList
instance Inspectable [Pitch] where
inspectableToMusic = compress 8 . scat . fmap fromPitch''
instance Inspectable Pitch where
inspectableToMusic = inspectableToMusic . (:[])
instance Inspectable Interval where
inspectableToMusic v = stretch 8 $inspectableToMusic [c::Pitch, c .+^ v]
instance Inspectable Span where
inspectableToMusic s = transform s c
instance Inspectable Time where
inspectableToMusic t = inspectableToMusic (t >-> (1/4))
instance Inspectable Duration where
inspectableToMusic d = inspectableToMusic (0 >-> d)
instance Inspectable [Span] where
inspectableToMusic xs = ucat $fmap inspectableToMusic xs
instance Inspectable [Voice Pitch] where
inspectableToMusic = asScore . ucat . fmap (fmap fromPitch'') . fmap (renderAlignedVoice . aligned 0 0)
instance Inspectable [Note Pitch] where
inspectableToMusic = inspectableToMusic . fmap ((^.voice) . pure)