module Data.Music.MusicXml.Score (
Score(..),
ScoreHeader(..),
Identification(..),
Creator(..),
Defaults(..),
ScoreAttrs(..),
PartAttrs(..),
MeasureAttrs(..),
PartList(..),
PartListElem(..),
GroupSymbol(..),
GroupBarlines(..),
Music(..),
MusicElem(..),
Attributes(..),
TimeSignature(..),
ClefSign(..),
Note(..),
FullNote(..),
IsChord,
noChord,
noTies,
Tie,
NoteProps(..),
HasNoteProps(..),
Notation(..),
FermataSign(..),
Articulation(..),
Ornament(..),
Technical(..),
Direction(..),
Lyric(..),
Pitch(..),
DisplayPitch(..),
PitchClass,
Semitones(..),
noSemitones,
Octaves(..),
Fifths(..),
Line(..),
Mode(..),
Accidental(..),
Duration(..),
NoteType(..),
Divs(..),
NoteVal(..),
NoteSize(..),
Beat(..),
BeatType(..),
Dynamics(..),
StemDirection(..),
NoteHead(..),
LineType(..),
Level(..),
BeamType(..),
StartStop(..),
StartStopChange(..),
StartStopContinue(..),
StartStopContinueChange(..),
) where
import Prelude hiding (getLine)
import Data.Default
import Data.Semigroup
import Data.Foldable
import Numeric.Natural
import TypeUnary.Nat
import Data.Music.MusicXml.Time
import Data.Music.MusicXml.Pitch
import Data.Music.MusicXml.Dynamics
import qualified Data.List as List
data Score
= Partwise
ScoreAttrs
ScoreHeader
[(PartAttrs,
[(MeasureAttrs, Music)])]
| Timewise
ScoreAttrs
ScoreHeader
[(MeasureAttrs,
[(PartAttrs, Music)])]
data ScoreHeader
= ScoreHeader
(Maybe String)
(Maybe String)
(Maybe Identification)
PartList
data Identification
= Identification
[Creator]
data Creator
= Creator
String
String
data Defaults
= Defaults
data ScoreAttrs
= ScoreAttrs
[Int]
data PartAttrs
= PartAttrs
String
data MeasureAttrs
= MeasureAttrs
Int
newtype PartList = PartList { getPartList :: [PartListElem] }
instance Default PartList where
def = PartList []
instance Semigroup PartList where
PartList xs <> PartList ys = PartList (setIds $ xs <> ys)
where
setIds = snd . List.mapAccumL setId partIds
setId id (Part _ name abbr dname dabbrev) = (tail id, Part (head id) name abbr dname dabbrev)
setId id x = (id, x)
partIds = [ "P" ++ show n | n <- [1..] ]
instance Monoid PartList where
mempty = def
mappend = (<>)
data PartListElem
= Part
String
String
(Maybe String)
(Maybe String)
(Maybe String)
| Group
Level
StartStop
String
(Maybe String)
(Maybe GroupSymbol)
(Maybe GroupBarlines)
Bool
data GroupSymbol = GroupBrace |GroupLine | GroupBracket |GroupSquare | NoGroupSymbol
data GroupBarlines = GroupBarLines | GroupNoBarLines |GroupMensurstrich
newtype Music = Music { getMusic :: [MusicElem] }
deriving (Semigroup, Monoid)
data MusicElem
= MusicAttributes
Attributes
| MusicBackup
Duration
| MusicForward
Duration
| MusicNote
Note
| MusicDirection
Direction
| MusicHarmony
| MusicFiguredBass
| MusicPrint
| MusicSound
| MusicBarline
| MusicGrouping
| MusicLink
| MusicBookmark
data Attributes
= Divisions
Divs
| Key
Fifths
Mode
| Time
TimeSignature
| Staves
Natural
| PartSymbol
| Instruments
Natural
| Clef
ClefSign
Line
| StaffDetails
| Transpose
| Directive
| MeasureStyle
data TimeSignature
= CommonTime
| CutTime
| DivTime
Beat
BeatType
data ClefSign
= GClef
| CClef
| FClef
| PercClef
| TabClef
deriving (Eq, Ord, Enum, Bounded)
data Note
= Note
FullNote
Duration
[Tie]
NoteProps
| CueNote
FullNote
Duration
NoteProps
| GraceNote
FullNote
[Tie]
NoteProps
data FullNote
= Pitched
IsChord
Pitch
| Unpitched
IsChord
(Maybe DisplayPitch)
| Rest
IsChord
(Maybe DisplayPitch)
type IsChord = Bool
type Tie = StartStop
data NoteProps
= NoteProps {
noteInstrument :: Maybe String,
noteVoice :: Maybe Natural,
noteType :: Maybe NoteType,
noteDots :: Natural,
noteAccidental :: Maybe (Accidental, Bool, Bool),
noteTimeMod :: Maybe (Natural, Natural),
noteStem :: Maybe StemDirection,
noteNoteHead :: Maybe (NoteHead, Bool, Bool),
noteNoteHeadText :: Maybe String,
noteStaff :: Maybe Natural,
noteBeam :: Maybe (Level, BeamType),
noteNotations :: [Notation],
noteLyrics :: [Lyric]
}
noChord :: IsChord
noChord = False
noTies :: [Tie]
noTies = []
class HasNoteProps a where
modifyNoteProps :: (NoteProps -> NoteProps) -> a -> a
instance HasNoteProps Note where
modifyNoteProps f (Note x d t p) = Note x d t (f p)
modifyNoteProps f (CueNote x d p) = CueNote x d (f p)
modifyNoteProps f (GraceNote x t p) = GraceNote x t (f p)
instance HasNoteProps MusicElem where
modifyNoteProps f (MusicNote n) = MusicNote (modifyNoteProps f n)
modifyNoteProps f x = x
data Notation
= Tied
StartStopContinue
| Slur
Level
StartStopContinue
| Tuplet
Level
StartStopContinue
| Glissando
Level
StartStopContinue
LineType
(Maybe String)
| Slide
Level
StartStopContinue
LineType
(Maybe String)
| Ornaments
[(Ornament, [Accidental])]
| Technical
[Technical]
| Articulations
[Articulation]
| DynamicNotation
Dynamics
| Fermata FermataSign
| Arpeggiate
| NonArpeggiate
| AccidentalMark
Accidental
| OtherNotation
String
data FermataSign = NormalFermata | AngledFermata | SquaredFermata
data Articulation
= Accent
| StrongAccent
| Staccato
| Tenuto
| DetachedLegato
| Staccatissimo
| Spiccato
| Scoop
| Plop
| Doit
| Falloff
| BreathMark
| Caesura
| Stress
| Unstress
| OtherArticulation
data Ornament
= TrillMark
| Turn
| DelayedTurn
| InvertedTurn
| DelayedInvertedTurn
| VerticalTurn
| Shake
| WavyLine
| Mordent
| InvertedMordent
| Schleifer
| Tremolo
Natural
| OtherOrnament
String
data Technical
= UpBow
| DownBow
| Harmonic
| OpenString
| ThumbPosition
| Fingering
| Pluck
| DoubleTongue
| TripleTongue
| Stopped
| SnapPizzicato
| Fret
| String
| HammerOn
| PullOff
| Bend
| Tap
| Heel
| Toe
| Fingernails
| Hole
| Arrow
| Handbell
| OtherTechnical
String
data Direction
= Rehearsal
String
| Segno
| Words
String
| Coda
| Crescendo
StartStop
| Diminuendo
StartStop
| Dynamics
Dynamics
| Dashes
Level
StartStop
| Bracket
| Pedal
StartStopChange
| Metronome
NoteVal
Bool
Tempo
| OctaveShift
| HarpPedals
| Damp
| DampAll
| EyeGlasses
| StringMute
| Scordatura
| Image
| PrincipalVoice
| AccordionRegistration
| Percussion
| OtherDirection
String
data Lyric = Lyric
newtype Level = Level { getLevel :: Max8 }
data BeamType
= BeginBeam
| ContinueBeam
| EndBeam
| ForwardHook
| BackwardHook
type StartStop = StartStopContinueChange
type StartStopChange = StartStopContinueChange
type StartStopContinue = StartStopContinueChange
data StartStopContinueChange
= Start
| Stop
| Continue
| Change
data StemDirection
= StemDown
| StemUp
| StemNone
| StemDouble
data LineType
= Solid
| Dashed
| Dotted
| Wavy
data NoteHead
= SlashNoteHead
| TriangleNoteHead
| DiamondNoteHead
| SquareNoteHead
| CrossNoteHead
| XNoteHead
| CircleXNoteHead
| InvertedTriangleNoteHead
| ArrowDownNoteHead
| ArrowUpNoteHead
| SlashedNoteHead
| BackSlashedNoteHead
| NormalNoteHead
| ClusterNoteHead
| CircleDotNoteHead
| LeftTriangleNoteHead
| RectangleNoteHead
| NoNoteHead
deriving instance Eq Level
deriving instance Show Level
deriving instance Num Level
type Max8 = Index N8
notImplemented x = error $ "Not implemented: " ++ x