% from AutoTrack by Stefan Ratschan \section{Chord-Symbol-, Scale- and other Charts} \label{sec:charts} \begin{haskelllisting} > module Haskore.Interface.AutoTrack.ChartBar > (T(Cons), dur, chords, readChordSymbol, > length) where > import qualified Haskore.Music as Music > import qualified Data.List as List > import qualified Haskore.Interface.AutoTrack.ChordSymbol as ChordSymbol > import qualified Haskore.Interface.AutoTrack.Transposeable as Transposeable > import Data.Char(isSpace, isAlpha) > import Haskore.Basic.Duration(wn, (%+), ) > import Prelude hiding (length) \end{haskelllisting} A bar consists of a time signature and a list of chord symbols. Bars have the following input syntax: \begin{verbatim} bar = { chord | timeSig | '%' | '_' } timeSig = '(' int '/' int ')' \end{verbatim} If no time signature is provided then a default is used (within chord chart the time signature of the bar before, and 4/4 for the first bar). The character '\%' is a short-cut for the chords just before. The character '\_' denotes a break. \begin{haskelllisting} > data T = Cons { > dur :: Music.Dur, > chords :: [ Maybe ChordSymbol.T ] > } deriving Show > > length :: Integral a => T -> a > length = fromIntegral . List.length . chords > instance Read T where > readsPrec _ = readChordSymbol wn Nothing > readChordSymbol :: Music.Dur -> Maybe ChordSymbol.T -> ReadS T > readChordSymbol oldSig oldChord (c:s) | isSpace c = readChordSymbol oldSig oldChord s > readChordSymbol _ oldChord s@('(':_) = > [ (Cons r b, r2) | (r, r1) <- readSig s, > (Cons _ b, r2) <- readChordSymbol r oldChord r1 ] > readChordSymbol oldSig (Just chord) ('%':r) = > [ (Cons oldSig (Just chord:b), r1) | (Cons _ b, r1) <- readChordSymbol oldSig (Just chord) r ] > readChordSymbol oldSig (Just _) ('_':r) = > [ (Cons oldSig (Nothing:b), r1) | (Cons _ b, r1) <- readChordSymbol oldSig Nothing r ] > readChordSymbol oldSig _ s@(d:_) | isAlpha d = > [ (Cons oldSig (Just c:b), r2) | (c, r1) <- reads s, > (Cons _ b, r2) <- readChordSymbol oldSig (Just c) r1 ] > readChordSymbol oldSig _ s = [ (Cons oldSig [], s) ] > > readSig :: ReadS Music.Dur > readSig s@('(':_) = > let readRatio s' = > [ (p%+q, r1) | > (p,'/':r) <- reads s', (q, r1) <- reads r ] > in readParen True readRatio s > readSig _ = [] \end{haskelllisting} Bars can be transposed. \begin{haskelllisting} > instance Transposeable.C T where > transpose i (Cons d l) = Cons d (fmap (fmap (Transposeable.transpose i)) l) \end{haskelllisting}