-- | Unit generator (Ugen) type and instances.
module Sound.Sc3.Ugen.Ugen where

import Data.Bits {- base -}
import qualified Data.Fixed as Fixed {- base -}
import Data.List {- base -}
import Data.Maybe {- base -}

import qualified System.Random as Random {- random -}

import qualified Sound.Sc3.Common.Math as Math
import Sound.Sc3.Common.Math.Operator
import Sound.Sc3.Common.Mce
import Sound.Sc3.Common.Rate

import Sound.Sc3.Ugen.Brackets
import Sound.Sc3.Ugen.Constant
import Sound.Sc3.Ugen.Control
import Sound.Sc3.Ugen.Label
import Sound.Sc3.Ugen.Mrg
import Sound.Sc3.Ugen.Primitive
import Sound.Sc3.Ugen.Proxy

-- * Basic types

{- | Sc3 samples are 32-bit 'Float'.
hsc3 uses 64-bit 'Double'.
If 'Ugen' values are used more generally (ie. see hsc3-forth) 'Float' may be too imprecise, i.e. for representing time stamps.
-}
type Sample = Double

-- | Union type of Unit Generator forms.
data Ugen
  = Constant_U Constant
  | Control_U Control
  | Label_U Label
  | Primitive_U (Primitive Ugen)
  | Proxy_U (Proxy Ugen)
  | Mce_U (Mce Ugen)
  | Mrg_U (Mrg Ugen)
  deriving (Ugen -> Ugen -> Bool
(Ugen -> Ugen -> Bool) -> (Ugen -> Ugen -> Bool) -> Eq Ugen
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Ugen -> Ugen -> Bool
== :: Ugen -> Ugen -> Bool
$c/= :: Ugen -> Ugen -> Bool
/= :: Ugen -> Ugen -> Bool
Eq, ReadPrec [Ugen]
ReadPrec Ugen
Int -> ReadS Ugen
ReadS [Ugen]
(Int -> ReadS Ugen)
-> ReadS [Ugen] -> ReadPrec Ugen -> ReadPrec [Ugen] -> Read Ugen
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Ugen
readsPrec :: Int -> ReadS Ugen
$creadList :: ReadS [Ugen]
readList :: ReadS [Ugen]
$creadPrec :: ReadPrec Ugen
readPrec :: ReadPrec Ugen
$creadListPrec :: ReadPrec [Ugen]
readListPrec :: ReadPrec [Ugen]
Read, Int -> Ugen -> ShowS
[Ugen] -> ShowS
Ugen -> String
(Int -> Ugen -> ShowS)
-> (Ugen -> String) -> ([Ugen] -> ShowS) -> Show Ugen
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Ugen -> ShowS
showsPrec :: Int -> Ugen -> ShowS
$cshow :: Ugen -> String
show :: Ugen -> String
$cshowList :: [Ugen] -> ShowS
showList :: [Ugen] -> ShowS
Show)

-- * Name

{- | Lookup operator name for operator Ugens, else Ugen name.

>>> map (\k -> ugen_user_name "BinaryOpUGen" (Special k)) [0, 2, 4, 9, 12, 17, 25]
["+","*","/",">","Min","Lcm","**"]
-}
ugen_user_name :: String -> Special -> String
ugen_user_name :: String -> Special -> String
ugen_user_name String
nm (Special Int
n) = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
nm (String -> Int -> Maybe String
ugen_operator_name String
nm Int
n)

-- * Instances

instance EqE Ugen where
  equal_to :: Ugen -> Ugen -> Ugen
equal_to = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpEq Double -> Double -> Double
forall n. (Num n, Eq n) => n -> n -> n
Math.sc3_eq
  not_equal_to :: Ugen -> Ugen -> Ugen
not_equal_to = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpNe Double -> Double -> Double
forall n. (Num n, Eq n) => n -> n -> n
Math.sc3_neq

instance OrdE Ugen where
  less_than :: Ugen -> Ugen -> Ugen
less_than = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpLt Double -> Double -> Double
forall n. (Num n, Ord n) => n -> n -> n
Math.sc3_lt
  less_than_or_equal_to :: Ugen -> Ugen -> Ugen
less_than_or_equal_to = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpLe Double -> Double -> Double
forall n. (Num n, Ord n) => n -> n -> n
Math.sc3_lte
  greater_than :: Ugen -> Ugen -> Ugen
greater_than = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpGt Double -> Double -> Double
forall n. (Num n, Ord n) => n -> n -> n
Math.sc3_gt
  greater_than_or_equal_to :: Ugen -> Ugen -> Ugen
greater_than_or_equal_to = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpGe Double -> Double -> Double
forall n. (Num n, Ord n) => n -> n -> n
Math.sc3_gte

-- | 'Ugen' form or 'Math.sc3_round_to'.
roundTo :: Ugen -> Ugen -> Ugen
roundTo :: Ugen -> Ugen -> Ugen
roundTo = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpRoundTo Double -> Double -> Double
forall n. RealFrac n => n -> n -> n
Math.sc3_round_to

instance RealFracE Ugen where
  properFractionE :: Ugen -> (Ugen, Ugen)
properFractionE = String -> Ugen -> (Ugen, Ugen)
forall a. HasCallStack => String -> a
error String
"Ugen.properFractionE"
  truncateE :: Ugen -> Ugen
truncateE = String -> Ugen -> Ugen
forall a. HasCallStack => String -> a
error String
"Ugen.truncateE"
  roundE :: Ugen -> Ugen
roundE Ugen
i = Ugen -> Ugen -> Ugen
roundTo Ugen
i Ugen
1
  ceilingE :: Ugen -> Ugen
ceilingE = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCeil Double -> Double
forall a. RealFracE a => a -> a
ceilingE
  floorE :: Ugen -> Ugen
floorE = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpFloor Double -> Double
forall a. RealFracE a => a -> a
floorE

instance UnaryOp Ugen where
  ampDb :: Ugen -> Ugen
ampDb = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpAmpDb Double -> Double
forall a. UnaryOp a => a -> a
ampDb
  asFloat :: Ugen -> Ugen
asFloat = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpAsFloat Double -> Double
forall a. UnaryOp a => a -> a
asFloat
  asInt :: Ugen -> Ugen
asInt = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpAsInt Double -> Double
forall a. UnaryOp a => a -> a
asInt
  cpsMidi :: Ugen -> Ugen
cpsMidi = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCpsMidi Double -> Double
forall a. UnaryOp a => a -> a
cpsMidi
  cpsOct :: Ugen -> Ugen
cpsOct = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCpsOct Double -> Double
forall a. UnaryOp a => a -> a
cpsOct
  cubed :: Ugen -> Ugen
cubed = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCubed Double -> Double
forall a. UnaryOp a => a -> a
cubed
  dbAmp :: Ugen -> Ugen
dbAmp = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpDbAmp Double -> Double
forall a. UnaryOp a => a -> a
dbAmp
  distort :: Ugen -> Ugen
distort = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpDistort Double -> Double
forall a. UnaryOp a => a -> a
distort
  frac :: Ugen -> Ugen
frac = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpFrac Double -> Double
forall a. UnaryOp a => a -> a
frac
  isNil :: Ugen -> Ugen
isNil = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpIsNil Double -> Double
forall a. UnaryOp a => a -> a
isNil
  log10 :: Ugen -> Ugen
log10 = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpLog10 Double -> Double
forall a. UnaryOp a => a -> a
log10
  log2 :: Ugen -> Ugen
log2 = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpLog2 Double -> Double
forall a. UnaryOp a => a -> a
log2
  midiCps :: Ugen -> Ugen
midiCps = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpMidiCps Double -> Double
forall a. UnaryOp a => a -> a
midiCps
  midiRatio :: Ugen -> Ugen
midiRatio = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpMidiRatio Double -> Double
forall a. UnaryOp a => a -> a
midiRatio
  notE :: Ugen -> Ugen
notE = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpNot Double -> Double
forall a. UnaryOp a => a -> a
notE
  notNil :: Ugen -> Ugen
notNil = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpNotNil Double -> Double
forall a. UnaryOp a => a -> a
notNil
  octCps :: Ugen -> Ugen
octCps = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpOctCps Double -> Double
forall a. UnaryOp a => a -> a
octCps
  ramp_ :: Ugen -> Ugen
ramp_ = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpRamp_ Double -> Double
forall a. UnaryOp a => a -> a
ramp_
  ratioMidi :: Ugen -> Ugen
ratioMidi = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpRatioMidi Double -> Double
forall a. UnaryOp a => a -> a
ratioMidi
  softClip :: Ugen -> Ugen
softClip = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSoftClip Double -> Double
forall a. UnaryOp a => a -> a
softClip
  squared :: Ugen -> Ugen
squared = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSquared Double -> Double
forall a. UnaryOp a => a -> a
squared

instance BinaryOp Ugen where
  iDiv :: Ugen -> Ugen -> Ugen
iDiv = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpIdiv Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
iDiv
  modE :: Ugen -> Ugen -> Ugen
modE = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpMod Double -> Double -> Double
forall a. Real a => a -> a -> a
Fixed.mod'
  lcmE :: Ugen -> Ugen -> Ugen
lcmE = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpLcm Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
lcmE
  gcdE :: Ugen -> Ugen -> Ugen
gcdE = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpGcd Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
gcdE
  roundUp :: Ugen -> Ugen -> Ugen
roundUp = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpRoundUp Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
roundUp
  trunc :: Ugen -> Ugen -> Ugen
trunc = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpTrunc Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
trunc
  atan2E :: Ugen -> Ugen -> Ugen
atan2E = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpAtan2 Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
atan2E
  hypot :: Ugen -> Ugen -> Ugen
hypot = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpHypot Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
hypot
  hypotx :: Ugen -> Ugen -> Ugen
