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 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 --this deletes half of the samples. As a result, the track speeds up by a factor of 2 bitcrusher :: DSPEffect bitcrusher [] = [] bitcrusher (x:xx:xs) = x : bitcrusher xs bitcrusher (x:xs) = xs --this does not do much bitrepeater :: DSPEffect bitrepeater [] = [] bitrepeater (x:y:z:xs) = x : x : x : bitrepeater xs bitrepeater (x:xs) = xs --same with this, no difference if applied. The two swapped samples would have to be further apart swapper::DSPEffect swapper [] = [] swapper (x:y:ys) = y : x : ys --this applies an echo effect on the track. a specifies the volume of the echo. echo:: Double -> DSPEffect echo a [] = [] echo a xs = echosummy a xs ((replicate 20000 0) ++ xs) --just a helper function for echo echosummy:: Double -> SampledSignal -> SampledSignal -> SampledSignal echosummy a xs [] = xs echosummy a [] ys = ys echosummy a (x:xs) (y:ys) = (x + (y * a)): echosummy a xs ys