module Music where

import Midi ( Event(Wait, Event, Say), Message, Channel(Channel),
              note, transposeEvent, mergeMany )
import ListLive ( afterEach )
import List ( map, replicate, repeat, concat )
import Prelude ( (*), div, (.), ($), negate, Int, Integer, Integral, String )


c, cf, cs, df, d, ds, ef, e, es, ff, f, fs,
  gf, g, gs, af, a, as, bf, b, bs ::
    Music (Event Message) ;

quarter :: Integer ;
quarter :: Integer
quarter = Integer
240 ;

p :: Music (Event a) ;
p :: forall a. Music (Event a)
p = Event a -> Music (Event a)
forall a. a -> Music a
Atom ( Integer -> Event a
forall a. Integer -> Event a
Wait Integer
quarter ) ;

c :: Music (Event Message)
c = [Music (Event Message)] -> Music (Event Message)
forall a. [Music a] -> Music a
Seq ([Music (Event Message)] -> Music (Event Message))
-> [Music (Event Message)] -> Music (Event Message)
forall a b. (a -> b) -> a -> b
$ (Event Message -> Music (Event Message))
-> [Event Message] -> [Music (Event Message)]
forall a b. (a -> b) -> [a] -> [b]
map Event Message -> Music (Event Message)
forall a. a -> Music a
Atom ([Event Message] -> [Music (Event Message)])
-> [Event Message] -> [Music (Event Message)]
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> [Event Message]
note Integer
quarter Integer
36 ;
cf :: Music (Event Message)
cf = Integer -> Music (Event Message) -> Music (Event Message)
down Integer
1 Music (Event Message)
c ; cs :: Music (Event Message)
cs = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
1 Music (Event Message)
c ;
df :: Music (Event Message)
df = Music (Event Message)
cs ; d :: Music (Event Message)
d = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
2 Music (Event Message)
c ; ds :: Music (Event Message)
ds = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
3 Music (Event Message)
c ;
ef :: Music (Event Message)
ef = Music (Event Message)
ds ; e :: Music (Event Message)
e = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
4 Music (Event Message)
c ; es :: Music (Event Message)
es = Music (Event Message)
f ;
ff :: Music (Event Message)
ff = Music (Event Message)
e ; f :: Music (Event Message)
f = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
5 Music (Event Message)
c ; fs :: Music (Event Message)
fs = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
6 Music (Event Message)
c ;
gf :: Music (Event Message)
gf = Music (Event Message)
fs ; g :: Music (Event Message)
g = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
7 Music (Event Message)
c ; gs :: Music (Event Message)
gs = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
8 Music (Event Message)
c ;
af :: Music (Event Message)
af = Music (Event Message)
gs ; a :: Music (Event Message)
a = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
9 Music (Event Message)
c ; as :: Music (Event Message)
as = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
10 Music (Event Message)
c ;
bf :: Music (Event Message)
bf = Music (Event Message)
as ; b :: Music (Event Message)
b = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
11 Music (Event Message)
c ; bs :: Music (Event Message)
bs = Integer -> Music (Event Message) -> Music (Event Message)
up Integer
12 Music (Event Message)
c ;

slow, speed :: Integer -> Music (Event a) -> Music (Event a) ;

slowdown, speedup :: (Integral a) => a -> a -> a ;

slow :: forall a. Integer -> Music (Event a) -> Music (Event a)
slow Integer
k = (Integer -> Integer) -> Music (Event a) -> Music (Event a)
forall a.
(Integer -> Integer) -> Music (Event a) -> Music (Event a)
wmap ( Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
slowdown Integer
k ) ; slowdown :: forall a. Integral a => a -> a -> a
slowdown a
k a
w = a
w a -> a -> a
forall a. Num a => a -> a -> a
* a
k ;
speed :: forall a. Integer -> Music (Event a) -> Music (Event a)
speed Integer
k = (Integer -> Integer) -> Music (Event a) -> Music (Event a)
forall a.
(Integer -> Integer) -> Music (Event a) -> Music (Event a)
wmap ( Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
speedup Integer
k ) ; speedup :: forall a. Integral a => a -> a -> a
speedup a
k a
w = a -> a -> a
forall a. Integral a => a -> a -> a
div a
w a
k ;

up, down ::
  Integer ->
  Music (Event Message) ->
  Music (Event Message) ;
up :: Integer -> Music (Event Message) -> Music (Event Message)
up Integer
dif Music (Event Message)
s = Integer -> Music (Event Message) -> Music (Event Message)
tr Integer
dif Music (Event Message)
s ; down :: Integer -> Music (Event Message) -> Music (Event Message)
down Integer
dif Music (Event Message)
s = Integer -> Music (Event Message) -> Music (Event Message)
tr ( Integer -> Integer
forall a. Num a => a -> a
negate Integer
dif ) Music (Event Message)
s ;

chan ::
  Integer ->
  Music (Event a) ->
  Music (Event (Midi.Channel a)) ;
