{-# LANGUAGE FlexibleContexts #-}
{- |
Copyright   :  (c) Henning Thielemann 2008-2009
License     :  GPL

Maintainer  :  synthesizer@henning-thielemann.de
Stability   :  provisional
Portability :  requires multi-parameter type classes
-}
module Synthesizer.Dimensional.Amplitude.Cut (
   -- * dissection
   unzip,
   unzip3,
   leftFromStereo, rightFromStereo,

   span, dropWhile, takeWhile,
   spanPrimitive, dropWhilePrimitive, takeWhilePrimitive,

   -- * glueing
   concat,      concatVolume,      concatPrimitive,
   append,      appendVolume,      appendPrimitive,
   zip,         zipVolume,
   zip3,        zip3Volume,
   mergeStereo, mergeStereoVolume, mergeStereoPrimitive,

   -- * miscellaneous
   selectBool,
   reverse,
  ) where

import qualified Synthesizer.Dimensional.Signal.Private as SigA
import Synthesizer.Dimensional.Signal.Private (toAmplitudeScalar, )

import qualified Synthesizer.Dimensional.Rate as Rate
import qualified Synthesizer.Dimensional.Amplitude as Amp

import qualified Synthesizer.Generic.Signal  as SigG
import qualified Synthesizer.Generic.Cut     as CutG
import qualified Synthesizer.State.Signal    as Sig

import qualified Synthesizer.Frame.Stereo as Stereo

import qualified Number.DimensionTerm        as DN
import qualified Algebra.DimensionTerm       as Dim

-- import Number.DimensionTerm ((&*&))

-- import qualified Algebra.NormedSpace.Maximum as NormedMax
import qualified Algebra.Module              as Module
import qualified Algebra.Field               as Field
-- import qualified Algebra.Ring                as Ring

import qualified Data.List as List

import NumericPrelude.Base (Ord, max, Bool, ($), (.), flip, )
import NumericPrelude.Numeric ((*>), )
import Prelude ()


-- * dissection

{-# INLINE unzip #-}
unzip ::
   (SigG.Transform sig (yv0, yv1),
    SigG.Transform sig yv0,
    SigG.Transform sig yv1) =>
   SigA.T rate amp (sig (yv0, yv1)) ->
   (SigA.T rate amp (sig yv0), SigA.T rate amp (sig yv1))
unzip :: forall (sig :: * -> *) yv0 yv1 rate amp.
(Transform sig (yv0, yv1), Transform sig yv0, Transform sig yv1) =>
T rate amp (sig (yv0, yv1))
-> (T rate amp (sig yv0), T rate amp (sig yv1))
unzip T rate amp (sig (yv0, yv1))
x =
   let (sig yv0
ss0,sig yv1
ss1) = forall (sig :: * -> *) a b.
(Transform sig (a, b), Transform sig a, Transform sig b) =>
sig (a, b) -> (sig a, sig b)
SigG.unzip (forall rate amplitude body. T rate amplitude body -> body
SigA.body T rate amp (sig (yv0, yv1))
x)
   in  (forall sig1 rate amp sig0.
sig1 -> T rate amp sig0 -> T rate amp sig1
SigA.replaceBody sig yv0
ss0 T rate amp (sig (yv0, yv1))
x, forall sig1 rate amp sig0.
sig1 -> T rate amp sig0 -> T rate amp sig1
SigA.replaceBody sig yv1
ss1 T rate amp (sig (yv0, yv1))
x)

{-# INLINE unzip3 #-}
unzip3 ::
   (SigG.Transform sig (yv0, yv1, yv2),
    SigG.Transform sig yv0,
    SigG.Transform sig yv1,
    SigG.Transform sig yv2) =>
   SigA.T rate amp (sig (yv0, yv1, yv2)) ->
   (SigA.T rate amp (sig yv0), SigA.T rate amp (sig yv1), SigA.T rate amp (sig yv2))
unzip3 :: forall (sig :: * -> *) yv0 yv1 yv2 rate amp.
(Transform sig (yv0, yv1, yv2), Transform sig yv0,
 Transform sig yv1, Transform sig yv2) =>
T rate amp (sig (yv0, yv1, yv2))
-> (T rate amp (sig yv0), T rate amp (sig yv1),
    T rate amp (sig yv2))
unzip3 T rate amp (sig (yv0, yv1, yv2))
x =
   let (sig yv0
ss0,sig yv1
ss1,sig yv2
ss2) = forall (sig :: * -> *) a b c.
(Transform sig (a, b, c), Transform sig a, Transform sig b,
 Transform sig c) =>
sig (a, b, c) -> (sig a, sig b, sig c)
SigG.unzip3 (forall rate amplitude body. T rate amplitude body -> body
SigA.body T rate amp (sig (yv0, yv1, yv2))
x)
   in  (forall sig1 rate amp sig0.
sig1 -> T rate amp sig0 -> T rate amp sig1
SigA.replaceBody sig yv0
ss0 T rate amp (sig (yv0, yv1, yv2))
x, forall sig1 rate amp sig0.
sig1 -> T rate amp sig0 -> T rate amp sig1
SigA.replaceBody sig yv1
ss1 T rate amp (sig (yv0, yv1, yv2))
x, forall sig1 rate amp sig0.
sig1 -> T rate amp sig0 -> T rate amp sig1
SigA.replaceBody sig yv2
ss2 T rate amp (sig (yv0, yv1, yv2))
x)


{-
ToDo:
spanNorm with a predicate with respect to a volume
would be useful in many cases.
But with respect to what notion of volume?
-}


span ::
   (SigG.Transform sig yv, Dim.C v, Field.C y, Module.C y yv) =>
   DN.T v y ->
   (yv -> Bool) ->
   (SigA.T rate (Amp.Dimensional v y) (sig yv) ->
    (SigA.T rate (Amp.Dimensional v y) (sig yv),
     SigA.T rate (Amp.Dimensional v y) (sig yv)))
span :: forall (sig :: * -> *) yv v y rate.
(Transform sig yv, C v, C y, C y yv) =>
T v y
-> (yv -> Bool)
-> T rate (Dimensional v y) (sig yv)
-> (T rate (Dimensional v y) (sig yv),
    T rate (Dimensional v y) (sig yv))
span T v y
v yv -> Bool
p T rate (Dimensional v y) (sig yv)
x =
   forall (sig :: * -> *) y rate amp.
Transform sig y =>
(y -> Bool)
-> T rate amp (sig y) -> (T rate amp (sig y), T rate amp (sig y))
spanPrivate (yv -> Bool
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall y v rate sig.
(C y, C v) =>
T rate (Dimensional v y) sig -> T v y -> y
toAmplitudeScalar T rate (Dimensional v y) (sig yv)
x T v y
v forall a v. C a v => a -> v -> v
*>)) T rate (Dimensional v y) (sig yv)
x

dropWhile ::
   (SigG.Transform sig yv, Dim.C v, Field.C y, Module.C y yv) =>
   DN.T v y ->
   (yv -> Bool) ->
   SigA.T rate (Amp.Dimensional v y) (sig yv) ->
   SigA.T rate (Amp.Dimensional v y) (sig yv)
dropWhile :: forall (sig :: * -> *) yv v y rate.
(Transform sig yv, C v, C y, C y yv) =>
T v y
-> (yv -> Bool)
-> T rate (Dimensional v y) (sig yv)
-> T rate (Dimensional v y) (sig yv)
dropWhile T v y
v yv -> Bool
p T rate (Dimensional v y) (sig yv)
x =
   forall (sig :: * -> *) y rate amp.
Transform sig y =>
(y -> Bool) -> T rate amp (sig y) -> T rate amp (sig y)
dropWhilePrivate (yv -> Bool
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall y v rate sig.
(C y, C v) =>
T rate (Dimensional v y) sig -> T v y -> y
toAmplitudeScalar T rate (Dimensional v y) (sig yv)
x T v y
v forall a v. C a v => a -> v -> v
*>)) T rate (Dimensional v y) (sig yv)
x

takeWhile ::
   (SigG.Transform sig yv, Dim.C v, Field.C y, Module.C y yv) =>
   DN.T v y ->
   (yv -> Bool) ->
   SigA.T rate (Amp.Dimensional v y) (sig yv) ->
   SigA.T rate (Amp.Dimensional v y) (sig yv)
takeWhile :: forall (sig :: * -> *) yv v y rate.
(Transform sig yv, C v, C y, C y yv) =>
T v y
-> (yv -> Bool)
-> T rate (Dimensional v y) (sig yv)
-> T rate (Dimensional v y) (sig yv)
takeWhile T v y
v yv -> Bool
p T rate (Dimensional v y) (sig yv)
x =
   forall (sig :: * -> *) y rate amp.
Transform sig y =>
(y -> Bool) -> T rate amp (sig y) -> T rate amp (sig y)
takeWhilePrivate (yv -> Bool
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall y v rate sig.
(C y, C v) =>
T rate (Dimensional v y) sig -> T v y -> y
toAmplitudeScalar T rate (Dimensional v y) (sig yv)
x T v y
v forall a v. C a v => a -> v -> v
*>)) T rate (Dimensional v y) (sig yv)
x



