{-# LANGUAGE FlexibleInstances #-} module Nes.APU.State.Filter.Sampled (SampledFilter (..), newSampledFilter) where import Control.Monad.IO.Class import Nes.APU.State.Filter.Class import Nes.APU.State.Filter.Constants import Nes.APU.State.Filter.Fir import Nes.APU.State.Filter.Iir import Prelude hiding (filter) data SampledFilter = MkSF { SampledFilter -> Either IirFilter FirFilter filter :: Either IirFilter FirFilter , SampledFilter -> SampleRate samplePeriod :: {-# UNPACK #-} !Float , SampledFilter -> SampleRate periodCounter :: {-# UNPACK #-} !Float } newSampledFilter :: Either IirFilter FirFilter -> SampleRate -> SampledFilter newSampledFilter :: Either IirFilter FirFilter -> SampleRate -> SampledFilter newSampledFilter Either IirFilter FirFilter filter SampleRate sampleRate = MkSF{SampleRate Either IirFilter FirFilter filter :: Either IirFilter FirFilter samplePeriod :: SampleRate periodCounter :: SampleRate filter :: Either IirFilter FirFilter periodCounter :: SampleRate samplePeriod :: SampleRate ..} where periodCounter :: SampleRate periodCounter = SampleRate 1 samplePeriod :: SampleRate samplePeriod = SampleRate 1 SampleRate -> SampleRate -> SampleRate forall a. Fractional a => a -> a -> a / SampleRate sampleRate instance (MonadIO m) => Filter m SampledFilter where consume :: SampleRate -> SampledFilter -> m SampledFilter consume = SampleRate -> SampledFilter -> m SampledFilter forall (m :: * -> *). MonadIO m => SampleRate -> SampledFilter -> m SampledFilter sampledFilterConsumeSample output :: SampledFilter -> m SampleRate output SampledFilter sf = Either IirFilter FirFilter -> m SampleRate forall (m :: * -> *) a. Filter m a => a -> m SampleRate output (Either IirFilter FirFilter -> m SampleRate) -> Either IirFilter FirFilter -> m SampleRate forall a b. (a -> b) -> a -> b $ SampledFilter -> Either IirFilter FirFilter filter SampledFilter sf {-# INLINE sampledFilterConsumeSample #-} sampledFilterConsumeSample :: (MonadIO m) => Sample -> SampledFilter -> m SampledFilter sampledFilterConsumeSample :: forall (m :: * -> *). MonadIO m => SampleRate -> SampledFilter -> m SampledFilter sampledFilterConsumeSample SampleRate sample SampledFilter sf = do Either IirFilter FirFilter filter' <- SampleRate -> Either IirFilter FirFilter -> m (Either IirFilter FirFilter) forall (m :: * -> *) a. Filter m a => SampleRate -> a -> m a consume SampleRate sample (Either IirFilter FirFilter -> m (Either IirFilter FirFilter)) -> Either IirFilter FirFilter -> m (Either IirFilter FirFilter) forall a b. (a -> b) -> a -> b $ SampledFilter -> Either IirFilter FirFilter filter SampledFilter sf SampledFilter -> m SampledFilter forall a. a -> m a forall (m :: * -> *) a. Monad m => a -> m a return SampledFilter sf { filter = filter' }