{-# LANGUAGE DuplicateRecordFields #-}

{- | The core domain model for a tablature\/score document.

The shape mirrors how a multi-track tab is actually organized:

* A 'Song' owns the master timeline — one 'Measure' per bar, in order —
  plus a list of 'Track's (one per instrument\/part).
* A 'Track' does /not/ store its beats in a list parallel to
  'songMeasures'. Instead 'trackBeats' is a 'Map' keyed by
  'MeasureIndex', so a track only needs entries for measures it actually
  has notes in, and the same 'MeasureIndex' is the join key back to the
  'Measure' that supplies its time\/key signature and tempo.
* A 'Beat' groups the 'Note's that start together (e.g. every fretted
  string sounding on beat 1), plus the 'Duration' shared by all of them.
* A 'Note' carries both the fretboard position ('noteString', 'noteFret')
  used for tab rendering and the sounding 'Pitch' \/ 'Velocity' used for
  MIDI playback — the two are kept in sync by whichever code constructs
  the 'Note' (parsers, or the UI's editing commands), not enforced by
  the type itself.
-}
module Termtab.Types (
    MeasureIndex (..),
    BeatIndex (..),
    TrackIndex (..),
    StringIndex (..),
    FretNumber (..),
    MidiChannel (..),
    MidiProgram (..),
    Velocity (..),
    Tempo (..),
    Pitch (..),
    Duration (..),
    Mode (..),
    TimeSignature (..),
    KeySignature (..),
    BendValue (..),
    SlideType (..),
    NoteEffect (..),
    Note (..),
    Beat (..),
    Measure (..),
    Instrument (..),
    Track (..),
    Song (..),
    UnsupportedFormat (..),
    ParseError (..),
) where

import Data.Map.Strict (Map)
import Data.Text (Text)

{- | Position of a 'Measure' within a 'Song', and the lookup key into a
'Track''s 'trackBeats' map.
-}
newtype MeasureIndex = MeasureIndex Int deriving (Int -> MeasureIndex -> ShowS
[MeasureIndex] -> ShowS
MeasureIndex -> String
(Int -> MeasureIndex -> ShowS)
-> (MeasureIndex -> String)
-> ([MeasureIndex] -> ShowS)
-> Show MeasureIndex
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MeasureIndex -> ShowS
showsPrec :: Int -> MeasureIndex -> ShowS
$cshow :: MeasureIndex -> String
show :: MeasureIndex -> String
$cshowList :: [MeasureIndex] -> ShowS
showList :: [MeasureIndex] -> ShowS
Show, MeasureIndex -> MeasureIndex -> Bool
(MeasureIndex -> MeasureIndex -> Bool)
-> (MeasureIndex -> MeasureIndex -> Bool) -> Eq MeasureIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MeasureIndex -> MeasureIndex -> Bool
== :: MeasureIndex -> MeasureIndex -> Bool
$c/= :: MeasureIndex -> MeasureIndex -> Bool
/= :: MeasureIndex -> MeasureIndex -> Bool
Eq, Eq MeasureIndex
Eq MeasureIndex =>
(MeasureIndex -> MeasureIndex -> Ordering)
-> (MeasureIndex -> MeasureIndex -> Bool)
-> (MeasureIndex -> MeasureIndex -> Bool)
-> (MeasureIndex -> MeasureIndex -> Bool)
-> (MeasureIndex -> MeasureIndex -> Bool)
-> (MeasureIndex -> MeasureIndex -> MeasureIndex)
-> (MeasureIndex -> MeasureIndex -> MeasureIndex)
-> Ord MeasureIndex
MeasureIndex -> MeasureIndex -> Bool
MeasureIndex -> MeasureIndex -> Ordering
MeasureIndex -> MeasureIndex -> MeasureIndex
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MeasureIndex -> MeasureIndex -> Ordering
compare :: MeasureIndex -> MeasureIndex -> Ordering
$c< :: MeasureIndex -> MeasureIndex -> Bool
< :: MeasureIndex -> MeasureIndex -> Bool
$c<= :: MeasureIndex -> MeasureIndex -> Bool
<= :: MeasureIndex -> MeasureIndex -> Bool
$c> :: MeasureIndex -> MeasureIndex -> Bool
> :: MeasureIndex -> MeasureIndex -> Bool
$c>= :: MeasureIndex -> MeasureIndex -> Bool
>= :: MeasureIndex -> MeasureIndex -> Bool
$cmax :: MeasureIndex -> MeasureIndex -> MeasureIndex
max :: MeasureIndex -> MeasureIndex -> MeasureIndex
$cmin :: MeasureIndex -> MeasureIndex -> MeasureIndex
min :: MeasureIndex -> MeasureIndex -> MeasureIndex
Ord)

-- | Position of a 'Beat' within the list of beats for one measure of one track.
newtype BeatIndex = BeatIndex Int deriving (Int -> BeatIndex -> ShowS
[BeatIndex] -> ShowS
BeatIndex -> String
(Int -> BeatIndex -> ShowS)
-> (BeatIndex -> String)
-> ([BeatIndex] -> ShowS)
-> Show BeatIndex
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BeatIndex -> ShowS
showsPrec :: Int -> BeatIndex -> ShowS
$cshow :: BeatIndex -> String
show :: BeatIndex -> String
$cshowList :: [BeatIndex] -> ShowS
showList :: [BeatIndex] -> ShowS
Show, BeatIndex -> BeatIndex -> Bool
(BeatIndex -> BeatIndex -> Bool)
-> (BeatIndex -> BeatIndex -> Bool) -> Eq BeatIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BeatIndex -> BeatIndex -> Bool
== :: BeatIndex -> BeatIndex -> Bool
$c/= :: BeatIndex -> BeatIndex -> Bool
/= :: BeatIndex -> BeatIndex -> Bool
Eq, Eq BeatIndex
Eq BeatIndex =>
(BeatIndex -> BeatIndex -> Ordering)
-> (BeatIndex -> BeatIndex -> Bool)
-> (BeatIndex -> BeatIndex -> Bool)
-> (BeatIndex -> BeatIndex -> Bool)
-> (BeatIndex -> BeatIndex -> Bool)
-> (BeatIndex -> BeatIndex -> BeatIndex)
-> (BeatIndex -> BeatIndex -> BeatIndex)
-> Ord BeatIndex
BeatIndex -> BeatIndex -> Bool
BeatIndex -> BeatIndex -> Ordering
BeatIndex -> BeatIndex -> BeatIndex
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: BeatIndex -> BeatIndex -> Ordering
compare :: BeatIndex -> BeatIndex -> Ordering
$c< :: BeatIndex -> BeatIndex -> Bool
< :: BeatIndex -> BeatIndex -> Bool
$c<= :: BeatIndex -> BeatIndex -> Bool
<= :: BeatIndex -> BeatIndex -> Bool
$c> :: BeatIndex -> BeatIndex -> Bool
> :: BeatIndex -> BeatIndex -> Bool
$c>= :: BeatIndex -> BeatIndex -> Bool
>= :: BeatIndex -> BeatIndex -> Bool
$cmax :: BeatIndex -> BeatIndex -> BeatIndex
max :: BeatIndex -> BeatIndex -> BeatIndex
$cmin :: BeatIndex -> BeatIndex -> BeatIndex
min :: BeatIndex -> BeatIndex -> BeatIndex
Ord)

-- | Position of a 'Track' within 'songTracks'.
newtype TrackIndex = TrackIndex Int deriving (Int -> TrackIndex -> ShowS
[TrackIndex] -> ShowS
TrackIndex -> String
(Int -> TrackIndex -> ShowS)
-> (TrackIndex -> String)
-> ([TrackIndex] -> ShowS)
-> Show TrackIndex
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TrackIndex -> ShowS
showsPrec :: Int -> TrackIndex -> ShowS
$cshow :: TrackIndex -> String
show :: TrackIndex -> String
$cshowList :: [TrackIndex] -> ShowS
showList :: [TrackIndex] -> ShowS
Show, TrackIndex -> TrackIndex -> Bool
(TrackIndex -> TrackIndex -> Bool)
-> (TrackIndex -> TrackIndex -> Bool) -> Eq TrackIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TrackIndex -> TrackIndex -> Bool
== :: TrackIndex -> TrackIndex -> Bool
$c/= :: TrackIndex -> TrackIndex -> Bool
/= :: TrackIndex -> TrackIndex -> Bool
Eq, Eq TrackIndex
Eq TrackIndex =>
(TrackIndex -> TrackIndex -> Ordering)
-> (TrackIndex -> TrackIndex -> Bool)
-> (TrackIndex -> TrackIndex -> Bool)
-> (TrackIndex -> TrackIndex -> Bool)
-> (TrackIndex -> TrackIndex -> Bool)
-> (TrackIndex -> TrackIndex -> TrackIndex)
-> (TrackIndex -> TrackIndex -> TrackIndex)
-> Ord TrackIndex
TrackIndex -> TrackIndex -> Bool
TrackIndex -> TrackIndex -> Ordering
TrackIndex -> TrackIndex -> TrackIndex
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: TrackIndex -> TrackIndex -> Ordering
compare :: TrackIndex -> TrackIndex -> Ordering
$c< :: TrackIndex -> TrackIndex -> Bool
< :: TrackIndex -> TrackIndex -> Bool
$c<= :: TrackIndex -> TrackIndex -> Bool
<= :: TrackIndex -> TrackIndex -> Bool
$c> :: TrackIndex -> TrackIndex -> Bool
> :: TrackIndex -> TrackIndex -> Bool
$c>= :: TrackIndex -> TrackIndex -> Bool
>= :: TrackIndex -> TrackIndex -> Bool
$cmax :: TrackIndex -> TrackIndex -> TrackIndex
max :: TrackIndex -> TrackIndex -> TrackIndex
$cmin :: TrackIndex -> TrackIndex -> TrackIndex
min :: TrackIndex -> TrackIndex -> TrackIndex
Ord)

{- | Which string of a fretted 'Instrument' a 'Note' is played on (0 = lowest
or highest string depending on convention used by the caller; this type
only pairs with 'FretNumber' to locate a tab cell).
-}
newtype StringIndex = StringIndex Int deriving (Int -> StringIndex -> ShowS
[StringIndex] -> ShowS
StringIndex -> String
(Int -> StringIndex -> ShowS)
-> (StringIndex -> String)
-> ([StringIndex] -> ShowS)
-> Show StringIndex
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StringIndex -> ShowS
showsPrec :: Int -> StringIndex -> ShowS
$cshow :: StringIndex -> String
show :: StringIndex -> String
$cshowList :: [StringIndex] -> ShowS
showList :: [StringIndex] -> ShowS
Show, StringIndex -> StringIndex -> Bool
(StringIndex -> StringIndex -> Bool)
-> (StringIndex -> StringIndex -> Bool) -> Eq StringIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StringIndex -> StringIndex -> Bool
== :: StringIndex -> StringIndex -> Bool
$c/= :: StringIndex -> StringIndex -> Bool
/= :: StringIndex -> StringIndex -> Bool
Eq, Eq StringIndex
Eq StringIndex =>
(StringIndex -> StringIndex -> Ordering)
-> (StringIndex -> StringIndex -> Bool)
-> (StringIndex -> StringIndex -> Bool)
-> (StringIndex -> StringIndex -> Bool)
-> (StringIndex -> StringIndex -> Bool)
-> (StringIndex -> StringIndex -> StringIndex)
-> (StringIndex -> StringIndex -> StringIndex)
-> Ord StringIndex
StringIndex -> StringIndex -> Bool
StringIndex -> StringIndex -> Ordering
StringIndex -> StringIndex -> StringIndex
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: StringIndex -> StringIndex -> Ordering
compare :: StringIndex -> StringIndex -> Ordering
$c< :: StringIndex -> StringIndex -> Bool
< :: StringIndex -> StringIndex -> Bool
$c<= :: StringIndex -> StringIndex -> Bool
<= :: StringIndex -> StringIndex -> Bool
$c> :: StringIndex -> StringIndex -> Bool
> :: StringIndex -> StringIndex -> Bool
$c>= :: StringIndex -> StringIndex -> Bool
>= :: StringIndex -> StringIndex -> Bool
$cmax :: StringIndex -> StringIndex -> StringIndex
max :: StringIndex -> StringIndex -> StringIndex
$cmin :: StringIndex -> StringIndex -> StringIndex
min :: StringIndex -> StringIndex -> StringIndex
Ord)

-- | Fret position for a fretted 'Note', paired with 'StringIndex'.
newtype FretNumber = FretNumber Int deriving (Int -> FretNumber -> ShowS
[FretNumber] -> ShowS
FretNumber -> String
(Int -> FretNumber -> ShowS)
-> (FretNumber -> String)
-> ([FretNumber] -> ShowS)
-> Show FretNumber
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FretNumber -> ShowS
showsPrec :: Int -> FretNumber -> ShowS
$cshow :: FretNumber -> String
show :: FretNumber -> String
$cshowList :: [FretNumber] -> ShowS
showList :: [FretNumber] -> ShowS
Show, FretNumber -> FretNumber -> Bool
(FretNumber -> FretNumber -> Bool)
-> (FretNumber -> FretNumber -> Bool) -> Eq FretNumber
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FretNumber -> FretNumber -> Bool
== :: FretNumber -> FretNumber -> Bool
$c/= :: FretNumber -> FretNumber -> Bool
/= :: FretNumber -> FretNumber -> Bool
Eq, Eq FretNumber
Eq FretNumber =>
(FretNumber -> FretNumber -> Ordering)
-> (FretNumber -> FretNumber -> Bool)
-> (FretNumber -> FretNumber -> Bool)
-> (FretNumber -> FretNumber -> Bool)
-> (FretNumber -> FretNumber -> Bool)
-> (FretNumber -> FretNumber -> FretNumber)
-> (FretNumber -> FretNumber -> FretNumber)
-> Ord FretNumber
FretNumber -> FretNumber -> Bool
FretNumber -> FretNumber -> Ordering
FretNumber -> FretNumber -> FretNumber
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: FretNumber -> FretNumber -> Ordering
compare :: FretNumber -> FretNumber -> Ordering
$c< :: FretNumber -> FretNumber -> Bool
< :: FretNumber -> FretNumber -> Bool
$c<= :: FretNumber -> FretNumber -> Bool
<= :: FretNumber -> FretNumber -> Bool
$c> :: FretNumber -> FretNumber -> Bool
> :: FretNumber -> FretNumber -> Bool
$c>= :: FretNumber -> FretNumber -> Bool
>= :: FretNumber -> FretNumber -> Bool
$cmax :: FretNumber -> FretNumber -> FretNumber
max :: FretNumber -> FretNumber -> FretNumber
$cmin :: FretNumber -> FretNumber -> FretNumber
min :: FretNumber -> FretNumber -> FretNumber
Ord)

-- | MIDI channel (0-15) a 'Track' is routed to for playback.
newtype MidiChannel = MidiChannel Int deriving (Int -> MidiChannel -> ShowS
[MidiChannel] -> ShowS
MidiChannel -> String
(Int -> MidiChannel -> ShowS)
-> (MidiChannel -> String)
-> ([MidiChannel] -> ShowS)
-> Show MidiChannel
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MidiChannel -> ShowS
showsPrec :: Int -> MidiChannel -> ShowS
$cshow :: MidiChannel -> String
show :: MidiChannel -> String
$cshowList :: [MidiChannel] -> ShowS
showList :: [MidiChannel] -> ShowS
Show, MidiChannel -> MidiChannel -> Bool
(MidiChannel -> MidiChannel -> Bool)
-> (MidiChannel -> MidiChannel -> Bool) -> Eq MidiChannel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MidiChannel -> MidiChannel -> Bool
== :: MidiChannel -> MidiChannel -> Bool
$c/= :: MidiChannel -> MidiChannel -> Bool
/= :: MidiChannel -> MidiChannel -> Bool
Eq, Eq MidiChannel
Eq MidiChannel =>
(MidiChannel -> MidiChannel -> Ordering)
-> (MidiChannel -> MidiChannel -> Bool)
-> (MidiChannel -> MidiChannel -> Bool)
-> (MidiChannel -> MidiChannel -> Bool)
-> (MidiChannel -> MidiChannel -> Bool)
-> (MidiChannel -> MidiChannel -> MidiChannel)
-> (MidiChannel -> MidiChannel -> MidiChannel)
-> Ord MidiChannel
MidiChannel -> MidiChannel -> Bool
MidiChannel -> MidiChannel -> Ordering
MidiChannel -> MidiChannel -> MidiChannel
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MidiChannel -> MidiChannel -> Ordering
compare :: MidiChannel -> MidiChannel -> Ordering
$c< :: MidiChannel -> MidiChannel -> Bool
< :: MidiChannel -> MidiChannel -> Bool
$c<= :: MidiChannel -> MidiChannel -> Bool
<= :: MidiChannel -> MidiChannel -> Bool
$c> :: MidiChannel -> MidiChannel -> Bool
> :: MidiChannel -> MidiChannel -> Bool
$c>= :: MidiChannel -> MidiChannel -> Bool
>= :: MidiChannel -> MidiChannel -> Bool
$cmax :: MidiChannel -> MidiChannel -> MidiChannel
max :: MidiChannel -> MidiChannel -> MidiChannel
$cmin :: MidiChannel -> MidiChannel -> MidiChannel
min :: MidiChannel -> MidiChannel -> MidiChannel
Ord)

-- | General MIDI program (patch\/instrument) number, used by 'Standard' instruments.
newtype MidiProgram = MidiProgram Int deriving (Int -> MidiProgram -> ShowS
[MidiProgram] -> ShowS
MidiProgram -> String
(Int -> MidiProgram -> ShowS)
-> (MidiProgram -> String)
-> ([MidiProgram] -> ShowS)
-> Show MidiProgram
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MidiProgram -> ShowS
showsPrec :: Int -> MidiProgram -> ShowS
$cshow :: MidiProgram -> String
show :: MidiProgram -> String
$cshowList :: [MidiProgram] -> ShowS
showList :: [MidiProgram] -> ShowS
Show, MidiProgram -> MidiProgram -> Bool
(MidiProgram -> MidiProgram -> Bool)
-> (MidiProgram -> MidiProgram -> Bool) -> Eq MidiProgram
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MidiProgram -> MidiProgram -> Bool
== :: MidiProgram -> MidiProgram -> Bool
$c/= :: MidiProgram -> MidiProgram -> Bool
/= :: MidiProgram -> MidiProgram -> Bool
Eq, Eq MidiProgram
Eq MidiProgram =>
(MidiProgram -> MidiProgram -> Ordering)
-> (MidiProgram -> MidiProgram -> Bool)
-> (MidiProgram -> MidiProgram -> Bool)
-> (MidiProgram -> MidiProgram -> Bool)
-> (MidiProgram -> MidiProgram -> Bool)
-> (MidiProgram -> MidiProgram -> MidiProgram)
-> (MidiProgram -> MidiProgram -> MidiProgram)
-> Ord MidiProgram
MidiProgram -> MidiProgram -> Bool
MidiProgram -> MidiProgram -> Ordering
MidiProgram -> MidiProgram -> MidiProgram
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MidiProgram -> MidiProgram -> Ordering
compare :: MidiProgram -> MidiProgram -> Ordering
$c< :: MidiProgram -> MidiProgram -> Bool
< :: MidiProgram -> MidiProgram -> Bool
$c<= :: MidiProgram -> MidiProgram -> Bool
<= :: MidiProgram -> MidiProgram -> Bool
$c> :: MidiProgram -> MidiProgram -> Bool
> :: MidiProgram -> MidiProgram -> Bool
$c>= :: MidiProgram -> MidiProgram -> Bool
>= :: MidiProgram -> MidiProgram -> Bool
$cmax :: MidiProgram -> MidiProgram -> MidiProgram
max :: MidiProgram -> MidiProgram -> MidiProgram
$cmin :: MidiProgram -> MidiProgram -> MidiProgram
min :: MidiProgram -> MidiProgram -> MidiProgram
Ord)

-- | MIDI note-on velocity (loudness) for a 'Note'.
newtype Velocity = Velocity Int deriving (Int -> Velocity -> ShowS
[Velocity] -> ShowS
Velocity -> String
(Int -> Velocity -> ShowS)
-> (Velocity -> String) -> ([Velocity] -> ShowS) -> Show Velocity
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Velocity -> ShowS
showsPrec :: Int -> Velocity -> ShowS
$cshow :: Velocity -> String
show :: Velocity -> String
$cshowList :: [Velocity] -> ShowS
showList :: [Velocity] -> ShowS
Show, Velocity -> Velocity -> Bool
(Velocity -> Velocity -> Bool)
-> (Velocity -> Velocity -> Bool) -> Eq Velocity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Velocity -> Velocity -> Bool
== :: Velocity -> Velocity -> Bool
$c/= :: Velocity -> Velocity -> Bool
/= :: Velocity -> Velocity -> Bool
Eq, Eq Velocity
Eq Velocity =>
(Velocity -> Velocity -> Ordering)
-> (Velocity -> Velocity -> Bool)
-> (Velocity -> Velocity -> Bool)
-> (Velocity -> Velocity -> Bool)
-> (Velocity -> Velocity -> Bool)
-> (Velocity -> Velocity -> Velocity)
-> (Velocity -> Velocity -> Velocity)
-> Ord Velocity
Velocity -> Velocity -> Bool
Velocity -> Velocity -> Ordering
Velocity -> Velocity -> Velocity
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Velocity -> Velocity -> Ordering
compare :: Velocity -> Velocity -> Ordering
$c< :: Velocity -> Velocity -> Bool
< :: Velocity -> Velocity -> Bool
$c<= :: Velocity -> Velocity -> Bool
<= :: Velocity -> Velocity -> Bool
$c> :: Velocity -> Velocity -> Bool
> :: Velocity -> Velocity -> Bool
$c>= :: Velocity -> Velocity -> Bool
>= :: Velocity -> Velocity -> Bool
$cmax :: Velocity -> Velocity -> Velocity
max :: Velocity -> Velocity -> Velocity
$cmin :: Velocity -> Velocity -> Velocity
min :: Velocity -> Velocity -> Velocity
Ord)

{- | Tempo in beats per minute. Appears both as a 'Song'-wide default
('songTempo') and as an optional per-'Measure' override ('tempoChange').
-}
newtype Tempo = Tempo Int deriving (Int -> Tempo -> ShowS
[Tempo] -> ShowS
Tempo -> String
(Int -> Tempo -> ShowS)
-> (Tempo -> String) -> ([Tempo] -> ShowS) -> Show Tempo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Tempo -> ShowS
showsPrec :: Int -> Tempo -> ShowS
$cshow :: Tempo -> String
show :: Tempo -> String
$cshowList :: [Tempo] -> ShowS
showList :: [Tempo] -> ShowS
Show, Tempo -> Tempo -> Bool
(Tempo -> Tempo -> Bool) -> (Tempo -> Tempo -> Bool) -> Eq Tempo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Tempo -> Tempo -> Bool
== :: Tempo -> Tempo -> Bool
$c/= :: Tempo -> Tempo -> Bool
/= :: Tempo -> Tempo -> Bool
Eq, Eq Tempo
Eq Tempo =>
(Tempo -> Tempo -> Ordering)
-> (Tempo -> Tempo -> Bool)
-> (Tempo -> Tempo -> Bool)
-> (Tempo -> Tempo -> Bool)
-> (Tempo -> Tempo -> Bool)
-> (Tempo -> Tempo -> Tempo)
-> (Tempo -> Tempo -> Tempo)
-> Ord Tempo
Tempo -> Tempo -> Bool
Tempo -> Tempo -> Ordering
Tempo -> Tempo -> Tempo
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Tempo -> Tempo -> Ordering
compare :: Tempo -> Tempo -> Ordering
$c< :: Tempo -> Tempo -> Bool
< :: Tempo -> Tempo -> Bool
$c<= :: Tempo -> Tempo -> Bool
<= :: Tempo -> Tempo -> Bool
$c> :: Tempo -> Tempo -> Bool
> :: Tempo -> Tempo -> Bool
$c>= :: Tempo -> Tempo -> Bool
>= :: Tempo -> Tempo -> Bool
$cmax :: Tempo -> Tempo -> Tempo
max :: Tempo -> Tempo -> Tempo
$cmin :: Tempo -> Tempo -> Tempo
min :: Tempo -> Tempo -> Tempo
Ord)

{- | Absolute MIDI pitch (0-127, middle C = 60). Used for both the sounding
pitch of a 'Note' and the open-string tuning of a fretted 'Instrument'.
-}
newtype Pitch = Pitch Int deriving (Int -> Pitch -> ShowS
[Pitch] -> ShowS
Pitch -> String
(Int -> Pitch -> ShowS)
-> (Pitch -> String) -> ([Pitch] -> ShowS) -> Show Pitch
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Pitch -> ShowS
showsPrec :: Int -> Pitch -> ShowS
$cshow :: Pitch -> String
show :: Pitch -> String
$cshowList :: [Pitch] -> ShowS
showList :: [Pitch] -> ShowS
Show, Pitch -> Pitch -> Bool
(Pitch -> Pitch -> Bool) -> (Pitch -> Pitch -> Bool) -> Eq Pitch
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Pitch -> Pitch -> Bool
== :: Pitch -> Pitch -> Bool
$c/= :: Pitch -> Pitch -> Bool
/= :: Pitch -> Pitch -> Bool
Eq, Eq Pitch
Eq Pitch =>
(Pitch -> Pitch -> Ordering)
-> (Pitch -> Pitch -> Bool)
-> (Pitch -> Pitch -> Bool)
-> (Pitch -> Pitch -> Bool)
-> (Pitch -> Pitch -> Bool)
-> (Pitch -> Pitch -> Pitch)
-> (Pitch -> Pitch -> Pitch)
-> Ord Pitch
Pitch -> Pitch -> Bool
Pitch -> Pitch -> Ordering
Pitch -> Pitch -> Pitch
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Pitch -> Pitch -> Ordering
compare :: Pitch -> Pitch -> Ordering
$c< :: Pitch -> Pitch -> Bool
< :: Pitch -> Pitch -> Bool
$c<= :: Pitch -> Pitch -> Bool
<= :: Pitch -> Pitch -> Bool
$c> :: Pitch -> Pitch -> Bool
> :: Pitch -> Pitch -> Bool
$c>= :: Pitch -> Pitch -> Bool
>= :: Pitch -> Pitch -> Bool
$cmax :: Pitch -> Pitch -> Pitch
max :: Pitch -> Pitch -> Pitch
$cmin :: Pitch -> Pitch -> Pitch
min :: Pitch -> Pitch -> Pitch
Ord)

{- | Rhythmic duration of a 'Beat'. 'Dotted' and 'Triplet' wrap another
'Duration' rather than being enumerated separately, so e.g. a dotted
eighth is @Dotted Eighth@ and a triplet eighth is @Triplet Eighth@; the
two can combine (@Dotted (Triplet Eighth)@) since nothing restricts nesting.
-}
data Duration
    = Whole
    | Half
    | Quarter
    | Eighth
    | Sixteenth
    | Thirty2nd
    | Dotted Duration
    | Triplet Duration
    deriving (Int -> Duration -> ShowS
[Duration] -> ShowS
Duration -> String
(Int -> Duration -> ShowS)
-> (Duration -> String) -> ([Duration] -> ShowS) -> Show Duration
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Duration -> ShowS
showsPrec :: Int -> Duration -> ShowS
$cshow :: Duration -> String
show :: Duration -> String
$cshowList :: [Duration] -> ShowS
showList :: [Duration] -> ShowS
Show, Duration -> Duration -> Bool
(Duration -> Duration -> Bool)
-> (Duration -> Duration -> Bool) -> Eq Duration
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Duration -> Duration -> Bool
== :: Duration -> Duration -> Bool
$c/= :: Duration -> Duration -> Bool
/= :: Duration -> Duration -> Bool
Eq, Eq Duration
Eq Duration =>
(Duration -> Duration -> Ordering)
-> (Duration -> Duration -> Bool)
-> (Duration -> Duration -> Bool)
-> (Duration -> Duration -> Bool)
-> (Duration -> Duration -> Bool)
-> (Duration -> Duration -> Duration)
-> (Duration -> Duration -> Duration)
-> Ord Duration
Duration -> Duration -> Bool
Duration -> Duration -> Ordering
Duration -> Duration -> Duration
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Duration -> Duration -> Ordering
compare :: Duration -> Duration -> Ordering
$c< :: Duration -> Duration -> Bool
< :: Duration -> Duration -> Bool
$c<= :: Duration -> Duration -> Bool
<= :: Duration -> Duration -> Bool
$c> :: Duration -> Duration -> Bool
> :: Duration -> Duration -> Bool
$c>= :: Duration -> Duration -> Bool
>= :: Duration -> Duration -> Bool
$cmax :: Duration -> Duration -> Duration
max :: Duration -> Duration -> Duration
$cmin :: Duration -> Duration -> Duration
min :: Duration -> Duration -> Duration
Ord)

-- | Major\/minor quality of a 'KeySignature'.
data Mode = Major | Minor deriving (Int -> Mode -> ShowS
[Mode] -> ShowS
Mode -> String
(Int -> Mode -> ShowS)
-> (Mode -> String) -> ([Mode] -> ShowS) -> Show Mode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Mode -> ShowS
showsPrec :: Int -> Mode -> ShowS
$cshow :: Mode -> String
show :: Mode -> String
$cshowList :: [Mode] -> ShowS
showList :: [Mode] -> ShowS
Show, Mode -> Mode -> Bool
(Mode -> Mode -> Bool) -> (Mode -> Mode -> Bool) -> Eq Mode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Mode -> Mode -> Bool
== :: Mode -> Mode -> Bool
$c/= :: Mode -> Mode -> Bool
/= :: Mode -> Mode -> Bool
Eq)

{- | Time signature as @TimeSignature numerator denominator@, e.g.
@TimeSignature 4 4@ for common time.
-}
data TimeSignature = TimeSignature Int Int
    deriving (Int -> TimeSignature -> ShowS
[TimeSignature] -> ShowS
TimeSignature -> String
(Int -> TimeSignature -> ShowS)
-> (TimeSignature -> String)
-> ([TimeSignature] -> ShowS)
-> Show TimeSignature
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TimeSignature -> ShowS
showsPrec :: Int -> TimeSignature -> ShowS
$cshow :: TimeSignature -> String
show :: TimeSignature -> String
$cshowList :: [TimeSignature] -> ShowS
showList :: [TimeSignature] -> ShowS
Show, TimeSignature -> TimeSignature -> Bool
(TimeSignature -> TimeSignature -> Bool)
-> (TimeSignature -> TimeSignature -> Bool) -> Eq TimeSignature
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TimeSignature -> TimeSignature -> Bool
== :: TimeSignature -> TimeSignature -> Bool
$c/= :: TimeSignature -> TimeSignature -> Bool
/= :: TimeSignature -> TimeSignature -> Bool
Eq)

{- | Key signature as @KeySignature accidentals mode@, where @accidentals@
is signed count of sharps (positive) or flats (negative) from the circle
of fifths, e.g. @KeySignature 2 Major@ is D major (two sharps).
-}
data KeySignature = KeySignature Int Mode
    deriving (Int -> KeySignature -> ShowS
[KeySignature] -> ShowS
KeySignature -> String
(Int -> KeySignature -> ShowS)
-> (KeySignature -> String)
-> ([KeySignature] -> ShowS)
-> Show KeySignature
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeySignature -> ShowS
showsPrec :: Int -> KeySignature -> ShowS
$cshow :: KeySignature -> String
show :: KeySignature -> String
$cshowList :: [KeySignature] -> ShowS
showList :: [KeySignature] -> ShowS
Show, KeySignature -> KeySignature -> Bool
(KeySignature -> KeySignature -> Bool)
-> (KeySignature -> KeySignature -> Bool) -> Eq KeySignature
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: KeySignature -> KeySignature -> Bool
== :: KeySignature -> KeySignature -> Bool
$c/= :: KeySignature -> KeySignature -> Bool
/= :: KeySignature -> KeySignature -> Bool
Eq)

{- | Pitch bend amount in semitones\/cents (interpretation is up to the
producer\/consumer, e.g. the GP5 parser or the audio engine); carried by
the 'Bend' 'NoteEffect'.
-}
newtype BendValue = BendValue Int deriving (Int -> BendValue -> ShowS
[BendValue] -> ShowS
BendValue -> String
(Int -> BendValue -> ShowS)
-> (BendValue -> String)
-> ([BendValue] -> ShowS)
-> Show BendValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BendValue -> ShowS
showsPrec :: Int -> BendValue -> ShowS
$cshow :: BendValue -> String
show :: BendValue -> String
$cshowList :: [BendValue] -> ShowS
showList :: [BendValue] -> ShowS
Show, BendValue -> BendValue -> Bool
(BendValue -> BendValue -> Bool)
-> (BendValue -> BendValue -> Bool) -> Eq BendValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BendValue -> BendValue -> Bool
== :: BendValue -> BendValue -> Bool
$c/= :: BendValue -> BendValue -> Bool
/= :: BendValue -> BendValue -> Bool
Eq)

{- | Variants of slide/legato articulation between fretted notes, used by
the 'Slide' 'NoteEffect'.
-}
data SlideType
    = SlideIntoFrom
    | SlideIntoBelow
    | SlideOutDown
    | SlideOutUp
    | ShiftSlide
    | LegatoSlide
    deriving (Int -> SlideType -> ShowS
[SlideType] -> ShowS
SlideType -> String
(Int -> SlideType -> ShowS)
-> (SlideType -> String)
-> ([SlideType] -> ShowS)
-> Show SlideType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SlideType -> ShowS
showsPrec :: Int -> SlideType -> ShowS
$cshow :: SlideType -> String
show :: SlideType -> String
$cshowList :: [SlideType] -> ShowS
showList :: [SlideType] -> ShowS
Show, SlideType -> SlideType -> Bool
(SlideType -> SlideType -> Bool)
-> (SlideType -> SlideType -> Bool) -> Eq SlideType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SlideType -> SlideType -> Bool
== :: SlideType -> SlideType -> Bool
$c/= :: SlideType -> SlideType -> Bool
/= :: SlideType -> SlideType -> Bool
Eq)

{- | A single articulation attached to a 'Note'. A note can carry several of
these via 'noteEffects' (e.g. a bend into a vibrato).
-}
data NoteEffect
    = Bend BendValue
    | Slide SlideType
    | HammerOn
    | PullOff
    | Vibrato
    | PalmMute
    deriving (Int -> NoteEffect -> ShowS
[NoteEffect] -> ShowS
NoteEffect -> String
(Int -> NoteEffect -> ShowS)
-> (NoteEffect -> String)
-> ([NoteEffect] -> ShowS)
-> Show NoteEffect
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NoteEffect -> ShowS
showsPrec :: Int -> NoteEffect -> ShowS
$cshow :: NoteEffect -> String
show :: NoteEffect -> String
$cshowList :: [NoteEffect] -> ShowS
showList :: [NoteEffect] -> ShowS
Show, NoteEffect -> NoteEffect -> Bool
(NoteEffect -> NoteEffect -> Bool)
-> (NoteEffect -> NoteEffect -> Bool) -> Eq NoteEffect
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NoteEffect -> NoteEffect -> Bool
== :: NoteEffect -> NoteEffect -> Bool
$c/= :: NoteEffect -> NoteEffect -> Bool
/= :: NoteEffect -> NoteEffect -> Bool
Eq)

{- | One played (or fretted) note. 'notePitch' \/ 'noteVelocity' describe
what should sound; 'noteString' \/ 'noteFret' describe where it sits on
the fretboard for tab rendering and are 'Nothing' for non-fretted
instruments (see 'Standard').
-}
data Note = Note
    { Note -> Pitch
notePitch :: Pitch
    , Note -> Velocity
noteVelocity :: Velocity
    , Note -> [NoteEffect]
noteEffects :: [NoteEffect]
    , Note -> Maybe StringIndex
noteString :: Maybe StringIndex
    , Note -> Maybe FretNumber
noteFret :: Maybe FretNumber
    }
    deriving (Int -> Note -> ShowS
[Note] -> ShowS
Note -> String
(Int -> Note -> ShowS)
-> (Note -> String) -> ([Note] -> ShowS) -> Show Note
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Note -> ShowS
showsPrec :: Int -> Note -> ShowS
$cshow :: Note -> String
show :: Note -> String
$cshowList :: [Note] -> ShowS
showList :: [Note] -> ShowS
Show, Note -> Note -> Bool
(Note -> Note -> Bool) -> (Note -> Note -> Bool) -> Eq Note
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Note -> Note -> Bool
== :: Note -> Note -> Bool
$c/= :: Note -> Note -> Bool
/= :: Note -> Note -> Bool
Eq)

{- | A set of 'Note's that start simultaneously, sharing one 'Duration'.
'beatIsRest' marks silence; when 'True', 'beatNotes' is expected to be
empty.
-}
data Beat = Beat
    { Beat -> Duration
beatDuration :: Duration
    , Beat -> [Note]
beatNotes :: [Note]
    , Beat -> Bool
beatIsRest :: Bool
    }
    deriving (Int -> Beat -> ShowS
[Beat] -> ShowS
Beat -> String
(Int -> Beat -> ShowS)
-> (Beat -> String) -> ([Beat] -> ShowS) -> Show Beat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Beat -> ShowS
showsPrec :: Int -> Beat -> ShowS
$cshow :: Beat -> String
show :: Beat -> String
$cshowList :: [Beat] -> ShowS
showList :: [Beat] -> ShowS
Show, Beat -> Beat -> Bool
(Beat -> Beat -> Bool) -> (Beat -> Beat -> Bool) -> Eq Beat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Beat -> Beat -> Bool
== :: Beat -> Beat -> Bool
$c/= :: Beat -> Beat -> Bool
/= :: Beat -> Beat -> Bool
Eq)

{- | Metadata for one bar of the 'Song'-wide timeline. This holds the
signatures and tempo change for the bar; it does /not/ hold notes — the
actual 'Beat's for this bar live in each 'Track''s 'trackBeats', keyed by
this measure's 'measureIndex'.
-}
data Measure = Measure
    { Measure -> MeasureIndex
measureIndex :: MeasureIndex
    , Measure -> TimeSignature
timeSignature :: TimeSignature
    , Measure -> KeySignature
keySignature :: KeySignature
    , Measure -> Maybe Tempo
tempoChange :: Maybe Tempo
    }
    deriving (Int -> Measure -> ShowS
[Measure] -> ShowS
Measure -> String
(Int -> Measure -> ShowS)
-> (Measure -> String) -> ([Measure] -> ShowS) -> Show Measure
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Measure -> ShowS
showsPrec :: Int -> Measure -> ShowS
$cshow :: Measure -> String
show :: Measure -> String
$cshowList :: [Measure] -> ShowS
showList :: [Measure] -> ShowS
Show, Measure -> Measure -> Bool
(Measure -> Measure -> Bool)
-> (Measure -> Measure -> Bool) -> Eq Measure
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Measure -> Measure -> Bool
== :: Measure -> Measure -> Bool
$c/= :: Measure -> Measure -> Bool
/= :: Measure -> Measure -> Bool
Eq)

{- | What a 'Track' is played on. 'Guitar' and 'Bass' are fretted
instruments described by their open-string 'tuning' (low to high) and
'stringCount'; their 'Note's are expected to carry 'noteString' \/
'noteFret'. 'Standard' is any non-fretted General MIDI instrument
addressed purely by 'MidiProgram', whose 'Note's carry only pitch data.
-}
data Instrument
    = Guitar {Instrument -> [Pitch]
tuning :: [Pitch], Instrument -> Int
stringCount :: Int}
    | Bass {tuning :: [Pitch], stringCount :: Int}
    | Standard MidiProgram
    deriving (Int -> Instrument -> ShowS
[Instrument] -> ShowS
Instrument -> String
(Int -> Instrument -> ShowS)
-> (Instrument -> String)
-> ([Instrument] -> ShowS)
-> Show Instrument
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Instrument -> ShowS
showsPrec :: Int -> Instrument -> ShowS
$cshow :: Instrument -> String
show :: Instrument -> String
$cshowList :: [Instrument] -> ShowS
showList :: [Instrument] -> ShowS
Show, Instrument -> Instrument -> Bool
(Instrument -> Instrument -> Bool)
-> (Instrument -> Instrument -> Bool) -> Eq Instrument
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Instrument -> Instrument -> Bool
== :: Instrument -> Instrument -> Bool
$c/= :: Instrument -> Instrument -> Bool
/= :: Instrument -> Instrument -> Bool
Eq)

{- | One instrument's part across the whole 'Song'. 'trackBeats' maps each
'MeasureIndex' that this track has content in to the ordered list of
'Beat's for that bar; a measure absent from the map is silent for this
track. 'trackChannel' is the MIDI channel used for playback.
-}
data Track = Track
    { Track -> Text
trackName :: Text
    , Track -> Instrument
trackInstrument :: Instrument
    , Track -> MidiChannel
trackChannel :: MidiChannel
    , Track -> Map MeasureIndex [Beat]
trackBeats :: Map MeasureIndex [Beat]
    }
    deriving (Int -> Track -> ShowS
[Track] -> ShowS
Track -> String
(Int -> Track -> ShowS)
-> (Track -> String) -> ([Track] -> ShowS) -> Show Track
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Track -> ShowS
showsPrec :: Int -> Track -> ShowS
$cshow :: Track -> String
show :: Track -> String
$cshowList :: [Track] -> ShowS
showList :: [Track] -> ShowS
Show, Track -> Track -> Bool
(Track -> Track -> Bool) -> (Track -> Track -> Bool) -> Eq Track
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Track -> Track -> Bool
== :: Track -> Track -> Bool
$c/= :: Track -> Track -> Bool
/= :: Track -> Track -> Bool
Eq)

{- | A complete tablature/score document: the master bar-by-bar timeline
('songMeasures') shared by every track, plus the per-instrument parts
('songTracks') that reference it via 'MeasureIndex'. 'songTempo' is the
default tempo, overridden per-bar by 'tempoChange'.
-}
data Song = Song
    { Song -> Text
songTitle :: Text
    , Song -> Text
songArtist :: Text
    , Song -> Tempo
songTempo :: Tempo
    , Song -> [Track]
songTracks :: [Track]
    , Song -> [Measure]
songMeasures :: [Measure]
    }
    deriving (Int -> Song -> ShowS
[Song] -> ShowS
Song -> String
(Int -> Song -> ShowS)
-> (Song -> String) -> ([Song] -> ShowS) -> Show Song
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Song -> ShowS
showsPrec :: Int -> Song -> ShowS
$cshow :: Song -> String
show :: Song -> String
$cshowList :: [Song] -> ShowS
showList :: [Song] -> ShowS
Show, Song -> Song -> Bool
(Song -> Song -> Bool) -> (Song -> Song -> Bool) -> Eq Song
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Song -> Song -> Bool
== :: Song -> Song -> Bool
$c/= :: Song -> Song -> Bool
/= :: Song -> Song -> Bool
Eq)

{- | A recognized-but-unhandled input file: 'unsupportedPath' is the file
that was read and 'unsupportedReason' explains what about its format
isn't supported (as opposed to the file simply being malformed, which is
'ParseErrorMalformed').
-}
data UnsupportedFormat = UnsupportedFormat
    { UnsupportedFormat -> String
unsupportedPath :: FilePath
    , UnsupportedFormat -> Text
unsupportedReason :: Text
    }
    deriving (Int -> UnsupportedFormat -> ShowS
[UnsupportedFormat] -> ShowS
UnsupportedFormat -> String
(Int -> UnsupportedFormat -> ShowS)
-> (UnsupportedFormat -> String)
-> ([UnsupportedFormat] -> ShowS)
-> Show UnsupportedFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> UnsupportedFormat -> ShowS
showsPrec :: Int -> UnsupportedFormat -> ShowS
$cshow :: UnsupportedFormat -> String
show :: UnsupportedFormat -> String
$cshowList :: [UnsupportedFormat] -> ShowS
showList :: [UnsupportedFormat] -> ShowS
Show, UnsupportedFormat -> UnsupportedFormat -> Bool
(UnsupportedFormat -> UnsupportedFormat -> Bool)
-> (UnsupportedFormat -> UnsupportedFormat -> Bool)
-> Eq UnsupportedFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UnsupportedFormat -> UnsupportedFormat -> Bool
== :: UnsupportedFormat -> UnsupportedFormat -> Bool
$c/= :: UnsupportedFormat -> UnsupportedFormat -> Bool
/= :: UnsupportedFormat -> UnsupportedFormat -> Bool
Eq)

{- | Failure result from a module in "Termtab.Parser.*". Distinguishes a
format that is understood but deliberately not supported
('ParseErrorUnsupported') from input that couldn't be parsed at all
('ParseErrorMalformed', carrying a human-readable description).
-}
data ParseError
    = ParseErrorUnsupported UnsupportedFormat
    | ParseErrorMalformed String
    deriving (Int -> ParseError -> ShowS
[ParseError] -> ShowS
ParseError -> String
(Int -> ParseError -> ShowS)
-> (ParseError -> String)
-> ([ParseError] -> ShowS)
-> Show ParseError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ParseError -> ShowS
showsPrec :: Int -> ParseError -> ShowS
$cshow :: ParseError -> String
show :: ParseError -> String
$cshowList :: [ParseError] -> ShowS
showList :: [ParseError] -> ShowS
Show)