-- | Hand-written bindings.
module Sound.Sc3.Ugen.Bindings.Hw where

import Sound.Sc3.Common.Rate
import Sound.Sc3.Common.Uid
import Sound.Sc3.Common.Unsafe

import qualified Sound.Sc3.Ugen.Bindings.Hw.Construct as C
import Sound.Sc3.Ugen.Types
import qualified Sound.Sc3.Ugen.Util as Util

-- | 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
Util.mrg2 Ugen
b (Rate -> String -> [Ugen] -> Int -> Ugen
C.mkOsc Rate
ir String
"ClearBuf" [Ugen
b] Int
1)

-- | Demand rate weighted random sequence generator.
dwrandId :: ID i => i -> Ugen -> Ugen -> Ugen -> Ugen
dwrandId :: forall i. ID i => i -> Ugen -> Ugen -> Ugen -> Ugen
dwrandId 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 forall a. a -> [a] -> [a]
: forall n. Real n => n -> Ugen
constant Int
n forall a. a -> [a] -> [a]
: [Ugen]
weights'
    in Maybe ([Sample] -> Sample)
-> [Rate]
-> Either Rate [Int]
-> String
-> [Ugen]
-> Maybe [Ugen]
-> Int
-> Special
-> UgenId
-> Ugen
mkUgen forall a. Maybe a
Nothing [Rate
dr] (forall a b. a -> Either a b
Left Rate
dr) String
"Dwrand" [Ugen]
inp (forall a. a -> Maybe a
Just [Ugen
list_]) Int
1 (Int -> Special
Special Int
0) (forall a. ID a => a -> UgenId
Util.toUid i
z)

dwrandM :: Uid m => Ugen -> Ugen -> Ugen -> m Ugen
dwrandM :: forall (m :: * -> *). Uid m => Ugen -> Ugen -> Ugen -> m Ugen
dwrandM = forall (m :: * -> *) a b c d.
Uid m =>
(Int -> Fn3 a b c d) -> Fn3 a b c (m d)
liftUid3 forall i. ID i => i -> Ugen -> Ugen -> Ugen -> Ugen
dwrandId

dwrand :: Ugen -> Ugen -> Ugen -> Ugen
dwrand :: Ugen -> Ugen -> Ugen -> Ugen
dwrand = forall a b c r. (a -> b -> c -> IO r) -> a -> b -> c -> r
liftUnsafe3 forall (m :: * -> *). Uid m => Ugen -> Ugen -> Ugen -> m Ugen
dwrandM

-- | 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 forall a. Maybe a
Nothing [Rate
kr,Rate
ar] (forall a b. a -> Either a b
Left Rate
rate) String
"EnvGen" [Ugen
gate_,Ugen
levelScale,Ugen
levelBias,Ugen
timeScale,Ugen
doneAction] (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 = 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, forall n. Real n => n -> Ugen
constant Int
sz, forall n. Real n => n -> Ugen
constant Int
from, 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]
Util.unpackLabel Bool
True Ugen
label_
  in String -> [Ugen] -> Int -> Ugen
C.mkFilter String
"Poll" ([Ugen
trig_,Ugen
in_,Ugen
trigid] 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 = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
nm) forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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] forall a. [a] -> [a] -> [a]
++ String -> [Ugen]
string_to_ugens String
n 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