module Synthesizer.Dimensional.Duration where
import qualified Synthesizer.Dimensional.Process as Proc
import Control.Applicative ((<$>))
import qualified Algebra.ToInteger as ToInteger
import qualified Algebra.Field as Field
import qualified Algebra.RealRing as RealRing
import qualified Number.DimensionTerm as DN
import qualified Algebra.DimensionTerm as Dim
import Number.DimensionTerm ((*&))
import qualified NumericPrelude.Numeric as NP
{- |
This type is intended to hold a duration
which is an integer with respect to the sampling rate.
It allows to do exact duration computations, i.e. without rounding errors.
The trade-off is that it is bound to a certain sampling rate
and you must convert to different sampling rates explicitly.
-}
newtype T s i = Cons i
fromTime ::
(Dim.C u, ToInteger.C i, RealRing.C t) =>
DN.T u t -> Proc.T s u t (T s i)
fromTime t = Cons . RealRing.round <$> Proc.toTimeScalar t
toTime ::
(Dim.C u, ToInteger.C i, Field.C t) =>
Proc.T s u t (T s i -> DN.T u t)
toTime =
(\sampleRate (Cons dur) -> NP.fromIntegral dur *& DN.unrecip sampleRate)
<$>
Proc.getSampleRate