hypotx = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpHypotx Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
hypotx
  fill :: Ugen -> Ugen -> Ugen
fill = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpFill Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
fill
  ring1 :: Ugen -> Ugen -> Ugen
ring1 = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpRing1 Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
ring1
  ring2 :: Ugen -> Ugen -> Ugen
ring2 = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpRing2 Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
ring2
  ring3 :: Ugen -> Ugen -> Ugen
ring3 = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpRing3 Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
ring3
  ring4 :: Ugen -> Ugen -> Ugen
ring4 = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpRing4 Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
ring4
  difSqr :: Ugen -> Ugen -> Ugen
difSqr = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpDifSqr Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
difSqr
  sumSqr :: Ugen -> Ugen -> Ugen
sumSqr = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpSumSqr Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
sumSqr
  sqrSum :: Ugen -> Ugen -> Ugen
sqrSum = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpSqrSum Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
sqrSum
  sqrDif :: Ugen -> Ugen -> Ugen
sqrDif = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpSqrDif Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
sqrDif
  absDif :: Ugen -> Ugen -> Ugen
absDif = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpAbsDif Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
absDif
  thresh :: Ugen -> Ugen -> Ugen
thresh = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpThresh Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
thresh
  amClip :: Ugen -> Ugen -> Ugen
amClip = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpAmClip Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
amClip
  scaleNeg :: Ugen -> Ugen -> Ugen
scaleNeg = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpScaleNeg Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
scaleNeg
  clip2 :: Ugen -> Ugen -> Ugen
clip2 = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpClip2 Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
clip2
  excess :: Ugen -> Ugen -> Ugen
excess = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpExcess Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
excess
  fold2 :: Ugen -> Ugen -> Ugen
fold2 = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpFold2 Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
fold2
  wrap2 :: Ugen -> Ugen -> Ugen
wrap2 = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpWrap2 Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
wrap2
  firstArg :: Ugen -> Ugen -> Ugen
firstArg = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpFirstArg Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
firstArg
  randRange :: Ugen -> Ugen -> Ugen
randRange = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpRandRange Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
randRange
  exprandRange :: Ugen -> Ugen -> Ugen
exprandRange = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpExpRandRange Double -> Double -> Double
forall a. BinaryOp a => a -> a -> a
exprandRange

-- instance MulAdd Ugen where mul_add = mulAdd

-- * Parser

-- | 'constant' of 'parse_double'.
parse_constant :: String -> Maybe Ugen
parse_constant :: String -> Maybe Ugen
parse_constant = (Double -> Ugen) -> Maybe Double -> Maybe Ugen
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Double -> Ugen
forall n. Real n => n -> Ugen
constant (Maybe Double -> Maybe Ugen)
-> (String -> Maybe Double) -> String -> Maybe Ugen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe Double
Math.parse_double

-- * Accessors

-- | See into 'Constant_U'.
un_constant :: Ugen -> Maybe Constant
un_constant :: Ugen -> Maybe Constant
un_constant Ugen
u =
  case Ugen
u of
    Constant_U Constant
c -> Constant -> Maybe Constant
forall a. a -> Maybe a
Just Constant
c
    Ugen
_ -> Maybe Constant
forall a. Maybe a
Nothing

-- | Value of 'Constant_U' 'Constant'.
u_constant :: Ugen -> Maybe Sample
u_constant :: Ugen -> Maybe Double
u_constant = (Constant -> Double) -> Maybe Constant -> Maybe Double
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Constant -> Double
constantValue (Maybe Constant -> Maybe Double)
-> (Ugen -> Maybe Constant) -> Ugen -> Maybe Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ugen -> Maybe Constant
un_constant

-- | Erroring variant.
u_constant_err :: Ugen -> Sample
u_constant_err :: Ugen -> Double
u_constant_err = Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe (String -> Double
forall a. HasCallStack => String -> a
error String
"u_constant") (Maybe Double -> Double)
-> (Ugen -> Maybe Double) -> Ugen -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ugen -> Maybe Double
u_constant

-- * Mrg

-- | Multiple root graph constructor.
mrg :: [Ugen] -> Ugen
mrg :: [Ugen] -> Ugen
mrg [Ugen]
u =
  case [Ugen]
u of
    [] -> String -> Ugen
forall a. HasCallStack => String -> a
error String
"mrg: []"
    [Ugen
x] -> Ugen
x
    (Ugen
x : [Ugen]
xs) -> Mrg Ugen -> Ugen
Mrg_U (Ugen -> Ugen -> Mrg Ugen
forall t. t -> t -> Mrg t
Mrg Ugen
x ([Ugen] -> Ugen
mrg [Ugen]
xs))

-- | See into 'Mrg_U', follows leftmost rule until arriving at non-Mrg node.
mrg_leftmost :: Ugen -> Ugen
mrg_leftmost :: Ugen -> Ugen
mrg_leftmost Ugen
u =
  case Ugen
u of
    Mrg_U Mrg Ugen
m -> Ugen -> Ugen
mrg_leftmost (Mrg Ugen -> Ugen
forall t. Mrg t -> t
mrgLeft Mrg Ugen
m)
    Ugen
_ -> Ugen
u

-- * Predicates

-- | Constant node predicate.
isConstant :: Ugen -> Bool
isConstant :: Ugen -> Bool
isConstant = Maybe Constant -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Constant -> Bool)
-> (Ugen -> Maybe Constant) -> Ugen -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ugen -> Maybe Constant
un_constant

-- | True if input is a sink 'Ugen', ie. has no outputs.  Sees into Mrg.
isSink :: Ugen -> Bool
isSink :: Ugen -> Bool
isSink Ugen
u =
  case Ugen -> Ugen
mrg_leftmost Ugen
u of
    Primitive_U Primitive Ugen
p -> [Rate] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Primitive Ugen -> [Rate]
forall t. Primitive t -> [Rate]
ugenOutputs Primitive Ugen
p)
    Mce_U Mce Ugen
m -> (Ugen -> Bool) -> [Ugen] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Ugen -> Bool
isSink (Mce Ugen -> [Ugen]
forall t. Mce t -> [t]
mce_to_list Mce Ugen
m)
    Ugen
_ -> Bool
False

-- | See into 'Proxy_U'.
un_proxy :: Ugen -> Maybe (Proxy Ugen)
un_proxy :: Ugen -> Maybe (Proxy Ugen)
un_proxy Ugen
u =
  case Ugen
u of
    Proxy_U Proxy Ugen
p -> Proxy Ugen -> Maybe (Proxy Ugen)
forall a. a -> Maybe a
Just Proxy Ugen
p
    Ugen
_ -> Maybe (Proxy Ugen)
forall a. Maybe a
Nothing

-- | Is 'Ugen' a 'Proxy'?
isProxy :: Ugen -> Bool
isProxy :: Ugen -> Bool
isProxy = Maybe (Proxy Ugen) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (Proxy Ugen) -> Bool)
-> (Ugen -> Maybe (Proxy Ugen)) -> Ugen -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ugen -> Maybe (Proxy Ugen)
un_proxy

-- | Get Primitive from Ugen if Ugen is a Primitive.
ugenPrimitive :: Ugen -> Maybe (Primitive Ugen)
ugenPrimitive :: Ugen -> Maybe (Primitive Ugen)
ugenPrimitive Ugen
u =
  case Ugen
u of
    Primitive_U Primitive Ugen
p -> Primitive Ugen -> Maybe (Primitive Ugen)
forall a. a -> Maybe a
Just Primitive Ugen
p
    Ugen
_ -> Maybe (Primitive Ugen)
forall a. Maybe a
Nothing

-- | Is 'Ugen' a 'Primitive'?
isPrimitive :: Ugen -> Bool
isPrimitive :: Ugen -> Bool
isPrimitive = Maybe (Primitive Ugen) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (Primitive Ugen) -> Bool)
-> (Ugen -> Maybe (Primitive Ugen)) -> Ugen -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ugen -> Maybe (Primitive Ugen)
ugenPrimitive

-- * Mce

-- | Multiple channel expansion node constructor.
mce :: [Ugen] -> Ugen
mce :: [Ugen] -> Ugen
mce [Ugen]
xs =
  case [Ugen]
xs of
    [] -> String -> Ugen
forall a. HasCallStack => String -> a
error String
"mce: []"
    [Ugen
x] -> Mce Ugen -> Ugen
Mce_U (Ugen -> Mce Ugen
forall t. t -> Mce t
Mce_Scalar Ugen
x)
    [Ugen]
_ -> Mce Ugen -> Ugen
Mce_U ([Ugen] -> Mce Ugen
forall t. [t] -> Mce t
mce_from_list [Ugen]
xs)

-- | Type specified 'mce_to_list'.
mceProxies :: Mce Ugen -> [Ugen]
mceProxies :: Mce Ugen -> [Ugen]
mceProxies = Mce Ugen -> [Ugen]
forall t. Mce t -> [t]
mce_to_list

-- | Multiple channel expansion node ('Mce_U') predicate.  Sees into Mrg.
isMce :: Ugen -> Bool
isMce :: Ugen -> Bool
isMce Ugen
u =
  case Ugen -> Ugen
mrg_leftmost Ugen
u of
    Mce_U Mce Ugen
_ -> Bool
True
    Ugen
_ -> Bool
False

{- | Output channels of Ugen as a list.
If required, preserves the RHS of an Mrg node in channel 0.
See also: mceChannel
-}
mceChannels :: Ugen -> [Ugen]
mceChannels :: Ugen -> [Ugen]
mceChannels Ugen
u =
  case Ugen
u of
    Mce_U Mce Ugen
m -> Mce Ugen -> [Ugen]
forall t. Mce t -> [t]
mce_to_list Mce Ugen
m
    Mrg_U (Mrg Ugen
x Ugen
y) ->
      case Ugen -> [Ugen]