chan :: forall a. Integer -> Music (Event a) -> Music (Event (Channel a))
chan Integer
cn = (a -> Channel a) -> Music (Event a) -> Music (Event (Channel a))
forall a b. (a -> b) -> Music (Event a) -> Music (Event b)
emap ( Integer -> a -> Channel a
forall a. Integer -> a -> Channel a
Channel Integer
cn ) ;

tr ::
  Integer ->
  Music (Event Message) ->
  Music (Event Message) ;
tr :: Integer -> Music (Event Message) -> Music (Event Message)
tr Integer
dif = (Event Message -> Event Message)
-> Music (Event Message) -> Music (Event Message)
forall a b. (a -> b) -> Music a -> Music b
amap ( Integer -> Event Message -> Event Message
transposeEvent Integer
dif ) ;

says :: [String] -> Music (Event a) ;
says :: forall a. [String] -> Music (Event a)
says [String]
ws = [Music (Event a)] -> Music (Event a)
forall a. [Music a] -> Music a
Seq ( Music (Event a) -> [Music (Event a)] -> [Music (Event a)]
forall a. a -> [a] -> [a]
afterEach Music (Event a)
forall a. Music (Event a)
p ( (String -> Music (Event a)) -> [String] -> [Music (Event a)]
forall a b. (a -> b) -> [a] -> [b]
map (Event a -> Music (Event a)
forall a. a -> Music a
Atom (Event a -> Music (Event a))
-> (String -> Event a) -> String -> Music (Event a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Event a
forall a. String -> Event a
Say) [String]
ws ) ) ;

major, minor, minor7 ::
  Music (Event Message) -> Music (Event Message) ;
major :: Music (Event Message) -> Music (Event Message)
major Music (Event Message)
s = [Music (Event Message)] -> Music (Event Message)
forall a. [Music a] -> Music a
Par [ Music (Event Message)
s, Integer -> Music (Event Message) -> Music (Event Message)
up Integer
4 Music (Event Message)
s, Integer -> Music (Event Message) -> Music (Event Message)
up Integer
7 Music (Event Message)
s ] ;
minor :: Music (Event Message) -> Music (Event Message)
minor Music (Event Message)
s = [Music (Event Message)] -> Music (Event Message)
forall a. [Music a] -> Music a
Par [ Music (Event Message)
s, Integer -> Music (Event Message) -> Music (Event Message)
up Integer
3 Music (Event Message)
s, Integer -> Music (Event Message) -> Music (Event Message)
up Integer
7 Music (Event Message)
s ] ;
minor7 :: Music (Event Message) -> Music (Event Message)
minor7 Music (Event Message)
s = [Music (Event Message)] -> Music (Event Message)
forall a. [Music a] -> Music a
Par [ Music (Event Message)
s, Integer -> Music (Event Message) -> Music (Event Message)
up Integer
3 Music (Event Message)
s, Integer -> Music (Event Message) -> Music (Event Message)
up Integer
7 Music (Event Message)
s, Integer -> Music (Event Message) -> Music (Event Message)
up Integer
11 Music (Event Message)
s ] ;

times :: Int -> Music a -> Music a ;
times :: forall a. Int -> Music a -> Music a
times Int
k Music a
s = [Music a] -> Music a
forall a. [Music a] -> Music a
Seq ( Int -> Music a -> [Music a]
forall a. Int -> a -> [a]
replicate Int
k Music a
s ) ;

emap :: (a -> b) -> Music (Event a) -> Music (Event b) ;
emap :: forall a b. (a -> b) -> Music (Event a) -> Music (Event b)
emap a -> b
fn ( Atom ( Event a
ev ) ) = Event b -> Music (Event b)
forall a. a -> Music a
Atom ( b -> Event b
forall a. a -> Event a
Event ( a -> b
fn a
ev ) ) ;
emap a -> b
_  ( Atom ( Wait Integer
w ) ) = Event b -> Music (Event b)
forall a. a -> Music a
Atom ( Integer -> Event b
forall a. Integer -> Event a
Wait Integer
w ) ;
emap a -> b
_  ( Atom ( Say String
s ) ) = Event b -> Music (Event b)
forall a. a -> Music a
Atom ( String -> Event b
forall a. String -> Event a
Say String
s ) ;
emap a -> b
fn ( Par [Music (Event a)]
xs ) = [Music (Event b)] -> Music (Event b)
forall a. [Music a] -> Music a
Par ( (Music (Event a) -> Music (Event b))
-> [Music (Event a)] -> [Music (Event b)]
forall a b. (a -> b) -> [a] -> [b]
map ( (a -> b) -> Music (Event a) -> Music (Event b)
forall a b. (a -> b) -> Music (Event a) -> Music (Event b)
emap a -> b
fn ) [Music (Event a)]
xs );
emap a -> b
fn ( Seq [Music (Event a)]
xs ) = [Music (Event b)] -> Music (Event b)
forall a. [Music a] -> Music a
Seq ( (Music (Event a) -> Music (Event b))
-> [Music (Event a)] -> [Music (Event b)]
forall a b. (a -> b) -> [a] -> [b]
map ( (a -> b) -> Music (Event a) -> Music (Event b)
forall a b. (a -> b) -> Music (Event a) -> Music (Event b)
emap a -> b
fn ) [Music (Event a)]
xs );

wmap ::
  (Integer -> Integer) ->
  Music (Event a) -> Music (Event a) ;
wmap :: forall a.
(Integer -> Integer) -> Music (Event a) -> Music (Event a)
wmap Integer -> Integer
_  ( Atom ( Event a
ev ) ) = Event a -> Music (Event a)
forall a. a -> Music a
Atom ( a -> Event a
forall a. a -> Event a
Event a
ev ) ;
wmap Integer -> Integer
fn ( Atom ( Wait Integer
w ) ) = Event a -> Music (Event a)
forall a. a -> Music a
Atom ( Integer -> Event a
forall a. Integer -> Event a
Wait ( Integer -> Integer
fn Integer
w ) ) ;
wmap Integer -> Integer
_  ( Atom ( Say String
s ) ) = Event a -> Music (Event a)
forall a. a -> Music a
Atom ( String -> Event a
forall a. String -> Event a
Say String
s ) ;
wmap Integer -> Integer
fn ( Par [Music (Event a)]
xs ) = [Music (Event a)] -> Music (Event a)
forall a. [Music a] -> Music a
Par ( (Music (Event a) -> Music (Event a))
-> [Music (Event a)] -> [Music (Event a)]
forall a b. (a -> b) -> [a] -> [b]
map ( (Integer -> Integer) -> Music (Event a) -> Music (Event a)
forall a.
(Integer -> Integer) -> Music (Event a) -> Music (Event a)
wmap Integer -> Integer
fn ) [Music (Event a)]
xs );
wmap Integer -> Integer
fn ( Seq [Music (Event a)]
xs ) = [Music (Event a)] -> Music (Event a)
forall a. [Music a] -> Music a
Seq ( (Music (Event a) -> Music (Event a))
-> [Music (Event a)] -> [Music (Event a)]
forall a b. (a -> b) -> [a] -> [b]
map ( (Integer -> Integer) -> Music (Event a) -> Music (Event a)
forall a.
(Integer -> Integer) -> Music (Event a) -> Music (Event a)
wmap Integer -> Integer
fn ) [Music (Event a)]
xs );

amap :: (a -> b) -> Music a -> Music b ;
amap :: forall a b. (a -> b) -> Music a -> Music b
amap a -> b
fn ( Atom a
atom ) = b -> Music b
forall a. a -> Music a
Atom ( a -> b
fn a
atom ) ;
amap a -> b
fn ( Par [Music a]
xs ) = [Music b] -> Music b
forall a. [Music a] -> Music a
Par ( (Music a -> Music b) -> [Music a] -> [Music b]
forall a b. (a -> b) -> [a] -> [b]
map ( (a -> b) -> Music a -> Music b
forall a b. (a -> b) -> Music a -> Music b
amap a -> b
fn ) [Music a]
xs );
amap a -> b
fn ( Seq [Music a]
xs ) = [Music b] -> Music b
forall a. [Music a] -> Music a
Seq ( (Music a -> Music b) -> [Music a] -> [Music b]
forall a b. (a -> b) -> [a] -> [b]
map ( (a -> b) -> Music a -> Music b
forall a b. (a -> b) -> Music a -> Music b
amap a -> b
fn ) [Music a]
xs );


forever :: Music a -> Music a ;
forever :: forall a. Music a -> Music a
forever Music a
s = [Music a] -> Music a
forall a. [Music a] -> Music a
Seq ( Music a -> [Music a]
forall a. a -> [a]
repeat Music a
s ) ;

data Music a =
         Atom a
       | Par [Music a]
       | Seq [Music a] ;


play :: Music (Event a) -> [Event a] ;
play :: forall a. Music (Event a) -> [Event a]
play (Par [Music (Event a)]
xs) = [[Event a]] -> [Event a]
forall a. [[Event a]] -> [Event a]
mergeMany ( (Music (Event a) -> [Event a]) -> [Music (Event a)] -> [[Event a]]
forall a b. (a -> b) -> [a] -> [b]
map Music (Event a) -> [Event a]
forall a. Music (Event a) -> [Event a]
play [Music (Event a)]
xs ) ;
play (Seq [Music (Event a)]
xs) = [[Event a]] -> [Event a]
forall a. [[a]] -> [a]
concat ( (Music (Event a) -> [Event a]) -> [Music (Event a)] -> [[Event a]]
forall a b. (a -> b) -> [a] -> [b]
map Music (Event a) -> [Event a]
forall a. Music (Event a) -> [Event a]
play [Music (Event a)]
xs ) ;
play (Atom Event a
atom) = [ Event a
atom ] ;