packages feed

hsc3-0.20: Sound/Sc3/Common/Rate.hs

-- | Operating rate definitions and utilities.
module Sound.Sc3.Common.Rate where

import Data.Char {- base -}
import Data.Maybe {- base -}

-- | Enumeration of operating rates of unit generators.
data Rate = InitialisationRate | ControlRate | AudioRate | DemandRate
            deriving (Eq,Ord,Enum,Bounded,Show,Read)

{- | Standard abbreviations of Rate values.
ir = initialisation, kr = control, ar = audio, dr = demand.
dr sorts to the right of the fixed clock rates.

> Data.List.sort [dr,ar,kr,ir] == [ir,kr,ar,dr]
-}
ir, kr, ar, dr :: Rate
ir = InitialisationRate
kr = ControlRate
ar = AudioRate
dr = DemandRate

{- | Standard SuperCollider rate abbreviations.

> map rateAbbrev [minBound .. maxBound] == ["ir","kr","ar","dr"]
-}
rateAbbrev :: Rate -> String
rateAbbrev rt =
  fromMaybe (error "rateAbbrev?")
  (lookup (fromEnum rt) (zip [0..] (words "ir kr ar dr")))

{- | Standard SuperCollider rate abbreviations.

> map rateName [minBound .. maxBound] == ["scalar","control","audio","demand"]
-}
rateName :: Rate -> String
rateName rt =
  fromMaybe (error "rateName?")
  (lookup (fromEnum rt) (zip [0..] (words "scalar control audio demand")))

-- | Integer rate identifier, as required for scsynth bytecode.
rateId :: Rate -> Int
rateId = fromEnum

-- | Color identifiers for each 'Rate'.
rate_color :: Rate -> String
rate_color r =
    case r of
      AudioRate -> "black"
      ControlRate -> "blue"
      InitialisationRate -> "yellow"
      DemandRate -> "red"

-- | Set of all 'Rate' values.
all_rates :: [Rate]
all_rates = [minBound .. maxBound]

{- | Case insensitive parser for rate.

> Data.Maybe.mapMaybe rate_parse (words "ar kR IR Dr") == [AudioRate,ControlRate,InitialisationRate,DemandRate]
-}
rate_parse :: String -> Maybe Rate
rate_parse r =
    case map toUpper r of
      "AR" -> Just AudioRate
      "KR" -> Just ControlRate
      "IR" -> Just InitialisationRate
      "DR" -> Just DemandRate
      _ -> Nothing

-- * Control rates

{- | Enumeration of the four operating rates for controls.
I = initialisation, K = control, T = trigger, A = audio.
-}
data K_Type = K_InitialisationRate | K_ControlRate | K_TriggerRate | K_AudioRate
             deriving (Eq,Show,Ord)

-- | Determine class of control given 'Rate' and /trigger/ status.
ktype :: Rate -> Bool -> K_Type
ktype r tr =
    if tr
    then case r of
           ControlRate -> K_TriggerRate
           _ -> error "ktype: non ControlRate trigger control"
    else case r of
           InitialisationRate -> K_InitialisationRate
           ControlRate -> K_ControlRate
           AudioRate -> K_AudioRate
           DemandRate -> error "ktype: DemandRate control"