-- | Band-limited oscillators
module Csound.Typed.Control.Vco(
    saw, isaw, pulse, tri, sqr, blosc,
    saw', isaw', pulse', tri', sqr', blosc',

    -- * Hard sync
    SyncSmooth(..),

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

    -- ** Hard sync with absolute frequency for slave oscillator
    sawSyncAbs, isawSyncAbs, pulseSyncAbs, triSyncAbs, sqrSyncAbs, bloscSyncAbs,
    sawSyncAbs', isawSyncAbs', pulseSyncAbs', triSyncAbs', sqrSyncAbs', bloscSyncAbs',

    -- ** Hard sync with custom smoothing algorythm
    sawSyncBy, isawSyncBy, pulseSyncBy, triSyncBy, sqrSyncBy, bloscSyncBy,
    sawSyncBy', isawSyncBy', pulseSyncBy', triSyncBy', sqrSyncBy', bloscSyncBy',

    -- ** Hard sync with absolute frequency for slave oscillator
    sawSyncAbsBy, isawSyncAbsBy, pulseSyncAbsBy, triSyncAbsBy, sqrSyncAbsBy, bloscSyncAbsBy,
    sawSyncAbsBy', isawSyncAbsBy', pulseSyncAbsBy', triSyncAbsBy', sqrSyncAbsBy', bloscSyncAbsBy'


) where

import Data.Default

import Csound.Dynamic(Gen(..), GenId(..))
import Csound.Typed.GlobalState
import Csound.Typed.Types

--------------------------------------------------------------
-- no phase

-- | A sawtooth.
saw :: Sig -> Sig
saw :: Sig -> Sig
saw = BandLimited -> Sig -> Sig
noPhaseWave BandLimited
Saw

-- | Integrated sawtooth: 4 * x * (1 - x).
isaw :: Sig -> Sig
isaw :: Sig -> Sig
isaw = BandLimited -> Sig -> Sig
noPhaseWave BandLimited
IntegratedSaw

-- | A triangle wave.
tri :: Sig -> Sig
tri :: Sig -> Sig
tri = BandLimited -> Sig -> Sig
noPhaseWave BandLimited
Triangle

-- | Pulse (not normalized).
pulse :: Sig -> Sig
pulse :: Sig -> Sig
pulse = BandLimited -> Sig -> Sig
noPhaseWave BandLimited
Pulse

-- | A square wave.
sqr :: Sig -> Sig
sqr :: Sig -> Sig
sqr = BandLimited -> Sig -> Sig
noPhaseWave BandLimited
Square

-- | A band-limited oscillator with user defined waveform (it's stored in the table).
blosc :: Tab -> Sig -> Sig
blosc :: Tab -> Sig -> Sig
blosc Tab
tab Sig
cps = GE Sig -> Sig
forall a. Val a => GE a -> a
hideGE (GE Sig -> Sig) -> GE Sig -> Sig
forall a b. (a -> b) -> a -> b
$ do
    Gen
gen <- PreTab -> GE Gen
fromPreTab (PreTab -> GE Gen) -> PreTab -> GE Gen
forall a b. (a -> b) -> a -> b
$ String -> Tab -> PreTab
getPreTabUnsafe String
"blosc: tab should be primitive, not an expression." Tab
tab
    Sig -> GE Sig
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig -> GE Sig) -> Sig -> GE Sig
forall a b. (a -> b) -> a -> b
$ BandLimited -> Sig -> Sig
noPhaseWave (Gen -> BandLimited
UserGen Gen
gen) Sig
cps

--------------------------------------------------------------
-- with phase

-- | A sawtooth.
saw' :: D -> Sig -> Sig
saw' :: D -> Sig -> Sig
saw' = BandLimited -> D -> Sig -> Sig
withPhaseWave BandLimited
Saw

-- | Integrated sawtooth: 4 * x * (1 - x).
isaw' :: D -> Sig -> Sig
isaw' :: D -> Sig -> Sig
isaw' = BandLimited -> D -> Sig -> Sig
withPhaseWave BandLimited
IntegratedSaw

-- | A triangle wave.
tri' :: D -> Sig -> Sig
tri' :: D -> Sig -> Sig
tri' = BandLimited -> D -> Sig -> Sig
withPhaseWave BandLimited
Triangle

-- | Pulse (not normalized).
pulse' :: D -> Sig -> Sig
pulse' :: D -> Sig -> Sig
pulse' = BandLimited -> D -> Sig -> Sig
withPhaseWave BandLimited
Pulse

-- | A square wave.
sqr' :: D -> Sig -> Sig
sqr' :: D -> Sig -> Sig
sqr' = BandLimited -> D -> Sig -> Sig
withPhaseWave BandLimited
Square

