diff --git a/music-preludes.cabal b/music-preludes.cabal
--- a/music-preludes.cabal
+++ b/music-preludes.cabal
@@ -1,62 +1,107 @@
 
-name:               music-preludes
-version:            1.6
-cabal-version:      >= 1.10
-author:             Hans Hoglund
-maintainer:         Hans Hoglund
-license:            BSD3
-license-file:       COPYING
-synopsis:           Some useful preludes for the Music Suite.
-category:           Music
-tested-with:        GHC
-build-type:         Simple
+name:                   music-preludes
+version:                1.6.1
+author:                 Hans Hoglund
+maintainer:             Hans Hoglund
+license:                BSD3
+license-file:           COPYING
+synopsis:               Some useful preludes for the Music Suite.
+category:               Music
+tested-with:            GHC
+build-type:             Simple
+cabal-version:          >= 1.10
 
-description: 
+description:
     Some useful preludes for the Music Suite.
-
+    .
     This library is part of the Music Suite, see <http://music-suite.github.io>.
 
 source-repository head
-  type:             git
-  location:         git://github.com/music-suite/music-preludes.git
-  
-library                    
-    build-depends: 
-        base                    >= 4 && < 5,
-        lens,
-        vector-space,
-        vector-space-points,
-        lilypond                == 1.6,
-        musicxml2               == 1.6,
-        process,
-        semigroups,
-        data-default,
-        monadplus,
-        reverse-apply,
-        music-score             == 1.6,
-        music-pitch             == 1.6,
-        music-dynamics          == 1.6,
-        music-parts             == 1.6,
-        music-pitch-literal     == 1.6,
-        music-dynamics-literal  == 1.6
-    hs-source-dirs: src
-    default-language: Haskell2010
-    exposed-modules:
-        Music.Prelude.Basic
-        Music.Prelude.Standard
-        Music.Prelude.Piano
-        Music.Prelude.StringQuartet
-        Music.Prelude.Instances
+  type:                 git
+  location:             git://github.com/music-suite/music-preludes.git
 
--- test-suite properties
---     type: exitcode-stdio-1.0
---     main-is: properties.hs
---     hs-source-dirs: tests
---     default-language: Haskell2010
---     ghc-options: -w -threaded -rtsopts -with-rtsopts=-N
---     build-depends:
---         HUnit                       >= 1.2,
---         QuickCheck                  >= 1.2 && < 1.3,
---         test-framework              >= 0.6,
---         test-framework-th           >= 0.2,
---         test-framework-quickcheck   >= 0.3
+library
+    build-depends:      base                    >= 4 && < 5,
+                        lens,
+                        split,
+                        unix,
+                        containers,
+                        vector-space,
+                        vector-space-points,
+                        lilypond                == 1.6,
+                        musicxml2               == 1.6,
+                        process,
+                        filepath                >= 1.3  && < 2,
+                        temporary               >= 1.1  && < 2,
+                        optparse-applicative    >= 0.8  && < 1,
+                        semigroups,
+                        data-default,
+                        monadplus,
+                        reverse-apply,
+                        music-score             == 1.6,
+                        music-pitch             == 1.6,
+                        music-dynamics          == 1.6,
+                        music-parts             == 1.6,
+                        music-pitch-literal     == 1.6,
+                        music-dynamics-literal  == 1.6
+    exposed-modules:    Music.Prelude.Basic
+                        Music.Prelude.Standard
+                        Music.Prelude.Piano
+                        Music.Prelude.StringQuartet
+                        Music.Prelude.CmdLine
+                        Music.Prelude.Instances
+    hs-source-dirs:     src
+    default-language:   Haskell2010
+
+executable "music2ly"
+    build-depends:      base,
+                        music-preludes
+    main-is:            music2ly.hs
+    hs-source-dirs:     tools
+    default-language:   Haskell2010
+
+executable "music2pdf"
+    build-depends:      base,
+                        music-preludes
+    main-is:            music2pdf.hs
+    hs-source-dirs:     tools
+    default-language:   Haskell2010
+
+executable "music2png"
+    build-depends:      base,
+                        music-preludes
+    main-is:            music2png.hs
+    hs-source-dirs:     tools
+    default-language:   Haskell2010
+
+executable "music2svg"
+    build-depends:      base,
+                        music-preludes
+    main-is:            music2svg.hs
+    hs-source-dirs:     tools
+    default-language:   Haskell2010
+
+executable "music2musicxml"
+    build-depends:      base,
+                        music-preludes
+    main-is:            music2musicxml.hs
+    hs-source-dirs:     tools
+    default-language:   Haskell2010
+
+executable "music2midi"
+    build-depends:      base,
+                        music-preludes
+    main-is:            music2midi.hs
+    hs-source-dirs:     tools
+    default-language:   Haskell2010
+
+test-suite "regression"
+    build-depends:      base                    >= 4   && < 5,
+                        tasty                   >= 0.8 && < 1,
+                        tasty-golden            >= 2.2 && < 3,
+                        process
+    type:               exitcode-stdio-1.0
+    main-is:            tests.hs
+    hs-source-dirs:     tests
+    default-language:   Haskell2010
+
diff --git a/src/Music/Prelude/Basic.hs b/src/Music/Prelude/Basic.hs
--- a/src/Music/Prelude/Basic.hs
+++ b/src/Music/Prelude/Basic.hs
@@ -47,8 +47,8 @@
 import qualified Music.Pitch
 import           Music.Score             hiding (Pitch)
 
