module GrayCode where
import Midi ;
import Pitch ;
import Tuple ;
import List () ;
import Bool (ifThenElse) ;
import ListLive ;
import Prelude hiding (fst, snd) ;
main :: [ Event (Channel Message) ] ;
main =
channel 0 $ changeTempo timeUnit $ cycle overlapping ;
shortChords, overlapping :: [ Event Message ] ;
shortChords =
concatMap chordFromCode $ grayCodes 4 ;
chordFromCode :: [ Bool ] -> [ Event Message ] ;
chordFromCode bits =
(filterWith bits $ map noteOn pitches)
++
Wait qn
:
(filterWith bits $ map noteOff pitches) ;
filterWith :: [ Bool ] -> [ a ] -> [ a ] ;
filterWith bits =
map snd . filter fst . zipWith Pair bits ;
overlapping =
concatMap (cons (Wait qn) . flip cons []) $
grayChanges makeNoteOnOff 4 ;
makeNoteOnOff :: Bool -> Integer -> Event Message ;
makeNoteOnOff bl n =
ifThenElse bl noteOn noteOff $ makePitch n ;
pitches :: [ Pitch ] ;
pitches = map makePitch $ enumFrom 0 ;
makePitch :: Integer -> Pitch ;
makePitch 0 = c 4 ;
makePitch 1 = e 4 ;
makePitch 2 = g 4 ;
makePitch _ = c 5 ;
grayCodes :: Integer -> [[Bool]] ;
grayCodes 0 = [[]] ;
grayCodes n =
map (cons False) (grayCodes (n1)) ++
map (cons True) (reverse $ grayCodes (n1)) ;
grayChanges :: (Bool -> Integer -> a) -> Integer -> [a] ;
grayChanges mk n =
grayChangesRec mk True n ++ [mk False n] ;
grayChangesRec :: (Bool -> Integer -> a) -> Bool -> Integer -> [a] ;
grayChangesRec _mk _bl 0 = [] ;
grayChangesRec mk bl n =
grayChangesRec mk True (n1) ++
mk bl (n1) :
grayChangesRec mk False (n1) ;
timeUnit :: Time ;
timeUnit = 150 ;
qn :: Integer ;
qn = 1 ;