-- | 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.Rate
import Sound.Sc3.Common.Mce

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
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Ugen -> Ugen -> Bool
$c/= :: Ugen -> Ugen -> Bool
== :: Ugen -> Ugen -> Bool
$c== :: Ugen -> Ugen -> Bool
Eq,ReadPrec [Ugen]
ReadPrec Ugen
Int -> ReadS Ugen
ReadS [Ugen]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Ugen]
$creadListPrec :: ReadPrec [Ugen]
readPrec :: ReadPrec Ugen
$creadPrec :: ReadPrec Ugen
readList :: ReadS [Ugen]
$creadList :: ReadS [Ugen]
readsPrec :: Int -> ReadS Ugen
$creadsPrec :: Int -> ReadS Ugen
Read,Int -> Ugen -> ShowS
[Ugen] -> ShowS
Ugen -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Ugen] -> ShowS
$cshowList :: [Ugen] -> ShowS
show :: Ugen -> String
$cshow :: Ugen -> String
showsPrec :: Int -> Ugen -> ShowS
$cshowsPrec :: Int -> Ugen -> ShowS
Show)

-- * Name

-- | Lookup operator name for operator Ugens, else Ugen name.
ugen_user_name :: String -> Special -> String
ugen_user_name :: String -> Special -> String
ugen_user_name String
nm (Special Int
n) = 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 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 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 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 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 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 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 forall n. RealFrac n => n -> n -> n
Math.sc3_round_to

instance RealFracE Ugen where
    properFractionE :: Ugen -> (Ugen, Ugen)
properFractionE = forall a. HasCallStack => String -> a
error String
"Ugen.properFractionE"
    truncateE :: Ugen -> Ugen
truncateE = 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 forall a. RealFracE a => a -> a
ceilingE
    floorE :: Ugen -> Ugen
floorE = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpFloor 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 forall a. UnaryOp a => a -> a
ampDb
    asFloat :: Ugen -> Ugen
asFloat = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpAsFloat forall a. UnaryOp a => a -> a
asFloat
    asInt :: Ugen -> Ugen
asInt = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpAsInt forall a. UnaryOp a => a -> a
asInt
    cpsMidi :: Ugen -> Ugen
cpsMidi = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCpsMidi forall a. UnaryOp a => a -> a
cpsMidi
    cpsOct :: Ugen -> Ugen
cpsOct = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCpsOct forall a. UnaryOp a => a -> a
cpsOct
    cubed :: Ugen -> Ugen
cubed = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCubed forall a. UnaryOp a => a -> a
cubed
    dbAmp :: Ugen -> Ugen
dbAmp = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpDbAmp forall a. UnaryOp a => a -> a
dbAmp
    distort :: Ugen -> Ugen
distort = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpDistort forall a. UnaryOp a => a -> a
distort
    frac :: Ugen -> Ugen
frac = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpFrac forall a. UnaryOp a => a -> a
frac
    isNil :: Ugen -> Ugen
isNil = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpIsNil forall a. UnaryOp a => a -> a
isNil
    log10 :: Ugen -> Ugen
log10 = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpLog10 forall a. UnaryOp a => a -> a
log10
    log2 :: Ugen -> Ugen
log2 = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpLog2 forall a. UnaryOp a => a -> a
log2
    midiCps :: Ugen -> Ugen
midiCps = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpMidiCps forall a. UnaryOp a => a -> a
midiCps
    midiRatio :: Ugen -> Ugen
midiRatio = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpMidiRatio forall a. UnaryOp a => a -> a
midiRatio
    notE :: Ugen -> Ugen
notE = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpNot forall a. UnaryOp a => a -> a
notE
    notNil :: Ugen -> Ugen
notNil = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpNotNil forall a. UnaryOp a => a -> a
notNil
    octCps :: Ugen -> Ugen
octCps = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpOctCps forall a. UnaryOp a => a -> a
octCps
    ramp_ :: Ugen -> Ugen
ramp_ = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpRamp_ forall a. UnaryOp a => a -> a
ramp_
    ratioMidi :: Ugen -> Ugen
ratioMidi = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpRatioMidi forall a. UnaryOp a => a -> a
ratioMidi
    softClip :: Ugen -> Ugen
softClip = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSoftClip forall a. UnaryOp a => a -> a
softClip
    squared :: Ugen -> Ugen
squared = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSquared 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall n. Real n => n -> Ugen
constant 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 -> forall a. a -> Maybe a
Just Constant
c
      Ugen