-- | A band-limited oscillator with user defined waveform (it's stored in the table).
blosc' :: Tab -> D -> Sig -> Sig
blosc' :: Tab -> D -> Sig -> Sig
blosc' Tab
tab D
phs Sig
cps = GE Sig -> Sig
forall a. Val a => GE a -> a
hideGE (GE Sig -> Sig) -> GE Sig -> Sig
forall a b. (a -> b) -> a -> b
$ do
    Gen
gen <- PreTab -> GE Gen
fromPreTab (PreTab -> GE Gen) -> PreTab -> GE Gen
forall a b. (a -> b) -> a -> b
$ String -> Tab -> PreTab
getPreTabUnsafe String
"blosc: tab should be primitive, not an expression." Tab
tab
    Sig -> GE Sig
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig -> GE Sig) -> Sig -> GE Sig
forall a b. (a -> b) -> a -> b
$ BandLimited -> D -> Sig -> Sig
withPhaseWave (Gen -> BandLimited
UserGen Gen
gen) D
phs Sig
cps

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

noPhaseWave :: BandLimited -> Sig -> Sig
noPhaseWave :: BandLimited -> Sig -> Sig
noPhaseWave BandLimited
waveType Sig
cps = GE E -> Sig
forall a. Val a => GE E -> a
fromGE (GE E -> Sig) -> GE E -> Sig
forall a b. (a -> b) -> a -> b
$ do
    E
expr <- Sig -> GE E
forall a. Val a => a -> GE E
toGE Sig
cps
    BandLimitedId
waveId <- BandLimited -> GE BandLimitedId
saveBandLimitedWave BandLimited
waveType
    E -> GE E
forall (m :: * -> *) a. Monad m => a -> m a
return (E -> GE E) -> E -> GE E
forall a b. (a -> b) -> a -> b
$ Maybe E -> BandLimitedId -> E -> E
readBandLimited Maybe E
forall a. Maybe a
Nothing BandLimitedId
waveId E
expr

withPhaseWave :: BandLimited -> D -> Sig -> Sig
withPhaseWave :: BandLimited -> D -> Sig -> Sig
withPhaseWave BandLimited
waveType D
phs Sig
cps = GE E -> Sig
forall a. Val a => GE E -> a
fromGE (GE E -> Sig) -> GE E -> Sig
forall a b. (a -> b) -> a -> b
$ do
    E
expr <- Sig -> GE E
forall a. Val a => a -> GE E
toGE Sig
cps
    E
phsExpr <- D -> GE E
forall a. Val a => a -> GE E
toGE D
phs
    BandLimitedId
waveId <- BandLimited -> GE BandLimitedId
saveBandLimitedWave BandLimited
waveType
    E -> GE E
forall (m :: * -> *) a. Monad m => a -> m a
return (E -> GE E) -> E -> GE E
forall a b. (a -> b) -> a -> b
$ Maybe E -> BandLimitedId -> E -> E
readBandLimited (E -> Maybe E
forall a. a -> Maybe a
Just E
phsExpr) BandLimitedId
waveId E
expr

--------------------------------------------------------------
-- no phase relative sync

relativeSync :: (Sig -> Sig -> Sig) -> (Sig -> Sig -> Sig)
relativeSync :: (Sig -> Sig -> Sig) -> Sig -> Sig -> Sig
relativeSync Sig -> Sig -> Sig
f Sig
ratioCps Sig
masterCps = Sig -> Sig -> Sig
f (Sig
ratioCps Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
masterCps) Sig
masterCps

-- | Sawtooth oscillator with hard-sync.
-- The first argument is a ration between slave and master oscillators.
--
-- > sawSync ratio cps
sawSync :: Sig -> Sig -> Sig
sawSync :: Sig -> Sig -> Sig
sawSync = (Sig -> Sig -> Sig) -> Sig -> Sig -> Sig
relativeSync Sig -> Sig -> Sig
sawSyncAbs

-- | Integrated sawtooth oscillator with hard-sync.
-- The first argument is a ration between slave and master oscillators.
--
-- > isawSync ratio cps
isawSync :: Sig -> Sig -> Sig
isawSync :: Sig -> Sig -> Sig
isawSync = (Sig -> Sig -> Sig) -> Sig -> Sig -> Sig
relativeSync Sig -> Sig -> Sig
isawSyncAbs


-- | Triangle oscillator with hard-sync.
-- The first argument is a ration between slave and master oscillators.
--
-- > triSync ratio cps
triSync :: Sig -> Sig -> Sig
triSync :: Sig -> Sig -> Sig
triSync = (Sig -> Sig -> Sig) -> Sig -> Sig -> Sig
relativeSync Sig -> Sig -> Sig
triSyncAbs

-- | Pulse oscillator with hard-sync.
-- The first argument is a ration between slave and master oscillators.
--
-- > pulseSync ratio cps
pulseSync :: Sig -> Sig -> Sig
pulseSync :: Sig -> Sig -> Sig
pulseSync = (Sig -> Sig -> Sig) -> Sig -> Sig -> Sig
relativeSync Sig -> Sig -> Sig
pulseSyncAbs

-- | Square oscillator with hard-sync.
-- The first argument is a ration between slave and master oscillators.
--
-- > sqrSync ratio cps
sqrSync :: Sig -> Sig -> Sig
sqrSync :: Sig -> Sig -> Sig
sqrSync = (Sig -> Sig -> Sig) -> Sig -> Sig -> Sig
relativeSync Sig -> Sig -> Sig
sqrSyncAbs

