% from AutoTrack by Stefan Ratschan

\begin{haskelllisting}

> module Haskore.Interface.AutoTrack.EventChart
>    (T(Cons), events, fromChordChart, fromChartBar) where

> import qualified Haskore.Music        as Music
> import qualified Haskore.Interface.AutoTrack.ChartBar    as ChartBar
> import qualified Haskore.Interface.AutoTrack.ChordChart  as ChordChart
> import qualified Haskore.Interface.AutoTrack.ChordSymbol as ChordSymbol
> import qualified Haskore.Interface.AutoTrack.Transposeable as Transposeable
> import qualified Haskore.Basic.Duration as Dur
> import qualified Data.List as List
> import           Data.Maybe(fromJust)

\end{haskelllisting}

Event charts are currently not used. An event chart represents a list of objects of a
certain type and duration (the ``events'').

\begin{haskelllisting}

> data T e = Cons {events :: [ (Music.Dur, e) ] } deriving Show

> fromChordChart :: ChordChart.T -> T ChordSymbol.T
> fromChordChart (ChordChart.Cons c) =
>    Cons (concatMap (events . fromChartBar) c)

> fromChartBar :: ChartBar.T -> T ChordSymbol.T
> fromChartBar (ChartBar.Cons d l) =
>    let f c = (d / Dur.fromRatio (List.genericLength l), fromJust c)
>    in  Cons (map f l)

\end{haskelllisting}

Transpose an event chart by a certain number of semitones

\begin{haskelllisting}

> instance (Transposeable.C a) => Transposeable.C (T a) where
>   transpose i = fmap (Transposeable.transpose i)

\end{haskelllisting}

Event charts can also act as functors:

\begin{haskelllisting}

> instance Functor T where
>   fmap f (Cons v) = Cons (map ( \(d, c) -> (d, f c) ) v)

\end{haskelllisting}