module Synthesizer.Piecewise where
import Data.Ix (Ix, )
import qualified Algebra.RealRing as RealRing
import NumericPrelude.Numeric
import NumericPrelude.Base
type T t y sig = [PieceData t y sig]
newtype Piece t y sig =
Piece {computePiece :: y
-> y
-> t
-> sig}
pieceFromFunction :: (y -> y -> t -> sig) -> Piece t y sig
pieceFromFunction = Piece
data PieceData t y sig =
PieceData {pieceType :: Piece t y sig,
pieceY0 :: y,
pieceY1 :: y,
pieceDur :: t}
newtype PieceRightSingle y = PRS y
newtype PieceRightDouble y = PRD y
data PieceDist t y sig = PD t (Piece t y sig) y
infixr 5 -|#, #|-, =|#, #|=, |#, #|
( #|-) :: (t, Piece t y sig) -> (PieceRightSingle y, T t y sig) ->
(PieceDist t y sig, T t y sig)
(d,c) #|- (PRS y1, xs) = (PD d c y1, xs)
(-|#) :: y -> (PieceDist t y sig, T t y sig) ->
(PieceRightSingle y, T t y sig)
y0 -|# (PD d c y1, xs) = (PRS y0, PieceData c y0 y1 d : xs)
( #|=) :: (t, Piece t y sig) -> (PieceRightDouble y, T t y sig) ->
(PieceDist t y sig, T t y sig)
(d,c) #|= (PRD y1, xs) = (PD d c y1, xs)
(=|#) :: (y,y) -> (PieceDist t y sig, T t y sig) ->
(PieceRightDouble y, T t y sig)
(y01,y10) =|# (PD d c y11, xs) = (PRD y01, PieceData c y10 y11 d : xs)
( #|) :: (t, Piece t y sig) -> y ->
(PieceDist t y sig, T t y sig)
(d,c) #| y1 = (PD d c y1, [])
(|#) :: y -> (PieceDist t y sig, T t y sig) ->
T t y sig
y0 |# (PD d c y1, xs) = PieceData c y0 y1 d : xs
data FlatPosition = FlatLeft | FlatRight
deriving (Show, Eq, Ord, Ix, Enum)
splitDurations :: (RealRing.C t) => [t] -> [(Int, t)]
splitDurations ts0 =
let (ds,ts) =
unzip $ scanl
(\(_,fr) d -> RealRing.splitFraction (fr+d))
(0,1) ts0
in zip (tail ds) (map (subtract 1) ts)