-- | Oscillators with hard and soft sync
module Csound.Air.Wave.Sync(
  -- * Hard sync
    SyncSmooth(..),

    sawSync, isawSync, pulseSync, sqrSync, triSync, bloscSync,
    sawSync', isawSync', pulseSync', sqrSync', triSync', bloscSync',

    -- ** With random phase
    rndSawSync, rndIsawSync, rndPulseSync, rndSqrSync, rndTriSync, rndBloscSync,

    -- ** With absolute slave frequencies
    sawSyncAbs, isawSyncAbs, pulseSyncAbs, sqrSyncAbs, triSyncAbs, bloscSyncAbs,
    sawSyncAbs', isawSyncAbs', pulseSyncAbs', sqrSyncAbs', triSyncAbs', bloscSyncAbs',


    -- ** With absolute custom smooth mode
    sawSyncBy, isawSyncBy, pulseSyncBy, sqrSyncBy, triSyncBy, bloscSyncBy,
    sawSyncBy', isawSyncBy', pulseSyncBy', sqrSyncBy', triSyncBy', bloscSyncBy',
    sawSyncAbsBy, isawSyncAbsBy, pulseSyncAbsBy, sqrSyncAbsBy, triSyncAbsBy, bloscSyncAbsBy,
    sawSyncAbsBy', isawSyncAbsBy', pulseSyncAbsBy', sqrSyncAbsBy', triSyncAbsBy', bloscSyncAbsBy',

    -- ** Raw (non-bandlimited) shapes

    -- *** With relative slave frequency
    rawTriSync, rawSqrSync, rawSawSync, rawPwSync,
    rawTriSyncBy, rawSqrSyncBy, rawSawSyncBy, rawPwSyncBy,

    -- *** With absolute slave frequency
  rawTriSyncAbs,  rawSqrSyncAbs, rawSawSyncAbs, rawPwSyncAbs,
    rawTriSyncAbsBy, rawSqrSyncAbsBy, rawSawSyncAbsBy, rawPwSyncAbsBy,

   -- * Soft sync

   -- *** With relative slave frequency
    softSync, rawSoftSync, softSyncBy, rawSoftSyncBy,

    -- *** With absolute slave frequency
    softSyncAbs, rawSoftSyncAbs, softSyncAbsBy, rawSoftSyncAbsBy
) where

import Data.Default

import Csound.Typed
import Csound.Typed.Opcode hiding (lfo, tab)
import Csound.Tab

import Csound.Air.Wave

--------------------------------------------------------------------------
-- hard sync random phase

rndPhsSync :: (D -> Sig -> Sig -> Sig) -> (Sig -> Sig -> SE Sig)
rndPhsSync :: (D -> Sig -> Sig -> Sig) -> Sig -> Sig -> SE Sig
rndPhsSync D -> Sig -> Sig -> Sig
f Sig
ratio Sig
cps = (D -> Sig) -> SE D -> SE Sig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\D
x -> D -> Sig -> Sig -> Sig
f D
x Sig
ratio Sig
cps) (SE D -> SE Sig) -> SE D -> SE Sig
forall a b. (a -> b) -> a -> b
$ D -> SE D
forall a. SigOrD a => a -> SE a
rnd D
1

-- | Hard sync with saw waveform and randomized phase.
rndSawSync :: Sig -> Sig -> SE Sig
rndSawSync :: Sig -> Sig -> SE Sig
rndSawSync = (D -> Sig -> Sig -> Sig) -> Sig -> Sig -> SE Sig
rndPhsSync D -> Sig -> Sig -> Sig
sawSync'

-- | Hard sync with integral saw waveform and randomized phase.
rndIsawSync :: Sig -> Sig -> SE Sig
rndIsawSync :: Sig -> Sig -> SE Sig
rndIsawSync = (D -> Sig -> Sig -> Sig) -> Sig -> Sig -> SE Sig
rndPhsSync D -> Sig -> Sig -> Sig
isawSync'

-- | Hard sync with pulse waveform and randomized phase.
rndPulseSync :: Sig -> Sig -> SE Sig
rndPulseSync :: Sig -> Sig -> SE Sig
rndPulseSync = (D -> Sig -> Sig -> Sig) -> Sig -> Sig -> SE Sig
rndPhsSync D -> Sig -> Sig -> Sig
pulseSync'

-- | Hard sync with square waveform and randomized phase.
rndSqrSync :: Sig -> Sig -> SE Sig
rndSqrSync :: Sig -> Sig -> SE Sig
rndSqrSync = (D -> Sig -> Sig -> Sig) -> Sig -> Sig -> SE Sig
rndPhsSync D -> Sig -> Sig -> Sig
sqrSync'