-- ToDo: this should be moved to a module that needs neither amplitude nor rate
spanPrimitive ::
   (SigG.Transform sig y, Amp.Primitive amp) =>
   (y -> Bool) ->
   (SigA.T rate amp (sig y) ->
    (SigA.T rate amp (sig y),
     SigA.T rate amp (sig y)))
spanPrimitive :: forall (sig :: * -> *) y amp rate.
(Transform sig y, Primitive amp) =>
(y -> Bool)
-> T rate amp (sig y) -> (T rate amp (sig y), T rate amp (sig y))
spanPrimitive =
   forall (sig :: * -> *) y rate amp.
Transform sig y =>
(y -> Bool)
-> T rate amp (sig y) -> (T rate amp (sig y), T rate amp (sig y))
spanPrivate

dropWhilePrimitive ::
   (SigG.Transform sig y, Amp.Primitive amp) =>
   (y -> Bool) ->
   SigA.T rate amp (sig y) ->
   SigA.T rate amp (sig y)
dropWhilePrimitive :: forall (sig :: * -> *) y amp rate.
(Transform sig y, Primitive amp) =>
(y -> Bool) -> T rate amp (sig y) -> T rate amp (sig y)
dropWhilePrimitive =
   forall (sig :: * -> *) y rate amp.
Transform sig y =>
(y -> Bool) -> T rate amp (sig y) -> T rate amp (sig y)
dropWhilePrivate