-- | Band-limited oscillator with hard-sync.
-- The first argument is a ration between slave and master oscillators.
--
-- > bloscSync tab ratio cps
bloscSync :: Tab -> Sig -> Sig -> Sig
bloscSync :: Tab -> Sig -> Sig -> Sig
bloscSync Tab
t = (Sig -> Sig -> Sig) -> Sig -> Sig -> Sig
relativeSync (Tab -> Sig -> Sig -> Sig
bloscSyncAbs Tab
t)

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


relativeSync' :: (D -> Sig -> Sig -> Sig) -> (D -> Sig -> Sig -> Sig)
relativeSync' :: (D -> Sig -> Sig -> Sig) -> D -> Sig -> Sig -> Sig
relativeSync' D -> Sig -> Sig -> Sig
f D
phase Sig
ratioCps Sig
masterCps = D -> Sig -> Sig -> Sig
f D
phase (Sig
ratioCps Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
masterCps) Sig
masterCps

-- | Sawtooth oscillator with hard-sync with phase.
-- The second argument is a ration between slave and master oscillators.
--
-- > sawSync' phase ratio cps
sawSync' :: D -> Sig -> Sig -> Sig
sawSync' :: D -> Sig -> Sig -> Sig
sawSync' = (D -> Sig -> Sig -> Sig) -> D -> Sig -> Sig -> Sig
relativeSync' D -> Sig -> Sig -> Sig
sawSyncAbs'

-- | Integrated sawtooth oscillator with hard-sync with phase.
-- The second argument is a ration between slave and master oscillators.
--
-- > isawSync' phase ratio cps
isawSync' :: D -> Sig -> Sig -> Sig
isawSync' :: D -> Sig -> Sig -> Sig
isawSync' = (D -> Sig -> Sig -> Sig) -> D -> Sig -> Sig -> Sig
relativeSync' D -> Sig -> Sig -> Sig
isawSyncAbs'

-- | Triangle oscillator with hard-sync with phase.
-- The second argument is a ration between slave and master oscillators.
--
-- > triSync' phase ratio cps
triSync' :: D -> Sig -> Sig -> Sig
triSync' :: D -> Sig -> Sig -> Sig
triSync' = (D -> Sig -> Sig -> Sig) -> D -> Sig -> Sig -> Sig
relativeSync' D -> Sig -> Sig -> Sig
triSyncAbs'

-- | Pulse oscillator with hard-sync with phase.
-- The second argument is a ration between slave and master oscillators.
--
-- > pulseSync' phase ratio cps
pulseSync' :: D -> Sig -> Sig -> Sig
pulseSync' :: D -> Sig -> Sig -> Sig
pulseSync' = (D -> Sig -> Sig -> Sig) -> D -> Sig -> Sig -> Sig
relativeSync' D -> Sig -> Sig -> Sig
pulseSyncAbs'

-- | Square oscillator with hard-sync with phase.
-- The second argument is a ration between slave and master oscillators.
--
-- > sqrSync' phase ratio cps
sqrSync' :: D -> Sig -> Sig -> Sig
sqrSync' :: D -> Sig -> Sig -> Sig
sqrSync' = (D -> Sig -> Sig -> Sig) -> D -> Sig -> Sig -> Sig
relativeSync' D -> Sig -> Sig -> Sig
sqrSyncAbs'

-- | Band-limited oscillator with hard-sync with phase.
-- The second argument is a ration between slave and master oscillators.
--
-- > bloscSync' phase tab ratio cps
bloscSync' :: Tab -> D -> Sig -> Sig -> Sig
bloscSync' :: Tab -> D -> Sig -> Sig -> Sig
bloscSync' Tab
t = (D -> Sig -> Sig -> Sig) -> D -> Sig -> Sig -> Sig
relativeSync' (Tab -> D -> Sig -> Sig -> Sig
bloscSyncAbs' Tab
t)

--------------------------------------------------------------
-- no phase relative sync

relativeSyncBy :: (SyncSmooth -> Sig -> Sig -> Sig) -> (SyncSmooth -> Sig -> Sig -> Sig)
relativeSyncBy :: (SyncSmooth -> Sig -> Sig -> Sig)
-> SyncSmooth -> Sig -> Sig -> Sig
relativeSyncBy SyncSmooth -> Sig -> Sig -> Sig
f SyncSmooth
smoothType Sig
ratioCps Sig
masterCps = SyncSmooth -> Sig -> Sig -> Sig
f SyncSmooth
smoothType (Sig
ratioCps Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
masterCps) Sig
masterCps

-- | Sawtooth oscillator with hard-sync. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > sawSyncBy spec ratio cps
sawSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
sawSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
sawSyncBy = (SyncSmooth -> Sig -> Sig -> Sig)
-> SyncSmooth -> Sig -> Sig -> Sig
relativeSyncBy SyncSmooth -> Sig -> Sig -> Sig
sawSyncAbsBy

