module Effects where import Data.List import Types addEffects :: [DSPEffect] -> SampledSignal -> SampledSignal addEffects = foldr (.) id applyEffectToInterval :: (Seconds, Seconds) -> SampledSignal -> DSPEffect -> SampledSignal applyEffectToInterval (from, to) signal effect -- assert that from >= 0, to - from >= 0, to <= length signal and simply return original signal if constraints aren't met | from < 0 || from > to || samplesPerSecond to > length signal = signal | otherwise = samplesBefore ++ samplesDuring ++ samplesAfter where samplesBefore = take nSamplesBefore signal -- unaffected samplesDuring = effect $ take nSamplesDuring (drop nSamplesBefore signal) -- effected samplesAfter = drop (nSamplesBefore + nSamplesDuring) signal -- unaffected nSamplesBefore = samplesPerSecond from nSamplesDuring = samplesPerSecond (to - from) gain :: Double gain = 2.0 clippingThreshold :: Double clippingThreshold = 0.8 clip :: Double -> DSPEffect clip threshold = map (\sample -> if sample > 0 then min threshold sample else max (negate threshold) sample) -- clip positive and negative samples addGain :: Double -> DSPEffect addGain value = map (* value) distortion :: DSPEffect distortion = clip clippingThreshold . addGain gain -- add more effects here echo :: Seconds -> DSPEffect echo t xs = hilf xs (replicate (samplesPerSecond t) 0.0) [] where ss = (replicate (samplesPerSecond t) 0.0) ++ xs hilf :: SampledSignal -> SampledSignal -> SampledSignal -> SampledSignal hilf [] _ _ = [] hilf (x:xs) (y:ys) sx = let nxt = (0.7*x + 0.3*y) in nxt : hilf xs ys (nxt:sx) hilf xs [] sx = hilf xs (reverse sx) [] crush :: DSPEffect crush = map (\sample -> fromIntegral(floor(sample*64))/64) ampM :: Signal -> Hz -> DSPEffect ampM ss frq xs = zipWith (*) xs nxs where spp = samplesPerPeriod frq fpp = fromIntegral spp nxs = [ss ((fromIntegral(mod i spp))/fpp) | i <- [0..(length xs - 1)]] ffrq :: [Int] -> DSPEffect --ffrq ys xs = let s = fromIntegral(length ys) in map (/s) $ hilf ys xs ffrq ys xs = hilf ys xs where hilf :: [Int] -> DSPEffect hilf [] ps = ps hilf (q:qs) pq = zipWith (+) nxs $ hilf qs pq where l = length pq --nxs = concat [replicate q t|(t,z) <- zip pq [0..l],mod z q == 0] nxs1 = [t*0.2 |(t,z) <- zip pq [0..l],mod z q == 0] l2 = length nxs1 nxs = concat $ replicate q nxs1 modu :: Integer modu = 123456789 aconst :: Integer aconst = 45612 cconst :: Integer cconst = 3242398 rng :: Integer -> Integer rng seed = mod (seed * aconst + cconst) modu rlist :: Integer -> Int -> [Integer] rlist x l = foldl' (\e@(b:bs) _ -> (rng b):e) [rng x] [2..l] rnd :: Integer -> DSPEffect rnd seed xs = let nsx = map (\x -> fromIntegral(mod x 100 - 50)*0.001) (rlist seed $ length xs) in zipWith (+) xs nsx