takeWhilePrimitive ::
   (SigG.Transform sig y, Amp.Primitive amp) =>
   (y -> Bool) ->
   SigA.T rate amp (sig y) ->
   SigA.T rate amp (sig y)
takeWhilePrimitive :: forall (sig :: * -> *) y amp rate.
(Transform sig y, Primitive amp) =>
(y -> Bool) -> T rate amp (sig y) -> T rate amp (sig y)
takeWhilePrimitive =
   forall (sig :: * -> *) y rate amp.
Transform sig y =>
(y -> Bool) -> T rate amp (sig y) -> T rate amp (sig y)
takeWhilePrivate



spanPrivate ::
   (SigG.Transform sig y) =>
   (y -> Bool) ->
   (SigA.T rate amp (sig y) ->
    (SigA.T rate amp (sig y),
     SigA.T rate amp (sig y)))
spanPrivate :: forall (sig :: * -> *) y rate amp.
Transform sig y =>
(y -> Bool)
-> T rate amp (sig y) -> (T rate amp (sig y), T rate amp (sig y))
spanPrivate y -> Bool
p T rate amp (sig y)
x =
   let (sig y
y,sig y
z) = forall (sig :: * -> *) y.
(Transform0 sig, Storage (sig y)) =>
(y -> Bool) -> sig y -> (sig y, sig y)
SigG.span y -> Bool
p forall a b. (a -> b) -> a -> b
$ forall rate amplitude body. T rate amplitude body -> body
SigA.body T rate amp (sig y)
x
   in  (forall sig1 rate amp sig0.
sig1 -> T rate amp sig0 -> T rate amp sig1
SigA.replaceBody sig y
y T rate amp (sig y)
x,
        forall sig1 rate amp sig0.
sig1 -> T rate amp sig0 -> T rate amp sig1
SigA.replaceBody sig y
z T rate amp (sig y)
x)

dropWhilePrivate ::
   (SigG.Transform sig y) =>
   (y -> Bool) ->
   SigA.T rate amp (sig y) ->
   SigA.T rate amp (sig y)
dropWhilePrivate :: forall (sig :: * -> *) y rate amp.
Transform sig y =>
(y -> Bool) -> T rate amp (sig y) -> T rate amp (sig y)
dropWhilePrivate y -> Bool
p =
   forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody (forall (sig :: * -> *) y.
(Transform0 sig, Storage (sig y)) =>
(y -> Bool) -> sig y -> sig y
SigG.dropWhile y -> Bool
p)

takeWhilePrivate ::
   (SigG.Transform sig y) =>
   (y -> Bool) ->
   SigA.T rate amp (sig y) ->
   SigA.T rate amp (sig y)
takeWhilePrivate :: forall (sig :: * -> *) y rate amp.
Transform sig y =>
(y -> Bool) -> T rate amp (sig y) -> T rate amp (sig y)
takeWhilePrivate y -> Bool
p =
   forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody (forall (sig :: * -> *) y.
(Transform0 sig, Storage (sig y)) =>
(y -> Bool) -> sig y -> sig y
SigG.takeWhile y -> Bool
p)