-- | Integrated sawtooth oscillator with hard-sync. We can specify the smoothness type.
-- The first argument is a ration between slave and master oscillators.
--
-- > isawSyncB specy ratio cps
isawSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
isawSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
isawSyncBy = (SyncSmooth -> Sig -> Sig -> Sig)
-> SyncSmooth -> Sig -> Sig -> Sig
relativeSyncBy SyncSmooth -> Sig -> Sig -> Sig
isawSyncAbsBy

-- | Triangle oscillator with hard-sync. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > triSyncBy spec ratio cps
triSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
triSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
triSyncBy = (SyncSmooth -> Sig -> Sig -> Sig)
-> SyncSmooth -> Sig -> Sig -> Sig
relativeSyncBy SyncSmooth -> Sig -> Sig -> Sig
triSyncAbsBy

-- | Pulse oscillator with hard-sync. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > pulseSyncBy spec ratio cps
pulseSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
pulseSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
pulseSyncBy = (SyncSmooth -> Sig -> Sig -> Sig)
-> SyncSmooth -> Sig -> Sig -> Sig
relativeSyncBy SyncSmooth -> Sig -> Sig -> Sig
pulseSyncAbsBy

-- | Square oscillator with hard-sync. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > sawSyncBy spec ratio cps
sqrSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
sqrSyncBy :: SyncSmooth -> Sig -> Sig -> Sig
sqrSyncBy = (SyncSmooth -> Sig -> Sig -> Sig)
-> SyncSmooth -> Sig -> Sig -> Sig
relativeSyncBy SyncSmooth -> Sig -> Sig -> Sig
sqrSyncAbsBy

-- | Bandlimited table oscillator with hard-sync. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > bloscSyncBy spec tab ratio cps
bloscSyncBy :: SyncSmooth -> Tab -> Sig -> Sig -> Sig
bloscSyncBy :: SyncSmooth -> Tab -> Sig -> Sig -> Sig
bloscSyncBy SyncSmooth
smoothType Tab
t = (SyncSmooth -> Sig -> Sig -> Sig)
-> SyncSmooth -> Sig -> Sig -> Sig
relativeSyncBy (\SyncSmooth
smoothTy -> SyncSmooth -> Tab -> Sig -> Sig -> Sig
bloscSyncAbsBy SyncSmooth
smoothTy Tab
t) SyncSmooth
smoothType

------------------------------------------------------------
-- phase

relativeSyncBy' :: (SyncSmooth -> D -> Sig -> Sig -> Sig) -> (SyncSmooth -> D -> Sig -> Sig -> Sig)
relativeSyncBy' :: (SyncSmooth -> D -> Sig -> Sig -> Sig)
-> SyncSmooth -> D -> Sig -> Sig -> Sig
relativeSyncBy' SyncSmooth -> D -> Sig -> Sig -> Sig
f SyncSmooth
smoothType D
phase Sig
ratioCps Sig
masterCps = SyncSmooth -> D -> Sig -> Sig -> Sig
f SyncSmooth
smoothType D
phase (Sig
ratioCps Sig -> Sig -> Sig
forall a. Num a => a -> a -> a
* Sig
masterCps) Sig
masterCps

-- | Sawtooth oscillator with hard-sync with phase. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > sawSyncBy' spec phase ratio cps
sawSyncBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
sawSyncBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
sawSyncBy' = (SyncSmooth -> D -> Sig -> Sig -> Sig)
-> SyncSmooth -> D -> Sig -> Sig -> Sig
relativeSyncBy' SyncSmooth -> D -> Sig -> Sig -> Sig
sawSyncAbsBy'

-- | Integrated sawtooth oscillator with hard-sync with phase. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > isawSyncBy' spec phase ratio cps
isawSyncBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
isawSyncBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
isawSyncBy' = (SyncSmooth -> D -> Sig -> Sig -> Sig)
-> SyncSmooth -> D -> Sig -> Sig -> Sig
relativeSyncBy' SyncSmooth -> D -> Sig -> Sig -> Sig
isawSyncAbsBy'

-- | Triangle oscillator with hard-sync with phase. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > triSyncBy' spec phase ratio cps
triSyncBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
triSyncBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
triSyncBy' = (SyncSmooth -> D -> Sig -> Sig -> Sig)
-> SyncSmooth -> D -> Sig -> Sig -> Sig
relativeSyncBy' SyncSmooth -> D -> Sig -> Sig -> Sig
triSyncAbsBy'

-- | Pulse oscillator with hard-sync with phase. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > pulseSyncBy' spec phase ratio cps
pulseSyncBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
pulseSyncBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
pulseSyncBy' = (SyncSmooth -> D -> Sig -> Sig -> Sig)
-> SyncSmooth -> D -> Sig -> Sig -> Sig
relativeSyncBy' SyncSmooth -> D -> Sig -> Sig -> Sig
pulseSyncAbsBy'

-- | Square oscillator with hard-sync with phase. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > sawSyncBy' spec phase ratio cps
sqrSyncBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
sqrSyncBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
sqrSyncBy' = (SyncSmooth -> D -> Sig -> Sig -> Sig)
-> SyncSmooth -> D -> Sig -> Sig -> Sig
relativeSyncBy' SyncSmooth -> D -> Sig -> Sig -> Sig
sqrSyncAbsBy'

