synthesizer-core-0.2: src/Synthesizer/Piecewise.hs
{- |
Construction of a data type that describes piecewise defined curves.
-}
module Synthesizer.Piecewise where
type T t y sig = [PieceData t y sig]
{- |
The curve type of a piece of a piecewise defined control curve.
-}
newtype Piece t y sig =
Piece {computePiece :: y {- y0 -}
-> y {- y1 -}
-> t {- duration -}
-> sig}
pieceFromFunction ::
(y -> y -> t -> sig) -> Piece t y sig
pieceFromFunction = Piece
{- |
The full description of a control curve piece.
-}
data PieceData t y sig =
PieceData {pieceType :: Piece t y sig,
pieceY0 :: y,
pieceY1 :: y,
pieceDur :: t}
-- deriving (Eq, Show)
newtype PieceRightSingle y = PRS y
newtype PieceRightDouble y = PRD y
data PieceDist t y sig = PD t (Piece t y sig) y
-- precedence and associativity like (:)
infixr 5 -|#, #|-, =|#, #|=, |#, #|
{- |
The 6 operators simplify constructing a list of @PieceData a@.
The description consists of nodes (namely the curve values at nodes)
and the connecting curve types.
The naming scheme is as follows:
In the middle there is a bar @|@.
With respect to the bar,
the pad symbol @\#@ is at the side of the curve type,
at the other side there is nothing, a minus sign @-@, or an equality sign @=@.
(1) Nothing means that here is the start or the end node of a curve.
(2) Minus means that here is a node where left and right curve meet at the same value.
The node description is thus one value.
(3) Equality sign means that here is a split node,
where left and right curve might have different ending and beginning values, respectively.
The node description consists of a pair of values.
-}
-- the leading space is necessary for the Haddock parser
( #|-) :: (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