module Harmony (Harmony(..),tomicromidi,tomidi) where

import qualified Midi as M
import qualified MicroMidi as MM
import qualified Pitch as P
import Melody
import qualified MelodyToMicroMidi as MelToMM
import Data.Ratio
import qualified MidiCCs

type Panning = M.Value

newtype Harmony d p = Harmony [(M.Channel,M.Program,Panning,Melody d p)]
    deriving (Show)

tomicromidi unitduration (Harmony []) = []
tomicromidi unitduration (Harmony ((channel,program,panning,melody):morelines)) =
    MM.mergestreams ((0,MM.ProgramChange channel program):
                     (0,MM.ControllerChange channel MidiCCs.pan panning):
                     MelToMM.tomicromidi channel unitduration melody)
      (tomicromidi unitduration (Harmony morelines))

testharmony::Harmony Rational Rational
testharmony = Harmony $
              [(0,48,32,soprano)
              ,(1,48,48,alto)
              ,(2,48,80,tenor)
              ,(3,48,96,bass)
              ]
    where
      n = Note
      soprano = Melody
          [(1%1,n (2%1) 64)
          ,(1%1,n (9%4) 64)
          ,(1%1,n (5%2) 64)
          ,(1%1,n (8%3) 64)
          --
          ,(1%1,n (9%4) 64)
          ,(1%1,n (5%2) 64)
          ,(1%1,n (10%3) 64)
          ,(1%1,n (3%1) 64)
          --
          ,(1%1,n (3%1) 64)
          ,(1%1,n (8%3) 64)
          ,(1%1,n (5%2) 64)
          ,(1%1,n (8%3) 64)
          --
          ,(2%1,n (9%4) 64)
          ,(1%1,n (2%1) 64)
          ,(1%1,Rest)
          ]
      alto = Melody
          [(1%1,n (2%1) 64)
          ,(1%1,n (15%8) 64)
          ,(2%1,n (2%1) 64)
          --
          ,(2%1,n (3%2) 64)
          ,(1%1,n (4%3) 64)
          ,(1%1,n (5%4) 64)
          --
          ,(1%1,n (3%2) 64)
          ,(1%1,n (5%3) 64)
          ,(5%1,n (3%2) 64)
          ,(1%1,Rest)
          ]
      tenor = Melody
          [(1%1,n (1%1) 64)
          ,(1%1,n (9%8) 64)
          ,(1%1,n (5%4) 64)
          ,(1%1,n (3%2) 64)
          --
          ,(1%1,n (9%8) 64)
          ,(1%1,n (15%16) 64)
          ,(2%1,n (1%1) 64)
          --
          ,(4%1,n (1%1) 64)
          --
          ,(2%1,n (15%16) 64)
          ,(1%1,n (1%1) 64)
          ,(1%1,Rest)           
          ]
      bass = Melody
             [(1%1,n (1%1) 64)
             ,(1%1,n (3%4) 64)
             ,(1%1,n (5%6) 64)
             ,(1%1,n (1%1) 64)
             --
             ,(2%1,n (3%4) 64)
             ,(2%1,n (1%2) 64)
             --
             ,(1%1,n (5%8) 64)
             ,(1%1,n (2%3) 64)
             ,(4%1,n (3%4) 64)
             ,(1%1,n (1%2) 64)
             ,(1%1,Rest)
             ]

tomidi unitduration harmony = 
    MM.tomidi (tomicromidi unitduration harmony)

test =
    writeFile "test.mid" (M.tofile 80 (tomidi 80 testharmony))