-- | Bandlimited table oscillator with hard-sync with phase. We can specify the smoothness type.
-- The @ratio@ argument is a ration between slave and master oscillators.
--
-- > bloscSyncBy' spec phase tab ratio cps
bloscSyncBy' :: SyncSmooth -> Tab -> D -> Sig -> Sig -> Sig
bloscSyncBy' :: SyncSmooth -> Tab -> D -> Sig -> Sig -> Sig
bloscSyncBy' SyncSmooth
smoothType Tab
t = (SyncSmooth -> D -> Sig -> Sig -> Sig)
-> SyncSmooth -> D -> Sig -> Sig -> Sig
relativeSyncBy' (\SyncSmooth
smoothTy -> SyncSmooth -> Tab -> D -> Sig -> Sig -> Sig
bloscSyncAbsBy' SyncSmooth
smoothTy Tab
t) SyncSmooth
smoothType

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

-- | Sawtooth oscillator with hard-sync.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > sawSyncAbs freq slaveCps masterCps
sawSyncAbs :: Sig -> Sig -> Sig
sawSyncAbs :: Sig -> Sig -> Sig
sawSyncAbs = SyncSmooth -> Sig -> Sig -> Sig
sawSyncAbsBy SyncSmooth
forall a. Default a => a
def

-- | Integrated sawtooth oscillator with hard-sync.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > isawSyncAbs freq slaveCps masterCps
isawSyncAbs :: Sig -> Sig -> Sig
isawSyncAbs :: Sig -> Sig -> Sig
isawSyncAbs = SyncSmooth -> Sig -> Sig -> Sig
isawSyncAbsBy SyncSmooth
forall a. Default a => a
def

-- | Triangle oscillator with hard-sync.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > triSyncAbs freq slaveCps masterCps
triSyncAbs :: Sig -> Sig -> Sig
triSyncAbs :: Sig -> Sig -> Sig
triSyncAbs = SyncSmooth -> Sig -> Sig -> Sig
triSyncAbsBy SyncSmooth
forall a. Default a => a
def

-- | Pulse oscillator with hard-sync.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > pulseSyncAbs freq slaveCps masterCps
pulseSyncAbs :: Sig -> Sig -> Sig
pulseSyncAbs :: Sig -> Sig -> Sig
pulseSyncAbs = SyncSmooth -> Sig -> Sig -> Sig
pulseSyncAbsBy SyncSmooth
forall a. Default a => a
def

-- | Square oscillator with hard-sync.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > sqrSyncAbs freq slaveCps masterCps
sqrSyncAbs :: Sig -> Sig -> Sig
sqrSyncAbs :: Sig -> Sig -> Sig
sqrSyncAbs = SyncSmooth -> Sig -> Sig -> Sig
sqrSyncAbsBy SyncSmooth
forall a. Default a => a
def

-- | Bandlimited table oscillator with hard-sync.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > bloscSyncAbs tab freq slaveCps masterCps
bloscSyncAbs :: Tab -> Sig -> Sig -> Sig
bloscSyncAbs :: Tab -> Sig -> Sig -> Sig
bloscSyncAbs = SyncSmooth -> Tab -> Sig -> Sig -> Sig
bloscSyncAbsBy SyncSmooth
forall a. Default a => a
def

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

-- | Sawtooth oscillator with hard-sync with phase.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > sawSyncAbs' phase freq slaveCps masterCps
sawSyncAbs' :: D -> Sig -> Sig -> Sig
sawSyncAbs' :: D -> Sig -> Sig -> Sig
sawSyncAbs' = SyncSmooth -> D -> Sig -> Sig -> Sig
sawSyncAbsBy' SyncSmooth
forall a. Default a => a
def

-- | Integrated sawtooth oscillator with hard-sync with phase.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > isawSyncAbs' phase freq slaveCps masterCps
isawSyncAbs' :: D -> Sig -> Sig -> Sig
isawSyncAbs' :: D -> Sig -> Sig -> Sig
isawSyncAbs' = SyncSmooth -> D -> Sig -> Sig -> Sig
isawSyncAbsBy' SyncSmooth
forall a. Default a => a
def

-- | Triangle oscillator with hard-sync with phase.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > triSyncAbs' phase freq slaveCps masterCps
triSyncAbs' :: D -> Sig -> Sig -> Sig
triSyncAbs' :: D -> Sig -> Sig -> Sig
triSyncAbs' = SyncSmooth -> D -> Sig -> Sig -> Sig
triSyncAbsBy' SyncSmooth
forall a. Default a => a
def

-- | Pulse oscillator with hard-sync with phase.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > pulseSyncAbs' phase freq slaveCps masterCps
pulseSyncAbs' :: D -> Sig -> Sig -> Sig
pulseSyncAbs' :: D -> Sig -> Sig -> Sig
pulseSyncAbs' = SyncSmooth -> D -> Sig -> Sig -> Sig
pulseSyncAbsBy' SyncSmooth
forall a. Default a => a
def

