-- | 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 import Csound.Typed.GlobalState -------------------------------------------------------------- -- no phase -- | A sawtooth. saw :: Sig -> Sig saw = noPhaseWave Saw -- | Integrated sawtooth: 4 * x * (1 - x). isaw :: Sig -> Sig isaw = noPhaseWave IntegratedSaw -- | A triangle wave. tri :: Sig -> Sig tri = noPhaseWave Triangle -- | Pulse (not normalized). pulse :: Sig -> Sig pulse = noPhaseWave Pulse -- | A square wave. sqr :: Sig -> Sig sqr = noPhaseWave Square -- | A band-limited oscillator with user defined waveform (it's stored in the table). blosc :: Tab -> Sig -> Sig blosc tab cps = hideGE $ do gen <- fromPreTab $ getPreTabUnsafe "blosc: tab should be primitive, not an expression." tab return $ noPhaseWave (UserGen gen) cps -------------------------------------------------------------- -- with phase -- | A sawtooth. saw' :: D -> Sig -> Sig saw' = withPhaseWave Saw -- | Integrated sawtooth: 4 * x * (1 - x). isaw' :: D -> Sig -> Sig isaw' = withPhaseWave IntegratedSaw -- | A triangle wave. tri' :: D -> Sig -> Sig tri' = withPhaseWave Triangle -- | Pulse (not normalized). pulse' :: D -> Sig -> Sig pulse' = withPhaseWave Pulse -- | A square wave. sqr' :: D -> Sig -> Sig sqr' = withPhaseWave Square -- | A band-limited oscillator with user defined waveform (it's stored in the table). blosc' :: Tab -> D -> Sig -> Sig blosc' tab phs cps = hideGE $ do gen <- fromPreTab $ getPreTabUnsafe "blosc: tab should be primitive, not an expression." tab return $ withPhaseWave (UserGen gen) phs cps -------------------------------------------------------------- noPhaseWave :: BandLimited -> Sig -> Sig noPhaseWave waveType cps = fromGE $ do expr <- toGE cps waveId <- saveBandLimitedWave waveType return $ readBandLimited Nothing waveId expr withPhaseWave :: BandLimited -> D -> Sig -> Sig withPhaseWave waveType phs cps = fromGE $ do expr <- toGE cps phsExpr <- toGE phs waveId <- saveBandLimitedWave waveType return $ readBandLimited (Just phsExpr) waveId expr -------------------------------------------------------------- -- no phase relative sync relativeSync :: (Sig -> Sig -> Sig) -> (Sig -> Sig -> Sig) relativeSync f ratioCps masterCps = f (ratioCps * masterCps) 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 = relativeSync 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 = relativeSync 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 = relativeSync 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 = relativeSync 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 = relativeSync 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 t = relativeSync (bloscSyncAbs t) -------------------------------------------------------------- relativeSync' :: (D -> Sig -> Sig -> Sig) -> (D -> Sig -> Sig -> Sig) relativeSync' f phase ratioCps masterCps = f phase (ratioCps * masterCps) 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' = relativeSync' 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' = relativeSync' 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' = relativeSync' 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' = relativeSync' 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' = relativeSync' 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' t = relativeSync' (bloscSyncAbs' t) -------------------------------------------------------------- -- no phase relative sync relativeSyncBy :: (SyncSmooth -> Sig -> Sig -> Sig) -> (SyncSmooth -> Sig -> Sig -> Sig) relativeSyncBy f smoothType ratioCps masterCps = f smoothType (ratioCps * masterCps) 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 = relativeSyncBy 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 = relativeSyncBy 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 = relativeSyncBy 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 = relativeSyncBy 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 = relativeSyncBy 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 smoothType t = relativeSyncBy (\smoothType -> bloscSyncAbsBy smoothType t) smoothType ------------------------------------------------------------ -- phase relativeSyncBy' :: (SyncSmooth -> D -> Sig -> Sig -> Sig) -> (SyncSmooth -> D -> Sig -> Sig -> Sig) relativeSyncBy' f smoothType phase ratioCps masterCps = f smoothType phase (ratioCps * masterCps) 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' = relativeSyncBy' 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' = relativeSyncBy' 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' = relativeSyncBy' 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' = relativeSyncBy' 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' = relativeSyncBy' 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' smoothType t = relativeSyncBy' (\smoothType -> bloscSyncAbsBy' smoothType t) 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 = sawSyncAbsBy 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 = isawSyncAbsBy 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 = triSyncAbsBy 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 = pulseSyncAbsBy 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 = sqrSyncAbsBy 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 = bloscSyncAbsBy 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' = sawSyncAbsBy' 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' = isawSyncAbsBy' 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' = triSyncAbsBy' 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' = pulseSyncAbsBy' 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' = sqrSyncAbsBy' 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' = bloscSyncAbsBy' def -------------------------------------------------------------- -- no phase -- | A hard sync for sawtooth with absolute slave frequency. -- -- > sawSyncAbs syncType salveCps masterCps sawSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig sawSyncAbsBy = noPhaseWaveHardSync 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 = noPhaseWaveHardSync IntegratedSaw -- | A hard sync for triangle wave with absolute slave frequency. -- -- > triSyncAbs syncType salveCps masterCps triSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig triSyncAbsBy = noPhaseWaveHardSync Triangle -- | A hard sync for pulse wave with absolute slave frequency. -- -- > pulseSyncAbs syncType salveCps masterCps pulseSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig pulseSyncAbsBy = noPhaseWaveHardSync Pulse -- | A hard sync for square wave with absolute slave frequency. -- -- > sqrSyncAbs syncType salveCps masterCps sqrSyncAbsBy :: SyncSmooth -> Sig -> Sig -> Sig sqrSyncAbsBy = noPhaseWaveHardSync 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 smoothType tab ratioCps cps = hideGE $ do gen <- fromPreTab $ getPreTabUnsafe "blosc: tab should be primitive, not an expression." tab return $ noPhaseWaveHardSync (UserGen gen) smoothType ratioCps cps -------------------------------------------------------------- -- with phase -- | A sawtooth. sawSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig sawSyncAbsBy' = withPhaseWaveHardSync Saw -- | Integrated sawtooth: 4 * x * (1 - x). isawSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig isawSyncAbsBy' = withPhaseWaveHardSync IntegratedSaw -- | A triangle wave. triSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig triSyncAbsBy' = withPhaseWaveHardSync Triangle -- | Pulse (not normalized). pulseSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig pulseSyncAbsBy' = withPhaseWaveHardSync Pulse -- | A square wave. sqrSyncAbsBy' :: SyncSmooth -> D -> Sig -> Sig -> Sig sqrSyncAbsBy' = withPhaseWaveHardSync Square -- | A band-limited oscillator with user defined waveform (it's stored in the table). bloscSyncAbsBy' :: SyncSmooth -> Tab -> D -> Sig -> Sig -> Sig bloscSyncAbsBy' smoothType tab phs ratioCps cps = hideGE $ do gen <- fromPreTab $ getPreTabUnsafe "blosc: tab should be primitive, not an expression." tab return $ withPhaseWaveHardSync (UserGen gen) smoothType phs ratioCps 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 = TrapSync getSyncShape :: SyncSmooth -> GE (Maybe BandLimited) getSyncShape x = case x of RawSync -> return $ Nothing SawSync -> gen7 4097 [1, 4097, 0] TriSync -> gen7 4097 [0, 2048, 1, 2049, 0] TrapSync -> gen7 4097 [1, 2048, 1, 2049, 0] UserSync tab -> do gen <- fromPreTab $ getPreTabUnsafe "blosc: tab should be primitive, not an expression." tab return $ Just $ UserGen gen where gen7 size args = return $ Just $ UserGen $ Gen { genSize = size, genId = IntGenId 7, genArgs = args, genFile = Nothing } noPhaseWaveHardSync :: BandLimited -> SyncSmooth -> Sig -> Sig -> Sig noPhaseWaveHardSync waveType smoothWaveType slaveCps cps = fromGE $ do smoothWave <- getSyncShape smoothWaveType exprSlaveCps <- toGE slaveCps exprCps <- toGE cps waveId <- saveBandLimitedWave waveType smoothWaveId <- case smoothWave of Nothing -> return Nothing Just wave -> fmap Just $ saveBandLimitedWave wave return $ readHardSyncBandLimited smoothWaveId Nothing waveId exprSlaveCps exprCps withPhaseWaveHardSync :: BandLimited -> SyncSmooth -> D -> Sig -> Sig -> Sig withPhaseWaveHardSync waveType smoothWaveType phs slaveCps cps = fromGE $ do smoothWave <- getSyncShape smoothWaveType phsExpr <- toGE phs exprSlaveCps <- toGE slaveCps exprCps <- toGE cps waveId <- saveBandLimitedWave waveType smoothWaveId <- case smoothWave of Nothing -> return Nothing Just wave -> fmap Just $ saveBandLimitedWave wave return $ readHardSyncBandLimited smoothWaveId (Just phsExpr) waveId exprSlaveCps exprCps