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 increaseAmplOverTime :: Double -> Double -> Double -> DSPEffect increaseAmplOverTime duration startAmpl endAmpl = zipWith (*) factors where numSamples = samplesPerSecond duration intList = [0..numSamples - 1] linearFactors = map ((/(fromIntegral numSamples-1.0)) . fromIntegral) intList increase = endAmpl - startAmpl factors = map ((+ startAmpl) . (* increase)) linearFactors echo :: Seconds -> Seconds -> DSPEffect echo duration delay sampledSignal = mixShortest delayTrack sampledSignal where numSam = samplesPerSecond duration record = take numSam sampledSignal numDelay = samplesPerSecond delay delayTrack = replicate numDelay 0 ++ record mixShortest :: [Double] -> [Double] -> [Double] mixShortest [] xs = xs mixShortest xs [] = xs mixShortest (x:xs) (y:ys) = ((x + y) / 2) : mixShortest xs ys triller :: Double -> Double -> Hz -> DSPEffect triller min max frequenzy = zipWith (*) factor where trillerFunction i = cos (fromIntegral i * 2*pi * frequenzy / sampleRate ) fittedTrilFct i = min + (max - min) * (trillerFunction i + 1) / 2 factor = map fittedTrilFct [0..]