-- | Square oscillator with hard-sync with phase.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > sqrSyncAbs' phase freq slaveCps masterCps
sqrSyncAbs' :: D -> Sig -> Sig -> Sig
sqrSyncAbs' :: D -> Sig -> Sig -> Sig
sqrSyncAbs' = SyncSmooth -> D -> Sig -> Sig -> Sig
sqrSyncAbsBy' SyncSmooth
forall a. Default a => a
def

-- | Bandlimited table oscillator with hard-sync with phase.
-- The @freq@ argument is an absolute frequency of a slave oscillator.
--
-- > bloscSyncAbs' phase tab freq slaveCps masterCps
bloscSyncAbs' :: Tab -> D -> Sig -> Sig -> Sig
bloscSyncAbs' :: Tab -> D -> Sig -> Sig -> Sig
bloscSyncAbs' = SyncSmooth -> Tab -> D -> Sig -> Sig -> Sig
bloscSyncAbsBy' SyncSmooth
forall a. Default a => a
def

--------------------------------------------------------------
-- no phase

-- | A hard sync for sawtooth with absolute slave frequency.
--
-- > sawSyncAbs syncType salveCps masterCps
sawSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
sawSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
sawSyncAbsBy = BandLimited -> SyncSmooth -> Sig -> Sig -> Sig
noPhaseWaveHardSync BandLimited
Saw

-- | A hard sync for integrated sawtooth: 4 * x * (1 - x) with absolute slave frequency.
--
-- > isawSyncAbs syncType salveCps masterCps
isawSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
isawSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
isawSyncAbsBy = BandLimited -> SyncSmooth -> Sig -> Sig -> Sig
noPhaseWaveHardSync BandLimited
IntegratedSaw

-- | A hard sync for triangle wave with absolute slave frequency.
--
-- > triSyncAbs syncType salveCps masterCps
triSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
triSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
triSyncAbsBy = BandLimited -> SyncSmooth -> Sig -> Sig -> Sig
noPhaseWaveHardSync BandLimited
Triangle

-- | A hard sync for pulse wave with absolute slave frequency.
--
-- > pulseSyncAbs syncType salveCps masterCps
pulseSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
pulseSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
pulseSyncAbsBy = BandLimited -> SyncSmooth -> Sig -> Sig -> Sig
noPhaseWaveHardSync BandLimited
Pulse

-- | A hard sync for square wave with absolute slave frequency.
--
-- > sqrSyncAbs syncType salveCps masterCps
sqrSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
sqrSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig
sqrSyncAbsBy = BandLimited -> SyncSmooth -> Sig -> Sig -> Sig
noPhaseWaveHardSync BandLimited
Square

-- | A hard sync for band-limited oscillator with user defined waveform (it's stored in the table) woth absolute frequency.
--
-- > bloscSyncAbs syncType ftable salveCps masterCps
bloscSyncAbsBy :: SyncSmooth -> Tab -> Sig -> Sig -> Sig
bloscSyncAbsBy :: SyncSmooth -> Tab -> Sig -> Sig -> Sig
bloscSyncAbsBy SyncSmooth
smoothType Tab
tab Sig
ratioCps Sig
cps = GE Sig -> Sig
forall a. Val a => GE a -> a
hideGE (GE Sig -> Sig) -> GE Sig -> Sig
forall a b. (a -> b) -> a -> b
$ do
    Gen
gen <- PreTab -> GE Gen
fromPreTab (PreTab -> GE Gen) -> PreTab -> GE Gen
forall a b. (a -> b) -> a -> b
$ String -> Tab -> PreTab
getPreTabUnsafe String
"blosc: tab should be primitive, not an expression." Tab
tab
    Sig -> GE Sig
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig -> GE Sig) -> Sig -> GE Sig
forall a b. (a -> b) -> a -> b
$ BandLimited -> SyncSmooth -> Sig -> Sig -> Sig
noPhaseWaveHardSync (Gen -> BandLimited
UserGen Gen
gen) SyncSmooth
smoothType Sig
ratioCps Sig
cps

--------------------------------------------------------------
-- with phase

-- | A sawtooth.
sawSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
sawSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
sawSyncAbsBy' = BandLimited -> SyncSmooth -> D -> Sig -> Sig -> Sig
withPhaseWaveHardSync BandLimited
Saw

-- | Integrated sawtooth: 4 * x * (1 - x).
isawSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
isawSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
isawSyncAbsBy' = BandLimited -> SyncSmooth -> D -> Sig -> Sig -> Sig
withPhaseWaveHardSync BandLimited
IntegratedSaw

-- | A triangle wave.
triSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
triSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
triSyncAbsBy' = BandLimited -> SyncSmooth -> D -> Sig -> Sig -> Sig
withPhaseWaveHardSync BandLimited
Triangle

-- | Pulse (not normalized).
pulseSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
pulseSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
pulseSyncAbsBy' = BandLimited -> SyncSmooth -> D -> Sig -> Sig -> Sig
withPhaseWaveHardSync BandLimited
Pulse

