content: > module HSoM.Examples.RandomMusic where
  > import Euterpea
  > import System.Random
  > import System.Random.Distributions
  > import qualified Data.MarkovChain as M
  
  
  > sGen :: StdGen
  > sGen = mkStdGen 42
  
  > randInts :: StdGen -> [Int]
  > randInts g =  let (x,g') = next g
  >               in x : randInts g'
  
  > randFloats :: [Float]
  > randFloats = randomRs (-1,1) sGen
  
  > randIntegers :: [Integer]
  > randIntegers = randomRs (0,100) sGen
  
  > randString :: String
  > randString = randomRs ('a','z') sGen
  
  > randIO :: IO Float
  > randIO = randomRIO (0,1)
  
  > randIO' :: IO ()
  > randIO' = do  r1 <- randomRIO (0,1) :: IO Float
  >               r2 <- randomRIO (0,1) :: IO Float
  >               print (r1 == r2)
  
  > toAbsP1    :: Float -> AbsPitch
  > toAbsP1 x  = round (40*x + 30)
  
  > mkNote1  :: AbsPitch -> Music Pitch
  > mkNote1  = note tn . pitch
  
  > mkLine1        :: [AbsPitch] -> Music Pitch
  > mkLine1 rands  = line (take 32 (map mkNote1 rands))
  
  uniform distribution
  
  > m1 :: Music Pitch
  > m1 = mkLine1 (randomRs (30,70) sGen)
  
  linear distribution
  
  > m2 :: Music Pitch
  > m2 =  let rs1 = rands linear sGen
  >       in mkLine1 (map toAbsP1 rs1)
  
  exponential distribution
  
  > m3      :: Float -> Music Pitch
  > m3 lam  =  let rs1 = rands (exponential lam) sGen
  >            in mkLine1 (map toAbsP1 rs1)
  
  Gaussian distribution
  
  > m4 :: Float -> Float -> Music Pitch
  > m4 sig mu   =  let rs1 = rands (gaussian sig mu) sGen
  >                in mkLine1 (map toAbsP1 rs1)
  
  
  Gaussian distribution with mean set to 0
  
  > m5      :: Float -> Music Pitch
  > m5 sig  =  let rs1 = rands (gaussian sig 0) sGen
  >            in mkLine2 50 (map toAbsP2 rs1)
  
  exponential distribution with mean adjusted to 0
  
  > m6      :: Float -> Music Pitch
  > m6 lam  =  let rs1 = rands (exponential lam) sGen
  >            in mkLine2 50 (map (toAbsP2 . subtract (1/lam)) rs1)
  
  > toAbsP2     :: Float -> AbsPitch
  > toAbsP2 x   = round (5*x)
  
  > mkLine2 :: AbsPitch -> [AbsPitch] -> Music Pitch
  > mkLine2 start rands = 
  >    line (take 64 (map mkNote1 (scanl (+) start rands)))
  
  > m2' = let rs1 = rands linear sGen
  >       in sum (take 1000 rs1) / 1000 :: Float
  
  > m5' sig = let rs1 = rands (gaussian sig 0) sGen
  >           in sum (take 1000 rs1)
  
  > m6' lam = let rs1 = rands (exponential lam) sGen
  >               rs2 = map (subtract (1/lam)) rs1
  >           in sum (take 1000 rs2)
  
  some sample training sequences
  
  > ps0,ps1,ps2 :: [Pitch]
  > ps0  = [(C,4), (D,4), (E,4)]
  > ps1  = [(C,4), (D,4), (E,4), (F,4), (G,4), (A,4), (B,4)]
  > ps2  = [  (C,4), (E,4), (G,4), (E,4), (F,4), (A,4), (G,4), (E,4),
  >           (C,4), (E,4), (G,4), (E,4), (F,4), (D,4), (C,4)]
  
  functions to package up run and runMulti
  
  > mc    ps   n = mkLine3 (M.run n ps 0 (mkStdGen 42))
  > mcm   pss  n = mkLine3 (concat (M.runMulti  n pss 0 
  >                                             (mkStdGen 42)))
  
  music-making functions
  
  > mkNote3     :: Pitch -> Music Pitch
  > mkNote3     = note tn
  
  > mkLine3     :: [Pitch] -> Music Pitch
  > mkLine3 ps  = line (take 64 (map mkNote3 ps))
  
  testing the Markov output directly
  
  > lc  ps n    = take 1000 (M.run n ps 0 (mkStdGen 42))
  > lcl pss n m = take 1000 (M.runMulti n pss 0 (mkStdGen 42) !! m)
  