module Call.Util.Deck (Deck(..), empty, source, pos, playing, playback, playbackOf) where
import Control.Lens
import Control.Monad.State.Strict
import Call.Data.Wave
import Call.Types
import qualified Data.Vector.Storable as V
import Control.Monad.Objective
import Control.Elevator
data Deck = Deck
{ _src :: Source Stereo
, _pos :: !Time
, _playing :: !Bool }
empty :: Deck
empty = Deck (Source $ const 0) 0 False
source :: Lens' Deck (Source Stereo)
source f s = f (_src s) <&> \a -> s { _src = a }
pos :: Lens' Deck Time
pos f s = f (_pos s) <&> \a -> s { _pos = a }
playing :: Lens' Deck Bool
playing f s = f (_playing s) <&> \a -> s { _playing = a }
playback :: MonadState Deck m => Time -> Int -> m (V.Vector Stereo)
playback dt n = do
Source s <- use source
pl <- use playing
t0 <- use pos
if pl
then do
pos += dt
return $ V.fromList $ take n $ map s [t0,t0 + dt / fromIntegral n..]
else return $ V.replicate n 0
playbackOf :: (MonadObjective b m, Elevate n m) => Inst b (State Deck) n -> Time -> Int -> m (V.Vector Stereo)
playbackOf i = \dt n -> i .- playback dt n