-- | A square wave.
sqrSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
sqrSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig
sqrSyncAbsBy' = BandLimited -> SyncSmooth -> D -> Sig -> Sig -> Sig
withPhaseWaveHardSync BandLimited
Square

-- | A band-limited oscillator with user defined waveform (it's stored in the table).
bloscSyncAbsBy' :: SyncSmooth -> Tab -> D -> Sig -> Sig -> Sig
bloscSyncAbsBy' :: SyncSmooth -> Tab -> D -> Sig -> Sig -> Sig
bloscSyncAbsBy' SyncSmooth
smoothType Tab
tab D
phs Sig
ratioCps Sig
cps = GE Sig -> Sig
forall a. Val a => GE a -> a
hideGE (GE Sig -> Sig) -> GE Sig -> Sig
forall a b. (a -> b) -> a -> b
$ do
    Gen
gen <- PreTab -> GE Gen
fromPreTab (PreTab -> GE Gen) -> PreTab -> GE Gen
forall a b. (a -> b) -> a -> b
$ String -> Tab -> PreTab
getPreTabUnsafe String
"blosc: tab should be primitive, not an expression." Tab
tab
    Sig -> GE Sig
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig -> GE Sig) -> Sig -> GE Sig
forall a b. (a -> b) -> a -> b
$ BandLimited -> SyncSmooth -> D -> Sig -> Sig -> Sig
withPhaseWaveHardSync (Gen -> BandLimited
UserGen Gen
gen) SyncSmooth
smoothType D
phs Sig
ratioCps Sig
cps

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

-- | Type of smooth shape to make smooth transitions on retrigger.
-- Available types are:
--
-- * No smooth: @RawSync@
--
-- * Ramp smooth: @SawSync@
--
-- * Triangular smooth: @TriSync@
--
-- * User defined shape: @UserSync@
data SyncSmooth = RawSync | SawSync | TriSync | TrapSync | UserSync Tab

instance Default SyncSmooth where
    def :: SyncSmooth
def = SyncSmooth
TrapSync

getSyncShape :: SyncSmooth -> GE (Maybe BandLimited)
getSyncShape :: SyncSmooth -> GE (Maybe BandLimited)
getSyncShape SyncSmooth
x = case SyncSmooth
x of
    SyncSmooth
RawSync -> Maybe BandLimited -> GE (Maybe BandLimited)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe BandLimited -> GE (Maybe BandLimited))
-> Maybe BandLimited -> GE (Maybe BandLimited)
forall a b. (a -> b) -> a -> b
$ Maybe BandLimited
forall a. Maybe a
Nothing
    SyncSmooth
SawSync -> Int -> [Double] -> GE (Maybe BandLimited)
forall (m :: * -> *).
Monad m =>
Int -> [Double] -> m (Maybe BandLimited)
gen7 Int
4097 [Double
1, Double
4097, Double
0]
    SyncSmooth
TriSync -> Int -> [Double] -> GE (Maybe BandLimited)
forall (m :: * -> *).
Monad m =>
Int -> [Double] -> m (Maybe BandLimited)
gen7 Int
4097 [Double
0, Double
2048, Double
1, Double
2049, Double
0]
    SyncSmooth
TrapSync -> Int -> [Double] -> GE (Maybe BandLimited)
forall (m :: * -> *).
Monad m =>
Int -> [Double] -> m (Maybe BandLimited)
gen7 Int
4097 [Double
1, Double
2048, Double
1, Double
2049, Double
0]
    UserSync Tab
tab -> do
        Gen
gen <- PreTab -> GE Gen
fromPreTab (PreTab -> GE Gen) -> PreTab -> GE Gen
forall a b. (a -> b) -> a -> b
$ String -> Tab -> PreTab
getPreTabUnsafe String
"blosc: tab should be primitive, not an expression." Tab
tab
        Maybe BandLimited -> GE (Maybe BandLimited)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe BandLimited -> GE (Maybe BandLimited))
-> Maybe BandLimited -> GE (Maybe BandLimited)
forall a b. (a -> b) -> a -> b
$ BandLimited -> Maybe BandLimited
forall a. a -> Maybe a
Just (BandLimited -> Maybe BandLimited)
-> BandLimited -> Maybe BandLimited
forall a b. (a -> b) -> a -> b
$ Gen -> BandLimited
UserGen Gen
gen
    where
        gen7 :: Int -> [Double] -> m (Maybe BandLimited)
gen7 Int
size [Double]
args = Maybe BandLimited -> m (Maybe BandLimited)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe BandLimited -> m (Maybe BandLimited))
-> Maybe BandLimited -> m (Maybe BandLimited)
forall a b. (a -> b) -> a -> b
$ BandLimited -> Maybe BandLimited
forall a. a -> Maybe a
Just (BandLimited -> Maybe BandLimited)
-> BandLimited -> Maybe BandLimited
forall a b. (a -> b) -> a -> b
$ Gen -> BandLimited
UserGen (Gen -> BandLimited) -> Gen -> BandLimited
forall a b. (a -> b) -> a -> b
$ Gen :: Int -> GenId -> [Double] -> Maybe String -> Gen
Gen { genSize :: Int
genSize = Int
size, genId :: GenId
genId = Int -> GenId
IntGenId Int
7, genArgs :: [Double]
genArgs = [Double]
args, genFile :: Maybe String
genFile = Maybe String
forall a. Maybe a
Nothing }

