music-pitch-1.8: src/Music/Pitch/Ambitus.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
------------------------------------------------------------------------------------
-- |
-- Copyright : (c) Hans Hoglund, Edward Lilley 2012–2014
--
-- License : BSD-style
--
-- Maintainer : hans@hanshoglund.se
-- Stability : experimental
-- Portability : non-portable (TF,GNTD)
--
-- Musical ambitus, or pitch ranges.
--
-------------------------------------------------------------------------------------
module Music.Pitch.Ambitus where
import Data.Interval hiding (Interval, interval)
import qualified Data.Interval as I
import Control.Lens
-- | An ambitus is a closed interval (in the mathematical sense).
--
-- Also known as /range/ or /tessitura/, this type can be used to restrict the
-- range of a melody, chord or other pitch container.
--
-- It is also used in @music-parts@ to represent the range of instruments.
--
newtype Ambitus a = Ambitus { getAmbitus :: (I.Interval a) }
instance Wrapped (Ambitus a) where
type Unwrapped (Ambitus a) = I.Interval a
_Wrapped' = iso getAmbitus Ambitus
instance Rewrapped (Ambitus a) (Ambitus b)
instance (Show a, Num a, Ord a) => Show (Ambitus a) where
show a = show (a^.from ambitus) ++ "^.ambitus"
ambitus :: (Num a, Ord a) => Iso' (a, a) (Ambitus a)
ambitus = iso toA unA . _Unwrapped
where
toA = (\(m, n) -> (I.<=..<=) (Finite m) (Finite n))
unA a = case (I.lowerBound a, I.upperBound a) of
(Finite m, Finite n) -> (m, n)