module Haskore.Example.Kantate147 where {- Kantate 147 by Johann Sebastian Bach -} import qualified Haskore.Basic.Pitch as Pitch import qualified Haskore.Basic.Tempo as Tempo import qualified Haskore.Music as Music import Haskore.Music (line, chord, (=:=)) import qualified Haskore.Melody as Melody import qualified Haskore.Music.GeneralMIDI as MidiMusic import Haskore.Basic.Duration (qn, (%+), ) import qualified Haskore.Performance.Context as Context import qualified Haskore.Performance.Default as DefltPf import qualified Numeric.NonNegative.Wrapper as NonNeg import qualified Haskore.Interface.MML as MML -- import qualified Medium.Controlled.List as CtrlMedium import qualified Medium.Controlled.ContextFreeGrammar as Grammar import qualified Data.MarkovChain as MarkovChain import qualified Haskore.Interface.MIDI.Write as WriteMidi import qualified Haskore.Interface.MIDI.InstrumentMap as InstrumentMap import qualified Sound.MIDI.File.Save as SaveMidi import qualified Sound.MIDI.File as MidiFile import qualified Data.List as List import Control.Monad.Trans.State (state, evalState, ) import System.Random (mkStdGen, split, ) initOctaves :: [Pitch.Octave] initOctaves = [1, 0, 2, 2] songMML :: [(String, String, String, String)] songMML = [ ("l2g>ge", "l2p2de", "l2p2l6g3f#g3a", "l6p6gab>dcced"), ("ec", "a>dc", "e3f#g3de3cdedcf#", "a3>da3ga3f#", "f#gadf#a>ce", "d3f#g3f#g3a", "bgab>dcced"), ("ed", "geced", "a3f#g3ec", "e>dcg6d3gb3>dg3d", "gb>dgdd"), ("g>f#e", "dc"), ("f#ed", "agf#", "a1b", "d1d"), ("ef#g", "gag", "bag", "c1d3d6", "al6d3ef#3g", "l6adef#aga>cp3d6d3d6", "f#3a6f#3d6d6", "a3>cccdcced"), ("be", "gdcdcdcge", "b>de", "dg3f#g3a", "gbab>dcced"), ("ec", "a>dc", "e3f#g3de3cdedcf#", "a3>f#a3ga3f#", "f#gadf#a>ce", "d3f#g3f#g3a", "bgab>dcced"), ("ed", "geced", "a3f#g3ec", "e>dcf#e", "dc", "l2g1g"), ("f#ed", "agf#", "d1d", "a1b"), ("ef#g", "gag", "c1d3d", "al6d3ef#3g", "l6ddef#aga>cd6d3d6", "f#3af#3dd", "a3>cccc", "bgab>dcced"), ("be", "gdcdcc8dcge", "l2b>de", "l6g3dg3f#g3a", "gbab>dcced"), ("ec", "a>dc", "e3f#g3de3cdedcf#", "a3>da3ga3f#", "f#gadf#a>ce", "d3f#g3f#g3a", "bgab>dcced"), ("ed", "geced", "a3f#g3ec", "e>dcg6f#3e6", "dp3g6d3e6", "gb3>dg3dgdc#"), ("dca4g4f4e4", "ea", ">c1c", "a>cce", "aag#", "c8d8dcdfd", "ef#", "al6a3g#a3b", "a>cceddfe"), ("cfe", "afc", ">c3c3c"), ("dd#e", "df#e", "a3g#a3f#d", "fedcab", "cl2c1d", "a>ceap3l2d"), (">ccag", "e1e", "l6ecdegfgb-a"), ("fdg", "df#g", "dd4e8f8d", "a>ccc3d", "a>ccd6", "gp3d6d3d6", "c3c3d3ge", "dde", "l2b1>c", "bgab>dcced"), ("ec", "a>dc", "ccdedcd3d", "l6a3c#d3ef#3g", "f#def#aga>cd6d3d6", "f#3af#3dd", "a3>cccc", "bgab>dcced"), ("be", "gdcdcc8dcg6d3g6", "gl6dg3d", "gb>dgda"), ("g1g2", "dp3g6e3c6", "d3b>c2", "fddedd6e6", "c3cda6f#3d6", "a2a3f#d3f#", ">ccge", "dde", "g3dg3f#g3a", "bgab>dcced"), ("ec", "a>dcdedcf#", "a3>da3ga3f#", "f#gadf#a>ce", "d3f#g3f#g3a", "bgab>dcced"), ("ed", "gec", "e>dc Music.Atom (dr * (3%+4)) at) songTrackwise in Grammar.fromMedium (map (("part"++) . show) [(0 :: Int) ..]) 4 songConvDurs {- Try to create new music by reordering the notes using Markov chains. -} markovChain :: Melody.T () markovChain = let tracks = map concat musicTracks gs = evalState (sequence (repeat (state split))) (mkStdGen 147) chains = zipWith (\track g -> line (MarkovChain.run 3 track 0 g)) tracks gs in chains !! 2 =:= chains !! 3 markovChainMidi :: MidiFile.T markovChainMidi = toMidi (Music.take 100 markovChain) ----- Player details cm :: InstrumentMap.ChannelTable MidiMusic.Instrument cm = [(MidiMusic.ChurchOrgan, MidiMusic.toChannel 1), (MidiMusic.Viola, MidiMusic.toChannel 2)] context :: Context.T NonNeg.Float Float MidiMusic.Note context = Context.setDur (Tempo.metro 105 qn) $ DefltPf.context toMidi :: Melody.T () -> MidiFile.T toMidi m = WriteMidi.fromGMMusic (cm, context, MidiMusic.fromMelodyNullAttr MidiMusic.ChurchOrgan m) midi :: MidiFile.T midi = toMidi song main :: IO () main = SaveMidi.toFile "test.mid" midi