-- | Hard sync with triangle waveform and randomized phase.
rndTriSync :: Sig -> Sig -> SE Sig
rndTriSync :: Sig -> Sig -> SE Sig
rndTriSync = (D -> Sig -> Sig -> Sig) -> Sig -> Sig -> SE Sig
rndPhsSync D -> Sig -> Sig -> Sig
triSync'

-- | Hard sync with band-limited table waveform waveform and randomized phase.
rndBloscSync :: Tab -> Sig -> Sig -> SE Sig
rndBloscSync :: Tab -> Sig -> Sig -> SE Sig
rndBloscSync Tab
t = (D -> Sig -> Sig -> Sig) -> Sig -> Sig -> SE Sig
rndPhsSync (Tab -> D -> Sig -> Sig -> Sig
bloscSync' Tab
t)

-------------------------------------------------------------------------
-- Hard-sync for simple non-bandlimited waveforms

-- | Hard-sync with non-bandlimited triangle wave.
rawTriSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
rawTriSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
rawTriSyncBy = Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncBy Tab
triTab

-- | Hard-sync with non-bandlimited square wave.
rawSqrSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
rawSqrSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
rawSqrSyncBy = Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncBy Tab
sqrTab

-- | Hard-sync with non-bandlimited sawtooth wave.
rawSawSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
rawSawSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
rawSawSyncBy = Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncBy Tab
sawTab

-- | Hard-sync with non-bandlimited pulse-width wave.
rawPwSyncBy  :: Double -> SyncSmooth -> Sig -> Sig -> Sig
rawPwSyncBy :: Double -> SyncSmooth -> Sig -> Sig -> Sig
rawPwSyncBy Double
duty = Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncBy (Double -> Tab
pwTab Double
duty)

-------------------------------------------------------------------------

-- | Hard-sync with non-bandlimited triangle wave.
rawTriSync :: Sig -> Sig -> Sig
rawTriSync :: Sig -> Sig -> Sig
rawTriSync = SyncSmooth -> Sig -> Sig -> Sig
rawTriSyncBy SyncSmooth
forall a. Default a => a
def

-- | Hard-sync with non-bandlimited square wave.
rawSqrSync :: Sig -> Sig -> Sig
rawSqrSync :: Sig -> Sig -> Sig
rawSqrSync = SyncSmooth -> Sig -> Sig -> Sig
rawSqrSyncBy SyncSmooth
forall a. Default a => a
def

-- | Hard-sync with non-bandlimited sawtooth wave.
rawSawSync :: Sig -> Sig -> Sig
rawSawSync :: Sig -> Sig -> Sig
rawSawSync = SyncSmooth -> Sig -> Sig -> Sig
rawSawSyncBy SyncSmooth
forall a. Default a => a
def

-- | Hard-sync with non-bandlimited pulse-width wave.
rawPwSync  :: Double -> Sig -> Sig -> Sig
rawPwSync :: Double -> Sig -> Sig -> Sig
rawPwSync Double
duty = Double -> SyncSmooth -> Sig -> Sig -> Sig
rawPwSyncBy Double
duty SyncSmooth
forall a. Default a => a
def

-------------------------------------------------------------------------
-- Hard-sync for simple non-bandlimited waveforms with absolute slave frequency

-- | Hard-sync with non-bandlimited triangle wave.
rawTriSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
rawTriSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
rawTriSyncAbsBy = Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncAbsBy Tab
triTab

-- | Hard-sync with non-bandlimited square wave.
rawSqrSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
rawSqrSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
rawSqrSyncAbsBy = Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncAbsBy Tab
sqrTab

-- | Hard-sync with non-bandlimited sawtooth wave.
rawSawSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
rawSawSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
rawSawSyncAbsBy = Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncAbsBy Tab
sawTab

-- | Hard-sync with non-bandlimited pulse-width wave.
rawPwSyncAbsBy  :: Double -> SyncSmooth -> Sig -> Sig -> Sig
rawPwSyncAbsBy :: Double -> SyncSmooth -> Sig -> Sig -> Sig
rawPwSyncAbsBy Double
duty = Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncAbsBy (Double -> Tab
pwTab Double
duty)

-------------------------------------------------------------------------

-- | Hard-sync with non-bandlimited triangle wave.
rawTriSyncAbs :: Sig -> Sig -> Sig
rawTriSyncAbs :: Sig -> Sig -> Sig
rawTriSyncAbs = SyncSmooth -> Sig -> Sig -> Sig
rawTriSyncAbsBy SyncSmooth
forall a. Default a => a
def