+import           Control.Lens.Operators  hiding ((<.>), (<|), (|>))
 import           Control.Monad.Plus
-import           Control.Lens.Operators   hiding ((|>), (<|), (<.>))
 
 import           Music.Prelude.Instances ()
 
diff --git a/src/Music/Prelude/CmdLine.hs b/src/Music/Prelude/CmdLine.hs
new file mode 100644
--- /dev/null
+++ b/src/Music/Prelude/CmdLine.hs
@@ -0,0 +1,146 @@
+
+module Music.Prelude.CmdLine (
+        converterMain,
+        translateFileAndRunLilypond,
+        translateFile,
+        versionString
+) where
+
+import           Data.Version          (showVersion)
+import           Data.Monoid
+import           Options.Applicative
+-- import           Paths_music_preludes  (version)
+import           Data.Char
+import           Data.List          (intercalate)
+import           Data.List.Split
+import           Data.Map           (Map)
+import qualified Data.Map           as Map
+import           Data.Maybe
+import           Prelude            hiding (readFile, writeFile)
+-- import           System.Console.GetOpt
+import           System.Environment
+import           System.Exit
+import           System.FilePath
+import           System.IO
+import           System.IO.Temp
+import qualified System.Posix.Env   as PE
+import           System.Process
+
+-- TODO Can not link due to haskell/cabal#1759
+versionString :: String
+versionString = "1.6"
+-- versionString = showVersion version
+
+data Options = Options {
+    prelude :: Maybe String,
+    outFile :: Maybe FilePath,
+    inFile  :: FilePath
+  } deriving (Show)
+
+converterOptions :: Parser Options
+converterOptions = Options
+  <$> (optional $ strOption $ mconcat [long "prelude", metavar "<name>"])
+  <*> (optional $ strOption $ mconcat [short 'o', long "output", metavar "<file>"])
+  <*> (argument str $ metavar "<input>")
+
+runConverter :: String -> String -> Options -> IO ()
+runConverter func ext (Options prelude outFile inFile) =
+  translateFile func ext prelude (Just inFile) outFile
+
+converterMain :: String -> String -> String -> IO ()
+converterMain func ext pgmName = execParser opts >>= runConverter func ext
+  where 
+      opts = info 
+        (helper <*> converterOptions) 
+        (fullDesc <> header (pgmName ++ "-" ++ versionString))
+
+
+translateFileAndRunLilypond :: String -> Maybe String -> Maybe FilePath -> IO ()
+translateFileAndRunLilypond format preludeName' inFile' = do
+  let inFile      = fromMaybe "test.music" inFile'
+  let preludeName = fromMaybe "basic" preludeName'
+  let lyFile      = takeBaseName inFile ++ ".ly"
+
+  translateFile "writeLilypond" "ly" (Just preludeName) (Just inFile) (Just lyFile)
+  rawSystem "lilypond" ["--" ++ format, "-o", takeBaseName inFile, lyFile]
+  runCommand $ "rm -f " ++ takeBaseName inFile ++ "-*.tex " ++ takeBaseName inFile ++ "-*.texi " ++ takeBaseName inFile ++ "-*.count " ++ takeBaseName inFile ++ "-*.eps " ++ takeBaseName inFile ++ "-*.pdf " ++ takeBaseName inFile ++ ".eps"
+  return ()
+
+translateFile :: String -> String -> Maybe String -> Maybe FilePath -> Maybe FilePath -> IO ()
+translateFile translationFunction outSuffix preludeName' inFile' outFile' = do
+  let inFile      = fromMaybe "test.music" inFile'
+  let preludeName = fromMaybe "basic" preludeName'
+  let outFile     = fromMaybe (
+                    takeDirectory inFile ++ "/" 
+                    ++ takeBaseName inFile 
+                    ++ "." ++ outSuffix) 
+                    outFile'
+
+  let prelude   = "Music.Prelude." ++ toCamel preludeName
+  let scoreType = "Score " ++ toCamel preludeName ++ "Note"
+  let main      = translationFunction
+  score       <- readFile inFile
+  newScore    <- return $ expand templ (Map.fromList [
+    ("prelude"   , prelude),
+    ("main"      , main),
+    ("scoreType" , scoreType),
+    ("score"     , score),
+    ("outFile"   , outFile)
+    ])
+
+  withSystemTempDirectory "music-suite." $ \tmpDir -> do
+    let tmpFile = tmpDir ++ "/" ++ takeFileName inFile
+    putStrLn $ "Converting music..."
+    writeFile tmpFile newScore
+    withMusicSuiteInScope $ do
+      putStrLn $ "Writing '" ++ outFile ++ "'..."
+      rawSystem "runhaskell" [tmpFile]
+
+  return ()
+  where
+    templ = "module Main where { import $(prelude); main = $(main) \"$(outFile)\" ( $(score) :: $(scoreType) ) }"
+
+
+type Template = String
+
+-- |
+-- Simple templating system.
+--
+-- >>> expand "me : $(name)" (Map.fromList [("name","Hans")])
+-- "me : Hans"
+--
+expand :: Template -> Map String String -> String
+expand t vs = (composed $ fmap (expander vs) $ Map.keys $ vs) t
+  where
+    expander vs k = replace ("$(" ++ k ++ ")") (fromJust $ Map.lookup k vs)
+
+composed :: [a -> a] -> a -> a
+composed = foldr (.) id
+
+
+replace :: Eq a => [a] -> [a] -> [a] -> [a]
+replace old new = intercalate new . splitOn old
+
+toCamel [] = []
+toCamel (x:xs) = toUpper x : xs
+
+-- | Temporarily modfiy an environment variable (POSIX only).
+--
+-- @
+-- withEnv MYVAR (\oldValue -> newValue) $ do
+--    ...
+-- @
+--
+withEnv :: String -> (Maybe String -> String) -> IO a -> IO ()
+withEnv n f k = do
+  x <- PE.getEnv n
+  PE.setEnv n (f x) True
+  k
+  case x of
+    Nothing -> PE.unsetEnv n
+    Just x2 -> PE.setEnv n x2 True
+
+-- TODO if no music-util, use ""
+withMusicSuiteInScope k = do
+  packagePath <- readProcess "music-util" ["package-path"] ""
+  withEnv "GHC_PACKAGE_PATH" (const packagePath) k
diff --git a/src/Music/Prelude/Instances.hs b/src/Music/Prelude/Instances.hs
--- a/src/Music/Prelude/Instances.hs
+++ b/src/Music/Prelude/Instances.hs
@@ -1,13 +1,12 @@
 
