% from AutoTrack by Stefan Ratschan
\subsubsection{Scales}
\begin{haskelllisting}
> module Haskore.Basic.Scale
> (T, ionian, dorian, phrygian, lydian, mixolydian,
> aeolian, lokrian, altered, htwt, wtht,
> ionianRel, dorianRel, phrygianRel, lydianRel, mixolydianRel,
> aeolianRel, lokrianRel, alteredRel, htwtRel, wthtRel,
>
> fromOffsets, fromIntervals, continue) where
> import qualified Haskore.Basic.Pitch as Pitch
> import Control.Monad(liftM2)
\end{haskelllisting}
Some of the following code is taken
from the EasyScale implementation of Martin Schwenke.
\begin{haskelllisting}
> type T = [Pitch.Absolute]
> type Intervals = [Pitch.Relative]
\end{haskelllisting}
Make a scale given a list of absolute pitches, usually starting at 0,
and a \type{Pitch.Class} representing the root note of the scale.
\begin{haskelllisting}
> fromOffsets :: [Pitch.Absolute] -> Pitch.Class -> T
> fromOffsets ns pc
> = map (+ Pitch.classToInt pc) ns
\end{haskelllisting}
Create a scale from a list of intervals between successive notes.
\begin{haskelllisting}
> fromIntervals :: Intervals -> Pitch.Class -> T
> fromIntervals = fromOffsets . scanl (+) 0
\end{haskelllisting}
Continue a scale to all octaves.
\begin{haskelllisting}
> continue :: T -> T
> continue = liftM2 (+) (iterate (12+) 0)
\end{haskelllisting}
Now some general useful scales from music theory.
\begin{haskelllisting}
> ionianRel, dorianRel, phrygianRel, lydianRel, mixolydianRel,
> aeolianRel, lokrianRel, alteredRel, htwtRel,
> wthtRel :: Intervals
> ionianRel = [ 2, 2, 1, 2, 2, 2, 1 ]
> dorianRel = [ 2, 1, 2, 2, 2, 1, 2 ]
> phrygianRel = [ 1, 2, 2, 2, 1, 2, 2 ]
> lydianRel = [ 2, 2, 2, 1, 2, 2, 1 ]
> mixolydianRel = [ 2, 2, 1, 2, 2, 1, 2 ]
> aeolianRel = [ 2, 1, 2, 2, 1, 2, 2 ]
> lokrianRel = [ 1, 2, 2, 1, 2, 2, 2 ]
> alteredRel = [ 1, 2, 1, 2, 2, 2, 2 ]
> htwtRel = [ 1, 2, 1, 2, 1, 2, 1, 2 ]
> wthtRel = [ 2, 1, 2, 1, 2, 1, 2, 1 ]
> ionian, dorian, phrygian, lydian, mixolydian,
> aeolian, lokrian, altered, htwt,
> wtht :: Pitch.Class -> T
> ionian = fromIntervals ionianRel
> dorian = fromIntervals dorianRel
> phrygian = fromIntervals phrygianRel
> lydian = fromIntervals lydianRel
> mixolydian = fromIntervals mixolydianRel
> aeolian = fromIntervals aeolianRel
> lokrian = fromIntervals lokrianRel
> altered = fromIntervals alteredRel
> htwt = fromIntervals htwtRel
> wtht = fromIntervals wthtRel
\end{haskelllisting}
Example:
Alternatively to applying \function{continue} to a scale
you can create an infinitely increasing scale
using the definition by intervals,
e.g. \code{fromIntervals (cycle ionianRel) Pitch.C}.