mceChannels Ugen
x of
        Ugen
r : [Ugen]
rs -> Mrg Ugen -> Ugen
Mrg_U (Ugen -> Ugen -> Mrg Ugen
forall t. t -> t -> Mrg t
Mrg Ugen
r Ugen
y) Ugen -> [Ugen] -> [Ugen]
forall a. a -> [a] -> [a]
: [Ugen]
rs
        [Ugen]
_ -> String -> [Ugen]
forall a. HasCallStack => String -> a
error String
"mceChannels"
    Ugen
_ -> [Ugen
u]

-- | Number of channels to expand to.  This function sees into Mrg, and is defined only for Mce nodes.
mceDegree :: Ugen -> Maybe Int
mceDegree :: Ugen -> Maybe Int
mceDegree Ugen
u =
  case Ugen -> Ugen
mrg_leftmost Ugen
u of
    Mce_U Mce Ugen
m -> Int -> Maybe Int
forall a. a -> Maybe a
Just ([Ugen] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Mce Ugen -> [Ugen]
mceProxies Mce Ugen
m))
    Ugen
_ -> Maybe Int
forall a. Maybe a
Nothing

-- | Erroring variant.
mceDegree_err :: Ugen -> Int
mceDegree_err :: Ugen -> Int
mceDegree_err = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (String -> Int
forall a. HasCallStack => String -> a
error String
"mceDegree: not mce") (Maybe Int -> Int) -> (Ugen -> Maybe Int) -> Ugen -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ugen -> Maybe Int
mceDegree

-- | Extend Ugen to specified degree.  Follows "leftmost" rule for Mrg nodes.
mceExtend :: Int -> Ugen -> [Ugen]
mceExtend :: Int -> Ugen -> [Ugen]
mceExtend Int
n Ugen
u =
  case Ugen
u of
    Mce_U Mce Ugen
m -> Mce Ugen -> [Ugen]
mceProxies (Int -> Mce Ugen -> Mce Ugen
forall t. Int -> Mce t -> Mce t
mce_extend Int
n Mce Ugen
m)
    Mrg_U (Mrg Ugen
x Ugen
y) ->
      case Int -> Ugen -> [Ugen]
mceExtend Int
n Ugen
x of
        Ugen
r : [Ugen]
rs -> Mrg Ugen -> Ugen
Mrg_U (Ugen -> Ugen -> Mrg Ugen
forall t. t -> t -> Mrg t
Mrg Ugen
r Ugen
y) Ugen -> [Ugen] -> [Ugen]
forall a. a -> [a] -> [a]
: [Ugen]
rs
        [Ugen]
_ -> String -> [Ugen]
forall a. HasCallStack => String -> a
error String
"mceExtend"
    Ugen
_ -> Int -> Ugen -> [Ugen]
forall a. Int -> a -> [a]
replicate Int
n Ugen
u

-- | Is Mce required, ie. are any input values Mce?
mceRequired :: [Ugen] -> Bool
mceRequired :: [Ugen] -> Bool
mceRequired = (Ugen -> Bool) -> [Ugen] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Ugen -> Bool
isMce

{- | Apply Mce transform to a list of inputs.
The transform extends each input so all are of equal length, and then transposes the matrix.

>>> mceInputTransform [mce [1, 2],mce [3, 4]] == Just [[1,3],[2,4]]
True

>>> mceInputTransform [mce [1, 2],mce [3, 4], mce [5, 6, 7]] == Just [[1,3,5],[2,4,6],[1,3,7]]
True

>>> mceInputTransform [mce [mce [1, 2], mce [3, 4]], mce [5, 6]] == Just [[mce [1, 2],5],[mce [3, 4],6]]
True
-}
mceInputTransform :: [Ugen] -> Maybe [[Ugen]]
mceInputTransform :: [Ugen] -> Maybe [[Ugen]]
mceInputTransform [Ugen]
i =
  if [Ugen] -> Bool
mceRequired [Ugen]
i
    then
      let n :: Int
n = [Int] -> Int
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ((Ugen -> Int) -> [Ugen] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Ugen -> Int
mceDegree_err ((Ugen -> Bool) -> [Ugen] -> [Ugen]
forall a. (a -> Bool) -> [a] -> [a]
filter Ugen -> Bool
isMce [Ugen]
i))
      in [[Ugen]] -> Maybe [[Ugen]]
forall a. a -> Maybe a
Just ([[Ugen]] -> [[Ugen]]
forall a. [[a]] -> [[a]]
transpose ((Ugen -> [Ugen]) -> [Ugen] -> [[Ugen]]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Ugen -> [Ugen]
mceExtend Int
n) [Ugen]
i))
    else Maybe [[Ugen]]
forall a. Maybe a
Nothing

-- | Build a Ugen after Mce transformation of inputs.
mceBuild :: ([Ugen] -> Ugen) -> [Ugen] -> Ugen
mceBuild :: ([Ugen] -> Ugen) -> [Ugen] -> Ugen
mceBuild [Ugen] -> Ugen
f [Ugen]
i =
  case [Ugen] -> Maybe [[Ugen]]
mceInputTransform [Ugen]
i of
    Maybe [[Ugen]]
Nothing -> [Ugen] -> Ugen
f [Ugen]
i
    Just [[Ugen]]
i' -> let xs :: [Ugen]
xs = ([Ugen] -> Ugen) -> [[Ugen]] -> [Ugen]
forall a b. (a -> b) -> [a] -> [b]
map (([Ugen] -> Ugen) -> [Ugen] -> Ugen
mceBuild [Ugen] -> Ugen
f) [[Ugen]]
i' in Mce Ugen -> Ugen
Mce_U ([Ugen] -> Mce Ugen
forall t. [t] -> Mce t
mce_from_list [Ugen]
xs)

{- | True if Mce is an immediate proxy for a multiple-out Primitive.
This is useful when disassembling graphs, ie. ugen_graph_forth_pp at hsc3-db.
It's also useful when editing a Primitive after it is constructed, as in bracketUgen.
-}
mce_is_direct_proxy :: Mce Ugen -> Bool
mce_is_direct_proxy :: Mce Ugen -> Bool
mce_is_direct_proxy Mce Ugen
m =
  case Mce Ugen
m of
    Mce_Scalar Ugen
_ -> Bool
False
    Mce_Vector [Mce Ugen]
_ ->
      let p :: [Maybe (Proxy Ugen)]
p = (Ugen -> Maybe (Proxy Ugen)) -> [Ugen] -> [Maybe (Proxy Ugen)]
forall a b. (a -> b) -> [a] -> [b]
map Ugen -> Maybe (Proxy Ugen)
un_proxy (Mce Ugen -> [Ugen]
forall t. Mce t -> [t]
mce_to_list Mce Ugen
m)
          p' :: [Proxy Ugen]
p' = [Maybe (Proxy Ugen)] -> [Proxy Ugen]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (Proxy Ugen)]
p
      in (Maybe (Proxy Ugen) -> Bool) -> [Maybe (Proxy Ugen)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Maybe (Proxy Ugen) -> Bool
forall a. Maybe a -> Bool
isJust [Maybe (Proxy Ugen)]
p
          Bool -> Bool -> Bool
&& [Primitive Ugen] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Primitive Ugen] -> [Primitive Ugen]
forall a. Eq a => [a] -> [a]
nub ((Proxy Ugen -> Primitive Ugen) -> [Proxy Ugen] -> [Primitive Ugen]
forall a b. (a -> b) -> [a] -> [b]
map Proxy Ugen -> Primitive Ugen
forall t. Proxy t -> Primitive t
proxySource [Proxy Ugen]
p')) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
          Bool -> Bool -> Bool
&& (Proxy Ugen -> Int) -> [Proxy Ugen] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Proxy Ugen -> Int
forall t. Proxy t -> Int
proxyIndex [Proxy Ugen]
p' [Int] -> [Int] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [Int
0 ..]

-- * Bracketed

{- | Attach Brackets (initialisation and cleanup message sequences) to Ugen.
     For simplicity and clarity, brackets can only be attached to Primitive, Constant and Control nodes.
     This will look into the direct (immediate) proxies of a Primitive.
-}
bracketUgen :: Ugen -> Brackets -> Ugen
bracketUgen :: Ugen -> Brackets -> Ugen
bracketUgen Ugen
u ([Message]
pre, [Message]
post) =
  let err :: a
err = String -> a
forall a. HasCallStack => String -> a
error String
"bracketUgen: only Constants or Primitive Ugens or immediate proxies may have brackets"
      rw_proxy :: Ugen -> Ugen
rw_proxy Ugen
pxy =
        case Ugen
pxy of
          Proxy_U (Proxy Primitive Ugen
p Int
pix) ->
            let ([Message]
lhs, [Message]
rhs) = Primitive Ugen -> Brackets
forall t. Primitive t -> Brackets
primitiveBrackets Primitive Ugen
p in Proxy Ugen -> Ugen
Proxy_U (Primitive Ugen -> Int -> Proxy Ugen
forall t. Primitive t -> Int -> Proxy t
Proxy (Primitive Ugen
p {primitiveBrackets = (lhs ++ pre, rhs ++ post)}) Int
pix)
          Ugen
_ -> Ugen
forall {a}. a
err
  in case Ugen
u of
      Constant_U Constant
c -> let ([Message]
lhs, [Message]
rhs) = Constant -> Brackets
constantBrackets Constant
c in Constant -> Ugen
Constant_U (Constant
c {constantBrackets = (lhs ++ pre, rhs ++ post)})
      Control_U Control
c -> let ([Message]
lhs, [Message]
rhs) = Control -> Brackets
controlBrackets Control
c in Control -> Ugen
Control_U (Control
c {controlBrackets = (lhs ++ pre, rhs ++ post)})
      Primitive_U Primitive Ugen
