diff --git a/Help/Graphs/adso.lhs b/Help/Graphs/adso.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/adso.lhs
@@ -0,0 +1,31 @@
+adso (rd)
+
+> let { rrand l r = getStdRandom (randomR (l, r))
+>     ; rrand_l j l r = replicateM j (rrand l r)
+>     ; threadPause :: Double -> IO ()
+>     ; threadPause t = when (t>0) (threadDelay (floor (t * 1e6)))
+>     ; n = 24
+>     ; adso = let { get b j = let k = mce [0 .. constant j - 1]
+>                              in bufRdN 1 kr b k NoLoop
+>                  ; m = sinOsc kr (get 3 n) 0
+>                  ; f = midiCPS (get 0 n) * (m * get 4 n + 1)
+>                  ; l = get 2 n
+>                  ; g = get 1 n }
+>              in out 0 (mix (pan2 (sinOsc ar f 0) l g))
+>     ; pattern fd t = do { z <- do { l <- rrand 22 48
+>                                   ; r <- rrand 54 122
+>                                   ; replicateM n (rrand l r) }
+>                         ; send fd (b_setn1 0 0 z)
+>                         ; let rn i l r = do { d <- rrand_l n l r
+>                                             ; send fd (b_setn1 i 0 d) }
+>                           in do { rn 1 0 0.1
+>                                 ; rn 2 (-1) 1
+>                                 ; rn 3 2 12
+>                                 ; rn 4 0.001 0.0075
+>                                 ; rn 5 1 24
+>                                 ; rn 6 0.05 2.4 }
+>                         ; threadPause t } }
+> in withSC3 (\fd -> do { mapM_ (\i -> async fd (b_alloc i n 1)) [0..6]
+>                       ; play fd adso
+>                       ; mapM_ (pattern fd) =<< rrand_l 32 0.025 0.75 
+>                       ; reset fd })
diff --git a/Help/Graphs/aleatoric-quartet.lhs b/Help/Graphs/aleatoric-quartet.lhs
--- a/Help/Graphs/aleatoric-quartet.lhs
+++ b/Help/Graphs/aleatoric-quartet.lhs
@@ -44,28 +44,3 @@
 ; var g = Mix.fill(4, mk_s)
 ; 5.do({ g = rapf.value(g) })
 ; Out.ar(0, LeakDC.ar(g, 0.995)) }.play
-
-(let* ((amp 0.4)
-       (density (MouseX kr 0.01 1 0 0.1))
-       (dmul (Mul (Recip density) (Mul 0.5 amp)))
-       (dadd (Add (Neg dmul) amp))
-       (rapf (lambda (i)
-	       (let ((r (Mce (rand 0 0.05) (rand 0 0.05))))
-		 (AllpassN i 0.05 r 1))))
-       (mk_f (lambda ()
-	       (let* ((i0 (IRand 0 2))
-		      (r0 (Select i0 (Mce 1 0.5 0.25)))
-		      (r1 (Rand -30 30))
-		      (n0 (LFNoise0 kr r0))
-		      (m (Lag (Round (MulAdd n0 7 (Add 66 r1)) 1) 0.2)))
-		 (MIDICPS m))))
-       (mk_s (lambda (_)
-	       (let* ((f (Recip (mk_f)))
-		      (r (Rand -1 1))
-		      (n0 (PinkNoise ar))
-		      (n1 (LFNoise1 kr 8))
-		      (x (Mul n0 (Max 0 (MulAdd n1 dmul dadd)))))
-		 (Pan2 (CombL x 0.02 f 3) r 1))))
-       (g (mix/fill 4 mk_s)))
-  (for-each (lambda (_) (set! g (rapf g))) (list 0 1 2 3))
-  (audition (Out 0 (LeakDC g 0.995))))
diff --git a/Help/Graphs/analog-bubbles.lhs b/Help/Graphs/analog-bubbles.lhs
--- a/Help/Graphs/analog-bubbles.lhs
+++ b/Help/Graphs/analog-bubbles.lhs
@@ -9,8 +9,3 @@
 ; var f = LFSaw.kr(0.4, 0, 24, o)
 ; var s = SinOsc.ar(f.midicps, 0, 0.04)
 ; Out.ar(0, CombN.ar(s, 0.2, 0.2, 4)) }.play
-
-(let* ((o (MulAdd (LFSaw kr (Mce 8 7.23) 0) 3 80))
-       (f (MulAdd (LFSaw kr 0.4 0) 24 o))
-       (s (Mul (SinOsc ar (MIDICPS f) 0) 0.04)))
-  (audition (Out 0 (CombN s 0.2 0.2 4))))
diff --git a/Help/Graphs/babbling-brook.lhs b/Help/Graphs/babbling-brook.lhs
--- a/Help/Graphs/babbling-brook.lhs
+++ b/Help/Graphs/babbling-brook.lhs
@@ -16,13 +16,4 @@
 ; var y = b.value(20, 800, 1000, 0.010) ! 2
 ; Out.ar(0, x + y) }.play
 
-(let* ((b (lambda (f m a g)
-	    (let* ((n1 (BrownNoise ar))
-		   (n2 (BrownNoise ar))
-		   (n3 (MulAdd (LPF n2 f) m a)))
-	      (Mul (RHPF (OnePole n1 0.99) n3 0.03) g))))
-       (x (clone 2 (b 14 400 500 0.006)))
-       (y (clone 2 (b 20 800 1000 0.010))))
-  (audition (Out 0 (Add x y))))
-
 http://lists.create.ucsb.edu/pipermail/sc-users/2007-April/033239.html
diff --git a/Help/Graphs/bottle.lhs b/Help/Graphs/bottle.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/bottle.lhs
@@ -0,0 +1,19 @@
+bottle (sc)
+
+> do { freq <- rand 220 880
+>    ; wn <- whiteNoise ar
+>    ; pn <- pinkNoise ar
+>    ; let { chain n f = foldl (>=>) return (replicate n f)
+>          ; perc = envPerc 0.1 0.6
+>          ; ex = envGen kr 1 1 0 1 DoNothing perc * wn * 0.02
+>          ; flute = ringz ex freq 0.3
+>          ; r = resonz pn (5 + (freq / 2)) 0.1
+>          ; breath = envGen kr 1 1 0 1 DoNothing perc * r
+>          ; rapf i = do { x <- linRand 0.001 0.1 (-1)
+>                        ; return (i + allpassN i 0.1 x 1.0 * 0.5) }
+>          ; cls i = let { en = replicate 3 (EnvNum (-4))
+>                        ; l = envLinen 0.01 3.0 1.0 1 en
+>                        ; z = (breath + i) * envGen kr 1 1 0 1 RemoveSynth l }
+>                    in mce2 z z }
+>      in do { f <- (chain 2 rapf) flute
+>            ; audition (out 0 (cls f)) } }
diff --git a/Help/Graphs/bowed-string.lhs b/Help/Graphs/bowed-string.lhs
--- a/Help/Graphs/bowed-string.lhs
+++ b/Help/Graphs/bowed-string.lhs
@@ -31,17 +31,3 @@
 ; var d = `[Array.series(12, f, f), Array.geom(12, 1, r1), r2]
 ; var k = Klank.ar(d, x)
 ; Out.ar(0, (k * 0.1).softclip) }.play
-
-(let* ((root 5)
-       (scale (map (lambda (n) (+ n root)) (list 0 2 4 5 7 9 11)))
-       (oct (list 24 36 48 60 72 84))
-       (f (midicps (+ (choose scale) (choose oct))))
-       (n0 (clone 2 (BrownNoise ar)))
-       (r0 (ExpRand 0.125 0.5))
-       (n1 (LFNoise1 kr r0))
-       (r1 (rand 0.7 0.9))
-       (r2 (list-tabulate 12 (lambda (_) (Rand 1.0 3.0))))
-       (x (Mul* n0 0.007 (Max 0 (MulAdd n1 0.6 0.4))))
-       (d (klank-data (iota 12 f f) (geom 12 1 r1) r2))
-       (k (Klank x 1 0 1 d)))
-  (audition (Out 0 (SoftClip (Mul k 0.1)))))
diff --git a/Help/Graphs/ccomb.lhs b/Help/Graphs/ccomb.lhs
--- a/Help/Graphs/ccomb.lhs
+++ b/Help/Graphs/ccomb.lhs
@@ -23,16 +23,3 @@
                 ; CombC.ar(x, flwr.reciprocal, f.reciprocal, m.range(1, 8)) } }
 ; var t = Dust.kr([0.75, 0.35])
 ; Out.ar(0, Mix.fill(12, spart.value(t)) * 0.1) }.play
-
-(let* ((rng (lambda (u l r) (LinLin u -1 1 l r)))
-       (lwr 48)
-       (flwr (midicps 48))
-       (spart (lambda (t)
-		(let* ((n (rng (LFNoise2 kr 0.1) lwr 72))
-		       (e (Decay2 t 0.01 (TRand 0.05 0.75 t)))
-		       (x (Mul (WhiteNoise ar) e))
-		       (m (LFNoise2 kr 0.1))
-		       (f (Lag (MIDICPS n) 0.25)))
-		  (CombC x (Recip flwr) (Recip f) (rng m 1.0 8.0)))))
-       (t (Dust ar (Mce 0.9 0.8))))
-  (audition (Out 0 (mix/fill 7 (lambda (_) (Mul (spart t) 0.1))))))
diff --git a/Help/Graphs/cricket.lhs b/Help/Graphs/cricket.lhs
--- a/Help/Graphs/cricket.lhs
+++ b/Help/Graphs/cricket.lhs
@@ -17,17 +17,3 @@
 ; var f = SinOsc.kr(r2, 0) * e * r3
 ; var r4 = Array.fill(2, { TRand.kr(2220, 2227, t) })
 ; Out.ar(0, SinOsc.ar(r4, 0) * f * 0.25) }.play
-
-(let* ((mRand (lambda (l r)
-		(Mce (Rand l r) (Rand l r))))
-       (mTRand (lambda (l r t)
-		 (Mce (TRand l r t) (TRand l r t))))
-       (r1 (mRand 10 13))
-       (r2 (mRand 10 13))
-       (r3 (mRand 4 7))
-       (t (Impulse kr 0.7 0))
-       (e (Decay2 (Impulse kr r1 0) 0.001 0.005))
-       (f (Mul* (SinOsc kr r2 0) e r3))
-       (r4 (mTRand 2220 2227 t)))
-  (audition (Out 0 (Mul* (SinOsc ar r4 0) f 0.25))))
-
diff --git a/Help/Graphs/cut-outs.lhs b/Help/Graphs/cut-outs.lhs
--- a/Help/Graphs/cut-outs.lhs
+++ b/Help/Graphs/cut-outs.lhs
@@ -22,16 +22,3 @@
 ; var b = TRand.kr(0, 1, Dust.kr(8))
 ; Out.kr(0, b)
 ; Out.ar(0, s.clip2(In.kr(0, 1)) * 0.25) }.play
-
-(let* ((t (Mul (Impulse ar 22 0) (Add (SinOsc kr 0.5 0) 1)))
-       (x (MouseX kr 0.005 0.12 1 0.1))
-       (y (MouseY kr 0.01 0.52 1 0.1))
-       (n (lambda (_)
-	    (let* ((n1 (LFNoise0 kr 2))
-		   (n2 (CoinGate (Add* 0.05 (Mul n1 0.4) y) (Mul t 0.5)))
-		   (n3 (TExpRand (Mce 500 900) 1600 t)))
-	      (Ringz n2 n3 x))))
-       (s (mix/fill 3 n))
-       (b (TRand 0 1 (Dust kr 8))))
-  (audition (Mrg (Out 0 b)
-		 (Out 0 (Mul (Clip2 s (In 1 kr 0)) 0.25)))))
diff --git a/Help/Graphs/cymbalism.lhs b/Help/Graphs/cymbalism.lhs
--- a/Help/Graphs/cymbalism.lhs
+++ b/Help/Graphs/cymbalism.lhs
@@ -21,6 +21,7 @@
           ; var rt = Array.fill(p, { 1 + Rand.new(0, 4) })
           ; `[f, nil, rt] }
 ; var z = Array.fill(2, y)
-; var t = Impulse.ar(Rand.new(0, 3) + 0.5)
-; var n = WhiteNoise.ar(0.03)
-; Out.ar(0, Klank.ar(z, Decay.ar(t, 0.004, n))) }.play
+; var t = Impulse.ar(Rand.new(0, 3) + 0.5, 0)
+; var n = WhiteNoise.ar() * 0.03
+; var s = Decay.ar(t, 0.004) * n
+; Out.ar(0, Klank.ar(z, s)) }.play
diff --git a/Help/Graphs/demanding-studies.lhs b/Help/Graphs/demanding-studies.lhs
--- a/Help/Graphs/demanding-studies.lhs
+++ b/Help/Graphs/demanding-studies.lhs
@@ -2,17 +2,17 @@
 
 > do { s1 <- drand dinf (mce [72, 75, 79, 82])
 >    ; s2 <- drand 1 (mce [82, 84, 86])
->    ; s2 <- dseq dinf (mce [72, 75, 79, s2])
+>    ; s3 <- dseq dinf (mce [72, 75, 79, s2])
 >    ; let { x = mouseX KR 5 13 Linear 0.2
 >          ; tr = impulse KR x 0
->          ; f = demand tr 0 (mce [midiCPS (s1 - 12), midiCPS s2])
+>          ; f = demand tr 0 (mce [midiCPS (s1 - 12), midiCPS s3])
 >          ; o1 = sinOsc AR (f + mce2 0 0.7) 0
 >          ; o2 = saw AR (f + mce2 0 0.7) * 0.3
 >          ; o3 = cubed (distort (log (distort (o1 + o2)))) }
 >      in audition (out 0 (o3 * 0.1)) }
 
 { var s1 = Drand.new([72, 75, 79, 82], inf)
-; var s2 = Drand.new([82, 84, 86])
+; var s2 = Drand.new([82, 84, 86], 1)
 ; var s3 = Dseq.new([72, 75, 79, s2], inf)
 ; var x = MouseX.kr(5, 13, 'linear', 0.2)
 ; var tr = Impulse.kr(x, 0)
diff --git a/Help/Graphs/dial-history.lhs b/Help/Graphs/dial-history.lhs
--- a/Help/Graphs/dial-history.lhs
+++ b/Help/Graphs/dial-history.lhs
@@ -13,7 +13,7 @@
 >       ; g1 <- grayNoise AR
 >       ; g2 <- grayNoise AR
 >       ; d <- lfdNoise3 KR 0.5
->       ; let { tr = trig (tDuty KR rate 0 DoNothing q) 0.09
+>       ; let { tr = trig (tDuty KR rate 0 DoNothing q 1) 0.09
 >             ; pat = latch tr tr
 >             ; x = mouseX KR 0 1 Linear 0.2
 >             ; h = hasher (pat * x)
@@ -22,9 +22,8 @@
 >             ; dial = select both (mce_r (transpose mfv))
 >             ; sig = sinOsc AR dial 0 * 0.05 * tr
 >             ; dsig = delayN sig 0.2 (range d 0 0.01)
->             ; hiss = g1 * 0.01 + hpf (g2 * 0.02) 3000
->             ; z = silent 1 }
->         in audition (mce_mrg (out 0 (mce2 z (dsig + hiss)))) }
+>             ; hiss = g1 * 0.01 + hpf (g2 * 0.02) 3000 }
+>         in audition (out 0 (dsig + hiss)) }
 
 { var mfv = [[697, 770, 852, 941], [1209, 1336, 1477, 1633]]
 ; var numbers = [[3, 1]] ++ {: [a, b], a <- (0..2), b <- (0..2) }.all
diff --git a/Help/Graphs/diffraction.lhs b/Help/Graphs/diffraction.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/diffraction.lhs
@@ -0,0 +1,20 @@
+diffraction (rd)
+
+> let { p = let { x = mouseX kr 0.001 0.02 Exponential 0.1
+>               ; y = mouseY kr 120 400 Exponential 0.1 }
+>           in do { f <- fmap (* mce2 32 64) (lfNoise0 kr 4)
+>                 ; w <- fmap (* x) (lfNoise0 kr 32)
+>                 ; z <- fmap (* 0.1) (lfNoise0 kr 2)
+>                 ; m <- lfNoise0 kr 6
+>                 ; let s = pulse ar f w
+>                   in return (resonz s (y + z) (m * 0.4 + 0.8) * 0.5) }
+>     ; q = do { n <- lfNoise0 kr 128
+>              ; s <- p
+>              ; return (combN s 0.2 (n * 0.1 + 0.1) 3) }
+>     ; r = let { x = mouseX kr 0.75 1.25 Exponential 0.1
+>               ; y = mouseY kr 0.25 1 Exponential 0.1
+>               ; f _ = do { fr <- fmap (* x) (rand 50 59)
+>                          ; am <- fmap (* y) (rand 0.04 0.16)
+>                          ; return (sinOsc ar fr 0 * am) } }
+>           in liftM2 mce2 (mixFillM 16 f) (mixFillM 12 f) }
+> in audition . (out 0) . sum =<< sequence [p, q, r]
diff --git a/Help/Graphs/discretion.lhs b/Help/Graphs/discretion.lhs
--- a/Help/Graphs/discretion.lhs
+++ b/Help/Graphs/discretion.lhs
@@ -10,16 +10,3 @@
 >                       ; a_ = mkls [(0, 0), (0.33, a), (1, 0)] t }
 >                   in return (saw AR f_ * a_) } }
 > in audition . out 0 . mix =<< clone 8 part
-
-(let* ((mkls (lambda (bp t)
-	       (EnvGen kr 1 1 0 1 removeSynth (env/bp bp t 1))))
-       (part (lambda (_)
-	       (let* ((f1 (clone 2 (Rand 50 55)))
-		      (f2 (clone 2 (Rand 50 65)))
-		      (f3 (clone 2 (Rand 50 55)))
-		      (a (clone 2 (Rand 0.01 0.035)))
-		      (t 21)
-		      (f_ (mkls (list 0.0 f1 0.33 f2 1.0 f3) t))
-		      (a_ (mkls (list 0 0 0.33 a 1 0) t)))
-		 (Mul (Saw ar f_) a_)))))
-  (audition (Out 0 (mix/fill 8 part))))
diff --git a/Help/Graphs/drummer.lhs b/Help/Graphs/drummer.lhs
--- a/Help/Graphs/drummer.lhs
+++ b/Help/Graphs/drummer.lhs
@@ -20,13 +20,3 @@
 ; var bass = SinOsc.ar(60, 0) * Decay2.ar(tr_4, 0.005, 0.5)
 ; var hihat = HPF.ar(n, 10000) * Decay2.ar(tr, 0.005, 0.5)
 ; Out.ar(0, Pan2.ar(snare + bass + hihat, 0, 0.4)) }.play
-
-(let* ((tempo 4)
-       (n (WhiteNoise ar))
-       (tr (Impulse ar tempo 0))
-       (tr_2 (PulseDivider tr 4 2))
-       (tr_4 (PulseDivider tr 4 0))
-       (snare (Mul n (Decay2 tr_2 0.005 0.5)))
-       (bass (Mul (SinOsc ar 60 0) (Decay2 tr_4 0.005 0.5)))
-       (hihat (Mul (HPF n 10000) (Decay2 tr 0.005 0.5))))
-  (audition (Out 0 (Pan2 (Add* snare bass hihat) 0 0.4))))
diff --git a/Help/Graphs/e-lamell.lhs b/Help/Graphs/e-lamell.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/e-lamell.lhs
@@ -0,0 +1,50 @@
+e-lamell (rd)
+
+> let { rrand l r = getStdRandom (randomR (l, r))
+>     ; i_rrand l r = return . floorE =<< rrand l r
+>     ; exp_rrand a b = do { n <- rrand 0 1
+>                          ; let r = b / a 
+>                            in return ((r ** n) * a) }
+>     ; choose l = return . (l !!) =<< rrand 0 (length l - 1)
+>     ; threadPause :: Double -> IO ()
+>     ; threadPause t = when (t>0) (threadDelay (floor (t * 1e6)))
+>     ; sendSynth fd n u = async fd (d_recv (synthdef n u))
+>     ; e_lamell = let { ctl s v = Control KR s v
+>                      ; f = ctl "f" 440
+>                      ; n = ctl "n" 12
+>                      ; d = ctl "d" 0.1
+>                      ; l = ctl "l" 0
+>                      ; a = ctl "a" 1 }
+>                  in do { t <- tChoose 1 (mce2 1 32)
+>                        ; let { h = line ar n t d DoNothing
+>                              ; s = blip ar f h
+>                              ; e_d = envPerc 0.005 d
+>                              ; e = envGen ar 1 a 0 1 RemoveSynth e_d }
+>                          in return (out 0 (pan2 s l e)) }
+>     ; r_note o p = do { oe <- choose o
+>                       ; pe <- choose p
+>                       ; return (oe * 12 + pe) }
+>     ; l_sel = r_note [2, 3] [0]
+>     ; h_sel = r_note [2, 3, 4] [0]
+>     ; mk_s_new f n d a l = s_new "blip" (-1) AddToTail 1
+>                                  [("f", f)
+>                                  ,("n", n)
+>                                  ,("d", d)
+>                                  ,("a", a)
+>                                  ,("l", l)]
+>     ; pattern fd = do { p <- do { f <- liftM midiCPS l_sel
+>                                 ; n <- rrand 2 36
+>                                 ; d <- exp_rrand 0.01 0.4
+>                                 ; a <- rrand 0 0.75
+>                                 ; l <- rrand (-1) 1
+>                                 ; return (mk_s_new f n d a l) }
+>                       ; q <- do { f <- liftM midiCPS h_sel
+>                                 ; n <- rrand 2 36
+>                                 ; d <- exp_rrand 0.01 0.4
+>                                 ; a <- choose [0, 0.25, 0.5, 1]
+>                                 ; l <- rrand (-1) 1
+>                                 ; return (mk_s_new f n d a l) }
+>                       ; send fd (Bundle (-1) [p, q]) 
+>                       ; threadPause 0.1 } }
+> in withSC3 (\fd -> do { sendSynth fd "blip" =<< e_lamell
+>                       ; replicateM_ 64 (pattern fd) })
diff --git a/Help/Graphs/eggcrate.lhs b/Help/Graphs/eggcrate.lhs
--- a/Help/Graphs/eggcrate.lhs
+++ b/Help/Graphs/eggcrate.lhs
@@ -3,9 +3,7 @@
 > let { cosu = cos . (* pi) 
 >     ; sinu = sin . (* pi)
 >     ; eggcrate u v = cosu u * sinu v
->     ; tChoose t a = do { n <- tiRand 0 (fromIntegral (length a)) t
->                        ; return (select n (mce a)) }
->     ; p = [64, 72, 96, 128, 256, 6400, 7200, 8400, 9600] }
+>     ; p = mce [64, 72, 96, 128, 256, 6400, 7200, 8400, 9600] }
 > in do { [x, y] <- replicateM 2 (brownNoise KR)
 >       ; t <- dust KR 2.4
 >       ; [f0, f1] <- replicateM 2 (tChoose t p)
diff --git a/Help/Graphs/f-lets.lhs b/Help/Graphs/f-lets.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/f-lets.lhs
@@ -0,0 +1,23 @@
+f-lets (rd)
+
+> let { f_let t g j n f = 
+>       let pd = pulseDivider t j 0
+>       in do { r0 <- tiRand (mce2 2 1) n pd
+>             ; r1 <- tRand 0.01 0.04 pd
+>             ; r2 <- tRand 0.05 0.10 pd
+>             ; return (formlet pd (f * r0) r1 r2 * g) }
+>     ; mk_n t = do { r0 <- tRand 0 1 t
+>                   ; r1 <- tRand 0 1 t
+>                   ; r2 <- tRand 0 1 t
+>                   ; r3 <- tRand 0 1 t
+>                   ; r4 <- coinGate 0.2 t
+>                   ; sequence
+>                     [ f_let t 0.15 2 9 (mce2 200 400)
+>                     , f_let t 0.25 2 9 (mce2 (200 + r0) (400 + r1))
+>                     , f_let t 0.05 4 5 (mce2 25 50)
+>                     , f_let t 0.15 4 5 (mce2 (25 + r2) (50 + r3))
+>                     , let lr = fmap (* (latch r4 t))
+>                       in lr (f_let t 0.5 1 16 (mce2 300 600)) ] }
+>     ; tr = impulse ar 24 0 }
+> in do { n <- lfNoise0 kr 2
+>       ; audition . out 0 . (* (n * 0.25 + 0.25)) . sum =<< mk_n tr }
diff --git a/Help/Graphs/feedr.lhs b/Help/Graphs/feedr.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/feedr.lhs
@@ -0,0 +1,20 @@
+feedr (rd)
+warning: input/output feedback loop
+
+> let { delayWr b i = recordBuf b 0 1 0 1 Loop 0 i
+>     ; tap nc b dt = playBuf nc b 1 0 (dt * (- sampleRate)) Loop
+>     ; dl = 6
+>     ; feedr n = do { t <- replicateM n (rand 0.0 (constant dl))
+>                    ; g <- replicateM n (rand 0.4 1.0)
+>                    ; f <- replicateM n (rand 0.9 0.95)
+>                    ; let { d = zipWith (\p q -> tap 2 10 p * q) t g
+>                          ; x = mouseX kr 0.02 1.0 Exponential 0.1
+>                          ; s = clip2 (leakDC (hpf (sum d) 20) 0.995) 1
+>                          ; i = soundIn (mce2 0 1)
+>                          ; r = i + sum (map (* x) (zipWith (*) d f)) }
+>                      in return (mrg [out 0 s, delayWr 10 r]) } }
+> in withSC3 (\fd -> do { nf <- fmap (* dl) (serverSampleRateActual fd)
+>                       ; send fd (b_alloc 10 (floor nf) 2)
+>                       ; audition =<< feedr 18 })
+
+> withSC3 (\fd -> send fd (b_zero 10))
diff --git a/Help/Graphs/fm-iter.lhs b/Help/Graphs/fm-iter.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/fm-iter.lhs
@@ -0,0 +1,14 @@
+fm-iter (rd)
+
+> let { t0 = impulse AR (recip 0.30) 0
+>     ; t1 = tDelay t0 0.15
+>     ; t = mce2 t0 t1 }
+> in do { k <- tRand 56 57 t
+>       ; i <- tRand 40 480 t
+>       ; j <- tRand (-1) 1 t
+>       ; let { c = midiCPS k
+>             ; m = midiCPS (k + 1 + j)
+>             ; s = envPerc 0.01 0.9
+>             ; e = envGen AR t 0.1 0 1 RemoveSynth s
+>             ; f = sinOsc AR c 0 * i + m }
+>         in audition (out 0 (sinOsc AR f 0 * e)) }
diff --git a/Help/Graphs/fm-kltr.lhs b/Help/Graphs/fm-kltr.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/fm-kltr.lhs
@@ -0,0 +1,46 @@
+fm-kltr (rd)
+
+> let { rrand l r = getStdRandom (randomR (l, r))
+>     ; threadPause :: Double -> IO ()
+>     ; threadPause t = when (t>0) (threadDelay (floor (t * 1e6)))
+>     ; gr =
+>           do { r1 <- rand 0.975 1.025
+>              ; r2 <- rand 0.5 1.5
+>              ; r3 <- rand 0.975 1.025
+>              ; r4 <- rand 0.75 1.25
+>              ; let { o = Control KR "out" 0
+>                    ; t = Control KR "trig" 0
+>                    ; a = Control KR "amp" 0.1
+>                    ; d = Control KR "dur" 0.1
+>                    ; f = Control KR "freq" 400.0
+>                    ; i = Control KR "index" 40.0
+>                    ; p = Control KR "pan" 0.0
+>                    ; f2 = Control KR "freq2" 600
+>                    ; ep = envPerc 0.01 d
+>                    ; e = envGen AR 1 a 0 1 RemoveSynth ep
+>                    ; so = sinOsc AR (xLine KR f (f * r1) d DoNothing) 0
+>                    ; xl = xLine KR f2 (f2 * r3) d DoNothing
+>                    ; m = so * line KR i (f * r2) d DoNothing + xl
+>                    ; l = line KR p (p * r4) d DoNothing }
+>                in return (out o (pan2 (sinOsc AR m 0) l e)) }
+>     ; fm fd f ff a d i =
+>         do { r1 <- rrand (-1) 1
+>            ; r2 <- rrand (-1) 1
+>            ; send fd (s_new "fm" (-1) AddToTail 1
+>                             [("freq", midiCPS f)
+>                             ,("freq2", midiCPS ff + r1)
+>                             ,("amp", a)
+>                             ,("dur", d)
+>                             ,("index", i)
+>                             ,("pan", r2)]) }
+>     ; nd fd =
+>         do { ff <- rrand 48 96
+>            ; a <- rrand 0.1 0.4
+>            ; d <- rrand 1.2 7.2
+>            ; i <- rrand 240 1480
+>            ; t <- rrand 0.15 1.25
+>            ; fm fd 53 ff a d i
+>            ; threadPause t } }
+> in withSC3 (\fd -> do { u <- gr
+>                       ; async fd (d_recv (synthdef "fm" u))
+>                       ; replicateM 32 (nd fd) })
diff --git a/Help/Graphs/forest-sounds.lhs b/Help/Graphs/forest-sounds.lhs
--- a/Help/Graphs/forest-sounds.lhs
+++ b/Help/Graphs/forest-sounds.lhs
@@ -12,13 +12,4 @@
                 ; BPF.ar(n1, o, 0.001) * 10 }
 ; Out.ar(0, Array.fill(2, insects)) }.play
 
-(let ((insects
-       (lambda (_)
-	 (let* ((n1 (BrownNoise ar))
-		(n2 (LFNoise2 kr 50))
-		(f (MulAdd n2 50 50))
-		(o (MulAdd (SinOsc kr f 0) 100 2000)))
-	   (Mul (BPF n1 o 0.001) 10)))))
-  (audition (Out 0 (mce/fill 2 insects))))
-
 sc-users, 2007-04-06
diff --git a/Help/Graphs/fwalk.lhs b/Help/Graphs/fwalk.lhs
--- a/Help/Graphs/fwalk.lhs
+++ b/Help/Graphs/fwalk.lhs
@@ -13,7 +13,7 @@
 >     ; fwalk r = do { t <- dust KR 3
 >                    ; r1 <- tiRand 0 6 t
 >                    ; r2 <- tRand (-0.0001) 0.0001 t
->                    ; let { f = bufRdL 1 KR (MCE [0, 1]) r1 NoLoop
+>                    ; let { f = bufRdL 1 KR (mce2 0 1) r1 NoLoop
 >                          ; f' = f + r2
 >                          ; o1 = blip AR (midiCPS (r + f)) 12
 >                          ; o2 = blip AR (midiCPS (r + f')) 12 }
diff --git a/Help/Graphs/h-chatter.lhs b/Help/Graphs/h-chatter.lhs
--- a/Help/Graphs/h-chatter.lhs
+++ b/Help/Graphs/h-chatter.lhs
@@ -39,25 +39,3 @@
            ; var o = Blip.ar(HenonN.ar(f, a, b, 0, 0).range(p, p * 2), h)
            ; Pan2.ar(o, l, g) * 0.35 }
 ; Out.ar(0, h0.value + h1.value) }.play
-
-(let* ((wrp (lambda (i l r)
-	      (let ((m (FDiv (Sub r l) 2)))
-		(MulAdd i m (Add l m)))))
-       (h0 (let* ((n (MulAdd (LFNoise0 kr 1) 5 5))
-		  (a (MulAdd (LFNoise2 kr n) 0.20 1.20))
-		  (b (MulAdd (LFNoise2 kr n) 0.15 0.15))
-		  (f 40)
-		  (h (HenonN ar (Mce f (Mul f 0.5)) a b 0 0)))
-	     (Mul (Saw ar (MulAdd h 3200 1600)) 0.35)))
-       (h1 (let* ((n0 (LFNoise0 ar 32))
-		  (n1 (LFNoise0 ar 2))
-		  (a (MouseX kr 1.2 1.4 0 0.1))
-		  (b (MouseY kr 0.2 0.3 0 0.1))
-		  (h (wrp n0 1 32))
-		  (p (wrp n1 2400 3200))
-		  (l (wrp n1 -0.75 0.75))
-		  (g (wrp n1 0.55 0.85))
-		  (f 40)
-		  (o (Blip ar (wrp (HenonN ar f a b 0 0) p (Mul p 2)) h)))
-	     (Mul (Pan2 o l g) 0.35))))
-  (audition (Out 0 (Add h0 h1))))
diff --git a/Help/Graphs/harmonic-swimming.lhs b/Help/Graphs/harmonic-swimming.lhs
--- a/Help/Graphs/harmonic-swimming.lhs
+++ b/Help/Graphs/harmonic-swimming.lhs
@@ -20,15 +20,3 @@
           ; var e = max(0, n * a + l)
           ; FSinOsc.ar(f * (h + 1), 0) * e }
 ; Out.ar(0, (0..p).collect(o).sum) }.play
-
-(let* ((a 0.02)
-       (f 50)
-       (p 20)
-       (z 0)
-       (l (Line kr 0 (- a) 60 0))
-       (o (lambda (h)
-	    (let* ((r (clone 2 (Rand 2 8)))
-		   (n (LFNoise1 kr r))
-		   (e (Max 0 (MulAdd n a l))))
-	      (Mul (FSinOsc ar (* f (+ h 1)) 0) e)))))
-  (audition (Out 0 (mix (make-mce (map o (iota p)))))))
diff --git a/Help/Graphs/hh-808.lhs b/Help/Graphs/hh-808.lhs
--- a/Help/Graphs/hh-808.lhs
+++ b/Help/Graphs/hh-808.lhs
@@ -1,7 +1,6 @@
 hh-808 (ryan at wabdo.com)
 
-> let { freeVerb i mx room damp = mkFilter "FreeVerb" [i, mx, room, damp] 1
->     ; time = 250
+> let { time = 250
 >     ; freqs = [205.35, 304.41, 369.64, 522.71, 540.54, 812.21]
 >     ; pulseEnv = let e = env [1.0, 0.6] [time] [EnvNum (-0.5)] 0 0
 >                  in envGen AR 1 1 0 (1/1000) DoNothing e
diff --git a/Help/Graphs/implosion.lhs b/Help/Graphs/implosion.lhs
--- a/Help/Graphs/implosion.lhs
+++ b/Help/Graphs/implosion.lhs
@@ -17,22 +17,3 @@
 >       ; l <- pmr_n KR n0 n1 0 0 d
 >       ; a <- pmr_n KR 0.1 0.6 0 0 d
 >       ; audition (out 0 (pan2 (saw AR f) l a)) }
-
-(let* ((mkls (lambda (bp t)
-	       (EnvGen kr 1 1 0 1 removeSynth (env/bp bp t 1))))
-       (mkrmp (lambda (l r t)
-		(mkls (list 0 l 1 r) t)))
-       (wrp (lambda (i l r)
-	      (let ((m (FDiv (Sub r l) 2)))
-		(MulAdd i m (Add l m)))))
-       (pmr/n (lambda (rt l0 l1 r0 r1 d)
-		(let ((le (mkrmp l0 r0 d))
-		      (re (mkrmp l1 r1 d)))
-		  (wrp (WhiteNoise rt) le re))))
-       (d (Rand 7.5 13.5))
-       (f0 (Rand 10990 16220))
-       (f1 (Rand  9440 19550))
-       (f (pmr/n ar 440 f0 f1 f1 d))
-       (l (pmr/n kr (rand -1 0) (rand 0 1) 0 0 d))
-       (a (pmr/n kr 0.1 0.6 0 0 d)))
-  (audition (Out 0 (Pan2 (Saw ar f) l a))))
diff --git a/Help/Graphs/k-ppr.lhs b/Help/Graphs/k-ppr.lhs
--- a/Help/Graphs/k-ppr.lhs
+++ b/Help/Graphs/k-ppr.lhs
@@ -30,21 +30,3 @@
 ; var s1 = stream.value(3140, 6240, 0.050, 0.005, 0.15)
 ; var s2 = stream.value(0400, 9000, 0.005, 0.005, 0.15)
 ; Out.ar(0, Array.fill(2, s1) + Array.fill(2, s2)) }.play
-
-(let* ((wrp (lambda (i l r)
-	      (LinLin i -1 1 l r)))
-       (x (MouseX kr 0.05 0.35 0 0.1))
-       (y (MouseY kr 0.15 0.75 0 0.1))
-       (ti (LFTri kr x 0))
-       (tf (wrp ti 100 200))
-       (t (Impulse ar tf 0))
-       (stream (lambda (lf rf ld rd g)
-		 (lambda (_)
-		   (let* ((r1 (Rand 9 18))
-			  (t* (PulseDivider t r1 0))
-			  (r2 (TRand lf (wrp ti lf rf) t*))
-			  (r3 (TRand ld rd t*)))
-		     (Mul (Ringz (Decay2 t* 0.01 0.5) r2 (Mul r3 y)) g)))))
-       (s1 (stream 3140 6240 0.050 0.005 0.15))
-       (s2 (stream 0400 9000 0.005 0.005 0.15)))
-  (audition (Out 0 (Add (mce/fill 2 s1) (mce/fill 2 s2)))))
diff --git a/Help/Graphs/klink.lhs b/Help/Graphs/klink.lhs
--- a/Help/Graphs/klink.lhs
+++ b/Help/Graphs/klink.lhs
@@ -23,15 +23,3 @@
 ; var n2 = TRand.ar(x, 3940, t)
 ; var n3 = TRand.ar(0.005, 0.275, t)
 ; Out.ar(0, Ringz.ar(i, n2, n3 * y)) }.play
-
-(let* ((n1 (LFNoise0 kr (Mce 0.5 1.5)))
-       (o (SinOsc kr n1 0))
-       (f (Mce 2 3))
-       (a (Mul (Abs (Slope o)) f))
-       (t (Impulse ar a 0))
-       (i (Decay2 t 0.01 0.1))
-       (x (MouseX kr 960 3620 1 0.1))
-       (y (MouseY kr 0.5 2.0 0 0.2))
-       (n2 (TRand x 3940 t))
-       (n3 (TRand 0.005 0.275 t)))
-  (audition (Out 0 (Ringz i n2 (Mul n3 y)))))
diff --git a/Help/Graphs/lf-pulses.lhs b/Help/Graphs/lf-pulses.lhs
--- a/Help/Graphs/lf-pulses.lhs
+++ b/Help/Graphs/lf-pulses.lhs
@@ -13,10 +13,3 @@
 ; var f = Formlet.ar(Blip.ar(10, 12), n0 * 43 + 700, 0.005, x)
 ; var o = SinOsc.ar(40, 0) * n1
 ; Out.ar(0, LeakDC.ar(f + o, 0.995).clip2(0.75)) }.play
-
-(let* ((n0 (LFNoise0 ar (Mce 20 40)))
-       (n1 (LFNoise0 ar (Mce 5 10)))
-       (x (MouseX kr 0.012 0.19 1 0.1))
-       (f (Formlet (Blip ar 10 12) (MulAdd n0 43 700) 0.005 x))
-       (o (Mul (SinOsc ar 40 0) n1)))
-  (audition (Out 0 (Clip2 (Add f o) 1))))
diff --git a/Help/Graphs/lfo-modulation.lhs b/Help/Graphs/lfo-modulation.lhs
--- a/Help/Graphs/lfo-modulation.lhs
+++ b/Help/Graphs/lfo-modulation.lhs
@@ -9,8 +9,3 @@
 ; var p = FSinOsc.kr([0.6, 0.7], 0, 3600, 4000)
 ; var s = RLPF.ar(LFPulse.ar(o, 0, 0.4, 0.05), p, 0.2)
 ; Out.ar(0, CombL.ar(s, 0.3, [0.2, 0.25], 2)) }.play
-
-(let* ((o (MulAdd (FSinOsc kr 0.05 0) 80 160))
-       (p (MulAdd (FSinOsc kr (Mce 0.6 0.7) 0) 3600 4000))
-       (s (RLPF (Mul (LFPulse ar o 0 0.4) 0.05) p 0.2)))
-  (audition (Out 0 (CombL s 0.3 (Mce 0.2 0.25) 2))))
diff --git a/Help/Graphs/lg-timed.lhs b/Help/Graphs/lg-timed.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/lg-timed.lhs
@@ -0,0 +1,36 @@
+lg-timed (rd)
+
+> let { timed r y p =
+>       do { d0 <- dser r p
+>          ; d1 <- dcons 0 d0
+>          ; d2 <- dser r y
+>          ; let t = tDuty AR d1 0 RemoveSynth d2 1
+>            in return (latch t t) }
+>     ; lg u = return (lag u 0.03)
+>     ; n = mce [52, 76, 66, 67, 68, 69]
+>     ; a = mce [0.35, 0.15, 0.04, 0.05, 0.16, 0.07]
+>     ; d = mce [0.1, 0.5, 0.09, 0.08, 0.07, 0.3]
+>     ; x = mouseX KR 0.5 1.25 Linear 0.2 }
+> in do { tn <- lg =<< timed dinf n (d * x)
+>       ; ta <- lg =<< timed dinf a (d * x)
+>       ; audition (out 0 (sinOsc AR (midiCPS tn) 0 * ta)) }
+
+{ var dcons = { arg x, xs
+              ; var i = Dseq.new([0, 1], 1)
+              ; var a = Dseq.new([x, xs], 1)
+              ; Dswitch.new(a, i) }
+; var timed = { arg r, y, p
+              ; var d0 = Dser.new(p, r)
+              ; var d1 = dcons.value(0, d0)
+              ; var d2 = Dser.new(y, r)
+              ; var t = TDuty.ar(d1, 0, d2, 2, 1)
+              ; Latch.ar(t, t) }
+; var lg = { arg u
+           ; Lag.ar(u, 0.03) }
+; var n = [52, 76, 66, 67, 68, 69]
+; var a = [0.35, 0.15, 0.04, 0.05, 0.16, 0.07]
+; var d = [0.1, 0.5, 0.09, 0.08, 0.07, 0.3]
+; var x = MouseX.kr(0.5, 1.25, 'linear', 0.2)
+; var tn = lg.value(timed.value(inf, n, d * x))
+; var ta = lg.value(timed.value(inf, a, d * x))
+; Out.ar(0, SinOsc.ar(tn.midicps, 0) * ta) }.play
diff --git a/Help/Graphs/lin-sosc.lhs b/Help/Graphs/lin-sosc.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/lin-sosc.lhs
@@ -0,0 +1,53 @@
+lin-sosc (rd)
+
+> let { n = 1024
+>     ; x = mouseX KR 0.001 1.0 Linear 0.1
+>     ; tblM b = playBuf 1 b (x * bufRateScale KR b) 0 0 Loop
+>     ; tblC b c = playBuf 1 b (in' 1 KR c * bufRateScale KR b) 0 0 Loop
+>     ; o = sinOsc AR (tblM 0) 0 * tblM 1 
+>     ; co = clip2 (pan2 o (tblC 1 0) 0.025) 0.25
+>     ; rrand (a, b) = getStdRandom (randomR (a,b))
+>     ; choose l = liftM (l !!) (rrand (0, length l - 1))
+>     ; pauseThread n = when (n > 1e-3) (threadDelay (floor (n * 1e6)))
+>     ; iota 0 _ _ = []
+>     ; iota n l s = l : iota (n - 1) (l + s) s
+>     ; geom 0 _ _ = []
+>     ; geom n i f = i : geom (n - 1) (i * f) f
+>     ; lineTo n l r = iota n l ((r - l) / n)
+>     ; xlineTo n l r = geom n l ((r / l) ** (1.0 / n))
+>     ; twoPi = pi * 2.0
+>     ; rng l r e = l + (e * (l - r))
+>     ; srng l r e = let m = (l - r ) / 2
+>                    in m + l + (e * m) 
+>     ; freq = [ lineTo n 440.0 444.0
+>              , lineTo n 40.0 16000.0
+>              , xlineTo n 40.0 16000.0
+>              , map (srng 20 21000 . sin) (lineTo n 0.0 twoPi)
+>              , map (srng 20 12000 . cos) (lineTo n 0.0 twoPi)
+>              , map (srng 20 22000 . tan) (lineTo n 0.0 twoPi)
+>              , map (srng 20 90 . tan) (lineTo n 0.0 twoPi) ]
+>     ; ampl = [ lineTo n 0.1 1.0
+>              , lineTo n 1.0 0.1
+>              , lineTo n 0.5 0.01
+>              , lineTo n 0.01 0.5
+>              , xlineTo n 1.0 0.1
+>              , xlineTo n 0.1 1.0
+>              , map sin (lineTo n 0.0 twoPi)
+>              , map cos (lineTo n 0.0 twoPi)
+>              , map (* 0.001) (map tan (lineTo n 0 twoPi)) ]
+>     ; sloc = [ 0.005, 0.0075, 0.01, 0.025, 0.05, 0.075
+>              , 0.1, 0.25, 0.5, 0.75
+>              , 0.8, 0.85, 1.0, 1.005 ]
+>     ; paus = [0.01, 0.05, 0.1, 0.15, 0.25, 0.5, 0.75]
+>     ; update fd = do { f <- choose freq
+>                      ; a <- choose ampl
+>                      ; s <- choose sloc
+>                      ; p <- choose paus
+>                      ; send fd (b_setn 0 [(0, f)])
+>                      ; send fd (b_setn 1 [(0, a)])
+>                      ; send fd (c_set [(0, s)])
+>                      ; pauseThread p } }
+> in do { withSC3 (\fd -> do { async fd (b_alloc 0 (floor n) 1)
+>                            ; async fd (b_alloc 1 (floor n) 1)
+>                            ; play fd (out 0 co) })
+>       ; forkIO (withSC3 (\fd -> replicateM_ 128 (update fd))) }
diff --git a/Help/Graphs/modal-space.lhs b/Help/Graphs/modal-space.lhs
--- a/Help/Graphs/modal-space.lhs
+++ b/Help/Graphs/modal-space.lhs
@@ -38,15 +38,15 @@
        (x (MouseX kr 0 15 0 0.1))
        (k (DegreeToKey 0 x 12))
        (c (lambda (n r)
-	    (let* ((o (Mul (SinOsc ar (MIDICPS (Add* r k n)) 0) 0.1))
-		   (t (LFPulse ar (MIDICPS (Mce 48 55)) 0.15 0.5))
+	    (let* ((o (Mul (SinOsc ar (MIDICPS (Add3 r k n)) 0) 0.1))
+		   (t (LFPulse ar (MIDICPS (mce2 48 55)) 0.15 0.5))
 		   (f (MIDICPS (MulAdd (SinOsc kr 0.1 0) 10 r)))
 		   (d (Mul (RLPF t f 0.1) 0.1))
 		   (m (Add o d)))
 	      (Add (CombN m 0.31 0.31 2) m)))))
   (with-sc3
    (lambda (fd)
-     (->< fd (/b_alloc 0 7 1))
-     (-> fd (/b_setn* 0 0 p))
-     (let ((n (Mul (LFNoise1 kr (Mce 3 3.05)) 0.04)))
+     (async fd (/b_alloc 0 7 1))
+     (send fd (/b_setn1 0 0 p))
+     (let ((n (Mul (LFNoise1 kr (mce2 3 3.05)) 0.04)))
        (play fd (Out 0 (Mul (Add (c n 48) (c n 72)) 0.25)))))))
diff --git a/Help/Graphs/moto-rev.lhs b/Help/Graphs/moto-rev.lhs
--- a/Help/Graphs/moto-rev.lhs
+++ b/Help/Graphs/moto-rev.lhs
@@ -7,7 +7,3 @@
 { var f = SinOsc.kr(0.2, 0) * 10 + 21
 ; var s = LFPulse.ar(f, [0, 0.1], 0.1)
 ; Out.ar(0, RLPF.ar(s, 100, 0.1).clip2(0.4)) }.play
-
-(let* ((f (MulAdd (SinOsc kr 0.2 0) 10 21))
-       (s (LFPulse ar f (Mce 0 0.1) 0.1)))
-  (audition (Out 0 (Clip2 (RLPF s 100 0.1) 0.4))))
diff --git a/Help/Graphs/mouse-clatter.lhs b/Help/Graphs/mouse-clatter.lhs
--- a/Help/Graphs/mouse-clatter.lhs
+++ b/Help/Graphs/mouse-clatter.lhs
@@ -18,7 +18,7 @@
 
 (let* ((x (MouseX kr 100 12000 0 0.1))
        (y (MouseY kr 0.01 0.15 0 0.1))
-       (n1 (LFNoise0 kr (Mce 3 3.25)))
+       (n1 (LFNoise0 kr (mce2 3 3.25)))
        (t (Impulse kr (MulAdd n1 16 18) 0))
        (n2 (TRand 0.005 y t))
        (n3 (WhiteNoise ar))
@@ -31,7 +31,5 @@
        (s (Add (Mul o 0.05) (IFFT* n7))))
   (with-sc3
    (lambda (fd)
-     (->< fd (/b_alloc 10 2048 1))
+     (async fd (/b_alloc 10 2048 1))
      (play fd (Out 0 s)))))
-
-
diff --git a/Help/Graphs/nharm.lhs b/Help/Graphs/nharm.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/nharm.lhs
@@ -0,0 +1,20 @@
+nharm (rd)
+
+> let { nharm n f = map ((* f) . fromIntegral) [1..n]
+>     ; rrand l r = getStdRandom (randomR (l, r))
+>     ; threadPause n = when (n>0) (threadDelay (floor (n * 1e6)))
+>     ; klg m u = do { n <- rrand 4 u
+>                    ; d <- rrand 9 12
+>                    ; f <- rrand m (m + 2)
+>                    ; l <- replicateM n (rrand 0.01 0.02)
+>                    ; p <- rrand (-1.0) 1.0
+>                    ; let { a = 0.5
+>                          ; e = envGen KR 1 0.9 0 1 RemoveSynth (envSine d a)
+>                          ; nh = nharm n (midiCPS f)
+>                          ; s = klangSpec nh l (replicate n 0.0) }
+>                      in return (pan2 (klang AR 1 0 s) p e) }
+>     ; ply :: Int -> (Double, Double) -> UGen -> Int -> IO ()
+>     ; ply n (l,r) m u = replicateM_ n (do { threadPause =<< rrand l r
+>                                           ; audition . out 0 =<< klg m u }) }
+> in do { forkIO (ply 32 (0.25, 0.75) 92 24)
+>       ; forkIO (ply 8 (1.25, 1.75) 12 54) }
diff --git a/Help/Graphs/one-line.lhs b/Help/Graphs/one-line.lhs
--- a/Help/Graphs/one-line.lhs
+++ b/Help/Graphs/one-line.lhs
@@ -9,8 +9,3 @@
 ; var lfs_t = lfs.trunc([400, 600]) * [1, -1]
 ; var f = OnePole.ar(Mix.new(lfs_t), 0.98)
 ; Out.ar(0, Pan2.ar(SinOsc.ar(f, 0), 0, 0.1)) }.play
-
-(let* ((lfs (MulAdd (LFSaw ar (Mce 1 0.99) (Mce 0 0.6)) 2000 2000))
-       (lfs_t (Mul (Trunc lfs (Mce 400 600)) (Mce 1 -1)))
-       (f (OnePole (mix lfs_t) 0.98)))
-  (audition (Out 0 (Pan2 (SinOsc ar f 0) 0 0.1))))
diff --git a/Help/Graphs/oscillator-cluster.lhs b/Help/Graphs/oscillator-cluster.lhs
--- a/Help/Graphs/oscillator-cluster.lhs
+++ b/Help/Graphs/oscillator-cluster.lhs
@@ -44,27 +44,3 @@
 ; var d = Rand.new(4, 7)
 ; var a = Rand.new(0.01, 0.05)
 ; Out.ar(0, fp.collect(prt.value(d, a)).sum) }.play
-
-(let* ((ln (lambda (a b d)
-	     (Line kr a b d removeSynth)))
-       (xln (lambda (a b d)
-	      (XLine kr a b d removeSynth)))
-       (rln (lambda (r a b d)
-	      (Line kr (Add a (Rand 0 r)) b d removeSynth)))
-       (rxln (lambda (r a b d)
-	       (XLine kr (Add a (Rand 0 r)) b d removeSynth)))
-       (prt (lambda (d a)
-	      (lambda (cf)
-		(let* ((r1 (Rand cf (Add cf 2)))
-		       (r2 (rln 1 5 0.01 d))
-		       (r3 (rln 10 20 0 d))
-		       (r4 (Rand 0.1 0.2))
-		       (f (Add (Mce cf r1) (Mul (SinOsc kr r2 0) r3)))
-		       (o (FSinOsc ar f 0))
-		       (e (Mul (Decay2 (Impulse ar 0 0) r4 d) a)))
-		  (Mul o e)))))
-       (np 12)
-       (fp (list-tabulate np (lambda (_) (Rand 220 660))))
-       (d (Rand 4 7))
-       (a (Rand 0.01 0.05)))
-  (audition (Out 0 (foldl Add 0 (map (prt d a) fp)))))
diff --git a/Help/Graphs/pattern-buffer.lhs b/Help/Graphs/pattern-buffer.lhs
--- a/Help/Graphs/pattern-buffer.lhs
+++ b/Help/Graphs/pattern-buffer.lhs
@@ -3,7 +3,7 @@
 > let { nf = 2 * 48000
 >     ; c = 24
 >     ; tseq l = let n = fromIntegral (length l) / 2.0
->                in select (lfSaw KR 0.5 0 * n + n) (MCE l)
+>                in select (lfSaw KR 0.5 0 * n + n) (mce l)
 >     ; rrand l r = getStdRandom (randomR (l, r))
 >     ; p = phasor AR 0 (bufRateScale KR 10) 0 (bufFrames KR 10) 0
 >     ; t = bufRdC 1 AR 10 p Loop 
diff --git a/Help/Graphs/police-state.lhs b/Help/Graphs/police-state.lhs
--- a/Help/Graphs/police-state.lhs
+++ b/Help/Graphs/police-state.lhs
@@ -30,19 +30,3 @@
 ; var n2 = LFNoise2.kr([0.3,0.3])
 ; var e = n1 * (n2 * 0.15 + 0.18)
 ; Out.ar(0, CombL.ar(Mix.fill(4, node) + e, 0.3, 0.3, 3)) }.play
-
-(let* ((node (lambda (_)
-	       (let* ((r0 (Rand 0.02 0.1))
-		      (r1 (Rand 0 two-pi))
-		      (r2 (Rand 0 600))
-		      (r3 (Rand 700 1300))
-		      (r4 (Rand -1 1))
-		      (r5 (Rand 80 120))
-		      (n0 (LFNoise2 ar r5))
-		      (f (MulAdd (SinOsc kr r0 r1) r2 r3)))
-		 (Pan2 (Mul (SinOsc ar f 0) n0) r4 0.1))))
-       (n0 (LFNoise2 kr (Mce 0.4 0.4)))
-       (n1 (LFNoise2 ar (MulAdd n0 90 620)))
-       (n2 (LFNoise2 kr (Mce 0.3 0.3)))
-       (e (Mul n1 (MulAdd n2 0.15 0.18))))
-  (audition (Out 0 (CombL (Add (mix/fill 4 node) e) 0.3 0.3 3))))
diff --git a/Help/Graphs/record-scratcher.lhs b/Help/Graphs/record-scratcher.lhs
--- a/Help/Graphs/record-scratcher.lhs
+++ b/Help/Graphs/record-scratcher.lhs
@@ -2,15 +2,13 @@
 
 > let { dup a = mce2 a a
 >     ; fn = "/home/rohan/audio/metal.wav"
->     ; b = 0
->     ; gate = 1
 >     ; d = env [0, 1, 0] [0.1, 0.1] [EnvSin] 1 0
->     ; e = envGen KR gate 1 0 1 RemoveSynth d
+>     ; e = envGen KR 1 1 0 1 RemoveSynth d
 >     ; x = mouseX KR (-10) 10 Linear 0.2
 >     ; dx = x - delayN x 0.1 0.1
 >     ; bdx = mouseButton KR 1 0 0.3 + dx
->     ; bdxr = bdx * bufRateScale KR (constant b)
->     ; scr = playBuf 1 (constant b) bdxr 0 0 Loop }
+>     ; bdxr = bdx * bufRateScale KR 0
+>     ; scr = playBuf 1 0 bdxr 0 0 Loop }
 > in withSC3 (\fd -> do { async fd (b_allocRead 0 fn 0 0)
 >                       ; play fd (out 0 (dup (scr * e))) })
 
diff --git a/Help/Graphs/rm-octaver.lhs b/Help/Graphs/rm-octaver.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/rm-octaver.lhs
@@ -0,0 +1,7 @@
+rm-octaver (andrea valle, miller puckette)
+
+> let { defaultPitch x = pitch x 440 60 4000 100 16 1 0.01 0.5 1
+>     ; i = soundIn 0
+>     ; p = defaultPitch i
+>     ; f = mceChannel 0 p }
+> in audition (out 0 (sinOsc ar (f * 0.5) 0 * i + i))
diff --git a/Help/Graphs/rzblp.lhs b/Help/Graphs/rzblp.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/rzblp.lhs
@@ -0,0 +1,22 @@
+rzblp (rd)
+
+> import System.IO.Unsafe
+
+> let { u = unsafePerformIO
+>     ; wrp i l r = let m = (r - l) / 2
+>                   in i * m + l + m
+>     ; lfn f l r = wrp (u (lfNoise0 kr f)) l r
+>     ; hpb q = mixFill 2 (\_ -> let { f = lfn q 1330 1395
+>                                    ; a = lfn q 0.001 0.007 }
+>                                in blip ar f 24 * a)
+>     ; mk_f d = let { q = lfn 5.2 5.2 5.21
+>                    ; a = u (d dinf (mce [1, 3, 2, 7, 8]))
+>                    ; tr = impulse kr q 0
+>                    ; freq = demand tr 0 a * 30 + 340 }
+>                in sum [ blip ar freq 3 * lfn q 0.001 0.01
+>                       , resonz (impulse ar q (mce2 0 0))
+>                                    (lfn 5 30 640)
+>                                    (lfn q 0.1 0.5) * lfn q 0.01 1.8
+>                       , hpb q * lfn q 1.2 1.8
+>                       , blip ar (lfn q 16 36) 3 * mce2 0.03 0.09 ] }
+> in audition (out 0 (mk_f drand + mk_f dxrand))
diff --git a/Help/Graphs/s-chirp.lhs b/Help/Graphs/s-chirp.lhs
--- a/Help/Graphs/s-chirp.lhs
+++ b/Help/Graphs/s-chirp.lhs
@@ -1,12 +1,10 @@
 s-chirp (rd)
 
-> let { tChoose t a = do { n <- tiRand 0 (fromIntegral (length a)) t
->                        ; return (select n (mce a)) }
->     ; x = mouseX KR 15 0 Linear 0.1
+> let { x = mouseX KR 15 0 Linear 0.1
 >     ; y = mouseY KR 15 27 Linear 0.1
 >     ; scl = [0, 2, 3.2, 5, 7, 9, 10] }
 > in do { t <- dust KR 9
->       ; b <- tChoose t [36, 48, 60, 72]
+>       ; b <- tChoose t (mce [36, 48, 60, 72])
 >       ; n <- liftM (* 0.04) (lfNoise1 KR (mce2 3 3.05))
 >       ; d <- tiRand x y t
 >       ; e <- liftM (decay2 t 0.005) (tRand 0.02 0.15 t)
@@ -20,24 +18,3 @@
 >       ; withSC3 (\fd -> do { async fd (b_alloc 0 7 1)
 >                            ; send fd (b_setn1 0 0 scl)
 >                            ; play fd (out 0 o) }) }
-
-(let* ((x (MouseX kr 15 0 0 0.1))
-       (y (MouseY kr 15 27 0 0.1))
-       (scl (list 0 2 3.2 5 7 9 10))
-       (t (Dust kr 9))
-       (b (TChoose t (Mce 36 48 60 72)))
-       (n (Mul (LFNoise1 kr (Mce 3 3.05)) 0.04))
-       (d (TIRand x y t))
-       (e (Decay2 t 0.005 (TRand 0.02 0.15 t)))
-       (k (DegreeToKey 0 d 12))
-       (f (MIDICPS (Add* b k n)))
-       (m (Mul* e (SinOsc ar f 0) 0.2))
-       (u (PulseDivider t 9 0))
-       (r0 (TRand 0.0075 0.125 u))
-       (r1 (TRand 0.05 0.15 u))
-       (o (MulAdd m 0.5 (AllpassC m 0.15 r0 r1))))
-  (with-sc3
-   (lambda (fd)
-     (->< fd (/b_alloc 0 7 1))
-     (-> fd (/b_setn* 0 0 scl))
-     (audition (Out 0 o)))))
diff --git a/Help/Graphs/sample-and-hold-liquidities.lhs b/Help/Graphs/sample-and-hold-liquidities.lhs
--- a/Help/Graphs/sample-and-hold-liquidities.lhs
+++ b/Help/Graphs/sample-and-hold-liquidities.lhs
@@ -18,12 +18,3 @@
 ; var p = Latch.kr(WhiteNoise.kr, c)
 ; var i = Pan2.ar(SinOsc.ar(f, 0, Decay2.kr(c, 0.1 * t, 0.9 * t)), p, 1)
 ; Out.ar(0, CombN.ar(i, 0.3, 0.3, 2)) }.play
-
-(let* ((r (MouseX kr 1 200 1 0.1))
-       (t (Recip r))
-       (c (Impulse kr r 0.4))
-       (cf (MouseY kr 100 8000 1 0.1))
-       (f (Latch (MulAdd (WhiteNoise kr) (Mul cf 0.5) cf) c))
-       (p (Latch (WhiteNoise kr) c))
-       (i (Pan2 (Mul (SinOsc ar f 0) (Decay2 c (Mul 0.1 t) (Mul 0.9 t))) p 1)))
-  (audition (Out 0 (CombN i 0.3 0.3 2))))
diff --git a/Help/Graphs/scratchy.lhs b/Help/Graphs/scratchy.lhs
--- a/Help/Graphs/scratchy.lhs
+++ b/Help/Graphs/scratchy.lhs
@@ -8,10 +8,6 @@
 ; var f = (n - 0.49).max(0) * 20
 ; Out.ar(0, RHPF.ar(f, 5000, 1)) }.play
 
-(let* ((n (Mul (clone 2 (BrownNoise ar)) 0.5))
-       (f (Mul (Max (Sub n 0.49) 0) 20)))
-  (audition (Out 0 (RHPF f 5000 1))))
-
 with non-monadic noise
 
 > let { bn = Sound.SC3.UGen.Base.brownNoise
diff --git a/Help/Graphs/shifting-pulses.lhs b/Help/Graphs/shifting-pulses.lhs
--- a/Help/Graphs/shifting-pulses.lhs
+++ b/Help/Graphs/shifting-pulses.lhs
@@ -18,14 +18,3 @@
 ; var f = n1.range(300, 1800)
 ; var rq = n2.range(0.01, 2)
 ; Out.ar(0, l * RLPF.ar(p, f, rq)) }.play
-
-(let* ((wrp (lambda (i l r) (LinLin i -1 1 l r)))
-       (n1 (clone 2 (BrownNoise kr)))
-       (n2 (clone 2 (BrownNoise kr)))
-       (n3 (clone 2 (BrownNoise kr)))
-       (t (Dust kr 0.75))
-       (l (Latch t t))
-       (p (Mul (Pulse ar (wrp n1 2 (Mce 11 15)) 0.01) 0.1))
-       (f (wrp n2 300 1800))
-       (rq (wrp n3 0.01 2)))
-  (audition (Out 0 (Mul l (RLPF p f rq)))))
diff --git a/Help/Graphs/sosc-lp.lhs b/Help/Graphs/sosc-lp.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/sosc-lp.lhs
@@ -0,0 +1,30 @@
+sosc-lp (rd)
+
+> let { dustR r lo hi = do { n1 <- dwhite 1 lo hi
+>                          ; n2 <- whiteNoise r
+>                          ; d <- dseq dinf n1
+>                          ; return (tDuty r d 0 DoNothing (abs n2) 1) }
+>     ; a = [60, 71, 89, 65, 36, 57, 92, 97, 92, 97]
+>     ; b = [71, 89, 60, 57, 65, 36, 95, 92, 93, 97]
+>     ; setup fd = do { async fd (b_alloc 10 9 1)
+>                     ; async fd (b_alloc 11 9 1)
+>                     ; send fd (b_setn1 10 0 a)
+>                     ; send fd (b_setn1 11 0 b) }
+>     ; d_env t = decay2 t 0.002 2.5
+>     ; idx t = stepper t 0 0 15 1 0
+>     ; f1 t = let { l = (bufRdL 1 kr 10 (idx t) Loop - 24)
+>                  ; r = (bufRdL 1 kr 11 (idx t) Loop - 24) }
+>            in midiCPS (mce2 l r)
+>     ; f2 t n = f1 t + n * 1.2
+>     ; o1 t = sinOsc ar (f1 t) 0 * d_env t
+>     ; o2 t n = sinOsc ar (f2 t n) 0 * d_env t
+>     ; sosc_lp t n = out 0 ((o1 t + o2 t n) * 0.2) }
+> in do { clk <- dustR kr 0.2 0.9
+>       ; n <- lfNoise0 kr (mce2 1 3)
+>       ; audition (sosc_lp clk n) }
+
+> let { a = [71, 60, 65, 89, 36, 57, 95, 97, 92, 97]
+>     ; b = [89, 71, 60, 65, 57, 36, 92, 95, 93, 97]
+>     ; resetup fd = do { send fd (b_setn1 10 0 a)
+>                       ; send fd (b_setn1 11 0 b) } }
+> in withSC3 resetup
diff --git a/Help/Graphs/sprinkler.lhs b/Help/Graphs/sprinkler.lhs
--- a/Help/Graphs/sprinkler.lhs
+++ b/Help/Graphs/sprinkler.lhs
@@ -9,10 +9,6 @@
 ; var t = LFPulse.kr(f, 0, 0.25, 0.1)
 ; Out.ar(0, BPZ2.ar(WhiteNoise.ar * t)) }.play
 
-(let* ((f (MulAdd (LFPulse kr 0.09 0 0.16) 10 7))
-       (t (Mul (LFPulse kr f 0 0.25) 0.1)))
-  (audition (Out 0 (BPZ2 (Mul (WhiteNoise ar) t)))))
-
 with non-monadic noise
 
 > let { n = Sound.SC3.UGen.Base.whiteNoise (uid 0) AR
diff --git a/Help/Graphs/sweepy-noise.lhs b/Help/Graphs/sweepy-noise.lhs
--- a/Help/Graphs/sweepy-noise.lhs
+++ b/Help/Graphs/sweepy-noise.lhs
@@ -7,8 +7,8 @@
 >          ; filtered = rlpf (n * 0.03) freq 0.1 }
 >      in audition (out 0 (combN filtered 0.3 0.3 2 + filtered)) }
 
-{ var lfoDepth = MouseY.kr(200, 8000, 'exponential')
-; var lfoRate = MouseX.kr(4, 60, 'exponential')
-; var freq = LFSaw.kr(lfoRate, 0, lfoDepth, lfoDepth * 1.2)
+{ var lfoDepth = MouseY.kr(200, 8000, 'exponential', 0.1)
+; var lfoRate = MouseX.kr(4, 60, 'exponential', 0.1)
+; var freq = LFSaw.kr(lfoRate, 0) * lfoDepth + (lfoDepth * 1.2)
 ; var filtered = RLPF.ar(WhiteNoise.ar([0.03,0.03]), freq, 0.1)
-; Out.ar(0, CombN.ar(filtered, 0.3, 0.3, 2, 1, filtered)) }.play
+; Out.ar(0, CombN.ar(filtered, 0.3, 0.3, 2) + filtered) }.play
diff --git a/Help/Graphs/tgb.lhs b/Help/Graphs/tgb.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/tgb.lhs
@@ -0,0 +1,30 @@
+tgb (rd)
+
+> let { mkls bp t = envGen KR 1 1 0 1 RemoveSynth (envCoord bp t 1 EnvLin)
+>     ; pm_t l r d t = let { le = mkls l d
+>                          ; re = mkls r d }
+>                      in tRand le re t
+>     ; wrp i l r = linLin i (-1) 1 l r
+>     ; pm_n rt l d = let { le = mkls l d
+>                         ; re = mkls l d }
+>                     in do { n <- whiteNoise rt
+>                           ; return (wrp n le re) }
+>     ; rrand l r = getStdRandom (randomR (l, r))
+>     ; gb b d = do { gps <- pm_n AR [(0, 400), (1, 900)] d
+>                   ; let { t = impulse AR gps 0
+>                         ; pm_f (l, r) = pm_t l r d t }
+>                     in do { du <- pm_f ([(0, 0.005), (0.5, 0.015), (1, 0.005)]
+>                                        ,[(0, 0.009), (0.5, 0.020), (1, 0.009)])
+>                           ; pn <- pm_f ([(0, -1.0), (0.5, -0.5), (1, 0.5)]
+>                                        ,[(0, -0.5), (0.5, 0.5), (1, 1.0)])
+>                           ; rt <- pm_f ([(0, 6), (0.5, 12), (1, 6)]
+>                                        ,[(0, 12), (0.5, 12), (1, 12)])
+>                           ; cs <- pm_f ([(0, 0), (1, 0.95)]
+>                                        ,[(0, 0), (1, 1)])
+>                           ; am <- pm_f ([(0, 0.25), (0.5, 0.55), (1, 0.15)]
+>                                        ,[(0, 0.5), (0.5, 0.75), (1, 0.25)])
+>                           ; let cs' = cs * (bufDur KR b)
+>                             in return (tGrains 2 t b rt cs' du pn am 2) } }
+>     ; fn = "/home/rohan/audio/text.snd" }
+> in withSC3 (\fd -> do { async fd (b_allocRead 10 fn 0 0)
+>                       ; play fd . (out 0) =<< gb 10 12 })
diff --git a/Help/Graphs/tgr-rpr.lhs b/Help/Graphs/tgr-rpr.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/tgr-rpr.lhs
@@ -0,0 +1,37 @@
+tgr-rpr (rd)
+
+> let { sf = "/home/rohan/audio/text.snd"
+>     ; preset = [ 0.01, 0.02
+>                , 0.95, 1.05
+>                , 0.02, 0.06
+>                , 0.2, 0.3
+>                , 0.7, 0.9
+>                , -1.0, 1.0 ]
+>     ; dustR r lo hi = do { n1 <- dwhite 1 lo hi
+>                          ; n2 <- whiteNoise r
+>                          ; d <- dseq dinf n1
+>                          ; return (tDuty r d 0 DoNothing (abs n2) 1) }
+>     ; rpr n t = tRand (in' 1 KR n) (in' 1 KR (n + 1)) t
+>     ; rrand l r = getStdRandom (randomR (l, r))
+>     ; rSet = [ (0.005, 0.025), (0.05, 0.25)
+>              , (0.75,  0.95) , (1.05, 1.25)
+>              , (0.001, 0.01) , (0.02, 0.04)
+>              , (0.1,   0.2)  , (0.2, 0.4)
+>              , (0.0,   0.45) , (0.55, 1.0)
+>              , (-1.0,  0.0)  , (0.0, 1.0) ]
+>     ; edit fd = do { s <- mapM (\(l,r) -> rrand l r) rSet
+>                    ; send fd (c_setn [(0, s)])
+>                    ; threadDelay 350000 } }
+> in do { clk <- dustR AR (in' 1 KR 0) (in' 1 KR 1)
+>       ; rat <- rpr 2 clk
+>       ; dur <- rpr 4 clk
+>       ; pos <- liftM (* (bufDur KR 10)) (rpr 8 clk)
+>       ; pan <- rpr 10 clk
+>       ; amp <- rpr 6 clk
+>       ; withSC3 (\fd -> do { async fd (b_allocRead 10 sf 0 0)
+>                            ; send fd (c_setn [(0, preset)])
+>                            ; let o = tGrains 2 clk 10 rat pos dur pan amp 2
+>                              in play fd (out 0 o)
+>                            ; threadDelay 3000000
+>                            ; replicateM_ 16 (edit fd)
+>                            ; reset fd }) }
diff --git a/Help/Graphs/theremin.lhs b/Help/Graphs/theremin.lhs
--- a/Help/Graphs/theremin.lhs
+++ b/Help/Graphs/theremin.lhs
@@ -1,11 +1,11 @@
 theremin (jmcc)
 
-> let { mod = 7
+> let { m = 7
 >     ; detune = 0
 >     ; x = mouseX KR 0 0.9 Linear 0.2
 >     ; y = mouseY KR 4000 200 Exponential 0.8
 >     ; f = y + detune
->     ; f' = f + f * sinOsc AR mod 0 * 0.02
+>     ; f' = f + f * sinOsc AR m 0 * 0.02
 >     ; a = sinOsc AR f' 0 * x }
 > in audition (out 0 (pan2 a 0 1))
 
@@ -17,12 +17,3 @@
 ; var f_ = f + (f * SinOsc.ar(mod, 0) * 0.02)
 ; var a = SinOsc.ar(f_, 0) * x
 ; Out.ar(0, (Pan2.ar(a, 0, 1))) }.play
-
-(let* ((mod 7)
-       (detune 0)
-       (x (MouseX kr 0 0.9 0 0.2))
-       (y (MouseY kr 4000 200 1 0.8))
-       (f (Add y detune))
-       (f* (Add f (Mul* f (SinOsc ar mod 0) 0.02)))
-       (a (Mul (SinOsc ar f* 0) x)))
-  (audition (Out 0 (Pan2 a 0 1))))
diff --git a/Help/Graphs/three-cpsw.lhs b/Help/Graphs/three-cpsw.lhs
--- a/Help/Graphs/three-cpsw.lhs
+++ b/Help/Graphs/three-cpsw.lhs
@@ -19,13 +19,3 @@
 ; var f = f1 * [9000, 12000] + 9500
 ; var o = Saw.ar(f) + Saw.ar(f * dh) + Saw.ar(f * dt)
 ; Out.ar(0, (o * a).clip2(0.75)) }.play
-
-(let* ((t (Dust kr (Mce 12 18)))
-       (f0 (TRand 1 64 t))
-       (f1 (LFNoise0 kr f0))
-       (a  (TRand 0.0 0.5 t))
-       (dt (TRand 0.975 1.025 t))
-       (dh (TRand 0.750 0.7505 t))
-       (f (MulAdd f1 (Mce 9000 12000) 9500))
-       (o (Add* (Saw ar f) (Saw ar (Mul f dh)) (Saw ar (Mul f dt)))))
-  (audition (Out 0 (Clip2 (Mul o a) 0.75))))
diff --git a/Help/Graphs/tipnso.lhs b/Help/Graphs/tipnso.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/tipnso.lhs
@@ -0,0 +1,12 @@
+tipnso (rd)
+
+> let { x = mouseX KR 1 32 Linear 0.1
+>     ; t = impulse AR x 0 }
+> in do { n1 <- tiRand 16 72 t
+>       ; n2 <- tiRand 0 1 t
+>       ; n3 <- pinkNoise AR
+>       ; let { e = decay2 t 0.01 (mce2 0.1 0.15)
+>             ; f = midiCPS (n1 + 36 + (12 * n2))
+>             ; s = sinOsc AR f 0 * e
+>             ; b = bpf (n3 * e) (36 + midiCPS n1) (175 / (midiCPS n1)) }
+>         in audition (out 0 ((s + b) * mce2 0.15 0.1)) }
diff --git a/Help/Graphs/tr-out.lhs b/Help/Graphs/tr-out.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/tr-out.lhs
@@ -0,0 +1,20 @@
+tr-out (rd)
+
+> let node n = do { t <- dust KR 1.6
+>                 ; r1 <- tRand 0 6 t
+>                 ; r2 <- tRand 0 6 t
+>                 ; r3 <- tRand 0 6 t
+>                 ; let { f = midiCPS (bufRdN 1 KR 0 r1 NoLoop)
+>                       ; p = bufRdN 1 KR 1 r2 NoLoop
+>                       ; a = bufRdN 1 KR 2 r3 NoLoop }
+>                   in return ( pan2 (sinOsc AR f 0) p a
+>                             , sendTrig t n (f / 660) ) }
+> in withSC3 (\fd -> do { async fd (b_alloc 0 6 1)
+>                       ; send fd (b_setn1 0 0 [60, 62, 64, 65, 67, 69])
+>                       ; async fd (b_alloc 1 6 1)
+>                       ; send fd (b_setn1 1 0 [-1, -0.5, 0, 0.25, 0.75, 1.0])
+>                       ; async fd (b_alloc 2 6 1)
+>                       ; send fd (b_setn1 2 0 [0.01, 0.05, 0.1, 0.15, 0.25, 0.35])
+>                       ; ns <- mapM node [1..4]
+>                       ; let o = sum (map fst ns)
+>                         in play fd (out 0 (mrg (o : map snd ns))) })
diff --git a/Help/Graphs/trkl.lhs b/Help/Graphs/trkl.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/trkl.lhs
@@ -0,0 +1,24 @@
+trkl (rd)
+
+> let trkl d ul fu dy la fy =
+>         let { tf = xLine kr 1 ul d RemoveSynth
+>             ; st = impulse ar (tf * 8) 0
+>             ; t = impulse ar tf 0 }
+>         in do { r0 <- rand (-1) 1
+>               ; r1 <- rand (-1) 1
+>               ; r2 <- tRand 0.05 1.0 t
+>               ; r3 <- tExpRand 0.0 0.25 st 
+>               ; fh <- tRand 1.75 2.25 t 
+>               ; let { a = dbAmp (line kr 12 la d RemoveSynth)
+>                     ; f = xLine kr fu 900 d RemoveSynth
+>                     ; p = line kr r0 r1 d RemoveSynth
+>                     ; o1 = mix (ringz (decay2 t 0.01 dy) (mce2 f (f * fh)) fy)
+>                     ; o2 = mix (saw ar (mce2 f (f * fh))) }
+>                in return (pan2 (o1 + o2 * decay2 t 0.1 r2 * r3) p a) }
+> in do { d <- rand 0.5 16
+>       ; ul <- rand 16 64
+>       ; fu <- rand 1200 9000
+>       ; dy <- rand 0.005 0.175
+>       ; la <- rand (-60) (-25)
+>       ; fy <- rand 0.015 0.125
+>       ; audition . (out 0) =<< trkl d ul fu dy la fy }
diff --git a/Help/Graphs/trmlo.lhs b/Help/Graphs/trmlo.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/trmlo.lhs
@@ -0,0 +1,41 @@
+trmlo (rd)
+
+> import System.IO.Unsafe
+
+> let { u_iRand p q = unsafePerformIO (iRand p q)
+>     ; u_rand p q = unsafePerformIO (rand p q)
+>     ; mWrp i l r = linLin i (-1) 1 (midiCPS l) (midiCPS r)
+>     ; mWrp1 i m = mWrp i m (m + 1)
+>     ; mWrpN i m n = mWrp i m (m + n)
+>     ; o1 = let { f = 5
+>                ; d = 3
+>                ; s = envSine d 0.1
+>                ; e = envGen kr 1 1 0 1 DoNothing s
+>                ; n = 65
+>                ; m = sinOsc kr f 0 }
+>            in pan2 (sinOsc ar (mWrp1 m n) 0) m e
+>     ; o2 = let { f = u_iRand 5 9
+>                ; d = u_iRand 5 9
+>                ; s = envSine d (u_rand 0.1 0.2)
+>                ; e = envGen kr 1 1 0 1 DoNothing s
+>                ; n = u_iRand 69 72
+>                ; m = sinOsc kr f 0 }
+>            in pan2 (sinOsc ar (mWrp1 m n) 0) m e
+>     ; o3 = let { f = u_iRand 5 9
+>                ; d = u_iRand 9 12
+>                ; s = envSine d (u_rand 0.1 0.2)
+>                ; e = envGen kr 1 1 0 1 DoNothing s
+>                ; n = u_iRand 69 72
+>                ; m = sinOsc kr f 0
+>                ; l = line kr 0 (u_iRand 1 5) d DoNothing }
+>            in pan2 (blip ar (mWrp1 m (n + l)) (linLin m (-1) 1 1 2)) m e
+>     ; o4 = let { f = u_iRand 5 18
+>                ; d = u_iRand 12 15
+>                ; s = envSine d (u_rand 0.1 0.2)
+>                ; e = envGen kr 1 5e-2 0 1 DoNothing s
+>                ; n = u_iRand 69 72
+>                ; m = sinOsc kr f 0
+>                ; l = line kr 0 (u_iRand 1 5) d RemoveSynth
+>                ; fr = mWrpN m (n + l) (u_iRand 1 5) }
+>            in pan2 (blip ar fr (linLin m (-1) 1 1 (u_iRand 2 24))) m e }
+> in audition (out 0 (o1 + o2 + o3 + o4))
diff --git a/Help/Graphs/tsort.lhs b/Help/Graphs/tsort.lhs
--- a/Help/Graphs/tsort.lhs
+++ b/Help/Graphs/tsort.lhs
@@ -16,11 +16,4 @@
 >     ; s = mixFill n f }
 > in audition (out 0 (s * e))
 
-(let* ((n 122)
-       (c (env/bp '(0 0 0.15 1 6 0) 1 1))
-       (e (EnvGen kr 1 1 0 1 removeSynth c))
-       (f (lambda (o) (Mul (SinOsc ar (Add 440 o) 0) 0.001)))
-       (s (mix/fill n f)))
-  (audition (Out 0 (Mul s e))))
-
 http://create.ucsb.edu/pipermail/sc-users/2003-March/002807.html
diff --git a/Help/Graphs/vlc-distrtn.lhs b/Help/Graphs/vlc-distrtn.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/vlc-distrtn.lhs
@@ -0,0 +1,130 @@
+vlc-distrtn (rd)
+caution - audio feedback graph
+
+> let { rrand l r = getStdRandom (randomR (l, r))
+>     ; choose l = return . (l !!) =<< rrand 0 (length l - 1)
+>     ; threadPause :: Double -> IO ()
+>     ; threadPause t = when (t>0) (threadDelay (floor (t * 1e6)))
+>     ; prep (ampl, phase) = [dbAmp ampl, phase]
+>     ; vlc = [ (0.00000, 1.85550)
+>             , (-9.92383, -0.65147)
+>             , (-8.74205, -0.74728)
+>             , (-3.70464, -1.39796)
+>             , (-9.43435, -1.14812)
+>             , (-25.84790, -1.03375)
+>             , (-16.99500, -2.41724)
+>             , (-29.17040, 2.67419)
+>             , (-26.82750, -1.61810)
+>             , (-18.59870, 1.34568)
+>             , (-19.72160, -2.85972)
+>             , (-29.43650, 0.54603)
+>             , (-23.63120, -1.47813)
+>             , (-28.20100, -1.98501)
+>             , (-41.20700, -1.11808)
+>             , (-33.14310, -2.19369)
+>             , (-31.54010, 1.43134)
+>             , (-47.62740, 1.28571)
+>             , (-28.79740, -1.03754)
+>             , (-34.97950, 0.37740)
+>             , (-39.05770, -0.57557)
+>             , (-38.84060, 2.34836)
+>             , (-40.18090, -0.96978)
+>             , (-47.32150, 2.14768)
+>             , (-45.49290, 2.52100)
+>             , (-40.57100, -1.39905)
+>             , (-47.19530, -2.23994)
+>             , (-50.80920, 2.97853)
+>             , (-48.13640, 0.46815)
+>             , (-58.56890, -1.01821)
+>             , (-57.81200, -3.08971)
+>             , (-47.96870, -0.48657)
+>             , (-43.96100, -0.10311)
+>             , (-50.49810, -2.80977)
+>             , (-50.61640, -0.17212)
+>             , (-60.64640, -1.02433)
+>             , (-58.03410, 1.06921)
+>             , (-55.46390, -2.04501)
+>             , (-54.31000, -1.53512)
+>             , (-52.78670, -1.49875)
+>             , (-57.99380, 0.17697)
+>             , (-56.76990, 2.28241)
+>             , (-54.17450, -1.85553)
+>             , (-62.58220, -2.40971)
+>             , (-59.86460, 1.04782)
+>             , (-61.58570, 1.56183)
+>             , (-52.62080, 1.68360)
+>             , (-49.82940, -1.11019)
+>             , (-56.18160, -0.78538)
+>             , (-57.73320, -2.23918)
+>             , (-49.87560, 3.09604)
+>             , (-51.00100, -0.53762)
+>             , (-59.71530, 0.99017)
+>             , (-65.73280, 2.43855)
+>             , (-73.01270, -0.90664)
+>             , (-61.81450, -0.53346)
+>             , (-65.58980, 1.51174)
+>             , (-75.94320, -3.06072)
+>             , (-65.22210, -1.49937)
+>             , (-70.79970, -2.96199)
+>             , (-64.72450, 1.78172)
+>             , (-73.24130, 0.26939)
+>             , (-66.17110, -0.23305)
+>             , (-61.32910, -3.12592)
+>             , (-66.98180, 0.64700)
+>             , (-65.23060, -2.94395)
+>             , (-70.13430, 1.29805)
+>             , (-68.43470, -1.35906)
+>             , (-71.33000, -2.71582)
+>             , (-86.90080, 2.11646)
+>             , (-74.97450, 2.76118)
+>             , (-68.02520, 0.94979)
+>             , (-67.32960, 3.05994)
+>             , (-67.32140, -2.79905)
+>             , (-68.22010, -2.33831) ]
+>     ; partial i freq detune fall n =
+>         do { n0 <- lfNoise1 kr 1
+>            ; n1 <- rand 0.75 1.25
+>            ; let { m = n * 2
+>                  ; ampl = bufRdN 1 kr 0 m NoLoop
+>                  ; f = freq * (n + 1) * (n0 * detune + 1) }
+>              in return (ringz i f (fall * n1) * ampl) }
+>     ; plyr n =
+>         let { ctl j k = Control KR j k
+>             ; buf = ctl "buf" 0
+>             ; iamp = ctl "iamp" 0.1
+>             ; ampl = ctl "ampl" 0.1
+>             ; freq = ctl "freq" 129.897
+>             ; fall = ctl "fall" 0.5
+>             ; loc = ctl "loc" 0.0
+>             ; detune = ctl "detune" 0.001
+>             ; i = soundIn 0 * iamp }
+>         in do { s <- mapM (partial i freq detune fall) [0 .. n-1]
+>               ; return (out 0 (clip2 (pan2 (sum s) loc ampl) 0.1)) }
+>     ; degree_to_key degree scale steps =
+>         let scale_n = length scale
+>         in (steps * (degree `div` scale_n)) + (scale !! (degree `mod` scale_n))
+>     ; getCps b =
+>         do { b_ <- choose b
+>            ; d <- choose [0 .. 8]
+>            ; let k = degree_to_key d [0, 2, 3, 5, 7, 8, 10] 12
+>              in return (midiCPS (b_ + realToFrac k)) }
+>     ; pattern fd =
+>         do { f <- getCps [24, 36, 48, 55, 60]
+>            ; ia <- rrand 0.05 0.75
+>            ; l <- rrand (-1) 1
+>            ; a <- rrand 0.05 0.1
+>            ; d <- rrand 0.001 0.005
+>            ; fl <- rrand 1 7
+>            ; send fd (n_set 1002 [("freq", f)
+>                                  ,("iamp", ia)
+>                                  ,("buf", 0)
+>                                  ,("loc", l)
+>                                  ,("ampl", a)
+>                                  ,("detune", d)
+>                                  ,("fall", fl)])
+>            ; threadPause =<< choose [0.25, 0.5, 0.75, 1.5] } }
+> in withSC3 (\fd -> do { async fd (b_alloc 0 (length vlc * 2) 1)
+>                       ; send fd (b_setn1 0 0 (concatMap prep vlc))
+>                       ; async fd . d_recv . synthdef "plyr48" =<< plyr 48
+>                       ; send fd (s_new "plyr48" 1002 AddToTail 1 [])
+>                       ; replicateM 32 (pattern fd) })
diff --git a/Help/Graphs/voscil.lhs b/Help/Graphs/voscil.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/voscil.lhs
@@ -0,0 +1,28 @@
+voscil (rd)
+
+> import System.IO.Unsafe
+
+> let { rrand l r = getStdRandom (randomR (l, r))
+>     ; lfn r = unsafePerformIO (lfNoise0 kr r)
+>     ; b = 32
+>     ; hb = (constant b - 1) / 2
+>     ; bn = 8192 * 4
+>     ; rt = 6
+>     ; f = 600
+>     ; s = let { v = vOsc ar (lfn rt * hb + hb) (f * 2) 0
+>               ; o = let { bf = lfn rt * 40 + 600
+>                         ; nh = lfn rt * 16 + 24 }
+>                     in blip ar bf nh * (lfn rt * 0.1 + 0.1)
+>               ; p = pan2 (v + o) (lfn rt) (lfn rt * 0.5 + 0.5)
+>               ; w = vOsc ar (lfSaw kr (1 / rt) 0 * hb + hb) f 0
+>               ; q = pan2 w (lfn rt) (lfn rt * 0.5 + 0.5) }
+>           in p + q
+>     ; run fd = let r_set i = 
+>                        do { m <- rrand 2 512
+>                           ; j <- replicateM m (rrand 0 bn)
+>                           ; k <- replicateM m (rrand (-1) 1)
+>                           ; async fd (b_alloc i bn 1)
+>                           ; send fd (b_set i (zip j k)) }
+>                in do { mapM_ r_set [0 .. (b - 1)]
+>                      ; play fd (out 0 s) } }
+> in withSC3 run
diff --git a/Help/Graphs/what-was-i-thinking.lhs b/Help/Graphs/what-was-i-thinking.lhs
--- a/Help/Graphs/what-was-i-thinking.lhs
+++ b/Help/Graphs/what-was-i-thinking.lhs
@@ -29,18 +29,3 @@
 ; var y = z * 0.6
 ; Out.ar(0, z + [ c.value(y) + c.value(y)
                 , c.value(y) + c.value(y) ]) }.play
-
-(let* ((n0 (MulAdd (LFNoise1 kr 0.2) 2000 2400))
-       (n1 (MulAdd (LFNoise1 kr 0.157) 0.4 0.5))
-       (i (Mul* (LFPulse ar 0.1 0 0.05) (Impulse ar 8 0) 500))
-       (d (Decay i 2))
-       (f (Max (Add (SinOsc kr 4 0) 80) d))
-       (p (Mul (Pulse ar f n1) 0.04))
-       (z (RLPF p n0 0.2))
-       (c (lambda (x) 
-	    (let* ((r (Rand 0 0.3))
-		   (n (MulAdd (LFNoise1 kr r) 0.025 0.035)))
-	      (CombL x 0.06 n 1))))
-       (y (Mul z 0.6)))
-  (audition (Out 0 (Add z (Mce (Add (c y) (c y))
-			       (Add (c y) (c y)))))))
diff --git a/Help/Graphs/wial.lhs b/Help/Graphs/wial.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/wial.lhs
@@ -0,0 +1,19 @@
+wial (rd)
+
+> let { pls c d f = let { t = pulseDivider c d 0
+>                       ; e = decay2 t 0.05 0.75
+>                       ; o = sinOsc AR (toggleFF t * f + f * 2) 0 }
+>                    in do { n0 <- tiRand 0 1 t
+>                          ; return (o * e * n0 * 0.5) }
+>     ; smpl f = [ (4, 6, f      ,  0.75)
+>                , (2, 6, f *   2,  0.75)
+>                , (1, 2, f *  16,  0.025)
+>                , (1, 5, f *  64,  0.005)
+>                , (1, 4, f * 128,  0.035)
+>                , (1, 3, f * 256,  0.15)
+>                , (2, 3, f * 512,  0.35) ]
+>     ; plss c (d0, d1, f, a) = liftM (* a) (pls c (mce2 d0 d1) f)
+>     ; clk = impulse AR 16 0 }
+> in do { n0 <- dust KR 2
+>       ; f <- twChoose n0 (mce2 (20 * 0.66) 20) (mce2 0.25 0.75) 0
+>       ; audition . out 0 . sum =<< mapM (plss clk) (smpl f) }
diff --git a/Help/Graphs/wind-metals.lhs b/Help/Graphs/wind-metals.lhs
--- a/Help/Graphs/wind-metals.lhs
+++ b/Help/Graphs/wind-metals.lhs
@@ -24,16 +24,3 @@
 ; var dt = Array.fill(n, { Rand.new(0.1, 2.0) })
 ; var s = Klank.ar(`[f, nil, dt], exc)
 ; Out.ar(0, (s * 0.1).softclip) }.play
-
-(let* ((n 6)
-       (base (ExpRand 60 4000))
-       (range (Rand 500 8000))
-       (n0 (clone 2 (BrownNoise ar)))
-       (r0 (ExpRand 0.125 0.5))
-       (n1 (LFNoise1 kr r0))
-       (f (list-tabulate n (lambda (_) (Rand base (Add base range)))))
-       (dt (list-tabulate n (lambda (_) (Rand 0.1 2))))
-       (exc (Mul* n0 0.007 (Max 0 (MulAdd n1 0.75 0.25))))
-       (k (klank-data f (make-list n 1) dt))
-       (s (Klank exc 1 0 1 k)))
-  (audition (Out 0 (SoftClip (Mul s 0.1)))))
diff --git a/Help/Graphs/xy-interference.lhs b/Help/Graphs/xy-interference.lhs
--- a/Help/Graphs/xy-interference.lhs
+++ b/Help/Graphs/xy-interference.lhs
@@ -15,12 +15,3 @@
            ; var b = SinOsc.ar(y, 0)
            ; a * b }
 ; Out.ar(0, Mix.fill(3, nd)) }.play
-
-(let* ((x (MouseX kr 20 22000 1 (Mce 0.005 0.025)))
-       (y (MouseY kr 20 22000 1 (Mce 0.005 0.075)))
-       (nd (lambda (_)
-	     (let* ((n (LFNoise0 kr (Mce 5 9)))
-		    (a (SinOsc ar (Add x n) 0))
-		    (b (SinOsc ar y 0)))
-	       (Mul a b)))))
-  (audition (Out 0 (mix/fill 3 nd))))
diff --git a/Help/Tutorial/Tutorial.lhs b/Help/Tutorial/Tutorial.lhs
--- a/Help/Tutorial/Tutorial.lhs
+++ b/Help/Tutorial/Tutorial.lhs
@@ -16,7 +16,7 @@
   $ darcs get http://slavepianos.org/rd/sw/hsc3
 
 To build use the standard Cabal process in each repository in
-sequence.
+sequence.  To install to the user package database type:
 
   $ runhaskell Setup.lhs configure --prefix ~
   $ runhaskell Setup.lhs build
@@ -28,7 +28,7 @@
 
   (push "~/sw/hsc3/emacs" load-path)
   (setq hsc3-interpreter "ghci")
-  (setq hsc3-help-directory "~/sw/hsc3/Help/")
+  (setq hsc3-help-directory "~/sw/hsc3/ Help/")
   (require 'hsc3)
 
 The hsc3 emacs mode associates itself with files having the extension
@@ -184,10 +184,10 @@
 * Identifier lookup & hasktags
 
 The emacs command M-. (find-tag) looks up an identifier in
-a 'tags' table.  The hasktags utility can generate tags files 
+a 'tags' table.  The hasktags utility can generate tags files
 from haskell source files that are usable with emacs.
 
-To generate the a tags file for hsc3, visit the hsc3 directory 
+To generate a tags file for hsc3, visit the hsc3 directory
 and type:
 
   $ find Sound -name '*.*hs' | xargs hasktags -e
@@ -197,9 +197,17 @@
 
   (setq tags-table-list '("~/sw/hsc3"))
 
+* External Unit Generators
+
+hsc3 includes bindings and help files for some unit generators
+not in the standard supercollider distribution.  In order to
+use these unit generators they must be installed, see:
+
+  http://sf.net/projects/sc3-plugins/
+
 * Example Unit Generator Graphs
 
-The Help/Graphs directory contains example unit generator graphs.  The
+The  Help/ directory contains example unit generator graphs.  The
 graphs are self contained, selecting the graph and typing C-cC-e will
 audition it.  In many cases both supercollider language and haskell
 versions are given, switch the emacs buffer to sclang-mode to run the
diff --git a/Help/UGen/Buffer/bufDur.help.lhs b/Help/UGen/Buffer/bufDur.help.lhs
--- a/Help/UGen/Buffer/bufDur.help.lhs
+++ b/Help/UGen/Buffer/bufDur.help.lhs
@@ -1,6 +1,6 @@
 bufDur rate bufnum
 
-Current duration of buffer.
+Current duration of buffer (in seconds).
 
 > withSC3 (\fd -> async fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0))
 
diff --git a/Help/UGen/Control/mrg2.help.lhs b/Help/UGen/Control/mrg2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/Control/mrg2.help.lhs
@@ -0,0 +1,26 @@
+mrg2 left right
+
+mrg2 defines a node indicating a multiple root graph.
+
+> let { l = out 0 (sinOsc AR 300 0 * 0.1)
+>     ; r = out 1 (sinOsc AR 900 0 * 0.1) }
+> in audition (mrg2 l r)
+
+there is a leftmost rule, so that mrg nodes need not
+be terminal.
+
+> let { l = sinOsc AR 300 0 * 0.1
+>     ; r = out 1 (sinOsc AR 900 0 * 0.1) }
+> in audition (out 0 (mrg2 l r))
+
+the leftmost node may be an mce node
+
+> let { l = sinOsc AR (mce2 300 400) 0 * 0.1
+>     ; r = out 1 (sinOsc AR 900 0 * 0.1) }
+> in audition (out 0 (mrg2 l r))
+
+the implementation is not thorough
+
+> let { l = sinOsc AR (mce2 300 400) 0 * 0.1
+>     ; r = out 1 (sinOsc AR 900 0 * 0.1) }
+> in audition (out 0 (mrg2 l r + mrg2 l r))
diff --git a/Help/UGen/Demand/dswitch.help.lhs b/Help/UGen/Demand/dswitch.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/Demand/dswitch.help.lhs
@@ -0,0 +1,32 @@
+dswitch index array
+
+Demand rate generator for embedding different inputs
+
+array - array of values or other ugens
+index - which of the inputs to return
+
+In difference to dswitch1, dswitch embeds all items of 
+an input demand ugen first before looking up the next index.
+
+> do { a0 <- dwhite 2 3 4
+>    ; a1 <- dwhite 2 0 1
+>    ; a2 <- dseq 2 (mce [1, 1, 1, 0])
+>    ; i <- dseq 2 (mce [0, 1, 2, 1, 0])
+>    ; d <- dswitch i (mce [a0, a1, a2])
+>    ; let { t = impulse KR 4 0
+>          ; f = demand t 0 d * 300 + 400
+>          ; o = sinOsc AR f 0 * 0.1 }
+>      in audition (out 0 o) }
+
+compare with dswitch1
+
+> do { a0 <- dwhite 2 3 4
+>    ; a1 <- dwhite 2 0 1
+>    ; a2 <- dseq 2 (mce [1, 1, 1, 0])
+>    ; i <- dseq 2 (mce [0, 1, 2, 1, 0])
+>    ; d <- dswitch1 i (mce [a0, a1, a2])
+>    ; let { t = impulse KR 4 0
+>          ; f = demand t 0 d * 300 + 400
+>          ; o = sinOsc AR f 0 * 0.1 }
+>      in audition (out 0 o) }
+
diff --git a/Help/UGen/Demand/tDuty.help.lhs b/Help/UGen/Demand/tDuty.help.lhs
--- a/Help/UGen/Demand/tDuty.help.lhs
+++ b/Help/UGen/Demand/tDuty.help.lhs
@@ -1,4 +1,4 @@
-tDuty rate duration reset doneAction level
+tDuty rate duration reset doneAction level gap
 
 Demand results as trigger from demand rate ugens.
 
@@ -23,26 +23,29 @@
 
 level      - demand ugen providing the output values.
 
+gap - if true the dirst duration precedes the first level,
+      else it follows it.
+
 Play a little rhythm
 
 > do { d <- dseq dinf (mce [0.1, 0.2, 0.4, 0.3])
->    ; audition (out 0 (tDuty AR d 0 DoNothing 1)) }
+>    ; audition (out 0 (tDuty AR d 0 DoNothing 1 1)) }
 
 Amplitude changes
 
 > do { d0 <- dseq dinf (mce [0.1, 0.2, 0.4, 0.3])
 >    ; d1 <- dseq dinf (mce [0.1, 0.4, 0.01, 0.5, 1.0])
->    ; audition (out 0 (ringz (tDuty AR d0 0 DoNothing d1) 1000 0.1)) }
+>    ; audition (out 0 (ringz (tDuty AR d0 0 DoNothing d1 1) 1000 0.1)) }
 
 Mouse control.
 
 > do { d <- dseq dinf (mce [0.1, 0.4, 0.01, 0.5, 1.0])
->    ; let x = mouseX KR 0.001 1 Linear 0.1
->      in audition (out 0 (ringz (tDuty AR x 0 DoNothing d) 1000 0.1)) }
+>    ; let x = mouseX KR 0.003 1 Exponential 0.1
+>      in audition (out 0 (ringz (tDuty AR x 0 DoNothing d 1) 1000 0.1)) }
 
-Note that the 440 is the long pitch.
+Note that the 440 is the shorter pitch, since gap is set to false
 
 > do { d0 <- dser 12 (mce [0.1, 0.3])
 >    ; d1 <- dser 12 (mce [440, 880])
->    ; let t = tDuty AR d0 0 RemoveSynth d1
+>    ; let t = tDuty AR d0 0 RemoveSynth d1 0
 >      in audition (out 0 (sinOsc AR (latch t t) 0 * 0.1)) }
diff --git a/Help/UGen/External/atsNoiSynth.help.lhs b/Help/UGen/External/atsNoiSynth.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/atsNoiSynth.help.lhs
@@ -0,0 +1,38 @@
+atsNoiSynth b nPartials partialStart partialSkip ptr sinP noiseP 
+            freqMul freqAdd nBands bandStart bandSkip
+
+Resynthesize sine data from an ATS analysis file
+
+           b - buffer containing ATS data
+   nPartials - number of partials to synthesize
+partialStart - partial in the analysis to start the 
+               synthesis on (zero indexed)
+ partialSkip - increment indicating partials to synthesize
+         ptr - index into data set (0, 1)
+       sineP - scaler on sinusoidal portion of the resynthesis
+      noiseP - scaler on noise portion of the resynthesis
+     freqMul - multiplier on the sinusoidal frequency information.
+     freqAdd - value to add to frequency information.
+      nBands - number of critical bands (noise) to synthesize.  
+               There are 25 critical bands.
+   bandStart - critical band to start resynthesis on. 
+               0 is the first band.
+    bandSkip - increment indicating bands to synthesize.
+
+> let { load_data fd b i d = 
+>       if length d < 512 
+>       then send fd (b_setn1 b i d) 
+>       else do { send fd (b_setn1 b i (take 512 d))
+>               ; load_data fd b (i + 512) (drop 512 d) } }
+> in do { ats <- atsRead "/home/rohan/tn/tn-56/ats/metal.ats"
+>       ; let { d = atsSC3 ats
+>             ; h = atsHeader ats
+>             ; x = mouseX KR 0.05 1.5 Linear 0.2
+>             ; y = mouseY KR 0 1 Linear 0.2
+>             ; np = constant (atsNPartials h)
+>             ; f = x / constant (atsAnalysisDuration h)
+>             ; ptr = clip (lfSaw AR f 1 * 0.5 + 0.5) 0 1
+>             ; rs = atsNoiSynth 10 np 0 1 ptr (1 - y) y 1 0 25 0 1 }
+>         in withSC3 (\fd -> do { async fd (b_alloc 10 (length d) 1)
+>                               ; load_data fd 10 0 d
+>                               ; play fd (out 0 rs) }) }
diff --git a/Help/UGen/External/atsSynth.help.lhs b/Help/UGen/External/atsSynth.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/atsSynth.help.lhs
@@ -0,0 +1,29 @@
+atsSynth b nPartials partialStart partialSkip ptr freqMul freqAdd
+
+Resynthesize sine data from an ATS analysis file.
+
+             b - buffer containing ATS data
+     nPartials - number of partials to synthesize
+  partialStart - partial to start the synthesis at (zero indexed)
+   partialSkip - increment indicating partials to synthesize
+           ptr - data index (0, 1)
+       freqMul - multiplier for sinusoidal frequency data
+       freqAdd - value to add to frequency data
+
+> let { load_data fd b i d = 
+>       if length d < 512 
+>       then send fd (b_setn1 b i d) 
+>       else do { send fd (b_setn1 b i (take 512 d))
+>               ; load_data fd b (i + 512) (drop 512 d) } }
+> in do { ats <- atsRead "/home/rohan/tn/tn-56/ats/metal.ats"
+>       ; let { d = atsSC3 ats
+>             ; h = atsHeader ats
+>             ; x = mouseX KR 0.05 1.5 Linear 0.2
+>             ; y = mouseY KR 0.25 2.0 Linear 0.2
+>             ; np = constant (atsNPartials h)
+>             ; f = x / constant (atsAnalysisDuration h)
+>             ; ptr = lfSaw AR f 1 * 0.5 + 0.5
+>             ; rs = atsSynth 10 np 0 1 (clip ptr 0 1) y 0 }
+>         in withSC3 (\fd -> do { async fd (b_alloc 10 (length d) 1)
+>                               ; load_data fd 10 0 d
+>                               ; play fd (out 0 rs) }) }
diff --git a/Help/UGen/External/ay.help.lhs b/Help/UGen/External/ay.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/ay.help.lhs
@@ -0,0 +1,68 @@
+ay tonea toneb tonec noise ctl vola volb volc envfreq envstyle chiptype
+
+Emulates the General Instrument AY-3-8910 (a.k.a. the Yamaha
+YM2149) 3-voice sound chip, as found in the ZX Spectrum
+128, the Atari ST, and various other home computers during
+the 1980s.
+
+The inputs are as follows:
+
+ * tonea, toneb, tonec - integer "tone" value for each of
+   the 3 voices, from 0 to 4095 (i.e. 12-bit range). Higher
+   value = lower pitch. For convenience, the AY.freqtotone
+   method converts a frequency value to something
+   appropriate for these inputs.
+
+ * noise - the period of the pseudo-random noise generator, 
+   0 to 31
+
+ * control - controls how the noise is mixed into the
+   tone(s), 0 to 32 (0 is mute). This is a binary mask value
+   which masks the noise/tone mixture in each channel, so
+   it's not linear.
+
+ * vola, volb, volc - volume of the three channels, 0 to 15
+   (or 0 to 31 if using YM chiptype)
+
+ * envfreq - envelope frequency, 0 to 4095
+
+ * envstyle - type of envelope used, 0 to 15
+
+ * chiptype - 0 for AY (default), 1 for YM. The models
+   behave slightly differently. This input cannot be
+   modulated - its value is only handled at the moment the
+   UGen starts.
+
+The chip's inputs are integer values, so non-integer values
+will be rounded off.
+
+The emulation is provided by the libayemu library:
+http://sourceforge.net/projects/libayemu.
+
+> audition (out 0 (ay 1777 1666 1555 1 7 15 15 15 4 1 0))
+
+> let { tonea = mouseY KR 10 3900 Exponential 0.2
+>     ; toneb = mouseX KR 10 3900 Exponential 0.2
+>     ; ctl = 3
+>     ; vola = 14
+>     ; volb = 14
+>     ; volc = 0 
+>     ; s = ay tonea toneb 1555 1 ctl vola volb volc 4 1 0 }
+> in audition (out 0 (pan2 s 0 0.25))
+
+> let { rate = mouseX KR 0.1 10 Linear 0.2
+>     ; rng l r i = return (linLin i (-1) 1 l r)
+>     ; mk_ctl l r = lfdNoise3 KR rate >>= rng l r
+>     ; mk_ctl_0 l r = lfdNoise0 KR rate >>= rng l r }
+> in do { tonea <- mk_ctl 10 3900
+>       ; toneb <- mk_ctl 10 3900
+>       ; tonec <- mk_ctl 10 3900
+>       ; n <- mk_ctl 0 31
+>       ; ctl <- mk_ctl_0 0 31
+>       ; vola <- mk_ctl 0 15
+>       ; volb <- mk_ctl 0 15
+>       ; volc <- mk_ctl 0 15
+>       ; envfreq <- mk_ctl 0 4095
+>       ; envstyle <- mk_ctl 0 15
+>       ; let s = ay tonea toneb tonec n ctl vola volb volc envfreq envstyle 0
+>         in audition (out 0 (pan2 s 0 0.5)) }
diff --git a/Help/UGen/External/lpcSynth.help.lhs b/Help/UGen/External/lpcSynth.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/lpcSynth.help.lhs
@@ -0,0 +1,44 @@
+lpcSynth buffer excitation ptr
+lpcVals rate buffer ptr
+
+lpcSynth uses data from a LPC data file to filter a signal.
+lpcVals returns pitch, rms and error data from the LPC data
+file.
+
+      buffer - the buffer LPC data is stored
+         ptr - index into LPC data (0,1)
+  excitation - the signal to filter
+
+lpcVals reads LPC data and extracts frequency (cps), 
+amplitude (rmso) and error signals.
+
+The LPC analysis files read are those generated by 
+lpanal (see csound).
+
+Note: since the LPC data set will likely exceed the UDP packet 
+limit, load_data splits the LPC data into 512*4 byte packets.
+Alternately use TCP, or write the LPC data to a disk file and use
+b_allocRead.
+
+> let { load_data fd b i d = 
+>       if length d < 512 
+>       then send fd (b_setn1 b i d) 
+>       else do { send fd (b_setn1 b i (take 512 d))
+>               ; load_data fd b (i + 512) (drop 512 d) }
+>     ; lpc_instr b n lpc = 
+>       let { x = mouseX KR 0.05 1.5 Linear 0.2
+>           ; y = mouseY KR 0.25 2.0 Linear 0.2
+>           ; f = x / constant (lpcAnalysisDuration (lpcHeader lpc))
+>           ; ptr = lfSaw AR f 1 * 0.5 + 0.5
+>           ; MCE [cps, rms, err] = lpcVals ar b ptr
+>           ; nh = floorE (22000 / cps)
+>           ; voc = blip AR (cps * y) nh * (1 - err)
+>           ; s = lpcSynth b (voc + (n * err * 20)) ptr }
+>       in s * 1e-5 * rms }
+> in do { lpc <- lpcRead "/home/rohan/tn/tn-56/lpc/fate.lpc"
+>       ; n <- pinkNoise AR
+>       ; let { d = lpcSC3 lpc 
+>             ; s = lpc_instr 10 n lpc }
+>         in withSC3 (\fd -> do { async fd (b_alloc 10 (length d) 1)
+>                               ; load_data fd 10 0 d
+>                               ; play fd (out 0 s) }) }
diff --git a/Help/UGen/External/lpcVals.help.lhs b/Help/UGen/External/lpcVals.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/lpcVals.help.lhs
@@ -0,0 +1,1 @@
+See lpcSynth
diff --git a/Help/UGen/External/membraneCircle.help.lhs b/Help/UGen/External/membraneCircle.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/membraneCircle.help.lhs
@@ -0,0 +1,25 @@
+membraneCircle input tension loss
+membraneHexagon input tension loss
+
+Triangular waveguide meshes of a drum-like membrane.  Input is
+an excitation signal, such as a pulse of noise.  Tension and
+loss are k-rate.
+
+The variants are named after the shape made out of triangular 
+meshes.
+
+Excite the mesh with some pink noise, triggered by an 
+impulse generator.  mouseX is tension and impulse frequency, 
+mouseY is duration of excitation, release-time and amplitude.
+
+> let { x = mouseX KR 0 1 Linear 0.2
+>     ; y = mouseY KR 1e-9 1 Exponential 0.2
+>     ; loss = linLin y 0 1 0.999999 0.999
+>     ; wobble = sinOsc KR 2 0
+>     ; tension = linLin x 0 1 0.01 0.1 + (wobble * 0.0001)
+>     ; p = envPerc 0.0001 y
+>     ; tr = impulse KR (linLin x 0 1 3 9) 0
+>     ; e = envGen KR tr (linLin y 0 1 0.05 0.25) 0 0.1 DoNothing p
+>     ; m = membraneCircle }
+> in do { n <- pinkNoise AR
+>       ; audition (out (mce2 0 1) (m (n * e) tension loss)) }
diff --git a/Help/UGen/External/membraneHexagon.help.lhs b/Help/UGen/External/membraneHexagon.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/membraneHexagon.help.lhs
@@ -0,0 +1,1 @@
+See membraneCircle.
diff --git a/Help/UGen/External/pv_Invert.help.lhs b/Help/UGen/External/pv_Invert.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/pv_Invert.help.lhs
@@ -0,0 +1,9 @@
+pv_Invert buffer
+
+> let { s = sinOsc AR 440 0 * 0.4
+>     ; n = Sound.SC3.UGen.Base.pinkNoise (uid 0) AR * 0.1
+>     ; i = s + n
+>     ; c0 = fft' 10 i
+>     ; c1 = pv_Invert c0 }
+> in withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                       ; audition (out 0 (mce2 i (ifft' c1) * 0.5)) })
diff --git a/Help/UGen/External/stkBowed.help.lhs b/Help/UGen/External/stkBowed.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/stkBowed.help.lhs
@@ -0,0 +1,4 @@
+stkBowed rt freq bowPressure bowPosition vibFreq vibGain loudness gate
+
+> let g = toggleFF (impulse KR 1 0)
+> in audition (out 0 (stkBowed AR 220 64 64 64 64 64 g))
diff --git a/Help/UGen/External/stkFlute.help.lhs b/Help/UGen/External/stkFlute.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/stkFlute.help.lhs
@@ -0,0 +1,5 @@
+stkFlute rate freq jetDelay noisegain vibFreq vibGain breathPressure tr
+
+> let { bp = line KR 76 32 3 RemoveSynth
+>     ; ng = line KR 16 64 3 DoNothing }
+> in audition (out 0 (stkFlute AR 400 64 ng 16 16 bp 1))
diff --git a/Help/UGen/External/stkMandolin.help.lhs b/Help/UGen/External/stkMandolin.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/stkMandolin.help.lhs
@@ -0,0 +1,25 @@
+stkMandolin rate f bs pp dm dt at tr
+
+        f - frequency
+       bs - body size
+       pp - pick position
+       dm - string damping
+       dt - string detune
+       at - after touch
+
+> let { x = mouseX KR 0.25 4 Linear 0.2 
+>     ; tr = impulse KR x 0 - 0.5 }
+> in do { mn <- tRand 54 66 tr
+>       ; [bs, pp, dm, dt, at] <- replicateM 5 (tRand 0 127 tr)
+>       ; audition (out 0 (stkMandolin AR (midiCPS mn) bs pp dm dt at tr)) }
+
+> let { x = mouseX KR 3 16 Linear 0.2 
+>     ; t = impulse KR x 0 - 0.5 
+>     ; tr = pulseDivider t 6 0 }
+> in do { mn <- tiRand 54 66 t
+>       ; bs <- tRand 72 94 tr
+>       ; pp <- tRand 32 42 tr
+>       ; dm <- tRand 64 72 tr
+>       ; dt <- tRand 0 4 tr
+>       ; at <- tRand 2 8 tr
+>       ; audition (out 0 (stkMandolin AR (midiCPS mn) bs pp dm dt at t)) }
diff --git a/Help/UGen/External/stkModalBar.help.lhs b/Help/UGen/External/stkModalBar.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/stkModalBar.help.lhs
@@ -0,0 +1,25 @@
+stkModalBar freq instrument stickHardness stickPosition 
+            vibratoGain vibratoFreq directStickMix volume trig
+
+  Marimba=0, Vibraphone=1, Agogo=2, Wood1=3, Reso=4,
+  Wood2=5, Beats=6, Two Fixed=7, Clump=8
+
+> let { x = mouseX KR 0.25 4 Linear 0.2 
+>     ; tr = impulse KR x 0 - 0.5
+>     ; tR = tRand 0 127 tr }
+> in do { i <- tRand 0 9 tr
+>       ; mn <- tiRand 25 96 tr
+>       ; [sh, sp, vg, vf, mx, v] <- replicateM 6 tR
+>       ; audition (out 0 (stkModalBar AR (midiCPS mn) i sh sp vg vf mx v tr)) }
+
+> let { x = mouseX KR 1 6 Linear 0.2 
+>     ; t = impulse KR x 0 - 0.5
+>     ; tr = pulseDivider t 6 0 }
+> in do { mn <- tiRand 52 64 t
+>       ; sh <- tRand 4 8 tr
+>       ; sp <- tRand 54 68 tr
+>       ; vg <- tRand 66 98 tr
+>       ; vf <- tRand 4 12 tr
+>       ; mx <- tRand 0 1 tr
+>       ; v <- tRand 16 48 tr
+>       ; audition (out 0 (stkModalBar AR (midiCPS mn) 1 sh sp vg vf mx v t)) }
diff --git a/Help/UGen/External/stkShakers.help.lhs b/Help/UGen/External/stkShakers.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/stkShakers.help.lhs
@@ -0,0 +1,24 @@
+stkShakers rt instr energy decay nObjects rfreq tr
+
+     instr - model type
+    energy - initial energy
+     decay - rate of decay of system
+  nObjects - number of particles / elements
+     rfreq - resonance frequency
+        tr - reset trigger
+
+  Maraca=0, Cabasa=1, Sekere=2, Guiro=3, Water Drops =4,
+  Bamboo Chimes=5, Tambourine=6, Sleigh Bells=7, Sticks=8,
+  Crunch=9, Wrench=10, Sand Paper=11, Coke Can=12, Next
+  Mug=13, Penny + Mug=14, Nickle + Mug = 15, Dime + Mug=16,
+  Quarter + Mug=17, Franc + Mug=18, Peso + Mug=19, Big
+  Rocks=20, Little Rocks=21, Tuned Bamboo Chimes=22
+
+> let { x = mouseX KR 0.25 4 Linear 0.2 
+>     ; tr = impulse KR x 0 - 0.5 }
+> in do { i <- tRand 0 23 tr
+>       ; [e, sd, no, rf] <- replicateM 4 (tRand 0 127 tr)
+>       ; audition (out 0 (stkShakers AR i e sd no rf tr)) }
+
+> let tr = impulse KR 1 0 - 0.5
+> in audition (out 0 (stkShakers AR 4 64 64 64 64 tr))
diff --git a/Help/UGen/External/vosim.help.lhs b/Help/UGen/External/vosim.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/External/vosim.help.lhs
@@ -0,0 +1,32 @@
+vosim tr freq nCycles decay
+
+      trig - starts a vosim pulse when a transition from
+             non-positive to positive occurs and no other
+             vosim is still going.  a-rate will produce
+             sample accurate triggering.
+
+      freq - sets the frequency of the squared sinewave.
+
+   nCycles - sets the number of squared sinewaves to use
+             in one vosim pulse.  nCycles gets checked
+             when VOSIM receives a trigger.
+
+     decay - sets the decay factor.
+
+> do { p <- tRand 0 1 (impulse AR 6 0)
+>    ; let { t = impulse AR (9 * ( 1 + ( p >* 0.95))) 0
+>          ; x = mouseX KR 0.25 2 Linear 0.2
+>          ; y = mouseY KR 0.25 1.5 Linear 0.2
+>          ; z = 9 
+>          ; range i l r = linLin i (-1) 1 l r
+>          ; mk_n = lfNoise2 KR z >>= return . range 0.25 2 
+>          ; tR l r = tRand (mce l) (mce r) }
+>      in do { f <- tR [40, 120, 220] [440, 990, 880] t
+>            ; n <- tR [4] [8, 16, 32] t
+>            ; d <- tR [0.2, 0.4, 0.6] [0.6, 0.8, 1] t
+>            ; a <- tR [0] [0.2, 0.6, 1] t
+>            ; l <- tR [-1] [1] t
+>            ; xn <- mk_n
+>            ; yn <- mk_n
+>            ; let v = vosim t (f * x * xn) n (d * y * yn) * a
+>              in audition (out 0 (pan2 (mix v) l 1)) } }
diff --git a/Help/UGen/Filter/freeVerb.help.lhs b/Help/UGen/Filter/freeVerb.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/Filter/freeVerb.help.lhs
@@ -0,0 +1,24 @@
+freeVerb in mix room damp
+freeVerb2 in1 in2 mix room damp
+
+A simple reverb.
+
+ in, in1, in2 - input signal
+          mix - dry/wet balance (0,1)
+         room - room size (0,1)
+         damp - reverb high frequency damping (0,1)
+
+> let { i = impulse ar 1 0
+>     ; c = lfCub ar 1200 0
+>     ; s = decay i 0.25 * c * 0.1
+>     ; x = mouseX kr 0 1 Linear 0.1
+>     ; y = mouseY kr 0 1 Linear 0.1
+>     ; r = freeVerb s y x 0.5 }
+> in audition (out 0 r)
+
+> let { i = soundIn (mce2 0 1)
+>     ; c = mceChannel
+>     ; x = mouseX kr 0 1 Linear 0.1
+>     ; y = mouseY kr 0 1 Linear 0.1
+>     ; r = freeVerb2 (c 0 i) (c 1 i) y x 0.5 }
+> in audition (out 0 r)
diff --git a/Help/UGen/IO/lagIn.help.lhs b/Help/UGen/IO/lagIn.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/IO/lagIn.help.lhs
@@ -0,0 +1,8 @@
+lagIn numChannels bus lag
+
+Smooth a control rate input signal.
+
+> withSC3 (\fd -> do { send fd (c_set [(10, 200)])
+>                    ; play fd (out 0 (sinOsc AR (lagIn 1 10 1) 0 * 0.1))
+>                    ; threadDelay 500000
+>                    ; send fd (c_set [(10, 2000)]) })
diff --git a/Help/UGen/IO/lagIn.lhs b/Help/UGen/IO/lagIn.lhs
deleted file mode 100644
--- a/Help/UGen/IO/lagIn.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-lagIn numChannels bus lag
-
-Smooth a control rate input signal.
-
-> withSC3 (\fd -> do { send fd (c_set [(10, 200)])
->                    ; play fd (out 0 (sinOsc AR (lagIn 1 10 1) 0 * 0.1))
->                    ; threadDelay 500000
->                    ; send fd (c_set [(10, 2000)]) })
diff --git a/Help/UGen/IO/soundIn.help.lhs b/Help/UGen/IO/soundIn.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/IO/soundIn.help.lhs
@@ -0,0 +1,12 @@
+soundIn channel
+
+Read audio from the sound input hardware.
+
+channel - input channel number to read, 
+          indexed from zero, can be mce.
+
+> audition (out 0 (soundIn 0))
+
+> audition (out 0 (soundIn (mce2 0 1)))
+
+> audition (out 0 (soundIn (mce [0, 2, 1, 3])))
diff --git a/Help/UGen/Information/sampleRate.help.lhs b/Help/UGen/Information/sampleRate.help.lhs
--- a/Help/UGen/Information/sampleRate.help.lhs
+++ b/Help/UGen/Information/sampleRate.help.lhs
@@ -6,3 +6,10 @@
 
 > let f = mce [sampleRate * 0.01, 440]
 > in audition (out 0 (sinOsc AR f 0 * 0.1))
+
+The server status command can extract nominal and
+actual sample rates from a running server.
+
+> withSC3 (\fd -> liftM2 (,)
+>                        (serverSampleRateNominal fd) 
+>                        (serverSampleRateActual fd))
diff --git a/Help/UGen/MachineListening/beatTrack.help.lhs b/Help/UGen/MachineListening/beatTrack.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/MachineListening/beatTrack.help.lhs
@@ -0,0 +1,57 @@
+beatTrack c lock
+
+     c - Audio input to track, already passed through an FFT
+         UGen; the expected size of FFT is 1024 for 44100
+         and 48000 sampling rate, and 2048 for double
+         those. No other sampling rates are supported.
+
+  lock - If this argument is greater than 0.5, the tracker
+         will lock at its current periodicity and continue
+         from the current phase. Whilst it updates the
+         model's phase and period, this is not reflected in
+         the output until lock goes back below 0.5.
+
+Autocorrelation based beat tracker; the underlying model
+assumes 4/4, but it should work on any isochronous beat
+structure, though there are biases to 100-120 bpm; a fast
+7/8 may not be tracked in that sense. There are four k-rate
+outputs, being ticks at quarter, eighth and sixteenth level
+from the determined beat, and the current detected
+tempo. Note that the sixteenth note output won't necessarily
+make much sense if the music being tracked has swing; it is
+provided just as a convenience.
+
+This beat tracker determines the beat, biased to the
+midtempo range by weighting functions. It does not determine
+the measure level, only a tactus. It is also slow reacting,
+using a 6 second temporal window for its autocorrelation
+maneouvres. Don't expect human musician level predictive
+tracking.
+
+On the other hand, it is tireless, relatively general
+(though obviously best at transient 4/4 heavy material
+without much expressive tempo variation), and can form the
+basis of computer processing that is decidedly faster than
+human.
+
+> let { i = soundIn 0
+>     ; x = mouseX KR (-1) 1 Linear 0.2
+>     ; MCE [b, h, q, t] = beatTrack (fft' 10 i) x
+>     ; f = mce [440, 660, 880]
+>     ; s = mix (sinOsc AR f 0 * 0.1 * decay (mce [b, h, q]) 0.05) }
+> in withSC3 (\fd -> do { async fd (b_alloc 10 1024 1)
+>                       ; play fd (out 0 s) })
+
+Davies, M. E. P.  and Plumbley, M. D. Beat Tracking With A
+Two State Model. Proceedings of the IEEE International
+Conference on Acoustics, Speech and Signal Processing
+(ICASSP 2005), Philadelphia, USA, March 19-23, 2005
+
+The UGen was converted by Nick Collins for beat tracking
+research in the course of his PhD and uses an original C
+implementation of Matthew Davies' MATLAB model. It first
+appeared as part of BBCut2 as AutoTrack but has now been
+added to core to enhance SuperCollider's realtime machine
+listening options.
+
+
diff --git a/Help/UGen/MachineListening/onsets.help.lhs b/Help/UGen/MachineListening/onsets.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/MachineListening/onsets.help.lhs
@@ -0,0 +1,100 @@
+onsets c threshold odftype relaxtime floor mingap medianspan whtype rawodf
+onsets' c threshold odftype
+
+An onset detector for musical audio signals - detects the
+beginning of notes/drumbeats/etc. Outputs a control-rate
+trigger signal which is 1 when an onset is detected, and 0
+otherwise.
+
+          c - an FFT chain
+
+  threshold - the detection threshold, typically between 0
+              and 1, although in rare cases you may find
+              values outside this range useful
+
+    odftype - the function used to analyse the signal
+              (options described below; OK to leave this at
+              its default value)
+
+  relaxtime - specifies the time (in seconds) for the
+              normalisation to "forget" about a recent
+              onset. If you find too much re-triggering
+              (e.g. as a note dies away unevenly) then you
+              might wish to increase this value.
+
+      floor - is a lower limit, connected to the idea of how
+              quiet the sound is expected to get without
+              becoming indistinguishable from noise. For
+              some cleanly-recorded classical music with
+              wide dynamic variations, I found it helpful to
+              go down as far as 0.000001.
+
+     mingap - specifies a minimum gap (in seconds) between
+              onset detections, a brute-force way to prevent
+              too many doubled detections.
+
+ medianspan - specifies the size (in FFT frames) of the
+              median window used for smoothing the detection
+              function before triggering.
+
+For the FFT chain, you should typically use a frame size of
+512 or 1024 (at 44.1 kHz sampling rate) and 50% hop size
+(which is the default setting in SC). For different sampling
+rates choose an FFT size to cover a similar time-span
+(around 10 to 20 ms).
+
+The onset detection should work well for a general range of
+monophonic and polyphonic audio signals. The onset detection
+is purely based on signal analysis and does not make use of
+any "top-down" inferences such as tempo.
+
+> let { x = mouseX KR 0 1 Linear 0.2
+>     ; i = soundIn 0
+>     ; c = fft' 10 i
+>     ; o = onsets' c x (onsetType "rcomplex")
+>     ; s = sinOsc AR 440 0 * 0.2
+>     ; e = envGen KR o 1 0 1 DoNothing (envPerc 0.001 0.1) }
+> in withSC3 (\fd -> do { async fd (b_alloc 10 512 1)
+>                       ; play fd (out 0 (s * e)) })
+
+The type argument chooses which onset detection function is
+used. In many cases the default will be fine. The following
+choices are available:
+
+    power - generally OK, good for percussive input, and
+            also very efficient
+
+   magsum - generally OK, good for percussive input, and
+            also very efficient
+
+  complex - performs generally very well, but more
+            CPU-intensive
+
+ rcomplex - performs generally very well, and slightly more
+            efficient than complex
+
+    phase - generally good, especially for tonal input,
+            medium efficiency
+
+   wphase - generally very good, especially for tonal input,
+            medium efficiency
+
+      mkl - generally very good, medium efficiency, pretty
+            different from the other methods
+
+Which of these should you choose? The differences aren't
+large, so I'd recommend you stick with the default \rcomplex
+unless you find specific problems with it. Then maybe try
+\wphase. The \mkl type is a bit different from the others so
+maybe try that too. They all have slightly different
+characteristics, and in tests perform at a similar quality
+level.
+
+For more details of all the processes involved, the
+different onset detection functions, and their evaluation,
+see
+
+D. Stowell and M. D. Plumbley. Adaptive whitening for
+improved real-time audio onset detection. Proceedings of the
+International Computer Music Conference (ICMC’07),
+Copenhagen, Denmark, August 2007.
diff --git a/Help/UGen/Oscillator/tChoose.help.lhs b/Help/UGen/Oscillator/tChoose.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/Oscillator/tChoose.help.lhs
@@ -0,0 +1,16 @@
+tChoose trig inputs
+
+The output is selected randomly on recieving a trigger from an
+array of inputs.  tChoose is a composite of tiRand and select.
+
+> let x = mouseX kr 1 1000 Exponential 0.1
+> in do { t <- dust ar x
+>       ; f <- liftM midiCPS (tiRand 48 60 t)
+>       ; o <- let a = mce [ sinOsc ar f 0
+>                          , saw ar (f * 2)
+>                          , pulse ar (f * 0.5) 0.1 ]
+>              in tChoose t a
+>       ; audition (out 0 (o * 0.1)) }
+
+;; Note: all the ugens are continously running. This may not be the
+;; most efficient way if each input is cpu-expensive.
diff --git a/Help/UGen/Oscillator/twChoose.help.lhs b/Help/UGen/Oscillator/twChoose.help.lhs
--- a/Help/UGen/Oscillator/twChoose.help.lhs
+++ b/Help/UGen/Oscillator/twChoose.help.lhs
@@ -8,14 +8,14 @@
 normalize the values.  TWChoose is a composite of TWindex and
 Select
 
-> let { twChoose t a w n = select (twindex t n w) a
->     ; x = mouseX KR 1 1000 Exponential 0.1 }
+> let x = mouseX KR 1 1000 Exponential 0.1
 > in do { d <- dust AR x
 >       ; let { a = mce [ sinOsc AR 220 0
->                     , saw AR 440
->                     , pulse AR 110 0.1] 
+>                       , saw AR 440
+>                       , pulse AR 110 0.1] 
 >             ; w = mce [0.5, 0.35, 0.15] }
->         in audition (out 0 (twChoose d a w 0 * 0.1)) }
+>         in do { o <- twChoose d a w 0
+>               ; audition (out 0 (o * 0.1)) } }
 
 Note: all the ugens are continously running. This may not be the
 most efficient way if each input is cpu-expensive.
diff --git a/Help/UGen/Oscillator/twindex.help.lhs b/Help/UGen/Oscillator/twindex.help.lhs
--- a/Help/UGen/Oscillator/twindex.help.lhs
+++ b/Help/UGen/Oscillator/twindex.help.lhs
@@ -2,20 +2,20 @@
 
 Triggered windex.  When triggered, returns a random index value based
 on array as a list of probabilities.  By default the list of
-probabilities should sum to 1.0, when the normalize flag is set to 1,
+probabilities should sum to 1, when the normalize flag is set to 1,
 the values get normalized by the ugen (less efficient) Assuming
 normalized values
 
 > let { p = mce [1/5, 2/5, 2/5]
 >     ; a = mce [400, 500, 600]
->     ; t = impulse KR 6 0
->     ; f = select (twindex t 0.0 p) a }
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
+>     ; t = impulse KR 6 0 }
+> in do { i <- twindex t 0 p
+>       ; audition (out 0 (sinOsc AR (select i  a) 0 * 0.1)) }
 
 Modulating probability values
 
 > let { p = mce [1/4, 1/2, sinOsc KR 0.3 0 * 0.5 + 0.5]
 >     ; a = mce [400, 500, 600]
 >     ; t = impulse KR 6 0
->     ; f = select (twindex t 1.0 p) a }
+>     ; f = select (twindex t 1 p) a }
 > in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Trigger/sendTrig.help.lhs b/Help/UGen/Trigger/sendTrig.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/Trigger/sendTrig.help.lhs
@@ -0,0 +1,24 @@
+sendTrig in id value
+
+On receiving a trigger (0 to non-zero transition), send a trigger
+message from the server back to all registered clients.  Clients
+register by sending a /notify message to the server.
+
+input - the trigger
+
+id    - an integer that will be passed with the trigger message.  This
+  	is useful if you have more than one SendTrig in a SynthDef
+
+value - a UGen or float that will be polled at the time of trigger,
+        and its value passed with the trigger message
+
+> withSC3 (\fd -> async fd (notify True))
+
+> do { s <- lfNoise0 KR 10
+>    ; let o = sinOsc AR (s * 200 + 500) 0 * 0.1
+>      in audition (mrg [sendTrig s 0 s, out 0 o]) }
+
+> withSC3 (\fd -> do { tr <- wait fd "/tr"
+>                    ; putStrLn (show tr) })
+
+> withSC3 (\fd -> async fd (notify False))
diff --git a/Help/UGen/Trigger/sendTrig.lhs b/Help/UGen/Trigger/sendTrig.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/sendTrig.lhs
+++ /dev/null
@@ -1,24 +0,0 @@
-sendTrig in id value
-
-On receiving a trigger (0 to non-zero transition), send a trigger
-message from the server back to all registered clients.  Clients
-register by sending a /notify message to the server.
-
-input - the trigger
-
-id    - an integer that will be passed with the trigger message.  This
-  	is useful if you have more than one SendTrig in a SynthDef
-
-value - a UGen or float that will be polled at the time of trigger,
-        and its value passed with the trigger message
-
-> withSC3 (\fd -> async fd (notify True))
-
-> do { s <- lfNoise0 KR 10
->    ; let o = sinOsc AR (s * 200 + 500) 0 * 0.1
->      in audition (mrg [sendTrig s 0 s, out 0 o]) }
-
-> withSC3 (\fd -> do { tr <- wait fd "/tr"
->                    ; putStrLn (show tr) })
-
-> withSC3 (\fd -> async fd (notify False))
diff --git a/Help/hsc3.help.lhs b/Help/hsc3.help.lhs
--- a/Help/hsc3.help.lhs
+++ b/Help/hsc3.help.lhs
@@ -266,7 +266,7 @@
 >             in mrg [b, localOut c]
 > in do { n <- whiteNoise AR
 >       ; let s = decay (impulse AR 0.3 0) 0.1 * n * 0.2
->         in audition (out 0 (ping_pong s)) }
+>         in audition (out 0 (ppd s)) }
 
 * Literals, Overloading, Coercion, Constants
 
@@ -485,6 +485,40 @@
 It is the type of audition that determines the
 type of a, the type is inferred so there is no
 need to write it.
+
+* Unsafe unit generator constructors
+
+Haskell provides a mechanism to force values
+from the IO monad, unsafePerformIO.
+
+Using this we can write unit generator graphs
+that have non-deterministic nodes using only
+orindary let binding.
+
+> import System.IO.Unsafe
+
+> let { u = unsafePerformIO
+>     ; a = u (whiteNoise AR)
+>     ; b = u (whiteNoise AR)
+>     ; c = a - b }
+> in audition (out 0 (c * 0.1))
+
+This is hardly more convenient than do notation,
+however we can also insert non-determinstic nodes
+directly into function arguments.
+
+> let { n = Sound.SC3.UGen.Unsafe.whiteNoise
+>     ; x = n AR - n AR }
+> in audition (out 0 (x * 0.1))
+
+The above uses the unsafe unit generator functions
+provided at Sound.SC3.UGen.Unsafe, and avoids the
+lifting operations which, for functions of many
+arguments, can be cumbersome.
+
+> let n = whiteNoise
+> in do { x <- liftM2 (-) (n AR) (n AR)
+>       ; audition (out 0 (x * 0.1)) }
 
 * Demand Rate, Sharing Again
 
diff --git a/README b/README
--- a/README
+++ b/README
@@ -1,13 +1,14 @@
-hsc3 - Haskell SuperCollider
+hsc3 - haskell supercollider
 
 hsc3 provides Sound.SC3, a Haskell module that facilitates using
 Haskell as a client to the SuperCollider synthesis server.  
 
 The hsc3 interaction environment is written for GNU Emacs.
 
-  http://slavepianos.org/rd/
+  http://slavepianos.org/rd/f/207949/
   http://haskell.org/
   http://audiosynth.com/
   http://gnu.org/software/emacs/
 
-(c) rohan drape, 2006-2008, GPL.2, http://gnu.org/copyleft/
+(c) rohan drape, 2006-2008
+    gpl, http://gnu.org/copyleft/
diff --git a/Sound/SC3/Server/Command.hs b/Sound/SC3/Server/Command.hs
--- a/Sound/SC3/Server/Command.hs
+++ b/Sound/SC3/Server/Command.hs
@@ -1,83 +1,83 @@
 module Sound.SC3.Server.Command where
 
+import Data.Word
 import Sound.OpenSoundControl
 import Sound.SC3.Server.Utilities
-import Data.Word (Word8)
 
 -- * Instrument definition commands.
 
 -- | Install a bytecode instrument definition. (Asynchronous)
 d_recv :: [Word8] -> OSC
-d_recv b = message "/d_recv" [blob b]
+d_recv b = Message "/d_recv" [Blob b]
 
 -- | Load an instrument definition from a named file. (Asynchronous)
 d_load :: String -> OSC
-d_load p = message "/d_load" [string p]
+d_load p = Message "/d_load" [String p]
 
 -- | Load a directory of instrument definitions files. (Asynchronous)
 d_loadDir :: String -> OSC
-d_loadDir p = message "/d_loadDir" [string p]
+d_loadDir p = Message "/d_loadDir" [String p]
 
 -- | Remove definition once all nodes using it have ended.
 d_free :: [String] -> OSC
-d_free n = message "/d_free" (map string n)
+d_free n = Message "/d_free" (map String n)
 
 -- * Node commands.
 
 -- | Place a node after another.
 n_after :: [(Int, Int)] -> OSC
-n_after l = message "/n_after" (mkDuples int int l)
+n_after l = Message "/n_after" (mk_duples Int Int l)
 
 -- | Place a node before another.
 n_before :: [(Int, Int)] -> OSC
-n_before l = message "/n_before" (mkDuples int int l)
+n_before l = Message "/n_before" (mk_duples Int Int l)
 
 -- | Fill ranges of a node's control values.
 n_fill :: Int -> [(String, Int, Double)] -> OSC
-n_fill nid l = message "/n_fill" (int nid : mkTriples string int float l)
+n_fill nid l = Message "/n_fill" (Int nid : mk_triples String Int Float l)
 
 -- | Delete a node.
 n_free :: [Int] -> OSC
-n_free nid = message "/n_free" (map int nid)
+n_free nid = Message "/n_free" (map Int nid)
 
 -- | Map a node's controls to read from a bus.
 n_map :: Int -> [(String, Int)] -> OSC
-n_map nid l = message "/n_map" (int nid : mkDuples string int l)
+n_map nid l = Message "/n_map" (Int nid : mk_duples String Int l)
 
 -- | Map a node's controls to read from buses.
 n_mapn :: Int -> [(String, Int, Int)] -> OSC
-n_mapn nid l = message "/n_mapn" (int nid : mkTriples string int int l)
+n_mapn nid l = Message "/n_mapn" (Int nid : mk_triples String Int Int l)
 
 -- | Get info about a node.
 n_query :: [Int] -> OSC
-n_query nid = message "/n_query" (map int nid)
+n_query nid = Message "/n_query" (map Int nid)
 
 -- | Turn node on or off.
 n_run :: [(Int, Bool)] -> OSC
-n_run l = message "/n_run" (mkDuples int (int . fromEnum) l)
+n_run l = Message "/n_run" (mk_duples Int (Int . fromEnum) l)
 
 -- | Set a node's control values.
 n_set :: Int -> [(String, Double)] -> OSC
-n_set nid c = message "/n_set" (int nid : mkDuples string float c)
+n_set nid c = Message "/n_set" (Int nid : mk_duples String Float c)
 
 -- | Set ranges of a node's control values.
 n_setn :: Int -> [(String, [Double])] -> OSC
-n_setn nid l = message "/n_setn" (int nid : concatMap f l)
-    where f (s,d) = string s : int (length d) : (map float d)
+n_setn nid l = Message "/n_setn" (Int nid : concatMap f l)
+    where f (s,d) = String s : Int (length d) : (map Float d)
 
 -- | Trace a node.
 n_trace :: [Int] -> OSC
-n_trace nid = message "/n_trace" (map int nid)
+n_trace nid = Message "/n_trace" (map Int nid)
 
 -- * Synthesis node commands.
 
 -- | Get control values.
 s_get :: Int -> [String] -> OSC
-s_get nid i = message "/s_get" (int nid : map string i)
+s_get nid i = Message "/s_get" (Int nid : map String i)
 
 -- | Get ranges of control values.
 s_getn :: Int -> [(String, Int)] -> OSC
-s_getn nid l = message "/s_getn" (int nid : mkDuples string int l)
+s_getn nid l = Message "/s_getn" (Int nid : mk_duples String Int l)
 
 -- | Enumeration of possible locations to add new nodes (s_new and g_new).
 data AddAction = AddToHead
@@ -89,127 +89,127 @@
 
 -- | Create a new synth.
 s_new :: String -> Int -> AddAction -> Int -> [(String, Double)] -> OSC
-s_new n i a t c = message "/s_new" (string n : int i : int (fromEnum a) : int t : mkDuples string float c)
+s_new n i a t c = Message "/s_new" (String n : Int i : Int (fromEnum a) : Int t : mk_duples String Float c)
 
 -- | Auto-reassign synth's ID to a reserved value.
 s_noid :: [Int] -> OSC
-s_noid nid = message "/s_noid" (map int nid)
+s_noid nid = Message "/s_noid" (map Int nid)
 
 -- * Group node commands.
 
 -- | Free all synths in this group and all its sub-groups.
 g_deepFree :: [Int] -> OSC
-g_deepFree nid = message "/g_deepFree" (map int nid)
+g_deepFree nid = Message "/g_deepFree" (map Int nid)
 
 -- | Delete all nodes in a group.
 g_freeAll :: [Int] -> OSC
-g_freeAll nid = message "/g_freeAll" (map int nid)
+g_freeAll nid = Message "/g_freeAll" (map Int nid)
 
 -- | Add node to head of group.
 g_head :: [(Int, Int)] -> OSC
-g_head l = message "/g_head" (mkDuples int int l)
+g_head l = Message "/g_head" (mk_duples Int Int l)
 
 -- | Create a new group.
 g_new :: [(Int, AddAction, Int)] -> OSC
-g_new l = message "/g_new" (mkTriples int (int . fromEnum) int l)
+g_new l = Message "/g_new" (mk_triples Int (Int . fromEnum) Int l)
 
 -- | Add node to tail of group.
 g_tail :: [(Int, Int)] -> OSC
-g_tail l = message "/g_tail" (mkDuples int int l)
+g_tail l = Message "/g_tail" (mk_duples Int Int l)
 
 -- * Unit Generator commands.
 
 -- | Send a command to a unit generator.
 u_cmd :: Int -> Int -> String -> [Datum] -> OSC
-u_cmd nid uid cmd arg = message "/u_cmd" ([int nid, int uid, string cmd] ++ arg)
+u_cmd nid uid cmd arg = Message "/u_cmd" ([Int nid, Int uid, String cmd] ++ arg)
 
 -- * Buffer commands.
 
 -- | Allocates zero filled buffer to number of channels and samples. (Asynchronous)
 b_alloc :: Int -> Int -> Int -> OSC
-b_alloc nid frames channels = message "/b_alloc" [int nid, int frames, int channels]
+b_alloc nid frames channels = Message "/b_alloc" [Int nid, Int frames, Int channels]
 
 -- | Allocate buffer space and read a sound file.
 b_allocRead :: Int -> String -> Int -> Int -> OSC
-b_allocRead nid p f n = message "/b_allocRead" [int nid, string p, int f, int n]
+b_allocRead nid p f n = Message "/b_allocRead" [Int nid, String p, Int f, Int n]
 
 -- | Close attached soundfile and write header information.
 b_close :: Int -> OSC
-b_close nid = message "/b_close" [int nid]
+b_close nid = Message "/b_close" [Int nid]
 
 -- | Fill ranges of sample values.
 b_fill :: Int -> [(Int, Int, Double)] -> OSC
-b_fill nid l = message "/b_fill" (int nid : mkTriples int int float l)
+b_fill nid l = Message "/b_fill" (Int nid : mk_triples Int Int Float l)
 
 -- | Free buffer data.
 b_free :: Int -> OSC
-b_free nid = message "/b_free" [int nid]
+b_free nid = Message "/b_free" [Int nid]
 
 -- | Call a command to fill a buffer.
 b_gen :: Int -> String -> [Double] -> OSC
-b_gen bid cmd arg = message "/b_gen" (int bid : string cmd : map float arg)
+b_gen bid cmd arg = Message "/b_gen" (Int bid : String cmd : map Float arg)
 
 -- | Get sample values.
 b_get :: Int -> [Int] -> OSC
-b_get nid i = message "/b_get" (int nid : map int i)
+b_get nid i = Message "/b_get" (Int nid : map Int i)
 
 -- | Get ranges of sample values.
 b_getn :: Int -> [(Int, Int)] -> OSC
-b_getn nid l = message "/b_getn" (int nid : mkDuples int int l)
+b_getn nid l = Message "/b_getn" (Int nid : mk_duples Int Int l)
 
 -- | Request \/b_info messages.
 b_query :: [Int] -> OSC
-b_query nid = message "/b_query" (map int nid)
+b_query nid = Message "/b_query" (map Int nid)
 
 -- | Read sound file data into an existing buffer.
 b_read :: Int -> String -> Int -> Int -> Int -> Int -> OSC
-b_read nid p f n f' z = message "/b_read" [int nid, string p, int f, int n, int f', int z]
+b_read nid p f n f' z = Message "/b_read" [Int nid, String p, Int f, Int n, Int f', Int z]
 
 -- | Set sample values.
 b_set :: Int -> [(Int, Double)] -> OSC
-b_set nid l = message "/b_set" (int nid : mkDuples int float l)
+b_set nid l = Message "/b_set" (Int nid : mk_duples Int Float l)
 
 -- | Set ranges of sample values.
 b_setn :: Int -> [(Int, [Double])] -> OSC
-b_setn nid l = message "/b_setn" (int nid : concatMap f l)
-    where f (i,d) = int i : int (length d) : map float d
+b_setn nid l = Message "/b_setn" (Int nid : concatMap f l)
+    where f (i,d) = Int i : Int (length d) : map Float d
 
 -- | Write sound file data.
 b_write :: Int -> String -> Int -> Int -> Int -> Int -> Int -> OSC
-b_write nid p h t f s z = message "/b_write" [int nid, string p, int h, int t, int f, int s, int z]
+b_write nid p h t f s z = Message "/b_write" [Int nid, String p, Int h, Int t, Int f, Int s, Int z]
 
 -- | Zero sample data.
 b_zero :: Int -> OSC
-b_zero nid = message "/b_zero" [int nid]
+b_zero nid = Message "/b_zero" [Int nid]
 
 -- * Control bus commands.
 
 -- |  Fill ranges of bus values.
 c_fill :: [(Int, Int, Double)] -> OSC
-c_fill l = message "/c_fill" (mkTriples int int float l)
+c_fill l = Message "/c_fill" (mk_triples Int Int Float l)
 
 -- | Get bus values.
 c_get :: [Int] -> OSC
-c_get nid = message "/c_get" (map int nid)
+c_get nid = Message "/c_get" (map Int nid)
 
 -- | Get ranges of bus values.
 c_getn :: [(Int, Int)] -> OSC
-c_getn l = message "/c_getn" (mkDuples int int l)
+c_getn l = Message "/c_getn" (mk_duples Int Int l)
 
 -- | Set bus values.
 c_set :: [(Int, Double)] -> OSC
-c_set l = message "/c_set" (mkDuples int float l)
+c_set l = Message "/c_set" (mk_duples Int Float l)
 
 -- | Set ranges of bus values.
 c_setn :: [(Int, [Double])] -> OSC
-c_setn l = message "/c_setn" (concatMap f l)
-    where f (i,d) = int i : int (length d) : map float d
+c_setn l = Message "/c_setn" (concatMap f l)
+    where f (i,d) = Int i : Int (length d) : map Float d
 
 -- * Server operation commands.
 
 -- | Remove all bundles from the scheduling queue.
 clearSched :: OSC
-clearSched = message "/clearSched" []
+clearSched = Message "/clearSched" []
 
 -- | Enumeration of OSC printer types.
 data PrintLevel = NoPrinter
@@ -220,23 +220,23 @@
 
 -- | Select printing of incoming Open Sound Control messages.
 dumpOSC :: PrintLevel -> OSC
-dumpOSC c = message "/dumpOSC" [int (fromEnum c)]
+dumpOSC c = Message "/dumpOSC" [Int (fromEnum c)]
 
 -- | Select reception of notification messages. (Asynchronous)
 notify :: Bool -> OSC
-notify c = message "/notify" [int (fromEnum c)]
+notify c = Message "/notify" [Int (fromEnum c)]
 
 -- | Stop synthesis server.
 quit :: OSC
-quit = message "/quit" []
+quit = Message "/quit" []
 
 -- | Request \/status.reply message.
 status :: OSC
-status = message "/status" []
+status = Message "/status" []
 
--- | Request \/synced message when all current asynchronous commands complete.
+-- | Request \/synced Message when all current asynchronous commands complete.
 sync :: Int -> OSC
-sync sid = message "/sync" [int sid]
+sync sid = Message "/sync" [Int sid]
 
 -- * Variants to simplify common cases.
 
@@ -247,6 +247,14 @@
 -- | Set a range of sample values.
 b_setn1 :: Int -> Int -> [Double] -> OSC
 b_setn1 nid i xs = b_setn nid [(i,xs)]
+
+-- | Set single bus values.
+c_set1 :: Int -> Double -> OSC
+c_set1 i x = c_set [(i, x)]
+
+-- | Set a signle node control value.
+n_set1 :: Int -> String -> Double -> OSC
+n_set1 nid k n = n_set nid [(k, n)]
 
 -- Local Variables:
 -- truncate-lines:t
diff --git a/Sound/SC3/Server/NRT.hs b/Sound/SC3/Server/NRT.hs
--- a/Sound/SC3/Server/NRT.hs
+++ b/Sound/SC3/Server/NRT.hs
@@ -1,13 +1,13 @@
 module Sound.SC3.Server.NRT ( encodeNRT 
                             , writeNRT ) where
 
-import Sound.OpenSoundControl
 import qualified Data.ByteString.Lazy as B
+import Sound.OpenSoundControl
 
 -- | Encode and prefix with encoded length.
 oscWithSize :: OSC -> B.ByteString
 oscWithSize o = B.append l b
-    where b = encodeOSC_NTP o
+    where b = encodeOSCNTP o
           l = encode_i32 (fromIntegral (B.length b))
 
 -- | Encode a list of OSC bundles as an NRT score.
diff --git a/Sound/SC3/Server/Play.hs b/Sound/SC3/Server/Play.hs
--- a/Sound/SC3/Server/Play.hs
+++ b/Sound/SC3/Server/Play.hs
@@ -2,9 +2,9 @@
                              , withSC3, audition ) where
 
 import Sound.OpenSoundControl
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.Server.Synthdef
 import Sound.SC3.Server.Command
+import Sound.SC3.Server.Synthdef
+import Sound.SC3.UGen.UGen
 
 -- | Construct an instrument definition, send /d_recv and /s_new
 -- | messages to scsynth.
diff --git a/Sound/SC3/Server/Status.hs b/Sound/SC3/Server/Status.hs
--- a/Sound/SC3/Server/Status.hs
+++ b/Sound/SC3/Server/Status.hs
@@ -1,10 +1,36 @@
-module Sound.SC3.Server.Status (serverStatus) where
+module Sound.SC3.Server.Status ( serverStatus
+                               , serverSampleRateNominal
+                               , serverSampleRateActual ) where
 
+import Control.Monad
 import Sound.OpenSoundControl
-import Sound.SC3.Server.Command (status)
+import Sound.SC3.Server.Command
 
+-- | Collect server status information.
+serverStatus :: Transport t => t -> IO [String]
+serverStatus fd = liftM statusFormat (serverStatusData fd)
+
+-- | Read nominal sample rate of server.
+serverSampleRateNominal :: (Transport t) => t -> IO Double
+serverSampleRateNominal fd = liftM (extractDouble . (!! 7)) (serverStatusData fd)
+
+-- | Read actual sample rate of server.
+serverSampleRateActual :: (Transport t) => t -> IO Double
+serverSampleRateActual fd = liftM (extractDouble . (!! 8)) (serverStatusData fd)
+
+extractDouble :: Datum -> Double
+extractDouble (Float f) = f
+extractDouble (Double f) = f
+extractDouble _ = error "extractDouble"
+
+serverStatusData :: Transport t => t -> IO [Datum]
+serverStatusData fd = do send fd status 
+                         (Message _ d) <- wait fd "status.reply"
+                         return d
+
 statusFields :: [String]
-statusFields = ["# UGens                     ", 
+statusFields = ["Unused                      ",
+                "# UGens                     ", 
                 "# Synths                    ", 
                 "# Groups                    ",
                 "# Instruments               ",
@@ -13,18 +39,8 @@
                 "Sample Rate (Nominal)       ",
                 "Sample Rate (Actual)        "]
 
-statusInfo :: OSC -> [String]
-statusInfo o = maybe [] f (address o)
-    where f a = if a == "status.reply" 
-                then maybe [] (map show . tail) (arguments o) 
-                else []
-
-statusFormat :: OSC -> [String]
-statusFormat r = s : zipWith (++) statusFields (statusInfo r)
+statusFormat :: [Datum] -> [String]
+statusFormat d = s : zipWith (++) 
+                             (tail statusFields) 
+                             (map show (tail d))
     where s = "***** SuperCollider Server Status *****"
-
--- | Collect server status information.
-serverStatus :: Transport t => t -> IO [String]
-serverStatus fd = do send fd status 
-                     r <- wait fd "status.reply"
-                     return (statusFormat r)
diff --git a/Sound/SC3/Server/Synthdef.hs b/Sound/SC3/Server/Synthdef.hs
--- a/Sound/SC3/Server/Synthdef.hs
+++ b/Sound/SC3/Server/Synthdef.hs
@@ -2,16 +2,18 @@
                                   , synth, synthdef ) where
 
 import qualified Data.ByteString.Lazy as B
+import qualified Data.Char as C
 import qualified Data.IntMap as M
-import Data.Char (ord)
 import Data.List
 import Data.Word
-import Sound.OpenSoundControl.Byte
+import Sound.OpenSoundControl
 import Sound.SC3.UGen.UGen
-import Sound.SC3.UGen.UGen.Predicate
 import Sound.SC3.UGen.Rate
 
+-- | Node identifier.
 type NodeId = Int
+
+-- | Port index.
 type PortIndex = Int
 
 -- | Type to represent unit generator graph.
@@ -26,11 +28,11 @@
                   , node_c_value :: Double }
           | NodeK { node_id :: NodeId
                   , node_k_rate :: Rate
-                  , node_k_name :: Name
+                  , node_k_name :: String
                   , node_k_default :: Double }
           | NodeU { node_id :: NodeId
                   , node_u_rate :: Rate
-                  , node_u_name :: Name
+                  , node_u_name :: String
                   , node_u_inputs :: [FromPort]
                   , node_u_outputs :: [Output]
                   , node_u_special :: Special
@@ -47,6 +49,19 @@
               | U NodeId PortIndex
                 deriving (Eq, Show)
 
+-- | Transform a unit generator into a graph.
+synth :: UGen -> Graph
+synth u = let (_, g) = mk_node (prepare_root u) empty_graph
+              (Graph _ cs ks us) = g
+              us' = if null ks 
+                    then reverse us
+                    else implicit (length ks) : reverse us
+          in Graph (-1) cs ks us'
+
+-- | Transform a unit generator into bytecode.
+synthdef :: String -> UGen -> [Word8]
+synthdef s u = B.unpack (encode_graphdef s (synth u))
+
 as_from_port :: Node -> FromPort
 as_from_port (NodeC n _) = C n
 as_from_port (NodeK n _ _ _) = K n
@@ -76,12 +91,12 @@
 mk_node_c _ _ = error "mk_node_c"
 
 -- Predicate to locate control, names must be unique.
-find_k_p :: Name -> Node -> Bool
+find_k_p :: String -> Node -> Bool
 find_k_p x (NodeK _ _ y _) = x == y
 find_k_p _ _ = error "find_k_p"
 
 -- Insert a control node into the graph.
-push_k :: (Rate, Name, Double) -> Graph -> (Node, Graph)
+push_k :: (Rate, String, Double) -> Graph -> (Node, Graph)
 push_k (r, nm, d) g =
     let n = NodeK (nextId g) r nm d
     in (n, g { controls = n : controls g
@@ -99,7 +114,7 @@
 acc (x:xs) ys g = let (y, g') = mk_node x g
                   in acc xs (y:ys) g'
 
-type UGenParts = (Rate, Name, [FromPort], [Output], Special, Maybe UGenId)
+type UGenParts = (Rate, String, [FromPort], [Output], Special, Maybe UGenId)
 
 -- Predicate to locate primitive, names must be unique.
 find_u_p :: UGenParts -> Node -> Bool
@@ -138,6 +153,7 @@
                   in mk_node_p n (proxyIndex u) g'
     | isMRG u = let (_, g') = mk_node (mrgRight u) g
                 in mk_node (mrgLeft u) g'
+    | isMCE u = error "mk_node: mce"
     | otherwise = error "mk_node"
 
 type Map = M.IntMap Int
@@ -148,7 +164,7 @@
 mk_maps (Graph _ cs ks us) = 
     ( M.fromList (zip (map node_id cs) [0..])
     , M.fromList (zip (map node_id ks) [0..])
-    , M.fromList (zip (map node_id (us)) [0..]) )
+    , M.fromList (zip (map node_id us) [0..]) )
 
 -- Locate index in map give node identifer.
 fetch :: NodeId -> Map -> Int
@@ -167,10 +183,6 @@
 encode_input :: Input -> B.ByteString
 encode_input (Input u p) = B.append (encode_i16 u) (encode_i16 p)
 
--- Pascal strings are length prefixed byte strings.
-str_pstr :: String -> [Word8]
-str_pstr s = (fromIntegral (length s)) : map (fromIntegral . ord) s
-
 -- Byte-encode control node.
 encode_node_k :: Maps -> Node -> B.ByteString
 encode_node_k (_, ks, _) (NodeK n _ nm _) =
@@ -221,16 +233,3 @@
     | isMCE u = mrg (mceProxies u)
     | isMRG u = MRG (prepare_root (mrgLeft u)) (prepare_root (mrgRight u))
     | otherwise = u
-
--- | Transform a unit generator into a graph.
-synth :: UGen -> Graph
-synth u = let (_, g) = mk_node (prepare_root u) empty_graph
-              (Graph _ cs ks us) = g
-              us' = if null ks 
-                    then reverse us
-                    else implicit (length ks) : reverse us
-          in Graph (-1) cs ks us'
-
--- | Transform a unit generator into bytecode.
-synthdef :: String -> UGen -> [Word8]
-synthdef s u = B.unpack (encode_graphdef s (synth u))
diff --git a/Sound/SC3/Server/Utilities.hs b/Sound/SC3/Server/Utilities.hs
--- a/Sound/SC3/Server/Utilities.hs
+++ b/Sound/SC3/Server/Utilities.hs
@@ -1,8 +1,8 @@
 module Sound.SC3.Server.Utilities where
 
-mkDuples :: (a -> c) -> (b -> c) -> [(a, b)] -> [c]
-mkDuples a b = concatMap (\(x,y) -> [a x, b y])
+mk_duples :: (a -> c) -> (b -> c) -> [(a, b)] -> [c]
+mk_duples a b = concatMap (\(x,y) -> [a x, b y])
 
-mkTriples :: (a -> d) -> (b -> d) -> (c -> d) -> [(a, b, c)] -> [d]
-mkTriples a b c = concatMap (\(x,y,z) -> [a x, b y, c z])
+mk_triples :: (a -> d) -> (b -> d) -> (c -> d) -> [(a, b, c)] -> [d]
+mk_triples a b c = concatMap (\(x,y,z) -> [a x, b y, c z])
 
diff --git a/Sound/SC3/UGen.hs b/Sound/SC3/UGen.hs
--- a/Sound/SC3/UGen.hs
+++ b/Sound/SC3/UGen.hs
@@ -7,6 +7,9 @@
                        module Sound.SC3.UGen.Envelope,
                        module Sound.SC3.UGen.Envelope.Construct,
                        module Sound.SC3.UGen.Enum,
+                       module Sound.SC3.UGen.External,
+                       module Sound.SC3.UGen.External.ATS,
+                       module Sound.SC3.UGen.External.LPC,
                        module Sound.SC3.UGen.FFT,
                        module Sound.SC3.UGen.FFT.Monadic,
                        module Sound.SC3.UGen.Filter,
@@ -21,10 +24,6 @@
                        module Sound.SC3.UGen.Panner,
                        module Sound.SC3.UGen.Rate,
                        module Sound.SC3.UGen.UGen,
-                       module Sound.SC3.UGen.UGen.Construct,
-                       module Sound.SC3.UGen.UGen.Math,
-                       module Sound.SC3.UGen.UGen.MCE,
-                       module Sound.SC3.UGen.UGen.Predicate,
                        module Sound.SC3.UGen.UId) where
 
 import Sound.SC3.UGen.Analysis
@@ -36,6 +35,9 @@
 import Sound.SC3.UGen.Envelope
 import Sound.SC3.UGen.Envelope.Construct
 import Sound.SC3.UGen.Enum
+import Sound.SC3.UGen.External
+import Sound.SC3.UGen.External.ATS
+import Sound.SC3.UGen.External.LPC
 import Sound.SC3.UGen.FFT
 import Sound.SC3.UGen.FFT.Monadic
 import Sound.SC3.UGen.Filter
@@ -50,8 +52,4 @@
 import Sound.SC3.UGen.Panner
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.UGen
-import Sound.SC3.UGen.UGen.Construct
-import Sound.SC3.UGen.UGen.Math
-import Sound.SC3.UGen.UGen.MCE
-import Sound.SC3.UGen.UGen.Predicate
 import Sound.SC3.UGen.UId
diff --git a/Sound/SC3/UGen/Analysis.hs b/Sound/SC3/UGen/Analysis.hs
--- a/Sound/SC3/UGen/Analysis.hs
+++ b/Sound/SC3/UGen/Analysis.hs
@@ -1,8 +1,7 @@
 module Sound.SC3.UGen.Analysis where
 
-import Sound.SC3.UGen.Rate (Rate(KR))
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct (mkFilter, mkOsc)
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
 
 -- | Amplitude follower.
 amplitude :: Rate -> UGen -> UGen -> UGen -> UGen
diff --git a/Sound/SC3/UGen/Buffer.hs b/Sound/SC3/UGen/Buffer.hs
--- a/Sound/SC3/UGen/Buffer.hs
+++ b/Sound/SC3/UGen/Buffer.hs
@@ -1,10 +1,9 @@
 module Sound.SC3.UGen.Buffer where
 
-import Sound.SC3.UGen.Rate (Rate(AR))
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct (mkFilter, mkFilterMCE, mkOsc, mkOscMCE)
-import Sound.SC3.UGen.Enum (Loop, Interpolation(..))
-import Sound.SC3.UGen.Utilities (fromLoop, fromInterpolation)
+import Sound.SC3.UGen.Enum
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.Utilities
 
 -- * Buffer query UGens.
 
@@ -36,45 +35,45 @@
 
 -- | Allpass filter (cubic interpolation).
 bufAllpassC :: UGen -> UGen -> UGen -> UGen -> UGen
-bufAllpassC buf i dly dcy = mkFilter "BufAllpassC" [buf,i,dly,dcy] 1
+bufAllpassC buf i dly dcy = mkFilter "BufAllpassC" [buf, i, dly, dcy] 1
 
 -- | Allpass filter (linear interpolation).
 bufAllpassL :: UGen -> UGen -> UGen -> UGen -> UGen
-bufAllpassL buf i dly dcy = mkFilter "BufAllpassL" [buf,i,dly,dcy] 1
+bufAllpassL buf i dly dcy = mkFilter "BufAllpassL" [buf, i, dly, dcy] 1
 
 -- | Allpass filter (no interpolation).
 bufAllpassN :: UGen -> UGen -> UGen -> UGen -> UGen
-bufAllpassN buf i dly dcy = mkFilter "BufAllpassN" [buf,i,dly,dcy] 1
+bufAllpassN buf i dly dcy = mkFilter "BufAllpassN" [buf, i, dly, dcy] 1
 
 -- | Comb filter (cubic interpolation).
 bufCombC :: UGen -> UGen -> UGen -> UGen -> UGen
-bufCombC buf i dly dcy = mkFilter "BufCombC" [buf,i,dly,dcy] 1
+bufCombC buf i dly dcy = mkFilter "BufCombC" [buf, i, dly, dcy] 1
 
 -- | Comb filter (linear interpolation).
 bufCombL :: UGen -> UGen -> UGen -> UGen -> UGen
-bufCombL buf i dly dcy = mkFilter "BufCombL" [buf,i,dly,dcy] 1
+bufCombL buf i dly dcy = mkFilter "BufCombL" [buf, i, dly, dcy] 1
 
 -- | Comb filter (no interpolation).
 bufCombN :: UGen -> UGen -> UGen -> UGen -> UGen
-bufCombN buf i dly dcy = mkFilter "BufCombN" [buf,i,dly,dcy] 1
+bufCombN buf i dly dcy = mkFilter "BufCombN" [buf, i, dly, dcy] 1
 
 -- | Delay line (cubic interpolation).
 bufDelayC :: UGen -> UGen -> UGen -> UGen
-bufDelayC buf i dly = mkFilter "BufDelayC" [buf,i,dly] 1
+bufDelayC buf i dly = mkFilter "BufDelayC" [buf, i, dly] 1
 
 -- | Delay line (linear interpolation).
 bufDelayL :: UGen -> UGen -> UGen -> UGen
-bufDelayL buf i dly = mkFilter "BufDelayL" [buf,i,dly] 1
+bufDelayL buf i dly = mkFilter "BufDelayL" [buf, i, dly] 1
 
 -- | Delay line (no interpolation).
 bufDelayN :: UGen -> UGen -> UGen -> UGen
-bufDelayN buf i dly = mkFilter "BufDelayN" [buf,i,dly] 1
+bufDelayN buf i dly = mkFilter "BufDelayN" [buf, i, dly] 1
 
 -- * Buffer I\/O.
 
 -- | Buffer reader.
 bufRd :: Int -> Rate -> UGen -> UGen -> Loop -> Interpolation -> UGen
-bufRd n r buf phs lp intp = mkOsc r "BufRd" [buf,phs,fromLoop lp,fromInterpolation intp] n
+bufRd n r buf phs lp intp = mkOsc r "BufRd" [buf, phs, from_loop lp, from_interpolation intp] n
 
 -- | Buffer reader (no interpolation).
 bufRdN :: Int -> Rate -> UGen -> UGen -> Loop -> UGen
@@ -90,7 +89,7 @@
 
 -- | Buffer writer.
 bufWr :: UGen -> UGen -> Loop -> UGen -> UGen
-bufWr buf phs lp i = mkFilterMCE "BufWr" [buf,phs,fromLoop lp] i 0
+bufWr buf phs lp i = mkFilterMCE "BufWr" [buf, phs, from_loop lp] i 0
 
 -- | Search a buffer for a value.
 detectIndex :: UGen -> UGen -> UGen
@@ -110,15 +109,15 @@
 
 -- | Buffer playback.
 playBuf :: Int -> UGen -> UGen -> UGen -> UGen -> Loop -> UGen
-playBuf n b r' t s l = mkOsc AR "PlayBuf" [b,r',t,s,fromLoop l] n
+playBuf n b r t s l = mkOsc AR "PlayBuf" [b, r, t, s, from_loop l] n
 
 -- | Buffer recording.
 recordBuf :: UGen -> UGen -> UGen -> UGen -> UGen -> Loop -> UGen -> UGen -> UGen
-recordBuf b o rl pl r l t i = mkOscMCE AR "RecordBuf" [b, o, rl, pl, r, fromLoop l, t] i 0
+recordBuf b o rl pl r l t i = mkOscMCE AR "RecordBuf" [b, o, rl, pl, r, from_loop l, t] i 0
 
 -- | Triggered buffer shuffler (grain generator).
 tGrains :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-tGrains n t b r c d p a i = mkFilter "TGrains" [t,b,r,c,d,p,a,i] n
+tGrains n t b r c d p a i = mkFilter "TGrains" [t, b, r, c, d, p, a, i] n
 
 -- | Three variable wavetable oscillator.
 vOsc3 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
diff --git a/Sound/SC3/UGen/Chaos.hs b/Sound/SC3/UGen/Chaos.hs
--- a/Sound/SC3/UGen/Chaos.hs
+++ b/Sound/SC3/UGen/Chaos.hs
@@ -1,8 +1,7 @@
 module Sound.SC3.UGen.Chaos where
 
-import Sound.SC3.UGen.Rate (Rate)
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct (mkOsc)
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
 
 -- | Chaotic noise.
 crackle :: Rate -> UGen -> UGen
diff --git a/Sound/SC3/UGen/Composite.hs b/Sound/SC3/UGen/Composite.hs
--- a/Sound/SC3/UGen/Composite.hs
+++ b/Sound/SC3/UGen/Composite.hs
@@ -1,14 +1,34 @@
 module Sound.SC3.UGen.Composite where
 
+import Sound.SC3.UGen.Demand.Monadic
 import Sound.SC3.UGen.Filter
+import Sound.SC3.UGen.Information
+import Sound.SC3.UGen.IO
 import Sound.SC3.UGen.Oscillator
+import Sound.SC3.UGen.Noise.Monadic
 import Sound.SC3.UGen.Panner
 import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.UGen (UGen, mce, mceProxies)
-import Sound.SC3.UGen.UGen.Math ()
-import Sound.SC3.UGen.UGen.MCE
-import Sound.SC3.UGen.UGen.Predicate
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UId
 
+-- | Demand rate (:) function.
+dcons :: (UId m) => UGen -> UGen -> m UGen
+dcons x xs = do i <- dseq 1 (mce2 0 1)
+                a <- dseq 1 (mce2 x xs)
+                dswitch i a
+
+-- | Dynamic klank, set of non-fixed resonating filters.
+dynKlank :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dynKlank i fs fo ds s = gen (mceChannels s)
+    where gen (f:a:d:xs) = ringz i (f * fs + fo) (d * ds) * a + gen xs
+          gen _ = 0
+
+-- | Frequency shifter, in terms of Hilbert UGen.
+freqShift :: UGen -> UGen -> UGen -> UGen
+freqShift i f p = mix (h * o)
+    where o = sinOsc AR f (mce [p + 0.5 * pi, p])
+          h = hilbert i
+
 -- | Collapse multiple channel expansion by summing.
 mix :: UGen -> UGen
 mix u | isMCE u = sum (mceProxies u)
@@ -22,12 +42,14 @@
 mixFillM :: (Monad m) => Int -> (Int -> m UGen) -> m UGen
 mixFillM n f = mapM f [0 .. n - 1] >>= return . sum
 
--- | Frequency shifter, in terms of Hilbert UGen.
-freqShift :: UGen -> UGen -> UGen -> UGen
-freqShift i f p = mix (h * o)
-    where o = sinOsc AR f (mce [p + 0.5 * pi, p])
-          h = hilbert i
+-- | PM oscillator.
+pmOsc :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+pmOsc r cf mf pm mp = sinOsc r cf (sinOsc r mf mp * pm)
 
+-- | Zero indexed audio input buses.
+soundIn :: UGen -> UGen
+soundIn n = in' 1 AR (numOutputBuses + n)
+
 -- | Pan a set of channels across the stereo field.
 splay :: UGen -> UGen -> UGen -> UGen -> UGen
 splay i s l c = mix (pan2 i (mce p * s + c) 1) * l * (sqrt (1 / n))
@@ -35,12 +57,10 @@
           m = n - 1
           p = map ( (+ (-1.0)) . (* (2 / m)) ) [0 .. m]
 
--- | Dynamic klank, set of non-fixed resonating filters.
-dynKlank :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-dynKlank i fs fo ds s = gen (mceChannels s)
-    where gen (f:a:d:xs) = ringz i (f * fs + fo) (d * ds) * a + gen xs
-          gen _ = 0
+tChoose :: (UId m) => UGen -> UGen -> m UGen
+tChoose t a = do r <- tiRand 0 (constant (length (mceChannels a))) t
+                 return (select r a)
 
--- | PM oscillator.
-pmOsc :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
-pmOsc r cf mf pm mp = sinOsc r cf (sinOsc r mf mp * pm)
+twChoose :: (UId m) => UGen -> UGen -> UGen -> UGen -> m UGen
+twChoose t a w n = do i <- twindex t n w
+                      return (select i a)
diff --git a/Sound/SC3/UGen/Demand.hs b/Sound/SC3/UGen/Demand.hs
--- a/Sound/SC3/UGen/Demand.hs
+++ b/Sound/SC3/UGen/Demand.hs
@@ -1,11 +1,9 @@
 module Sound.SC3.UGen.Demand where
 
-import Sound.SC3.UGen.Rate (Rate)
-import Sound.SC3.UGen.UGen (UGen(Constant))
-import Sound.SC3.UGen.UGen.Construct (mkOsc, mkOscMCE, mkFilterKeyed)
-import Sound.SC3.UGen.UGen.MCE (mceChannels)
-import Sound.SC3.UGen.Enum (DoneAction)
-import Sound.SC3.UGen.Utilities (fromDoneAction)
+import Sound.SC3.UGen.Enum
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.Utilities
 
 -- | Infinte repeat counter for demand rate unit generators.
 dinf :: UGen
@@ -18,12 +16,16 @@
 
 -- | Demand envlope generator.
 demandEnvGen :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> DoneAction -> UGen
-demandEnvGen r l d s c g rst ls lb ts a = mkOsc r "DemandEnvGen" [l,d,s,c,g,rst,ls,lb,ts,fromDoneAction a] 1
+demandEnvGen r l d s c g rst ls lb ts a = mkOsc r "DemandEnvGen" [l, d, s, c, g, rst, ls, lb, ts, from_done_action a] 1
 
 -- | Demand results from demand rate ugens.
 duty :: Rate -> UGen -> UGen -> DoneAction -> UGen -> UGen
-duty rate d r act l = mkOsc rate "Duty" [d, r, fromDoneAction act, l] 1
+duty rate d r act l = mkOsc rate "Duty" [d, r, from_done_action act, l] 1
 
 -- | Demand results as trigger from demand rate ugens.
-tDuty :: Rate -> UGen -> UGen -> DoneAction -> UGen -> UGen
-tDuty r d rst act l = mkOscMCE r "TDuty" [d,rst,fromDoneAction act] l 1
+tDuty :: Rate -> UGen -> UGen -> DoneAction -> UGen -> UGen -> UGen
+tDuty r d rst act l gap = mkOsc r "TDuty" [d, rst, from_done_action act, l, gap] 1
+
+-- Local Variables:
+-- truncate-lines:t
+-- End:
diff --git a/Sound/SC3/UGen/Demand/Base.hs b/Sound/SC3/UGen/Demand/Base.hs
--- a/Sound/SC3/UGen/Demand/Base.hs
+++ b/Sound/SC3/UGen/Demand/Base.hs
@@ -1,18 +1,17 @@
 module Sound.SC3.UGen.Demand.Base where
 
-import Sound.SC3.UGen.Rate (Rate(DR))
-import Sound.SC3.UGen.UGen (UGen, UGenId)
-import Sound.SC3.UGen.UGen.Construct (mkOscId, mkOscMCEId)
 import Sound.SC3.UGen.Enum
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
 import Sound.SC3.UGen.Utilities
 
 -- | Buffer demand ugen.
 dbufrd :: UGenId -> UGen -> UGen -> Loop -> UGen
-dbufrd z b p l = mkOscId z DR "Dbufrd" [b, p, fromLoop l] 1
+dbufrd z b p l = mkOscId z DR "Dbufrd" [b, p, from_loop l] 1
 
 -- | Buffer write on demand unit generator.
 dbufwr :: UGenId -> UGen -> UGen -> UGen -> Loop -> UGen
-dbufwr z b p i l = mkOscId z DR "Dbufwr" [b, p, i, fromLoop l] 1
+dbufwr z b p i l = mkOscId z DR "Dbufwr" [b, p, i, from_loop l] 1
 
 -- | Demand rate white noise.
 dwhite :: UGenId -> UGen -> UGen -> UGen -> UGen
@@ -57,3 +56,7 @@
 -- | Demand rate input switching.
 dswitch1 :: UGenId -> UGen -> UGen -> UGen
 dswitch1 z l array = mkOscMCEId z DR "Dswitch1" [l] array 1
+
+-- | Demand rate input switching.
+dswitch :: UGenId -> UGen -> UGen -> UGen
+dswitch z l array = mkOscMCEId z DR "Dswitch" [l] array 1
diff --git a/Sound/SC3/UGen/Demand/Monadic.hs b/Sound/SC3/UGen/Demand/Monadic.hs
--- a/Sound/SC3/UGen/Demand/Monadic.hs
+++ b/Sound/SC3/UGen/Demand/Monadic.hs
@@ -1,7 +1,7 @@
 module Sound.SC3.UGen.Demand.Monadic where
 
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UGen.Lift
 import qualified Sound.SC3.UGen.Demand.Base as D
 import Sound.SC3.UGen.UId
 import Sound.SC3.UGen.Enum
@@ -57,3 +57,7 @@
 -- | Demand rate input switching.
 dswitch1 :: (UId m) => UGen -> UGen -> m UGen
 dswitch1 = liftU2 D.dswitch1
+
+-- | Demand rate input switching.
+dswitch :: (UId m) => UGen -> UGen -> m UGen
+dswitch = liftU2 D.dswitch
diff --git a/Sound/SC3/UGen/Demand/Unsafe.hs b/Sound/SC3/UGen/Demand/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/Demand/Unsafe.hs
@@ -0,0 +1,62 @@
+module Sound.SC3.UGen.Demand.Unsafe where
+
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UGen.Lift
+import qualified Sound.SC3.UGen.Demand.Monadic as D
+import Sound.SC3.UGen.Enum
+
+-- | Buffer demand ugen.
+dbufrd :: UGen -> UGen -> Loop -> UGen
+dbufrd = liftP3 D.dbufrd
+
+-- | Buffer write on demand unit generator.
+dbufwr :: UGen -> UGen -> UGen -> Loop -> UGen
+dbufwr = liftP4 D.dbufwr
+
+-- | Demand rate white noise.
+dwhite :: UGen -> UGen -> UGen -> UGen
+dwhite = liftP3 D.dwhite
+
+-- | Demand rate integer white noise.
+diwhite :: UGen -> UGen -> UGen -> UGen
+diwhite = liftP3 D.diwhite
+
+-- | Demand rate brown noise.
+dbrown :: UGen -> UGen -> UGen -> UGen -> UGen
+dbrown = liftP4 D.dbrown
+
+-- | Demand rate integer brown noise.
+dibrown :: UGen -> UGen -> UGen -> UGen -> UGen
+dibrown = liftP4 D.dibrown
+
+-- | Demand rate random selection.
+drand :: UGen -> UGen -> UGen
+drand = liftP2 D.drand
+
+-- | Demand rate random selection with no immediate repetition.
+dxrand :: UGen -> UGen -> UGen
+dxrand = liftP2 D.dxrand
+
+-- | Demand rate arithmetic series.
+dseries :: UGen -> UGen -> UGen -> UGen
+dseries = liftP3 D.dseries
+
+-- | Demand rate geometric series.
+dgeom :: UGen -> UGen -> UGen -> UGen
+dgeom = liftP3 D.dgeom
+
+-- | Demand rate sequence generator.
+dseq :: UGen -> UGen -> UGen
+dseq = liftP2 D.dseq
+
+-- | Demand rate series generator.
+dser :: UGen -> UGen -> UGen
+dser = liftP2 D.dser
+
+-- | Demand rate input switching.
+dswitch1 :: UGen -> UGen -> UGen
+dswitch1 = liftP2 D.dswitch1
+
+-- | Demand rate input switching.
+dswitch :: UGen -> UGen -> UGen
+dswitch = liftP2 D.dswitch
diff --git a/Sound/SC3/UGen/Enum.hs b/Sound/SC3/UGen/Enum.hs
--- a/Sound/SC3/UGen/Enum.hs
+++ b/Sound/SC3/UGen/Enum.hs
@@ -1,6 +1,6 @@
 module Sound.SC3.UGen.Enum where
 
-import Sound.SC3.UGen.UGen (UGen)
+import Sound.SC3.UGen.UGen
 
 -- | Loop indicator input.
 data Loop = Loop
diff --git a/Sound/SC3/UGen/Envelope.hs b/Sound/SC3/UGen/Envelope.hs
--- a/Sound/SC3/UGen/Envelope.hs
+++ b/Sound/SC3/UGen/Envelope.hs
@@ -1,23 +1,22 @@
 module Sound.SC3.UGen.Envelope where
 
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct (mkOsc, mkFilter)
-import Sound.SC3.UGen.Rate (Rate)
-import Sound.SC3.UGen.Enum (DoneAction)
-import Sound.SC3.UGen.Utilities (fromDoneAction)
+import Sound.SC3.UGen.Enum
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.Utilities
 
 -- | Segment based envelope generator.
 envGen :: Rate -> UGen -> UGen -> UGen -> UGen -> DoneAction -> [UGen] -> UGen
 envGen r gate lvl bias scale act pts = mkOsc r "EnvGen" i 1
- where i = [gate, lvl, bias, scale, fromDoneAction act] ++ pts
+ where i = [gate, lvl, bias, scale, from_done_action act] ++ pts
 
 -- | Line generator.
 line :: Rate -> UGen -> UGen -> UGen -> DoneAction -> UGen
-line r start end dur act = mkOsc r "Line" [start, end, dur, fromDoneAction act] 1
+line r start end dur act = mkOsc r "Line" [start, end, dur, from_done_action act] 1
 
 -- | Exponential line generator.
 xLine :: Rate -> UGen -> UGen -> UGen -> DoneAction -> UGen
-xLine r start end dur act = mkOsc r "XLine" [start, end, dur, fromDoneAction act] 1
+xLine r start end dur act = mkOsc r "XLine" [start, end, dur, from_done_action act] 1
 
 -- | Free node on trigger.
 freeSelf :: UGen -> UGen
@@ -45,7 +44,7 @@
 
 -- | Raise specified done action when input goes silent.
 detectSilence ::  UGen -> UGen -> UGen -> DoneAction -> UGen
-detectSilence i a t act = mkFilter "DetectSilence" [i, a, t, fromDoneAction act] 0
+detectSilence i a t act = mkFilter "DetectSilence" [i, a, t, from_done_action act] 0
 
 -- | When triggered free specified node.
 free :: UGen -> UGen -> UGen
@@ -53,5 +52,4 @@
 
 -- | Linear envelope generator.
 linen :: UGen -> UGen -> UGen -> UGen -> DoneAction -> UGen
-linen g at sl rt da = mkFilter "Linen" [g,at,sl,rt,fromDoneAction da] 1
-
+linen g at sl rt da = mkFilter "Linen" [g, at, sl, rt, from_done_action da] 1
diff --git a/Sound/SC3/UGen/Envelope/Construct.hs b/Sound/SC3/UGen/Envelope/Construct.hs
--- a/Sound/SC3/UGen/Envelope/Construct.hs
+++ b/Sound/SC3/UGen/Envelope/Construct.hs
@@ -1,10 +1,9 @@
 module Sound.SC3.UGen.Envelope.Construct where
 
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Math ()
-import Sound.SC3.UGen.Math ((>=*), (<=*))
-import Sound.SC3.UGen.Enum (EnvCurve(..))
-import Sound.SC3.UGen.Utilities (dbl, d_dx, env_curve, env_value)
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.Math
+import Sound.SC3.UGen.Enum
+import Sound.SC3.UGen.Utilities
 
 -- | Basic envelope data constructor.
 env :: [UGen] -> [UGen] -> [EnvCurve] -> UGen -> UGen -> [UGen]
diff --git a/Sound/SC3/UGen/External.hs b/Sound/SC3/UGen/External.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/External.hs
@@ -0,0 +1,68 @@
+module Sound.SC3.UGen.External where
+
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
+
+-- | Resynthesize sinusoidal ATS analysis data.
+atsSynth :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+atsSynth b np ps pk fp m a = mkOsc AR "AtsSynth" [b, np, ps, pk, fp, m, a] 1
+
+-- | Resynthesize sinusoidal and critical noise ATS analysis data.
+atsNoiSynth :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+atsNoiSynth b np ps pk fp sr nr m a nb bs bk = mkOsc AR "AtsNoiSynth" [b, np, ps, pk, fp, sr, nr, m, a, nb, bs, bk] 1
+
+-- | Emulation of AY (aka YM) soundchip, used in Spectrum/Atari.
+ay :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+ay ta tb tc n c va vb vc ef es ct = mkOsc AR "AY" [ta, tb, tc, n, c, va, vb, vc, ef, es, ct] 1
+
+-- | Convert frequency value to value appropriate for AY tone inputs.
+ayFreqToTone :: Fractional a => a -> a
+ayFreqToTone f = 110300 / (f - 0.5)
+
+-- | Triangular waveguide mesh of a drum-like membrane.
+membraneCircle :: UGen -> UGen -> UGen -> UGen
+membraneCircle i t l = mkOsc AR "MembraneCircle" [i, t, l] 1
+
+-- | Triangular waveguide mesh of a drum-like membrane.
+membraneHexagon :: UGen -> UGen -> UGen -> UGen
+membraneHexagon i t l = mkOsc AR "MembraneHexagon" [i, t, l] 1
+
+-- | Extract cps, rmso and err signals from LPC data.
+lpcVals :: Rate -> UGen -> UGen -> UGen
+lpcVals r b ptr = mkOsc r "LPCVals" [b, ptr] 3
+
+-- | Resynthesize LPC analysis data.
+lpcSynth :: UGen -> UGen -> UGen -> UGen
+lpcSynth b s ptr = mkOsc AR "LPCSynth" [b, s, ptr] 1
+
+-- | Invert FFT amplitude data.
+pv_Invert :: UGen -> UGen
+pv_Invert b = mkOsc KR "PV_Invert" [b] 1
+
+-- | STK flute model.
+stkFlute :: Rate-> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkFlute rt f jd ng vf vg bp tr = mkOsc rt "StkFlute" [f, jd, ng, vf, vg, bp, tr] 1
+
+-- | STK modal bar models.
+stkModalBar :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkModalBar rt f i sh sp vg vf mx v tr = mkOsc rt "StkModalBar" [f, i, sh, sp, vg, vf, mx, v, tr] 1
+
+-- | STK bowed string model.
+stkBowed :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkBowed rt f pr po vf vg l g = mkOsc rt "StkBowed" [f, pr, po, vf, vg, l, g] 1
+
+-- | STK mandolin model.
+stkMandolin :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkMandolin rt f bs pp dm dt at tr = mkOsc rt "StkMandolin" [f, bs, pp, dm, dt, at, tr] 1 
+
+-- | STK shaker models.
+stkShakers :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkShakers rt i e d o rf tr = mkOsc rt "StkShakers" [i, e, d, o, rf, tr] 1
+
+-- | Vocal simulation due to W. Kaegi.
+vosim :: UGen -> UGen -> UGen -> UGen -> UGen
+vosim t f nc d = mkOsc AR "VOSIM" [t, f, nc, d] 1
+
+-- Local Variables:
+-- truncate-lines:t
+-- End:
diff --git a/Sound/SC3/UGen/External/ATS.hs b/Sound/SC3/UGen/External/ATS.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/External/ATS.hs
@@ -0,0 +1,97 @@
+module Sound.SC3.UGen.External.ATS ( ATS(..)
+                                   , ATSHeader(..)
+                                   , ATSFrame
+                                   , atsRead
+                                   , atsSC3 ) where
+
+import Control.Monad
+import qualified Data.ByteString.Lazy as B
+import Data.List
+import Sound.OpenSoundControl
+import System.IO
+
+-- | ATS analysis data.
+data ATS = ATS { atsHeader :: ATSHeader
+               , atsFrames :: [ATSFrame] }
+           deriving (Eq, Show)
+
+-- | ATS analysis meta-data.
+data ATSHeader = ATSHeader { atsSampleRate :: Double
+                           , atsFrameSize :: Int
+                           , atsWindowSize :: Int
+                           , atsNPartials :: Int
+                           , atsNFrames :: Int
+                           , atsMaxAmplitude :: Double
+                           , atsMaxFrequency :: Double
+                           , atsAnalysisDuration :: Double
+                           , atsFileType :: Int
+                           } deriving (Eq, Show)
+
+-- | ATS analysis frame data. 
+type ATSFrame = [Double]
+
+-- | Read an ATS data file.
+atsRead :: FilePath -> IO ATS
+atsRead fn = do
+  h <- openFile fn ReadMode
+  v <- B.hGet h 8
+  let reader = get_reader v
+  hdr_r <- replicateM 9 (reader h)
+  let f j = hdr_r !! (j - 1)
+      g = floor . f
+      ft = g 9
+      (n, x) = ftype_n ft
+      np = g 4
+      nf = g 5
+      fl = np * n + x
+      hdr = ATSHeader (f 1) (g 2) (g 3) np nf (f 6) (f 7) (f 8) ft
+      get_f = replicateM fl (reader h)
+  d <- replicateM nf get_f
+  hClose h
+  return (ATS hdr d)
+
+-- | Analysis data in format required by the sc3 ATS UGens.
+atsSC3 :: ATS -> [Double]
+atsSC3 (ATS h d) = 
+    let f = fromIntegral
+        td = transpose d
+    in ( f (atsFileType h) :
+         f (atsNPartials h) :
+         f (atsNFrames h) :
+         f (atsWindowSize h) :
+         concatMap (td !!) (atsSC3Indices h) )
+
+-- be
+read_f64 :: Handle -> IO Double
+read_f64 h = B.hGet h 8 >>= return . decode_f64
+
+-- le
+read_f64LE :: Handle -> IO Double
+read_f64LE h = B.hGet h 8 >>= return . decode_f64 . B.reverse
+
+-- Determine endianess and hence reader.
+get_reader :: B.ByteString -> (Handle -> IO Double)
+get_reader v = if decode_f64 v == 123.0
+               then read_f64
+               else read_f64LE
+
+-- Calculate partial depth and frame constant.
+ftype_n :: Int -> (Int, Int)
+ftype_n 1 = (2, 1)
+ftype_n 2 = (3, 1)
+ftype_n 3 = (2, 26)
+ftype_n 4 = (3, 26)
+ftype_n _ = undefined
+
+-- Indices for track data in the order required by sc3.
+atsSC3Indices :: ATSHeader -> [Int]
+atsSC3Indices h = 
+    let np = atsNPartials h
+        o = 3 * (np - 1)
+        a = [1,4 .. (1 + o)]
+        f = map (+ 1) a
+        p = map (+ 1) f
+        n = map (+ (4+o)) [0..24]
+    in if atsFileType h == 4
+       then a ++ f ++ p ++ n
+       else error "atsSC3Indices: illegal ATS file type (/= 4)"
diff --git a/Sound/SC3/UGen/External/LPC.hs b/Sound/SC3/UGen/External/LPC.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/External/LPC.hs
@@ -0,0 +1,61 @@
+module Sound.SC3.UGen.External.LPC ( LPC(..)
+                                   , LPCHeader(..)
+                                   , LPCFrame
+                                   , lpcRead
+                                   , lpcSC3 ) where
+
+import Control.Monad
+import qualified Data.ByteString.Lazy as B
+import Data.List
+import Sound.OpenSoundControl
+import System.IO
+
+-- | LPC analysis data.
+data LPC = LPC { lpcHeader :: LPCHeader
+               , lpcFrames :: [LPCFrame] }
+           deriving (Eq, Show)
+
+-- | LPC analysis meta-data.
+data LPCHeader = LPCHeader { lpcHeaderSize :: Int
+                           , lpcMagic :: Int
+                           , lpcNPoles :: Int
+                           , lpcFrameSize :: Int
+                           , lpcFrameRate :: Double
+                           , lpcSampleRate :: Double
+                           , lpcAnalysisDuration :: Double
+                           , lpcNFrames :: Int
+                           } deriving (Eq, Show)
+
+-- | LPC analysis frame data.
+type LPCFrame = [Double]
+
+-- | Read an lpanal format LPC data file.
+lpcRead :: FilePath -> IO LPC
+lpcRead fn = do
+  h <- openFile fn ReadMode
+  l <- hFileSize h
+  [hs, lm, np, fs] <- replicateM 4 (read_i32 h)
+  [fr, sr, fd] <- replicateM 3 (read_f32 h)
+  let nf = ((fromIntegral l - hs) `div` 4) `div` fs
+      hdr = LPCHeader hs lm np fs fr sr fd nf
+      hc = hs - (7 * 4)
+      get_f = replicateM fs (read_f32 h)
+  B.hGet h hc
+  d <- replicateM nf get_f
+  hClose h
+  return (LPC hdr d)
+
+-- | Analysis data in format required by the sc3 LPC UGens.
+lpcSC3 :: LPC -> [Double]
+lpcSC3 (LPC h d) = let f = fromIntegral
+                       np = f (lpcNPoles h)
+                       nf = f (lpcNFrames h)
+                       fs = f (lpcFrameSize h)
+                   in np : nf : fs : concat (transpose d)
+
+read_i32 :: Handle -> IO Int
+read_i32 h = B.hGet h 4 >>= return . decode_i32
+
+read_f32 :: Handle -> IO Double
+read_f32 h = B.hGet h 4 >>= return . decode_f32
+
diff --git a/Sound/SC3/UGen/FFT.hs b/Sound/SC3/UGen/FFT.hs
--- a/Sound/SC3/UGen/FFT.hs
+++ b/Sound/SC3/UGen/FFT.hs
@@ -1,10 +1,7 @@
 module Sound.SC3.UGen.FFT where
 
 import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.UGen (UGen, constant, mce)
-import Sound.SC3.UGen.UGen.Construct
-import Sound.SC3.UGen.UGen.Math ()
-import Sound.SC3.UGen.UGen.MCE
+import Sound.SC3.UGen.UGen
 
 -- | Fast fourier transform.
 fft :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
diff --git a/Sound/SC3/UGen/FFT/Base.hs b/Sound/SC3/UGen/FFT/Base.hs
--- a/Sound/SC3/UGen/FFT/Base.hs
+++ b/Sound/SC3/UGen/FFT/Base.hs
@@ -1,8 +1,7 @@
 module Sound.SC3.UGen.FFT.Base where
 
-import Sound.SC3.UGen.Rate (Rate(KR))
-import Sound.SC3.UGen.UGen (UGen, UGenId)
-import Sound.SC3.UGen.UGen.Construct (mkOscId)
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
 
 -- | Randomize order of bins.
 pv_BinScramble :: UGenId -> UGen -> UGen -> UGen -> UGen -> UGen
@@ -15,3 +14,7 @@
 -- | Cross fade, copying bins in random order.
 pv_RandWipe :: UGenId -> UGen -> UGen -> UGen -> UGen -> UGen
 pv_RandWipe z ba bb wp trg = mkOscId z KR "PV_RandWipe" [ba,bb,wp,trg] 1
+
+-- Local Variables:
+-- truncate-lines:t
+-- End:
diff --git a/Sound/SC3/UGen/FFT/Monadic.hs b/Sound/SC3/UGen/FFT/Monadic.hs
--- a/Sound/SC3/UGen/FFT/Monadic.hs
+++ b/Sound/SC3/UGen/FFT/Monadic.hs
@@ -1,7 +1,7 @@
 module Sound.SC3.UGen.FFT.Monadic where
 
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UGen.Lift
 import qualified Sound.SC3.UGen.FFT.Base as F
 import Sound.SC3.UGen.UId
 
diff --git a/Sound/SC3/UGen/FFT/Unsafe.hs b/Sound/SC3/UGen/FFT/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/FFT/Unsafe.hs
@@ -0,0 +1,17 @@
+module Sound.SC3.UGen.FFT.Unsafe where
+
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UGen.Lift
+import qualified Sound.SC3.UGen.FFT.Monadic as F
+
+-- | Randomize order of bins.
+pv_BinScramble :: UGen -> UGen -> UGen -> UGen -> UGen
+pv_BinScramble = liftP4 F.pv_BinScramble
+
+-- | Randomly clear bins.
+pv_RandComb :: UGen -> UGen -> UGen -> UGen
+pv_RandComb = liftP3 F.pv_RandComb
+
+-- | Cross fade, copying bins in random order.
+pv_RandWipe :: UGen -> UGen -> UGen -> UGen -> UGen
+pv_RandWipe = liftP4 F.pv_RandWipe
diff --git a/Sound/SC3/UGen/Filter.hs b/Sound/SC3/UGen/Filter.hs
--- a/Sound/SC3/UGen/Filter.hs
+++ b/Sound/SC3/UGen/Filter.hs
@@ -1,20 +1,19 @@
 module Sound.SC3.UGen.Filter where
 
-import Sound.SC3.UGen.UGen (UGen, mce)
-import Sound.SC3.UGen.UGen.Construct (mkFilter, mkFilterMCE)
-import Data.List (transpose)
+import Data.List
+import Sound.SC3.UGen.UGen
 
 -- | Allpass filter (no interpolation)
 allpassN :: UGen -> UGen -> UGen -> UGen -> UGen
-allpassN i maxTime dly dcy = mkFilter "AllpassN" [i, maxTime, dly, dcy] 1
+allpassN i mt dly dcy = mkFilter "AllpassN" [i, mt, dly, dcy] 1
 
 -- | Allpass filter (linear interpolation)
 allpassL :: UGen -> UGen -> UGen -> UGen -> UGen
-allpassL i maxTime dly dcy = mkFilter "AllpassL" [i, maxTime, dly, dcy] 1
+allpassL i mt dly dcy = mkFilter "AllpassL" [i, mt, dly, dcy] 1
 
 -- | Allpass filter (cubic interpolation)
 allpassC :: UGen -> UGen -> UGen -> UGen -> UGen
-allpassC i maxTime dly dcy = mkFilter "AllpassC" [i, maxTime, dly, dcy] 1
+allpassC i mt dly dcy = mkFilter "AllpassC" [i, mt, dly, dcy] 1
 
 -- | Basic psychoacoustic amplitude compensation.
 ampComp :: UGen -> UGen -> UGen -> UGen
@@ -26,7 +25,7 @@
 
 -- | Bandpass filter
 bpf :: UGen -> UGen -> UGen -> UGen
-bpf i freq rq = mkFilter "BPF" [i,freq,rq] 1
+bpf i freq rq = mkFilter "BPF" [i, freq, rq] 1
 
 -- | Two zero fixed midpass filter.
 bpz2 :: UGen -> UGen
@@ -34,7 +33,7 @@
 
 -- | Band reject filter
 brf :: UGen -> UGen -> UGen -> UGen
-brf i freq rq = mkFilter "BRF" [i,freq,rq] 1
+brf i freq rq = mkFilter "BRF" [i, freq, rq] 1
 
 -- | Two zero fixed midcut filter.
 brz2 :: UGen -> UGen
@@ -42,19 +41,19 @@
 
 -- | Clip input between lower and upper bounds.
 clip :: UGen -> UGen -> UGen -> UGen
-clip i l h = mkFilter "Clip" [i,l,h] 1
+clip i l h = mkFilter "Clip" [i, l, h] 1
 
 -- | Comb filter (no interpolation)
 combN :: UGen -> UGen -> UGen -> UGen -> UGen
-combN i maxTime dly dcy = mkFilter "CombN" [i, maxTime, dly, dcy] 1
+combN i mt dly dcy = mkFilter "CombN" [i, mt, dly, dcy] 1
 
 -- | Comb filter (linear interpolation)
 combL :: UGen -> UGen -> UGen -> UGen -> UGen
-combL i maxTime dly dcy = mkFilter "CombL" [i, maxTime, dly, dcy] 1
+combL i mt dly dcy = mkFilter "CombL" [i, mt, dly, dcy] 1
 
 -- | Comb filter (cubic interpolation)
 combC :: UGen -> UGen -> UGen -> UGen -> UGen
-combC i maxTime dly dcy = mkFilter "CombC" [i, maxTime, dly, dcy] 1
+combC i mt dly dcy = mkFilter "CombC" [i, mt, dly, dcy] 1
 
 -- | Convert signal to modal pitch.
 degreeToKey :: UGen -> UGen -> UGen -> UGen
@@ -62,11 +61,11 @@
 
 -- | Exponential decay.
 decay :: UGen -> UGen -> UGen
-decay i dcy = mkFilter "Decay" [i,dcy] 1
+decay i dcy = mkFilter "Decay" [i, dcy] 1
 
 -- | Exponential decay (equvalent to $decay dcy - decay atk$).
 decay2 :: UGen -> UGen -> UGen -> UGen
-decay2 i atk dcy = mkFilter "Decay2" [i,atk,dcy] 1
+decay2 i atk dcy = mkFilter "Decay2" [i, atk, dcy] 1
 
 -- | Single sample delay.
 delay1 :: UGen -> UGen
@@ -78,27 +77,35 @@
 
 -- | Simple delay line (cubic interpolation).
 delayC :: UGen -> UGen -> UGen -> UGen
-delayC i maxTime dly = mkFilter "DelayC" [i,maxTime,dly] 1
+delayC i mt dly = mkFilter "DelayC" [i, mt, dly] 1
 
 -- | Simple delay line (linear interpolation).
 delayL :: UGen -> UGen -> UGen -> UGen
-delayL i maxTime dly = mkFilter "DelayL" [i,maxTime,dly] 1
+delayL i mt dly = mkFilter "DelayL" [i, mt, dly] 1
 
 -- | Simple delay line (no interpolation).
 delayN :: UGen -> UGen -> UGen -> UGen
-delayN i maxTime dly = mkFilter "DelayN" [i,maxTime,dly] 1
+delayN i mt dly = mkFilter "DelayN" [i, mt, dly] 1
 
 -- | FOF like filter.
 formlet :: UGen -> UGen -> UGen -> UGen -> UGen
-formlet i f a d = mkFilter "Formlet" [i,f,a,d] 1
+formlet i f a d = mkFilter "Formlet" [i, f, a, d] 1
 
 -- | First order filter section.
 fos :: UGen -> UGen -> UGen -> UGen -> UGen
-fos i a0 a1 b1 = mkFilter "FOS" [i,a0,a1,b1] 1
+fos i a0 a1 b1 = mkFilter "FOS" [i, a0, a1, b1] 1
 
+-- | A simple reverb.
+freeVerb :: UGen -> UGen -> UGen -> UGen -> UGen
+freeVerb i mx room damp = mkFilter "FreeVerb" [i, mx, room, damp] 1
+
+-- | A simple reverb (two channel).
+freeVerb2 :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+freeVerb2 i1 i2 mx room damp = mkFilter "FreeVerb2" [i1, i2, mx, room, damp] 2
+
 -- | Gate.
 gate :: UGen -> UGen -> UGen
-gate i t = mkFilter "Gate" [i,t] 1
+gate i t = mkFilter "Gate" [i, t] 1
 
 -- | Hash input values.
 hasher :: UGen -> UGen
@@ -110,7 +117,7 @@
 
 -- | Highpass filter.
 hpf :: UGen -> UGen -> UGen
-hpf i f = mkFilter "HPF" [i,f] 1
+hpf i f = mkFilter "HPF" [i, f] 1
 
 -- | Two point difference filter.
 hpz1 :: UGen -> UGen
@@ -122,11 +129,11 @@
 
 -- | Is signal within specified range.
 inRange :: UGen -> UGen -> UGen -> UGen
-inRange i lo hi = mkFilter "InRange" [i,lo,hi] 1
+inRange i lo hi = mkFilter "InRange" [i, lo, hi] 1
 
 -- | Fixed resonator filter bank.
 klank :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-klank i fs fp d s = mkFilterMCE "Klank" [i,fs,fp,d] s 1
+klank i fs fp d s = mkFilterMCE "Klank" [i, fs, fp, d] s 1
 
 -- | Format frequency, amplitude and decay time data as required for klank.
 klankSpec :: [UGen] -> [UGen] -> [UGen] -> UGen
@@ -134,39 +141,39 @@
 
 -- | Simple averaging filter.
 lag :: UGen -> UGen -> UGen
-lag i t = mkFilter "Lag" [i,t] 1
+lag i t = mkFilter "Lag" [i, t] 1
 
 -- | Nested lag filter.
 lag2 :: UGen -> UGen -> UGen
-lag2 i t = mkFilter "Lag2" [i,t] 1
+lag2 i t = mkFilter "Lag2" [i, t] 1
 
 -- | Twice nested lag filter.
 lag3 :: UGen -> UGen -> UGen
-lag3 i t = mkFilter "Lag3" [i,t] 1
+lag3 i t = mkFilter "Lag3" [i, t] 1
 
 -- | Last value before chang above threshhold.
 lastValue :: UGen -> UGen -> UGen
-lastValue i t = mkFilter "LastValue" [i,t] 1
+lastValue i t = mkFilter "LastValue" [i, t] 1
 
 -- | Sample and hold.
 latch :: UGen -> UGen -> UGen
-latch i t = mkFilter "Latch" [i,t] 1
+latch i t = mkFilter "Latch" [i, t] 1
 
 -- | Remove DC offset.
 leakDC :: UGen -> UGen -> UGen
-leakDC i coef = mkFilter "LeakDC" [i,coef] 1
+leakDC i coef = mkFilter "LeakDC" [i, coef] 1
 
 -- | Map from one linear range to another linear range.
 linLin :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-linLin i sl sh dl dh = mkFilter "LinLin" [i,sl,sh,dl,dh] 1
+linLin i sl sh dl dh = mkFilter "LinLin" [i, sl, sh, dl, dh] 1
 
 -- | Map from a linear range to an exponential range.
 linExp :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-linExp i sl sh dl dh = mkFilter "LinExp" [i,sl,sh,dl,dh] 1
+linExp i sl sh dl dh = mkFilter "LinExp" [i, sl, sh, dl, dh] 1
 
 -- | Lowpass filter.
 lpf :: UGen -> UGen -> UGen
-lpf i f = mkFilter "LPF" [i,f] 1
+lpf i f = mkFilter "LPF" [i, f] 1
 
 -- | Two point average filter.
 lpz1 :: UGen -> UGen
@@ -178,11 +185,11 @@
 
 -- | Masks off bits in the mantissa of signal.
 mantissaMask :: UGen -> UGen -> UGen
-mantissaMask i bits = mkFilter "MantissaMask" [i,bits] 1
+mantissaMask i bits = mkFilter "MantissaMask" [i, bits] 1
 
 -- | Median filter.
 median :: UGen -> UGen -> UGen
-median size i = mkFilter "Median" [size,i] 1
+median size i = mkFilter "Median" [size, i] 1
 
 -- | Moog VCF implementation.
 moogFF :: UGen -> UGen -> UGen -> UGen -> UGen
@@ -190,31 +197,31 @@
 
 -- | Most changed input.
 mostChange :: UGen -> UGen -> UGen
-mostChange a b = mkFilter "MostChange" [a,b] 1
+mostChange a b = mkFilter "MostChange" [a, b] 1
 
 -- | Multiply add ternary operator.
 mulAdd :: UGen -> UGen -> UGen -> UGen
-mulAdd s m a = mkFilter "MulAdd" [s,m,a] 1
+mulAdd s m a = mkFilter "MulAdd" [s, m, a] 1
 
 -- | Flattens dynamics.
 normalizer :: UGen -> UGen -> UGen -> UGen
-normalizer i level dur = mkFilter "Normalizer" [i,level,dur] 1
+normalizer i level dur = mkFilter "Normalizer" [i, level, dur] 1
 
 -- | One pole filter.
 onePole :: UGen -> UGen -> UGen
-onePole i coef = mkFilter "OnePole" [i,coef] 1
+onePole i coef = mkFilter "OnePole" [i, coef] 1
 
 -- | One zero filter.
 oneZero :: UGen -> UGen -> UGen
-oneZero i coef = mkFilter "OneZero" [i,coef] 1
+oneZero i coef = mkFilter "OneZero" [i, coef] 1
 
 -- | Maximum value.
 peak :: UGen -> UGen -> UGen
-peak t r = mkFilter "Peak" [t,r] 1
+peak t r = mkFilter "Peak" [t, r] 1
 
 -- | Simple time domain pitch shifter.
 pitchShift :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-pitchShift i w p d t = mkFilter "PitchShift" [i,w,p,d,t] 1
+pitchShift i w p d t = mkFilter "PitchShift" [i, w, p, d, t] 1
 
 -- | Karplus-Strong synthesis.
 pluck :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
@@ -222,7 +229,7 @@
 
 -- | Trigger counter.
 pulseCount :: UGen -> UGen -> UGen
-pulseCount t r = mkFilter "PulseCount" [t,r] 1
+pulseCount t r = mkFilter "PulseCount" [t, r] 1
 
 -- | Pass every nth trigger.
 pulseDivider :: UGen -> UGen -> UGen -> UGen
@@ -230,31 +237,31 @@
 
 -- | Resonant highpass filter.
 rhpf :: UGen -> UGen -> UGen -> UGen
-rhpf i freq rq = mkFilter "RHPF" [i,freq,rq] 1
+rhpf i freq rq = mkFilter "RHPF" [i, freq, rq] 1
 
 -- | Resonant lowpass filter.
 rlpf :: UGen -> UGen -> UGen -> UGen
-rlpf i freq rq = mkFilter "RLPF" [i,freq,rq] 1
+rlpf i freq rq = mkFilter "RLPF" [i, freq, rq] 1
 
 -- | Resonant filter.
 resonz :: UGen -> UGen -> UGen -> UGen
-resonz i freq bwr = mkFilter "Resonz" [i,freq,bwr] 1
+resonz i freq bwr = mkFilter "Resonz" [i, freq, bwr] 1
 
 -- | Ringing filter (equivalent to Resonz).
 ringz :: UGen -> UGen -> UGen -> UGen
-ringz i freq dcy = mkFilter "Ringz" [i,freq,dcy] 1
+ringz i freq dcy = mkFilter "Ringz" [i, freq, dcy] 1
 
 -- | Track maximum level.
 runningMax :: UGen -> UGen -> UGen
-runningMax i t = mkFilter "RunningMax" [i,t] 1
+runningMax i t = mkFilter "RunningMax" [i, t] 1
 
 -- | Track minimum level.
 runningMin :: UGen -> UGen -> UGen
-runningMin i t = mkFilter "RunningMin" [i,t] 1
+runningMin i t = mkFilter "RunningMin" [i, t] 1
 
 -- | Running sum.
 runningSum :: UGen -> UGen -> UGen
-runningSum i n = mkFilter "RunningSum" [i,n] 1
+runningSum i n = mkFilter "RunningSum" [i, n] 1
 
 -- | Select output from array of inputs.
 select :: UGen -> UGen -> UGen
@@ -266,31 +273,31 @@
 
 -- | Set-reset flip flop.
 setResetFF :: UGen -> UGen -> UGen
-setResetFF t r = mkFilter "SetResetFF" [t,r] 1
+setResetFF t r = mkFilter "SetResetFF" [t, r] 1
 
 -- | Wave shaper.
 shaper :: UGen -> UGen -> UGen
-shaper b s = mkFilter "Shaper" [b,s] 1
+shaper b s = mkFilter "Shaper" [b, s] 1
 
 -- | Remove transients and higher frequencies.
 slew :: UGen -> UGen -> UGen -> UGen
-slew i up dn = mkFilter "Slew" [i,up,dn] 1
+slew i up dn = mkFilter "Slew" [i, up, dn] 1
 
 -- | Second order filter section (biquad). 
 sos :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-sos i a0 a1 a2 b1 b2 = mkFilter "SOS" [i,a0,a1,a2,b1,b2] 1
+sos i a0 a1 a2 b1 b2 = mkFilter "SOS" [i, a0, a1, a2, b1, b2] 1
 
 -- | Stepper pulse counter.
 stepper :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-stepper t r minTime maxTime s v = mkFilter "Stepper" [t,r,minTime,maxTime,s,v] 1
+stepper t r mn mx s v = mkFilter "Stepper" [t, r, mn, mx, s, v] 1
 
 -- | Triggered linear ramp.
 sweep :: UGen -> UGen -> UGen
-sweep t r = mkFilter "Sweep" [t,r] 1
+sweep t r = mkFilter "Sweep" [t, r] 1
 
 -- | Delay trigger by specified interval. 
 tDelay :: UGen -> UGen -> UGen
-tDelay i d = mkFilter "TDelay" [i,d] 1
+tDelay i d = mkFilter "TDelay" [i, d] 1
 
 -- | Time since last triggered.
 timer :: UGen -> UGen
@@ -302,25 +309,21 @@
 
 -- | When triggered output trigger for specified duration.
 trig :: UGen -> UGen -> UGen
-trig i d = mkFilter "Trig" [i,d] 1
+trig i d = mkFilter "Trig" [i, d] 1
 
 -- | When triggered output unit signal for specified duration.
 trig1 :: UGen -> UGen -> UGen
-trig1 i d = mkFilter "Trig1" [i,d] 1
-
--- | Triggered windex.
-twindex :: UGen -> UGen -> UGen -> UGen
-twindex i n a = mkFilterMCE "TWindex" [i,n] a 1
+trig1 i d = mkFilter "Trig1" [i, d] 1
 
 -- | Two pole filter.
 twoPole :: UGen -> UGen -> UGen -> UGen
-twoPole i freq radius = mkFilter "TwoPole" [i,freq,radius] 1
+twoPole i freq radius = mkFilter "TwoPole" [i, freq, radius] 1
 
 -- | Two zero filter.
 twoZero :: UGen -> UGen -> UGen -> UGen
-twoZero i freq radius = mkFilter "TwoZero" [i,freq,radius] 1
+twoZero i freq radius = mkFilter "TwoZero" [i, freq, radius] 1
 
 -- | Index into a table with a signal.
 wrapIndex :: UGen -> UGen -> UGen
-wrapIndex b i = mkFilter "WrapIndex" [b,i] 1
+wrapIndex b i = mkFilter "WrapIndex" [b, i] 1
 
diff --git a/Sound/SC3/UGen/Granular.hs b/Sound/SC3/UGen/Granular.hs
--- a/Sound/SC3/UGen/Granular.hs
+++ b/Sound/SC3/UGen/Granular.hs
@@ -1,8 +1,7 @@
 module Sound.SC3.UGen.Granular where
 
-import Sound.SC3.UGen.Rate (Rate(AR))
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
 
 -- | Granular synthesis with sound stored in a buffer.
 grainBuf :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
diff --git a/Sound/SC3/UGen/Graph/Naive.hs b/Sound/SC3/UGen/Graph/Naive.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/Graph/Naive.hs
+++ /dev/null
@@ -1,73 +0,0 @@
-module Sound.SC3.UGen.Graph.Naive ( Graph(..)
-                                  , Input(..)
-                                  , graph
-                                  , nodeIndex
-                                  , makeInput ) where
-
-import Sound.SC3.UGen.Rate (Rate(KR))
-import Sound.SC3.UGen.UGen (UGen(..), Special(..))
-import Sound.SC3.UGen.UGen.Predicate
-
-import Data.Maybe (fromMaybe)
-import Data.List (nub, elemIndex)
-
-data Graph = Graph { constants :: [UGen]
-                   , controls :: [UGen]
-                   , primitives :: [UGen] }
-             deriving (Eq, Show)
-data Input = Input Int Int deriving (Eq, Show)
-
--- | The list of all UGens referenced in a UGen graph.
-nodes :: UGen -> [UGen]
-nodes u@(Primitive _ _ i _ _ _) = u : concatMap nodes i
-nodes (Proxy u _) = u : nodes u
-nodes (MCE u) = concatMap nodes u
-nodes (MRG x y) = nodes x ++ nodes y
-nodes u = [u]
-
--- | Construct implicit control UGen (k-rate only).
-implicit :: Int -> UGen
-implicit n = Primitive KR "Control" [] (replicate n KR) (Special 0) Nothing
-
--- | Construct a UGen graph.
-graph :: UGen -> Graph
-graph root = Graph n c u'
-  where e = (nub . reverse) (nodes root)
-        n = filter isConstant e
-        c = filter isControl e
-        u = filter isUGen e
-        u' = if null c then u else implicit (length c) : u
-
--- | Determine index of a node in the Graph.
-elemIndex' :: (Eq a, Show a) => a -> [a] -> Int
-elemIndex' e l = fromMaybe (error ("node not in graph?" ++ show (e,l))) 
-                 (elemIndex e l)
-                 
--- | Determine index of UGen in Graph.
-ugenIndex :: Graph -> UGen -> Int
-ugenIndex (Graph _ _ u) x = elemIndex' x u
-
--- | Determine index of Constant in Graph.
-constantIndex :: Graph -> UGen -> Int
-constantIndex (Graph n _ _) x = elemIndex' x n
-
--- | Determine index of Control in Graph.
-controlIndex :: Graph -> UGen -> Int
-controlIndex (Graph _ c _) x = elemIndex' x c
-
--- | Determine index of any node in Graph.
-nodeIndex :: Graph -> UGen -> Int
-nodeIndex g u@(Constant _) = constantIndex g u
-nodeIndex g u@(Control _ _ _) = controlIndex g u
-nodeIndex g u@(Primitive _ _ _ _ _ _) = ugenIndex g u
-nodeIndex g (MRG u _) = ugenIndex g u
-nodeIndex _ _ = error "nodeIndex: illegal input"
-
--- | Construct Input value for UGen in Graph.
-makeInput :: Graph -> UGen -> Input
-makeInput g u@(Primitive _ _ _ _ _ _) = Input (ugenIndex g u) 0
-makeInput g u@(Constant _) = Input (-1) (constantIndex g u)
-makeInput g u@(Control _ _ _) = Input 0 (controlIndex g u)
-makeInput g (Proxy u n) = Input (ugenIndex g u) n
-makeInput g (MRG u _) = makeInput g u
-makeInput _ u = error ("makeInput: illegal input: " ++ show u)
diff --git a/Sound/SC3/UGen/IO.hs b/Sound/SC3/UGen/IO.hs
--- a/Sound/SC3/UGen/IO.hs
+++ b/Sound/SC3/UGen/IO.hs
@@ -1,10 +1,9 @@
 module Sound.SC3.UGen.IO where
 
-import Sound.SC3.UGen.Rate (Rate(KR,AR))
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct
-import Sound.SC3.UGen.Enum (Warp)
-import Sound.SC3.UGen.Utilities (fromWarp)
+import Sound.SC3.UGen.Enum
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.Utilities
 
 -- | Read signal from an audio or control bus.
 in' :: Int -> Rate -> UGen -> UGen
@@ -14,6 +13,7 @@
 localIn :: Int -> Rate -> UGen
 localIn nc r = mkOsc r "LocalIn" [] nc
 
+-- | Control rate bus input with lag.
 lagIn :: Int -> UGen -> UGen -> UGen
 lagIn nc bus lag = mkOsc KR "LagIn" [bus, lag] nc
 
@@ -57,15 +57,15 @@
 
 -- | Report the status of the first pointer button.
 mouseButton :: Rate -> UGen -> UGen -> UGen -> UGen
-mouseButton r minVal maxVal lag = mkOsc r "MouseButton" [minVal, maxVal, lag] 1
+mouseButton r ll rl lag = mkOsc r "MouseButton" [ll, rl, lag] 1
 
 -- | Cursor UGen, X axis.
 mouseX :: Rate -> UGen -> UGen -> Warp -> UGen -> UGen
-mouseX r minVal maxVal warp lag = mkOsc r "MouseX" [minVal, maxVal, fromWarp warp, lag] 1
+mouseX r ll rl w lag = mkOsc r "MouseX" [ll, rl, from_warp w, lag] 1
 
 -- | Cursor UGen, Y axis.
 mouseY :: Rate -> UGen -> UGen -> Warp -> UGen -> UGen
-mouseY r minVal maxVal warp lag = mkOsc r "MouseY" [minVal, maxVal, fromWarp warp, lag] 1
+mouseY r ll rl w lag = mkOsc r "MouseY" [ll, rl, from_warp w, lag] 1
 
 -- | Control variant.
 trigControl :: Int -> Rate -> UGen
diff --git a/Sound/SC3/UGen/Information.hs b/Sound/SC3/UGen/Information.hs
--- a/Sound/SC3/UGen/Information.hs
+++ b/Sound/SC3/UGen/Information.hs
@@ -1,48 +1,47 @@
 module Sound.SC3.UGen.Information where
 
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.Utilities (mkInfoUGen)
+import Sound.SC3.UGen.UGen
 
 -- | Sample rate of synthesis server, frames per second.
 sampleRate :: UGen
-sampleRate = mkInfoUGen "SampleRate"
+sampleRate = mkInfo "SampleRate"
 
 -- | Duration of one sample, seconds.
 sampleDur :: UGen
-sampleDur = mkInfoUGen "SampleDur"
+sampleDur = mkInfo "SampleDur"
 
 -- | Duration of one sample, radians.
 radiansPerSample :: UGen
-radiansPerSample = mkInfoUGen "RadiansPerSample"
+radiansPerSample = mkInfo "RadiansPerSample"
 
 -- | Control rate of synthesis server, periods per second.
 controlRate :: UGen
-controlRate = mkInfoUGen "ControlRate"
+controlRate = mkInfo "ControlRate"
 
 -- | Sub-sample accurate scheduling offset.
 subsampleOffset :: UGen
-subsampleOffset = mkInfoUGen "SubsampleOffset"
+subsampleOffset = mkInfo "SubsampleOffset"
 
 -- | Number of allocated output audio rate buses.
 numOutputBuses :: UGen
-numOutputBuses = mkInfoUGen "NumOutputBuses"
+numOutputBuses = mkInfo "NumOutputBuses"
 
 -- | Number of allocated input audio rate buses.
 numInputBuses :: UGen
-numInputBuses = mkInfoUGen "NumInputBuses"
+numInputBuses = mkInfo "NumInputBuses"
 
 -- | Number of allocated audio rate buses.
 numAudioBuses :: UGen
-numAudioBuses = mkInfoUGen "NumAudioBuses"
+numAudioBuses = mkInfo "NumAudioBuses"
 
 -- | Number of allocated control rate buses.
 numControlBuses :: UGen
-numControlBuses = mkInfoUGen "NumControlBuses"
+numControlBuses = mkInfo "NumControlBuses"
 
 -- | Number of allocated buffers.
 numBuffers :: UGen
-numBuffers = mkInfoUGen "NumBuffers"
+numBuffers = mkInfo "NumBuffers"
 
 -- | Number of runnings synthesis nodes.
 numRunningSynths :: UGen
-numRunningSynths = mkInfoUGen "NumRunningSynths"
+numRunningSynths = mkInfo "NumRunningSynths"
diff --git a/Sound/SC3/UGen/MachineListening.hs b/Sound/SC3/UGen/MachineListening.hs
--- a/Sound/SC3/UGen/MachineListening.hs
+++ b/Sound/SC3/UGen/MachineListening.hs
@@ -2,15 +2,17 @@
 
 import Data.List
 import Data.Maybe
-import Sound.SC3.UGen.Rate (Rate(KR))
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.Math ()
-import Sound.SC3.UGen.UGen.Construct (mkOsc)
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
 
 -- | Autocorrelation beat tracker.
 beatTrack :: UGen -> UGen -> UGen
 beatTrack fft lock = mkOsc KR "BeatTrack" [fft, lock] 4
 
+-- | Template matching beat tracker.
+beatTrack2 :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+beatTrack2 b mf ws pa lk w = mkOsc KR "BeatTrack2" [b, mf, ws, pa, lk, w] 6
+
 -- | Extraction of instantaneous loudness in sones.
 loudness :: UGen -> UGen -> UGen -> UGen
 loudness fft smask tmask = mkOsc KR "Compander" [fft, smask, tmask] 1
@@ -21,16 +23,29 @@
     where t = ["power", "magsum", "complex", "rcomplex", "phase", "wphase", "mkl"]
 
 -- | Onset detector.
-onsets :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-onsets c t o r f mg ms w = mkOsc KR "Onsets" [c, t, o, r, f, mg, ms, w] 1
+onsets :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+onsets c t o r f mg ms wt rw = mkOsc KR "Onsets" [c, t, o, r, f, mg, ms, wt, rw] 1
 
 -- | Onset detector with default values for minor parameters.
 onsets' :: UGen -> UGen -> UGen -> UGen
-onsets' c t o = onsets c t o 1.0 0.1 10.0 11.0 1.0
+onsets' c t o = onsets c t o 1 0.1 10 11 1 0
 
 -- | Key tracker.
 keyTrack :: UGen -> UGen -> UGen -> UGen -> UGen
 keyTrack fft kd cl _ = mkOsc KR "KeyTrack" [fft, kd, cl] 1
+
+-- | Mel frequency cepstral coefficients.
+mfcc :: Int -> UGen -> UGen
+mfcc nc b = mkOsc KR "MFCC" [b, constant nc] nc
+
+specFlatness :: UGen -> UGen
+specFlatness b = mkOsc KR "SpecFlatness" [b] 1
+
+specPcile :: UGen -> UGen -> UGen -> UGen
+specPcile b f i = mkOsc KR "SpecPcile" [b, f, i] 1
+
+specCentroid :: UGen -> UGen
+specCentroid b = mkOsc KR "SpecFlatness" [b] 1
 
 -- Local Variables:
 -- truncate-lines:t
diff --git a/Sound/SC3/UGen/Math.hs b/Sound/SC3/UGen/Math.hs
--- a/Sound/SC3/UGen/Math.hs
+++ b/Sound/SC3/UGen/Math.hs
@@ -1,9 +1,7 @@
 module Sound.SC3.UGen.Math where
 
 import Sound.SC3.UGen.Operator
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct
-import Sound.SC3.UGen.UGen.Math ()
+import Sound.SC3.UGen.UGen
 
 -- The Eq and Ord classes in the Prelude require Bool, hence the name
 -- mangling.  True is 1.0, False is 0.0
diff --git a/Sound/SC3/UGen/Noise/Base.hs b/Sound/SC3/UGen/Noise/Base.hs
--- a/Sound/SC3/UGen/Noise/Base.hs
+++ b/Sound/SC3/UGen/Noise/Base.hs
@@ -1,8 +1,7 @@
 module Sound.SC3.UGen.Noise.Base where
 
-import Sound.SC3.UGen.Rate (Rate(IR))
-import Sound.SC3.UGen.UGen (UGen, UGenId)
-import Sound.SC3.UGen.UGen.Construct (mkOscId, mkFilterId)
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
 
 -- | Brown noise.
 brownNoise :: UGenId -> Rate -> UGen
@@ -14,7 +13,7 @@
 
 -- | Randomly pass or block triggers.
 coinGate :: UGenId -> UGen -> UGen -> UGen
-coinGate z prob i = mkFilterId z "CoinGate" [prob,i] 1
+coinGate z prob i = mkFilterId z "CoinGate" [prob, i] 1
 
 -- | Random impulses in (-1, 1).
 dust2 :: UGenId -> Rate -> UGen -> UGen
@@ -26,7 +25,7 @@
 
 -- | Random value in exponential distribution.
 expRand :: UGenId -> UGen -> UGen -> UGen
-expRand z lo hi = mkOscId z IR "ExpRand" [lo,hi] 1
+expRand z lo hi = mkOscId z IR "ExpRand" [lo, hi] 1
 
 -- | Gray noise.
 grayNoise :: UGenId -> Rate -> UGen
@@ -34,7 +33,7 @@
 
 -- | Random integer in uniform distribution.
 iRand :: UGenId -> UGen -> UGen -> UGen
-iRand z lo hi = mkOscId z IR "IRand" [lo,hi] 1
+iRand z lo hi = mkOscId z IR "IRand" [lo, hi] 1
 
 -- | Clip noise.
 lfClipNoise :: UGenId -> Rate -> UGen -> UGen
@@ -48,7 +47,7 @@
 lfdNoise0 :: UGenId -> Rate -> UGen -> UGen
 lfdNoise0 z r freq = mkOscId z r "LFDNoise0" [freq] 1
 
--- | Dynamic ramp noise. 
+-- | Dynamic ramp noise.
 lfdNoise1 :: UGenId -> Rate -> UGen -> UGen
 lfdNoise1 z r freq = mkOscId z r "LFDNoise1" [freq] 1
 
@@ -74,11 +73,11 @@
 
 -- | Random value in skewed linear distribution.
 linRand :: UGenId -> UGen -> UGen -> UGen -> UGen
-linRand z lo hi m = mkOscId z IR "LinRand" [lo,hi,m] 1
+linRand z lo hi m = mkOscId z IR "LinRand" [lo, hi, m] 1
 
 -- | Random value in sum of n linear distribution.
 nRand :: UGenId -> UGen -> UGen -> UGen -> UGen
-nRand z lo hi n = mkOscId z IR "NRand" [lo,hi,n] 1
+nRand z lo hi n = mkOscId z IR "NRand" [lo, hi, n] 1
 
 -- | Pink noise.
 pinkNoise :: UGenId -> Rate -> UGen
@@ -86,19 +85,23 @@
 
 -- | Random value in uniform distribution.
 rand :: UGenId -> UGen -> UGen -> UGen
-rand z lo hi = mkOscId z IR "Rand" [lo,hi] 1
+rand z lo hi = mkOscId z IR "Rand" [lo, hi] 1
 
 -- | Random value in exponential distribution on trigger.
 tExpRand :: UGenId -> UGen -> UGen -> UGen -> UGen
-tExpRand z lo hi trig = mkFilterId z "TExpRand" [lo,hi,trig] 1
+tExpRand z lo hi trig = mkFilterId z "TExpRand" [lo, hi, trig] 1
 
 -- | Random integer in uniform distribution on trigger.
 tiRand :: UGenId -> UGen -> UGen -> UGen -> UGen
-tiRand z lo hi trig = mkFilterId z "TIRand" [lo,hi,trig] 1
+tiRand z lo hi trig = mkFilterId z "TIRand" [lo, hi, trig] 1
 
 -- | Random value in uniform distribution on trigger.
 tRand :: UGenId -> UGen -> UGen -> UGen -> UGen
-tRand z lo hi trig = mkFilterId z "TRand" [lo,hi,trig] 1
+tRand z lo hi trig = mkFilterId z "TRand" [lo, hi, trig] 1
+
+-- | Triggered windex.
+twindex :: UGenId -> UGen -> UGen -> UGen -> UGen
+twindex z i n a = mkFilterMCEId z "TWindex" [i, n] a 1
 
 -- | White noise.
 whiteNoise :: UGenId -> Rate -> UGen
diff --git a/Sound/SC3/UGen/Noise/Monadic.hs b/Sound/SC3/UGen/Noise/Monadic.hs
--- a/Sound/SC3/UGen/Noise/Monadic.hs
+++ b/Sound/SC3/UGen/Noise/Monadic.hs
@@ -1,8 +1,8 @@
 module Sound.SC3.UGen.Noise.Monadic where
 
-import Sound.SC3.UGen.Rate (Rate)
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UGen.Lift
 import qualified Sound.SC3.UGen.Noise.Base as N
 import Sound.SC3.UGen.UId
 
@@ -50,7 +50,7 @@
 lfdNoise0 :: (UId m) => Rate -> UGen -> m UGen
 lfdNoise0 = liftU2 N.lfdNoise0
 
--- | Dynamic ramp noise. 
+-- | Dynamic ramp noise.
 lfdNoise1 :: (UId m) => Rate -> UGen -> m UGen
 lfdNoise1 = liftU2 N.lfdNoise1
 
@@ -101,6 +101,10 @@
 -- | Random value in uniform distribution on trigger.
 tRand :: (UId m) => UGen -> UGen -> UGen -> m UGen
 tRand = liftU3 N.tRand
+
+-- | Triggered windex.
+twindex :: (UId m) => UGen -> UGen -> UGen -> m UGen
+twindex = liftU3 N.twindex
 
 -- | White noise.
 whiteNoise :: (UId m) => Rate -> m UGen
diff --git a/Sound/SC3/UGen/Noise/Unsafe.hs b/Sound/SC3/UGen/Noise/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/Noise/Unsafe.hs
@@ -0,0 +1,110 @@
+module Sound.SC3.UGen.Noise.Unsafe where
+
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UGen.Lift
+import qualified Sound.SC3.UGen.Noise.Monadic as N
+
+-- | Brown noise.
+brownNoise :: Rate -> UGen
+brownNoise = liftP N.brownNoise
+
+-- | Clip noise.
+clipNoise :: Rate -> UGen
+clipNoise = liftP N.clipNoise
+
+-- | Randomly pass or block triggers.
+coinGate :: UGen -> UGen -> UGen
+coinGate = liftP2 N.coinGate
+
+-- | Random impulses in (-1, 1).
+dust2 :: Rate -> UGen -> UGen
+dust2 = liftP2 N.dust2
+
+-- | Random impulse in (0,1).
+dust :: Rate -> UGen -> UGen
+dust = liftP2 N.dust
+
+-- | Random value in exponential distribution.
+expRand :: UGen -> UGen -> UGen
+expRand = liftP2 N.expRand
+
+-- | Gray noise.
+grayNoise :: Rate -> UGen
+grayNoise = liftP N.grayNoise
+
+-- | Random integer in uniform distribution.
+iRand :: UGen -> UGen -> UGen
+iRand = liftP2 N.iRand
+
+-- | Clip noise.
+lfClipNoise :: Rate -> UGen -> UGen
+lfClipNoise = liftP2 N.lfClipNoise
+
+-- | Dynamic clip noise.
+lfdClipNoise :: Rate -> UGen -> UGen
+lfdClipNoise = liftP2 N.lfdClipNoise
+
+-- | Dynamic step noise.
+lfdNoise0 :: Rate -> UGen -> UGen
+lfdNoise0 = liftP2 N.lfdNoise0
+
+-- | Dynamic ramp noise.
+lfdNoise1 :: Rate -> UGen -> UGen
+lfdNoise1 = liftP2 N.lfdNoise1
+
+-- | Dynamic quadratic noise
+lfdNoise2 :: Rate -> UGen -> UGen
+lfdNoise2 = liftP2 N.lfdNoise2
+
+-- | Dynamic cubic noise
+lfdNoise3 :: Rate -> UGen -> UGen
+lfdNoise3 = liftP2 N.lfdNoise3
+
+-- | Step noise.
+lfNoise0 :: Rate -> UGen -> UGen
+lfNoise0 = liftP2 N.lfNoise0
+
+-- | Ramp noise.
+lfNoise1 :: Rate -> UGen -> UGen
+lfNoise1 = liftP2 N.lfNoise1
+
+-- | Quadratic noise.
+lfNoise2 :: Rate -> UGen -> UGen
+lfNoise2 = liftP2 N.lfNoise2
+
+-- | Random value in skewed linear distribution.
+linRand :: UGen -> UGen -> UGen -> UGen
+linRand = liftP3 N.linRand
+
+-- | Random value in sum of n linear distribution.
+nRand :: UGen -> UGen -> UGen -> UGen
+nRand = liftP3 N.nRand
+
+-- | Pink noise.
+pinkNoise :: Rate -> UGen
+pinkNoise = liftP N.pinkNoise
+
+-- | Random value in uniform distribution.
+rand :: UGen -> UGen -> UGen
+rand = liftP2 N.rand
+
+-- | Random value in exponential distribution on trigger.
+tExpRand :: UGen -> UGen -> UGen -> UGen
+tExpRand = liftP3 N.tExpRand
+
+-- | Random integer in uniform distribution on trigger.
+tiRand :: UGen -> UGen -> UGen -> UGen
+tiRand = liftP3 N.tiRand
+
+-- | Random value in uniform distribution on trigger.
+tRand :: UGen -> UGen -> UGen -> UGen
+tRand = liftP3 N.tRand
+
+-- | Triggered windex.
+twindex :: UGen -> UGen -> UGen -> UGen
+twindex = liftP3 N.twindex
+
+-- | White noise.
+whiteNoise :: Rate -> UGen
+whiteNoise = liftP N.whiteNoise
diff --git a/Sound/SC3/UGen/Oscillator.hs b/Sound/SC3/UGen/Oscillator.hs
--- a/Sound/SC3/UGen/Oscillator.hs
+++ b/Sound/SC3/UGen/Oscillator.hs
@@ -1,9 +1,8 @@
 module Sound.SC3.UGen.Oscillator where
 
-import Sound.SC3.UGen.Rate (Rate(AR))
-import Sound.SC3.UGen.UGen (UGen, mce)
-import Sound.SC3.UGen.UGen.Construct (mkOsc, mkOscMCE)
-import Data.List(transpose)
+import Data.List
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.UGen
 
 -- | Band Limited ImPulse generator.
 blip :: Rate -> UGen -> UGen -> UGen
@@ -77,7 +76,7 @@
 sinOsc :: Rate -> UGen -> UGen -> UGen
 sinOsc r freq phase = mkOsc r "SinOsc" [freq, phase] 1
 
--- | Sawtooth oscillator hard synched to a fundamental. 
+-- | Sawtooth oscillator hard synched to a fundamental.
 syncSaw :: Rate -> UGen -> UGen -> UGen
 syncSaw r syncFreq sawFreq = mkOsc r "SyncSaw" [syncFreq, sawFreq] 1
 
diff --git a/Sound/SC3/UGen/Panner.hs b/Sound/SC3/UGen/Panner.hs
--- a/Sound/SC3/UGen/Panner.hs
+++ b/Sound/SC3/UGen/Panner.hs
@@ -1,7 +1,6 @@
 module Sound.SC3.UGen.Panner where
 
-import Sound.SC3.UGen.UGen (UGen)
-import Sound.SC3.UGen.UGen.Construct (mkFilter, mkFilterMCE)
+import Sound.SC3.UGen.UGen
 
 -- | Two channel equal power panner.
 pan2 :: UGen -> UGen -> UGen -> UGen
@@ -39,7 +38,7 @@
 panAz nc i p l w o = mkFilterMCE "PanAz" [i, p, l, w, o] nc 0
 
 xFade2 :: UGen -> UGen -> UGen -> UGen -> UGen
-xFade2 inA inB pan level = mkFilter "XFade" [inA, inB, pan, level] 2
+xFade2 inA inB pan level = mkFilter "XFade2" [inA, inB, pan, level] 2
 
 linXFade2 :: UGen -> UGen -> UGen -> UGen
-linXFade2 inA inB pan = mkFilter "XFade" [inA, inB, pan] 2
+linXFade2 inA inB pan = mkFilter "LinXFade2" [inA, inB, pan] 2
diff --git a/Sound/SC3/UGen/Rate.hs b/Sound/SC3/UGen/Rate.hs
--- a/Sound/SC3/UGen/Rate.hs
+++ b/Sound/SC3/UGen/Rate.hs
@@ -1,17 +1,28 @@
-module Sound.SC3.UGen.Rate (Rate(..), rateId) where
+module Sound.SC3.UGen.Rate ( Rate(..)
+                           , rateId
+                           , ar, kr, ir, dr ) where
 
--- | Operating rate of UGen.
-data Rate = IR | KR | AR | DR deriving (Eq, Show, Enum)
+-- | Operating rate of unit generator.
+data Rate = IR | KR | AR | DR 
+            deriving (Eq, Show, Enum)
 
 instance Ord Rate where
-    compare a b = compare (rateOrd a) (rateOrd b)
+    compare a b = compare (rate_ord a) (rate_ord b)
 
-rateOrd :: Rate -> Int
-rateOrd IR = 0
-rateOrd KR = 1
-rateOrd AR = 2
-rateOrd DR = 3
+-- | Rate constructors.
+ar, kr, ir, dr :: Rate
+ar = AR
+kr = KR
+ir = IR
+dr = DR
 
 -- | Integer rate identifier, as required for scsynth bytecode.
 rateId :: Rate -> Int
 rateId = fromEnum
+
+-- Rates as ordered for filter rate selection.
+rate_ord :: Rate -> Int
+rate_ord IR = 0
+rate_ord KR = 1
+rate_ord AR = 2
+rate_ord DR = 3
diff --git a/Sound/SC3/UGen/UGen.hs b/Sound/SC3/UGen/UGen.hs
--- a/Sound/SC3/UGen/UGen.hs
+++ b/Sound/SC3/UGen/UGen.hs
@@ -1,24 +1,19 @@
-module Sound.SC3.UGen.UGen ( Name, UGenId(..), UGen(..), Output, Special(..)
-                           , constant, control
-                           , mce, mce2
-                           , mrg, mrg2
-                           , proxy
-                           , clone, uid ) where
+module Sound.SC3.UGen.UGen where
 
-import Control.Monad (liftM, replicateM)
-import Sound.SC3.UGen.Rate (Rate)
+import Control.Monad
+import Data.List
+import Sound.SC3.UGen.Operator
+import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.UId
+import System.Random
 
-type Name = String
-type Output = Rate
-newtype Special = Special Int deriving (Eq, Show)
-newtype UGenId = UGenId Int deriving (Eq, Show)
+-- | Unit generator.
 data UGen = Constant { constantValue :: Double }
-          | Control { controlRate_ :: Rate
-                    , controlName :: Name
+          | Control { controlOperatingRate :: Rate
+                    , controlName :: String
                     , controlDefault :: Double }
           | Primitive { ugenRate :: Rate
-                      , ugenName :: Name
+                      , ugenName :: String
                       , ugenInputs :: [UGen]
                       , ugenOutputs :: [Output]
                       , ugenSpecial :: Special
@@ -30,40 +25,344 @@
                 , mrgRight :: UGen }
             deriving (Eq, Show)
 
--- | UGen identifier constructor.
+-- | Unit generator output descriptor.
+type Output = Rate
+
+-- | Operating mode of unary and binary operators.
+newtype Special = Special Int 
+    deriving (Eq, Show)
+
+-- | Identifier for non-functional unit generators.
+newtype UGenId = UGenId Int 
+    deriving (Eq, Show)
+
+-- * Unit generator node constructors.
+
+-- | Unit generator identifier constructor.
 uid :: Int -> UGenId
 uid = UGenId
 
--- | Constant value constructor.
+-- | Constant value node constructor.
 constant :: (Real a) => a -> UGen
 constant = Constant . realToFrac
 
--- | Control input constructor.
-control :: Rate -> Name -> Double -> UGen
+-- | Control input node constructor.
+control :: Rate -> String -> Double -> UGen
 control = Control
 
--- | Multiple channel expansion constructor.
+-- | Multiple channel expansion node constructor.
 mce :: [UGen] -> UGen
 mce = MCE
 
+-- | Multiple root graph node constructor.
+mrg2 :: UGen -> UGen -> UGen
+mrg2 = MRG
+
+-- | Unit generator proxy node constructor.
+proxy :: UGen -> Int -> UGen
+proxy = Proxy
+
+-- * Unit generator node predicates.
+
+-- | Constant node predicate.
+isConstant :: UGen -> Bool
+isConstant (Constant _) = True
+isConstant _            = False
+
+-- | Control node predicate.
+isControl :: UGen -> Bool
+isControl (Control _ _ _) = True
+isControl _               = False
+
+-- | Unit generator primitive node predicate.
+isUGen :: UGen -> Bool
+isUGen (Primitive _ _ _ _ _ _) = True
+isUGen _ = False
+
+-- | Proxy node predicate.
+isProxy :: UGen -> Bool
+isProxy (Proxy _ _) = True
+isProxy _           = False
+
+-- | Multiple channel expansion node predicate.
+isMCE :: UGen -> Bool
+isMCE (MCE _) = True
+isMCE _       = False
+
+-- | MRG predicate.
+isMRG :: UGen -> Bool
+isMRG (MRG _ _) = True
+isMRG _ = False
+
+-- * Multiple channel expansion.
+
 -- | Multiple channel expansion for two inputs.
 mce2 :: UGen -> UGen -> UGen
 mce2 x y = mce [x, y]
 
+-- | Clone a unit generator (mce . replicateM).
+clone :: (UId m) => Int -> m UGen -> m UGen
+clone n u = liftM mce (replicateM n u)
+
+-- | Number of channels to expand to.
+mceDegree :: UGen -> Int
+mceDegree (MCE l) = length l
+mceDegree (MRG u _) = mceDegree u
+mceDegree _ = error "mceDegree: illegal ugen"
+
+-- | Extend UGen to specified degree.
+mceExtend :: Int -> UGen -> [UGen]
+mceExtend n (MCE l) = take n (cycle l)
+mceExtend n (MRG x y) = (MRG r y : rs) where (r:rs) = mceExtend n x
+mceExtend n u = replicate n u
+
+-- | Apply MCE transformation.
+mceTransform :: UGen -> UGen
+mceTransform (Primitive r n i o s d) = MCE (map f i')
+    where f j = Primitive r n j o s d
+          upr = maximum (map mceDegree (filter isMCE i))
+          i' = transpose (map (mceExtend upr) i)
+mceTransform _ = error "mceTransform: illegal ugen"
+
+-- | Apply MCE transformation if required.
+mceExpand :: UGen -> UGen
+mceExpand (MCE l) = MCE (map mceExpand l)
+mceExpand (MRG x y) = MRG (mceExpand x) y
+mceExpand u = if required u then mceExpand (mceTransform u) else u
+    where required (Primitive _ _ i _ _ _) = not (null (filter isMCE i))
+          required _ = False
+
+-- | Apply UGen list operation on MCE contents.
+mceEdit :: ([UGen] -> [UGen]) -> UGen -> UGen
+mceEdit f (MCE l) = MCE (f l)
+mceEdit _ _ = error "mceEdit: non MCE value"
+
+-- | Reverse order of channels at MCE.
+mceReverse :: UGen -> UGen
+mceReverse = mceEdit reverse
+
+-- | Obtain indexed channel at MCE.
+mceChannel :: Int -> UGen -> UGen
+mceChannel n (MCE l) = l !! n
+mceChannel _ _ = error "mceChannel: non MCE value"
+
+-- | Output channels of UGen as a list.
+mceChannels :: UGen -> [UGen]
+mceChannels (MCE l) = l
+mceChannels (MRG x y) = (MRG r y) : rs where (r:rs) = mceChannels x
+mceChannels u = [u]
+
+-- | Transpose rows and columns, ie. {{a,b},{c,d}} to {{a,c},{b,d}}.
+mceTranspose :: UGen -> UGen
+mceTranspose u = mce (map mce (transpose (map mceChannels (mceChannels u))))
+
+-- * Multiple root graphs.
+
 -- | Multiple root graph constructor.
 mrg :: [UGen] -> UGen
 mrg [] = undefined
 mrg [x] = x
 mrg (x:xs) = MRG x (mrg xs)
 
--- | Multiple root graph with two inputs.
-mrg2 :: UGen -> UGen -> UGen
-mrg2 = MRG
+-- * Unit generator function builders.
 
-proxy :: UGen -> Int -> UGen
-proxy = Proxy
+-- | Apply proxy transformation if required.
+proxify :: UGen -> UGen
+proxify u 
+    | isMCE u = mce (map proxify (mceProxies u))
+    | isMRG u = mrg [proxify (mrgLeft u), mrgRight u]
+    | isUGen u = let o = ugenOutputs u
+                 in case o of
+                      (_:_:_) -> mce (map (proxy u) [0..(length o - 1)])
+                      _ -> u
+    | otherwise = error "proxify: illegal ugen"
 
--- | Clone UGen.
-clone :: (UId m) => Int -> m UGen -> m UGen
-clone n u = liftM mce (replicateM n u)
+-- | Determine the rate of a UGen.
+rateOf :: UGen -> Rate
+rateOf u
+    | isConstant u = IR
+    | isControl u = controlOperatingRate u
+    | isUGen u = ugenRate u
+    | isProxy u = rateOf (proxySource u)
+    | isMCE u = maximum (map rateOf (mceProxies u))
+    | isMRG u = rateOf (mrgLeft u)
+    | otherwise = undefined
 
+-- True is input is a sink UGen, ie. has no outputs.
+is_sink :: UGen -> Bool
+is_sink u
+    | isUGen u = null (ugenOutputs u)
+    | isMCE u = all is_sink (mceProxies u)
+    | isMRG u = is_sink (mrgLeft u)
+    | otherwise = False
+
+-- Ensure input UGen is valid, ie. not a sink.
+check_input :: UGen -> UGen
+check_input u = if is_sink u 
+                then error ("illegal input" ++ show u) 
+                else u
+
+-- | Construct proxied and multiple channel expanded UGen.
+mkUGen :: Rate -> String -> [UGen] -> [Output] -> Special -> Maybe UGenId -> UGen
+mkUGen r n i o s z = proxify (mceExpand u)
+    where u = Primitive r n (map check_input i) o s z
+
+-- | Operator UGen constructor.
+mkOperator :: String -> [UGen] -> Int -> UGen
+mkOperator c i s = mkUGen r c i [r] (Special s) Nothing
+    where r = maximum (map rateOf i)
+
+-- | Unary math constructor with constant optimization.
+mkUnaryOperator :: Unary -> (Double -> Double) -> UGen -> UGen
+mkUnaryOperator i f a 
+    | isConstant a = constant (f (constantValue a))
+    | otherwise = mkOperator "UnaryOpUGen" [a] (fromEnum i)
+
+-- | Binary math constructor with constant optimization.
+mkBinaryOperator :: Binary -> (Double -> Double -> Double) -> UGen -> UGen -> UGen
+mkBinaryOperator i f a b 
+    | isConstant a && isConstant b = let a' = constantValue a
+                                         b' = constantValue b
+                                     in constant (f a' b')
+    | otherwise = mkOperator "BinaryOpUGen" [a, b] (fromEnum i)
+
+mk_osc :: Maybe UGenId -> Rate -> String -> [UGen] -> Int -> UGen
+mk_osc z r c i o = mkUGen r c i (replicate o r) (Special 0) z
+
+-- | Oscillator constructor.
+mkOsc :: Rate -> String -> [UGen] -> Int -> UGen
+mkOsc = mk_osc Nothing
+
+-- | Oscillator constructor, setting identifier.
+mkOscId :: UGenId -> Rate -> String -> [UGen] -> Int -> UGen
+mkOscId z = mk_osc (Just z)
+
+mk_osc_mce :: Maybe UGenId -> Rate -> String -> [UGen] -> UGen -> Int -> UGen
+mk_osc_mce z r c i j o = mk_osc z r c (i ++ mceChannels j) o
+
+-- | Variant oscillator constructor with MCE collapsing input.
+mkOscMCE :: Rate -> String -> [UGen] -> UGen -> Int -> UGen
+mkOscMCE = mk_osc_mce Nothing
+
+-- | Variant oscillator constructor with MCE collapsing input.
+mkOscMCEId :: UGenId -> Rate -> String -> [UGen] -> UGen -> Int -> UGen
+mkOscMCEId z = mk_osc_mce (Just z)
+
+mk_filter :: Maybe UGenId -> String -> [UGen] -> Int -> UGen
+mk_filter z c i o = mkUGen r c i o' (Special 0) z
+    where r = maximum (map rateOf i)
+          o'= replicate o r
+
+-- | Filter UGen constructor.
+mkFilter :: String -> [UGen] -> Int -> UGen
+mkFilter = mk_filter Nothing
+
+-- | Filter UGen constructor.
+mkFilterId :: UGenId -> String -> [UGen] -> Int -> UGen
+mkFilterId z = mk_filter (Just z)
+
+-- | Variant filter with rate derived from keyed input.
+mkFilterKeyed :: String -> Int -> [UGen] -> Int -> UGen
+mkFilterKeyed c k i o = mkUGen r c i o' (Special 0) Nothing
+    where r = rateOf (i !! k)
+          o' = replicate o r
+
+mk_filter_mce :: Maybe UGenId -> String -> [UGen] -> UGen -> Int -> UGen
+mk_filter_mce z c i j o = mk_filter z c (i ++ mceChannels j) o
+
+-- | Variant filter constructor with MCE collapsing input.
+mkFilterMCE :: String -> [UGen] -> UGen -> Int -> UGen
+mkFilterMCE = mk_filter_mce Nothing
+
+-- | Variant filter constructor with MCE collapsing input.
+mkFilterMCEId :: UGenId -> String -> [UGen] -> UGen -> Int -> UGen
+mkFilterMCEId z = mk_filter_mce (Just z)
+
+-- | Information unit generators are very specialized.
+mkInfo :: String -> UGen
+mkInfo name = mkOsc IR name [] 1
+
+-- Unit generators are numbers.
+instance Num UGen where
+    negate         = mkUnaryOperator Neg negate
+    (+)            = mkBinaryOperator Add (+)
+    (-)            = mkBinaryOperator Sub (-)
+    (*)            = mkBinaryOperator Mul (*)
+    abs            = mkUnaryOperator Abs abs
+    signum         = mkUnaryOperator Sign signum
+    fromInteger    = Constant . fromInteger
+
+-- Unit generators are fractional.
+instance Fractional UGen where
+    recip          = mkUnaryOperator Recip recip
+    (/)            = mkBinaryOperator FDiv (/)
+    fromRational   = Constant . fromRational
+
+-- Unit generators are floating point.
+instance Floating UGen where
+    pi             = Constant pi
+    exp            = mkUnaryOperator Exp exp
+    log            = mkUnaryOperator Log log
+    sqrt           = mkUnaryOperator Sqrt sqrt
+    (**)           = mkBinaryOperator Pow (**)
+    logBase a b    = log b / log a
+    sin            = mkUnaryOperator Sin sin
+    cos            = mkUnaryOperator Cos cos
+    tan            = mkUnaryOperator Tan tan
+    asin           = mkUnaryOperator ArcSin asin
+    acos           = mkUnaryOperator ArcCos acos
+    atan           = mkUnaryOperator ArcTan atan
+    sinh           = mkUnaryOperator SinH sinh
+    cosh           = mkUnaryOperator CosH cosh
+    tanh           = mkUnaryOperator TanH tanh
+    asinh x        = log (sqrt (x*x+1) + x)
+    acosh x        = log (sqrt (x*x-1) + x)
+    atanh x        = (log (1+x) - log (1-x)) / 2
+
+-- Unit generators are real.
+instance Real UGen where
+    toRational (Constant n) = toRational n
+    toRational _ = error "toRational at non-constant UGen"
+
+-- Unit generators are integral.
+instance Integral UGen where
+    quot = mkBinaryOperator IDiv undefined
+    rem = mkBinaryOperator Mod undefined
+    quotRem a b = (quot a b, rem a b)
+    div = mkBinaryOperator IDiv undefined
+    mod = mkBinaryOperator Mod undefined
+    toInteger (Constant n) = floor n
+    toInteger _ = error "toInteger at non-constant UGen"
+
+-- Unit generators are orderable.
+instance Ord UGen where
+    (Constant a) <  (Constant b) = a <  b
+    _            <  _            = error "< at UGen is partial, see <*"
+    (Constant a) <= (Constant b) = a <= b
+    _            <= _            = error "<= at UGen is partial, see <=*"
+    (Constant a) >  (Constant b) = a <  b
+    _            >  _            = error "> at UGen is partial, see >*"
+    (Constant a) >= (Constant b) = a >= b
+    _            >= _            = error ">= at UGen is partial, see >=*"
+    min = mkBinaryOperator Min min
+    max = mkBinaryOperator Max max
+
+-- Unit generators are enumerable.
+instance Enum UGen where
+    succ u                = u + 1
+    pred u                = u - 1
+    toEnum i              = constant i
+    fromEnum (Constant n) = truncate n
+    fromEnum _            = error "cannot enumerate non-constant UGens"
+    enumFrom              = iterate (+1)
+    enumFromThen n m      = iterate (+(m-n)) n
+    enumFromTo n m        = takeWhile (<= m+1/2) (enumFrom n)
+    enumFromThenTo n n' m = takeWhile (p (m + (n'-n)/2)) (enumFromThen n n')
+        where p = if n' >= n then (>=) else (<=)
+
+-- Unit generators are stochastic.
+instance Random UGen where
+    randomR (Constant l, Constant r) g = let (n, g') = randomR (l,r) g
+                                         in (Constant n, g')
+    randomR _ _ = error "randomR: non constant (l,r)"
+    random g = randomR (-1.0, 1.0) g
diff --git a/Sound/SC3/UGen/UGen/Construct.hs b/Sound/SC3/UGen/UGen/Construct.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/UGen/Construct.hs
+++ /dev/null
@@ -1,136 +0,0 @@
-module Sound.SC3.UGen.UGen.Construct ( mkUnaryOperator, mkBinaryOperator
-                                     , mkOscId, mkOsc
-                                     , mkOscMCEId, mkOscMCE
-                                     , mkFilterId, mkFilter, mkFilterKeyed
-                                     , mkFilterMCE
-                                     , liftU, liftU2, liftU3, liftU4 ) where
-
-import Sound.SC3.UGen.Operator
-import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.UGen
-import Sound.SC3.UGen.UGen.MCE
-import Sound.SC3.UGen.UGen.Predicate
-import Sound.SC3.UGen.UId
-
--- * UGen Constructors.
-
--- | Apply proxy transformation if required.
-proxify :: UGen -> UGen
-proxify u 
-    | isMCE u = mce (map proxify (mceProxies u))
-    | isMRG u = mrg [proxify (mrgLeft u), mrgRight u]
-    | isUGen u = let o = ugenOutputs u
-                 in case o of
-                      (_:_:_) -> mce (map (proxy u) [0..(length o - 1)])
-                      _ -> u
-    | otherwise = error "proxify: illegal ugen"
-
--- | Determine the rate of a UGen.
-rateOf :: UGen -> Rate
-rateOf u
-    | isConstant u = IR
-    | isControl u = controlRate_ u
-    | isUGen u = ugenRate u
-    | isProxy u = rateOf (proxySource u)
-    | isMCE u = maximum (map rateOf (mceProxies u))
-    | isMRG u = rateOf (mrgLeft u)
-    | otherwise = undefined
-
--- | True is input is a sink UGen, ie. has no outputs.
-isSink :: UGen -> Bool
-isSink u
-    | isUGen u = null (ugenOutputs u)
-    | isMCE u = all isSink (mceProxies u)
-    | isMRG u = isSink (mrgLeft u)
-    | otherwise = False
-
--- | Ensure input UGen is valid, ie. not a sink.
-checkInput :: UGen -> UGen
-checkInput u = if isSink u then error ("illegal input" ++ show u) else u
-
--- | Construct proxied and multiple channel expanded UGen.
-mkUGen :: Rate -> Name -> [UGen] -> [Output] -> Special -> Maybe UGenId -> UGen
-mkUGen r n i o s z = proxify (mceExpand u)
-    where u = Primitive r n (map checkInput i) o s z
-
--- | Operator UGen constructor.
-mkOperator :: Name -> [UGen] -> Int -> UGen
-mkOperator c i s = mkUGen r c i [r] (Special s) Nothing
-    where r = maximum (map rateOf i)
-
--- | Unary math constructor with constant optimization.
-mkUnaryOperator :: Unary -> (Double -> Double) -> UGen -> UGen
-mkUnaryOperator i f a 
-    | isConstant a = constant (f (constantValue a))
-    | otherwise = mkOperator "UnaryOpUGen" [a] (fromEnum i)
-
--- | Binary math constructor with constant optimization.
-mkBinaryOperator :: Binary -> (Double -> Double -> Double) -> UGen -> UGen -> UGen
-mkBinaryOperator i f a b 
-    | isConstant a && isConstant b = let a' = constantValue a
-                                         b' = constantValue b
-                                     in constant (f a' b')
-    | otherwise = mkOperator "BinaryOpUGen" [a, b] (fromEnum i)
-
-mkOsc_ :: Maybe UGenId -> Rate -> Name -> [UGen] -> Int -> UGen
-mkOsc_ z r c i o = mkUGen r c i (replicate o r) (Special 0) z
-
--- | Oscillator constructor.
-mkOsc :: Rate -> Name -> [UGen] -> Int -> UGen
-mkOsc = mkOsc_ Nothing
-
--- | Oscillator constructor, setting identifier.
-mkOscId :: UGenId -> Rate -> Name -> [UGen] -> Int -> UGen
-mkOscId z = mkOsc_ (Just z)
-
-mkOscMCE_ :: Maybe UGenId -> Rate -> Name -> [UGen] -> UGen -> Int -> UGen
-mkOscMCE_ z r c i j o = mkOsc_ z r c (i ++ mceChannels j) o
-
--- | Variant oscillator constructor with MCE collapsing input.
-mkOscMCE :: Rate -> Name -> [UGen] -> UGen -> Int -> UGen
-mkOscMCE = mkOscMCE_ Nothing
-
--- | Variant oscillator constructor with MCE collapsing input.
-mkOscMCEId :: UGenId -> Rate -> Name -> [UGen] -> UGen -> Int -> UGen
-mkOscMCEId z = mkOscMCE_ (Just z)
-
-mkFilter_ :: Maybe UGenId -> Name -> [UGen] -> Int -> UGen
-mkFilter_ z c i o = mkUGen r c i o' (Special 0) z
-    where r = maximum (map rateOf i)
-          o'= replicate o r
-
--- | Filter UGen constructor.
-mkFilter :: Name -> [UGen] -> Int -> UGen
-mkFilter = mkFilter_ Nothing
-
--- | Filter UGen constructor.
-mkFilterId :: UGenId -> Name -> [UGen] -> Int -> UGen
-mkFilterId z = mkFilter_ (Just z)
-
--- | Variant filter with rate derived from keyed input.
-mkFilterKeyed :: Name -> Int -> [UGen] -> Int -> UGen
-mkFilterKeyed c k i o = mkUGen r c i o' (Special 0) Nothing
-    where r = rateOf (i !! k)
-          o' = replicate o r
-
--- | Variant filter constructor with MCE collapsing input.
-mkFilterMCE :: Name -> [UGen] -> UGen -> Int -> UGen
-mkFilterMCE c i j o = mkFilter c (i ++ mceChannels j) o
-
--- | Lifting UGenId requiring UGens to UId
-liftU :: (UId m) => (UGenId -> a -> UGen) -> (a -> m UGen)
-liftU f a = do n <- generateUId
-               return (f (UGenId n) a)
-
-liftU2 :: (UId m) => (UGenId -> a -> b -> UGen) -> (a -> b -> m UGen)
-liftU2 f a b = do n <- generateUId
-                  return (f (UGenId n) a b)
-
-liftU3 :: (UId m) => (UGenId -> a -> b -> c -> UGen) -> (a -> b -> c -> m UGen)
-liftU3 f a b c = do n <- generateUId
-                    return (f (UGenId n) a b c)
-
-liftU4 :: (UId m) => (UGenId -> a -> b -> c -> d -> UGen) -> (a -> b -> c -> d -> m UGen)
-liftU4 f a b c d = do n <- generateUId
-                      return (f (UGenId n) a b c d)
-
diff --git a/Sound/SC3/UGen/UGen/Lift.hs b/Sound/SC3/UGen/UGen/Lift.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/UGen/Lift.hs
@@ -0,0 +1,41 @@
+module Sound.SC3.UGen.UGen.Lift where
+
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UId
+import System.IO.Unsafe
+
+-- | Lift base UGen to monadic form.
+liftU :: (UId m) => (UGenId -> a -> UGen) -> (a -> m UGen)
+liftU f a = do n <- generateUId
+               return (f (UGenId n) a)
+
+-- | Lift base UGen to monadic form.
+liftU2 :: (UId m) => (UGenId -> a -> b -> UGen) -> (a -> b -> m UGen)
+liftU2 f a b = do n <- generateUId
+                  return (f (UGenId n) a b)
+
+-- | Lift base UGen to monadic form.
+liftU3 :: (UId m) => (UGenId -> a -> b -> c -> UGen) -> (a -> b -> c -> m UGen)
+liftU3 f a b c = do n <- generateUId
+                    return (f (UGenId n) a b c)
+
+-- | Lift base UGen to monadic form.
+liftU4 :: (UId m) => (UGenId -> a -> b -> c -> d -> UGen) -> (a -> b -> c -> d -> m UGen)
+liftU4 f a b c d = do n <- generateUId
+                      return (f (UGenId n) a b c d)
+
+-- | Lift monadic UGen to unsafe form.
+liftP :: (a -> IO UGen) -> (a -> UGen)
+liftP f a = unsafePerformIO (f a)
+
+-- | Lift monadic UGen to unsafe form.
+liftP2 :: (a -> b -> IO UGen) -> (a -> b -> UGen)
+liftP2 f a b = unsafePerformIO (f a b)
+
+-- | Lift monadic UGen to unsafe form.
+liftP3 :: (a -> b -> c -> IO UGen) -> (a -> b -> c -> UGen)
+liftP3 f a b c = unsafePerformIO (f a b c)
+
+-- | Lift monadic UGen to unsafe form.
+liftP4 :: (a -> b -> c -> d -> IO UGen) -> (a -> b -> c -> d -> UGen)
+liftP4 f a b c d = unsafePerformIO (f a b c d)
diff --git a/Sound/SC3/UGen/UGen/MCE.hs b/Sound/SC3/UGen/UGen/MCE.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/UGen/MCE.hs
+++ /dev/null
@@ -1,60 +0,0 @@
-module Sound.SC3.UGen.UGen.MCE where
-
-import Data.List (transpose)
-import Sound.SC3.UGen.UGen
-import Sound.SC3.UGen.UGen.Predicate
-
--- * Multiple Channel Expansion
-
--- | Number of channels to expand to.
-mceDegree :: UGen -> Int
-mceDegree (MCE l) = length l
-mceDegree (MRG u _) = mceDegree u
-mceDegree _ = error "mceDegree: illegal ugen"
-
--- | Extend UGen to specified degree.
-mceExtend :: Int -> UGen -> [UGen]
-mceExtend n (MCE l) = take n (cycle l)
-mceExtend n (MRG x y) = (MRG r y : rs) where (r:rs) = mceExtend n x
-mceExtend n u = replicate n u
-
--- | Apply MCE transformation.
-mceTransform :: UGen -> UGen
-mceTransform (Primitive r n i o s d) = MCE (map f i')
-    where f j = Primitive r n j o s d
-          upr = maximum (map mceDegree (filter isMCE i))
-          i' = transpose (map (mceExtend upr) i)
-mceTransform _ = error "mceTransform: illegal ugen"
-
--- | Apply MCE transformation if required.
-mceExpand :: UGen -> UGen
-mceExpand (MCE l) = MCE (map mceExpand l)
-mceExpand (MRG x y) = MRG (mceExpand x) y
-mceExpand u = if required u then mceExpand (mceTransform u) else u
-    where required (Primitive _ _ i _ _ _) = not (null (filter isMCE i))
-          required (MCE l) = any required l
-          required _ = False
-
--- | Apply UGen list operation on MCE contents.
-mceEdit :: ([UGen] -> [UGen]) -> UGen -> UGen
-mceEdit f (MCE l) = MCE (f l)
-mceEdit _ _ = error "mceEdit: non MCE value"
-
--- | Reverse order of channels at MCE.
-mceReverse :: UGen -> UGen
-mceReverse = mceEdit reverse
-
--- | Obtain indexed channel at MCE.
-mceChannel :: Int -> UGen -> UGen
-mceChannel n (MCE l) = l !! n
-mceChannel _ _ = error "mceChannel: non MCE value"
-
--- | Output channels of UGen as a list.
-mceChannels :: UGen -> [UGen]
-mceChannels (MCE l) = l
-mceChannels (MRG x y) = (MRG r y) : rs where (r:rs) = mceChannels x
-mceChannels u = [u]
-
--- | Transpose rows and columns, ie. {{a,b},{c,d}} to {{a,c},{b,d}}.
-mceTranspose :: UGen -> UGen
-mceTranspose u = mce (map mce (transpose (map mceChannels (mceChannels u))))
diff --git a/Sound/SC3/UGen/UGen/Math.hs b/Sound/SC3/UGen/UGen/Math.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/UGen/Math.hs
+++ /dev/null
@@ -1,83 +0,0 @@
-module Sound.SC3.UGen.UGen.Math () where
-
-import System.Random (Random, randomR, random)
-import Sound.SC3.UGen.Operator (Unary(..),Binary(..))
-import Sound.SC3.UGen.UGen
-import Sound.SC3.UGen.UGen.Construct
-
-instance Num UGen where
-    negate         = mkUnaryOperator Neg negate
-    (+)            = mkBinaryOperator Add (+)
-    (-)            = mkBinaryOperator Sub (-)
-    (*)            = mkBinaryOperator Mul (*)
-    abs            = mkUnaryOperator Abs abs
-    signum         = mkUnaryOperator Sign signum
-    fromInteger    = Constant . fromInteger
-
-instance Fractional UGen where
-    recip          = mkUnaryOperator Recip recip
-    (/)            = mkBinaryOperator FDiv (/)
-    fromRational   = Constant . fromRational
-
-instance Floating UGen where
-    pi             = Constant pi
-    exp            = mkUnaryOperator Exp exp
-    log            = mkUnaryOperator Log log
-    sqrt           = mkUnaryOperator Sqrt sqrt
-    (**)           = mkBinaryOperator Pow (**)
-    logBase a b    = log b / log a
-    sin            = mkUnaryOperator Sin sin
-    cos            = mkUnaryOperator Cos cos
-    tan            = mkUnaryOperator Tan tan
-    asin           = mkUnaryOperator ArcSin asin
-    acos           = mkUnaryOperator ArcCos acos
-    atan           = mkUnaryOperator ArcTan atan
-    sinh           = mkUnaryOperator SinH sinh
-    cosh           = mkUnaryOperator CosH cosh
-    tanh           = mkUnaryOperator TanH tanh
-    asinh x        = log (sqrt (x*x+1) + x)
-    acosh x        = log (sqrt (x*x-1) + x)
-    atanh x        = (log (1+x) - log (1-x)) / 2
-
-instance Real UGen where
-    toRational (Constant n) = toRational n
-    toRational _ = error "toRational at non-constant UGen"
-
-instance Integral UGen where
-    quot = mkBinaryOperator IDiv undefined
-    rem = mkBinaryOperator Mod undefined
-    quotRem a b = (quot a b, rem a b)
-    div = mkBinaryOperator IDiv undefined
-    mod = mkBinaryOperator Mod undefined
-    toInteger (Constant n) = floor n
-    toInteger _ = error "toInteger at non-constant UGen"
-
-instance Ord UGen where
-    (Constant a) <  (Constant b) = a <  b
-    _            <  _            = error "< at UGen is partial, see <*"
-    (Constant a) <= (Constant b) = a <= b
-    _            <= _            = error "<= at UGen is partial, see <=*"
-    (Constant a) >  (Constant b) = a <  b
-    _            >  _            = error "> at UGen is partial, see >*"
-    (Constant a) >= (Constant b) = a >= b
-    _            >= _            = error ">= at UGen is partial, see >=*"
-    min  = mkBinaryOperator Min min
-    max  = mkBinaryOperator Max max
-
-instance Enum UGen where
-    succ u                = u + 1
-    pred u                = u - 1
-    toEnum i              = constant i
-    fromEnum (Constant n) = truncate n
-    fromEnum _            = error "cannot enumerate non-constant UGens"
-    enumFrom              = iterate (+1)
-    enumFromThen n m      = iterate (+(m-n)) n
-    enumFromTo n m        = takeWhile (<= m+1/2) (enumFrom n)
-    enumFromThenTo n n' m = takeWhile (p (m + (n'-n)/2)) (enumFromThen n n')
-        where p = if n' >= n then (>=) else (<=)
-
-instance Random UGen where
-    randomR (Constant l, Constant r) g = let (n, g') = randomR (l,r) g
-                                         in (Constant n, g')
-    randomR _ _ = error "randomR: non constant (l,r)"
-    random g = randomR (-1.0, 1.0) g
diff --git a/Sound/SC3/UGen/UGen/Predicate.hs b/Sound/SC3/UGen/UGen/Predicate.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/UGen/Predicate.hs
+++ /dev/null
@@ -1,34 +0,0 @@
-module Sound.SC3.UGen.UGen.Predicate where
-
-import Sound.SC3.UGen.UGen
-
--- | Constant predicate.
-isConstant :: UGen -> Bool
-isConstant (Constant _) = True
-isConstant _            = False
-
--- | Control predicate.
-isControl :: UGen -> Bool
-isControl (Control _ _ _) = True
-isControl _               = False
-
--- | UGen predicate.
-isUGen :: UGen -> Bool
-isUGen (Primitive _ _ _ _ _ _) = True
-isUGen _ = False
-
--- | Proxy predicate.
-isProxy :: UGen -> Bool
-isProxy (Proxy _ _) = True
-isProxy _           = False
-
--- | MCE predicate.
-isMCE :: UGen -> Bool
-isMCE (MCE _) = True
-isMCE _       = False
-
--- | MRG predicate.
-isMRG :: UGen -> Bool
-isMRG (MRG _ _) = True
-isMRG _ = False
-
diff --git a/Sound/SC3/UGen/Unsafe.hs b/Sound/SC3/UGen/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/Unsafe.hs
@@ -0,0 +1,7 @@
+module Sound.SC3.UGen.Unsafe (module Sound.SC3.UGen.Demand.Unsafe,
+                              module Sound.SC3.UGen.FFT.Unsafe,
+                              module Sound.SC3.UGen.Noise.Unsafe) where
+
+import Sound.SC3.UGen.Demand.Unsafe
+import Sound.SC3.UGen.FFT.Unsafe
+import Sound.SC3.UGen.Noise.Unsafe
diff --git a/Sound/SC3/UGen/Utilities.hs b/Sound/SC3/UGen/Utilities.hs
--- a/Sound/SC3/UGen/Utilities.hs
+++ b/Sound/SC3/UGen/Utilities.hs
@@ -1,45 +1,43 @@
 module Sound.SC3.UGen.Utilities where
 
 import Sound.SC3.UGen.Enum
-import Sound.SC3.UGen.UGen (UGen(..))
-import Sound.SC3.UGen.UGen.Construct (mkOsc)
-import Sound.SC3.UGen.Rate (Rate(IR))
+import Sound.SC3.UGen.UGen
 
-fromLoop :: Loop -> UGen
-fromLoop NoLoop       = Constant 0
-fromLoop Loop         = Constant 1
-fromLoop (WithLoop u) = u
+from_loop :: Loop -> UGen
+from_loop NoLoop = Constant 0
+from_loop Loop = Constant 1
+from_loop (WithLoop u) = u
 
-fromInterpolation :: Interpolation -> UGen
-fromInterpolation NoInterpolation     = Constant 1
-fromInterpolation LinearInterpolation = Constant 2
-fromInterpolation CubicInterpolation  = Constant 4
-fromInterpolation (Interpolation u)   = u
+from_interpolation :: Interpolation -> UGen
+from_interpolation NoInterpolation = Constant 1
+from_interpolation LinearInterpolation = Constant 2
+from_interpolation CubicInterpolation = Constant 4
+from_interpolation (Interpolation u) = u
 
-fromDoneAction :: DoneAction -> UGen
-fromDoneAction DoNothing      = Constant 0
-fromDoneAction PauseSynth     = Constant 1
-fromDoneAction RemoveSynth    = Constant 2
-fromDoneAction (DoneAction u) = u
+from_done_action :: DoneAction -> UGen
+from_done_action DoNothing = Constant 0
+from_done_action PauseSynth = Constant 1
+from_done_action RemoveSynth = Constant 2
+from_done_action (DoneAction u) = u
 
-fromWarp :: Warp -> UGen
-fromWarp Linear      = Constant 0
-fromWarp Exponential = Constant 1
-fromWarp (Warp u)    = u
+from_warp :: Warp -> UGen
+from_warp Linear = Constant 0
+from_warp Exponential = Constant 1
+from_warp (Warp u) = u
 
 env_curve :: EnvCurve -> UGen
-env_curve EnvStep    = Constant 0.0
-env_curve EnvLin     = Constant 1.0
-env_curve EnvExp     = Constant 2.0 
-env_curve EnvSin     = Constant 3.0
-env_curve EnvCos     = Constant 4.0
+env_curve EnvStep = Constant 0.0
+env_curve EnvLin = Constant 1.0
+env_curve EnvExp = Constant 2.0 
+env_curve EnvSin = Constant 3.0
+env_curve EnvCos = Constant 4.0
 env_curve (EnvNum _) = Constant 5.0
-env_curve EnvSqr     = Constant 6.0
-env_curve EnvCub     = Constant 7.0
+env_curve EnvSqr = Constant 6.0
+env_curve EnvCub = Constant 7.0
 
 env_value :: EnvCurve -> UGen
 env_value (EnvNum u) = u
-env_value _          = Constant 0.0
+env_value _ = Constant 0.0
 
 d_dx :: (Num a) => [a] -> [a]
 d_dx [] = []
@@ -48,8 +46,4 @@
 d_dx (x:y:r) = y - x : d_dx (y:r)
 
 dbl :: a -> [a]
-dbl x = [x,x]
-
-mkInfoUGen :: String -> UGen
-mkInfoUGen name = mkOsc IR name [] 1
-
+dbl x = [x, x]
diff --git a/hsc3.cabal b/hsc3.cabal
--- a/hsc3.cabal
+++ b/hsc3.cabal
@@ -1,446 +1,498 @@
-Name:             hsc3
-Version:          0.2
-License:          GPL
-Copyright:        Rohan Drape, 2006-2008
-Author:           Rohan Drape
-Maintainer:       rd@slavepianos.org
-Stability:        Experimental
-Homepage:         http://slavepianos.org/rd/f/207949/
-Synopsis:         Haskell SuperCollider
-Description:      Haskell client for the SuperCollider synthesis server
-Category:         Sound
-Tested-With:      GHC==6.8.2
-Build-Type:       Simple
-Build-Depends:    base, binary, bytestring, containers, hosc == 0.2,
-                  network, random
-GHC-Options:      -Wall -fno-warn-orphans -fwarn-tabs -O2
-Exposed-modules:  Sound.SC3
-                  Sound.SC3.UGen
-                  Sound.SC3.UGen.Analysis
-                  Sound.SC3.UGen.Base
-                  Sound.SC3.UGen.Buffer
-                  Sound.SC3.UGen.Chaos
-                  Sound.SC3.UGen.Composite
-                  Sound.SC3.UGen.Demand
-                  Sound.SC3.UGen.Demand.Base
-                  Sound.SC3.UGen.Demand.Monadic
-                  Sound.SC3.UGen.Envelope
-                  Sound.SC3.UGen.Envelope.Construct
-                  Sound.SC3.UGen.Enum
-                  Sound.SC3.UGen.FFT
-                  Sound.SC3.UGen.FFT.Base
-                  Sound.SC3.UGen.FFT.Monadic
-                  Sound.SC3.UGen.Filter
-                  Sound.SC3.UGen.Graph.Naive
-                  Sound.SC3.UGen.Granular
-                  Sound.SC3.UGen.Information
-                  Sound.SC3.UGen.IO
-		  Sound.SC3.UGen.MachineListening
-                  Sound.SC3.UGen.Math
-                  Sound.SC3.UGen.Noise.Base
-                  Sound.SC3.UGen.Noise.Monadic
-                  Sound.SC3.UGen.Operator
-                  Sound.SC3.UGen.Oscillator
-                  Sound.SC3.UGen.Panner
-                  Sound.SC3.UGen.Rate
-                  Sound.SC3.UGen.UGen
-                  Sound.SC3.UGen.UGen.Construct
-                  Sound.SC3.UGen.UGen.Math
-                  Sound.SC3.UGen.UGen.MCE
-                  Sound.SC3.UGen.UGen.Predicate
-                  Sound.SC3.UGen.UId
-                  Sound.SC3.Server
-                  Sound.SC3.Server.Command
-                  Sound.SC3.Server.Play
-                  Sound.SC3.Server.Status
-                  Sound.SC3.Server.Synthdef
-                  Sound.SC3.Server.NRT
-Other-modules:    Sound.SC3.Server.Utilities
-                  Sound.SC3.UGen.Utilities
+Name:              hsc3
+Version:           0.3
+Synopsis:          Haskell SuperCollider
+Description:       hsc3 provides Sound.SC3, a haskell module that 
+                   facilitates using haskell as a client to the 
+                   SuperCollider synthesis server.  
+License:           GPL
+Category:          Sound
+Copyright:         (c) Rohan Drape, 2006-2008
+Author:            Rohan Drape
+Maintainer:        rd@slavepianos.org
+Stability:         Experimental
+Homepage:          http://slavepianos.org/rd/f/207949/
+Tested-With:       GHC==6.8.2
+Build-Type:        Simple
+Cabal-Version:     >= 1.2
 
-Data-files:       README
-                  emacs/hsc3.el
-                  -- The below is appended by:
-                  -- find Help -name "*.*hs" | sort | \
-                  -- sed "s/^/                  /" >> hsc3.cabal
-                  Help/Graphs/aleatoric-quartet.lhs
-                  Help/Graphs/analog-bubbles.lhs
-                  Help/Graphs/babbling-brook.lhs
-                  Help/Graphs/bit-reduction.lhs
-                  Help/Graphs/bowed-string.lhs
-                  Help/Graphs/ccomb.lhs
-                  Help/Graphs/chain-saw.lhs
-                  Help/Graphs/chrd.lhs
-                  Help/Graphs/cricket.lhs
-                  Help/Graphs/crotale.lhs
-                  Help/Graphs/cut-outs.lhs
-                  Help/Graphs/cymbalism.lhs
-                  Help/Graphs/deep-sea.lhs
-                  Help/Graphs/demanding-studies.lhs
-                  Help/Graphs/dial-history.lhs
-                  Help/Graphs/discretion.lhs
-                  Help/Graphs/drummer.lhs
-                  Help/Graphs/eggcrate.lhs
-                  Help/Graphs/forest-sounds.lhs
-                  Help/Graphs/fwalk.lhs
-                  Help/Graphs/half-life.lhs
-                  Help/Graphs/harmonic-swimming.lhs
-                  Help/Graphs/harmonic-tumbling.lhs
-                  Help/Graphs/h-chatter.lhs
-                  Help/Graphs/hh-808.lhs
-                  Help/Graphs/implosion.lhs
-                  Help/Graphs/karplus-strong.lhs
-                  Help/Graphs/klink.lhs
-                  Help/Graphs/k-ppr.lhs
-                  Help/Graphs/lfo-modulation.lhs
-                  Help/Graphs/lf-pulses.lhs
-                  Help/Graphs/modal-space.lhs
-                  Help/Graphs/moto-rev.lhs
-                  Help/Graphs/mouse-clatter.lhs
-                  Help/Graphs/noise-burst-sweep.lhs
-                  Help/Graphs/one-line.lhs
-                  Help/Graphs/oscillator-cluster.lhs
-                  Help/Graphs/pattern-buffer.lhs
-                  Help/Graphs/plucked-strings.lhs
-                  Help/Graphs/police-state.lhs
-                  Help/Graphs/pulsing-bottles.lhs
-                  Help/Graphs/record-scratcher.lhs
-                  Help/Graphs/red-frik.lhs
-                  Help/Graphs/reverberated-sine-percussion.lhs
-                  Help/Graphs/sample-and-hold-liquidities.lhs
-                  Help/Graphs/s-chirp.lhs
-                  Help/Graphs/scratchy.lhs
-                  Help/Graphs/scritto.lhs
-                  Help/Graphs/shepard-tones.lhs
-                  Help/Graphs/shifting-pulses.lhs
-                  Help/Graphs/snare-909.lhs
-                  Help/Graphs/spe.lhs
-                  Help/Graphs/sprinkler.lhs
-                  Help/Graphs/strummable-guitar.lhs
-                  Help/Graphs/sweepy-noise.lhs
-                  Help/Graphs/synthetic-piano.lhs
-                  Help/Graphs/tank.lhs
-                  Help/Graphs/theremin.lhs
-                  Help/Graphs/three-cpsw.lhs
-                  Help/Graphs/tsort.lhs
-                  Help/Graphs/what-was-i-thinking.lhs
-                  Help/Graphs/wind-metals.lhs
-                  Help/Graphs/xy-interference.lhs
-                  Help/hsc3.help.lhs
-                  Help/Server/b_alloc.help.lhs
-                  Help/Server/b_allocRead.help.lhs
-                  Help/Server/b_close.help.lhs
-                  Help/Server/b_fill.help.lhs
-                  Help/Server/b_free.help.lhs
-                  Help/Server/b_gen.help.lhs
-                  Help/Server/b_get.help.lhs
-                  Help/Server/b_getn.help.lhs
-                  Help/Server/b_query.help.lhs
-                  Help/Server/b_read.help.lhs
-                  Help/Server/b_set.help.lhs
-                  Help/Server/b_setn.help.lhs
-                  Help/Server/b_write.help.lhs
-                  Help/Server/b_zero.help.lhs
-                  Help/Server/c_fill.help.lhs
-                  Help/Server/c_get.help.lhs
-                  Help/Server/c_getn.help.lhs
-                  Help/Server/clearSched.help.lhs
-                  Help/Server/c_set.help.lhs
-                  Help/Server/c_setn.help.lhs
-                  Help/Server/d_free.help.lhs
-                  Help/Server/d_loadDir.help.lhs
-                  Help/Server/d_load.help.lhs
-                  Help/Server/d_recv.help.lhs
-                  Help/Server/dumpOSC.help.lhs
-                  Help/Server/g_deepFree.help.lhs
-                  Help/Server/g_freeAll.help.lhs
-                  Help/Server/g_head.help.lhs
-                  Help/Server/g_new.help.lhs
-                  Help/Server/g_tail.help.lhs
-                  Help/Server/n_after.help.lhs
-                  Help/Server/n_before.help.lhs
-                  Help/Server/n_fill.help.lhs
-                  Help/Server/n_free.help.lhs
-                  Help/Server/n_map.help.lhs
-                  Help/Server/n_mapn.help.lhs
-                  Help/Server/notify.help.lhs
-                  Help/Server/n_query.help.lhs
-                  Help/Server/n_run.help.lhs
-                  Help/Server/n_set.help.lhs
-                  Help/Server/n_setn.help.lhs
-                  Help/Server/n_trace.help.lhs
-                  Help/Server/quit.help.lhs
-                  Help/Server/s_get.help.lhs
-                  Help/Server/s_getn.help.lhs
-                  Help/Server/s_new.help.lhs
-                  Help/Server/s_noid.help.lhs
-                  Help/Server/status.help.lhs
-                  Help/Server/sync.help.lhs
-                  Help/Server/tr.help.lhs
-                  Help/Server/u_cmd.help.lhs
-                  Help/Tutorial/Tutorial.lhs
-                  Help/UGen/Analysis/amplitude.help.lhs
-                  Help/UGen/Analysis/compander.help.lhs
-                  Help/UGen/Analysis/pitch.help.lhs
-                  Help/UGen/Analysis/runningSum.help.lhs
-                  Help/UGen/Analysis/slope.help.lhs
-                  Help/UGen/Analysis/zeroCrossing.help.lhs
-                  Help/UGen/Buffer/bufAllpassC.help.lhs
-                  Help/UGen/Buffer/bufAllpassL.help.lhs
-                  Help/UGen/Buffer/bufAllpassN.help.lhs
-                  Help/UGen/Buffer/bufChannels.help.lhs
-                  Help/UGen/Buffer/bufCombC.help.lhs
-                  Help/UGen/Buffer/bufCombL.help.lhs
-                  Help/UGen/Buffer/bufCombN.help.lhs
-                  Help/UGen/Buffer/bufDelayC.help.lhs
-                  Help/UGen/Buffer/bufDelayL.help.lhs
-                  Help/UGen/Buffer/bufDelayN.help.lhs
-                  Help/UGen/Buffer/bufDur.help.lhs
-                  Help/UGen/Buffer/bufFrames.help.lhs
-                  Help/UGen/Buffer/bufRateScale.help.lhs
-                  Help/UGen/Buffer/bufRd.help.lhs
-                  Help/UGen/Buffer/bufSampleRate.help.lhs
-                  Help/UGen/Buffer/detectIndex.help.lhs
-                  Help/UGen/Buffer/index.help.lhs
-                  Help/UGen/Buffer/indexInBetween.help.lhs
-                  Help/UGen/Buffer/osc.help.lhs
-                  Help/UGen/Buffer/playBuf.help.lhs
-                  Help/UGen/Buffer/recordBuf.help.lhs
-                  Help/UGen/Buffer/vOsc.help.lhs
-                  Help/UGen/Chaos/crackle.help.lhs
-                  Help/UGen/Chaos/cuspL.help.lhs
-                  Help/UGen/Chaos/cuspN.help.lhs
-                  Help/UGen/Chaos/fbSineC.help.lhs
-                  Help/UGen/Chaos/fbSineL.help.lhs
-                  Help/UGen/Chaos/fbSineN.help.lhs
-                  Help/UGen/Chaos/henonC.help.lhs
-                  Help/UGen/Chaos/henonL.help.lhs
-                  Help/UGen/Chaos/henonN.help.lhs
-                  Help/UGen/Chaos/latoocarfianC.help.lhs
-                  Help/UGen/Chaos/linCongC.help.lhs
-                  Help/UGen/Chaos/linCongL.help.lhs
-                  Help/UGen/Chaos/linCongN.help.lhs
-                  Help/UGen/Chaos/logistic.help.lhs
-                  Help/UGen/Chaos/lorenzL.help.lhs
-                  Help/UGen/Chaos/quadC.help.lhs
-                  Help/UGen/Chaos/quadL.help.lhs
-                  Help/UGen/Chaos/quadN.help.lhs
-                  Help/UGen/Chaos/rossler.help.lhs
-                  Help/UGen/Demand/dbrown.help.lhs
-                  Help/UGen/Demand/dbufrd.help.lhs
-                  Help/UGen/Demand/dbufwr.help.lhs
-                  Help/UGen/Demand/demandEnvGen.help.lhs
-                  Help/UGen/Demand/demand.help.lhs
-                  Help/UGen/Demand/dgeom.help.lhs
-                  Help/UGen/Demand/dibrown.help.lhs
-                  Help/UGen/Demand/diwhite.help.lhs
-                  Help/UGen/Demand/drand.help.lhs
-                  Help/UGen/Demand/dseq.help.lhs
-                  Help/UGen/Demand/dser.help.lhs
-                  Help/UGen/Demand/dseries.help.lhs
-                  Help/UGen/Demand/dswitch1.help.lhs
-                  Help/UGen/Demand/duty.help.lhs
-                  Help/UGen/Demand/dwhite.help.lhs
-                  Help/UGen/Demand/dxrand.help.lhs
-                  Help/UGen/Demand/tDuty.help.lhs
-                  Help/UGen/Envelope/detectSilence.help.lhs
-                  Help/UGen/Envelope/done.help.lhs
-                  Help/UGen/Envelope/envGen.help.lhs
-                  Help/UGen/Envelope/free.help.lhs
-                  Help/UGen/Envelope/freeSelf.help.lhs
-                  Help/UGen/Envelope/freeSelfWhenDone.help.lhs
-                  Help/UGen/Envelope/line.help.lhs
-                  Help/UGen/Envelope/linen.help.lhs
-                  Help/UGen/Envelope/pause.help.lhs
-                  Help/UGen/Envelope/pauseSelf.help.lhs
-                  Help/UGen/Envelope/pauseSelfWhenDone.help.lhs
-                  Help/UGen/Envelope/xLine.help.lhs
-                  Help/UGen/FFT/convolution.help.lhs
-                  Help/UGen/FFT/fft.help.lhs
-                  Help/UGen/FFT/ifft.help.lhs
-                  Help/UGen/FFT/packFFT.help.lhs
-                  Help/UGen/FFT/pv_BinScramble.help.lhs
-                  Help/UGen/FFT/pv_BinShift.help.lhs
-                  Help/UGen/FFT/pv_BinWipe.help.lhs
-                  Help/UGen/FFT/pv_BrickWall.help.lhs
-                  Help/UGen/FFT/pvcollect.help.lhs
-                  Help/UGen/FFT/pv_ConformalMap.help.lhs
-                  Help/UGen/FFT/pv_Copy.help.lhs
-                  Help/UGen/FFT/pv_Diffuser.help.lhs
-                  Help/UGen/FFT/pv_LocalMax.help.lhs
-                  Help/UGen/FFT/pv_MagAbove.help.lhs
-                  Help/UGen/FFT/pv_MagBelow.help.lhs
-                  Help/UGen/FFT/pv_MagClip.help.lhs
-                  Help/UGen/FFT/pv_MagFreeze.help.lhs
-                  Help/UGen/FFT/pv_RandComb.help.lhs
-                  Help/UGen/FFT/pv_RandWipe.help.lhs
-                  Help/UGen/FFT/pv_RectComb.help.lhs
-                  Help/UGen/Filter/allpassC.help.lhs
-                  Help/UGen/Filter/allpassL.help.lhs
-                  Help/UGen/Filter/allpassN.help.lhs
-                  Help/UGen/Filter/bpf.help.lhs
-                  Help/UGen/Filter/bpz2.help.lhs
-                  Help/UGen/Filter/brf.help.lhs
-                  Help/UGen/Filter/clip.help.lhs
-                  Help/UGen/Filter/combC.help.lhs
-                  Help/UGen/Filter/combL.help.lhs
-                  Help/UGen/Filter/combN.help.lhs
-                  Help/UGen/Filter/decay2.help.lhs
-                  Help/UGen/Filter/decay.help.lhs
-                  Help/UGen/Filter/degreeToKey.help.lhs
-                  Help/UGen/Filter/delay1.help.lhs
-                  Help/UGen/Filter/delay2.help.lhs
-                  Help/UGen/Filter/delayA.help.lhs
-                  Help/UGen/Filter/delayL.help.lhs
-                  Help/UGen/Filter/delayN.help.lhs
-                  Help/UGen/Filter/formlet.help.lhs
-                  Help/UGen/Filter/fos.help.lhs
-                  Help/UGen/Filter/freqShift.help.lhs
-                  Help/UGen/Filter/hasher.help.lhs
-                  Help/UGen/Filter/hpf.help.lhs
-                  Help/UGen/Filter/hpz1.help.lhs
-                  Help/UGen/Filter/hpz2.help.lhs
-                  Help/UGen/Filter/klank.help.lhs
-                  Help/UGen/Filter/lag2.help.lhs
-                  Help/UGen/Filter/lag3.help.lhs
-                  Help/UGen/Filter/lag.help.lhs
-                  Help/UGen/Filter/latch.help.lhs
-                  Help/UGen/Filter/leakDC.help.lhs
-                  Help/UGen/Filter/limiter.help.lhs
-                  Help/UGen/Filter/linExp.help.lhs
-                  Help/UGen/Filter/linLin.help.lhs
-                  Help/UGen/Filter/lpf.help.lhs
-                  Help/UGen/Filter/lpz1.help.lhs
-                  Help/UGen/Filter/lpz2.help.lhs
-                  Help/UGen/Filter/mantissaMask.help.lhs
-                  Help/UGen/Filter/median.help.lhs
-                  Help/UGen/Filter/moogFF.help.lhs
-                  Help/UGen/Filter/normalizer.help.lhs
-                  Help/UGen/Filter/onePole.help.lhs
-                  Help/UGen/Filter/oneZero.help.lhs
-                  Help/UGen/Filter/pitchShift.help.lhs
-                  Help/UGen/Filter/pluck.help.lhs
-                  Help/UGen/Filter/resonz.help.lhs
-                  Help/UGen/Filter/rhpf.help.lhs
-                  Help/UGen/Filter/ringz.help.lhs
-                  Help/UGen/Filter/rlpf.help.lhs
-                  Help/UGen/Filter/select.help.lhs
-                  Help/UGen/Filter/shaper.help.lhs
-                  Help/UGen/Filter/slew.help.lhs
-                  Help/UGen/Filter/sos.help.lhs
-                  Help/UGen/Filter/twoPole.help.lhs
-                  Help/UGen/Filter/twoZero.help.lhs
-                  Help/UGen/Filter/wrapIndex.help.lhs
-                  Help/UGen/Granular/grainBuf.help.lhs
-                  Help/UGen/Granular/grainFM.help.lhs
-                  Help/UGen/Granular/grainIn.help.lhs
-                  Help/UGen/Granular/grainSin.help.lhs
-                  Help/UGen/Granular/warp1.help.lhs
-                  Help/UGen/Information/controlRate.help.lhs
-                  Help/UGen/Information/numAudioBuses.help.lhs
-                  Help/UGen/Information/numBuffers.help.lhs
-                  Help/UGen/Information/numControlBuses.help.lhs
-                  Help/UGen/Information/numInputBuses.help.lhs
-                  Help/UGen/Information/numOutputBuses.help.lhs
-                  Help/UGen/Information/numRunningSynths.help.lhs
-                  Help/UGen/Information/radiansPerSample.help.lhs
-                  Help/UGen/Information/sampleDur.help.lhs
-                  Help/UGen/Information/sampleRate.help.lhs
-                  Help/UGen/Information/subsampleOffset.help.lhs
-                  Help/UGen/IO/inFeedback.help.lhs
-                  Help/UGen/IO/in.help.lhs
-                  Help/UGen/IO/inTrig.help.lhs
-                  Help/UGen/IO/keyState.help.lhs
-                  Help/UGen/IO/lagIn.lhs
-                  Help/UGen/IO/localIn.help.lhs
-                  Help/UGen/IO/localOut.help.lhs
-                  Help/UGen/IO/mouseButton.help.lhs
-                  Help/UGen/IO/mouseX.help.lhs
-                  Help/UGen/IO/mouseY.help.lhs
-                  Help/UGen/IO/offsetOut.help.lhs
-                  Help/UGen/IO/out.help.lhs
-                  Help/UGen/IO/replaceOut.help.lhs
-                  Help/UGen/IO/xOut.help.lhs
-                  Help/UGen/Math/absDif.help.lhs
-                  Help/UGen/Math/abs.help.lhs
-                  Help/UGen/Math/amClip.help.lhs
-                  Help/UGen/Math/atan2.help.lhs
-                  Help/UGen/Math/clip2.help.lhs
-                  Help/UGen/Math/difSqr.help.lhs
-                  Help/UGen/Math/distort.help.lhs
-                  Help/UGen/Math/fold2.help.lhs
-                  Help/UGen/Math/hypot.help.lhs
-                  Help/UGen/Math/ring1.help.lhs
-                  Help/UGen/Math/scaleNeg.help.lhs
-                  Help/UGen/Math/softClip.help.lhs
-                  Help/UGen/Math/sumSqr.help.lhs
-                  Help/UGen/Math/thresh.help.lhs
-                  Help/UGen/Noise/brownNoise.help.lhs
-                  Help/UGen/Noise/clipNoise.help.lhs
-                  Help/UGen/Noise/coinGate.help.lhs
-                  Help/UGen/Noise/dust2.help.lhs
-                  Help/UGen/Noise/dust.help.lhs
-                  Help/UGen/Noise/expRand.help.lhs
-                  Help/UGen/Noise/grayNoise.help.lhs
-                  Help/UGen/Noise/iRand.help.lhs
-                  Help/UGen/Noise/lfClipNoise.help.lhs
-                  Help/UGen/Noise/lfdClipNoise.help.lhs
-                  Help/UGen/Noise/lfdNoise0.help.lhs
-                  Help/UGen/Noise/lfdNoise1.help.lhs
-                  Help/UGen/Noise/lfdNoise3.help.lhs
-                  Help/UGen/Noise/lfNoise0.help.lhs
-                  Help/UGen/Noise/lfNoise1.help.lhs
-                  Help/UGen/Noise/lfNoise2.help.lhs
-                  Help/UGen/Noise/linRand.help.lhs
-                  Help/UGen/Noise/nRand.help.lhs
-                  Help/UGen/Noise/pinkNoise.help.lhs
-                  Help/UGen/Noise/rand.help.lhs
-                  Help/UGen/Noise/randID.help.lhs
-                  Help/UGen/Noise/randSeed.help.lhs
-                  Help/UGen/Noise/tExpRand.help.lhs
-                  Help/UGen/Noise/tiRand.help.lhs
-                  Help/UGen/Noise/tRand.help.lhs
-                  Help/UGen/Noise/whiteNoise.help.lhs
-                  Help/UGen/Oscillator/blip.help.lhs
-                  Help/UGen/Oscillator/formant.help.lhs
-                  Help/UGen/Oscillator/fSinOsc.help.lhs
-                  Help/UGen/Oscillator/gendy1.help.lhs
-                  Help/UGen/Oscillator/impulse.help.lhs
-                  Help/UGen/Oscillator/klang.help.lhs
-                  Help/UGen/Oscillator/lfCub.help.lhs
-                  Help/UGen/Oscillator/lfPar.help.lhs
-                  Help/UGen/Oscillator/lfPulse.help.lhs
-                  Help/UGen/Oscillator/lfSaw.help.lhs
-                  Help/UGen/Oscillator/lfTri.help.lhs
-                  Help/UGen/Oscillator/oscN.help.lhs
-                  Help/UGen/Oscillator/pulse.help.lhs
-                  Help/UGen/Oscillator/saw.help.lhs
-                  Help/UGen/Oscillator/silent.help.lhs
-                  Help/UGen/Oscillator/sinOsc.help.lhs
-                  Help/UGen/Oscillator/syncSaw.help.lhs
-                  Help/UGen/Oscillator/tGrains.help.lhs
-                  Help/UGen/Oscillator/twChoose.help.lhs
-                  Help/UGen/Oscillator/twindex.help.lhs
-                  Help/UGen/Panner/linPan2.help.lhs
-                  Help/UGen/Panner/pan2.help.lhs
-                  Help/UGen/Panner/rotate2.help.lhs
-                  Help/UGen/Panner/splay.help.lhs
-                  Help/UGen/Trigger/gate.help.lhs
-                  Help/UGen/Trigger/inRange.help.lhs
-                  Help/UGen/Trigger/lastValue.help.lhs
-                  Help/UGen/Trigger/mostChange.help.lhs
-                  Help/UGen/Trigger/peak.help.lhs
-                  Help/UGen/Trigger/phasor.help.lhs
-                  Help/UGen/Trigger/pulseCount.help.lhs
-                  Help/UGen/Trigger/pulseDivider.help.lhs
-                  Help/UGen/Trigger/runningMax.help.lhs
-                  Help/UGen/Trigger/runningMin.help.lhs
-                  Help/UGen/Trigger/sendTrig.lhs
-                  Help/UGen/Trigger/setResetFF.help.lhs
-                  Help/UGen/Trigger/stepper.help.lhs
-                  Help/UGen/Trigger/sweep.help.lhs
-                  Help/UGen/Trigger/tDelay.help.lhs
-                  Help/UGen/Trigger/timer.help.lhs
-                  Help/UGen/Trigger/toggleFF.help.lhs
-                  Help/UGen/Trigger/trig1.help.lhs
-                  Help/UGen/Trigger/trig.help.lhs
+Data-files:        README
+                   emacs/hsc3.el
+                   -- The below is appended by:
+                   -- find Help -name "*.*hs" | sort | \
+                   -- sed "s/^/                   /" >> hsc3.cabal
+                   Help/Graphs/adso.lhs
+                   Help/Graphs/aleatoric-quartet.lhs
+                   Help/Graphs/analog-bubbles.lhs
+                   Help/Graphs/babbling-brook.lhs
+                   Help/Graphs/bit-reduction.lhs
+                   Help/Graphs/bottle.lhs
+                   Help/Graphs/bowed-string.lhs
+                   Help/Graphs/ccomb.lhs
+                   Help/Graphs/chain-saw.lhs
+                   Help/Graphs/chrd.lhs
+                   Help/Graphs/cricket.lhs
+                   Help/Graphs/crotale.lhs
+                   Help/Graphs/cut-outs.lhs
+                   Help/Graphs/cymbalism.lhs
+                   Help/Graphs/deep-sea.lhs
+                   Help/Graphs/demanding-studies.lhs
+                   Help/Graphs/dial-history.lhs
+                   Help/Graphs/diffraction.lhs
+                   Help/Graphs/discretion.lhs
+                   Help/Graphs/drummer.lhs
+                   Help/Graphs/eggcrate.lhs
+                   Help/Graphs/e-lamell.lhs
+                   Help/Graphs/feedr.lhs
+                   Help/Graphs/f-lets.lhs
+                   Help/Graphs/fm-iter.lhs
+                   Help/Graphs/fm-kltr.lhs
+                   Help/Graphs/forest-sounds.lhs
+                   Help/Graphs/fwalk.lhs
+                   Help/Graphs/half-life.lhs
+                   Help/Graphs/harmonic-swimming.lhs
+                   Help/Graphs/harmonic-tumbling.lhs
+                   Help/Graphs/h-chatter.lhs
+                   Help/Graphs/hh-808.lhs
+                   Help/Graphs/implosion.lhs
+                   Help/Graphs/karplus-strong.lhs
+                   Help/Graphs/klink.lhs
+                   Help/Graphs/k-ppr.lhs
+                   Help/Graphs/lfo-modulation.lhs
+                   Help/Graphs/lf-pulses.lhs
+                   Help/Graphs/lg-timed.lhs
+                   Help/Graphs/lin-sosc.lhs
+                   Help/Graphs/modal-space.lhs
+                   Help/Graphs/moto-rev.lhs
+                   Help/Graphs/mouse-clatter.lhs
+                   Help/Graphs/nharm.lhs
+                   Help/Graphs/noise-burst-sweep.lhs
+                   Help/Graphs/one-line.lhs
+                   Help/Graphs/oscillator-cluster.lhs
+                   Help/Graphs/pattern-buffer.lhs
+                   Help/Graphs/plucked-strings.lhs
+                   Help/Graphs/police-state.lhs
+                   Help/Graphs/pulsing-bottles.lhs
+                   Help/Graphs/record-scratcher.lhs
+                   Help/Graphs/red-frik.lhs
+                   Help/Graphs/reverberated-sine-percussion.lhs
+                   Help/Graphs/rm-octaver.lhs
+                   Help/Graphs/rzblp.lhs
+                   Help/Graphs/sample-and-hold-liquidities.lhs
+                   Help/Graphs/s-chirp.lhs
+                   Help/Graphs/scratchy.lhs
+                   Help/Graphs/scritto.lhs
+                   Help/Graphs/shepard-tones.lhs
+                   Help/Graphs/shifting-pulses.lhs
+                   Help/Graphs/snare-909.lhs
+                   Help/Graphs/sosc-lp.lhs
+                   Help/Graphs/spe.lhs
+                   Help/Graphs/sprinkler.lhs
+                   Help/Graphs/strummable-guitar.lhs
+                   Help/Graphs/sweepy-noise.lhs
+                   Help/Graphs/synthetic-piano.lhs
+                   Help/Graphs/tank.lhs
+                   Help/Graphs/tgb.lhs
+                   Help/Graphs/tgr-rpr.lhs
+                   Help/Graphs/theremin.lhs
+                   Help/Graphs/three-cpsw.lhs
+                   Help/Graphs/tipnso.lhs
+                   Help/Graphs/trkl.lhs
+                   Help/Graphs/trmlo.lhs
+                   Help/Graphs/tr-out.lhs
+                   Help/Graphs/tsort.lhs
+                   Help/Graphs/vlc-distrtn.lhs
+                   Help/Graphs/voscil.lhs
+                   Help/Graphs/what-was-i-thinking.lhs
+                   Help/Graphs/wial.lhs
+                   Help/Graphs/wind-metals.lhs
+                   Help/Graphs/xy-interference.lhs
+                   Help/hsc3.help.lhs
+                   Help/Server/b_alloc.help.lhs
+                   Help/Server/b_allocRead.help.lhs
+                   Help/Server/b_close.help.lhs
+                   Help/Server/b_fill.help.lhs
+                   Help/Server/b_free.help.lhs
+                   Help/Server/b_gen.help.lhs
+                   Help/Server/b_get.help.lhs
+                   Help/Server/b_getn.help.lhs
+                   Help/Server/b_query.help.lhs
+                   Help/Server/b_read.help.lhs
+                   Help/Server/b_set.help.lhs
+                   Help/Server/b_setn.help.lhs
+                   Help/Server/b_write.help.lhs
+                   Help/Server/b_zero.help.lhs
+                   Help/Server/c_fill.help.lhs
+                   Help/Server/c_get.help.lhs
+                   Help/Server/c_getn.help.lhs
+                   Help/Server/clearSched.help.lhs
+                   Help/Server/c_set.help.lhs
+                   Help/Server/c_setn.help.lhs
+                   Help/Server/d_free.help.lhs
+                   Help/Server/d_loadDir.help.lhs
+                   Help/Server/d_load.help.lhs
+                   Help/Server/d_recv.help.lhs
+                   Help/Server/dumpOSC.help.lhs
+                   Help/Server/g_deepFree.help.lhs
+                   Help/Server/g_freeAll.help.lhs
+                   Help/Server/g_head.help.lhs
+                   Help/Server/g_new.help.lhs
+                   Help/Server/g_tail.help.lhs
+                   Help/Server/n_after.help.lhs
+                   Help/Server/n_before.help.lhs
+                   Help/Server/n_fill.help.lhs
+                   Help/Server/n_free.help.lhs
+                   Help/Server/n_map.help.lhs
+                   Help/Server/n_mapn.help.lhs
+                   Help/Server/notify.help.lhs
+                   Help/Server/n_query.help.lhs
+                   Help/Server/n_run.help.lhs
+                   Help/Server/n_set.help.lhs
+                   Help/Server/n_setn.help.lhs
+                   Help/Server/n_trace.help.lhs
+                   Help/Server/quit.help.lhs
+                   Help/Server/s_get.help.lhs
+                   Help/Server/s_getn.help.lhs
+                   Help/Server/s_new.help.lhs
+                   Help/Server/s_noid.help.lhs
+                   Help/Server/status.help.lhs
+                   Help/Server/sync.help.lhs
+                   Help/Server/tr.help.lhs
+                   Help/Server/u_cmd.help.lhs
+                   Help/Tutorial/Tutorial.lhs
+                   Help/UGen/Analysis/amplitude.help.lhs
+                   Help/UGen/Analysis/compander.help.lhs
+                   Help/UGen/Analysis/pitch.help.lhs
+                   Help/UGen/Analysis/runningSum.help.lhs
+                   Help/UGen/Analysis/slope.help.lhs
+                   Help/UGen/Analysis/zeroCrossing.help.lhs
+                   Help/UGen/Buffer/bufAllpassC.help.lhs
+                   Help/UGen/Buffer/bufAllpassL.help.lhs
+                   Help/UGen/Buffer/bufAllpassN.help.lhs
+                   Help/UGen/Buffer/bufChannels.help.lhs
+                   Help/UGen/Buffer/bufCombC.help.lhs
+                   Help/UGen/Buffer/bufCombL.help.lhs
+                   Help/UGen/Buffer/bufCombN.help.lhs
+                   Help/UGen/Buffer/bufDelayC.help.lhs
+                   Help/UGen/Buffer/bufDelayL.help.lhs
+                   Help/UGen/Buffer/bufDelayN.help.lhs
+                   Help/UGen/Buffer/bufDur.help.lhs
+                   Help/UGen/Buffer/bufFrames.help.lhs
+                   Help/UGen/Buffer/bufRateScale.help.lhs
+                   Help/UGen/Buffer/bufRd.help.lhs
+                   Help/UGen/Buffer/bufSampleRate.help.lhs
+                   Help/UGen/Buffer/detectIndex.help.lhs
+                   Help/UGen/Buffer/index.help.lhs
+                   Help/UGen/Buffer/indexInBetween.help.lhs
+                   Help/UGen/Buffer/osc.help.lhs
+                   Help/UGen/Buffer/playBuf.help.lhs
+                   Help/UGen/Buffer/recordBuf.help.lhs
+                   Help/UGen/Buffer/vOsc.help.lhs
+                   Help/UGen/Chaos/crackle.help.lhs
+                   Help/UGen/Chaos/cuspL.help.lhs
+                   Help/UGen/Chaos/cuspN.help.lhs
+                   Help/UGen/Chaos/fbSineC.help.lhs
+                   Help/UGen/Chaos/fbSineL.help.lhs
+                   Help/UGen/Chaos/fbSineN.help.lhs
+                   Help/UGen/Chaos/henonC.help.lhs
+                   Help/UGen/Chaos/henonL.help.lhs
+                   Help/UGen/Chaos/henonN.help.lhs
+                   Help/UGen/Chaos/latoocarfianC.help.lhs
+                   Help/UGen/Chaos/linCongC.help.lhs
+                   Help/UGen/Chaos/linCongL.help.lhs
+                   Help/UGen/Chaos/linCongN.help.lhs
+                   Help/UGen/Chaos/logistic.help.lhs
+                   Help/UGen/Chaos/lorenzL.help.lhs
+                   Help/UGen/Chaos/quadC.help.lhs
+                   Help/UGen/Chaos/quadL.help.lhs
+                   Help/UGen/Chaos/quadN.help.lhs
+                   Help/UGen/Chaos/rossler.help.lhs
+                   Help/UGen/Control/mrg2.help.lhs
+                   Help/UGen/Demand/dbrown.help.lhs
+                   Help/UGen/Demand/dbufrd.help.lhs
+                   Help/UGen/Demand/dbufwr.help.lhs
+                   Help/UGen/Demand/demandEnvGen.help.lhs
+                   Help/UGen/Demand/demand.help.lhs
+                   Help/UGen/Demand/dgeom.help.lhs
+                   Help/UGen/Demand/dibrown.help.lhs
+                   Help/UGen/Demand/diwhite.help.lhs
+                   Help/UGen/Demand/drand.help.lhs
+                   Help/UGen/Demand/dseq.help.lhs
+                   Help/UGen/Demand/dser.help.lhs
+                   Help/UGen/Demand/dseries.help.lhs
+                   Help/UGen/Demand/dswitch1.help.lhs
+                   Help/UGen/Demand/dswitch.help.lhs
+                   Help/UGen/Demand/duty.help.lhs
+                   Help/UGen/Demand/dwhite.help.lhs
+                   Help/UGen/Demand/dxrand.help.lhs
+                   Help/UGen/Demand/tDuty.help.lhs
+                   Help/UGen/Envelope/detectSilence.help.lhs
+                   Help/UGen/Envelope/done.help.lhs
+                   Help/UGen/Envelope/envGen.help.lhs
+                   Help/UGen/Envelope/free.help.lhs
+                   Help/UGen/Envelope/freeSelf.help.lhs
+                   Help/UGen/Envelope/freeSelfWhenDone.help.lhs
+                   Help/UGen/Envelope/line.help.lhs
+                   Help/UGen/Envelope/linen.help.lhs
+                   Help/UGen/Envelope/pause.help.lhs
+                   Help/UGen/Envelope/pauseSelf.help.lhs
+                   Help/UGen/Envelope/pauseSelfWhenDone.help.lhs
+                   Help/UGen/Envelope/xLine.help.lhs
+                   Help/UGen/External/atsNoiSynth.help.lhs
+                   Help/UGen/External/atsSynth.help.lhs
+                   Help/UGen/External/ay.help.lhs
+                   Help/UGen/External/lpcSynth.help.lhs
+                   Help/UGen/External/lpcVals.help.lhs
+                   Help/UGen/External/membraneCircle.help.lhs
+                   Help/UGen/External/membraneHexagon.help.lhs
+                   Help/UGen/External/pv_Invert.help.lhs
+                   Help/UGen/External/stkBowed.help.lhs
+                   Help/UGen/External/stkFlute.help.lhs
+                   Help/UGen/External/stkMandolin.help.lhs
+                   Help/UGen/External/stkModalBar.help.lhs
+                   Help/UGen/External/stkShakers.help.lhs
+                   Help/UGen/External/vosim.help.lhs
+                   Help/UGen/FFT/convolution.help.lhs
+                   Help/UGen/FFT/fft.help.lhs
+                   Help/UGen/FFT/ifft.help.lhs
+                   Help/UGen/FFT/packFFT.help.lhs
+                   Help/UGen/FFT/pv_BinScramble.help.lhs
+                   Help/UGen/FFT/pv_BinShift.help.lhs
+                   Help/UGen/FFT/pv_BinWipe.help.lhs
+                   Help/UGen/FFT/pv_BrickWall.help.lhs
+                   Help/UGen/FFT/pvcollect.help.lhs
+                   Help/UGen/FFT/pv_ConformalMap.help.lhs
+                   Help/UGen/FFT/pv_Copy.help.lhs
+                   Help/UGen/FFT/pv_Diffuser.help.lhs
+                   Help/UGen/FFT/pv_LocalMax.help.lhs
+                   Help/UGen/FFT/pv_MagAbove.help.lhs
+                   Help/UGen/FFT/pv_MagBelow.help.lhs
+                   Help/UGen/FFT/pv_MagClip.help.lhs
+                   Help/UGen/FFT/pv_MagFreeze.help.lhs
+                   Help/UGen/FFT/pv_RandComb.help.lhs
+                   Help/UGen/FFT/pv_RandWipe.help.lhs
+                   Help/UGen/FFT/pv_RectComb.help.lhs
+                   Help/UGen/Filter/allpassC.help.lhs
+                   Help/UGen/Filter/allpassL.help.lhs
+                   Help/UGen/Filter/allpassN.help.lhs
+                   Help/UGen/Filter/bpf.help.lhs
+                   Help/UGen/Filter/bpz2.help.lhs
+                   Help/UGen/Filter/brf.help.lhs
+                   Help/UGen/Filter/clip.help.lhs
+                   Help/UGen/Filter/combC.help.lhs
+                   Help/UGen/Filter/combL.help.lhs
+                   Help/UGen/Filter/combN.help.lhs
+                   Help/UGen/Filter/decay2.help.lhs
+                   Help/UGen/Filter/decay.help.lhs
+                   Help/UGen/Filter/degreeToKey.help.lhs
+                   Help/UGen/Filter/delay1.help.lhs
+                   Help/UGen/Filter/delay2.help.lhs
+                   Help/UGen/Filter/delayA.help.lhs
+                   Help/UGen/Filter/delayL.help.lhs
+                   Help/UGen/Filter/delayN.help.lhs
+                   Help/UGen/Filter/formlet.help.lhs
+                   Help/UGen/Filter/fos.help.lhs
+                   Help/UGen/Filter/freeVerb.help.lhs
+                   Help/UGen/Filter/freqShift.help.lhs
+                   Help/UGen/Filter/hasher.help.lhs
+                   Help/UGen/Filter/hpf.help.lhs
+                   Help/UGen/Filter/hpz1.help.lhs
+                   Help/UGen/Filter/hpz2.help.lhs
+                   Help/UGen/Filter/klank.help.lhs
+                   Help/UGen/Filter/lag2.help.lhs
+                   Help/UGen/Filter/lag3.help.lhs
+                   Help/UGen/Filter/lag.help.lhs
+                   Help/UGen/Filter/latch.help.lhs
+                   Help/UGen/Filter/leakDC.help.lhs
+                   Help/UGen/Filter/limiter.help.lhs
+                   Help/UGen/Filter/linExp.help.lhs
+                   Help/UGen/Filter/linLin.help.lhs
+                   Help/UGen/Filter/lpf.help.lhs
+                   Help/UGen/Filter/lpz1.help.lhs
+                   Help/UGen/Filter/lpz2.help.lhs
+                   Help/UGen/Filter/mantissaMask.help.lhs
+                   Help/UGen/Filter/median.help.lhs
+                   Help/UGen/Filter/moogFF.help.lhs
+                   Help/UGen/Filter/normalizer.help.lhs
+                   Help/UGen/Filter/onePole.help.lhs
+                   Help/UGen/Filter/oneZero.help.lhs
+                   Help/UGen/Filter/pitchShift.help.lhs
+                   Help/UGen/Filter/pluck.help.lhs
+                   Help/UGen/Filter/resonz.help.lhs
+                   Help/UGen/Filter/rhpf.help.lhs
+                   Help/UGen/Filter/ringz.help.lhs
+                   Help/UGen/Filter/rlpf.help.lhs
+                   Help/UGen/Filter/select.help.lhs
+                   Help/UGen/Filter/shaper.help.lhs
+                   Help/UGen/Filter/slew.help.lhs
+                   Help/UGen/Filter/sos.help.lhs
+                   Help/UGen/Filter/twoPole.help.lhs
+                   Help/UGen/Filter/twoZero.help.lhs
+                   Help/UGen/Filter/wrapIndex.help.lhs
+                   Help/UGen/Granular/grainBuf.help.lhs
+                   Help/UGen/Granular/grainFM.help.lhs
+                   Help/UGen/Granular/grainIn.help.lhs
+                   Help/UGen/Granular/grainSin.help.lhs
+                   Help/UGen/Granular/warp1.help.lhs
+                   Help/UGen/Information/controlRate.help.lhs
+                   Help/UGen/Information/numAudioBuses.help.lhs
+                   Help/UGen/Information/numBuffers.help.lhs
+                   Help/UGen/Information/numControlBuses.help.lhs
+                   Help/UGen/Information/numInputBuses.help.lhs
+                   Help/UGen/Information/numOutputBuses.help.lhs
+                   Help/UGen/Information/numRunningSynths.help.lhs
+                   Help/UGen/Information/radiansPerSample.help.lhs
+                   Help/UGen/Information/sampleDur.help.lhs
+                   Help/UGen/Information/sampleRate.help.lhs
+                   Help/UGen/Information/subsampleOffset.help.lhs
+                   Help/UGen/IO/inFeedback.help.lhs
+                   Help/UGen/IO/in.help.lhs
+                   Help/UGen/IO/inTrig.help.lhs
+                   Help/UGen/IO/keyState.help.lhs
+                   Help/UGen/IO/lagIn.help.lhs
+                   Help/UGen/IO/localIn.help.lhs
+                   Help/UGen/IO/localOut.help.lhs
+                   Help/UGen/IO/mouseButton.help.lhs
+                   Help/UGen/IO/mouseX.help.lhs
+                   Help/UGen/IO/mouseY.help.lhs
+                   Help/UGen/IO/offsetOut.help.lhs
+                   Help/UGen/IO/out.help.lhs
+                   Help/UGen/IO/replaceOut.help.lhs
+                   Help/UGen/IO/soundIn.help.lhs
+                   Help/UGen/IO/xOut.help.lhs
+                   Help/UGen/MachineListening/beatTrack.help.lhs
+                   Help/UGen/MachineListening/onsets.help.lhs
+                   Help/UGen/Math/absDif.help.lhs
+                   Help/UGen/Math/abs.help.lhs
+                   Help/UGen/Math/amClip.help.lhs
+                   Help/UGen/Math/atan2.help.lhs
+                   Help/UGen/Math/clip2.help.lhs
+                   Help/UGen/Math/difSqr.help.lhs
+                   Help/UGen/Math/distort.help.lhs
+                   Help/UGen/Math/fold2.help.lhs
+                   Help/UGen/Math/hypot.help.lhs
+                   Help/UGen/Math/ring1.help.lhs
+                   Help/UGen/Math/scaleNeg.help.lhs
+                   Help/UGen/Math/softClip.help.lhs
+                   Help/UGen/Math/sumSqr.help.lhs
+                   Help/UGen/Math/thresh.help.lhs
+                   Help/UGen/Noise/brownNoise.help.lhs
+                   Help/UGen/Noise/clipNoise.help.lhs
+                   Help/UGen/Noise/coinGate.help.lhs
+                   Help/UGen/Noise/dust2.help.lhs
+                   Help/UGen/Noise/dust.help.lhs
+                   Help/UGen/Noise/expRand.help.lhs
+                   Help/UGen/Noise/grayNoise.help.lhs
+                   Help/UGen/Noise/iRand.help.lhs
+                   Help/UGen/Noise/lfClipNoise.help.lhs
+                   Help/UGen/Noise/lfdClipNoise.help.lhs
+                   Help/UGen/Noise/lfdNoise0.help.lhs
+                   Help/UGen/Noise/lfdNoise1.help.lhs
+                   Help/UGen/Noise/lfdNoise3.help.lhs
+                   Help/UGen/Noise/lfNoise0.help.lhs
+                   Help/UGen/Noise/lfNoise1.help.lhs
+                   Help/UGen/Noise/lfNoise2.help.lhs
+                   Help/UGen/Noise/linRand.help.lhs
+                   Help/UGen/Noise/nRand.help.lhs
+                   Help/UGen/Noise/pinkNoise.help.lhs
+                   Help/UGen/Noise/rand.help.lhs
+                   Help/UGen/Noise/randID.help.lhs
+                   Help/UGen/Noise/randSeed.help.lhs
+                   Help/UGen/Noise/tExpRand.help.lhs
+                   Help/UGen/Noise/tiRand.help.lhs
+                   Help/UGen/Noise/tRand.help.lhs
+                   Help/UGen/Noise/whiteNoise.help.lhs
+                   Help/UGen/Oscillator/blip.help.lhs
+                   Help/UGen/Oscillator/formant.help.lhs
+                   Help/UGen/Oscillator/fSinOsc.help.lhs
+                   Help/UGen/Oscillator/gendy1.help.lhs
+                   Help/UGen/Oscillator/impulse.help.lhs
+                   Help/UGen/Oscillator/klang.help.lhs
+                   Help/UGen/Oscillator/lfCub.help.lhs
+                   Help/UGen/Oscillator/lfPar.help.lhs
+                   Help/UGen/Oscillator/lfPulse.help.lhs
+                   Help/UGen/Oscillator/lfSaw.help.lhs
+                   Help/UGen/Oscillator/lfTri.help.lhs
+                   Help/UGen/Oscillator/oscN.help.lhs
+                   Help/UGen/Oscillator/pulse.help.lhs
+                   Help/UGen/Oscillator/saw.help.lhs
+                   Help/UGen/Oscillator/silent.help.lhs
+                   Help/UGen/Oscillator/sinOsc.help.lhs
+                   Help/UGen/Oscillator/syncSaw.help.lhs
+                   Help/UGen/Oscillator/tChoose.help.lhs
+                   Help/UGen/Oscillator/tGrains.help.lhs
+                   Help/UGen/Oscillator/twChoose.help.lhs
+                   Help/UGen/Oscillator/twindex.help.lhs
+                   Help/UGen/Panner/linPan2.help.lhs
+                   Help/UGen/Panner/pan2.help.lhs
+                   Help/UGen/Panner/rotate2.help.lhs
+                   Help/UGen/Panner/splay.help.lhs
+                   Help/UGen/Trigger/gate.help.lhs
+                   Help/UGen/Trigger/inRange.help.lhs
+                   Help/UGen/Trigger/lastValue.help.lhs
+                   Help/UGen/Trigger/mostChange.help.lhs
+                   Help/UGen/Trigger/peak.help.lhs
+                   Help/UGen/Trigger/phasor.help.lhs
+                   Help/UGen/Trigger/pulseCount.help.lhs
+                   Help/UGen/Trigger/pulseDivider.help.lhs
+                   Help/UGen/Trigger/runningMax.help.lhs
+                   Help/UGen/Trigger/runningMin.help.lhs
+                   Help/UGen/Trigger/sendTrig.help.lhs
+                   Help/UGen/Trigger/setResetFF.help.lhs
+                   Help/UGen/Trigger/stepper.help.lhs
+                   Help/UGen/Trigger/sweep.help.lhs
+                   Help/UGen/Trigger/tDelay.help.lhs
+                   Help/UGen/Trigger/timer.help.lhs
+                   Help/UGen/Trigger/toggleFF.help.lhs
+                   Help/UGen/Trigger/trig1.help.lhs
+                   Help/UGen/Trigger/trig.help.lhs
+
+Library
+  Build-Depends:   base, binary, bytestring, containers, hosc == 0.3,
+                   network, random
+  GHC-Options:     -Wall -fwarn-tabs -O2
+  Exposed-modules: Sound.SC3
+                   Sound.SC3.Server
+                   Sound.SC3.Server.Command
+                   Sound.SC3.Server.NRT
+                   Sound.SC3.Server.Play
+                   Sound.SC3.Server.Status
+                   Sound.SC3.Server.Synthdef
+                   Sound.SC3.UGen
+                   Sound.SC3.UGen.Analysis
+                   Sound.SC3.UGen.Base
+                   Sound.SC3.UGen.Buffer
+                   Sound.SC3.UGen.Chaos
+                   Sound.SC3.UGen.Composite
+                   Sound.SC3.UGen.Demand
+                   Sound.SC3.UGen.Demand.Base
+                   Sound.SC3.UGen.Demand.Monadic
+                   Sound.SC3.UGen.Demand.Unsafe
+                   Sound.SC3.UGen.Enum
+                   Sound.SC3.UGen.Envelope
+                   Sound.SC3.UGen.Envelope.Construct
+                   Sound.SC3.UGen.External
+                   Sound.SC3.UGen.External.ATS
+                   Sound.SC3.UGen.External.LPC
+                   Sound.SC3.UGen.FFT
+                   Sound.SC3.UGen.FFT.Base
+                   Sound.SC3.UGen.FFT.Monadic
+                   Sound.SC3.UGen.FFT.Unsafe
+                   Sound.SC3.UGen.Filter
+                   Sound.SC3.UGen.Granular
+                   Sound.SC3.UGen.IO
+                   Sound.SC3.UGen.Information
+                   Sound.SC3.UGen.MachineListening
+                   Sound.SC3.UGen.Math
+                   Sound.SC3.UGen.Noise.Base
+                   Sound.SC3.UGen.Noise.Monadic
+                   Sound.SC3.UGen.Noise.Unsafe
+                   Sound.SC3.UGen.Operator
+                   Sound.SC3.UGen.Oscillator
+                   Sound.SC3.UGen.Panner
+                   Sound.SC3.UGen.Rate
+                   Sound.SC3.UGen.UGen
+                   Sound.SC3.UGen.UId
+                   Sound.SC3.UGen.Unsafe
+  Other-modules:   Sound.SC3.Server.Utilities
+                   Sound.SC3.UGen.Utilities
+                   Sound.SC3.UGen.UGen.Lift
