hamusic-0.1: src/Music/Analysis/Abstract/Voices.lhs
\begin{code}
-- |
-- Maintainer : silva.samuel@alumni.uminho.pt
-- Stability : experimental
-- Portability: portable
-- This module implements multiple voices
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}
-- * Types
-- |
type MultiVoiceNode = ((VoiceZipNode, IntegerNumber), NotationNode)
type MultiVoiceAbsolute = ((VoiceZipAbsolute, IntegerNumber), NotationNode)
type MultiVoiceRelative = ((VoiceZipRelative, IntegerNumber), NotationNode)
-- | default settings
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 using above layers
transpose :: Number -> Motive MultiVoiceAbsolute -> Motive MultiVoiceAbsolute
transpose n =
mapMotive (const (uncurry joinVoices)) .
joinMotivePair . (id >< Notations.transpose n) . splitMotivePair .
mapMotive (const splitVoices)
-- | tempo transformation using above layers
tempo :: Number -> Motive MultiVoiceAbsolute -> Motive MultiVoiceAbsolute
tempo n =
mapMotive (const (uncurry joinVoices)) .
joinMotivePair . (id >< Notations.tempo n) . splitMotivePair .
mapMotive (const splitVoices)
-- | duration computation using above layers
duration :: Motive MultiVoiceNode -> Number
duration =
Notations.duration . p2 . splitMotivePair . mapMotive (const splitVoices)
-- | reverse using above layers
reverse :: Motive MultiVoiceNode -> Motive MultiVoiceNode
reverse =
mapMotive (const (uncurry joinVoices)) .
joinMotivePair . (id >< Notations.reverse) .
splitMotivePair .
mapMotive (const splitVoices)
-- | absolute transformation using above layers
absolute :: Motive MultiVoiceRelative -> Motive MultiVoiceAbsolute
absolute =
mapMotive (const (uncurry joinVoices)) .
joinMotivePair . (id >< Notations.absolute) . splitMotivePair .
mapMotive (const splitVoices)
-- | relative transformation using above layers
relative :: Motive MultiVoiceAbsolute -> Motive MultiVoiceRelative
relative =
mapMotive (const (uncurry joinVoices)) .
joinMotivePair . (id >< Notations.relative) . splitMotivePair .
mapMotive (const splitVoices)
\end{code}