module Music.Time.Internal.Convert (
scoreToVoice,
reactiveToVoice'
) where
import Control.Applicative
import Control.Lens hiding (transform, time)
import Control.Monad
import Control.Monad.Plus
import Data.AffineSpace
import Data.AffineSpace.Point
import Data.Foldable (Foldable (..))
import Data.Ord
import Data.Ratio
import Data.Semigroup
import Data.String
import Data.Traversable
import Data.VectorSpace
import Music.Time
import qualified Data.Foldable as Foldable
import qualified Data.List as List
reactiveToVoice' :: Span -> Reactive a -> Voice a
reactiveToVoice' (view range -> (u,v)) r = (^. voice) $ fmap (^. note) $ durs `zip` (fmap (r `atTime`) times)
where
times = 0 : filter (\t -> u < t && t < v) (occs r)
durs = toRelativeTimeN' v times
scoreToVoice :: Transformable a => Score a -> Voice (Maybe a)
scoreToVoice = (^. voice) . fmap (^. note) . fmap throwTime . addRests . (^. triples)
where
throwTime (t,d,x) = (d,x)
addRests = concat . snd . mapAccumL g 0
where
g u (t, d, x)
| u == t = (t .+^ d, [(t, d, Just x)])
| u < t = (t .+^ d, [(u, t .-. u, Nothing), (t, d, Just x)])
| otherwise = error "scoreToVoice: Strange prevTime"