-- | Hand-written bindings.
module Sound.SC3.UGen.Bindings.HW where

import Sound.SC3.Common.Rate
import qualified Sound.SC3.Common.UId as I
import qualified Sound.SC3.UGen.Bindings.HW.Construct as C
import Sound.SC3.UGen.Type
import qualified Sound.SC3.UGen.UGen as U

-- | Zero local buffer.
--
-- ClearBuf does not copy the buffer number through so this is an MRG node.
clearBuf :: UGen -> UGen
clearBuf :: UGen -> UGen
clearBuf UGen
b = UGen -> UGen -> UGen
U.mrg2 UGen
b (Rate -> String -> [UGen] -> Int -> UGen
C.mkOsc Rate
IR String
"ClearBuf" [UGen
b] Int
1)

-- | Demand rate weighted random sequence generator.
dwrand :: I.ID i => i -> UGen -> UGen -> UGen -> UGen
dwrand :: i -> UGen -> UGen -> UGen -> UGen
dwrand i
z UGen
repeats UGen
weights UGen
list_ =
    let n :: Int
n = UGen -> Int
mceDegree_err UGen
list_
        weights' :: [UGen]
weights' = Int -> UGen -> [UGen]
mceExtend Int
n UGen
weights
        inp :: [UGen]
inp = UGen
repeats UGen -> [UGen] -> [UGen]
forall a. a -> [a] -> [a]
: Int -> UGen
forall n. Real n => n -> UGen
constant Int
n UGen -> [UGen] -> [UGen]
forall a. a -> [a] -> [a]
: [UGen]
weights'
    in Maybe ([Sample] -> Sample)
-> [Rate]
-> Either Rate [Int]
-> String
-> [UGen]
-> Maybe [UGen]
-> Int
-> Special
-> UGenId
-> UGen
mkUGen Maybe ([Sample] -> Sample)
forall a. Maybe a
Nothing [Rate
DR] (Rate -> Either Rate [Int]
forall a b. a -> Either a b
Left Rate
DR) String
"Dwrand" [UGen]
inp ([UGen] -> Maybe [UGen]
forall a. a -> Maybe a
Just [UGen
list_]) Int
1 (Int -> Special
Special Int
0) (i -> UGenId
forall a. ID a => a -> UGenId
U.toUId i
z)

-- | Variant on 'envGen' without enumeration types.
envGen_ll :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
envGen_ll :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
envGen_ll Rate
rate UGen
gate_ UGen
levelScale UGen
levelBias UGen
timeScale UGen
doneAction UGen
envelope_ = Maybe ([Sample] -> Sample)
-> [Rate]
-> Either Rate [Int]
-> String
-> [UGen]
-> Maybe [UGen]
-> Int
-> Special
-> UGenId
-> UGen
mkUGen Maybe ([Sample] -> Sample)
forall a. Maybe a
Nothing [Rate
KR,Rate
AR] (Rate -> Either Rate [Int]
forall a b. a -> Either a b
Left Rate
rate) String
"EnvGen" [UGen
gate_,UGen
levelScale,UGen
levelBias,UGen
timeScale,UGen
doneAction] ([UGen] -> Maybe [UGen]
forall a. a -> Maybe a
Just [UGen
envelope_]) Int
1 (Int -> Special
Special Int
0) UGenId
NoId

-- | Outputs signal for @FFT@ chains, without performing FFT.
fftTrigger :: UGen -> UGen -> UGen -> UGen
fftTrigger :: UGen -> UGen -> UGen -> UGen
fftTrigger UGen
b UGen
h UGen
p = Rate -> String -> [UGen] -> Int -> UGen
C.mkOsc Rate
KR String
"FFTTrigger" [UGen
b,UGen
h,UGen
p] Int
1

-- | Pack demand-rate FFT bin streams into an FFT chain.
packFFT :: UGen -> Int -> Int -> Int -> UGen -> UGen -> UGen
packFFT :: UGen -> Int -> Int -> Int -> UGen -> UGen -> UGen
packFFT UGen
b Int
sz Int
from Int
to UGen
z UGen
mp =
    let n :: UGen
