{-# LANGUAGE NoImplicitPrelude #-}{- |
An implementation of a Delay using a classical circular buffer
running in the State Thread monad.
-}moduleSynthesizer.Plain.Filter.Delay.STwhereimportqualifiedSynthesizer.Plain.InterpolationasInterpolationimportqualifiedAlgebra.RealFieldasRealFieldimportqualifiedAlgebra.AdditiveasAdditiveimportControl.Monad.ST.Lazy(runST,strictToLazyST,ST)importData.Array.STimportqualifiedPreludeasPimportPreludeBaseimportNumericPrelude{-
I had no success in hiding ST in the 'modulatedST' function.
The explicit type signature is crucial.
-}modulatedAction::(RealField.Ca,Additive.Cv)=>Interpolation.Tav->Int->[a]->[v]->STs[v]modulatedActionipsizetsxs=letipNum=Interpolation.numberipipFunc=Interpolation.funcipindoarr<-strictToLazyST(newArray(0,2*size-1)zero)::Additive.Cv=>STs(STArraysIntv)mapM(\(n,t,x)->strictToLazyST$dowriteArrayarrnxwriteArrayarr(n+size)xlet(ti,tf)=splitFractionty<-mapM(readArrayarr)(takeipNum[(n+ti)..])return(ifti<0thenerror"negative delay"elseifsize<ti+ipNumthenerror"too much delay"elseipFunctfy))(zip3(cycle[(size-1),(size-2)..0])tsxs)modulated::(RealField.Ca,Additive.Cv)=>Interpolation.Tav->Int->[a]->[v]->[v]modulatedipmaxDelaytsxs=letoffset=Interpolation.offsetipindropoffset(runST(modulatedActionip(maxDelay+Interpolation.numberip)(replicateoffsetzero++ts)xs))