module HarmTrace.Audio.AnnotationParser ( parseAnnotationData
, parseKeyAnnotationData
) where
import HarmTrace.Audio.DataParser (pNumData)
import HarmTrace.Base.MusicTime
import HarmTrace.Base.MusicRep
import HarmTrace.Base.Parsing
import HarmTrace.Base.ChordTokenizer ( pRoot, pChord)
parseAnnotationData :: Parser [TimedData ChordLabel]
parseAnnotationData = pListSep_ng pLineEnd pChordSegment <* pLineEnd
<* (pLineEnd `opt` "\n")
pChordSegment :: Parser (TimedData ChordLabel)
pChordSegment = timedData' <$> pNumData <* pSpaceTab
<*> pNumData <* pSpaceTab
<*> pChord
parseKeyAnnotationData :: Parser [TimedData Key]
parseKeyAnnotationData = noNoneKey <$> pListSep_ng pLineEnd pKeySegment
<* pLineEnd where
noNoneKey = filter ((/= Note Nothing N) . keyRoot . getData)
pKeySegment :: Parser (TimedData Key)
pKeySegment = timedData' <$> pNumData <* pSpaceTab
<*> pNumData <* pSpaceTab
<*> (pKey <|> pKeyNone)
pKey :: Parser Key
pKey = Key <$ pString "Key" <* pSpaceTab <*> pRoot <*> pMode
pKeyNone :: Parser Key
pKeyNone = Key (Note Nothing N) MajMode <$ pString "Silence"
pMode :: Parser Mode
pMode = MajMode <$ pString ""
<|> MinMode <$ pString ":minor"
<|> MinMode <$ pString ":aeolian"
<|> MajMode <$ pString ":major"
<|> MinMode <$ pString ":dorian"
<|> MajMode <$ pString ":mixolydian"
<|> MajMode <$ pString ":modal"
timedData' :: NumData -> NumData -> a -> TimedData a
timedData' on off chrd = TimedData chrd [Time on, Time off]
pSpaceTab :: Parser Char
pSpaceTab = pSym ' ' <|> pSym '\t'