diff -rN -u old-llvm-tf/alsa/Synthesizer/LLVM/Server/CausalPacked/Test.hs new-llvm-tf/alsa/Synthesizer/LLVM/Server/CausalPacked/Test.hs
--- old-llvm-tf/alsa/Synthesizer/LLVM/Server/CausalPacked/Test.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/alsa/Synthesizer/LLVM/Server/CausalPacked/Test.hs	2016-08-25 13:23:11.000000000 +0200
@@ -82,7 +82,7 @@
 import Control.Exception (bracket, )
 
 -- import NumericPrelude.Numeric (zero, round, (^?), )
-import Prelude hiding (Real, round, break, id, )
+import Prelude hiding (Real, break, id, )
 
 
 sampleRate :: SampleRate Real
@@ -107,6 +107,11 @@
    PIO.T t (SV.Vector a) -> [t] -> IO ()
 writeTest (PIO.Cons next create delete) evsChunky =
    IO.withFile "/tmp/test.f32" IO.WriteMode $ \h ->
+      {-
+      Is the use of 'bracket' correct?
+      I think 'delete' must be called with the final state,
+      not with the initial one.
+      -}
       bracket create delete $
          let loop evs s0 =
                 case evs of
@@ -601,10 +606,11 @@
 phonemeControl ::
    PC.ShortStrictTime ->
    (PC.ShortStrictTime -> ctrl) ->
+   Maybe (PC.StrictTime, VoiceMsg.Velocity) ->
    Instr.WithEnvelopeControl ctrl
-phonemeControl cs ctrl =
+phonemeControl cs ctrl stop =
    Zip.Cons
