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 qualified Haskore.Performance.Context as Context import qualified Haskore.Interface.MML as MML import qualified Media.ContextFreeGrammar as Grammar import qualified Haskore.General.MarkovChain as MarkovChain import qualified Haskore.Interface.MIDI.File as MidiFile import qualified Haskore.Interface.MIDI.InstrumentMap as InstrumentMap import qualified Haskore.Interface.MIDI.Write as WriteMidi import qualified Haskore.Interface.MIDI.Save as SaveMidi import qualified Haskore.Interface.MIDI.General as GeneralMidi import Data.Ratio((%)) import qualified Data.List as List import Control.Monad.State 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.fromMedia (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.walk 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 Float MidiMusic.Note context = Context.setDur (Tempo.metro 105 Music.qn) $ Context.deflt toMidi :: Melody.T () -> MidiFile.T toMidi m = WriteMidi.fromGMMusic (cm, context, MidiMusic.fromMelodyIgnoreAttr MidiMusic.ChurchOrgan m) midi :: MidiFile.T midi = toMidi song main :: IO () main = SaveMidi.toFile "test.mid" midi