\begin{code}
module Music.Analysis.Abstract.Voices where
import Music.Analysis.PF ((><), split, p1, p2)
import Music.Analysis.Base (Number, IntegerNumber)
import Music.Analysis.Abstract.Settings (Settings)
import Music.Analysis.Abstract.Motive
import Music.Analysis.Abstract.Zip
import Music.Analysis.Abstract.Notations as Notations
import Data.Function (id, (.), const)
import Data.Tuple (uncurry)
import Prelude ()
\end{code}
\begin{code}
type MultiVoiceNode = ((VoiceZipNode, IntegerNumber), NotationNode)
type MultiVoiceAbsolute = ((VoiceZipAbsolute, IntegerNumber), NotationNode)
type MultiVoiceRelative = ((VoiceZipRelative, IntegerNumber), NotationNode)
settings :: Settings
settings = Notations.settings
\end{code}
\begin{code}
joinVoices :: IntegerNumber -> (a, NotationNode) ->
((a, IntegerNumber), NotationNode)
joinVoices b = split (split p1 (const b)) p2
splitVoices :: ((a, IntegerNumber), NotationNode) ->
(IntegerNumber, (a, NotationNode))
splitVoices = split (p2 . p1) (split (p1 . p1) p2)
\end{code}
This are defined some combinators, like are transpose.
These functions are defined using functions from Notations module.
\begin{code}
transpose :: Number -> Motive MultiVoiceAbsolute -> Motive MultiVoiceAbsolute
transpose n =
mapMotive (const (uncurry joinVoices)) .
joinMotivePair . (id >< Notations.transpose n) . splitMotivePair .
mapMotive (const splitVoices)
tempo :: Number -> Motive MultiVoiceAbsolute -> Motive MultiVoiceAbsolute
tempo n =
mapMotive (const (uncurry joinVoices)) .
joinMotivePair . (id >< Notations.tempo n) . splitMotivePair .
mapMotive (const splitVoices)
duration :: Motive MultiVoiceNode -> Number
duration =
Notations.duration . p2 . splitMotivePair . mapMotive (const splitVoices)
reverse :: Motive MultiVoiceNode -> Motive MultiVoiceNode
reverse =
mapMotive (const (uncurry joinVoices)) .
joinMotivePair . (id >< Notations.reverse) .
splitMotivePair .
mapMotive (const splitVoices)
absolute :: Motive MultiVoiceRelative -> Motive MultiVoiceAbsolute
absolute =
mapMotive (const (uncurry joinVoices)) .
joinMotivePair . (id >< Notations.absolute) . splitMotivePair .
mapMotive (const splitVoices)
relative :: Motive MultiVoiceAbsolute -> Motive MultiVoiceRelative
relative =
mapMotive (const (uncurry joinVoices)) .
joinMotivePair . (id >< Notations.relative) . splitMotivePair .
mapMotive (const splitVoices)
\end{code}