_ -> forall a. Maybe a
Nothing

-- | Value of 'Constant_U' 'Constant'.
u_constant :: Ugen -> Maybe Sample
u_constant :: Ugen -> Maybe Double
u_constant = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Constant -> Double
constantValue 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 = forall a. a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => String -> a
error String
"u_constant") 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
      [] -> forall a. HasCallStack => String -> a
error String
"mrg: []"
      [Ugen
x] -> Ugen
x
      (Ugen
x:[Ugen]
xs) -> Mrg Ugen -> Ugen
Mrg_U (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 (forall t. Mrg t -> t
mrgLeft Mrg Ugen
m)
      Ugen
_ -> Ugen
u

-- * Predicates

-- | Constant node predicate.
isConstant :: Ugen -> Bool
isConstant :: Ugen -> Bool
isConstant = forall a. Maybe a -> Bool
isJust 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 -> forall (t :: * -> *) a. Foldable t => t a -> Bool
null (forall t. Primitive t -> [Rate]
ugenOutputs Primitive Ugen
p)
      Mce_U Mce Ugen
m -> forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Ugen -> Bool
isSink (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 -> forall a. a -> Maybe a
Just Proxy Ugen
p
      Ugen
_ -> forall a. Maybe a
Nothing

-- | Is 'Ugen' a 'Proxy'?
isProxy :: Ugen -> Bool
isProxy :: Ugen -> Bool
isProxy = forall a. Maybe a -> Bool
isJust 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 -> forall a. a -> Maybe a
Just Primitive Ugen
p
    Ugen
_ -> forall a. Maybe a
Nothing

-- | Is 'Ugen' a 'Primitive'?
isPrimitive :: Ugen -> Bool
isPrimitive :: Ugen -> Bool
isPrimitive = forall a. Maybe a -> Bool
isJust 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
      [] -> forall a. HasCallStack => String -> a
error String
"mce: []"
      [Ugen
x] -> Mce Ugen -> Ugen
Mce_U (forall t. t -> Mce t
Mce_Scalar Ugen
x)
      [Ugen]
_ -> Mce Ugen -> Ugen
Mce_U (forall t. [t] -> Mce t
mce_from_list [Ugen]
xs)

-- | Type specified 'mce_to_list'.
mceProxies :: Mce Ugen -> [Ugen]
mceProxies :: Mce Ugen -> [Ugen]
mceProxies = 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 and Mrg node in channel 0.
mceChannels :: Ugen -> [Ugen]
mceChannels :: Ugen -> [Ugen]
mceChannels Ugen
u =
    case Ugen
u of
      Mce_U Mce Ugen
m -> forall t. Mce t -> [t]
mce_to_list Mce Ugen
m
      Mrg_U (Mrg Ugen
x Ugen
y) -> let Ugen
r:[Ugen]
rs = Ugen -> [Ugen]
mceChannels Ugen
x in Mrg Ugen -> Ugen
Mrg_U (forall t. t -> t -> Mrg t
Mrg Ugen
r Ugen
y) forall a. a -> [a] -> [a]
: [Ugen]
rs
      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 -> forall a. a -> Maybe a
Just (forall (t :: * -> *) a. Foldable t => t a -> Int
length (Mce Ugen -> [Ugen]
mceProxies Mce Ugen
m))
      Ugen
_ -> forall a. Maybe a
Nothing

-- | Erroring variant.
mceDegree_err :: Ugen -> Int
mceDegree_err :: Ugen -> Int
mceDegree_err = forall a. a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => String -> a
error String
"mceDegree: not mce") 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 (forall t. Int -> Mce t -> Mce t
mce_extend Int
n Mce Ugen
m)
      Mrg_U (Mrg Ugen
x Ugen
y) -> let (Ugen
r:[Ugen]
rs) = Int -> Ugen -> [Ugen]
mceExtend Int
n Ugen
x
                         in Mrg Ugen -> Ugen
Mrg_U (forall t. t -> t -> Mrg t
Mrg Ugen
r Ugen
y) forall a. a -> [a] -> [a]
: [Ugen]
rs
      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 = 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 [mce2 1 2,mce2 3 4] == Just [[1,3],[2,4]]
> mceInputTransform [mce2 1 2,mce2 3 4,mce3 5 6 7] == Just [[1,3,5],[2,4,6],[1,3,7]]
> mceInputTransform [mce2 (mce2 1 2) (mce2 3 4),mce2 5 6] == Just [[mce2 1 2,5],[mce2 3 4,6]]
-}
mceInputTransform :: [Ugen] -> Maybe [[Ugen]]
mceInputTransform :: [Ugen] -> Maybe [[Ugen]]
mceInputTransform [Ugen]
i =
    if [Ugen] -> Bool