{-# INLINE leftFromStereo #-}
leftFromStereo :: (Dim.C u) =>
   SigA.R s u y (Stereo.T yv) -> SigA.R s u y yv
leftFromStereo :: forall u s y yv. C u => R s u y (T yv) -> R s u y yv
leftFromStereo = forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody (forall a b. (a -> b) -> T a -> T b
Sig.map forall a. T a -> a
Stereo.left)

{-# INLINE rightFromStereo #-}
rightFromStereo :: (Dim.C u) =>
   SigA.R s u y (Stereo.T yv) -> SigA.R s u y yv
rightFromStereo :: forall u s y yv. C u => R s u y (T yv) -> R s u y yv
rightFromStereo = forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody (forall a b. (a -> b) -> T a -> T b
Sig.map forall a. T a -> a
Stereo.right)



-- * glueing

type Signal s u y sig yv =
   SigA.T (Rate.Phantom s) (Amp.Dimensional u y) (sig yv)

{- |
Similar to @foldr1 append@ but more efficient and accurate,
because it reduces the number of amplifications.
Does not work for infinite lists,
because no maximum amplitude can be computed.
-}
{-# INLINE concat #-}
concat ::
   (Ord y, Field.C y, Dim.C u,
    Module.C y yv,
    SigG.Transform sig yv) =>
   [Signal s u y sig yv] -> Signal s u y sig yv
concat :: forall y u yv (sig :: * -> *) s.
(Ord y, C y, C u, C y yv, Transform sig yv) =>
[Signal s u y sig yv] -> Signal s u y sig yv
concat [Signal s u y sig yv]
xs =
   forall y u yv (sig :: * -> *) s.
(C y, C u, C y yv, Transform sig yv) =>
T u y -> [Signal s u y sig yv] -> Signal s u y sig yv
concatVolume (forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
List.maximum (forall a b. (a -> b) -> [a] -> [b]
List.map forall rate amp sig. T rate (Numeric amp) sig -> amp
SigA.actualAmplitude [Signal s u y sig yv]
xs)) [Signal s u y sig yv]
xs

{- |
Give the output volume explicitly.
Does also work for infinite lists.
-}
{-# INLINE concatVolume #-}
concatVolume ::
   (Field.C y, Dim.C u,
    Module.C y yv,
    SigG.Transform sig yv) =>
   DN.T u y ->
   [Signal s u y sig yv] -> Signal s u y sig yv
concatVolume :: forall y u yv (sig :: * -> *) s.
(C y, C u, C y yv, Transform sig yv) =>
T u y -> [Signal s u y sig yv] -> Signal s u y sig yv
concatVolume T u y
amp [Signal s u y sig yv]
xs =
   let smps :: [sig yv]
smps = forall a b. (a -> b) -> [a] -> [b]
List.map (forall y yv (sig :: * -> *) amp rate.
(C y yv, Transform sig yv) =>
(amp -> y) -> T rate (Numeric amp) (sig yv) -> sig yv
SigA.vectorSamples (forall y v rate sig.
(C y, C v) =>
T rate (Dimensional v y) sig -> T v y -> y
toAmplitudeScalar T (Phantom s) (Dimensional u y) (sig yv)
z)) [Signal s u y sig yv]
xs
       z :: T (Phantom s) (Dimensional u y) (sig yv)
z = forall amp sig s. amp -> sig -> T (Phantom s) (Numeric amp) sig
SigA.fromBody T u y
amp (forall sig. Monoid sig => [sig] -> sig
SigG.concat [sig yv]
smps)
   in  forall {s}. T (Phantom s) (Dimensional u y) (sig yv)
z

{-# INLINE concatPrimitive #-}
concatPrimitive ::
   (CutG.Transform sig, Amp.Primitive amp) =>
   [SigA.T (Rate.Phantom s) amp sig] ->
   SigA.T (Rate.Phantom s) amp sig
concatPrimitive :: forall sig amp s.
(Transform sig, Primitive amp) =>
[T (Phantom s) amp sig] -> T (Phantom s) amp sig
concatPrimitive =
   forall amp sig s. Primitive amp => sig -> T (Phantom s) amp sig
SigA.primitiveFromBody forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall sig. Monoid sig => [sig] -> sig
SigG.concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map forall rate amplitude body. T rate amplitude body -> body
SigA.body


{-# INLINE merge #-}
merge ::
   (Ord y, Field.C y, Dim.C u,
    Module.C y yv0, Module.C y yv1,
    SigG.Transform sig0 yv0, SigG.Transform sig1 yv1) =>
   (sig0 yv0 -> sig1 yv1 -> sig2 yv2) ->
   Signal s u y sig0 yv0 -> Signal s u y sig1 yv1 -> Signal s u y sig2 yv2
merge :: forall y u yv0 yv1 (sig0 :: * -> *) (sig1 :: * -> *)
       (sig2 :: * -> *) yv2 s.
(Ord y, C y, C u, C y yv0, C y yv1, Transform sig0 yv0,
 Transform sig1 yv1) =>
(sig0 yv0 -> sig1 yv1 -> sig2 yv2)
-> Signal s u y sig0 yv0
-> Signal s u y sig1 yv1
-> Signal s u y sig2 yv2
merge sig0 yv0 -> sig1 yv1 -> sig2 yv2
f Signal s u y sig0 yv0
x0 Signal s u y sig1 yv1
x1 =
   forall y u yv0 yv1 (sig0 :: * -> *) (sig1 :: * -> *)
       (sig2 :: * -> *) yv2 s.
(C y, C u, C y yv0, C y yv1, Transform sig0 yv0,
 Transform sig1 yv1) =>
(sig0 yv0 -> sig1 yv1 -> sig2 yv2)
-> T u y
-> Signal s u y sig0 yv0
-> Signal s u y sig1 yv1
-> Signal s u y sig2 yv2
mergeVolume sig0 yv0 -> sig1 yv1 -> sig2 yv2
f (forall a. Ord a => a -> a -> a
max (forall rate amp sig. T rate (Numeric amp) sig -> amp
SigA.actualAmplitude Signal s u y sig0 yv0
x0) (forall rate amp sig. T rate (Numeric amp) sig -> amp
SigA.actualAmplitude Signal s u y sig1 yv1
x1)) Signal s u y sig0 yv0
x0 Signal s u y sig1 yv1
x1

{-# INLINE mergeVolume #-}
mergeVolume ::
   (Field.C y, Dim.C u,
    Module.C y yv0, Module.C y yv1,
    SigG.Transform sig0 yv0, SigG.Transform sig1 yv1) =>
   (sig0 yv0 -> sig1 yv1 -> sig2 yv2) ->
   DN.T u y ->
   Signal s u y sig0 yv0 -> Signal s u y sig1 yv1 -> Signal s u y sig2 yv2
mergeVolume :: forall y u yv0 yv1 (sig0 :: * -> *) (sig1 :: * -> *)
       (sig2 :: * -> *) yv2 s.
(C y, C u, C y yv0, C y yv1, Transform sig0 yv0,
 Transform sig1 yv1) =>
(sig0 yv0 -> sig1 yv1 -> sig2 yv2)
-> T u y
-> Signal s u y sig0 yv0
-> Signal s u y sig1 yv1
-> Signal s u y sig2 yv2
mergeVolume sig0 yv0 -> sig1 yv1 -> sig2 yv2
f T u y
amp Signal s u y sig0 yv0
x Signal s u y sig1 yv1
y =
   let sampX :: sig0 yv0
sampX = forall y yv (sig :: * -> *) amp rate.
(C y yv, Transform sig yv) =>
(amp -> y) -> T rate (Numeric amp) (sig yv) -> sig yv
SigA.vectorSamples (forall y v rate sig.
(C y, C v) =>
T rate (Dimensional v y) sig -> T v y -> y
toAmplitudeScalar T (Phantom s) (Dimensional u y) (sig2 yv2)
z) Signal s u y sig0 yv0
x
       sampY :: sig1 yv1
sampY = forall y yv (sig :: * -> *) amp rate.
(C y yv, Transform sig yv) =>
(amp -> y) -> T rate (Numeric amp) (sig yv) -> sig yv
SigA.vectorSamples (forall y v rate sig.
(C y, C v) =>
T rate (Dimensional v y) sig -> T v y -> y
toAmplitudeScalar T (Phantom s) (Dimensional u y) (sig2 yv2)
z) Signal s u y sig1 yv1
y
       z :: T (Phantom s) (Dimensional u y) (sig2 yv2)
z = forall amp sig s. amp -> sig -> T (Phantom s) (Numeric amp) sig
SigA.fromBody T u y
amp (sig0 yv0 -> sig1 yv1 -> sig2 yv2
f sig0 yv0
sampX sig1 yv1
sampY)
   in  forall {s}. T (Phantom s) (Dimensional u y) (sig2 yv2)
z

{-# INLINE mergePrimitive #-}
mergePrimitive ::
   (Amp.Primitive amp) =>
   (sig0 -> sig1 -> sig2) ->
   SigA.T (Rate.Phantom s) amp sig0 ->
   SigA.T (Rate.Phantom s) amp sig1 ->
   SigA.T (Rate.Phantom s) amp sig2
mergePrimitive :: forall amp sig0 sig1 sig2 s.
Primitive amp =>
(sig0 -> sig1 -> sig2)
-> T (Phantom s) amp sig0
-> T (Phantom s) amp sig1
-> T (Phantom s) amp sig2
mergePrimitive sig0 -> sig1 -> sig2
f T (Phantom s) amp sig0
x T (Phantom s) amp sig1
y =
   forall rate amplitude body.
rate -> amplitude -> body -> T rate amplitude body
SigA.Cons forall s. Phantom s
Rate.Phantom forall amp. Primitive amp => amp
Amp.primitive forall a b. (a -> b) -> a -> b
$
      sig0 -> sig1 -> sig2
f (forall rate amplitude body. T rate amplitude body -> body
SigA.body T (Phantom s) amp sig0
x) (forall rate amplitude body. T rate amplitude body -> body
SigA.body T (Phantom s) amp sig1
y)


{-# INLINE append #-}
append ::
   (Ord y, Field.C y, Dim.C u,
    Module.C y yv,
    SigG.Transform sig yv) =>
   Signal s u y sig yv -> Signal s u y sig yv -> Signal s u y sig yv
append :: forall y u yv (sig :: * -> *) s.
(Ord y, C y, C u, C y yv, Transform sig yv) =>
Signal s u y sig yv -> Signal s u y sig yv -> Signal s u y sig yv
append = forall y u yv0 yv1 (sig0 :: * -> *) (sig1 :: * -> *)
       (sig2 :: * -> *) yv2 s.
(Ord y, C y, C u, C y yv0, C y yv1, Transform sig0 yv0,
 Transform sig1 yv1) =>
(sig0 yv0 -> sig1 yv1 -> sig2 yv2)
-> Signal s u y sig0 yv0
-> Signal s u y sig1 yv1
-> Signal s u y sig2 yv2
merge forall sig. Monoid sig => sig -> sig -> sig
SigG.append

{-# INLINE appendVolume #-}
appendVolume ::
   (Field.C y, Dim.C u,
    Module.C y yv,
    SigG.Transform sig yv) =>
   DN.T u y ->
   Signal s u y sig yv -> Signal s u y sig yv -> Signal s u y sig yv
appendVolume :: forall y u yv (sig :: * -> *) s.
(C y, C u, C y yv, Transform sig yv) =>
T u y
-> Signal s u y sig yv
-> Signal s u y sig yv
-> Signal s u y sig yv
appendVolume = forall y u yv0 yv1 (sig0 :: * -> *) (sig1 :: * -> *)
       (sig2 :: * -> *) yv2 s.
(C y, C u, C y yv0, C y yv1, Transform sig0 yv0,
 Transform sig1 yv1) =>
(sig0 yv0 -> sig1 yv1 -> sig2 yv2)
-> T u y
-> Signal s u y sig0 yv0
-> Signal s u y sig1 yv1
-> Signal s u y sig2 yv2
mergeVolume forall sig. Monoid sig => sig -> sig -> sig
SigG.append

{-# INLINE appendPrimitive #-}
appendPrimitive ::
   (CutG.Transform sig, Amp.Primitive amp) =>
   SigA.T (Rate.Phantom s) amp sig ->
   SigA.T (Rate.Phantom s) amp sig ->
   SigA.T (Rate.Phantom s) amp sig
appendPrimitive :: forall sig amp s.
(Transform sig, Primitive amp) =>
T (Phantom s) amp sig
-> T (Phantom s) amp sig -> T (Phantom s) amp sig
appendPrimitive = forall amp sig0 sig1 sig2 s.
Primitive amp =>
(sig0 -> sig1 -> sig2)
-> T (Phantom s) amp sig0
-> T (Phantom s) amp sig1
-> T (Phantom s) amp sig2
mergePrimitive forall sig. Monoid sig => sig -> sig -> sig
SigG.append


{-# INLINE zip #-}
zip ::
   (Ord y, Field.C y, Dim.C u,
    Module.C y yv0, Module.C y yv1,
    SigG.Read sig yv0, SigG.Transform sig yv1, SigG.Transform sig (yv0,yv1)) =>
   Signal s u y sig yv0 -> Signal s u y sig yv1 -> Signal s u y sig (yv0,yv1)
zip :: forall y u yv0 yv1 (sig :: * -> *) s.
(Ord y, C y, C u, C y yv0, C y yv1, Read sig yv0,
 Transform sig yv1, Transform sig (yv0, yv1)) =>
Signal s u y sig yv0
-> Signal s u y sig yv1 -> Signal s u y sig (yv0, yv1)
zip =
   forall y u yv0 yv1 (sig0 :: * -> *) (sig1 :: * -> *)
       (sig2 :: * -> *) yv2 s.
(Ord y, C y, C u, C y yv0, C y yv1, Transform sig0 yv0,
 Transform sig1 yv1) =>
(sig0 yv0 -> sig1 yv1 -> sig2 yv2)
-> Signal s u y sig0 yv0
-> Signal s u y sig1 yv1
-> Signal s u y sig2 yv2
merge (forall (sig :: * -> *) b c a.
(Transform sig b, Transform sig c) =>
(a -> b -> c) -> T a -> sig b -> sig c
SigG.zipWithState (,)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (sig :: * -> *) yv rate amp.
Read sig yv =>
T rate amp (sig yv) -> T rate amp (T yv)
SigA.restore

{-# INLINE zipVolume #-}
zipVolume ::
   (Field.C y, Dim.C u,
    Module.C y yv0, Module.C y yv1,
    SigG.Read sig yv0, SigG.Transform sig yv1, SigG.Transform sig (yv0,yv1)) =>
   DN.T u y ->
   Signal s u y sig yv0 -> Signal s u y sig yv1 -> Signal s u y sig (yv0,yv1)
zipVolume :: forall y u yv0 yv1 (sig :: * -> *) s.
(C y, C u, C y yv0, C y yv1, Read sig yv0, Transform sig yv1,
 Transform sig (yv0, yv1)) =>
T u y
-> Signal s u y sig yv0
-> Signal s u y sig yv1
-> Signal s u y sig (yv0, yv1)
zipVolume T u y
vol =
   forall y u yv0 yv1 (sig0 :: * -> *) (sig1 :: * -> *)
       (sig2 :: * -> *) yv2 s.
(C y, C u, C y yv0, C y yv1, Transform sig0 yv0,
 Transform sig1 yv1) =>
(sig0 yv0 -> sig1 yv1 -> sig2 yv2)
-> T u y
-> Signal s u y sig0 yv0
-> Signal s u y sig1 yv1
-> Signal s u y sig2 yv2
mergeVolume (forall (sig :: * -> *) b c a.
(Transform sig b, Transform sig c) =>
(a -> b -> c) -> T a -> sig b -> sig c
SigG.zipWithState (,)) T u y
vol forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (sig :: * -> *) yv rate amp.
Read sig yv =>
T rate amp (sig yv) -> T rate amp (T yv)
SigA.restore



{-# INLINE mergeStereo #-}
mergeStereo ::
   (Ord y, Field.C y, Dim.C u,
    Module.C y yv,
    SigG.Transform sig yv, SigG.Transform sig (Stereo.T yv)) =>
   Signal s u y sig yv -> Signal s u y sig yv -> Signal s u y sig (Stereo.T yv)
mergeStereo :: forall y u yv (sig :: * -> *) s.
(Ord y, C y, C u, C y yv, Transform sig yv,
 Transform sig (T yv)) =>
Signal s u y sig yv
-> Signal s u y sig yv -> Signal s u y sig (T yv)
mergeStereo = forall y u yv0 yv1 (sig0 :: * -> *) (sig1 :: * -> *)
       (sig2 :: * -> *) yv2 s.
(Ord y, C y, C u, C y yv0, C y yv1, Transform sig0 yv0,
 Transform sig1 yv1) =>
(sig0 yv0 -> sig1 yv1 -> sig2 yv2)
-> Signal s u y sig0 yv0
-> Signal s u y sig1 yv1
-> Signal s u y sig2 yv2
merge (forall (sig :: * -> *) a b c.
(Read sig a, Transform sig b, Transform sig c) =>
(a -> b -> c) -> sig a -> sig b -> sig c
SigG.zipWith forall a. a -> a -> T a
Stereo.cons)

{-# INLINE mergeStereoVolume #-}
mergeStereoVolume ::
   (Field.C y, Dim.C u,
    Module.C y yv,
    SigG.Transform sig yv, SigG.Transform sig (Stereo.T yv)) =>
   DN.T u y ->
   Signal s u y sig yv -> Signal s u y sig yv -> Signal s u y sig (Stereo.T yv)
mergeStereoVolume :: forall y u yv (sig :: * -> *) s.
(C y, C u, C y yv, Transform sig yv, Transform sig (T yv)) =>
T u y
-> Signal s u y sig yv
-> Signal s u y sig yv
-> Signal s u y sig (T yv)
mergeStereoVolume = forall y u yv0 yv1 (sig0 :: * -> *) (sig1 :: * -> *)
       (sig2 :: * -> *) yv2 s.
(C y, C u, C y yv0, C y yv1, Transform sig0 yv0,
 Transform sig1 yv1) =>
(sig0 yv0 -> sig1 yv1 -> sig2 yv2)
-> T u y
-> Signal s u y sig0 yv0
-> Signal s u y sig1 yv1
-> Signal s u y sig2 yv2
mergeVolume (forall (sig :: * -> *) a b c.
(Read sig a, Transform sig b, Transform sig c) =>
(a -> b -> c) -> sig a -> sig b -> sig c
SigG.zipWith forall a. a -> a -> T a
Stereo.cons)

{-# INLINE mergeStereoPrimitive #-}
mergeStereoPrimitive ::
   (Amp.Primitive amp, SigG.Transform sig y, SigG.Transform sig (Stereo.T y)) =>
   SigA.T (Rate.Phantom s) amp (sig y) ->
   SigA.T (Rate.Phantom s) amp (sig y) ->
   SigA.T (Rate.Phantom s) amp (sig (Stereo.T y))
mergeStereoPrimitive :: forall amp (sig :: * -> *) y s.
(Primitive amp, Transform sig y, Transform sig (T y)) =>
T (Phantom s) amp (sig y)
-> T (Phantom s) amp (sig y) -> T (Phantom s) amp (sig (T y))
mergeStereoPrimitive =
   forall amp sig0 sig1 sig2 s.
Primitive amp =>
(sig0 -> sig1 -> sig2)
-> T (Phantom s) amp sig0
-> T (Phantom s) amp sig1
-> T (Phantom s) amp sig2
mergePrimitive (forall (sig :: * -> *) a b c.
(Read sig a, Transform sig b, Transform sig c) =>
(a -> b -> c) -> sig a -> sig b -> sig c
SigG.zipWith forall a. a -> a -> T a
Stereo.cons)



{-# INLINE zip3 #-}
zip3 ::
   (Ord y, Field.C y, Dim.C u,
    Module.C y yv0, Module.C y yv1, Module.C y yv2,
    SigG.Read sig yv0, SigG.Read sig yv1,
    SigG.Transform sig yv2, SigG.Transform sig (yv0, yv1, yv2)) =>
   Signal s u y sig yv0 -> Signal s u y sig yv1 -> Signal s u y sig yv2 ->
   Signal s u y sig (yv0,yv1,yv2)
zip3 :: forall y u yv0 yv1 yv2 (sig :: * -> *) s.
(Ord y, C y, C u, C y yv0, C y yv1, C y yv2, Read sig yv0,
 Read sig yv1, Transform sig yv2, Transform sig (yv0, yv1, yv2)) =>
Signal s u y sig yv0
-> Signal s u y sig yv1
-> Signal s u y sig yv2
-> Signal s u y sig (yv0, yv1, yv2)
zip3 Signal s u y sig yv0
x0 Signal s u y sig yv1
x1 Signal s u y sig yv2
x2 =
   forall y u yv0 yv1 yv2 (sig :: * -> *) s.
(C y, C u, C y yv0, C y yv1, C y yv2, Read sig yv0, Read sig yv1,
 Transform sig yv2, Transform sig (yv0, yv1, yv2)) =>
T u y
-> Signal s u y sig yv0
-> Signal s u y sig yv1
-> Signal s u y sig yv2
-> Signal s u y sig (yv0, yv1, yv2)
zip3Volume
      (forall rate amp sig. T rate (Numeric amp) sig -> amp
SigA.actualAmplitude Signal s u y sig yv0
x0 forall a. Ord a => a -> a -> a
`max` forall rate amp sig. T rate (Numeric amp) sig -> amp
SigA.actualAmplitude Signal s u y sig yv1
x1 forall a. Ord a => a -> a -> a
`max` forall rate amp sig. T rate (Numeric amp) sig -> amp
SigA.actualAmplitude Signal s u y sig yv2
x2)
      Signal s u y sig yv0
x0 Signal s u y sig yv1
x1 Signal s u y sig yv2
x2

{-# INLINE zip3Volume #-}
zip3Volume ::
   (Field.C y, Dim.C u,
    Module.C y yv0, Module.C y yv1, Module.C y yv2,
    SigG.Read sig yv0, SigG.Read sig yv1,
    SigG.Transform sig yv2, SigG.Transform sig (yv0, yv1, yv2)) =>
   DN.T u y ->
   Signal s u y sig yv0 -> Signal s u y sig yv1 -> Signal s u y sig yv2 ->
   Signal s u y sig (yv0,yv1,yv2)
zip3Volume :: forall y u yv0 yv1 yv2 (sig :: * -> *) s.
(C y, C u, C y yv0, C y yv1, C y yv2, Read sig yv0, Read sig yv1,
 Transform sig yv2, Transform sig (yv0, yv1, yv2)) =>
T u y
-> Signal s u y sig yv0
-> Signal s u y sig yv1
-> Signal s u y sig yv2
-> Signal s u y sig (yv0, yv1, yv2)
zip3Volume T u y
amp Signal s u y sig yv0
x0 Signal s u y sig yv1
x1 Signal s u y sig yv2
x2 =
   let sampX0 :: T yv0
sampX0 = forall y yv (sig :: * -> *) amp rate.
(C y yv, Transform sig yv) =>
(amp -> y) -> T rate (Numeric amp) (sig yv) -> sig yv
SigA.vectorSamples (forall y v rate sig.
(C y, C v) =>
T rate (Dimensional v y) sig -> T v y -> y
toAmplitudeScalar T (Phantom s) (Dimensional u y) (sig (yv0, yv1, yv2))
z) (forall (sig :: * -> *) yv rate amp.
Read sig yv =>
T rate amp (sig yv) -> T rate amp (T yv)
SigA.restore Signal s u y sig yv0
x0)
       sampX1 :: T yv1
sampX1 = forall y yv (sig :: * -> *) amp rate.
(C y yv, Transform sig yv) =>
(amp -> y) -> T rate (Numeric amp) (sig yv) -> sig yv
SigA.vectorSamples (forall y v rate sig.
(C y, C v) =>
T rate (Dimensional v y) sig -> T v y -> y
toAmplitudeScalar T (Phantom s) (Dimensional u y) (sig (yv0, yv1, yv2))
z) (forall (sig :: * -> *) yv rate amp.
Read sig yv =>
T rate amp (sig yv) -> T rate amp (T yv)
SigA.restore Signal s u y sig yv1
x1)
       sampX2 :: sig yv2
sampX2 = forall y yv (sig :: * -> *) amp rate.
(C y yv, Transform sig yv) =>
(amp -> y) -> T rate (Numeric amp) (sig yv) -> sig yv
SigA.vectorSamples (forall y v rate sig.
(C y, C v) =>
T rate (Dimensional v y) sig -> T v y -> y
toAmplitudeScalar T (Phantom s) (Dimensional u y) (sig (yv0, yv1, yv2))
z) Signal s u y sig yv2
x2
       z :: T (Phantom s) (Dimensional u y) (sig (yv0, yv1, yv2))
z = forall amp sig s. amp -> sig -> T (Phantom s) (Numeric amp) sig
SigA.fromBody T u y
amp (forall (sig :: * -> *) c d a b.
(Transform sig c, Transform sig d) =>
(a -> b -> c -> d) -> T a -> T b -> sig c -> sig d
SigG.zipWithState3 (,,) T yv0
sampX0 T yv1
sampX1 sig yv2
sampX2)
   in  forall {s}. T (Phantom s) (Dimensional u y) (sig (yv0, yv1, yv2))
z


-- * miscellaneous

{-# INLINE selectBool #-}
selectBool ::
   (Ord y, Field.C y, Dim.C u,
    Module.C y yv,
    SigG.Read sig yv,
    SigG.Transform sig Bool, SigG.Transform sig yv) =>
   Signal s u y sig yv {- ^ False -} ->
   Signal s u y sig yv {- ^ True -} ->
   SigA.T (Rate.Phantom s) Amp.Abstract (sig Bool) ->
   Signal s u y sig yv
selectBool :: forall y u yv (sig :: * -> *) s.
(Ord y, C y, C u, C y yv, Read sig yv, Transform sig Bool,
 Transform sig yv) =>
Signal s u y sig yv
-> Signal s u y sig yv
-> T (Phantom s) Abstract (sig Bool)
-> Signal s u y sig yv
selectBool Signal s u y sig yv
xf Signal s u y sig yv
xt T (Phantom s) Abstract (sig Bool)
cs =
   forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody
      (forall a b c. (a -> b -> c) -> b -> a -> c
flip (forall (sig :: * -> *) b c a.
(Transform sig b, Transform sig c) =>
(a -> b -> c) -> T a -> sig b -> sig c
SigG.zipWithState (\(yv
xfi,yv
xti) Bool
c -> if Bool
c then yv
xti else yv
xfi))
          (forall rate amplitude body. T rate amplitude body -> body
SigA.body T (Phantom s) Abstract (sig Bool)
cs))
      (forall y u yv0 yv1 (sig :: * -> *) s.
(Ord y, C y, C u, C y yv0, C y yv1, Read sig yv0,
 Transform sig yv1, Transform sig (yv0, yv1)) =>
Signal s u y sig yv0
-> Signal s u y sig yv1 -> Signal s u y sig (yv0, yv1)
zip
         (forall (sig :: * -> *) yv rate amp.
Read sig yv =>
T rate amp (sig yv) -> T rate amp (T yv)
SigA.restore Signal s u y sig yv
xf)
         (forall (sig :: * -> *) yv rate amp.
Read sig yv =>
T rate amp (sig yv) -> T rate amp (T yv)
SigA.restore Signal s u y sig yv
xt))

{-# INLINE reverse #-}
reverse ::
   (SigG.Transform sig yv) =>
   SigA.T rate amp (sig yv) ->
   SigA.T rate amp (sig yv)
reverse :: forall (sig :: * -> *) yv rate amp.
Transform sig yv =>
T rate amp (sig yv) -> T rate amp (sig yv)
reverse =
   forall sig0 sig1 rate amp.
(sig0 -> sig1) -> T rate amp sig0 -> T rate amp sig1
SigA.processBody forall sig. Transform sig => sig -> sig
SigG.reverse