packages feed

synthesizer-dimensional-0.9: src/Synthesizer/Dimensional/Duration.hs

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