noPhaseWaveHardSync :: BandLimited -> SyncSmooth -> Sig -> Sig -> Sig
noPhaseWaveHardSync :: BandLimited -> SyncSmooth -> Sig -> Sig -> Sig
noPhaseWaveHardSync BandLimited
waveType SyncSmooth
smoothWaveType Sig
slaveCps Sig
cps = GE E -> Sig
forall a. Val a => GE E -> a
fromGE (GE E -> Sig) -> GE E -> Sig
forall a b. (a -> b) -> a -> b
$ do
    Maybe BandLimited
smoothWave <- SyncSmooth -> GE (Maybe BandLimited)
getSyncShape SyncSmooth
smoothWaveType
    E
exprSlaveCps <- Sig -> GE E
forall a. Val a => a -> GE E
toGE Sig
slaveCps
    E
exprCps <- Sig -> GE E
forall a. Val a => a -> GE E
toGE Sig
cps
    BandLimitedId
waveId <- BandLimited -> GE BandLimitedId
saveBandLimitedWave BandLimited
waveType
    Maybe BandLimitedId
smoothWaveId <- case Maybe BandLimited
smoothWave of
        Maybe BandLimited
Nothing -> Maybe BandLimitedId -> GE (Maybe BandLimitedId)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe BandLimitedId
forall a. Maybe a
Nothing
        Just BandLimited
wave -> (BandLimitedId -> Maybe BandLimitedId)
-> GE BandLimitedId -> GE (Maybe BandLimitedId)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap BandLimitedId -> Maybe BandLimitedId
forall a. a -> Maybe a
Just (GE BandLimitedId -> GE (Maybe BandLimitedId))
-> GE BandLimitedId -> GE (Maybe BandLimitedId)
forall a b. (a -> b) -> a -> b
$ BandLimited -> GE BandLimitedId
saveBandLimitedWave BandLimited
wave
    E -> GE E
forall (m :: * -> *) a. Monad m => a -> m a
return (E -> GE E) -> E -> GE E
forall a b. (a -> b) -> a -> b
$ Maybe BandLimitedId -> Maybe E -> BandLimitedId -> E -> E -> E
readHardSyncBandLimited Maybe BandLimitedId
smoothWaveId Maybe E
forall a. Maybe a
Nothing BandLimitedId
waveId E
exprSlaveCps E
exprCps

withPhaseWaveHardSync :: BandLimited -> SyncSmooth -> D -> Sig -> Sig -> Sig
withPhaseWaveHardSync :: BandLimited -> SyncSmooth -> D -> Sig -> Sig -> Sig
withPhaseWaveHardSync BandLimited
waveType SyncSmooth
smoothWaveType D
phs Sig
slaveCps Sig
cps = GE E -> Sig
forall a. Val a => GE E -> a
fromGE (GE E -> Sig) -> GE E -> Sig
forall a b. (a -> b) -> a -> b
$ do
    Maybe BandLimited
smoothWave <- SyncSmooth -> GE (Maybe BandLimited)
getSyncShape SyncSmooth
smoothWaveType
    E
phsExpr <- D -> GE E
forall a. Val a => a -> GE E
toGE D
phs
    E
exprSlaveCps <- Sig -> GE E
forall a. Val a => a -> GE E
toGE Sig
slaveCps
    E
exprCps <- Sig -> GE E
forall a. Val a => a -> GE E
toGE Sig
cps
    BandLimitedId
waveId <- BandLimited -> GE BandLimitedId
saveBandLimitedWave BandLimited
waveType
    Maybe BandLimitedId
smoothWaveId <- case Maybe BandLimited
smoothWave of
        Maybe BandLimited
Nothing -> Maybe BandLimitedId -> GE (Maybe BandLimitedId)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe BandLimitedId
forall a. Maybe a
Nothing
        Just BandLimited
wave -> (BandLimitedId -> Maybe BandLimitedId)
-> GE BandLimitedId -> GE (Maybe BandLimitedId)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap BandLimitedId -> Maybe BandLimitedId
forall a. a -> Maybe a
Just (GE BandLimitedId -> GE (Maybe BandLimitedId))
-> GE BandLimitedId -> GE (Maybe BandLimitedId)
forall a b. (a -> b) -> a -> b
$ BandLimited -> GE BandLimitedId
saveBandLimitedWave BandLimited
wave
    E -> GE E
forall (m :: * -> *) a. Monad m => a -> m a
return (E -> GE E) -> E -> GE E
forall a b. (a -> b) -> a -> b
$ Maybe BandLimitedId -> Maybe E -> BandLimitedId -> E -> E -> E
readHardSyncBandLimited Maybe BandLimitedId
smoothWaveId (E -> Maybe E
forall a. a -> Maybe a
Just E
phsExpr) BandLimitedId
waveId E
exprSlaveCps E
exprCps