-      (Gate.chunk (PC.longFromShortTime cs) Nothing)
+      (Gate.chunk (PC.longFromShortTime cs) stop)
       (Zip.Cons
          (Zip.Cons
             (EventListBT.singleton (DN.time 0.5) cs)
@@ -621,7 +627,17 @@
 
    phoneme <- Speech.phonemeMask
    masks <- Speech.loadMasks Speech.maskNamesGrouped
+   let cs = 512
+       decayTime = round $ case sampleRate of Option.SampleRate sr -> sr*0.1
+       (decayChunks, decayStop) = divMod decayTime cs
    writeTest
       (unpack <<< phoneme masks sampleRate 0 (VoiceMsg.toPitch 64) <<<
        Zip.arrowSecond (Zip.arrowSecond (string sampleRate 0 440))) $
-      replicate 100 $ phonemeControl 512 stringControl
+
+      (replicate (NonNegW.toNumber decayChunks) $
+       phonemeControl cs stringControl Nothing)
+      ++
+      (phonemeControl cs stringControl $
+       Just (PC.longFromShortTime decayStop, VoiceMsg.normalVelocity))
+      :
+      (replicate 100 $ phonemeControl cs stringControl Nothing)
diff -rN -u old-llvm-tf/alsa/Synthesizer/LLVM/Server.hs new-llvm-tf/alsa/Synthesizer/LLVM/Server.hs
--- old-llvm-tf/alsa/Synthesizer/LLVM/Server.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/alsa/Synthesizer/LLVM/Server.hs	2016-08-25 13:23:11.000000000 +0200
@@ -11,7 +11,7 @@
 
 
 part :: Int
-part = 106
+part = 153 -- 159 -- 415 -- 105
 
 main :: IO ()
 main =
@@ -71,6 +71,7 @@
       405 -> ServerCausalTest.sequenceStaccato
       406 -> ServerCausalTest.sequenceControlled
       407 -> ServerCausalTest.sequenceControlledModulated
+      408 -> ServerCausalTest.speech
       409 -> ServerCausalTest.functional
       410 -> ServerCausalTest.functionalPlug
       411 -> ServerCausalTest.functionalTine >>
diff -rN -u old-llvm-tf/example/Synthesizer/LLVM/LNdW2011.hs new-llvm-tf/example/Synthesizer/LLVM/LNdW2011.hs
--- old-llvm-tf/example/Synthesizer/LLVM/LNdW2011.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/example/Synthesizer/LLVM/LNdW2011.hs	2016-08-25 13:23:11.000000000 +0200
@@ -222,7 +222,9 @@
    IO ()
 playFromEvents latency period =
    PALSA.playFromEvents
-      Play.defaultDevice (ClientName "Haskell-LLVM-demo")
+--      Play.defaultDevice
+      ("tee:default,'/tmp/test.f32',raw")
+      (ClientName "Haskell-LLVM-demo")
       latency period sampleRate
 
 
@@ -548,8 +550,12 @@
        .
        MCS.filter [
           MCS.controllerExponential Ctrl.volume (0.001, 0.99) 0.2,
+          MCS.controllerLinear (Ctrl.fromInt 73) (0, 5) 2,
+          MCS.controllerExponential (Ctrl.fromInt 72) (hertz 100, hertz 500) (hertz 250),
+{-
           MCS.controllerLinear Ctrl.modulation (0, 5) 2,
           MCS.pitchBend 2 (hertz 250),
+-}
           MCS.controllerLinear Ctrl.vectorX (-10, 10) 0,
           MCS.controllerLinear Ctrl.vectorY (-10, 10) 0]
        .
diff -rN -u old-llvm-tf/example/Synthesizer/LLVM/Test.hs new-llvm-tf/example/Synthesizer/LLVM/Test.hs
--- old-llvm-tf/example/Synthesizer/LLVM/Test.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/example/Synthesizer/LLVM/Test.hs	2016-08-25 13:23:11.000000000 +0200
@@ -4,6 +4,7 @@
 
 import Synthesizer.LLVM.LAC2011 ()
 import Synthesizer.LLVM.LNdW2011 ()
+import qualified Synthesizer.LLVM.LNdW2011 as LNdW2011
 
 import qualified Synthesizer.LLVM.Server.Default as Default
 import qualified Synthesizer.LLVM.Server.SampledSound as Sample
@@ -28,6 +29,7 @@
 import qualified Synthesizer.LLVM.Causal.ProcessValue as CausalV
 import qualified Synthesizer.LLVM.Causal.Process as Causal
 import qualified Synthesizer.LLVM.Interpolation as Interpolation
+-- import qualified Synthesizer.LLVM.Simple.Value as Value
 import qualified Synthesizer.LLVM.Simple.Signal as Sig
 import qualified Synthesizer.LLVM.Simple.Value as Value
 import qualified Synthesizer.LLVM.Storable.Signal as SigStL
@@ -1995,3 +1997,8 @@
 main = do
    LLVM.initializeNativeTarget
    filterSweepComplex
+--   playMono (pingSig 0.01)
+--   helixSpeechVariCompare
+   when False LNdW2011.flyPacked
+   when False LNdW2011.modulation
+   when False LNdW2011.bubblesPacked
diff -rN -u old-llvm-tf/jack/Synthesizer/LLVM/Server/JACK.hs new-llvm-tf/jack/Synthesizer/LLVM/Server/JACK.hs
--- old-llvm-tf/jack/Synthesizer/LLVM/Server/JACK.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/jack/Synthesizer/LLVM/Server/JACK.hs	2016-08-25 13:23:11.000000000 +0200
@@ -257,4 +257,4 @@
 
 
 main :: IO ()
-main = keyboardMultiChannel
+main = voderMaskSeparated
diff -rN -u old-llvm-tf/Makefile new-llvm-tf/Makefile
--- old-llvm-tf/Makefile	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/Makefile	2016-08-25 13:23:11.000000000 +0200
@@ -1,5 +1,5 @@
-GHCI7 = ghci -XCPP -DNoImplicitPrelude=RebindableSyntax
-BUILDDIR = dist/repl
+GHCI7 = ghci-7.8.4 -XCPP -DNoImplicitPrelude=RebindableSyntax
+BUILDDIR = dist/repl78
 DIRS = -i:src:example:testsuite:alsa:jack -hidir $(BUILDDIR) -odir $(BUILDDIR) -stubdir $(BUILDDIR)
 
 # Option -fobject-code is required to handle the foreign import of the FunPtr.
@@ -10,10 +10,10 @@
 	$(GHCI7) -Wall -fobject-code $(DIRS) example/Synthesizer/LLVM/Test.hs
 
 ghci-inst:
-	ghci -Wall -i:example example/Synthesizer/LLVM/LNdW2011.hs
+	ghci -Wall -i:example:alsa example/Synthesizer/LLVM/LNdW2011.hs
 
 ghci7-inst:
-	$(GHCI7) -hide-package llvm -Wall example/Synthesizer/LLVM/LNdW2011.hs
+	$(GHCI7) -Wall -i:example:alsa example/Synthesizer/LLVM/LNdW2011.hs
 
 ghci-server:
 	ghci -Wall server/Synthesizer/LLVM/Server.hs server/Synthesizer/LLVM/Server/*.hs
@@ -31,6 +31,9 @@
 %.s:	%.bc
 	llc $<
 
+%.o:	%.bc
+	llc -filetype obj $<
+
 # This would lead to a cycle with llvm-as.
 # %.ll:	%.bc
 #	llvm-dis $<
diff -rN -u old-llvm-tf/server/Synthesizer/LLVM/Server/CausalPacked/Arrange.hs new-llvm-tf/server/Synthesizer/LLVM/Server/CausalPacked/Arrange.hs
--- old-llvm-tf/server/Synthesizer/LLVM/Server/CausalPacked/Arrange.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/server/Synthesizer/LLVM/Server/CausalPacked/Arrange.hs	2016-08-25 13:23:11.000000000 +0200
@@ -460,6 +460,9 @@
    note _chan (Phoneme on v p) = Just (v, p, on)
 
 
+{-
+We should only filter out keys where we have phonemes.
+-}
 voderSplit ::
    (Check.C msg, Construct.C msg, Arrow arrow) =>
    ChannelMsg.Channel ->
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Causal/Process.hs new-llvm-tf/src/Synthesizer/LLVM/Causal/Process.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Causal/Process.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Causal/Process.hs	2016-08-25 13:23:11.000000000 +0200
@@ -58,6 +58,7 @@
    runStorableChunky,
    ) where
 
+-- import qualified Synthesizer.LLVM.RingBuffer as RingBuffer
 import Synthesizer.LLVM.Causal.ProcessPrivate
 
 import qualified Synthesizer.LLVM.Simple.SignalPrivate as Sig
@@ -66,6 +67,7 @@
 import qualified Synthesizer.LLVM.Frame.Stereo as Stereo
 import qualified Synthesizer.LLVM.Frame as Frame
 import qualified Synthesizer.LLVM.Execution as Exec
+-- import Synthesizer.LLVM.Causal.ProcessPrivate (reverbParams, )
 
 import qualified Synthesizer.Plain.Modifier as Modifier
 import qualified Synthesizer.Causal.Class as CausalClass
@@ -106,10 +108,13 @@
 import Data.Tuple.HT (swap, )
 import Data.Word (Word32, )
 
+import System.Random (Random, RandomGen, )
+
 import qualified Foreign.Marshal.Utils as AllocUtil
+import qualified Foreign.Concurrent as FC
 import Foreign.Storable (Storable, )
-import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, newForeignPtr, )
-import Foreign.Ptr (FunPtr, Ptr, )
+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, )
+import Foreign.Ptr (Ptr, )
 import Control.Exception (bracket, )
 import qualified System.Unsafe as Unsafe
 
@@ -268,6 +273,55 @@
    process a a
 delay1Zero = loopZero (arr swap)
 
+{-
+delayZero :: (Memory.C a, A.Additive a) => Int -> T p a a
+delayZero time =
+   map RingBuffer.oldest <<< RingBuffer.trackConst A.zero time
+
+{- |
+Delay time must be greater than zero!
+-}
+comb ::
+   (A.PseudoRing al,
+    Storable a, MakeValueTuple a, ValueTuple a ~ al, Memory.C al) =>
+   a -> Int -> T p (Value a) (Value a)
+comb gain time =
+   loopZero (mix >>> (Cat.id &&&
+      (delayZero (time-1) >>> amplify gain)))
+
+{- |
+Example: apply a stereo reverb to a mono sound.
+
+> traverse
+>    (\seed -> reverb (Random.mkStdGen seed) 16 (0.92,0.98) (200,1000))
+>    (Stereo.cons 42 23)
+
+Unfortunately 'reverb' replicates code:
+@num@ comb filters mean @num@ times the code of 'comb'.
+This is because in principle the types inside the 'comb' Process
+depend on the parameters.
+We can only hope that the LLVM optimizer can spot such duplications,
+but I do not think it actually does so.
+-}
+reverb ::
+   (Random a,
+    IsArithmetic a, SoV.RationalConstant a,
+    MakeValueTuple a, ValueTuple a ~ (Value a),
+    Storable a, Memory.FirstClass a,
+    RandomGen g) =>
+   g -> Int -> (a,a) -> (Int,Int) ->
+   T p (Value a) (Value a)
+reverb rnd num gainRange timeRange =
+{-
+Is it necessary to add the original signal?
+Why do we divide by num, not (num+1) then?
+-}
+   map (A.mul (A.fromRational' $ recip $ fromIntegral num)) <<<
+   (foldl (+) Cat.id $
+    List.map (\(g,t) -> comb $# g $# t) $
+    reverbParams rnd num gainRange timeRange)
+-}
+
 
 {- |
 This allows to compute a chain of equal processes efficiently,
@@ -522,6 +576,12 @@
          (stop . snd))
 
 {-
+extendFold :: Core a b -> Fold.T b c -> Fold.T a c
+extendFold f (Fold.Cons acc b0) = Fold.Cons (\b a -> acc b =<< f a) b0
+-}
+
+
+{-
 It is quite similar to quantizeLift but the control is the reciprocal.
 This is especially a problem since we need the fractional part for interpolation.
 -}
@@ -616,11 +676,10 @@
    (forall r z.
     (Phi z) => param -> aValue -> state -> MaybeCont.T r z (bValue, state)) ->
    (forall r. param -> CodeGenFunction r state) ->
-   IO (FunPtr
-         (Ptr paramStruct -> Word32 -> Ptr aStruct -> Ptr bStruct -> IO Word32))
+   IO (Ptr paramStruct -> Word32 -> Ptr aStruct -> Ptr bStruct -> IO Word32)
 compile next start =
    Exec.compileModule $
-      Exec.createFunction "fillprocessblock" $
+      Exec.createFunction derefFillPtr "fillprocessblock" $
          \ paramPtr size alPtr blPtr -> do
             param <- Memory.load paramPtr
             s <- start param
@@ -657,7 +716,7 @@
          SVB.createAndTrim len $ \ bPtr ->
          AllocUtil.with params $ \paramPtr ->
             fmap (fromIntegral :: Word32 -> Int) $
-            derefFillPtr fill
+            fill
                (Memory.castStorablePtr paramPtr)
                (fromIntegral len)
                (Memory.castStorablePtr aPtr)
@@ -667,6 +726,9 @@
 foreign import ccall safe "dynamic" derefStartPtr ::
    Exec.Importer (Ptr b -> IO (Ptr a))
 
+foreign import ccall safe "dynamic" derefStopPtr ::
+   Exec.Importer (Ptr a -> IO ())
+
 foreign import ccall safe "dynamic" derefChunkPtr ::
    Exec.Importer
       (Ptr paramStruct -> Ptr stateStruct -> Word32 ->
@@ -683,22 +745,22 @@
     param -> aValue -> state -> MaybeCont.T r z (bValue, state)) ->
    (forall r.
     param -> CodeGenFunction r state) ->
-   IO (FunPtr (Ptr paramStruct -> IO (Ptr stateStruct)),
-       FunPtr (Ptr stateStruct -> IO ()),
-       FunPtr (Ptr paramStruct -> Ptr stateStruct ->
-               Word32 -> Ptr aStruct -> Ptr bStruct -> IO Word32))
+   IO (Ptr paramStruct -> IO (Ptr stateStruct),
+       Ptr stateStruct -> IO (),
+       Ptr paramStruct -> Ptr stateStruct ->
+       Word32 -> Ptr aStruct -> Ptr bStruct -> IO Word32)
 compileChunky next start =
    Exec.compileModule $
       liftA3 (,,)
-         (Exec.createFunction "startprocess" $
+         (Exec.createFunction derefStartPtr "startprocess" $
           \paramPtr -> do
              pptr <- LLVM.malloc
              param <- Memory.load paramPtr
              flip Memory.store pptr =<< start param
              ret pptr)
-         (Exec.createFunction "stopprocess" $
+         (Exec.createFunction derefStopPtr "stopprocess" $
           \ pptr -> LLVM.free pptr >> ret ())
-         (Exec.createFunction "fillprocess" $
+         (Exec.createFunction derefChunkPtr "fillprocess" $
           \paramPtr sptr loopLen aPtr bPtr -> do
              sInit <- Memory.load sptr
              param <- Memory.load paramPtr
@@ -720,9 +782,8 @@
     Storable a, MakeValueTuple a,
     Storable b, MakeValueTuple b,
     Storable parameters, MakeValueTuple parameters) =>
-   FunPtr
-      (Ptr paramStruct -> Ptr stateStruct ->
-       Word32 -> Ptr aStruct -> Ptr bStruct -> IO Word32) ->
+   (Ptr paramStruct -> Ptr stateStruct ->
+    Word32 -> Ptr aStruct -> Ptr bStruct -> IO Word32) ->
    ForeignPtr parameters ->
    ForeignPtr stateStruct ->
    SVL.Vector a -> IO [SVB.Vector b]
@@ -737,7 +798,7 @@
                    withForeignPtr statePtr $ \sptr ->
                    SVB.createAndTrim size $
                       fmap (fromIntegral :: Word32 -> Int) .
-                      derefChunkPtr fill paramPtr sptr (fromIntegral size)
+                      fill paramPtr sptr (fromIntegral size)
                          (Memory.castStorablePtr aPtr) .
                       Memory.castStorablePtr
                 (if SV.length v > 0
@@ -758,14 +819,9 @@
    return $ \sig -> SVL.fromChunks $ Unsafe.performIO $ do
       (ioContext, params) <- createIOContext
       paramPtr <- ForeignPtr.new (deleteIOContext ioContext) params
-      statePtr <-
-         if False
-           then
-               -- 'params' will be stored twice
-               ForeignPtr.newParam stopFunc startFunc params
-           else
-               newForeignPtr stopFunc =<<
-               ForeignPtr.with paramPtr (derefStartPtr startFunc)
+      statePtr <- do
+         ptr <- ForeignPtr.with paramPtr startFunc
+         FC.newForeignPtr ptr (stopFunc ptr)
 
       traverseChunks fill paramPtr statePtr sig
 
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Causal/ProcessPrivate.hs new-llvm-tf/src/Synthesizer/LLVM/Causal/ProcessPrivate.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Causal/ProcessPrivate.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Causal/ProcessPrivate.hs	2016-08-25 13:23:11.000000000 +0200
@@ -55,6 +55,7 @@
 
 
 class CausalClass.C process => C process where
+   -- called crochetL in synthesizer-core
    simple ::
       (Memory.C state) =>
       (forall r c.
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/Functional.hs new-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/Functional.hs
--- old-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/Functional.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/Functional.hs	2016-08-25 13:23:11.000000000 +0200
@@ -7,6 +7,10 @@
    lift, fromSignal,
    ($&), (&|&),
    compile,
+{-
+   stereoFromMono,
+   stereoFromMonoControlled,
+-}
    compileSignal,
    withArgs, MakeArguments, Arguments, makeArgs,
    AnyArg(..),
@@ -220,6 +224,7 @@
       (\p a state -> Trans.lift (next p a state))
       start stop create delete
 
+-- rename to fromCausal ?
 lift :: CausalP.T p inp out -> T p inp out
 lift = tagUnique . liftCode
 
@@ -263,6 +268,18 @@
 
 
 {- |
+'Stereo.liftApplicative' specialised to 'T'.
+
+stereoFromMono ::
+   (Phi a, Phi c, Undefined a) =>
+   (forall inp0. T p inp0 c -> T p inp0 a) ->
+   T p inp (Stereo.T c) -> T p inp (Stereo.T a)
+stereoFromMono proc stereo =
+   CausalP.stereoFromMono (proc (lift id)) $& stereo
+-}
+
+
+{- |
 Using 'withArgs' you can simplify
 
 > let x = F.lift (arr fst)
@@ -343,7 +360,7 @@
 
 
 
-
+-- generalize withGuidedArgs and with PatternArgs to FunctionalPlug
 {- |
 This is similar to 'withArgs'
 but it allows to specify the decomposition depth using a pattern.
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/FunctionalPlug.hs new-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/FunctionalPlug.hs
--- old-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/FunctionalPlug.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/FunctionalPlug.hs	2016-08-25 13:23:11.000000000 +0200
@@ -82,6 +82,7 @@
    Plugged
       (pp -> inp -> x)
       (PIn.T x y)
+      -- this is an arrows:Transformer.State
       (CausalP.T pl (y, Vault) (out, Vault))
    |
    {-
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/Process.hs new-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/Process.hs
--- old-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/Process.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/Process.hs	2016-08-25 13:23:11.000000000 +0200
@@ -92,13 +92,13 @@
 import qualified Synthesizer.LLVM.Frame as Frame
 import qualified Synthesizer.LLVM.Execution as Exec
 
+import qualified Synthesizer.Generic.Cut as Cut
+import qualified Synthesizer.Causal.Class as CausalClass
+
 import qualified Data.StorableVector.Lazy as SVL
 import qualified Data.StorableVector as SV
 import qualified Data.StorableVector.Base as SVB
 
-import qualified Synthesizer.Generic.Cut as Cut
-import qualified Synthesizer.Causal.Class as CausalClass
-
 import qualified LLVM.Extra.ScalarOrVector as SoV
 import qualified LLVM.Extra.MaybeContinuation as MaybeCont
 import qualified LLVM.Extra.Maybe as Maybe
@@ -122,6 +122,7 @@
 import Control.Monad (liftM, when, )
 import Control.Applicative (liftA2, liftA3, pure, (<*>), )
 import Control.Functor.HT (void, unzip, )
+import Control.Exception (bracket, )
 
 import qualified Data.List as List
 import Data.Traversable (traverse, )
@@ -132,22 +133,22 @@
 
 import System.Random (Random, RandomGen, )
 
-import qualified Algebra.Transcendental as Trans
-
 import qualified Synthesizer.LLVM.Alloc as Alloc
 import qualified System.Unsafe as Unsafe
 import qualified Foreign.Marshal.Utils as AllocUtil
+-- import qualified Foreign.Concurrent as FC
 import Foreign.Storable.Tuple ()
 import Foreign.Storable (Storable, poke, peek, )
 import Foreign.StablePtr
           (StablePtr, newStablePtr, freeStablePtr, deRefStablePtr, )
 import Foreign.ForeignPtr (touchForeignPtr, withForeignPtr, )
 import Foreign.Ptr (FunPtr, Ptr, castPtr, freeHaskellFunPtr, )
-import Control.Exception (bracket, )
 
 import qualified Synthesizer.LLVM.Debug.Storable as DebugSt
 import qualified Synthesizer.LLVM.Debug.Counter as DebugCnt
 
+import qualified Algebra.Transcendental as Trans
+
 import NumericPrelude.Numeric
 import NumericPrelude.Base hiding
           (and, iterate, map, unzip, zip, zipWith, take, takeWhile, sequence_, )
@@ -462,6 +463,7 @@
 {- |
 Delay by a variable amount of samples.
 The momentum delay must be between @0@ and @maxTime@, inclusively.
+How about automated clipping?
 -}
 delayControlled ::
    (Storable a, MakeValueTuple a, ValueTuple a ~ al, Memory.C al) =>
@@ -476,6 +478,8 @@
 Non-integer delays are achieved by linear interpolation.
 The momentum delay must be between @0@ and @maxTime@, inclusively.
 -}
+-- delayControlledInterpolatedZero
+
 delayControlledInterpolated ::
    (Interpolation.C nodes,
     Storable vh, MakeValueTuple vh, ValueTuple vh ~ v, Memory.C v,
@@ -517,7 +521,7 @@
    T p al al
 comb gain time =
    loopZero (mix >>> (Cat.id &&&
-      (delayZero (subtract 1 time) >>> amplify gain)))
+      (delayZero (time-1) >>> amplify gain)))
 
 combStereo ::
    (A.PseudoRing al,
@@ -528,17 +532,7 @@
    loopZero (mix >>> (Cat.id &&&
       (delayZero (subtract 1 time) >>> amplifyStereo gain)))
 
-{- |
-Example: apply a stereo reverb to a mono sound.
 
-> traverse
->    (\seed -> reverbSimple (Random.mkStdGen seed) 16 (0.92,0.98) (200,1000))
->    (Stereo.cons 42 23)
-
-There is a serious problem:
-The parameters are not of type 'Param.T',
-thus they cannot depend e.g. on a dynamic sample rate as required by JACK.
--}
 reverbSimple ::
    (Random a,
     IsArithmetic a, SoV.RationalConstant a,
@@ -611,6 +605,9 @@
 but the factor is reciprocal and controllable
 and we use linear interpolation.
 The shrinking factor must be non-negative.
+
+The functionality for skipping of input values
+can certainly be shared with quantizeLift and Signal.interpolateConstant.
 -}
 frequencyModulationLinear ::
    (SoV.IntegerConstant a, IsFloating a, LLVM.CmpRet a, LLVM.CmpResult a ~ Bool,
@@ -646,8 +643,8 @@
 
 
 {- |
-@trigger fill signal@ send @signal@ to the output
-and restart it whenever the Boolean process input is 'True'.
+@trigger fill signal@ sends @signal@ to the output
+and restarts it whenever the Boolean process input is 'True'.
 Before the first occurrence of 'True'
 and between instances of the signal the output is filled with 'Maybe.nothing'.
 
@@ -732,9 +729,8 @@
    IO (p -> SV.Vector a -> SV.Vector b)
 runStorable (Cons next start stop createIOContext deleteIOContext) = do
    fill <-
-      fmap derefFillPtr $
       Exec.compileModule $
-      Exec.createFunction "fillprocessblock" $
+      Exec.createFunction derefFillPtr "fillprocessblock" $
       \paramPtr size alPtr blPtr -> do
          param <- Memory.load paramPtr
          (c,s) <- start param
@@ -793,23 +789,23 @@
     CodeGenFunction r ()) ->
    IO (FunPtr (Ptr paramStruct -> IO (Ptr contextStateStruct)),
        FunPtr (Ptr contextStateStruct -> IO ()),
-       FunPtr (Ptr contextStateStruct -> Word32 ->
-               Ptr structA -> Ptr structB -> IO Word32))
+       Ptr contextStateStruct -> Word32 ->
+       Ptr structA -> Ptr structB -> IO Word32)
 compileChunky next start stop =
    Exec.compileModule $
       liftA3 (,,)
-         (Exec.createFunction "startprocess" $
+         (Exec.createFunPtr "startprocess" $
           \paramPtr -> do
              pptr <- LLVM.malloc
              flip Memory.store pptr . mapSnd Maybe.just =<< start =<< Memory.load paramPtr
              ret pptr)
-         (Exec.createFunction "stopprocess" $
+         (Exec.createFunPtr "stopprocess" $
           \ contextStatePtr -> do
              (c,ms) <- Memory.load contextStatePtr
              Maybe.for ms $ stop c
              LLVM.free contextStatePtr
              ret ())
-         (Exec.createFunction "fillprocess" $
+         (Exec.createFunction derefChunkPtr "fillprocess" $
           \ contextStatePtr loopLen aPtr bPtr -> do
              (param, msInit) <- Memory.load contextStatePtr
              (pos,msExit) <-
@@ -864,23 +860,23 @@
     LLVM.CodeGenFunction r stateOut) ->
    IO (FunPtr (Ptr paramStruct -> IO (Ptr contextStateStruct)),
        FunPtr (Ptr contextStateStruct -> IO ()),
-       FunPtr (Ptr contextStateStruct -> Word32 ->
-               Ptr paramStructIn -> Ptr paramStructOut -> IO Word32))
+       Ptr contextStateStruct -> Word32 ->
+       Ptr paramStructIn -> Ptr paramStructOut -> IO Word32)
 compilePlugged nextIn startIn next start stop nextOut startOut =
    Exec.compileModule $
       liftA3 (,,)
-         (Exec.createFunction "startprocess" $
+         (Exec.createFunPtr "startprocess" $
           \paramPtr -> do
              pptr <- LLVM.malloc
              flip Memory.store pptr . mapSnd Maybe.just =<< start =<< Memory.load paramPtr
              ret pptr)
-         (Exec.createFunction "stopprocess" $
+         (Exec.createFunPtr "stopprocess" $
           \ contextStatePtr -> do
              (c,ms) <- Memory.load contextStatePtr
              Maybe.for ms $ stop c
              LLVM.free contextStatePtr
              ret ())
-         (Exec.createFunction "fillprocess" $
+         (Exec.createFunction derefChunkPtr "fillprocess" $
           \ contextStatePtr loopLen inPtr outPtr -> do
              (param, msInit) <- Memory.load contextStatePtr
              inParam  <- Memory.load inPtr
@@ -943,7 +939,7 @@
                         withForeignPtr statePtr $ \sptr ->
                         SVB.createAndTrim size $
                         fmap fromIntegral .
-                        derefChunkPtr fill sptr
+                        fill sptr
                            (fromIntegral size)
                            (Memory.castStorablePtr aPtr) .
                         Memory.castStorablePtr
@@ -1012,10 +1008,15 @@
          actualSize <-
             AllocUtil.with paramIn $ \inptr ->
             AllocUtil.with paramOut $ \outptr ->
-            derefChunkPtr fill paramPtr
+            fill paramPtr
                (fromIntegral maximumSize)
                (Memory.castStorablePtr inptr)
                (Memory.castStorablePtr outptr)
+         -- print actualSize
+         when (fromIntegral actualSize > maximumSize) $
+            error $ "CausalParametrized.Process: " ++
+                    "output size " ++ show actualSize ++
+                    " > input size " ++ show maximumSize
          deleteIn contextIn
          b <- deleteOut (fromIntegral actualSize) contextOut
          return (b, s))
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/ProcessPacked.hs new-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/ProcessPacked.hs
--- old-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/ProcessPacked.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/ProcessPacked.hs	2016-08-25 13:23:11.000000000 +0200
@@ -117,6 +117,9 @@
 differentiate initial =
    Cat.id - delay1 initial
 
+-- is it coherent with scalar 'integrate' ?
+-- Serial.cumulate lags
+-- need another Vector.cumulate
 integrate ::
    (Storable a, MakeValueTuple a, ValueTuple a ~ Value a, Vector.Arithmetic a,
     Memory.FirstClass a, Memory.Stored a ~ am, IsSized am,
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/ProcessPrivate.hs new-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/ProcessPrivate.hs
--- old-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/ProcessPrivate.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/CausalParameterized/ProcessPrivate.hs	2016-08-25 13:23:11.000000000 +0200
@@ -507,3 +507,5 @@
    T p al al
 integrateSync =
    flip loop ((\a -> (a,a)) ^<< zipWithSimple A.add)
+
+-- integrateZero
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/ConstantPiece.hs new-llvm-tf/src/Synthesizer/LLVM/ConstantPiece.hs
--- old-llvm-tf/src/Synthesizer/LLVM/ConstantPiece.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/ConstantPiece.hs	2016-08-25 13:23:11.000000000 +0200
@@ -122,6 +122,7 @@
    EventIt.dispose
 
 
+-- could be based on piecewiseConstant
 lazySize ::
    Param.T p SVP.LazySize ->
    SigP.T p (T ())
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Execution.hs new-llvm-tf/src/Synthesizer/LLVM/Execution.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Execution.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Execution.hs	2016-08-25 13:23:11.000000000 +0200
@@ -60,6 +60,10 @@
 
    Counter.with counter $ R.ReaderT $ \cnt -> do
       writeBitcodeToFile "" cnt m
+{-
+causes Instrument.sampledSound to generate larger output chunks than input chunks
+this may generate junk at the end of sampled sounds
+-}
       when False $ do
          void $ Opt.optimizeModule 3 m
          writeBitcodeToFile "-opt" cnt m
@@ -73,12 +77,18 @@
    String -> LLVM.FunctionCodeGen f -> LLVM.CodeGenModule (LLVM.Function f)
 createLLVMFunction = LLVM.createNamedFunction LLVM.ExternalLinkage
 
-createFunction ::
+createFunPtr ::
    (LLVM.FunctionArgs f) =>
    String -> LLVM.FunctionCodeGen f -> Exec (FunPtr f)
-createFunction name f =
+createFunPtr name f =
    Compose $ EE.getPointerToFunction <$> createLLVMFunction name f
 
+createFunction ::
+   (EE.ExecutionFunction f, LLVM.FunctionArgs f) =>
+   (FunPtr f -> f) -> String -> LLVM.FunctionCodeGen f -> Exec f
+createFunction importer name f =
+   Compose $ EE.getExecutionFunction importer <$> createLLVMFunction name f
+
 
 auxForeignPtr :: IO () -> IO (ForeignPtr CChar)
 auxForeignPtr = FC.newForeignPtr nullPtr
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Filter/Allpass.hs new-llvm-tf/src/Synthesizer/LLVM/Filter/Allpass.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Filter/Allpass.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Filter/Allpass.hs	2016-08-25 13:23:11.000000000 +0200
@@ -66,6 +66,7 @@
 
 import NumericPrelude.Numeric
 import NumericPrelude.Base
+-- import qualified Prelude as P
 
 
 instance (Phi a) => Phi (Parameter a) where
@@ -201,6 +202,8 @@
          (Undefined, Class.Zero, Storable,
           Functor, App.Applicative, Fold.Foldable, Trav.Traversable)
 
+-- deriving instance (Phi a) => Phi (CascadeParameter n a)
+
 instance (Phi a) => Phi (CascadeParameter n a) where
    phis bb (CascadeParameter v) = fmap CascadeParameter $ Loop.phis bb v
    addPhis bb (CascadeParameter x) (CascadeParameter y) = Loop.addPhis bb x y
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Filter/NonRecursive.hs new-llvm-tf/src/Synthesizer/LLVM/Filter/NonRecursive.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Filter/NonRecursive.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Filter/NonRecursive.hs	2016-08-25 13:23:11.000000000 +0200
@@ -16,6 +16,7 @@
 import qualified Synthesizer.LLVM.Storable.Vector as SVU
 import qualified Data.StorableVector as SV
 
+-- import qualified LLVM.Extra.Vector as Vector
 import qualified LLVM.Extra.Memory as Memory
 import qualified LLVM.Extra.Control as C
 import qualified LLVM.Extra.Arithmetic as A
@@ -178,3 +179,21 @@
    (ai,r2) <- Serial.shiftUp undefTuple r1
    (_, a1) <- Serial.shiftUp ai a0
    return (a1, ((a1,r2,j2), k1))
+
+
+{-
+{-
+Before calling this you must reverse the vectors
+either in the ring buffer or in the mask.
+-}
+scalarProductPackedMask ::
+   (Memory.FirstClass a, Memory.Stored a ~ am,
+    LLVM.IsPrimitive am, IsSized am, SizeOf am ~ amsize,
+    TypeNum.Positive n, TypeNum.Positive (n :*: amsize),
+    Vector.Arithmetic a) =>
+   Value Word32 ->
+   RingBuffer.T (Vector n am) -> Value (Ptr (Vector n am)) ->
+   CodeGenFunction r (Value a)
+scalarProductPackedMask n rb mask =
+   Vector.sum =<< scalarProduct n rb mask
+-}
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Filter/SecondOrder.hs new-llvm-tf/src/Synthesizer/LLVM/Filter/SecondOrder.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Filter/SecondOrder.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Filter/SecondOrder.hs	2016-08-25 13:23:11.000000000 +0200
@@ -149,6 +149,16 @@
    unfoldCode = Value.unfoldCodeTraversable
 
 
+{-
+ToDo:
+define lowpassParameter, bandpassParameter, highpassParameter, bandlimitParameter
+that match the behavior of the Universal filter.
+The recursive portion should be the same for all these filters.
+Only the non-recursive portion should differ.
+This way we would also get a version of the universal filter
+that can be vectorized.
+We should define and test this conversion in synthesizer-core.
+-}
 {-# DEPRECATED bandpassParameter "only for testing, use Universal or Moog filter for production code" #-}
 bandpassParameter ::
    (A.Transcendental a, A.RationalConstant a) =>
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Frame/SerialVector.hs new-llvm-tf/src/Synthesizer/LLVM/Frame/SerialVector.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Frame/SerialVector.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Frame/SerialVector.hs	2016-08-25 13:23:11.000000000 +0200
@@ -91,6 +91,19 @@
       A.IntegerConstant, A.RationalConstant, Num)
 --      SoV.IntegerConstant, SoV.RationalConstant, SoV.TranscendentalConstant)
 
+{-
+deriving instance Phi v => Phi (T v)
+deriving instance A.Additive v => A.Additive (T v)
+deriving instance A.Algebraic v => A.Algebraic (T v)
+deriving instance A.Transcendental v => A.Transcendental (T v)
+deriving instance A.PseudoRing v => A.PseudoRing (T v)
+deriving instance A.Field v => A.Field (T v)
+deriving instance A.Real v => A.Real (T v)
+deriving instance A.Fraction v => A.Fraction (T v)
+-}
+
+-- deriving instance St.Storable v => St.Storable (T v)
+
 instance (Phi v) => Phi (T v) where
    phis bb (Cons v) = fmap Cons $ Loop.phis bb v
    addPhis bb (Cons x) (Cons y) = Loop.addPhis bb x y
@@ -173,6 +186,8 @@
 newtype Iterator mode it v = Iterator {unIterator :: it}
    deriving (Class.Undefined)
 
+-- deriving instance Phi it => Phi (Iterator mode it v)
+
 instance Phi it => Phi (Iterator mode it v) where
    phis bb (Iterator x) = fmap Iterator $ Loop.phis bb x
    addPhis bb (Iterator x) (Iterator y) = Loop.addPhis bb x y
@@ -279,6 +294,7 @@
 
    readStart (Cons v) = return $ Iterator v
    readNext (Iterator v0) = do
+      -- How about using Vector.shiftDown with undef element instead?
       x <- Vector.extract (LLVM.valueOf 0) v0
       v1 <- Vector.rotateDown v0
       return (x, Iterator v1)
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Frame.hs new-llvm-tf/src/Synthesizer/LLVM/Frame.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Frame.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Frame.hs	2016-08-25 13:23:11.000000000 +0200
@@ -25,6 +25,7 @@
 import NumericPrelude.Base
 
 
+-- maybe move this and other Stereo functions to Frame.Stereo
 {- |
 Copy mono signal to both stereo channels.
 -}
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Interpolation.hs new-llvm-tf/src/Synthesizer/LLVM/Interpolation.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Interpolation.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Interpolation.hs	2016-08-25 13:23:11.000000000 +0200
@@ -106,6 +106,11 @@
    writeNext = Serial.writeNextTraversable
    writeStop = Serial.writeStopTraversable
 
+{-
+instance (Serial.Zero v) => Serial.Zero (Nodes02 v) where
+   writeZero = Serial.writeZeroTraversable
+-}
+
 
 instance (Class.Undefined a) => Class.Undefined (Nodes02 a) where
    undefTuple = Class.undefTuplePointed
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Parameterized/Signal.hs new-llvm-tf/src/Synthesizer/LLVM/Parameterized/Signal.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Parameterized/Signal.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Parameterized/Signal.hs	2016-08-25 13:23:11.000000000 +0200
@@ -45,11 +45,11 @@
 import qualified LLVM.Extra.Maybe as Maybe
 import qualified LLVM.Extra.ForeignPtr as ForeignPtr
 import qualified LLVM.Extra.Memory as Memory
-import qualified LLVM.Extra.Execution as ExecExtra
 import LLVM.Extra.Class (MakeValueTuple, ValueTuple, Undefined, undefTuple, )
 import LLVM.Extra.Arithmetic (advanceArrayElementPtr, )
 import LLVM.Extra.Control (whileLoop, ifThen, )
 
+import qualified LLVM.ExecutionEngine as EE
 import qualified LLVM.Util.Loop as Loop
 import qualified LLVM.Core as LLVM
 import LLVM.Core
@@ -81,6 +81,7 @@
 import Foreign.Ptr (FunPtr, Ptr, nullPtr, )
 import Control.Exception (bracket, )
 import qualified System.Unsafe as Unsafe
+-- import qualified Foreign.Concurrent as FC
 
 import qualified Synthesizer.LLVM.Debug.Storable as DebugSt
 import qualified Synthesizer.LLVM.Debug.Counter as Counter
@@ -594,9 +595,8 @@
 run (Cons next start stop createIOContext deleteIOContext) =
    do -- this compiles once and is much faster than simpleFunction
       fill <-
-         fmap derefFillPtr .
          Exec.compileModule .
-         Exec.createFunction "fillsignalblock" $
+         Exec.createFunction derefFillPtr "fillsignalblock" $
          \paramPtr size bPtr -> do
             param <- Memory.load paramPtr
             (c,s) <- start param
@@ -686,11 +686,16 @@
     context -> state -> CodeGenFunction r ()) ->
    IO (FunPtr (Ptr paramStruct -> IO (Ptr contextStateStruct)),
        FunPtr (Ptr contextStateStruct -> IO ()),
-       FunPtr (Ptr contextStateStruct ->
-               Word32 -> Ptr struct -> IO Word32))
+       Ptr contextStateStruct -> Word32 -> Ptr struct -> IO Word32)
 compileChunky next start stop =
    Exec.compileModule $
-   Compose (ExecExtra.compile <$> moduleChunky next start stop)
+   Compose
+      ((\(nextF, startF, stopF) ->
+         liftA3 (,,)
+            (EE.getPointerToFunction nextF)
+            (EE.getPointerToFunction startF)
+            (EE.getExecutionFunction derefFillPtr stopF))
+         <$> moduleChunky next start stop)
 
 debugMain ::
    forall parameters struct paramStruct contextStateStruct.
@@ -786,7 +791,7 @@
                          withForeignPtr statePtr $ \sptr ->
                          SVB.createAndTrim size $
                          fmap fromIntegral .
-                         derefChunkPtr fill sptr (fromIntegral size) .
+                         fill sptr (fromIntegral size) .
                          Memory.castStorablePtr
                       touchForeignPtr ioContextPtr
                       (if SV.length v > 0
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Random.hs new-llvm-tf/src/Synthesizer/LLVM/Random.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Random.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Random.hs	2016-08-25 13:23:11.000000000 +0200
@@ -3,6 +3,8 @@
 Very simple random number generator according to Knuth
 which should be fast and should suffice for generating just noise.
 <http://www.softpanorama.org/Algorithms/random_generators.shtml>
+
+We can certainly avoid the 'rem' operation using Montgomery multiplication.
 -}
 module Synthesizer.LLVM.Random where
 
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/Instrument.hs new-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/Instrument.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/Instrument.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/Instrument.hs	2016-08-25 13:23:11.000000000 +0200
@@ -77,8 +77,10 @@
 import qualified Data.StorableVector as SV
 
 import qualified LLVM.Extra.Monad as LM
+import LLVM.Extra.Class (Undefined, )
 
 import qualified LLVM.Core as LLVM
+import LLVM.Util.Loop (Phi, )
 
 import qualified Type.Data.Num.Decimal as TypeNum
 
@@ -87,13 +89,14 @@
 import Control.Category (id, (.), )
 import Control.Monad (liftM2, liftM3, liftM4, (<=<), )
 import Control.Applicative (pure, liftA2, liftA3, )
+import Control.Functor.HT (unzip, )
 import Data.Monoid (mappend, )
-import Data.Tuple.HT (fst3, snd3, thd3, )
+import Data.Tuple.HT (fst3, snd3, thd3, mapPair, )
 
 import qualified Number.DimensionTerm as DN
 
 import NumericPrelude.Numeric
-import NumericPrelude.Base hiding (id, (.), )
+import NumericPrelude.Base hiding (id, unzip, (.), )
 
 
 type Instrument a sig = SampleRate a -> MIO.Instrument a sig
@@ -406,16 +409,62 @@
                   expo =
                      F.fromSignal $
                      SigPS.exponential2 (timeConst 1) (1 + vel)
-                  osci freq =
-                     CausalPS.osciSimple WaveL.approxSine2 $&
-                        expo * depth *
-                           (CausalPS.osciSimple WaveL.approxSine2
-                            $& zero &|& index*freq)
-                        &|&
-                        freq
-              in  Stereo.liftApplicative osci freqs)))
+                  osci indexDepth freq =
+                     case unzip indexDepth of
+                        (index1,depth1) ->
+                           CausalPS.osciSimple WaveL.approxSine2 $&
+                              expo * depth1 *
+                                 (CausalPS.osciSimple WaveL.approxSine2
+                                  $& zero &|& index1*freq)
+                              &|&
+                              freq
+              in  stereoFromMonoControlled osci (index&|&depth) freqs)))
       (pingControlledEnvelope (Just 0.01))
 
+{- |
+'Stereo.liftApplicative' specialised to 'T'.
+
+Should be moved to Functional utility module.
+(Functional module itself would cause cyclic dependency.)
+-}
+stereoFromMonoControlled,
+      _stereoFromMonoControlledArgs,
+      _stereoFromMonoControlledGuided,
+      _stereoFromMonoControlledPrepared,
+      _stereoFromMonoControlledPrepared2 ::
+   (Phi a, Phi b, Phi c, Undefined b) =>
+   (forall inp0. F.T p inp0 c -> F.T p inp0 a -> F.T p inp0 b) ->
+   F.T p inp c -> F.T p inp (Stereo.T a) -> F.T p inp (Stereo.T b)
+stereoFromMonoControlled proc ctrl stereo =
+   CausalP.stereoFromMonoControlled
+      (F.compile $ uncurry proc $ unzip $ F.lift id)
+   $&
+   ctrl &|& stereo
+
+_stereoFromMonoControlledArgs proc ctrl stereo =
+   CausalP.stereoFromMonoControlled
+      (F.withArgs (uncurry proc) <<^ mapPair (F.AnyArg, F.AnyArg))
+   $&
+   ctrl &|& stereo
+
+_stereoFromMonoControlledGuided proc ctrl stereo =
+   CausalP.stereoFromMonoControlled
+      (F.withGuidedArgs (F.atom, F.atom) (uncurry proc))
+   $&
+   ctrl &|& stereo
+
+_stereoFromMonoControlledPrepared proc ctrl stereo =
+   CausalP.stereoFromMonoControlled
+      (F.withPreparedArgs (F.pairArgs F.atomArg F.atomArg) (uncurry proc))
+   $&
+   ctrl &|& stereo
+
+_stereoFromMonoControlledPrepared2 proc ctrl stereo =
+   CausalP.stereoFromMonoControlled
+      (F.withPreparedArgs2 F.atomArg F.atomArg proc)
+   $&
+   ctrl &|& stereo
+
 
 bellNoiseStereoFM ::
    IO (SampleRate Real -> Real -> Real ->
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/InstrumentPlug.hs new-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/InstrumentPlug.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/InstrumentPlug.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/InstrumentPlug.hs	2016-08-25 13:23:11.000000000 +0200
@@ -45,6 +45,8 @@
 
 import qualified LLVM.Core as LLVM
 
+-- import qualified Types.Data.Num as TypeNum
+
 import qualified Data.Traversable as Trav
 import Control.Category (id, (.), )
 import Control.Applicative (liftA2, )
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/SpeechExplore.hs new-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/SpeechExplore.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/SpeechExplore.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/SpeechExplore.hs	2016-08-25 13:23:11.000000000 +0200
@@ -104,7 +104,7 @@
 
 saveSound :: (PathClass.AbsRel ar) => Path.File ar -> SVL.Vector Real -> IO ()
 saveSound path xs =
-   void $ SoxWrite.simple SVL.hPut mempty (Path.toString path) sampleRateInt xs
+   print =<< SoxWrite.simple SVL.hPut mempty (Path.toString path) sampleRateInt xs
 
 tmpWave :: String -> Path.AbsFile
 tmpWave name = Path.absDir "/tmp" </> Path.relFile name <.> "wav"
@@ -344,6 +344,11 @@
 transferMasks ::IO ()
 transferMasks = do
 --   forM_ (map (++"-noise") vowelNames) $ \name -> do
+   {-
+   If this dummy write is missing, then writing the first mask fails.
+   -}
+   saveSound (tmpWave "dummy") $ SVL.fromChunks [SV.replicate 512 0]
+--   forM_ stopConsonantNames $ \name -> do
    forM_ (tonalNames++sibilantNames++stopConsonantNames) $ \name -> do
       trans <- transfer <$> loadPhoneme name
       saveSound (maskWave name) $ normalize $ transferWindow trans
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/Speech.hs new-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/Speech.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/Speech.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Server/CausalPacked/Speech.hs	2016-08-25 13:23:11.000000000 +0200
@@ -1,3 +1,7 @@
+{-
+Sprachverstaendlichkeit durch Hochpassfilter verbessern.
+Entweder bei der Berechnung der Masken im Spektrum oder bei der Synthese.
+-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE NoImplicitPrelude #-}
@@ -74,7 +78,7 @@
 
 {-
 stimmhaft
-a, e, i, o, u, ä, ö, ü
+a, e, i, o, u, ae, oe, ue
 l, m, n, ng
 
 Diphtong
@@ -83,7 +87,7 @@
 stimmlos/Zischlaute
 f, h, w, s, sch, th, ch (weich), ch (kochen), r
 
-explosiv
+plosiv
 b, p, g, k, d, t
 -}
 
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Server/Common.hs new-llvm-tf/src/Synthesizer/LLVM/Server/Common.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Server/Common.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Server/Common.hs	2016-08-25 13:23:11.000000000 +0200
@@ -105,6 +105,7 @@
    [EventListTT.T time body]
 chopEvents chunkSize =
    let go evs =
+          -- splitBeforeTime?
           let (chunk,rest) = EventListTT.splitAtTime chunkSize evs
           in  if EventListTT.duration chunk == 0
                 then []
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Server/CommonPacked.hs new-llvm-tf/src/Synthesizer/LLVM/Server/CommonPacked.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Server/CommonPacked.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Server/CommonPacked.hs	2016-08-25 13:23:11.000000000 +0200
@@ -44,6 +44,7 @@
 type Vector = Serial.Plain VectorSize Real
 type VectorValue = Serial.Value VectorSize Real
 type VectorSize = TypeNum.D4
+-- type VectorSize = TypeNum.D8
 
 
 vectorSize :: Int
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Server/SampledSoundAnalysis.hs new-llvm-tf/src/Synthesizer/LLVM/Server/SampledSoundAnalysis.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Server/SampledSoundAnalysis.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Server/SampledSoundAnalysis.hs	2016-08-25 13:23:11.000000000 +0200
@@ -118,6 +118,12 @@
 argMax =
    fst . Fold.maximumBy (comparing snd) .
    zip (iterate succ 0)
+{-
+argMax :: (Ord a) => SigS.T a -> Int
+argMax =
+   fst . Fold.maximumBy (comparing snd) .
+   SigS.zip (SigS.iterate succ 0)
+-}
 
 main :: IO ()
 main =
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Server/SampledSound.hs new-llvm-tf/src/Synthesizer/LLVM/Server/SampledSound.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Server/SampledSound.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Server/SampledSound.hs	2016-08-25 13:23:11.000000000 +0200
@@ -36,6 +36,7 @@
    }
 
 
+-- ToDo: flag failure if files cannot be found, or just remain silent
 load :: (PathClass.AbsRel ar) => Path.File ar -> IO (SVL.Vector Real)
 load path =
    bracket (SoxRead.open SoxOption.none (Path.toString path)) SoxRead.close $
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Simple/Signal.hs new-llvm-tf/src/Synthesizer/LLVM/Simple/Signal.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Simple/Signal.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Simple/Signal.hs	2016-08-25 13:23:11.000000000 +0200
@@ -9,8 +9,6 @@
    T,
    amplify,
    amplifyStereo,
-   compile,
-   compileChunky,
    constant,
    envelope,
    envelopeStereo,
@@ -78,8 +76,6 @@
 import NumericPrelude.Numeric
 import NumericPrelude.Base hiding (and, iterate, map, zip, zipWith, )
 
-import qualified Prelude as P
-
 
 constant :: (C signal, IsConst a) => a -> signal (Value a)
 constant x = pure (valueOf x)
@@ -100,6 +96,25 @@
       (stop . fst))
 
 
+{-
+{- |
+@tail empty@ generates the empty signal.
+-}
+tail ::
+   (C signal) =>
+   signal a -> signal a
+tail =
+   alter (\(Core next start stop) -> Core
+      next
+      (\parameter -> do
+         (c,s0) <- start parameter
+         MaybeCont.resolve (next c s0)
+            (return (c,s0))
+            (\(_a,s1) -> return (c,s1)))
+      stop)
+-}
+
+
 mix ::
    (C signal, A.Additive a) =>
    signal a -> signal a -> signal a
@@ -242,10 +257,10 @@
     Memory.C state, Memory.Struct state ~ stateStruct) =>
    (forall r z. (Phi z) => state -> MaybeCont.T r z (value, state)) ->
    (forall r. CodeGenFunction r state) ->
-   IO (FunPtr (Word32 -> Ptr struct -> IO Word32))
+   IO (Word32 -> Ptr struct -> IO Word32)
 compile next start =
    Exec.compileModule $
-      Exec.createFunction "fillsignalblock" $ \ size bPtr -> do
+      Exec.createFunction derefFillPtr "fillsignalblock" $ \ size bPtr -> do
          s <- start
          (pos,_) <- MaybeCont.arrayLoop size bPtr s $ \ ptri s0 -> do
             (y,s1) <- next s0
@@ -263,7 +278,7 @@
       do fill <-
             compile (next $ valueTupleOf params) (start $ valueTupleOf params)
          fmap (fromIntegral :: Word32 -> Int) $
-            derefFillPtr fill (fromIntegral len) (Memory.castStorablePtr ptr)
+            fill (fromIntegral len) (Memory.castStorablePtr ptr)
 
 
 foreign import ccall safe "dynamic" derefChunkPtr ::
@@ -280,26 +295,26 @@
     CodeGenFunction r state) ->
    IO (FunPtr (IO (Ptr stateStruct)),
        FunPtr (Ptr stateStruct -> IO ()),
-       FunPtr (Ptr stateStruct -> Word32 -> Ptr struct -> IO Word32))
+       Ptr stateStruct -> Word32 -> Ptr struct -> IO Word32)
 compileChunky next start =
    Exec.compileModule $
       liftA3 (,,)
-         (Exec.createFunction "startsignal" $
+         (Exec.createFunPtr "startsignal" $
           do
              pptr <- LLVM.malloc
              flip Memory.store pptr =<< start
              ret pptr)
 {- for debugging: allocation with initialization makes type inference difficult
-         (Exec.createFunction "startsignal" $
+         (Exec.createFunPtr "startsignal" $
           do
              pptr <- malloc
              let retn :: CodeGenFunction r state -> Value (Ptr state) -> CodeGenFunction (Ptr state) ()
                  retn _ ptr = ret ptr
              retn undefined pptr)
 -}
-         (Exec.createFunction "stopsignal" $
+         (Exec.createFunPtr "stopsignal" $
           \ pptr -> LLVM.free pptr >> ret ())
-         (Exec.createFunction "fillsignal" $
+         (Exec.createFunction derefChunkPtr "fillsignal" $
           \ sptr loopLen ptr -> do
              sInit <- Memory.load sptr
              (pos,sExit) <- MaybeCont.arrayLoop loopLen ptr sInit $
@@ -318,8 +333,7 @@
      (Cons next start createIOContext deleteIOContext) = do
    (ioContext, params) <- createIOContext
    (startFunc, stopFunc, fill) <-
-      compileChunky
-         (next $ valueTupleOf params) (start $ valueTupleOf params)
+      compileChunky (next $ valueTupleOf params) (start $ valueTupleOf params)
 
    statePtr <- ForeignPtr.newInit stopFunc startFunc
    ioContextPtr <- Exec.auxForeignPtr (deleteIOContext ioContext)
@@ -330,7 +344,7 @@
                withForeignPtr statePtr $ \sptr ->
                SVB.createAndTrim size $
                fmap (fromIntegral :: Word32 -> Int) .
-               derefChunkPtr fill sptr (fromIntegral size) .
+               fill sptr (fromIntegral size) .
                Memory.castStorablePtr
             touchForeignPtr ioContextPtr
             (if SV.length v > 0
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Simple/Value.hs new-llvm-tf/src/Synthesizer/LLVM/Simple/Value.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Simple/Value.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Simple/Value.hs	2016-08-25 13:23:11.000000000 +0200
@@ -336,6 +336,8 @@
 and selects components from @t@ and @f@ according to @c@.
 It is useful for vector values and
 for sharing @t@ or @f@ with other branches of an expression.
+
+Attention: vector valued select is not implemented on older LLVM versions.
 -}
 (??) ::
    (LLVM.IsFirstClass a, LLVM.CmpRet a) =>
@@ -542,6 +544,9 @@
 
 instance Flatten a => Flatten (Complex.T a) where
    type Registers (Complex.T a) = Complex.T (Registers a)
+{-
+   flattenCode = flattenCodeTraversable
+-}
    flattenCode s =
       liftM2 (Complex.+:)
          (flattenCode $ Complex.real s)
diff -rN -u old-llvm-tf/src/Synthesizer/LLVM/Storable/Signal.hs new-llvm-tf/src/Synthesizer/LLVM/Storable/Signal.hs
--- old-llvm-tf/src/Synthesizer/LLVM/Storable/Signal.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/src/Synthesizer/LLVM/Storable/Signal.hs	2016-08-25 13:23:11.000000000 +0200
@@ -149,9 +149,8 @@
 makeReverser rev =
    fmap (\f len srcPtr dstPtr ->
       f len (Memory.castStorablePtr srcPtr) (Memory.castStorablePtr dstPtr)) $
-   fmap derefMixPtr $
    Exec.compileModule $
-   Exec.createFunction "reverse" $ \ size ptrA ptrB -> do
+   Exec.createFunction derefMixPtr "reverse" $ \ size ptrA ptrB -> do
       ptrAEnd <- getElementPtr ptrA (size, ())
       _ <- arrayLoop size ptrB ptrAEnd $ \ ptrBi ptrAj0 -> do
          ptrAj1 <- getElementPtr ptrAj0 (-1 :: Int32, ())
@@ -278,9 +277,8 @@
    value -> IO (Word32 -> Ptr a -> IO ())
 fillBuffer x =
    fmap (\f len ptr -> f len (Memory.castStorablePtr ptr)) $
-   fmap derefFillPtr $
    Exec.compileModule $
-   Exec.createFunction "constantfill" $ \ size ptr -> do
+   Exec.createFunction derefFillPtr "constantfill" $ \ size ptr -> do
       arrayLoop size ptr () $ \ ptri () -> do
          Memory.store x ptri
          return ()
@@ -297,9 +295,8 @@
 makeMixer add =
    fmap (\f len srcPtr dstPtr ->
       f len (Memory.castStorablePtr srcPtr) (Memory.castStorablePtr dstPtr)) $
-   fmap derefMixPtr $
    Exec.compileModule $
-   Exec.createFunction "mix" $ \ size srcPtr dstPtr -> do
+   Exec.createFunction derefMixPtr "mix" $ \ size srcPtr dstPtr -> do
       _ <- arrayLoop size srcPtr dstPtr $ \ srcPtri dstPtri -> do
          y <- Memory.load srcPtri
          Memory.modify (add y) dstPtri
diff -rN -u old-llvm-tf/synthesizer-llvm.cabal new-llvm-tf/synthesizer-llvm.cabal
--- old-llvm-tf/synthesizer-llvm.cabal	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/synthesizer-llvm.cabal	2016-08-25 13:23:11.000000000 +0200
@@ -71,7 +71,7 @@
     llvm-extra >=0.6 && <0.7,
     -- llvm must be imported with restrictive version bounds,
     -- because we import implicitly and unqualified
-    llvm-tf >=3.0.3.3 && <3.1.1,
+    llvm-tf >=3.1 && <3.1.1,
     tfp >=1.0 && <1.1,
     vault >=0.3 && <0.4,
     synthesizer-core >=0.8 && <0.9,
@@ -98,6 +98,7 @@
 
   Default-Language: Haskell98
   GHC-Options:    -Wall
+--  GHCi-Options:   -fobject-code
   If impl(ghc>=7.0)
     GHC-Options: -fwarn-unused-do-bind
     CPP-Options: -DNoImplicitPrelude=RebindableSyntax
@@ -441,6 +442,8 @@
       GHC-Options: -fcontext-stack=1000
     Else
       GHC-Options: -freduction-depth=1000
+  -- Explore instead of Analysis,
+  -- because I use "Analysis" for generic signal analysis functions already
   Main-Is:        src/Synthesizer/LLVM/Server/CausalPacked/SpeechExplore.hs
 
 Test-Suite synthi-llvm-test
diff -rN -u old-llvm-tf/testsuite/Test/Synthesizer/LLVM/Filter.hs new-llvm-tf/testsuite/Test/Synthesizer/LLVM/Filter.hs
--- old-llvm-tf/testsuite/Test/Synthesizer/LLVM/Filter.hs	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/testsuite/Test/Synthesizer/LLVM/Filter.hs	2016-08-25 13:23:11.000000000 +0200
@@ -36,10 +36,10 @@
 import qualified Synthesizer.Causal.Filter.NonRecursive as FiltC
 import qualified Synthesizer.Causal.Displacement as DispC
 import qualified Synthesizer.Causal.Process as CausalS
-import qualified Synthesizer.Basic.Wave as WaveCore
 import qualified Synthesizer.State.Displacement as DispS
 import qualified Synthesizer.State.Oscillator as OsciS
 import qualified Synthesizer.State.Signal as SigS
+import qualified Synthesizer.Basic.Wave as WaveCore
 import qualified Synthesizer.Basic.Phase as Phase
 
 import qualified Data.StorableVector.Lazy as SVL
@@ -300,13 +300,25 @@
           (SigPS.unpack $ firstOrderCausalPacked reduct toneP)
 
 
+bandpassParameter ::
+   (A.Transcendental a, A.RationalConstant a) =>
+   a -> LLVM.CodeGenFunction r (SecondOrder.Parameter a)
+bandpassParameter f = do
+   param <- SecondOrder.bandpassParameter (A.fromInteger' 10) f
+   c0 <- A.mul (A.fromRational' 0.1) (SecondOrder.c0 param)
+   c1 <- A.mul (A.fromRational' 0.512) c0
+   c2 <- A.mul (A.fromRational' (-0.137)) c0
+   return (param {SecondOrder.c0 = c0,
+                  SecondOrder.c1 = c1,
+                  SecondOrder.c2 = c2} )
+
 secondOrderCausal ::
    Param.T p Float ->
    SigP.T p (Value Float) ->
    SigP.T p (Value Float)
 secondOrderCausal reduct xs =
    SecondOrder.causal
-    $< lfoSine (SecondOrder.bandpassParameter (LLVM.valueOf (10::Float))) reduct
+    $< lfoSine bandpassParameter reduct
     $* xs
 
 secondOrderCausalPacked ::
@@ -315,8 +327,9 @@
    SigP.T p VectorValue
 secondOrderCausalPacked reduct =
    applyPacked SecondOrder.causalPacked
-      (lfoSine (SecondOrder.bandpassParameter (LLVM.valueOf (10::Float))) reduct)
+      (lfoSine bandpassParameter reduct)
 
+-- check visual similarity between the two signals, also check difference signal
 secondOrderPacked :: IO (ChunkSize -> ((Int,Int), Int) -> SimFloat)
 secondOrderPacked =
    let freq  = rangeFromInt (0.001, 0.01) <<^ fst . fst
@@ -324,9 +337,24 @@
        reduct = (4*) ^<< rangeFromInt (1, 25) <<^ snd
        tone  = SigP.osciSimple  Wave.triangle phase freq
        toneP = SigPS.osciSimple Wave.triangle phase freq
+   in  checkSimilarity 1e-3 limitFloat
+          (secondOrderCausal reduct tone)
+          (SigPS.unpack $ secondOrderCausalPacked reduct toneP)
+
+{-
+secondOrderPacked :: IO (ChunkSize -> ((Int,Int), (Int,Int), Int) -> SimFloat)
+secondOrderPacked =
+   let freq  = rangeFromInt (0.001, 0.01) <<^ fst . fst3
+       phase = rangeFromInt (0, 0.99) <<^ snd . fst3
+       c1 = rangeFromInt (-1, 1) <<^ fst . fst3
+       c2 = rangeFromInt (-1, 1) <<^ snd . fst3
+       reduct = (4*) ^<< rangeFromInt (1, 25) <<^ thd3
+       tone  = SigP.osciSimple  Wave.triangle phase freq
+       toneP = SigPS.osciSimple Wave.triangle phase freq
    in  checkSimilarity 1e-2 limitFloat
           (secondOrderCausal reduct tone)
           (SigPS.unpack $ secondOrderCausalPacked reduct toneP)
+-}
 
 secondOrderCausalPacked2 ::
    Param.T p Float ->
diff -rN -u old-llvm-tf/ToDo new-llvm-tf/ToDo
--- old-llvm-tf/ToDo	2016-08-25 13:23:11.000000000 +0200
+++ new-llvm-tf/ToDo	2016-08-25 13:23:11.000000000 +0200
@@ -1,3 +1,85 @@
+Engine.getPointerToFunction:
+   ganz verbergen oder aber ein eigenes FunPtr herausgeben:
+      data EE.FunPtr f = FunPtr ExecutionEngine (Foreign.FunPtr f)
+
+teste auf redundante Imports mit GHC-7.8.4
+
+Simple.Signal, Parameterized.Signal exportieren immer noch compileChunky etc.
+
+CausalParam.reverbSimple -> Causal.reverb
+   dazu müssten wir von RingBuffer eine Variante ohne Parameter schaffen
+   oh da hängt so viel dran - es hängt wieder an alignedMalloc
+
+comb-Filter, welcher Original am Anfang nicht enthält.
+   Dazu müssen wir nur das Signal woanders in der Rückkopplungsschleife abgreifen.
+   Wahrscheinlich ist es das:
+      loopZero
+         (mix >>> amplify gain >>> delayZero (subtract 1 time) >>>
+            (Causal.delay1Zero &&& Cat.id))
+
+do not write Bitcode files by default
+
+src/Synthesizer/LLVM/Server/Packed/Instrument.hs
+   move ideas to ToDo or separate file
+
+Simple.Signal.alter
+   Wieso wird da der exitState weggeworfen?
+   Wird der überhaupt in Core gebraucht?
+
+Process.comb:
+   If we swap 'delay' and 'amplify',
+   then we would not amplify the initial zeros.
+
+Funktioniert optimize zuverlässiger, wenn man TargetTriple setzt?
+   nein
+   Mal an kleinen Beispielen untersuchen, woran es hakt.
+
+Fold:
+   Brauchen wir das überhaupt,
+   oder sollten wird einfach eine 'last' Funktion für Signale haben?
+   Kleines Problem:
+      'Fold' funktioniert immer, während 'last' an leerem Signal scheitert.
+
+Server-Main: Subcommands statt Zahlen und Neuübersetzung
+   dann könnte man auch Optionen abhängig von Kommando anbieten
+
+Iterator-Sachen könnten eigentlich alle auf einem List-Iterator basieren:
+   Synthesizer.LLVM.EventIterator
+   Synthesizer.LLVM.Storable.ChunkIterator
+   Synthesizer.LLVM.Storable.LazySizeIterator
+
+Speech:
+   sollte in öffentlicher Schnittstelle verbleiben,
+   kann aber Exportliste vertragen,
+   wie auch die Instrument-Module.
+   Vielleicht sollte das ganze Server-Zeug mal in ein eigenes Paket.
+
+SampledSound: Tomatensalat-Sachen in 'server'-Verzeichnis ausgliedern
+   aber dadurch wird man Abhängigkeit von pathtype in Library-Teil nicht los
+
+synthi-llvm-alsa:
+   enthält Debug-Aufbauten, die nichts mit ALSA zu tun haben
+
+Cabal.Flag: debug, optimize
+   besser: optparse-Optionen
+      so können Benutzer beim Start entscheiden,
+      ob sie generator.bc-Dateien haben wollen
+      und ob der Optimierer eingesetzt werden soll
+
+merge scalar and vector computing
+   Every process should contain a scalar and a vector loop body.
+   We need converters from the vector to the scalar loop state and vice versa.
+   There should be a generic constructor
+      that constructs the vector loop body from the scalar one.
+
+Test.stereoFromMonoParameterizedSignal: move to Signal
+Test.multiMix, multiMixSignal: move to Process and Signal, respectively
+
+Optionen --optimize und --dump-bitcode
+
+kann man Simple.Process.Core als gemeinsamen Teil
+   von Causal.Process und CausalParameterized.Process verwenden?
+
 Live-Sequencer/Sprachsynthese:
    Vergleiche synthetisierte Explosivlaute mit natürlichen
    bei nicht-gefundener Datei darf Synthi nicht abstürzen
@@ -7,6 +89,10 @@
    kurze Attack/Decay- und Release-Zeiten führen zu Abstürzen
 example:Test.allpassPhaser: crash
 
+osciPlain, loopConst -> eigenes Modul
+   auch für constant, exponential usw.
+   könnte manche Sachen in Test vereinfachen
+
 biete zwei Versionen für alle integrierenden Prozesse (osci, integrate, skip)
    Lag:
       Differenz wirkt erst auf nachfolgenden Wert
@@ -39,6 +125,18 @@
 Parameterized.SignalValue:
    Gegenstück zu CausalParameterized.ProcessValue
 
+reparameterize ::
+   Param q p -> Signal p a -> Signal q a
+reparameterize ::
+   Param q p -> Causal p a b -> Causal q a b
+
+   Does that simplify usage of functions
+   that manipulate parameters, like
+      replicateControlledParam
+      stereoFromMonoParameterized
+      trigger
+   ?
+
 reverb:
    reverb -> reverbSimple oder ganz entfernen
    reverbEfficient -> reverb
@@ -53,6 +151,8 @@
    Causal.stereoFromMonoParameterized
    Causal.replicateControlledParam
 
+wir sollten lieber CSize statt Word32 für Größenangaben verwenden
+
 Parameter:
    Es gibt noch ein paar Param.get und Param.value,
       die nicht so einfach durch Param.with zu ersetzen sind.
@@ -78,6 +178,12 @@
    dass man 'start' mehrmals pro 'create' aufrufen darf
    Würde das mit Lazy-StorableVector und StablePtr immer noch funktionieren?
 
+Storable:
+   sollten wir überhaupt Storable-Klasse für Austausch mit LLVM-Funktionen nehmen?
+   Storable-Bool ist möglicherweise nicht verträglich mit LLVM.load
+   Sollten wir Strukturen mit Paaren zusammensetzen
+      oder mit eigenem Pair-Datentyp?
+
 example:layzChord verursacht
    Stack dump:
    0. Running pass 'X86 DAG->DAG Instruction Selection' on function '@fillsignal'
@@ -92,11 +198,14 @@
    if I append one, then I get an error from SoX and the last release is missing
    How can I achieve, that all sounds are rendered completely?
    Test this with a stream of some mono sounds.
+
 in testsuite:
    use fractions with power of two denominator in order to avoid rounding errors
    this won't help for exponential curve and filters
+
 sometimes a sound is terminated without a release phase
    I suspect that our policy of how to interpret shortened vectors in CausalIO is problematic.
+
 tfp-laws e.g. Pos x, Pos y -> Pos (x:*:y) for simplification of type signatures
    if we cannot implement them in tfp, we should implement them in llvm-tf as Vector casts
    I assume that our "closed world instances" technique could help to apply such simplifications.