p -> let ([Message]
lhs, [Message]
rhs) = Primitive Ugen -> Brackets
forall t. Primitive t -> Brackets
primitiveBrackets Primitive Ugen
p in Primitive Ugen -> Ugen
Primitive_U (Primitive Ugen
p {primitiveBrackets = (lhs ++ pre, rhs ++ post)})
      Mce_U Mce Ugen
m ->
        if Mce Ugen -> Bool
mce_is_direct_proxy Mce Ugen
m
          then Mce Ugen -> Ugen
Mce_U ((Ugen -> Ugen) -> Mce Ugen -> Mce Ugen
forall a b. (a -> b) -> Mce a -> Mce b
mce_map Ugen -> Ugen
rw_proxy Mce Ugen
m)
          else Ugen
forall {a}. a
err
      Ugen
_ -> Ugen
forall {a}. a
err

-- | Retrieve Brackets from Ugen.
ugenBrackets :: Ugen -> Brackets
ugenBrackets :: Ugen -> Brackets
ugenBrackets Ugen
u =
  case Ugen
u of
    Constant_U Constant
c -> Constant -> Brackets
constantBrackets Constant
c
    Control_U Control
c -> Control -> Brackets
controlBrackets Control
c
    Primitive_U Primitive Ugen
p -> Primitive Ugen -> Brackets
forall t. Primitive t -> Brackets
primitiveBrackets Primitive Ugen
p
    Ugen
_ -> Brackets
emptyBrackets

-- * Validators

-- | Ensure input 'Ugen' is valid, ie. not a sink.
checkInput :: Ugen -> Ugen
checkInput :: Ugen -> Ugen
checkInput Ugen
u =
  if Ugen -> Bool
isSink Ugen
u
    then String -> Ugen
forall a. HasCallStack => String -> a
error (String
"checkInput: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Ugen -> String
forall a. Show a => a -> String
show Ugen
u)
    else Ugen
u

-- * Constructors

-- | Constant value node constructor.
constant :: Real n => n -> Ugen
constant :: forall n. Real n => n -> Ugen
constant = Constant -> Ugen
Constant_U (Constant -> Ugen) -> (n -> Constant) -> n -> Ugen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Brackets -> Constant) -> Brackets -> Double -> Constant
forall a b c. (a -> b -> c) -> b -> a -> c
flip Double -> Brackets -> Constant
Constant Brackets
emptyBrackets (Double -> Constant) -> (n -> Double) -> n -> Constant
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac

-- | Type specialised 'constant'.
int_to_ugen :: Int -> Ugen
int_to_ugen :: Int -> Ugen
int_to_ugen = Int -> Ugen
forall n. Real n => n -> Ugen
constant

-- | Type specialised 'constant'.
float_to_ugen :: Float -> Ugen
float_to_ugen :: Float -> Ugen
float_to_ugen = Float -> Ugen
forall n. Real n => n -> Ugen
constant

-- | Type specialised 'constant'.
double_to_ugen :: Double -> Ugen
double_to_ugen :: Double -> Ugen
double_to_ugen = Double -> Ugen
forall n. Real n => n -> Ugen
constant

-- | Unit generator proxy node constructor.
proxy :: Ugen -> Int -> Ugen
proxy :: Ugen -> Int -> Ugen
proxy Ugen
u Int
n =
  case Ugen
u of
    Primitive_U Primitive Ugen
p -> Proxy Ugen -> Ugen
Proxy_U (Primitive Ugen -> Int -> Proxy Ugen
forall t. Primitive t -> Int -> Proxy t
Proxy Primitive Ugen
p Int
n)
    Ugen
_ -> String -> Ugen
forall a. HasCallStack => String -> a
error String
"proxy: not primitive?"

-- | Determine the rate of a Ugen.
rateOf :: Ugen -> Rate
rateOf :: Ugen -> Rate
rateOf Ugen
u =
  case Ugen
u of
    Constant_U Constant
_ -> Rate
InitialisationRate
    Control_U Control
c -> Control -> Rate
controlOperatingRate Control
c
    Label_U Label
_ -> Rate
InitialisationRate
    Primitive_U Primitive Ugen
p -> Primitive Ugen -> Rate
forall t. Primitive t -> Rate
ugenRate Primitive Ugen
p
    Proxy_U Proxy Ugen
p -> Primitive Ugen -> Rate
forall t. Primitive t -> Rate
ugenRate (Proxy Ugen -> Primitive Ugen
forall t. Proxy t -> Primitive t
proxySource Proxy Ugen
p)
    Mce_U Mce Ugen
_ -> [Rate] -> Rate
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ((Ugen -> Rate) -> [Ugen] -> [Rate]
forall a b. (a -> b) -> [a] -> [b]
map Ugen -> Rate
rateOf (Ugen -> [Ugen]
mceChannels Ugen
u))
    Mrg_U Mrg Ugen
m -> Ugen -> Rate
rateOf (Mrg Ugen -> Ugen
forall t. Mrg t -> t
mrgLeft Mrg Ugen
m)

-- | Apply proxy transformation if required.
proxify :: Ugen -> Ugen
proxify :: Ugen -> Ugen
proxify Ugen
u =
  case Ugen
u of
    Mce_U Mce Ugen
m -> [Ugen] -> Ugen
mce ((Ugen -> Ugen) -> [Ugen] -> [Ugen]
forall a b. (a -> b) -> [a] -> [b]
map Ugen -> Ugen
proxify (Mce Ugen -> [Ugen]
forall t. Mce t -> [t]
mce_to_list Mce Ugen
m))
    Mrg_U Mrg Ugen
m -> [Ugen] -> Ugen
mrg [Ugen -> Ugen
proxify (Mrg Ugen -> Ugen
forall t. Mrg t -> t
mrgLeft Mrg Ugen
m), Mrg Ugen -> Ugen
forall t. Mrg t -> t
mrgRight Mrg Ugen
m]
    Primitive_U Primitive Ugen
p ->
      let o :: [Rate]
o = Primitive Ugen -> [Rate]
forall t. Primitive t -> [Rate]
ugenOutputs Primitive Ugen
p
      in case [Rate]
o of
          Rate
_ : Rate
_ : [Rate]
_ -> [Ugen] -> Ugen
mce ((Int -> Ugen) -> [Int] -> [Ugen]
forall a b. (a -> b) -> [a] -> [b]
map (Ugen -> Int -> Ugen
proxy Ugen
u) [Int
0 .. [Rate] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Rate]
o Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1])
          [Rate]
_ -> Ugen
u
    Constant_U Constant
_ -> Ugen
u
    Ugen
_ -> String -> Ugen
forall a. HasCallStack => String -> a
error String
"proxify: illegal ugen"

{- | Filters with DemandRate inputs run at ControlRate.
This is a little unfortunate, it'd be nicer if the rate in this circumstance could be given.
-}
mk_ugen_select_rate :: String -> [Ugen] -> [Rate] -> Either Rate [Int] -> Rate
mk_ugen_select_rate :: String -> [Ugen] -> [Rate] -> Either Rate [Int] -> Rate
mk_ugen_select_rate String
nm [Ugen]
h [Rate]
rs Either Rate [Int]
r =
  let at_note :: String -> [a] -> Int -> a
at_note String
note [a]
list Int
index = if Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
index Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
list then String -> a
forall a. HasCallStack => String -> a
error String
note else [a]
list [a] -> Int -> a
forall a. HasCallStack => [a] -> Int -> a
!! Int
index -- hugs...
      is_right :: Either a b -> Bool
is_right Either a b
e = case Either a b
e of Right b
_ -> Bool
True; Either a b
_ -> Bool
False -- hugs...
      r' :: Rate
r' = (Rate -> Rate) -> ([Int] -> Rate) -> Either Rate [Int] -> Rate
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Rate -> Rate
forall a. a -> a
id ([Rate] -> Rate
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Rate] -> Rate) -> ([Int] -> [Rate]) -> [Int] -> Rate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Rate) -> [Int] -> [Rate]
forall a b. (a -> b) -> [a] -> [b]
map (Ugen -> Rate
rateOf (Ugen -> Rate) -> (Int -> Ugen) -> Int -> Rate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [Ugen] -> Int -> Ugen
forall {a}. String -> [a] -> Int -> a
at_note (String
"mkUgen: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
nm) [Ugen]
h)) Either Rate [Int]
r
  in if Either Rate [Int] -> Bool
forall {a} {b}. Either a b -> Bool
is_right Either Rate [Int]
r Bool -> Bool -> Bool
&& Rate
r' Rate -> Rate -> Bool
forall a. Eq a => a -> a -> Bool
== Rate
DemandRate Bool -> Bool -> Bool
&& Rate
DemandRate Rate -> [Rate] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Rate]
rs
      then if Rate
ControlRate Rate -> [Rate] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Rate]
rs then Rate
ControlRate else String -> Rate
forall a. HasCallStack => String -> a
error String
"mkUgen: DemandRate input to non-ControlRate filter"
      else
        if Rate
r' Rate -> [Rate] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Rate]
rs Bool -> Bool -> Bool
|| Rate
r' Rate -> Rate -> Bool
forall a. Eq a => a -> a -> Bool
== Rate
DemandRate
          then Rate
r'
          else String -> Rate
forall a. HasCallStack => String -> a
error (String
"mkUgen: rate restricted: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Either Rate [Int], Rate, [Rate], String) -> String
forall a. Show a => a -> String
show (Either Rate [Int]
r, Rate
r', [Rate]
rs, String
nm))

