packages feed

hsc3-0.20: Sound/Sc3/Ugen/Control.hs

-- | Control
module Sound.Sc3.Ugen.Control where

import Text.Printf {- base -}

import Sound.Sc3.Common.Rate {- hsc3 -}
import Sound.Sc3.Ugen.Brackets {- hsc3 -}

-- * Control Group

{- | Controls may form part of a control group.
There are presently three types of groups.
Ranges controls have two values (minima, maxima) and are ordinarily drawn as a range slider.
Array controls have n values [e1 .. eN] and are ordinarily drawn as a multislider.
Xy controls have two values (x, y) and are ordinarily drawn as a two dimensional slider.
-}
data Control_Group
  = Control_Range
  | Control_Array Int
  | Control_Xy
  deriving (Ord, Eq, Read, Show)

-- | The number of elements in a control group.
control_group_degree :: Control_Group -> Int
control_group_degree grp =
  case grp of
    Control_Range -> 2
    Control_Array n -> n
    Control_Xy -> 2

{- | Grouped controls have names that have equal prefixes and identifying suffixes.
     Range controls have two elements, minima and maxima, suffixes are [ and ].
     Array controls have n elements and have zero-indexed numerical suffixes.
     Xy controls have two elements, X and Y coordinates, suffixes are X and Y.
-}
control_group_suffixes :: Control_Group -> [String]
control_group_suffixes grp =
  case grp of
    Control_Range -> ["[","]"]
    Control_Array n -> map (printf "%02d") [0 .. n - 1]
    Control_Xy -> ["X","Y"]

-- * Control Meta

-- | Control meta-data.
data Control_Meta n =
    Control_Meta
    {ctl_min :: n -- ^ Minimum
    ,ctl_max :: n -- ^ Maximum
    ,ctl_warp :: String -- ^ @(0,1)@ @(min,max)@ transfer function.
    ,ctl_step :: n -- ^ The step to increment & decrement by.
    ,ctl_units :: String -- ^ Unit of measure (ie hz, ms etc.).
    ,controlGroup :: Maybe Control_Group} -- ^ Control group.
  deriving (Ord, Eq, Read, Show)

-- * Control Meta (T)

-- | 3-tuple form of 'Control_Meta' data.
type Control_Meta_T3 n = (n, n, String)

-- | Lift 'Control_Meta_T3' to 'Control_Meta' allowing type coercion.
control_meta_t3 :: Num m => (n -> m) -> Control_Meta_T3 n -> Control_Meta m
control_meta_t3 f (l,r,w) = Control_Meta (f l) (f r) w 0 "" Nothing

-- | 5-tuple form of 'Control_Meta' data.
type Control_Meta_T5 n = (n,n,String,n,String)

-- | Lift 'Control_Meta_T5' to 'Control_Meta' allowing type coercion.
control_meta_t5 :: (n -> m) -> Control_Meta_T5 n -> Control_Meta m
control_meta_t5 f (l,r,w,stp,u) = Control_Meta (f l) (f r) w (f stp) u Nothing

-- * Control

{- | Control inputs.
It is an unchecked invariant that controls with equal names within a Ugen graph must be equal in all other respects.
-}
data Control =
  Control
  {controlOperatingRate :: Rate
  ,controlIndex :: Maybe Int
  ,controlName :: String
  ,controlDefault :: Double
  ,controlTriggered :: Bool
  ,controlMeta :: Maybe (Control_Meta Double)
  ,controlBrackets :: Brackets}
  deriving (Ord, Eq, Read, Show)

{-
-- | Control type
data CVarTy = CVarInit | CVarControl | CVarTrigger deriving (Eq,Read,Show)
CVar CVarTy String Double -- ^ Control input (named)
-}