-- | Hard-sync with non-bandlimited square wave.
rawSqrSyncAbs :: Sig -> Sig -> Sig
rawSqrSyncAbs :: Sig -> Sig -> Sig
rawSqrSyncAbs = SyncSmooth -> Sig -> Sig -> Sig
rawSqrSyncAbsBy SyncSmooth
forall a. Default a => a
def

-- | Hard-sync with non-bandlimited sawtooth wave.
rawSawSyncAbs :: Sig -> Sig -> Sig
rawSawSyncAbs :: Sig -> Sig -> Sig
rawSawSyncAbs = SyncSmooth -> Sig -> Sig -> Sig
rawSawSyncAbsBy SyncSmooth
forall a. Default a => a
def

-- | Hard-sync with non-bandlimited pulse-width wave.
rawPwSyncAbs  :: Double -> Sig -> Sig -> Sig
rawPwSyncAbs :: Double -> Sig -> Sig -> Sig
rawPwSyncAbs Double
duty = Double -> SyncSmooth -> Sig -> Sig -> Sig
rawPwSyncAbsBy Double
duty SyncSmooth
forall a. Default a => a
def


-------------------------------------------------------------------------

oscSyncBy :: Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncBy :: Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncBy Tab
tab SyncSmooth
smoothType Sig
cpsRatio Sig
cps = Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncAbsBy Tab
tab SyncSmooth
smoothType (Sig
cpsRatio Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
cps) Sig
cps

-- | Hard-sync with non-bandlimited waves.
oscSyncAbsBy :: Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncAbsBy :: Tab -> SyncSmooth -> Sig -> Sig -> Sig
oscSyncAbsBy Tab
tab SyncSmooth
smoothType Sig
slaveCps Sig
cps = (\Sig -> Sig -> Sig
smoothFun -> (Sig -> Sig -> Sig) -> Tab -> Sig -> Sig -> Sig
syncOsc Sig -> Sig -> Sig
smoothFun Tab
tab (Sig -> Sig
ar Sig
slaveCps) (Sig -> Sig
ar Sig
cps)) ((Sig -> Sig -> Sig) -> Sig) -> (Sig -> Sig -> Sig) -> Sig
forall a b. (a -> b) -> a -> b
$ case SyncSmooth
smoothType of
    SyncSmooth
RawSync         -> (\Sig
_ Sig
_ -> Sig
1)
    SyncSmooth
SawSync         -> (\Sig
amaster Sig
_ -> (Sig
1 Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
- Sig
amaster))
    SyncSmooth
TriSync         -> ((Sig -> Sig) -> Sig -> Sig -> Sig
forall a b. a -> b -> a
const ((Sig -> Sig) -> Sig -> Sig -> Sig)
-> (Sig -> Sig) -> Sig -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Tab -> Sig -> Sig
forall a. (Tuple a, SigOrD a) => Tab -> a -> a
readSync Tab
uniTriTab)
    SyncSmooth
TrapSync        -> ((Sig -> Sig) -> Sig -> Sig -> Sig
forall a b. a -> b -> a
const ((Sig -> Sig) -> Sig -> Sig -> Sig)
-> (Sig -> Sig) -> Sig -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Tab -> Sig -> Sig
forall a. (Tuple a, SigOrD a) => Tab -> a -> a
readSync Tab
uniTrapTab)
    UserSync Tab
genTab -> ((Sig -> Sig) -> Sig -> Sig -> Sig
forall a b. a -> b -> a
const ((Sig -> Sig) -> Sig -> Sig -> Sig)
-> (Sig -> Sig) -> Sig -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Tab -> Sig -> Sig
forall a. (Tuple a, SigOrD a) => Tab -> a -> a
readSync Tab
genTab)
    where
        readSync :: Tab -> a -> a
readSync Tab
ft a
async = a -> Tab -> a
forall a. SigOrD a => a -> Tab -> a
table3 a
async Tab
ft a -> D -> a
forall a. Tuple a => a -> D -> a
`withD` D
1

uniSawTab, uniTriTab, uniTrapTab :: Tab

