AlgoRhythm-0.1.0.0: app/Main.hs
{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE PostfixOperators #-}
module Main where
import Dynamics
import Export
import Grammar
import Music
import qualified Generate as Gen
import Control.Monad
main :: IO ()
main = do
let ?harmonyConfig = HarmonyConfig
{ basePc = C
, baseOct = Oct4
, baseScale = japanese
, chords = equally allChords
}
let ?midiConfig = defaultMIDIConfig
let t = 4 * wn
harmonicStructure <- runGrammar uuHarmony t ?harmonyConfig
background <- voiceLead harmonicStructure
let melodyConfig = Gen.GenConfig
{ Gen.key = C
, Gen.baseScale = japanese
, Gen.chords = harmonicStructure
, Gen.phraseDistribution = [(1, Gen.High), (1, Gen.Medium), (2, Gen.Low)]
, Gen.octaveDistribution = [(1, 3), (3, 4), (2, 5)]
}
foreground <- Gen.runGenerator () (Gen.diatonicMelody melodyConfig)
playDev 4 $ 2 ## dyn (toMusicCore background :=: toMusicCore foreground)
-- | Chaos blues. Generates a short music composition using the Chaos function
-- represented in Figure 1 of Chaos Melody Theory by Elaine Walker
-- (http://www.ziaspace.com/elaine/chaos/ChaosMelodyTheory.pdf)
chaosBlues :: Bool -> IO ()
chaosBlues addDyn = do
m <- Gen.genChaosMusic
let m' = if addDyn then dyn m else toMusicCore m
let ?midiConfig = defaultMIDIConfig
writeToMidiFile "out.midi" m'
playDev 0 m'
simpleMelody :: IO ()
simpleMelody = do
m <- Gen.runGenerator () $ replicateM 4 Gen.melodyInC
let ?midiConfig = MIDIConfig (4%4) [AcousticGrandPiano]
writeToMidiFile "simpleMelody.midi" (line m)
randomMelody :: IO ()
randomMelody = do
m <- Gen.runGenerator () Gen.randomMelody
let ?midiConfig = MIDIConfig (4%4) [AcousticGrandPiano]
writeToMidiFile "random.midi" m
-- Jazz example using the primitive generation DSL.
jazz :: IO ()
jazz = do
let ?midiConfig = MIDIConfig (4%4) [AltoSax, AcousticGrandPiano]
let t = 12 * wn
-- Harmony.
let ?harmonyConfig = HarmonyConfig
{ basePc = D
, baseOct = Oct4
, baseScale = dorian
, chords = equally [maj, mi, maj7, m7, dim, d7, m7b5]
}
harmonicStructure <- runGrammar uuHarmony t ?harmonyConfig
background <- voiceLead harmonicStructure
let melodyConfig = Gen.GenConfig
{ Gen.key = D
, Gen.baseScale = dorian
, Gen.chords = harmonicStructure
, Gen.phraseDistribution = [(4, Gen.High), (7, Gen.Medium), (2, Gen.Low)]
, Gen.octaveDistribution = [(2, 3), (7, 4), (4, 5)]
}
foreground <- Gen.runGenerator () (Gen.diatonicMelody melodyConfig)
writeToMidiFile "jazz1.midi" (foreground :=: toMusicCore background)
-- A piece with fast banjo playing.
fastBanjo :: IO ()
fastBanjo = do
let ?midiConfig = MIDIConfig (6%4) [Banjo, ElectricGuitarMuted]
let t = 32 * wn
-- Harmony.
let ?harmonyConfig = HarmonyConfig
{ basePc = C
, baseOct = Oct4
, baseScale = ionian
, chords = equally [maj, mi, dim]
}
harmonicStructure <- runGrammar uuHarmony t ?harmonyConfig
background <- voiceLead harmonicStructure
let melodyConfig = Gen.GenConfig
{ Gen.key = C
, Gen.baseScale = ionian
, Gen.chords = harmonicStructure
, Gen.phraseDistribution = [(1, Gen.High), (0, Gen.Medium), (0, Gen.Low)]
, Gen.octaveDistribution = [(3, 3), (5, 4), (2, 5)]
}
foreground <- Gen.runGenerator () (Gen.diatonicMelody melodyConfig)
writeToMidiFile "out.midi" (((Rest $ 4 * wn) :+: foreground) :=: toMusicCore background)
rockOrganBlues :: IO ()
rockOrganBlues = do
let ?midiConfig = MIDIConfig (6%4) [RockOrgan, AcousticGrandPiano]
let ?harmonyConfig = HarmonyConfig
{ basePc = C
, baseOct = Oct4
, baseScale = ionian
, chords = equally [maj, mi, dim]
}
let harmonicStructure = foldr1 (:+:) $
map (Note hn . (=| d7))
[E, E, E, E, E, E, E, E, A, A, A, A, E, E, E, E, B, B, A, A, E, E, B, B]
let background = flip (<#) 3 <$> harmonicStructure
let melodyConfig = Gen.GenConfig
{ Gen.key = E
, Gen.baseScale = blues
, Gen.chords = 2##harmonicStructure
, Gen.phraseDistribution = [(5, Gen.High), (5, Gen.Medium), (1, Gen.Low)]
, Gen.octaveDistribution = [(3, 3), (5, 4), (2, 5)]
}
foreground <- Gen.runGenerator () (Gen.diatonicMelody melodyConfig)
foreground' <- Gen.runGenerator () (Gen.diatonicMelody melodyConfig)
writeToMidiFile "out.midi" ((foreground :+: foreground') :=: toMusicCore (4##background))
-- Hypnotic passage.
hypnotic :: Melody
hypnotic = 2%5 *~ cascades :+: (cascades ><)
where
cascades = rep id (%> sn) 2 cascade
cascade = rep (~> M3) (%> en) 5 run
run = rep (~> P4) (%> tn) 5 (D#3 <| tn)
rep :: (Melody -> Melody) -> (Melody -> Melody) -> Int -> Melody -> Melody
rep _ _ 0 _ = (0~~)
rep f g n m = m :=: g (rep f g (n - 1) (f m))
writeHypnotic :: IO ()
writeHypnotic = writeToMidiFile "hypnotic.mid" hypnotic
where ?midiConfig = MIDIConfig 1 [RhodesPiano]
-- Byzantine dance for Harpsichord.
byzantineDance :: IO ()
byzantineDance = do
let ?harmonyConfig = HarmonyConfig
{ basePc = Fs
, baseOct = Oct4
, baseScale = byzantine
, chords = equally allChords
}
let ?melodyConfig = defMelodyConfig
{ scales = equally allScales
, octaves = [(1, Oct3), (20, Oct4), (15, Oct5), (1, Oct6)]
}
let ?midiConfig = MIDIConfig (7%4) [Harpsichord]
(back, fore) <- integrate (8 * wn)
writeToMidiFile "byzantine-h.mid" back
writeToMidiFile "byzantine-m.mid" fore
playDev 4 $ back :=: fore
-- Sonata in E Minor.
sonata :: IO ()
sonata = do
let ?harmonyConfig = HarmonyConfig
{ basePc = E
, baseOct = Oct4
, baseScale = minor
, chords = equally [mi, maj, dim]
}
let ?melodyConfig = defMelodyConfig
{ scales = equally [ionian, harmonicMinor]
, octaves = [(5, Oct4), (20, Oct5), (10, Oct6)]
}
let ?midiConfig = MIDIConfig (7%10) [AcousticGrandPiano, Flute]
(back, fore) <- integrate (12 * wn)
writeToMidiFile "sonata-h.mid" back
writeToMidiFile "sonata-m.mid" fore
playDev 4 $ back :=: fore
-- Romanian Elegy for Piano & Cello.
romanianElegy :: IO ()
romanianElegy = do
let ?harmonyConfig = HarmonyConfig
{ basePc = C
, baseOct = Oct4
, baseScale = romanian
, chords = equally [mi, maj, aug, dim, m7, m7b5]
}
let ?melodyConfig = defMelodyConfig
{ scales = equally allScales
, octaves = [(20, Oct3), (15, Oct4), (10, Oct5)]
}
let ?midiConfig = MIDIConfig 1 [Harpsichord]
(back, fore) <- integrate (12 * wn)
writeToMidiFile "romanian-h.mid" back
writeToMidiFile "romanian-m.mid" fore
playDev 4 $ back :=: fore
-- Oriental Algebras for Metalophone, Sitar & Tablas.
orientalAlgebras :: IO ()
orientalAlgebras = do
let ?harmonyConfig = HarmonyConfig
{ basePc = A
, baseOct = Oct3
, baseScale = arabian
, chords = equally allChords
}
let ?melodyConfig = defMelodyConfig
{ scales = equally allScales
, octaves = [(20, Oct4), (15, Oct5), (5, Oct6)]
, colorWeight = 0
, approachWeight = 10
}
let ?midiConfig = MIDIConfig (6%5) [Harpsichord , Sitar]
(back, fore) <- integrate (12 * wn)
let ?tablaBeat = en
rhythm <- dyn <$> runGrammar tabla (12 * wn) ()
writeToMidiFile "oriental-h.mid" back
writeToMidiFile "oriental-m.mid" fore
writeToMidiFile "oriental-r.mid" rhythm
playDev 4 $ back :=: fore