hsc3-0.19: Sound/SC3/Server/Param.hs
-- | Synthesis parameters
module Sound.SC3.Server.Param where
import Data.Function {- base -}
import Data.List {- base -}
import Data.Maybe {- base -}
import Data.List.Split {- split -}
import Sound.SC3.Common.Math {- hsc3 -}
-- | An SC3 synthesis parameters, ie. (control-name,control-value).
type Param1 = (String,Double)
-- | Set of SC3 synthesiser parameters.
type Param = [Param1]
-- | Add new, or overwrite existing, parameter.
param_insert :: Param -> Param1 -> Param
param_insert p z = z : deleteBy ((==) `on` fst) z p
-- | Merge, require keys be unique.
--
-- > param_merge_uniq [("a",1),("b",2)] [("c",3),("d",4)] == [("a",1),("b",2),("c",3),("d",4)]
-- > param_merge_uniq [("a",1)] [("a",2)] -- error
param_merge_uniq :: Param -> Param -> Param
param_merge_uniq p1 p2 =
case map fst p1 `intersect` map fst p2 of
[] -> p1 ++ p2
_ -> error "param_merge_uniq?"
-- | Merge, right biased.
--
-- > param_merge_r [("a",1),("b",2)] [("c",3),("a",4)] == [("b",2),("c",3),("a",4)]
param_merge_r :: Param -> Param -> Param
param_merge_r p1 p2 =
let p3 = let k2 = map fst p2 in filter (\(x,_) -> x `notElem` k2) p1
in p3 ++ p2
-- | Right-fold (right-biased) of 'param_merge'
--
-- > param_merge_r_seq [[("a",1),("b",2)],[("c",3),("a",4)],[("b",5)]] == [("c",3),("a",4),("b",5)]
param_merge_r_seq :: [Param] -> Param
param_merge_r_seq = foldr1 param_merge_r
-- | Lookup parameter value, with default.
param_get :: Param -> String -> Double -> Double
param_get p k v = fromMaybe v (lookup k p)
-- | Given (param-separator,key-value-separator) parse paramter string.
--
-- > param_parse (';','=') "a=1;b=2" == [("a",1),("b",2)]
param_parse :: (Char,Char) -> String -> Param
param_parse (c1,c2) str =
let f x = case splitOn [c2] x of
[lhs,rhs] -> (lhs,read rhs)
_ -> error ("param_parse: " ++ x)
in if null str then [] else map f (splitOn [c1] str)
-- | Inverse of 'param_parse', /k/ is the precision to print values to.
--
-- > param_pp (';','=') 4 [("a",1),("b",2)] == "a=1.0;b=2.0"
param_pp :: (Char,Char) -> Int -> Param -> String
param_pp (c1,c2) k =
let f (lhs,rhs) = concat [lhs,[c2],double_pp k rhs]
in intercalate [c1] . map f