moduleSynthesizer.Storable.CutwhereimportqualifiedSynthesizer.Storable.SignalasSigimportqualifiedData.StorableVector.LazyasSVLimportqualifiedData.StorableVector.ST.StrictasSVSTimportControl.Monad.ST.Strict(ST,runST,)importqualifiedData.EventList.Relative.TimeBodyasEventListimportqualifiedData.EventList.Relative.TimeMixedasEventListTMimportqualifiedData.EventList.Absolute.TimeBodyasAbsEventListimportControl.Monad.Trans.State(runState,modify,gets,put,)-- import Control.Monad (mapM, )importData.Tuple.HT(mapSnd,)-- import qualified Algebra.Real as RealimportqualifiedAlgebra.AdditiveasAdditiveimportqualifiedNumber.NonNegativeasNonNegimportForeign.Storable(Storable)importPreludeBaseimportNumericPrelude{- |
ChunkSize is only required for zero padding.
-}{-# INLINE arrange #-}arrange::(Storablev,Additive.Cv)=>Sig.ChunkSize->EventList.TNonNeg.Int(Sig.Tv){-^ A list of pairs: (relative start time, signal part),
The start time is relative to the start time
of the previous event. -}->Sig.Tv{-^ The mixed signal. -}arrangesize=uncurrySig.append.fliprunStateSig.empty.fmap(Sig.concat.EventList.getTimes).EventList.mapM(\timeNN->lettime=NonNeg.toNumbertimeNNindo(prefix,suffix)<-gets(Sig.splitAtPadsizetime)putsuffixreturnprefix)(\body->modify(Sig.mixbody))arrangeList::(Storablev,Additive.Cv)=>Sig.ChunkSize->EventList.TNonNeg.Int(Sig.Tv){-^ A list of pairs: (relative start time, signal part),
The start time is relative to the start time
of the previous event. -}->Sig.Tv{-^ The mixed signal. -}arrangeListsizeevs=letxs=EventList.getBodiesevsincaseEventList.getTimesevsoft:ts->Sig.replicatesize(NonNeg.toNumbert)zero`Sig.append`addShiftedManysizetsxs[]->Sig.emptyaddShiftedMany::(Storablea,Additive.Ca)=>Sig.ChunkSize->[NonNeg.Int]->[Sig.Ta]->Sig.TaaddShiftedManysizedsxss=foldr(uncurry(addShiftedsize))Sig.empty(zip(ds++[0])xss){-
It is crucial that 'mix' uses the chunk size structure of the second operand.
This way we avoid unnecessary and even infinite look-ahead.
-}addShifted::(Storablea,Additive.Ca)=>Sig.ChunkSize->NonNeg.Int->Sig.Ta->Sig.Ta->Sig.TaaddShiftedsizedelNNpxpy=letdel=NonNeg.toNumberdelNNinuncurrySig.append$mapSnd(flipSig.mixpy)$Sig.splitAtPadsizedelpx{- |
The result is a Lazy StorableVector with chunks of the given size.
-}{-# INLINE arrangeEquidist #-}arrangeEquidist::(Storablev,Additive.Cv)=>Sig.ChunkSize->EventList.TNonNeg.Int(Sig.Tv){-^ A list of pairs: (relative start time, signal part),
The start time is relative to the start time
of the previous event. -}->Sig.Tv{-^ The mixed signal. -}arrangeEquidist(SVL.ChunkSizesz)=letsznn=NonNeg.fromNumberMsg"arrangeEquidist"szgoaccevs=let(now,future)=EventListTM.splitAtTimesznnevsxs=AbsEventList.toPairList$EventList.toAbsoluteEventList0$EventListTM.switchTimeR(const)now(chunk,newAcc)=runST(dov<-SVST.newszzeronewAcc0<-mapM(addToBufferv0)acc-- newAcc1 <- AbsEventList.mapM (addToBuffer v) xsnewAcc1<-mapM(\(i,s)->addToBufferv(NonNeg.toNumberi)s)xsvf<-SVST.freezevreturn(vf,filter(not.Sig.null)(newAcc0++newAcc1)))inchunk:gonewAccfutureinSig.fromChunks.go[]addToBuffer::(Storablea,Additive.Ca)=>SVST.Vectorsa->Int->Sig.Ta->STs(Sig.Ta)addToBuffervstart=letn=SVST.lengthv{-# INLINE go #-}goi=ifi>=nthenreturnelseSig.switchL(returnSig.empty)(\xxs->SVST.modifyvi(xAdditive.+)>>go(succi)xs)ingostart