{-# LANGUAGE
     DataKinds
   , OverloadedStrings
   #-}

{-# LANGUAGE NoIncoherentInstances #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE NoUndecidableInstances #-}

module Vivid.UGens.Info (
     checkBadValues
   , controlDur
   , controlRate
     -- In Vivid.UGens.Demand:
   -- , dpoll
   , numAudioBuses
   , numBuffers
   , numControlBuses
   , numInputBuses
   , numOutputBuses
   , numRunningSynths
   , poll
   , radiansPerSample
   , sampleDur
   , sampleRate
   , subsampleOffset
   ) where

import Vivid.SC.SynthDef.Types (CalculationRate(..))
import Vivid.SynthDef
import Vivid.SynthDef.FromUA
import Vivid.UGens.Args

checkBadValues :: (Args '["in"] '["id", "post"] a) => a -> SDBody a Signal
checkBadValues :: a -> SDBody a Signal
checkBadValues = String
-> CalculationRate
-> Vs '["in", "id", "post"]
-> (UA "id" (SDBodyArgs a), UA "post" (SDBodyArgs a))
-> a
-> SDBody a Signal
forall (tags :: [Symbol]) optional userSupplied (args :: [Symbol]).
(GetSymbolVals (Vs tags), FromUA optional, FromUA userSupplied,
 SDBodyArgs optional ~ SDBodyArgs userSupplied,
 SDBodyArgs optional ~ args) =>
String
-> CalculationRate
-> Vs tags
-> optional
-> userSupplied
-> SDBody' args Signal
makeUGen
   String
"CheckBadValues" CalculationRate
AR
   (Vs '["in", "id", "post"]
forall (a :: [Symbol]). Vs a
Vs::Vs '["in", "id", "post"])
   (Float -> UA "id" (SDBodyArgs a)
forall s (as :: [Symbol]). ToSig s as => s -> UA "id" as
id_ (Float
0::Float), Float -> UA "post" (SDBodyArgs a)
forall s (as :: [Symbol]). ToSig s as => s -> UA "post" as
post_ (Float
2::Float))

-- | The (current) duration of a control block on the server in seconds
-- 
--   Equal to @1 ~/ controlRate@
controlDur :: SDBody' a Signal
controlDur :: SDBody' a Signal
controlDur =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"ControlDur") CalculationRate
IR [] Int
1

-- | The current control rate of the server
-- 
--   Equal to @1 ~/ controlDur@
controlRate :: SDBody' a Signal
controlRate :: SDBody' a Signal
controlRate =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"ControlRate") CalculationRate
IR [] Int
1

-- | The number of audio buses
numAudioBuses :: SDBody' a Signal
numAudioBuses :: SDBody' a Signal
numAudioBuses =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"NumAudioBuses") CalculationRate
IR [] Int
1

-- | The number of open buffers
numBuffers :: SDBody' a Signal
numBuffers :: SDBody' a Signal
numBuffers =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"NumBuffers") CalculationRate
IR [] Int
1

numControlBuses :: SDBody' a Signal
numControlBuses :: SDBody' a Signal
numControlBuses =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"NumControlBuses") CalculationRate
IR [] Int
1

numInputBuses :: SDBody' a Signal
numInputBuses :: SDBody' a Signal
numInputBuses =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"NumInputBuses") CalculationRate
IR [] Int
1

numOutputBuses :: SDBody' a Signal
numOutputBuses :: SDBody' a Signal
numOutputBuses =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"NumOutputBuses") CalculationRate
IR [] Int
1

numRunningSynths :: SDBody' a Signal
numRunningSynths :: SDBody' a Signal
numRunningSynths =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"NumRunningSynths") CalculationRate
IR [] Int
1

-- | This is CPU-intensive: only use for debugging!
-- 
--   First argument is frequency of polling: the number of times per second to poll
-- 
--   Returns the UGen it's polling so you can add \"poll\" to an existing
--   signal chain without altering it
poll :: Float -> String -> SDBody' a Signal -> SDBody' a Signal
poll :: Float -> String -> SDBody' a Signal -> SDBody' a Signal
poll Float
freq String
label SDBody' a Signal
polledThing = do
   Signal
imp <- UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"Impulse") CalculationRate
AR [Float -> Signal
Constant Float
freq] Int
1
   Signal
pt <- SDBody' a Signal
polledThing
   let args :: [Signal]
args = ([Signal
imp, Signal
pt] [Signal] -> [Signal] -> [Signal]
forall a. [a] -> [a] -> [a]
++) ([Signal] -> [Signal]) -> [Signal] -> [Signal]
forall a b. (a -> b) -> a -> b
$ (Int -> Signal) -> [Int] -> [Signal]
forall a b. (a -> b) -> [a] -> [b]
map (Float -> Signal
Constant (Float -> Signal) -> (Int -> Float) -> Int -> Signal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac) ([Int] -> [Signal]) -> [Int] -> [Signal]
forall a b. (a -> b) -> a -> b
$
        [-Int
1, (forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length::[a]->Int) String
label] [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ (Char -> Int) -> String -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Int
forall a. Enum a => a -> Int
fromEnum String
label
   Signal
_ <- UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"Poll") CalculationRate
AR [Signal]
args Int
1
   Signal -> SDBody' a Signal
forall (f :: * -> *) a. Applicative f => a -> f a
pure Signal
pt

radiansPerSample :: SDBody' a Signal
radiansPerSample :: SDBody' a Signal
radiansPerSample =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"RadiansPerSample") CalculationRate
IR [] Int
1

sampleDur :: SDBody' a Signal
sampleDur :: SDBody' a Signal
sampleDur =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"SampleDur") CalculationRate
IR [] Int
1

sampleRate :: SDBody' a Signal
sampleRate :: SDBody' a Signal
sampleRate =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"SampleRate") CalculationRate
IR [] Int
1

subsampleOffset :: SDBody' a Signal
subsampleOffset :: SDBody' a Signal
subsampleOffset =
   UGen -> SDBody' a Signal
forall (args :: [Symbol]). UGen -> SDBody' args Signal
addUGen (UGen -> SDBody' a Signal) -> UGen -> SDBody' a Signal
forall a b. (a -> b) -> a -> b
$ UGenName -> CalculationRate -> [Signal] -> Int -> UGen
UGen (ByteString -> UGenName
UGName_S ByteString
"SubsampleOffset") CalculationRate
IR [] Int
1