-{-# LANGUAGE
-    GeneralizedNewtypeDeriving,
-    StandaloneDeriving,
-    MultiParamTypeClasses,
-    DeriveDataTypeable,
-    TypeFamilies, 
-    FlexibleInstances,
-    UndecidableInstances,
-    ViewPatterns #-} 
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE FlexibleInstances          #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE TypeFamilies               #-}
+{-# LANGUAGE UndecidableInstances       #-}
+{-# LANGUAGE ViewPatterns               #-}
 
 ------------------------------------------------------------------------------------
 -- |
@@ -25,28 +24,28 @@
 
 module Music.Prelude.Instances () where
 
-import Data.Default
-import Data.Typeable
-import Data.AffineSpace.Point
+import           Data.AffineSpace.Point
+import           Data.Default
+import           Data.Typeable
 
-import Music.Pitch
-import Music.Dynamics
-import Music.Parts
-import Music.Score hiding (Pitch, Interval, Fifths, Note)
+import           Music.Dynamics
+import           Music.Parts
+import           Music.Pitch
+import           Music.Score            hiding (Fifths, Interval, Note, Pitch)
 
-import qualified Music.Score as Score
-import qualified Music.Lilypond as Lilypond
-import qualified Music.MusicXml.Simple as Xml
+import qualified Music.Lilypond         as Lilypond
+import qualified Music.MusicXml.Simple  as Xml
+import qualified Music.Score            as Score
 
 deriving instance Typeable Music.Parts.Part
 
 type instance Music.Score.Part BasicPart = BasicPart
 instance HasPart BasicPart where
-        getPart = id
-        modifyPart = id
+    getPart = id
+    modifyPart = id
 
 -- FIXME
-instance Delayable Pitch      
+instance Delayable Pitch
 instance Stretchable Pitch
 type instance Score.Pitch Pitch = Pitch
 
@@ -60,109 +59,29 @@
     endTie = id
 
 instance HasMidi Semitones where
-    getMidi a = getMidi $ (60 + fromIntegral a :: Integer)
+    getMidi a = getMidi $ (fromIntegral a :: Integer)
 
 instance HasMidi Pitch where
     getMidi p = getMidi $ semitones (p .-. c)
 
 instance HasMusicXml Pitch where
-    getMusicXml      (realToFrac -> d) = (`Xml.note` d) . snd3 Just . spellPitch
-    getMusicXmlChord (realToFrac -> d) = (`Xml.chord` (realToFrac d)) . fmap (snd3 Just . spellPitch)
+    getMusicXml      (realToFrac -> d) = (`Xml.note` d) . snd3 Just . spellPitch 4
+    getMusicXmlChord (realToFrac -> d) = (`Xml.chord` (realToFrac d)) . fmap (snd3 Just . spellPitch 4)
 
 instance HasLilypond Pitch where
-    getLilypond      d = (^*realToFrac (d*4)) . Lilypond.note . pitchLilypond . Lilypond.Pitch . spellPitch . (.+^ perfect octave)
-    getLilypondChord d = (^*realToFrac (d*4)) . Lilypond.chord . fmap (pitchLilypond . Lilypond.Pitch . spellPitch . (.+^ perfect octave))
+    getLilypond      d = (^*realToFrac (d*4)) . Lilypond.note . pitchLilypond . Lilypond.Pitch . spellPitch 5
+    getLilypondChord d = (^*realToFrac (d*4)) . Lilypond.chord . fmap (pitchLilypond . Lilypond.Pitch . spellPitch 5)
 
 -- TODO move
 snd3 f (a, b, c) = (a, f b, c)
 pitchLilypond a = Lilypond.NotePitch a Nothing
 
-spellPitch :: (Enum p, Num a, Num o) => Pitch -> (p, a, o)
-spellPitch p = (pitchName, pitchAccidental, octave)
+spellPitch :: (Enum p, Num a, Num o) => Octaves -> Pitch -> (p, a, o)
+spellPitch referenceOctave p = (pitchName, pitchAccidental, octave)
     where
         pitchName       = toEnum $ fromEnum $ name p
         pitchAccidental = fromIntegral $ accidental p
-        octave          = fromIntegral $ (+ 4) $ octaves (p .-. c)
-
-instance Alterable a => Alterable (Score a) where
-    sharpen = fmap sharpen
-    flatten = fmap flatten
-
-instance Alterable a => Alterable (ChordT a) where
-    sharpen = fmap sharpen
-    flatten = fmap flatten
-
-instance Alterable a => Alterable (DynamicT a) where
-    sharpen = fmap sharpen
-    flatten = fmap flatten
-
-instance Alterable a => Alterable (SlideT a) where
-    sharpen = fmap sharpen
-    flatten = fmap flatten
-
-instance Alterable a => Alterable (TieT a) where
-    sharpen = fmap sharpen
-    flatten = fmap flatten
-
-instance Alterable a => Alterable (HarmonicT a) where
-    sharpen = fmap sharpen
-    flatten = fmap flatten
-
-instance Alterable a => Alterable (ArticulationT a) where
-    sharpen = fmap sharpen
-    flatten = fmap flatten
-
-instance Alterable a => Alterable (TextT a) where
-    sharpen = fmap sharpen
-    flatten = fmap flatten
-
-instance Alterable a => Alterable (TremoloT a) where
-    sharpen = fmap sharpen
-    flatten = fmap flatten
-
-instance Alterable a => Alterable (PartT n a) where
-    sharpen = fmap sharpen
-    flatten = fmap flatten
-
-instance Augmentable a => Augmentable (Score a) where
-    augment = fmap augment
-    diminish = fmap diminish
-
-instance Augmentable a => Augmentable (ChordT a) where
-    augment = fmap augment
-    diminish = fmap diminish
-
-instance Augmentable a => Augmentable (DynamicT a) where
-    augment = fmap augment
-    diminish = fmap diminish
-
-instance Augmentable a => Augmentable (SlideT a) where
-    augment = fmap augment
-    diminish = fmap diminish
-
-instance Augmentable a => Augmentable (TieT a) where
-    augment = fmap augment
-    diminish = fmap diminish
-
-instance Augmentable a => Augmentable (HarmonicT a) where
-    augment = fmap augment
-    diminish = fmap diminish
-
-instance Augmentable a => Augmentable (ArticulationT a) where
-    augment = fmap augment
-    diminish = fmap diminish
-
-instance Augmentable a => Augmentable (TextT a) where
-    augment = fmap augment
-    diminish = fmap diminish
-
-instance Augmentable a => Augmentable (TremoloT a) where
-    augment = fmap augment
-    diminish = fmap diminish
-
-instance Augmentable a => Augmentable (PartT n a) where
-    augment = fmap augment
-    diminish = fmap diminish
+        octave          = fromIntegral $ (+ referenceOctave) $ octaves (p .-. c)
 
 instance HasMidiProgram BasicPart where
     getMidiChannel _ = 0
diff --git a/src/Music/Prelude/Piano.hs b/src/Music/Prelude/Piano.hs
--- a/src/Music/Prelude/Piano.hs
+++ b/src/Music/Prelude/Piano.hs
@@ -1,7 +1,6 @@
 
-{-# LANGUAGE
-    GeneralizedNewtypeDeriving,
-    DeriveDataTypeable #-} 
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 
 ------------------------------------------------------------------------------------
 -- |
@@ -24,14 +23,14 @@
         asScore
   ) where
 
-import Music.Pitch
-import Music.Score hiding (Pitch, Interval, Note)
-import Music.Dynamics.Literal --TODO
-import Data.Typeable
-import Data.AffineSpace.Point
-import qualified Music.Score as Score
-import qualified Music.Lilypond as Lilypond
-import qualified Music.MusicXml.Simple as Xml
+import           Data.AffineSpace.Point
+import           Data.Typeable
+import           Music.Dynamics.Literal
+import qualified Music.Lilypond         as Lilypond
+import qualified Music.MusicXml.Simple  as Xml
+import           Music.Pitch
+import           Music.Score            hiding (Interval, Note, Pitch)
+import qualified Music.Score            as Score
 
 asScore :: Score Note -> Score Note
 asScore = id
diff --git a/src/Music/Prelude/Standard.hs b/src/Music/Prelude/Standard.hs
--- a/src/Music/Prelude/Standard.hs
+++ b/src/Music/Prelude/Standard.hs
@@ -1,8 +1,7 @@
 
-{-# LANGUAGE
-    GeneralizedNewtypeDeriving,
-    DeriveDataTypeable,
-    TypeFamilies #-}
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE TypeFamilies               #-}
 
 ------------------------------------------------------------------------------------
 -- |
@@ -33,15 +32,16 @@
         openAndPlay
   ) where
 
-import Data.Default
-import Data.Typeable
+import           Data.Default
+import           Data.Typeable
 
-import Music.Pitch
-import Music.Dynamics
-import Music.Parts
-import Music.Score hiding (Pitch, Interval, Fifths, Note, Part, pitch)
+import           Music.Dynamics
+import           Music.Parts
+import           Music.Pitch
+import           Music.Score             hiding (Fifths, Interval, Note, Part,
+                                          Pitch, pitch)
 
-import Music.Prelude.Instances ()
+import           Music.Prelude.Instances ()
 
 asNote :: Note -> Note
 asNote = id
@@ -57,7 +57,7 @@
 
 -- newtype BasicPart = BasicPart { getBasicPart :: Integer }
 --     deriving (Eq, Ord, Num, Integral, Real, Enum, Typeable)
--- 
+--
 -- instance Default BasicPart where def = BasicPart 0
 -- instance Show BasicPart where
 --     show _ = ""
diff --git a/src/Music/Prelude/StringQuartet.hs b/src/Music/Prelude/StringQuartet.hs
--- a/src/Music/Prelude/StringQuartet.hs
+++ b/src/Music/Prelude/StringQuartet.hs
@@ -1,7 +1,6 @@
 
-{-# LANGUAGE
-    GeneralizedNewtypeDeriving,
-    DeriveDataTypeable #-} 
+{-# LANGUAGE DeriveDataTypeable         #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 
 ------------------------------------------------------------------------------------
 -- |
@@ -23,14 +22,14 @@
         asScore
   ) where
 
-import Music.Pitch
-import Music.Score hiding (Pitch, Interval, Note)
-import Music.Dynamics.Literal --TODO
-import Data.Typeable
-import Data.AffineSpace.Point
-import qualified Music.Score as Score
-import qualified Music.Lilypond as Lilypond
-import qualified Music.MusicXml.Simple as Xml
+import           Data.AffineSpace.Point
+import           Data.Typeable
+import           Music.Dynamics.Literal
+import qualified Music.Lilypond         as Lilypond
+import qualified Music.MusicXml.Simple  as Xml
+import           Music.Pitch
+import           Music.Score            hiding (Interval, Note, Pitch)
+import qualified Music.Score            as Score
 
 asScore :: Score Note -> Score Note
 asScore = id
diff --git a/tests/tests.hs b/tests/tests.hs
new file mode 100644
--- /dev/null
+++ b/tests/tests.hs
@@ -0,0 +1,90 @@
+
+module Main where
+
+import Test.Tasty
+import Test.Tasty.Golden
+import System.Process
+
+main = defaultMain $ testGroup "All tests" [sanity, golden]
+
+testMusicFile name = testGroup name [
+  testMusicFileAs "mid" name,
+  testMusicFileAs "xml" name,
+  testMusicFileAs "ly"  name
+  ]
+
+converter ext = case ext of
+  "mid" -> "music2midi"
+  "xml" -> "music2musicxml"
+  "ly"  -> "music2ly"
+
+testMusicFileAs ext name =
+  goldenVsFile 
+    (name ++ "." ++ ext)
+    ("tests/golden/" ++ name ++ "." ++ ext)
+    ("tests/current/" ++ name ++ "." ++ ext)
+    ((system $ converter ext ++" -o tests/current/"++name++"."++ext++" tests/"++name++".music") 
+      >> return ())
+
+{-
+  This test will always fail if the test files have been edited.
+
+  If you have edited one or more test files and DEFINITELY intend to make 
+  your changes permanent, please assure that you are in a clean working
+  directory (except for your edits), and then run:
+
+      $ make generate
+  
+  You should commit all the resulting files along with your edits.
+-}
+sanity = testGroup "Sanity checks" [
+  testMusicFilesCheckSum,
+  testGenratedFilesChecksum
+  ]
+
+testMusicFilesCheckSum =
+  goldenVsFile
+      "Original file checksums"
+      "tests/originals_ref.sha"
+      "tests/originals_check.sha"
+      (system "shasum tests/*.music | shasum > tests/originals_check.sha" >> return ())
+
+testGenratedFilesChecksum =
+  goldenVsFile
+      "Generated file checksums"
+      "tests/generated_ref.sha"
+      "tests/generated_check.sha"
+      (system "shasum tests/golden/* | shasum > tests/generated_check.sha" >> return ())
+
+golden = testGroup "Regression tests" [
+  testMusicFile "articulation_all_accents",
+  testMusicFile "articulation_all_separations",
+  testMusicFile "articulation_legato",
+  testMusicFile "articulation_portato",
+  testMusicFile "articulation_staccato",
+  testMusicFile "dynamics_constant",
+  testMusicFile "melody_chords",
+  testMusicFile "meta_annotations",
+  testMusicFile "meta_clef1",
+  testMusicFile "meta_composer",
+  testMusicFile "meta_time_signature",
+  testMusicFile "misc_counterpoint",
+  testMusicFile "octaves",
+  testMusicFile "overlay_chords",
+  testMusicFile "overlay_voices",
+  testMusicFile "pitch_inv",
+  testMusicFile "sharpen",
+  testMusicFile "simple_figure",
+  testMusicFile "simple_start_later",
+  testMusicFile "single_note",
+  testMusicFile "special_gliss",
+  testMusicFile "special_harmonics",
+  testMusicFile "special_text",
+  testMusicFile "special_tremolo",
+  testMusicFile "stretch_single_note1",
+  testMusicFile "stretch_single_note2",
+  testMusicFile "stretch_single_note3",
+  testMusicFile "times",
+  testMusicFile "track_single",
+  testMusicFile "voice_single"
+  ]
diff --git a/tools/music2ly.hs b/tools/music2ly.hs
new file mode 100644
--- /dev/null
+++ b/tools/music2ly.hs
@@ -0,0 +1,8 @@
+
+module Main where
+
+import           Music.Prelude.CmdLine
+import           System.Environment
+
+main :: IO ()
+main = getProgName >>= converterMain "writeLilypond" "ly"
diff --git a/tools/music2midi.hs b/tools/music2midi.hs
new file mode 100644
--- /dev/null
+++ b/tools/music2midi.hs
@@ -0,0 +1,8 @@
+
+module Main where
+
+import           Music.Prelude.CmdLine
+import           System.Environment
+
+main :: IO ()
+main = getProgName >>= converterMain "writeMidi" "mid"
diff --git a/tools/music2musicxml.hs b/tools/music2musicxml.hs
new file mode 100644
--- /dev/null
+++ b/tools/music2musicxml.hs
@@ -0,0 +1,8 @@
+
+module Main where
+
+import           Music.Prelude.CmdLine
+import           System.Environment
+
+main :: IO ()
+main = getProgName >>= converterMain "writeMusicXml" "xml"
diff --git a/tools/music2pdf.hs b/tools/music2pdf.hs
new file mode 100644
--- /dev/null
+++ b/tools/music2pdf.hs
@@ -0,0 +1,14 @@
+
+module Main where
+
+import           Music.Prelude.CmdLine
+import           System.Environment
+
+-- TODO
+main = do
+  args <- getArgs
+  main2 args
+
+main2 args = do
+  [inFile] <- return args
+  translateFileAndRunLilypond "pdf" (Just "basic") (Just inFile)
diff --git a/tools/music2png.hs b/tools/music2png.hs
new file mode 100644
--- /dev/null
+++ b/tools/music2png.hs
@@ -0,0 +1,14 @@
+
+module Main where
+
+import           Music.Prelude.CmdLine
+import           System.Environment
+
+-- TODO
+main = do
+  args <- getArgs
+  main2 args
+
+main2 args = do
+  [inFile] <- return args
+  translateFileAndRunLilypond "png" (Just "basic") (Just inFile)
diff --git a/tools/music2svg.hs b/tools/music2svg.hs
new file mode 100644
--- /dev/null
+++ b/tools/music2svg.hs
@@ -0,0 +1,14 @@
+
+module Main where
+
+import           Music.Prelude.CmdLine
+import           System.Environment
+
+-- TODO
+main = do
+  args <- getArgs
+  main2 args
+
+main2 args = do
+  [inFile] <- return args
+  translateFileAndRunLilypond "svg" (Just "basic") (Just inFile)
