hsc3-0.21: Sound/Sc3/Ugen/Mce.hs
-- | Multiple channel expansion
module Sound.Sc3.Ugen.Mce where
import Control.Monad {- base -}
import Data.List {- base -}
import qualified Data.List.Split as Split {- split -}
import Sound.Sc3.Common.Uid {- hsc3 -}
import qualified Sound.Sc3.Ugen.Math as Math {- hsc3 -}
import Sound.Sc3.Ugen.Ugen {- hsc3 -}
-- | Construct a list of Ugens by applying f to consecutive identifiers (from z) and indices (from 0).
listFillId :: (Integral n, ID z, Enum z) => z -> Int -> (z -> n -> Ugen) -> [Ugen]
listFillId z n f = zipWith f [z ..] [0 .. fromIntegral n - 1]
-- | Construct a list of Ugens by applying f at consecutive indices (from 0).
listFillM :: (Uid m, Integral n) => Int -> (n -> m Ugen) -> m [Ugen]
listFillM n f = mapM f [0 .. fromIntegral n - 1]
-- | Construct a list of Ugens by applying f at consecutive indices (from 0).
listFill :: Integral n => Int -> (n -> Ugen) -> [Ugen]
listFill n f = map f [0 .. fromIntegral n - 1]
-- | 'mce' of 'replicate'
mceConst :: Int -> Ugen -> Ugen
mceConst n = mce . replicate n
-- | 'mce' of 'map' /f/ of 'id_seq' /n/.
mceGenId :: ID z => (Id -> Ugen) -> Int -> z -> Ugen
mceGenId f n = mce . map f . id_seq n
-- | Applicative variant of mceGenId.
mceGenM :: Applicative f => f Ugen -> Int -> f Ugen
mceGenM f n = fmap mce (replicateM n f)
-- | Count 'mce' channels.
mceSize :: Ugen -> Ugen
mceSize = constant . length . mceChannels
-- | Mix divided by number of inputs.
mceMean :: Ugen -> Ugen
mceMean e = let p = mceChannels e in Math.sum_opt p / constant (length p)
-- | Construct an Mce array of Ugens.
mceFill :: Integral n => Int -> (n -> Ugen) -> Ugen
mceFill n = mce . listFill n
-- | 'mce' of 'listFillId'
mceFillId :: (Integral n, ID z, Enum z) => z -> Int -> (z -> n -> Ugen) -> Ugen
mceFillId z n = mce . listFillId z n
-- | Type specialised mceFill
mceFillInt :: Int -> (Int -> Ugen) -> Ugen
mceFillInt = mceFill
-- | Collapse possible mce by summing.
mix :: Ugen -> Ugen
mix = Math.sum_opt . mceChannels
-- | Mix variant, sum to n channels.
mixTo :: Int -> Ugen -> Ugen
mixTo n u =
let xs = transpose (Split.chunksOf n (mceChannels u))
in mce (map Math.sum_opt xs)
-- | 'mix' of 'mceFill'
mixFill :: Integral n => Int -> (n -> Ugen) -> Ugen
mixFill n = mix . mceFill n
-- | Type specialised mixFill
mixFillInt :: Int -> (Int -> Ugen) -> Ugen
mixFillInt = mixFill
-- | Type specialised mixFill
mixFillUgen :: Int -> (Ugen -> Ugen) -> Ugen
mixFillUgen = mixFill
-- | 'mix' of 'mceFillId'
mixFillId :: (Integral n, ID z, Enum z) => z -> Int -> (z -> n -> Ugen) -> Ugen
mixFillId z n = mix . mceFillId z n
-- | Monad variant on mixFill.
mixFillM :: (Integral n, Monad m) => Int -> (n -> m Ugen) -> m Ugen
mixFillM n f = fmap Math.sum_opt (mapM f [0 .. fromIntegral n - 1])