{- | Construct proxied and multiple channel expanded Ugen.

cf = constant function, rs = rate set, r = rate, nm = name, i = inputs, i_mce = list of Mce inputs, o = outputs.
-}
mkUgen ::
  Maybe ([Sample] -> Sample) ->
  [Rate] ->
  Either Rate [Int] ->
  String ->
  [Ugen] ->
  Maybe [Ugen] ->
  Int ->
  Special ->
  UgenId ->
  Ugen
mkUgen :: Maybe ([Double] -> Double)
-> [Rate]
-> Either Rate [Int]
-> String
-> [Ugen]
-> Maybe [Ugen]
-> Int
-> Special
-> UgenId
-> Ugen
mkUgen Maybe ([Double] -> Double)
cf [Rate]
rs Either Rate [Int]
r String
nm [Ugen]
i Maybe [Ugen]
i_mce Int
o Special
s UgenId
z =
  let i' :: [Ugen]
i' = [Ugen] -> ([Ugen] -> [Ugen]) -> Maybe [Ugen] -> [Ugen]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Ugen]
i (([Ugen]
i [Ugen] -> [Ugen] -> [Ugen]
forall a. [a] -> [a] -> [a]
++) ([Ugen] -> [Ugen]) -> ([Ugen] -> [Ugen]) -> [Ugen] -> [Ugen]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Ugen -> [Ugen]) -> [Ugen] -> [Ugen]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Ugen -> [Ugen]
mceChannels) Maybe [Ugen]
i_mce
      f :: [Ugen] -> Ugen
f [Ugen]
h =
        let r' :: Rate
r' = String -> [Ugen] -> [Rate] -> Either Rate [Int] -> Rate
mk_ugen_select_rate String
nm [Ugen]
h [Rate]
rs Either Rate [Int]
r
            o' :: [Rate]
o' = Int -> Rate -> [Rate]
forall a. Int -> a -> [a]
replicate Int
o Rate
r'
            u :: Ugen
u = Primitive Ugen -> Ugen
Primitive_U (Rate
-> String
-> [Ugen]
-> [Rate]
-> Special
-> UgenId
-> Brackets
-> Primitive Ugen
forall t.
Rate
-> String
-> [t]
-> [Rate]
-> Special
-> UgenId
-> Brackets
-> Primitive t
Primitive Rate
r' String
nm [Ugen]
h [Rate]
o' Special
s UgenId
z Brackets
emptyBrackets)
        in case Maybe ([Double] -> Double)
cf of
            Just [Double] -> Double
cf' ->
              if (Ugen -> Bool) -> [Ugen] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Ugen -> Bool
isConstant [Ugen]
h
                then Double -> Ugen
forall n. Real n => n -> Ugen
constant ([Double] -> Double
cf' ((Ugen -> Maybe Double) -> [Ugen] -> [Double]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Ugen -> Maybe Double
u_constant [Ugen]
h))
                else Ugen
u
            Maybe ([Double] -> Double)
Nothing -> Ugen
u
  in Ugen -> Ugen
