Basic support for polyphonic ABC tunes.

Where voice headers are present in the tune body, partition it into seperate bodies, one for each voice.

In ABC, voices can be introduced like this:

V:1 abc ... def ... V:2 CDE ... EFG ....

or like this:

[V:1] abc ... [V:1] def ... [V:2] CDE ... [V:2] EFG

which means that we either have a self-standing voice header before each group of lines (which inherit this voice) or else we have an inline voice header defined explictly against each line.

Of course, there is nothing in the spec which prevents degenerate cases where both forms are present. In this case, we'll assume inline headers take precedence

The strategy is to fold over the tune structure in the State monad. State will be changed each time we come across a free-standing Voice header in the tune body. The current voice is this unless over-ridden by an inline voice.
The fold builds up a Map of Voices to partitioned ABC tune bodies

#getVoiceLabels Source

getVoiceLabels :: AbcTune -> Array String

given a tune, find all the different voice names (labels) no matter where they might be hiding

#getVoiceMap Source

getVoiceMap :: AbcTune -> Map String AbcTune

get a map of voice name to tune (filtering the body for just that tune voice) if there is no voice header, then the voice name is "unnamed" and attached to the entire tune. If voices are found, then the title of each partitioned voice tune is set to 'Voice voice-name'

#partitionVoices Source

partitionVoices :: AbcTune -> NonEmptyArray AbcTune

given a tune, partition it into multiple such tunes, one for each voice with the title of each partitioned tune set to the voice label where there are no voices, just return the singleton which contains the original tune

#partitionTuneBody Source

partitionTuneBody :: AbcTune -> NonEmptyArray TuneBody

given a tune, partition its body into multiple such bodies with a separate body for each distinct voice where there are no voices, just return the singleton which contains the original tune body