{-# LANGUAGE DataKinds , ExtendedDefaultRules , FlexibleContexts , LambdaCase , OverloadedStrings , TypeFamilies, NoMonoLocalBinds , NoIncoherentInstances , NoMonomorphismRestriction , NoUndecidableInstances #-} module Vivid.UGens.Buffer ( -- * Buffer > Info bufChannels , bufDur , bufFrames , bufRateScale , bufSampleRate , bufSamples -- * Buffer , bufRd , bufWr --- , dbufrd --- , dbufwr --- , delTapRd --- , delTapWr --- , detectIndex -- In Vivid.UGens.InOut: -- , diskIn -- In Vivid.UGens.InOut: -- , diskOut -- In Vivid.UGens.Generators.Granular: -- , grainBuf --- , harmonics --- , index --- , indexInBetween --- , indexL , localBuf --- , multiTap , phasor , playBuf , playBufPoly , recordBuf , recordBufPoly --- , scopeOut --- , shaper -- In Vivid.UGens.Generators.Granular -- , tGrains --- , tap -- In Vivid.UGens.InOut: -- , vDiskIn -- In Vivid.UGens.Generators.Granular -- , warp1 --- , wrapIndex ) where import Vivid.SC.SynthDef.Types (CalculationRate(..)) import Vivid.SynthDef import Vivid.SynthDef.FromUA import Vivid.UGens.Args import Data.Proxy import GHC.Real (Ratio((:%))) -- | Add a single LocalBuf for FFT -- -- Can use 'Vivid.UGens.Args.chans_' for \"numChans\" -- and 'frames_' for \"Vivid.UGens.Args.numFrames\" localBuf :: Args '["numChans","numFrames"] '[] a => a -> SDBody a Signal localBuf args = do mlb <- addOrIncrementMaxLocalBufs numChannels' <- uaArgVal args (Proxy::Proxy "numChans") numFrames' <- uaArgVal args (Proxy::Proxy "numFrames") -- Another example where the args in sclang and scsynth are in different orders: addUGen $ UGen (UGName_S "LocalBuf") IR [numChannels', numFrames', mlb] 1 {-# DEPRECATED playBuf "use playBufPoly instead (and use bufRateScale and set doneAction)" #-} -- | Unlike in SC, \"doneAction\\" defaults to 2 -- -- Also, the default rate is the 'bufRateScale' of the buffer playBuf :: (Args '["buf"] '["rate","trigger","startPos","loop","doneAction"] a) => a -> SDBody a Signal playBuf args = ($ args) $ makeUGen "PlayBuf" AR (Vs::Vs '["buf","rate","trigger","startPos","loop","doneAction"]) (rate_ defaultRate, trigger_ ((1)::Float), startPos_ ((0)::Float) ,loop_ ((0)::Float), doneAction_ ((2)::Float)) where -- TODO: maybe don't want to do this. especially cause if you set the rate it doesn't multiply by this -- alternative is to change 'rate_' to 'bufrate_' and have that 'arg' function do a multiply -- update docs too: -- todo : put bufratescale on all of em if we decide to keep this behavior defaultRate = bufRateScale $ uaArgVal args (V::V "buf") playBufPoly :: (Args '["buf"] '["rate","trigger","startPos","loop","doneAction"] a) => Int -> a -> SDBody a [Signal] playBufPoly numChans args = ($ args) $ makePolyUGen numChans "PlayBuf" AR (Vs::Vs '["buf","rate","trigger","startPos","loop","doneAction"]) (rate_ (1::Float), trigger_ ((1)::Float), startPos_ ((0)::Float) ,loop_ ((0)::Float), doneAction_ (0::Float)) -- NOTE doneAction is back to 0...! Good idea? (TODO) -- | Unlike in SC, "doneAction" defaults to 2 and "loop" defaults to 0 recordBuf :: (Args '["buf","in"] '["offset","recLevel","preLevel","run","loop","trigger","doneAction"] a) => a -> SDBody a Signal recordBuf = makeUGen "RecordBuf" AR (Vs::Vs '["buf","offset","recLevel","preLevel","run","loop","trigger","doneAction","in"]) -- this is another example of different order: (offset_ ((0)::Float), recLevel_ ((1)::Float), preLevel_ ((0)::Float), run_ ((1)::Float), loop_ ((0)::Float), trigger_ ((1)::Float), doneAction_ ((2)::Float)) -- | Unlike in SC, "doneAction" defaults to 2 and "loop" defaults to 0 recordBufPoly :: (Args '["buf","in"] '["offset","recLevel","preLevel","run","loop","trigger","doneAction"] a) => Int -> a -> SDBody a [Signal] recordBufPoly numChans = makePolyUGen numChans "RecordBuf" AR (Vs::Vs '["buf","offset","recLevel","preLevel","run","loop","trigger","doneAction","in"]) -- this is another example of different order: (offset_ ((0)::Float), recLevel_ ((1)::Float), preLevel_ ((0)::Float), run_ ((1)::Float), loop_ ((0)::Float), trigger_ ((1)::Float), doneAction_ ((2)::Float)) -- | Defaults to 'KR'. Can be 'IR' too but be careful that the buffer doesn't change if so! bufChannels :: (Args '["buf"] '[] a) => a -> SDBody a Signal bufChannels = makeUGen "BufChannels" KR (Vs::Vs '["buf"]) NoDefaults -- | Defaults to 'KR'. Can be 'IR' too but be careful that the buffer doesn't change if so! bufDur :: (Args '["buf"] '[] a) => a -> SDBody a Signal bufDur = makeUGen "BufDur" KR (Vs::Vs '["buf"]) NoDefaults -- bufFrames :: (Args '["buf"] '[] a) => a -> SDBody a Signal -- | Defaults to 'KR'. Can be 'IR' too but be careful that the buffer doesn't change if so! -- -- Note you don't need to use "buf_" when you use this bufFrames :: ToSig s as => s -> SDBody' as Signal bufFrames = (. buf_) $ makeUGen "BufFrames" KR (Vs::Vs '["buf"]) NoDefaults -- bufRateScale :: (Args '["buf"] '[] a) => a -> SDBody a Signal -- | Defaults to 'KR'. Can be 'IR' too but be careful that the buffer doesn't change if so! -- -- Note you don't need to use "buf_" when you use this bufRateScale :: ToSig s as => s -> SDBody' as Signal bufRateScale = (. buf_) $ makeUGen "BufRateScale" KR (Vs::Vs '["buf"]) NoDefaults -- bufSampleRate :: (Args '["buf"] '[] a) => a -> SDBody a Signal -- | Defaults to 'KR'. Can be 'IR' too but be careful that the buffer doesn't change if so! -- -- Note you don't need to use "buf_" when you use this bufSampleRate :: ToSig s as => s -> SDBody' as Signal bufSampleRate = (. buf_) $ makeUGen "BufSampleRate" KR (Vs::Vs '["buf"]) NoDefaults -- bufSamples :: (Args '["buf"] '[] a) => a -> SDBody a Signal -- | Defaults to 'KR'. Can be 'IR' too but be careful that the buffer doesn't change if so! -- -- Note you don't need to use "buf_" when you use this bufSamples :: ToSig s as => s -> SDBody' as Signal bufSamples = (. buf_) $ makeUGen "BufSamples" KR (Vs::Vs '["buf"]) NoDefaults -- | \"phase\" must be at audio rate ('AR') -- -- \"numChans\" can't be set after the synth is created, and must be a fixed integer bufRd :: Args '["numChans", "buf", "phase"] '["loop", "interp"] a => a -> SDBody a [Signal] bufRd args = do numChans <- uaArgVal args (V::V "numChans") >>= \case Constant x -> case toRational x of n :% 1 -> pure $ fromInteger n _ -> error $ "bufRd: numChans not an integer!: " ++ show x _ -> error "bufrd: not a fixed integer!" makePolyUGen numChans "BufRd" AR (Vs::Vs '["buf", "phase", "loop", "interp"]) (loop_ ((1)::Float), interp_ ((2)::Float)) args -- | "phase" must be at audio rate ('AR') bufWr :: (Args '["in", {- "numChans", -} "buf", "phase"] '["loop"] a) => a -> SDBody a Signal bufWr = makeUGen "BufWr" AR -- An example of arguments in different orders in sclang and scsynth: (Vs::Vs '["buf", "phase", "loop", "in"]) (loop_ ((1)::Float)) -- returns demandrate --- dbufrd :: --- dbufrd = --- dbufwr :: --- dbufwr = -- | "phase" must be the output of 'delTapWr' --delTapRd :: (Args '["buf", "phase", "delSecs"] '["interp"] a) => s -> SDBody a Signal --- delTapRd :: --- delTapRd = --- delTapWr :: --- delTapWr = --- detectIndex :: --- detectIndex = --- harmonics :: --- harmonics = --- index :: --- index = --- indexInBetween :: --- indexInBetween = --- indexL :: --- indexL = --- multiTap :: --- multiTap = phasor :: (Args '[] '["trigger", "rate", "start", "end", "resetPos"] a) => a -> SDBody a Signal phasor = makeUGen "Phasor" AR (Vs::Vs '["trigger", "rate", "start", "end", "resetPos"]) (trig_ ((0)::Float), rate_ ((1)::Float), start_ ((0)::Float), end_ ((1)::Float), resetPos_ ((0)::Float)) --- scopeOut :: --- scopeOut = --- shaper :: --- shaper = --- tap :: --- tap = --- wrapIndex :: --- wrapIndex =