content: {-# LANGUAGE
       DataKinds
     , ExtendedDefaultRules
     , LambdaCase
     , OverloadedStrings
  
     , NoIncoherentInstances
     , NoMonomorphismRestriction
     , NoUndecidableInstances
     #-}
  
  module Vivid.UGens.InOut (
       -- This is deprecated in SC:
     --   audioIn
  ---     diskIn
       diskOut
  ---   , in__
     , aIn
     , kIn
  ---   , inFeedback
  ---   , inTrig
  ---   , lagIn
     , localIn
     , localOut
  ---   , maxLocalBufs
  ---   , offsetOut
     , out
     , out'
     , aOut
  --- , kOut
  --- , kOut_mono
     , replaceOut
  
       -- These 2 have been deprecated in SC:
  --    , sharedIn
  --    , sharedOut
  
     , soundIn
  ---   , vDiskIn
  ---   , xOut
     ) where
  
  import Vivid.SC.SynthDef.Types (CalculationRate(..))
  import Vivid.SC.Server.Types (BufferId(..))
  import Vivid.SynthDef
  import Vivid.SynthDef.FromUA
  import Vivid.UGens.Algebraic
  import Vivid.UGens.Args
  
  import Data.Proxy
  
  aIn :: Args '["bus"] '[] a => a -> SDBody a Signal
  aIn = makeUGen
     "In" AR
     (Vs::Vs '["bus"])
     NoDefaults
  
  --- diskIn ::
  --- diskIn =
  
  -- | 'buf' is a temporary buffer to accumulate before writing.
  -- 
  --    "NOTE: The Buffer's numFrames must be a power of two and is recommended to be at least 65536 -- preferably 131072 or 262144. Smaller buffer sizes mean more frequent disk access, which can cause glitches."
  --
  --    65536 == 2 ^ 16
  --    131072 == 2 ^ 17
  --    262144 == 2 ^ 18
  -- 
  --    For ease of use with 'sd' this has output type \"[Signal]\", but the list
  --      is always empty
  diskOut :: ToSig s a => BufferId -> [s] -> SDBody' a [Signal]
  diskOut (BufferId bufId) sigs = do
     sigs' <- mapM toSig sigs
     addPolyUGen $ UGen (UGName_S "DiskOut") AR (Constant (realToFrac bufId) : sigs') 0
  
  --- in__ ::
  --- in__ =
  --- inFeedback ::
  --- inFeedback =
  --- inTrig ::
  --- inTrig =
  
  kIn :: Args '["bus"] '[] a => a -> SDBody a Signal
  kIn = makeUGen
     "In" KR
     (Vs::Vs '["bus"])
     NoDefaults
  
  --- lagIn ::
  --- lagIn =
  
  -- localIn :: Args '[] '["default"] a => Int -> a -> SDBody a [Signal]
  -- "default" is 0 for now:
  localIn :: Int -> SDBody' a [Signal]
  localIn numChans = do
     addPolyUGen $ UGen (UGName_S "LocalIn") AR [Constant 0] numChans
  
  localOut :: ToSig s as => [s] -> SDBody' as ()
  localOut inSig = do
     sigs <- mapM toSig inSig
     addPolyUGen (UGen (UGName_S "LocalOut") AR sigs 0) >>= \case
        [] -> pure ()
        _ -> error "??? (23s0g)"
     pure ()
  
  
  --- maxLocalBufs ::
  --- maxLocalBufs =
  --- offsetOut ::
  --- offsetOut =
  
  out :: (ToSig i a, ToSig busNum a) => busNum -> [i] -> SDBody' a [Signal]
  out = aOut
  
  out' :: (Elem "out" a, ToSig i a) => [i] -> SDBody' a [Signal]
  out' = out (V::V "out")
  
  aOut :: (ToSig i a, ToSig busNum a) => busNum -> [i] -> SDBody' a [Signal]
  aOut busNum is = do
     busNum' <- toSig busNum
     is' <- mapM toSig is
     addPolyUGen $ UGen (UGName_S "Out") AR (busNum' : is') ((length::[a]->Int) is)
  
  -- kOut
  
  -- kIn ::
  -- kIn =
  
  -- todo: does this work/is it robust?:
  replaceOut :: (ToSig i a, ToSig busNum a) => busNum -> [i] -> SDBody' a [Signal]
  replaceOut busNum is = do
     busNum' <- toSig busNum
     is' <- mapM toSig is
     addPolyUGen $ UGen (UGName_S "ReplaceOut") AR (busNum' : is') ((length::[a]->Int) is)
  
  -- | Audio bus input (usually mic)
  soundIn :: Args '["bus"] '[] a => a -> SDBody a Signal
  soundIn args = do
     bus <- args `uaArgVal` (Proxy::Proxy "bus")
     nob <- addUGen $ UGen (UGName_S "NumOutputBuses") IR [] 1 {- :: SDBody a Signal -}
     inPos <- nob ~+ (bus :: Signal)
     addUGen $ UGen (UGName_S "In") AR [inPos] 1
  
  
  --- vDiskIn ::
  --- vDiskIn =
  
  -- | "Send signal to a bus, crossfading with previous contents"
  -- 
  --   
  --- xOut ::
  --- xOut =
  