proxify (([Ugen] -> Ugen) -> [Ugen] -> Ugen
mceBuild [Ugen] -> Ugen
f ((Ugen -> Ugen) -> [Ugen] -> [Ugen]
forall a b. (a -> b) -> [a] -> [b]
map Ugen -> Ugen
checkInput [Ugen]
i'))

-- * Operators

-- | Operator Ugen constructor.
mkOperator :: ([Sample] -> Sample) -> String -> [Ugen] -> Int -> Ugen
mkOperator :: ([Double] -> Double) -> String -> [Ugen] -> Int -> Ugen
mkOperator [Double] -> Double
f String
c [Ugen]
i Int
s =
  let ix :: [Int]
ix = [Int
0 .. [Ugen] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ugen]
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
  in Maybe ([Double] -> Double)
-> [Rate]
-> Either Rate [Int]
-> String
-> [Ugen]
-> Maybe [Ugen]
-> Int
-> Special
-> UgenId
-> Ugen
mkUgen (([Double] -> Double) -> Maybe ([Double] -> Double)
forall a. a -> Maybe a
Just [Double] -> Double
f) [Rate]
all_rates ([Int] -> Either Rate [Int]
forall a b. b -> Either a b
Right [Int]
ix) String
c [Ugen]
i Maybe [Ugen]
forall a. Maybe a
Nothing Int
1 (Int -> Special
Special Int
s) UgenId
NoId

-- | Unary math constructor.
mkUnaryOperator :: Sc3_Unary_Op -> (Sample -> Sample) -> Ugen -> Ugen
mkUnaryOperator :: Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
i Double -> Double
f Ugen
a =
  let g :: [Double] -> Double
g [Double
x] = Double -> Double
f Double
x
      g [Double]
_ = String -> Double
forall a. HasCallStack => String -> a
error String
"mkUnaryOperator: non unary input"
  in ([Double] -> Double) -> String -> [Ugen] -> Int -> Ugen
mkOperator [Double] -> Double
g String
"UnaryOpUGen" [Ugen
a] (Sc3_Unary_Op -> Int
forall a. Enum a => a -> Int
fromEnum Sc3_Unary_Op
i)

{- | Binary math constructor with constant optimisation.

>>> constant 2 * constant 3 == constant 6
True

>>> let o = mkUgen Nothing [AudioRate] (Left AudioRate) "SinOsc" [constant 440, constant 0] Nothing 1 (Special 0) (Uid 0)
>>> o * 1 == o && 1 * o == o && o * 2 /= o
True

>>> o + 0 == o && 0 + o == o && o + 1 /= o
True

>>> o - 0 == o && 0 - o /= o
True

>>> o / 1 == o && 1 / o /= o
True

>>> o ** 1 == o && o ** 2 /= o
True
-}
mkBinaryOperator_optimise_constants ::
  Sc3_Binary_Op ->
  (Sample -> Sample -> Sample) ->
  (Either Sample Sample -> Bool) ->
  Ugen ->
  Ugen ->
  Ugen
mkBinaryOperator_optimise_constants :: Sc3_Binary_Op
-> (Double -> Double -> Double)
-> (Either Double Double -> Bool)
-> Ugen
-> Ugen
-> Ugen
mkBinaryOperator_optimise_constants Sc3_Binary_Op
i Double -> Double -> Double
f Either Double Double -> Bool
o Ugen
a Ugen
b =
  let g :: [Double] -> Double
g [Double
x, Double
y] = Double -> Double -> Double
f Double
x Double
y
      g [Double]
_ = String -> Double
forall a. HasCallStack => String -> a
error String
"mkBinaryOperator: non binary input"
      r :: Maybe Ugen
r = case (Ugen
a, Ugen
b) of
        (Constant_U (Constant Double
a' ([], [])), Ugen
_) ->
          if Either Double Double -> Bool
o (Double -> Either Double Double
forall a b. a -> Either a b
Left Double
a') then Ugen -> Maybe Ugen
forall a. a -> Maybe a
Just Ugen
b else Maybe Ugen
forall a. Maybe a
Nothing
        (Ugen
_, Constant_U (Constant Double
b' ([], []))) ->
          if Either Double Double -> Bool
o (Double -> Either Double Double
forall a b. b -> Either a b
Right Double
b') then Ugen -> Maybe Ugen
forall a. a -> Maybe a
Just Ugen
a else Maybe Ugen
forall a. Maybe a
Nothing
        (Ugen, Ugen)
_ -> Maybe Ugen
forall a. Maybe a
Nothing
  in Ugen -> Maybe Ugen -> Ugen
forall a. a -> Maybe a -> a
fromMaybe (([Double] -> Double) -> String -> [Ugen] -> Int -> Ugen
mkOperator [Double] -> Double
g String
"BinaryOpUGen" [Ugen
a, Ugen
b] (Sc3_Binary_Op -> Int
forall a. Enum a => a -> Int
fromEnum Sc3_Binary_Op
i)) Maybe Ugen
r

-- | Plain (non-optimised) binary math constructor.
mkBinaryOperator :: Sc3_Binary_Op -> (Sample -> Sample -> Sample) -> Ugen -> Ugen -> Ugen
mkBinaryOperator :: Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
i Double -> Double -> Double
f Ugen
a Ugen
b =
  let g :: [Double] -> Double
g [Double
x, Double
y] = Double -> Double -> Double
f Double
x Double
y
      g [Double]
_ = String -> Double
forall a. HasCallStack => String -> a
error String
"mkBinaryOperator: non binary input"
  in ([Double] -> Double) -> String -> [Ugen] -> Int -> Ugen
mkOperator [Double] -> Double
g String
"BinaryOpUGen" [Ugen
a, Ugen
b] (Sc3_Binary_Op -> Int
forall a. Enum a => a -> Int
fromEnum Sc3_Binary_Op
i)

-- * Numeric instances

-- | Is /u/ the primitive for the named Ugen.
is_primitive_for :: String -> Ugen -> Bool
is_primitive_for :: String -> Ugen -> Bool
is_primitive_for String
k Ugen
u =
  case Ugen
u of
    Primitive_U (Primitive Rate
_ String
nm [Ugen
_, Ugen
_] [Rate
_] Special
_ UgenId
_ Brackets
_) -> String
nm String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
k
    Ugen
_ -> Bool
False

-- | Is /u/ the primitive for the named Ugen.
is_constant_of :: Sample -> Ugen -> Bool
is_constant_of :: Double -> Ugen -> Bool
is_constant_of Double
k Ugen
u =
  case Ugen
u of
    Constant_U Constant
c -> Constant -> Double
constantValue Constant
c Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
k
    Ugen
_ -> Bool
False

-- | Is /u/ a binary math operator with SPECIAL of /k/.
is_math_binop :: Int -> Ugen -> Bool
is_math_binop :: Int -> Ugen -> Bool
is_math_binop Int
k Ugen
u =
  case Ugen
u of
    Primitive_U (Primitive Rate
_ String
"BinaryOpUGen" [Ugen
_, Ugen
_] [Rate
_] (Special Int
s) UgenId
NoId Brackets
_) -> Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
k
    Ugen
_ -> Bool
False

-- | Is /u/ an ADD operator?
is_add_operator :: Ugen -> Bool
is_add_operator :: Ugen -> Bool
is_add_operator = Int -> Ugen -> Bool
is_math_binop Int
0

assert_is_add_operator :: String -> Ugen -> Ugen
assert_is_add_operator :: String -> Ugen -> Ugen
assert_is_add_operator String
msg Ugen
u = if Ugen -> Bool
is_add_operator Ugen
u then Ugen
u else String -> Ugen
forall a. HasCallStack => String -> a
error (String
"assert_is_add_operator: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg)

-- | Is /u/ an MUL operator?
is_mul_operator :: Ugen -> Bool
is_mul_operator :: Ugen -> Bool
is_mul_operator = Int -> Ugen -> Bool
is_math_binop Int
2

{- | MulAdd re-writer, applicable only directly at add operator Ugen.
The MulAdd Ugen is very sensitive to input rates.
Add=AudioRate with In|Mul=InitialisationRate|Const will crash scsynth.
This only considers primitives that do not have bracketing messages.
-}
mul_add_optimise_direct :: Ugen -> Ugen
mul_add_optimise_direct :: Ugen -> Ugen
mul_add_optimise_direct Ugen
u =
  let reorder :: (Ugen, Ugen, Ugen) -> Maybe (Rate, (Ugen, Ugen, Ugen))
reorder (Ugen
i, Ugen
j, Ugen
k) =
        let (Rate
ri, Rate
rj, Rate
rk) = (Ugen -> Rate
rateOf Ugen
i, Ugen -> Rate
rateOf Ugen
j, Ugen -> Rate
rateOf Ugen
k)
        in if Rate
rk Rate -> Rate -> Bool
forall a. Ord a => a -> a -> Bool
> Rate -> Rate -> Rate
forall a. Ord a => a -> a -> a
max Rate
ri Rate
rj
            then Maybe (Rate, (Ugen, Ugen, Ugen))
forall a. Maybe a
Nothing
            else (Rate, (Ugen, Ugen, Ugen)) -> Maybe (Rate, (Ugen, Ugen, Ugen))
forall a. a -> Maybe a
Just (Rate -> Rate -> Rate
forall a. Ord a => a -> a -> a
max (Rate -> Rate -> Rate
forall a. Ord a => a -> a -> a
max Rate
ri Rate
rj) Rate
rk, if Rate
rj Rate -> Rate -> Bool
forall a. Ord a => a -> a -> Bool
> Rate
ri then (Ugen
j, Ugen
i, Ugen
k) else (Ugen
i, Ugen
j, Ugen
k))
  in case String -> Ugen -> Ugen
assert_is_add_operator String
"MUL-ADD" Ugen
u of
      Primitive_U
        (Primitive Rate
_ String
_ [Primitive_U (Primitive Rate
_ String
"BinaryOpUGen" [Ugen
i, Ugen
j] [Rate
_] (Special Int
2) UgenId
NoId ([], [])), Ugen
k] [Rate
_] Special
_ UgenId
NoId ([], [])) ->
          case (Ugen, Ugen, Ugen) -> Maybe (Rate, (Ugen, Ugen, Ugen))
reorder (Ugen
i, Ugen
j, Ugen
k) of
            Just (Rate
rt, (Ugen
p, Ugen
q, Ugen
r)) -> Primitive Ugen -> Ugen
Primitive_U (Rate
-> String
-> [Ugen]
-> [Rate]
-> Special
-> UgenId
-> Brackets
-> Primitive Ugen
forall t.
Rate
-> String
-> [t]
-> [Rate]
-> Special
-> UgenId
-> Brackets
-> Primitive t
Primitive Rate
rt String
"MulAdd" [Ugen
p, Ugen
q, Ugen
r] [Rate
rt] (Int -> Special
Special Int
0) UgenId
NoId ([], []))
            Maybe (Rate, (Ugen, Ugen, Ugen))
Nothing -> Ugen
u
      Primitive_U
        (Primitive Rate
_ String
_ [Ugen
k, Primitive_U (Primitive Rate
_ String
"BinaryOpUGen" [Ugen
i, Ugen
j] [Rate
_] (Special Int
2) UgenId
NoId ([], []))] [Rate
_] Special
_ UgenId
NoId ([], [])) ->
          case (Ugen, Ugen, Ugen) -> Maybe (Rate, (Ugen, Ugen, Ugen))
reorder (Ugen
i, Ugen
j, Ugen
k) of
            Just (Rate
rt, (Ugen
p, Ugen
q, Ugen
r)) -> Primitive Ugen -> Ugen
Primitive_U (Rate
-> String
-> [Ugen]
-> [Rate]
-> Special
-> UgenId
-> Brackets
-> Primitive Ugen
forall t.
Rate
-> String
-> [t]
-> [Rate]
-> Special
-> UgenId
-> Brackets
-> Primitive t
Primitive Rate
rt String
"MulAdd" [Ugen
p, Ugen
q, Ugen
r] [Rate
rt] (Int -> Special
Special Int
0) UgenId
NoId ([], []))
            Maybe (Rate, (Ugen, Ugen, Ugen))
Nothing -> Ugen
u
      Ugen
_ -> Ugen
u

{- | MulAdd optimiser, applicable at any Ugen (ie. checks /u/ is an ADD ugen)

> import Sound.Sc3
> g1 = sinOsc ar 440 0 * 0.1 + control ir "x" 0.05
> g2 = sinOsc ar 440 0 * control ir "x" 0.1 + 0.05
> g3 = control ir "x" 0.1 * sinOsc ar 440 0 + 0.05
> g4 = 0.05 + sinOsc ar 440 0 * 0.1
-}
mul_add_optimise :: Ugen -> Ugen
mul_add_optimise :: Ugen -> Ugen
mul_add_optimise Ugen
u = if Ugen -> Bool
is_add_operator Ugen
u then Ugen -> Ugen
mul_add_optimise_direct Ugen
u else Ugen
u

{- | Sum3 re-writer, applicable only directly at add operator Ugen.
     This only considers nodes that have no bracketing messages.
-}
sum3_optimise_direct :: Ugen -> Ugen
sum3_optimise_direct :: Ugen -> Ugen
sum3_optimise_direct Ugen
u =
  case String -> Ugen -> Ugen
assert_is_add_operator String
"SUM3" Ugen
u of
    Primitive_U (Primitive Rate
r String
_ [Primitive_U (Primitive Rate
_ String
"BinaryOpUGen" [Ugen
i, Ugen
j] [Rate
_] (Special Int
0) UgenId
NoId ([], [])), Ugen
k] [Rate
_] Special
_ UgenId
NoId ([], [])) ->
      Primitive Ugen -> Ugen
Primitive_U (Rate
-> String
-> [Ugen]
-> [Rate]
-> Special
-> UgenId
-> Brackets
-> Primitive Ugen
forall t.
Rate
-> String
-> [t]
-> [Rate]
-> Special
-> UgenId
-> Brackets
-> Primitive t
Primitive Rate
r String
"Sum3" [Ugen
i, Ugen
j, Ugen
k] [Rate
r] (Int -> Special
Special Int
0) UgenId
NoId ([], []))
    Primitive_U (Primitive Rate
r String
_ [Ugen
k, Primitive_U (Primitive Rate
_ String
"BinaryOpUGen" [Ugen
i, Ugen
j] [Rate
_] (Special Int
0) UgenId
NoId ([], []))] [Rate
_] Special
_ UgenId
NoId ([], [])) ->
      Primitive Ugen -> Ugen
Primitive_U (Rate
-> String
-> [Ugen]
-> [Rate]
-> Special
-> UgenId
-> Brackets
-> Primitive Ugen
forall t.
Rate
-> String
-> [t]
-> [Rate]
-> Special
-> UgenId
-> Brackets
-> Primitive t
Primitive Rate
r String
"Sum3" [Ugen
i, Ugen
j, Ugen
k] [Rate
r] (Int -> Special
Special Int
0) UgenId
NoId ([], []))
    Ugen
_ -> Ugen
u

-- | /Sum3/ optimiser, applicable at any /u/ (ie. checks if /u/ is an ADD operator).
sum3_optimise :: Ugen -> Ugen
sum3_optimise :: Ugen -> Ugen
sum3_optimise Ugen
u = if Ugen -> Bool
is_add_operator Ugen
u then Ugen -> Ugen
sum3_optimise_direct Ugen
u else Ugen
u

-- | 'sum3_optimise' of 'mul_add_optimise'.
add_optimise :: Ugen -> Ugen
add_optimise :: Ugen -> Ugen
add_optimise = Ugen -> Ugen
sum3_optimise (Ugen -> Ugen) -> (Ugen -> Ugen) -> Ugen -> Ugen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ugen -> Ugen
mul_add_optimise

-- | Unit generators are numbers.
instance Num Ugen where
  negate :: Ugen -> Ugen
negate = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpNeg Double -> Double
forall a. Num a => a -> a
negate
  + :: Ugen -> Ugen -> Ugen
(+) =
    (Ugen -> Ugen) -> (Ugen -> Ugen) -> Ugen -> Ugen
forall a b. (a -> b) -> (Ugen -> a) -> Ugen -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Ugen -> Ugen
add_optimise
      ((Ugen -> Ugen) -> Ugen -> Ugen)
-> (Ugen -> Ugen -> Ugen) -> Ugen -> Ugen -> Ugen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sc3_Binary_Op
-> (Double -> Double -> Double)
-> (Either Double Double -> Bool)
-> Ugen
-> Ugen
-> Ugen
mkBinaryOperator_optimise_constants Sc3_Binary_Op
OpAdd Double -> Double -> Double
forall a. Num a => a -> a -> a
(+) (Either Double Double -> [Either Double Double] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Double -> Either Double Double
forall a b. a -> Either a b
Left Double
0, Double -> Either Double Double
forall a b. b -> Either a b
Right Double
0])
  (-) = Sc3_Binary_Op
-> (Double -> Double -> Double)
-> (Either Double Double -> Bool)
-> Ugen
-> Ugen
-> Ugen
mkBinaryOperator_optimise_constants Sc3_Binary_Op
OpSub (-) (Double -> Either Double Double
forall a b. b -> Either a b
Right Double
0 Either Double Double -> Either Double Double -> Bool
forall a. Eq a => a -> a -> Bool
==)
  * :: Ugen -> Ugen -> Ugen
(*) = Sc3_Binary_Op
-> (Double -> Double -> Double)
-> (Either Double Double -> Bool)
-> Ugen
-> Ugen
-> Ugen
mkBinaryOperator_optimise_constants Sc3_Binary_Op
OpMul Double -> Double -> Double
forall a. Num a => a -> a -> a
(*) (Either Double Double -> [Either Double Double] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Double -> Either Double Double
forall a b. a -> Either a b
Left Double
1, Double -> Either Double Double
forall a b. b -> Either a b
Right Double
1])
  abs :: Ugen -> Ugen
abs = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpAbs Double -> Double
forall a. Num a => a -> a
abs
  signum :: Ugen -> Ugen
signum = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSign Double -> Double
forall a. Num a => a -> a
signum
  fromInteger :: Integer -> Ugen
fromInteger = Constant -> Ugen
Constant_U (Constant -> Ugen) -> (Integer -> Constant) -> Integer -> Ugen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Brackets -> Constant) -> Brackets -> Double -> Constant
forall a b c. (a -> b -> c) -> b -> a -> c
flip Double -> Brackets -> Constant
Constant ([], []) (Double -> Constant) -> (Integer -> Double) -> Integer -> Constant
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Double
forall a. Num a => Integer -> a
fromInteger

-- | Unit generators are fractional.
instance Fractional Ugen where
  recip :: Ugen -> Ugen
recip = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpRecip Double -> Double
forall a. Fractional a => a -> a
recip
  / :: Ugen -> Ugen -> Ugen
(/) = Sc3_Binary_Op
-> (Double -> Double -> Double)
-> (Either Double Double -> Bool)
-> Ugen
-> Ugen
-> Ugen
mkBinaryOperator_optimise_constants Sc3_Binary_Op
OpFdiv Double -> Double -> Double
forall a. Fractional a => a -> a -> a
(/) (Double -> Either Double Double
forall a b. b -> Either a b
Right Double
1 Either Double Double -> Either Double Double -> Bool
forall a. Eq a => a -> a -> Bool
==)
  fromRational :: Rational -> Ugen
fromRational = Constant -> Ugen
Constant_U (Constant -> Ugen) -> (Rational -> Constant) -> Rational -> Ugen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Brackets -> Constant) -> Brackets -> Double -> Constant
forall a b c. (a -> b -> c) -> b -> a -> c
flip Double -> Brackets -> Constant
Constant ([], []) (Double -> Constant)
-> (Rational -> Double) -> Rational -> Constant
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Double
forall a. Fractional a => Rational -> a
fromRational

-- | Unit generators are floating point.
instance Floating Ugen where
  pi :: Ugen
pi = Constant -> Ugen
Constant_U (Double -> Brackets -> Constant
Constant Double
forall a. Floating a => a
pi ([], []))
  exp :: Ugen -> Ugen
exp = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpExp Double -> Double
forall a. Floating a => a -> a
exp
  log :: Ugen -> Ugen
log = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpLog Double -> Double
forall a. Floating a => a -> a
log
  sqrt :: Ugen -> Ugen
sqrt = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSqrt Double -> Double
forall a. Floating a => a -> a
sqrt
  ** :: Ugen -> Ugen -> Ugen
(**) = Sc3_Binary_Op
-> (Double -> Double -> Double)
-> (Either Double Double -> Bool)
-> Ugen
-> Ugen
-> Ugen
mkBinaryOperator_optimise_constants Sc3_Binary_Op
OpPow Double -> Double -> Double
forall a. Floating a => a -> a -> a
(**) (Double -> Either Double Double
forall a b. b -> Either a b
Right Double
1 Either Double Double -> Either Double Double -> Bool
forall a. Eq a => a -> a -> Bool
==)
  logBase :: Ugen -> Ugen -> Ugen
logBase Ugen
a Ugen
b = Ugen -> Ugen
forall a. Floating a => a -> a
log Ugen
b Ugen -> Ugen -> Ugen
forall a. Fractional a => a -> a -> a
/ Ugen -> Ugen
forall a. Floating a => a -> a
log Ugen
a
  sin :: Ugen -> Ugen
sin = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSin Double -> Double
forall a. Floating a => a -> a
sin
  cos :: Ugen -> Ugen
cos = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCos Double -> Double
forall a. Floating a => a -> a
cos
  tan :: Ugen -> Ugen
tan = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpTan Double -> Double
forall a. Floating a => a -> a
tan
  asin :: Ugen -> Ugen
asin = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpArcSin Double -> Double
forall a. Floating a => a -> a
asin
  acos :: Ugen -> Ugen
acos = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpArcCos Double -> Double
forall a. Floating a => a -> a
acos
  atan :: Ugen -> Ugen
atan = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpArcTan Double -> Double
forall a. Floating a => a -> a
atan
  sinh :: Ugen -> Ugen
sinh = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSinh Double -> Double
forall a. Floating a => a -> a
sinh
  cosh :: Ugen -> Ugen
cosh = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCosh Double -> Double
forall a. Floating a => a -> a
cosh
  tanh :: Ugen -> Ugen
tanh = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpTanh Double -> Double
forall a. Floating a => a -> a
tanh
  asinh :: Ugen -> Ugen
asinh Ugen
x = Ugen -> Ugen
forall a. Floating a => a -> a
log (Ugen -> Ugen
forall a. Floating a => a -> a
sqrt (Ugen
x Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
* Ugen
x Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
+ Ugen
1) Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
+ Ugen
x)
  acosh :: Ugen -> Ugen
acosh Ugen
x = Ugen -> Ugen
forall a. Floating a => a -> a
log (Ugen -> Ugen
forall a. Floating a => a -> a
sqrt (Ugen
x Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
* Ugen
x Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
- Ugen
1) Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
+ Ugen
x)
  atanh :: Ugen -> Ugen
atanh Ugen
x = (Ugen -> Ugen
forall a. Floating a => a -> a
log (Ugen
1 Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
+ Ugen
x) Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
- Ugen -> Ugen
forall a. Floating a => a -> a
log (Ugen
1 Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
- Ugen
x)) Ugen -> Ugen -> Ugen
forall a. Fractional a => a -> a -> a
/ Ugen
2

-- | Unit generators are real.
instance Real Ugen where
  toRational :: Ugen -> Rational
toRational (Constant_U (Constant Double
n ([], []))) = Double -> Rational
forall a. Real a => a -> Rational
toRational Double
n
  toRational Ugen
_ = String -> Rational
forall a. HasCallStack => String -> a
error String
"Ugen.toRational: only un-bracketed constants considered"

-- | Unit generators are integral.
instance Integral Ugen where
  quot :: Ugen -> Ugen -> Ugen
quot = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpIdiv (String -> Double -> Double -> Double
forall a. HasCallStack => String -> a
error String
"Ugen.quot")
  rem :: Ugen -> Ugen -> Ugen
rem = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpMod (String -> Double -> Double -> Double
forall a. HasCallStack => String -> a
error String
"Ugen.rem")
  quotRem :: Ugen -> Ugen -> (Ugen, Ugen)
quotRem Ugen
a Ugen
b = (Ugen -> Ugen -> Ugen
forall a. Integral a => a -> a -> a
quot Ugen
a Ugen
b, Ugen -> Ugen -> Ugen
forall a. Integral a => a -> a -> a
rem Ugen
a Ugen
b)
  div :: Ugen -> Ugen -> Ugen
div = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpIdiv (String -> Double -> Double -> Double
forall a. HasCallStack => String -> a
error String
"Ugen.div")
  mod :: Ugen -> Ugen -> Ugen
mod = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpMod (String -> Double -> Double -> Double
forall a. HasCallStack => String -> a
error String
"Ugen.mod")
  toInteger :: Ugen -> Integer
toInteger (Constant_U (Constant Double
n ([], []))) = Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
n
  toInteger Ugen
_ = String -> Integer
forall a. HasCallStack => String -> a
error String
"Ugen.toInteger: only un-bracketed constants considered"

instance RealFrac Ugen where
  properFraction :: forall b. Integral b => Ugen -> (b, Ugen)
properFraction = String -> Ugen -> (b, Ugen)
forall a. HasCallStack => String -> a
error String
"Ugen.properFraction, see properFractionE"
  round :: forall b. Integral b => Ugen -> b
round = String -> Ugen -> b
forall a. HasCallStack => String -> a
error String
"Ugen.round, see roundE"
  ceiling :: forall b. Integral b => Ugen -> b
ceiling = String -> Ugen -> b
forall a. HasCallStack => String -> a
error String
"Ugen.ceiling, see ceilingE"
  floor :: forall b. Integral b => Ugen -> b
floor = String -> Ugen -> b
forall a. HasCallStack => String -> a
error String
"Ugen.floor, see floorE"

{- | Unit generators are orderable (when 'Constants').

>>> constant 2 > constant 1
True
-}
instance Ord Ugen where
  (Constant_U Constant
a) < :: Ugen -> Ugen -> Bool
< (Constant_U Constant
b) = Constant
a Constant -> Constant -> Bool
forall a. Ord a => a -> a -> Bool
< Constant
b
  Ugen
_ < Ugen
_ = String -> Bool
forall a. HasCallStack => String -> a
error String
"Ugen.<, see <*"
  (Constant_U Constant
a) <= :: Ugen -> Ugen -> Bool
<= (Constant_U Constant
b) = Constant
a Constant -> Constant -> Bool
forall a. Ord a => a -> a -> Bool
<= Constant
b
  Ugen
_ <= Ugen
_ = String -> Bool
forall a. HasCallStack => String -> a
error String
"Ugen.<= at, see <=*"
  (Constant_U Constant
a) > :: Ugen -> Ugen -> Bool
> (Constant_U Constant
b) = Constant
a Constant -> Constant -> Bool
forall a. Ord a => a -> a -> Bool
> Constant
b
  Ugen
_ > Ugen
_ = String -> Bool
forall a. HasCallStack => String -> a
error String
"Ugen.>, see >*"
  (Constant_U Constant
a) >= :: Ugen -> Ugen -> Bool
>= (Constant_U Constant
b) = Constant
a Constant -> Constant -> Bool
forall a. Ord a => a -> a -> Bool
>= Constant
b
  Ugen
_ >= Ugen
_ = String -> Bool
forall a. HasCallStack => String -> a
error String
"Ugen.>=, see >=*"
  min :: Ugen -> Ugen -> Ugen
min = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpMin Double -> Double -> Double
forall a. Ord a => a -> a -> a
min
  max :: Ugen -> Ugen -> Ugen
max = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpMax Double -> Double -> Double
forall a. Ord a => a -> a -> a
max

-- | Unit generators are enumerable.
instance Enum Ugen where
  succ :: Ugen -> Ugen
succ Ugen
u = Ugen
u Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
+ Ugen
1
  pred :: Ugen -> Ugen
pred Ugen
u = Ugen
u Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
- Ugen
1
  toEnum :: Int -> Ugen
toEnum Int
n = Constant -> Ugen
Constant_U (Double -> Brackets -> Constant
Constant (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n) ([], []))
  fromEnum :: Ugen -> Int
fromEnum (Constant_U (Constant Double
n ([], []))) = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate Double
n
  fromEnum Ugen
_ = String -> Int
forall a. HasCallStack => String -> a
error String
"Ugen.fromEnum: non-constant"
  enumFrom :: Ugen -> [Ugen]
enumFrom = (Ugen -> Ugen) -> Ugen -> [Ugen]
forall a. (a -> a) -> a -> [a]
iterate (Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
+ Ugen
1)
  enumFromThen :: Ugen -> Ugen -> [Ugen]
enumFromThen Ugen
n Ugen
m = (Ugen -> Ugen) -> Ugen -> [Ugen]
forall a. (a -> a) -> a -> [a]
iterate (Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
+ (Ugen
m Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
- Ugen
n)) Ugen
n
  enumFromTo :: Ugen -> Ugen -> [Ugen]
enumFromTo Ugen
n Ugen
m = (Ugen -> Bool) -> [Ugen] -> [Ugen]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Ugen -> Ugen -> Bool
forall a. Ord a => a -> a -> Bool
<= Ugen
m Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
+ Ugen
1 Ugen -> Ugen -> Ugen
forall a. Fractional a => a -> a -> a
/ Ugen
2) (Ugen -> [Ugen]
forall a. Enum a => a -> [a]
enumFrom Ugen
n)
  enumFromThenTo :: Ugen -> Ugen -> Ugen -> [Ugen]
enumFromThenTo Ugen
n Ugen
n' Ugen
m =
    let p :: Ugen -> Ugen -> Bool
p = if Ugen
n' Ugen -> Ugen -> Bool
forall a. Ord a => a -> a -> Bool
>= Ugen
n then Ugen -> Ugen -> Bool
forall a. Ord a => a -> a -> Bool
(>=) else Ugen -> Ugen -> Bool
forall a. Ord a => a -> a -> Bool
(<=)
    in (Ugen -> Bool) -> [Ugen] -> [Ugen]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Ugen -> Ugen -> Bool
p (Ugen
m Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
+ (Ugen
n' Ugen -> Ugen -> Ugen
forall a. Num a => a -> a -> a
- Ugen
n) Ugen -> Ugen -> Ugen
forall a. Fractional a => a -> a -> a
/ Ugen
2)) (Ugen -> Ugen -> [Ugen]
forall a. Enum a => a -> a -> [a]
enumFromThen Ugen
n Ugen
n')

{- | Unit generators are stochastic.
Only un-bracketed constant values are considered.
-}
instance Random.Random Ugen where
  randomR :: forall g. RandomGen g => (Ugen, Ugen) -> g -> (Ugen, g)
randomR (Constant_U (Constant Double
l ([], [])), Constant_U (Constant Double
r ([], []))) g
g =
    let (Double
n, g
g') = (Double, Double) -> g -> (Double, g)
forall g. RandomGen g => (Double, Double) -> g -> (Double, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
Random.randomR (Double
l, Double
r) g
g
    in (Constant -> Ugen
Constant_U (Double -> Brackets -> Constant
Constant Double
n ([], [])), g
g')
  randomR (Ugen, Ugen)
_ g
_ = String -> (Ugen, g)
forall a. HasCallStack => String -> a
error String
"Ugen.randomR: non constant (l,r)"
  random :: forall g. RandomGen g => g -> (Ugen, g)
random = (Ugen, Ugen) -> g -> (Ugen, g)
forall g. RandomGen g => (Ugen, Ugen) -> g -> (Ugen, g)
forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g)
Random.randomR (-Ugen
1.0, Ugen
1.0)

-- * Bitwise

-- | 'Operator.OpBitAnd'
bitAnd :: Ugen -> Ugen -> Ugen
bitAnd :: Ugen -> Ugen -> Ugen
bitAnd = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpBitAnd Double -> Double -> Double
forall a. HasCallStack => a
undefined

-- | 'Operator.OpBitOr'
bitOr :: Ugen -> Ugen -> Ugen
bitOr :: Ugen -> Ugen -> Ugen
bitOr = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpBitOr Double -> Double -> Double
forall a. HasCallStack => a
undefined

-- | 'OpBitXor'
bitXOr :: Ugen -> Ugen -> Ugen
bitXOr :: Ugen -> Ugen -> Ugen
bitXOr = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpBitXor Double -> Double -> Double
forall a. HasCallStack => a
undefined

-- | 'OpBitNot'
bitNot :: Ugen -> Ugen
bitNot :: Ugen -> Ugen
bitNot = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpBitNot Double -> Double
forall a. HasCallStack => a
undefined

-- | 'OpShiftLeft'
shiftLeft :: Ugen -> Ugen -> Ugen
shiftLeft :: Ugen -> Ugen -> Ugen
shiftLeft = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpShiftLeft Double -> Double -> Double
forall a. HasCallStack => a
undefined

-- | 'OpShiftRight'
shiftRight :: Ugen -> Ugen -> Ugen
shiftRight :: Ugen -> Ugen -> Ugen
shiftRight = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpShiftRight Double -> Double -> Double
forall a. HasCallStack => a
undefined

-- | 'OpUnsignedShift'
unsignedShift :: Ugen -> Ugen -> Ugen
unsignedShift :: Ugen -> Ugen -> Ugen
unsignedShift = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpUnsignedShift Double -> Double -> Double
forall a. HasCallStack => a
undefined

-- | Ugens are bit patterns.
instance Bits Ugen where
  .&. :: Ugen -> Ugen -> Ugen
(.&.) = Ugen -> Ugen -> Ugen
bitAnd
  .|. :: Ugen -> Ugen -> Ugen
(.|.) = Ugen -> Ugen -> Ugen
bitOr
  xor :: Ugen -> Ugen -> Ugen
xor = Ugen -> Ugen -> Ugen
bitXOr
  complement :: Ugen -> Ugen
complement = Ugen -> Ugen
bitNot
  shiftL :: Ugen -> Int -> Ugen
shiftL Ugen
p Int
q = Ugen -> Ugen -> Ugen
shiftLeft Ugen
p (Int -> Ugen
forall n. Real n => n -> Ugen
constant Int
q)
  shiftR :: Ugen -> Int -> Ugen
shiftR Ugen
p Int
q = Ugen -> Ugen -> Ugen
shiftRight Ugen
p (Int -> Ugen
forall n. Real n => n -> Ugen
constant Int
q)
  rotate :: Ugen -> Int -> Ugen
rotate = String -> Ugen -> Int -> Ugen
forall a. HasCallStack => String -> a
error String
"Ugen.rotate"
  bitSize :: Ugen -> Int
bitSize = String -> Ugen -> Int
forall a. HasCallStack => String -> a
error String
"Ugen.bitSize"
  bit :: Int -> Ugen
bit = String -> Int -> Ugen
forall a. HasCallStack => String -> a
error String
"Ugen.bit"
  testBit :: Ugen -> Int -> Bool
testBit = String -> Ugen -> Int -> Bool
forall a. HasCallStack => String -> a
error String
"Ugen.testBit"
  popCount :: Ugen -> Int
popCount = String -> Ugen -> Int
forall a. HasCallStack => String -> a
error String
"Ugen.popCount" -- hugs...
  bitSizeMaybe :: Ugen -> Maybe Int
bitSizeMaybe = String -> Ugen -> Maybe Int
forall a. HasCallStack => String -> a
error String
"Ugen.bitSizeMaybe" -- hugs...
  isSigned :: Ugen -> Bool
isSigned Ugen
_ = Bool
True

{-
import qualified GHC.Exts as Exts {- base -}

instance Exts.IsList Ugen where
  type Item Ugen = Ugen
  fromList = mce
  toList = mceChannels
-}