uniSawTab :: Tab
uniSawTab  = Int -> Tab -> Tab
setSize Int
4097 (Tab -> Tab) -> Tab -> Tab
forall a b. (a -> b) -> a -> b
$ [Double] -> Tab
elins [Double
1, Double
0]
uniTriTab :: Tab
uniTriTab  = Int -> Tab -> Tab
setSize Int
4097 (Tab -> Tab) -> Tab -> Tab
forall a b. (a -> b) -> a -> b
$ [Double] -> Tab
elins [Double
0, Double
1, Double
0]
uniTrapTab :: Tab
uniTrapTab = Int -> Tab -> Tab
setSize Int
4097 (Tab -> Tab) -> Tab -> Tab
forall a b. (a -> b) -> a -> b
$ [Double] -> Tab
elins [Double
1, Double
1, Double
0]

syncOsc :: (Sig -> Sig -> Sig) -> Tab -> Sig -> Sig -> Sig
syncOsc :: (Sig -> Sig -> Sig) -> Tab -> Sig -> Sig -> Sig
syncOsc Sig -> Sig -> Sig
smoothFun Tab
ftab Sig
slaveCps Sig
cps = Sig -> Sig
dcblock (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig
aout
    where
        (Sig
amaster, Sig
asyncMaster) = Sig -> Sig -> (Sig, Sig)
syncphasor Sig
cps Sig
0
        (Sig
aslave,  Sig
_asyncSlave)  = Sig -> Sig -> (Sig, Sig)
syncphasor Sig
slaveCps Sig
asyncMaster
        aosc :: Sig
aosc = Sig -> Tab -> Sig
forall a. SigOrD a => a -> Tab -> a
table3 Sig
aslave Tab
ftab Sig -> D -> Sig
forall a. Tuple a => a -> D -> a
`withD` D
1
        aout :: Sig
aout = Sig
aosc Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig -> Sig -> Sig
smoothFun Sig
amaster Sig
asyncMaster

----------------------------------------------------------
-- Soft-sync

-- | Soft sync with given waveform (with band-limited square wave for switch).
-- The soft sync amount is controlled with ratio between master and slave frequencies.
--
-- > softSync slaveWave ratio masterWave
softSync :: SigSpace a => (Sig -> a) -> Sig -> (Sig -> a)
softSync :: (Sig -> a) -> Sig -> Sig -> a
softSync = SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
forall a. SigSpace a => SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
softSyncBy SyncSmooth
forall a. Default a => a
def

-- | Soft sync with given waveform (with raw square wave for switch). It's faster than `softSync`
-- The soft sync amount is controlled with ratio between master and slave frequencies.
--
-- > rawSoftSync slaveWave ratio masterWave
rawSoftSync :: SigSpace a => (Sig -> a) -> Sig -> (Sig -> a)
rawSoftSync :: (Sig -> a) -> Sig -> Sig -> a
rawSoftSync = SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
forall a. SigSpace a => SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
rawSoftSyncBy SyncSmooth
forall a. Default a => a
def

-- | Soft sync with given waveform (with band-limited square wave for switch).
-- The soft sync amount is controlled with ratio between master and slave frequencies.
-- With first argument we can specify the smoothness algorithm.
--
-- > softSyncBy spec slaveWave ratio masterWave
--
softSyncBy :: SigSpace a => SyncSmooth -> (Sig -> a) -> Sig -> (Sig -> a)
softSyncBy :: SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
softSyncBy = (Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
forall a.
SigSpace a =>
(Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
genSoftSync Sig -> Sig
sqr Tab -> Sig -> Sig
blosc

-- | Soft sync with given waveform (with raw square wave for switch). It's faster than `softSyncBy`
-- The soft sync amount is controlled with ratio between master and slave frequencies.
-- With first argument we can specify the smoothness algorithm.
--
-- > rawSoftSyncBy spec slaveWave ratio masterWave
--
rawSoftSyncBy :: SigSpace a => SyncSmooth -> (Sig -> a) -> Sig -> (Sig -> a)
rawSoftSyncBy :: SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
rawSoftSyncBy = (Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
forall a.
SigSpace a =>
(Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
genSoftSync Sig -> Sig
rawSqr Tab -> Sig -> Sig
oscBy

----------------------------------------------------------


-- | Soft sync with given waveform (with band-limited square wave for switch).
-- The soft sync amount is controlled with absolute frequency of the slave oscillator.
--
-- > softSyncAbs slaveWave ratio masterWave
softSyncAbs :: SigSpace a => (Sig -> a) -> Sig -> (Sig -> a)
softSyncAbs :: (Sig -> a) -> Sig -> Sig -> a
softSyncAbs = SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
forall a. SigSpace a => SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
softSyncAbsBy SyncSmooth
forall a. Default a => a
def

-- | Soft sync with given waveform (with raw square wave for switch). It's faster than `softSyncAbs`
-- The soft sync amount is controlled with absolute frequency of the slave oscillator.
--
-- > rawSoftSyncAbs slaveWave ratio masterWave
rawSoftSyncAbs :: SigSpace a => (Sig -> a) -> Sig -> (Sig -> a)
rawSoftSyncAbs :: (Sig -> a) -> Sig -> Sig -> a
rawSoftSyncAbs = SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
forall a. SigSpace a => SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
rawSoftSyncAbsBy SyncSmooth
forall a. Default a => a
def


-- | Soft sync with given waveform (with band-limited square wave for switch).
-- The soft sync amount is controlled with absolute frequency of the slave oscillator.
-- With first argument we can specify the smoothness algorithm.
--
-- > softSyncAbsBy spec slaveWave ratio masterWave
--
softSyncAbsBy :: SigSpace a => SyncSmooth -> (Sig -> a) -> Sig -> (Sig -> a)
softSyncAbsBy :: SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
softSyncAbsBy = (Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
forall a.
SigSpace a =>
(Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
genSoftSyncAbs Sig -> Sig
sqr Tab -> Sig -> Sig
blosc

-- | Soft sync with given waveform (with raw square wave for switch). It's faster than `softSyncAbsBy`
-- The soft sync amount is controlled with absolute frequency of the slave oscillator.
-- With first argument we can specify the smoothness algorithm.
--
-- > rawSoftSyncBy spec slaveWave ratio masterWave
--
rawSoftSyncAbsBy :: SigSpace a => SyncSmooth -> (Sig -> a) -> Sig -> (Sig -> a)
rawSoftSyncAbsBy :: SyncSmooth -> (Sig -> a) -> Sig -> Sig -> a
rawSoftSyncAbsBy = (Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
forall a.
SigSpace a =>
(Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
genSoftSyncAbs Sig -> Sig
rawSqr Tab -> Sig -> Sig
oscBy

----------------------------------------------------------

genSoftSync :: SigSpace a => (Sig -> Sig) -> (Tab -> Sig -> Sig) -> SyncSmooth -> (Sig -> a) -> Sig -> (Sig -> a)
genSoftSync :: (Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
genSoftSync Sig -> Sig
cpsSwitchWave Tab -> Sig -> Sig
smoothTabWave SyncSmooth
smoothType Sig -> a
wave Sig
ratio Sig
cps = (Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
forall a.
SigSpace a =>
(Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
genSoftSyncAbs Sig -> Sig
cpsSwitchWave Tab -> Sig -> Sig
smoothTabWave SyncSmooth
smoothType Sig -> a
wave (Sig
ratio Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
cps) Sig
cps

genSoftSyncAbs :: SigSpace a => (Sig -> Sig) -> (Tab -> Sig -> Sig) -> SyncSmooth -> (Sig -> a) -> Sig -> (Sig -> a)
genSoftSyncAbs :: (Sig -> Sig)
-> (Tab -> Sig -> Sig)
-> SyncSmooth
-> (Sig -> a)
-> Sig
-> Sig
-> a
genSoftSyncAbs Sig -> Sig
cpsSwitchWave Tab -> Sig -> Sig
smoothTabWave SyncSmooth
smoothType Sig -> a
wave Sig
slaveCps Sig
cps = (Sig -> a -> a) -> a -> Sig -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Sig -> a -> a
forall a. SigSpace a => Sig -> a -> a
mul a
rawSync (Sig -> a) -> Sig -> a
forall a b. (a -> b) -> a -> b
$ case SyncSmooth
smoothType of
    SyncSmooth
RawSync  -> Sig
1
    SyncSmooth
SawSync  -> Tab -> Sig -> Sig
smoothTabWave Tab
uniSawTab Sig
cps
    SyncSmooth
TriSync  -> Tab -> Sig -> Sig
smoothTabWave Tab
uniTriTab Sig
cps
    SyncSmooth
TrapSync -> Tab -> Sig -> Sig
smoothTabWave Tab
uniTrapTab Sig
cps
    UserSync Tab
t -> Tab -> Sig -> Sig
smoothTabWave Tab
t Sig
cps
    where
        rawSync :: a
rawSync = Sig -> a
wave (Sig -> Sig
ar (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig -> Sig
ar Sig
slaveCps Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* (Sig -> Sig
ar (Sig -> Sig) -> Sig -> Sig
forall a b. (a -> b) -> a -> b
$ Sig -> Sig
cpsSwitchWave Sig
cps))

------------------------------------------------------
-- PW and Ramp hard sync

-- pwSync