n = Int -> UGen
forall n. Real n => n -> UGen
constant (UGen -> Int
mceDegree_err UGen
mp)
    in Rate -> String -> [UGen] -> UGen -> Int -> UGen
C.mkOscMCE Rate
KR String
"PackFFT" [UGen
b, Int -> UGen
forall n. Real n => n -> UGen
constant Int
sz, Int -> UGen
forall n. Real n => n -> UGen
constant Int
from, Int -> UGen
forall n. Real n => n -> UGen
constant Int
to, UGen
z, UGen
n] UGen
mp Int
1

-- | Poll value of input UGen when triggered.
poll :: UGen -> UGen -> UGen -> UGen -> UGen
poll :: UGen -> UGen -> UGen -> UGen -> UGen
poll UGen
trig_ UGen
in_ UGen
trigid UGen
label_ =
  let q :: [UGen]
q = Bool -> UGen -> [UGen]
U.unpackLabel Bool
True UGen
label_
  in String -> [UGen] -> Int -> UGen
C.mkFilter String
"Poll" ([UGen
trig_,UGen
in_,UGen
trigid] [UGen] -> [UGen] -> [UGen]
forall a. [a] -> [a] -> [a]
++ [UGen]
q) Int
0

-- | FFT onset detector.
pv_HainsworthFoote :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
pv_HainsworthFoote :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
pv_HainsworthFoote UGen
buf UGen
h UGen
f UGen
thr UGen
wt = Rate -> String -> [UGen] -> Int -> UGen
C.mkOsc Rate
AR String
"PV_HainsworthFoote" [UGen
buf,UGen
h,UGen
f,UGen
thr,UGen
wt] Int
1

-- | FFT feature detector for onset detection.
--
-- buffer, propsc=0.25, prophfe=0.25, prophfc=0.25, propsf=0.25, threshold=1.0, waittime=0.04
pv_JensenAndersen :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
pv_JensenAndersen :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
pv_JensenAndersen UGen
buffer UGen
propsc UGen
prophfe UGen
prophfc UGen
propsf UGen
threshold UGen
waittime = Rate -> String -> [UGen] -> Int -> UGen
C.mkOsc Rate
AR String
"PV_JensenAndersen" [UGen
buffer,UGen
propsc,UGen
prophfe,UGen
prophfc,UGen
propsf,UGen
threshold,UGen
waittime] Int
1

-- | ASCII string to length prefixed list of constant UGens.
--
-- > string_to_ugens "/label" == map fromIntegral [6,47,108,97,98,101,108]
string_to_ugens :: String -> [UGen]
string_to_ugens :: String -> [UGen]
string_to_ugens String
nm = Int -> UGen
forall a b. (Integral a, Num b) => a -> b
fromIntegral (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
nm) UGen -> [UGen] -> [UGen]
forall a. a -> [a] -> [a]
: (Char -> UGen) -> String -> [UGen]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> UGen
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> UGen) -> (Char -> Int) -> Char -> UGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
forall a. Enum a => a -> Int
fromEnum) String
nm

-- | Send a reply message from the server back to all registered clients.
sendReply :: UGen -> UGen -> String -> [UGen] -> UGen
sendReply :: UGen -> UGen -> String -> [UGen] -> UGen
sendReply UGen
i UGen
k String
n [UGen]
v = String -> [UGen] -> Int -> UGen
C.mkFilter String
"SendReply" ([UGen
i,UGen
k] [UGen] -> [UGen] -> [UGen]
forall a. [a] -> [a] -> [a]
++ String -> [UGen]
string_to_ugens String
n [UGen] -> [UGen] -> [UGen]
forall a. [a] -> [a] -> [a]
++ [UGen]
v) Int
0

-- | Unpack a single value (magnitude or phase) from an FFT chain
unpack1FFT :: UGen -> UGen -> UGen -> UGen -> UGen
unpack1FFT :: UGen -> UGen -> UGen -> UGen -> UGen
unpack1FFT UGen
buf UGen
size UGen
index_ UGen
which = Rate -> String -> [UGen] -> Int -> UGen
C.mkOsc Rate
DR String
"Unpack1FFT" [UGen
buf, UGen
size, UGen
index_, UGen
which] Int
1