module Data.Music.Sibelius (
SibeliusScore(..),
SibeliusStaff(..),
SibeliusSystemStaff(..),
SibeliusBar(..),
SibeliusBarObject(..),
isTimeSignature,
SibeliusChord(..),
SibeliusNote(..),
SibeliusSlur(..),
SibeliusCrescendoLine(..),
SibeliusDiminuendoLine(..),
SibeliusTuplet(..),
SibeliusArticulation(..),
readSibeliusArticulation,
SibeliusClef(..),
SibeliusKeySignature(..),
SibeliusTimeSignature(..),
SibeliusText(..),
) where
import Control.Monad.Plus
import Control.Applicative
import Data.Semigroup
import Data.Aeson
import qualified Data.HashMap.Strict as HashMap
data SibeliusScore = SibeliusScore {
scoreTitle :: String,
scoreComposer :: String,
scoreInformation :: String,
scoreStaffHeight :: Double,
scoreTransposing :: Bool,
scoreStaves :: [SibeliusStaff],
scoreSystemStaff :: SibeliusSystemStaff
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusScore where
parseJSON (Object v) = SibeliusScore
<$> v .: "title"
<*> v .: "composer"
<*> v .: "information"
<*> v .: "staffHeight"
<*> v .: "transposing"
<*> v .: "staves"
<*> v .: "systemStaff"
data SibeliusSystemStaff = SibeliusSystemStaff {
systemStaffBars :: [SibeliusBar]
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusSystemStaff where
parseJSON (Object v) = SibeliusSystemStaff
<$> v .: "bars"
data SibeliusStaff = SibeliusStaff {
staffBars :: [SibeliusBar],
staffName :: String,
staffShortName :: String
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusStaff where
parseJSON (Object v) = SibeliusStaff
<$> v .: "bars"
<*> v .: "name"
<*> v .: "shortName"
data SibeliusBar = SibeliusBar {
barElements :: [SibeliusBarObject]
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusBar where
parseJSON (Object v) = SibeliusBar
<$> v .: "elements"
data SibeliusBarObject
= SibeliusBarObjectText SibeliusText
| SibeliusBarObjectClef SibeliusClef
| SibeliusBarObjectSlur SibeliusSlur
| SibeliusBarObjectCrescendoLine SibeliusCrescendoLine
| SibeliusBarObjectDiminuendoLine SibeliusDiminuendoLine
| SibeliusBarObjectTimeSignature SibeliusTimeSignature
| SibeliusBarObjectKeySignature SibeliusKeySignature
| SibeliusBarObjectTuplet SibeliusTuplet
| SibeliusBarObjectChord SibeliusChord
| SibeliusBarObjectUnknown String
deriving (Eq, Ord, Show)
isTimeSignature (SibeliusBarObjectTimeSignature _) = True
isTimeSignature _ = False
instance FromJSON SibeliusBarObject where
parseJSON x@(Object v) = case HashMap.lookup "type" v of
Just "text" -> SibeliusBarObjectText <$> parseJSON x
Just "clef" -> SibeliusBarObjectClef <$> parseJSON x
Just "slur" -> SibeliusBarObjectSlur <$> parseJSON x
Just "cresc" -> SibeliusBarObjectCrescendoLine <$> parseJSON x
Just "dim" -> SibeliusBarObjectDiminuendoLine <$> parseJSON x
Just "time" -> SibeliusBarObjectTimeSignature <$> parseJSON x
Just "key" -> SibeliusBarObjectKeySignature <$> parseJSON x
Just "tuplet" -> SibeliusBarObjectTuplet <$> parseJSON x
Just "chord" -> SibeliusBarObjectChord <$> parseJSON x
Just typ -> SibeliusBarObjectUnknown <$> (return $ show typ)
_ -> mempty
data SibeliusText = SibeliusText {
textVoice :: Int,
textPosition :: Int,
textText :: String,
textStyle :: Maybe String
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusText where
parseJSON (Object v) = SibeliusText
<$> v .: "voice"
<*> v .: "position"
<*> v .: "text"
<*> v .:? "style"
data SibeliusClef = SibeliusClef {
clefVoice :: Int,
clefPosition :: Int,
clefStyle :: Maybe String
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusClef where
parseJSON (Object v) = SibeliusClef
<$> v .: "voice"
<*> v .: "position"
<*> v .: "style"
data SibeliusSlur = SibeliusSlur {
slurVoice :: Int,
slurPosition :: Int,
slurDuration :: Int,
slurStyle :: Maybe String
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusSlur where
parseJSON (Object v) = SibeliusSlur
<$> v .: "voice"
<*> v .: "position"
<*> v .: "duration"
<*> v .: "style"
data SibeliusCrescendoLine = SibeliusCrescendoLine {
crescVoice :: Int,
crescPosition :: Int,
crescDuration :: Int,
crescStyle :: Maybe String
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusCrescendoLine where
parseJSON (Object v) = SibeliusCrescendoLine
<$> v .: "voice"
<*> v .: "position"
<*> v .: "duration"
<*> v .: "style"
data SibeliusDiminuendoLine = SibeliusDiminuendoLine {
dimVoice :: Int,
dimPosition :: Int,
dimDuration :: Int,
dimStyle :: Maybe String
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusDiminuendoLine where
parseJSON (Object v) = SibeliusDiminuendoLine
<$> v .: "voice"
<*> v .: "position"
<*> v .: "duration"
<*> v .: "style"
data SibeliusTimeSignature = SibeliusTimeSignature {
timeVoice :: Int,
timePosition :: Int,
timeValue :: [Int],
timeIsCommon :: Bool,
timeIsAllaBreve :: Bool
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusTimeSignature where
parseJSON (Object v) = SibeliusTimeSignature
<$> v .: "voice"
<*> v .: "position"
<*> v .: "value"
<*> v .: "common"
<*> v .: "allaBreve"
data SibeliusKeySignature = SibeliusKeySignature {
keyVoice :: Int,
keyPosition :: Int,
keyMajor :: Bool,
keySharps :: Int,
keyIsOpen :: Bool
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusKeySignature where
parseJSON (Object v) = SibeliusKeySignature
<$> v .: "voice"
<*> v .: "position"
<*> v .: "major"
<*> v .: "sharps"
<*> v .: "isOpen"
data SibeliusTuplet = SibeliusTuplet {
tupletVoice :: Int,
tupletPosition :: Int,
tupletDuration :: Int,
tupletPlayedDuration :: Int,
tupletValue :: [Int]
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusTuplet where
parseJSON (Object v) = SibeliusTuplet
<$> v .: "voice"
<*> v .: "position"
<*> v .: "duration"
<*> v .: "playedDuration"
<*> v .: "value"
data SibeliusArticulation
= UpBow
| DownBow
| Plus
| Harmonic
| Marcato
| Accent
| Tenuto
| Wedge
| Staccatissimo
| Staccato
deriving (Eq, Ord, Show, Enum)
readSibeliusArticulation :: String -> Maybe SibeliusArticulation
readSibeliusArticulation = go
where
go "upbow" = Just UpBow
go "downBow" = Just DownBow
go "plus" = Just Plus
go "harmonic" = Just Harmonic
go "marcato" = Just Marcato
go "accent" = Just Accent
go "tenuto" = Just Tenuto
go "wedge" = Just Wedge
go "staccatissimo" = Just Staccatissimo
go "staccato" = Just Staccato
go _ = Nothing
data SibeliusChord = SibeliusChord {
chordPosition :: Int,
chordDuration :: Int,
chordVoice :: Int,
chordArticulations :: [SibeliusArticulation],
chordSingleTremolos :: Int,
chordDoubleTremolos :: Int,
chordAcciaccatura :: Bool,
chordAppoggiatura :: Bool,
chordNotes :: [SibeliusNote]
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusChord where
parseJSON (Object v) = SibeliusChord
<$> v .: "position"
<*> v .: "duration"
<*> v .: "voice"
<*> fmap (mmapMaybe readSibeliusArticulation) (v .: "articulations")
<*> v .: "singleTremolos"
<*> v .: "doubleTremolos"
<*> v .: "acciaccatura"
<*> v .: "appoggiatura"
<*> v .: "notes"
data SibeliusNote = SibeliusNote {
notePitch :: Int,
noteDiatonicPitch :: Int,
noteAccidental :: Int,
noteTied :: Bool,
noteStyle :: Maybe Int
}
deriving (Eq, Ord, Show)
instance FromJSON SibeliusNote where
parseJSON (Object v) = SibeliusNote
<$> v .: "pitch"
<*> v .: "diatonicPitch"
<*> v .: "accidental"
<*> v .: "tied"
<*> v .: "style"