mceRequired [Ugen]
i
    then let n :: Int
n = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (forall a b. (a -> b) -> [a] -> [b]
map Ugen -> Int
mceDegree_err (forall a. (a -> Bool) -> [a] -> [a]
filter Ugen -> Bool
isMce [Ugen]
i))
         in forall a. a -> Maybe a
Just (forall a. [[a]] -> [[a]]
transpose (forall a b. (a -> b) -> [a] -> [b]
map (Int -> Ugen -> [Ugen]
mceExtend Int
n) [Ugen]
i))
    else 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 = forall a b. (a -> b) -> [a] -> [b]
map (([Ugen] -> Ugen) -> [Ugen] -> Ugen
mceBuild [Ugen] -> Ugen
f) [[Ugen]]
i' in Mce Ugen -> Ugen
Mce_U (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 = forall a b. (a -> b) -> [a] -> [b]
map Ugen -> Maybe (Proxy Ugen)
un_proxy (forall t. Mce t -> [t]
mce_to_list Mce Ugen
m)
              p' :: [Proxy Ugen]
p' = forall a. [Maybe a] -> [a]
catMaybes [Maybe (Proxy Ugen)]
p
          in forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all forall a. Maybe a -> Bool
isJust [Maybe (Proxy Ugen)]
p Bool -> Bool -> Bool
&&
             forall (t :: * -> *) a. Foldable t => t a -> Int
length (forall a. Eq a => [a] -> [a]
nub (forall a b. (a -> b) -> [a] -> [b]
map forall t. Proxy t -> Primitive t
proxySource [Proxy Ugen]
p')) forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
&&
             forall a b. (a -> b) -> [a] -> [b]
map forall t. Proxy t -> Int
proxyIndex [Proxy Ugen]
p' 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 = 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) = forall t. Primitive t -> Brackets
primitiveBrackets Primitive Ugen
p in Proxy Ugen -> Ugen
Proxy_U (forall t. Primitive t -> Int -> Proxy t
Proxy (Primitive Ugen
p {primitiveBrackets :: Brackets
primitiveBrackets = ([Message]
lhs forall a. [a] -> [a] -> [a]
++ [Message]
pre, [Message]
rhs forall a. [a] -> [a] -> [a]
++ [Message]
post)}) Int
pix)
          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 :: Brackets
constantBrackets = ([Message]
lhs forall a. [a] -> [a] -> [a]
++ [Message]
pre, [Message]
rhs forall a. [a] -> [a] -> [a]
++ [Message]
post)})
       Control_U Control
c -> let ([Message]
lhs, [Message]
rhs) = Control -> Brackets
controlBrackets Control
c in Control -> Ugen
Control_U (Control
c {controlBrackets :: Brackets
controlBrackets = ([Message]
lhs forall a. [a] -> [a] -> [a]
++ [Message]
pre, [Message]
rhs forall a. [a] -> [a] -> [a]
++ [Message]
post)})
       Primitive_U Primitive Ugen
p -> let ([Message]
lhs, [Message]
rhs) = forall t. Primitive t -> Brackets
primitiveBrackets Primitive Ugen
p in Primitive Ugen -> Ugen
Primitive_U (Primitive Ugen
p {primitiveBrackets :: Brackets
primitiveBrackets = ([Message]
lhs forall a. [a] -> [a] -> [a]
++ [Message]
pre, [Message]
rhs forall a. [a] -> [a] -> [a]
++ [Message]
post)})
       Mce_U Mce Ugen
m ->
         if Mce Ugen -> Bool
mce_is_direct_proxy Mce Ugen
m
         then Mce Ugen -> Ugen
Mce_U (forall a b. (a -> b) -> Mce a -> Mce b
mce_map Ugen -> Ugen
rw_proxy Mce Ugen
m)
         else forall {a}. a
err
       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 -> 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 forall a. HasCallStack => String -> a
error (String
"checkInput: " forall a. [a] -> [a] -> [a]
++ 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip Double -> Brackets -> Constant
Constant Brackets
emptyBrackets forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall n. Real n => n -> Ugen
constant

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

-- | Type specialised 'constant'.
double_to_ugen :: Double -> Ugen
double_to_ugen :: Double -> Ugen
double_to_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 (forall t. Primitive t -> Int -> Proxy t
Proxy Primitive Ugen
p Int
n)
      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 -> forall t. Primitive t -> Rate
ugenRate Primitive Ugen
p
      Proxy_U Proxy Ugen
p -> forall t. Primitive t -> Rate
ugenRate (forall t. Proxy t -> Primitive t
proxySource Proxy Ugen
p)
      Mce_U Mce Ugen
_ -> forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (forall a b. (a -> b) -> [a] -> [b]
map Ugen -> Rate
rateOf (Ugen -> [Ugen]
mceChannels Ugen
u))
      Mrg_U Mrg Ugen
m -> Ugen -> Rate
rateOf (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 (forall a b. (a -> b) -> [a] -> [b]
map Ugen -> Ugen
proxify (forall t. Mce t -> [t]
mce_to_list Mce Ugen
m))
      Mrg_U Mrg Ugen
m -> [Ugen] -> Ugen
mrg [Ugen -> Ugen
proxify (forall t. Mrg t -> t
mrgLeft Mrg Ugen
m), forall t. Mrg t -> t
mrgRight Mrg Ugen
m]
      Primitive_U Primitive Ugen
p ->
          let o :: [Rate]
o = forall t. Primitive t -> [Rate]
ugenOutputs Primitive Ugen
p
          in case [Rate]
o of
               Rate
_:Rate
_:[Rate]
_ -> [Ugen] -> Ugen
mce (forall a b. (a -> b) -> [a] -> [b]
map (Ugen -> Int -> Ugen
proxy Ugen
u) [Int
0 .. forall (t :: * -> *) a. Foldable t => t a -> Int
length [Rate]
o forall a. Num a => a -> a -> a
- Int
1])
               [Rate]
_ -> Ugen
u
      Constant_U Constant
_ -> Ugen
u
      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 forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
index forall a. Ord a => a -> a -> Bool
>= forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
list then forall a. HasCallStack => String -> a
error String
note else [a]
list forall a. [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' = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> a
id (forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (Ugen -> Rate
rateOf forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a}. String -> [a] -> Int -> a
at_note (String
"mkUgen: " forall a. [a] -> [a] -> [a]
++ String
nm) [Ugen]
h)) Either Rate [Int]
r
  in if forall {a} {b}. Either a b -> Bool
is_right Either Rate [Int]
r Bool -> Bool -> Bool
&& Rate
r' forall a. Eq a => a -> a -> Bool
== Rate
DemandRate Bool -> Bool -> Bool
&& Rate
DemandRate forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Rate]
rs
     then if Rate
ControlRate forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Rate]
rs then Rate
ControlRate else forall a. HasCallStack => String -> a
error String
"mkUgen: DemandRate input to non-ControlRate filter"
     else if Rate
r' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Rate]
rs Bool -> Bool -> Bool
|| Rate
r' forall a. Eq a => a -> a -> Bool
== Rate
DemandRate
          then Rate
r'
          else forall a. HasCallStack => String -> a
error (String
"mkUgen: rate restricted: " forall a. [a] -> [a] -> [a]
++ 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' = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Ugen]
i (([Ugen]
i forall a. [a] -> [a] -> [a]
++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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' = forall a. Int -> a -> [a]
replicate Int
o Rate
r'
                  u :: Ugen
u = Primitive Ugen -> Ugen
Primitive_U (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 forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Ugen -> Bool
isConstant [Ugen]
h
                     then forall n. Real n => n -> Ugen
constant ([Double] -> Double
cf' (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 (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 .. forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ugen]
i 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 (forall a. a -> Maybe a
Just [Double] -> Double
f) [Rate]
all_rates (forall a b. b -> Either a b
Right [Int]
ix) String
c [Ugen]
i 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]
_ = 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] (forall a. Enum a => a -> Int
fromEnum Sc3_Unary_Op
i)

-- | Binary math constructor with constant optimisation.
--
-- > constant 2 * constant 3 == constant 6
--
-- > let o = sinOsc ar 440 0
--
-- > o * 1 == o && 1 * o == o && o * 2 /= o
-- > o + 0 == o && 0 + o == o && o + 1 /= o
-- > o - 0 == o && 0 - o /= o
-- > o / 1 == o && 1 / o /= o
-- > o ** 1 == o && o ** 2 /= o
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]
_ = 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 (forall a b. a -> Either a b
Left Double
a') then forall a. a -> Maybe a
Just Ugen
b else forall a. Maybe a
Nothing
             (Ugen
_,Constant_U (Constant Double
b' ([],[]))) ->
                 if Either Double Double -> Bool
o (forall a b. b -> Either a b
Right Double
b') then forall a. a -> Maybe a
Just Ugen
a else forall a. Maybe a
Nothing
             (Ugen, Ugen)
_ -> forall a. Maybe a
Nothing
   in forall a. a -> Maybe a -> a
fromMaybe (([Double] -> Double) -> String -> [Ugen] -> Int -> Ugen
mkOperator [Double] -> Double
g String
"BinaryOpUGen" [Ugen
a, Ugen
b] (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]
_ = 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] (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 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 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 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 forall a. HasCallStack => String -> a
error (String
"assert_is_add_operator: " 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 forall a. Ord a => a -> a -> Bool
> forall a. Ord a => a -> a -> a
max Rate
ri Rate
rj
           then forall a. Maybe a
Nothing
           else forall a. a -> Maybe a
Just (forall a. Ord a => a -> a -> a
max (forall a. Ord a => a -> a -> a
max Rate
ri Rate
rj) Rate
rk,if Rate
rj 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 (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 (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 (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 (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 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 forall a. Num a => a -> a
negate
    + :: Ugen -> Ugen -> Ugen
(+) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Ugen -> Ugen
add_optimise 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 forall a. Num a => a -> a -> a
(+) (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [forall a b. a -> Either a b
Left Double
0,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 (-) (forall a b. b -> Either a b
Right Double
0 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 forall a. Num a => a -> a -> a
(*) (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [forall a b. a -> Either a b
Left Double
1,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 forall a. Num a => a -> a
abs
    signum :: Ugen -> Ugen
signum = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSign forall a. Num a => a -> a
signum
    fromInteger :: Integer -> Ugen
fromInteger = Constant -> Ugen
Constant_U forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip Double -> Brackets -> Constant
Constant ([],[]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 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 forall a. Fractional a => a -> a -> a
(/) (forall a b. b -> Either a b
Right Double
1 forall a. Eq a => a -> a -> Bool
==)
    fromRational :: Rational -> Ugen
fromRational = Constant -> Ugen
Constant_U forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip Double -> Brackets -> Constant
Constant ([],[]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 forall a. Floating a => a
pi ([],[]))
    exp :: Ugen -> Ugen
exp = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpExp forall a. Floating a => a -> a
exp
    log :: Ugen -> Ugen
log = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpLog forall a. Floating a => a -> a
log
    sqrt :: Ugen -> Ugen
sqrt = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSqrt 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 forall a. Floating a => a -> a -> a
(**) (forall a b. b -> Either a b
Right Double
1 forall a. Eq a => a -> a -> Bool
==)
    logBase :: Ugen -> Ugen -> Ugen
logBase Ugen
a Ugen
b = forall a. Floating a => a -> a
log Ugen
b forall a. Fractional a => a -> a -> a
/ 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 forall a. Floating a => a -> a
sin
    cos :: Ugen -> Ugen
cos = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCos forall a. Floating a => a -> a
cos
    tan :: Ugen -> Ugen
tan = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpTan forall a. Floating a => a -> a
tan
    asin :: Ugen -> Ugen
asin = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpArcSin forall a. Floating a => a -> a
asin
    acos :: Ugen -> Ugen
acos = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpArcCos forall a. Floating a => a -> a
acos
    atan :: Ugen -> Ugen
atan = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpArcTan forall a. Floating a => a -> a
atan
    sinh :: Ugen -> Ugen
sinh = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpSinh forall a. Floating a => a -> a
sinh
    cosh :: Ugen -> Ugen
cosh = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpCosh forall a. Floating a => a -> a
cosh
    tanh :: Ugen -> Ugen
tanh = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpTanh forall a. Floating a => a -> a
tanh
    asinh :: Ugen -> Ugen
asinh Ugen
x = forall a. Floating a => a -> a
log (forall a. Floating a => a -> a
sqrt (Ugen
xforall a. Num a => a -> a -> a
*Ugen
xforall a. Num a => a -> a -> a
+Ugen
1) forall a. Num a => a -> a -> a
+ Ugen
x)
    acosh :: Ugen -> Ugen
acosh Ugen
x = forall a. Floating a => a -> a
log (forall a. Floating a => a -> a
sqrt (Ugen
xforall a. Num a => a -> a -> a
*Ugen
xforall a. Num a => a -> a -> a
-Ugen
1) forall a. Num a => a -> a -> a
+ Ugen
x)
    atanh :: Ugen -> Ugen
atanh Ugen
x = (forall a. Floating a => a -> a
log (Ugen
1forall a. Num a => a -> a -> a
+Ugen
x) forall a. Num a => a -> a -> a
- forall a. Floating a => a -> a
log (Ugen
1forall a. Num a => a -> a -> a
-Ugen
x)) 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 ([],[]))) = forall a. Real a => a -> Rational
toRational Double
n
    toRational Ugen
_ = 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 (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 (forall a. HasCallStack => String -> a
error String
"Ugen.rem")
    quotRem :: Ugen -> Ugen -> (Ugen, Ugen)
quotRem Ugen
a Ugen
b = (forall a. Integral a => a -> a -> a
quot Ugen
a Ugen
b, 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 (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 (forall a. HasCallStack => String -> a
error String
"Ugen.mod")
    toInteger :: Ugen -> Integer
toInteger (Constant_U (Constant Double
n ([],[]))) = forall a b. (RealFrac a, Integral b) => a -> b
floor Double
n
    toInteger Ugen
_ = 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 = forall a. HasCallStack => String -> a
error String
"Ugen.properFraction, see properFractionE"
  round :: forall b. Integral b => Ugen -> b
round = forall a. HasCallStack => String -> a
error String
"Ugen.round, see roundE"
  ceiling :: forall b. Integral b => Ugen -> b
ceiling = forall a. HasCallStack => String -> a
error String
"Ugen.ceiling, see ceilingE"
  floor :: forall b. Integral b => Ugen -> b
floor = 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 forall a. Ord a => a -> a -> Bool
< Constant
b
    Ugen
_ < Ugen
_ = forall a. HasCallStack => String -> a
error String
"Ugen.<, see <*"
    (Constant_U Constant
a) <= :: Ugen -> Ugen -> Bool
<= (Constant_U Constant
b) = Constant
a forall a. Ord a => a -> a -> Bool
<= Constant
b
    Ugen
_ <= Ugen
_ = forall a. HasCallStack => String -> a
error String
"Ugen.<= at, see <=*"
    (Constant_U Constant
a) > :: Ugen -> Ugen -> Bool
> (Constant_U Constant
b) = Constant
a forall a. Ord a => a -> a -> Bool
> Constant
b
    Ugen
_ > Ugen
_ = forall a. HasCallStack => String -> a
error String
"Ugen.>, see >*"
    (Constant_U Constant
a) >= :: Ugen -> Ugen -> Bool
>= (Constant_U Constant
b) = Constant
a forall a. Ord a => a -> a -> Bool
>= Constant
b
    Ugen
_ >= Ugen
_ = 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 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 forall a. Ord a => a -> a -> a
max

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

-- | Ugens are bit patterns.
instance Bits Ugen where
    .&. :: Ugen -> Ugen -> Ugen
(.&.) = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpBitAnd forall a. HasCallStack => a
undefined
    .|. :: Ugen -> Ugen -> Ugen
(.|.) = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpBitOr forall a. HasCallStack => a
undefined
    xor :: Ugen -> Ugen -> Ugen
xor = Sc3_Binary_Op
-> (Double -> Double -> Double) -> Ugen -> Ugen -> Ugen
mkBinaryOperator Sc3_Binary_Op
OpBitXor forall a. HasCallStack => a
undefined
    complement :: Ugen -> Ugen
complement = Sc3_Unary_Op -> (Double -> Double) -> Ugen -> Ugen
mkUnaryOperator Sc3_Unary_Op
OpBitNot forall a. HasCallStack => a
undefined
    shift :: Ugen -> Int -> Ugen
shift = forall a. HasCallStack => String -> a
error String
"Ugen.shift"
    rotate :: Ugen -> Int -> Ugen
rotate = forall a. HasCallStack => String -> a
error String
"Ugen.rotate"
    bitSize :: Ugen -> Int
bitSize = forall a. HasCallStack => String -> a
error String
"Ugen.bitSize"
    bit :: Int -> Ugen
bit = forall a. HasCallStack => String -> a
error String
"Ugen.bit"
    testBit :: Ugen -> Int -> Bool
testBit = forall a. HasCallStack => String -> a
error String
"Ugen.testBit"
    popCount :: Ugen -> Int
popCount = forall a. HasCallStack => String -> a
error String
"Ugen.popCount" -- hugs...
    bitSizeMaybe :: Ugen -> Maybe Int
bitSizeMaybe = 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
-}