diff --git a/Help/Graphs/aleatoric-quartet.lhs b/Help/Graphs/aleatoric-quartet.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/aleatoric-quartet.lhs
@@ -0,0 +1,71 @@
+aleatoric quartet (jmcc)
+
+> let { amp = 0.07
+>     ; density = mouseX KR 0.01 1 Linear 0.1
+>     ; dmul = recip density * 0.5 * amp
+>     ; dadd = amp - dmul
+>     ; chain n f = foldl (>=>) return (replicate n f)
+>     ; rapf i = do { r <- clone 2 (rand 0 0.05)
+>                   ; return (allpassN i 0.05 r 1) }
+>     ; mk_f = do { i0 <- iRand 0 2
+>                 ; let r0 = select i0 (mce [1, 0.5, 0.25])
+>                   in do { r1 <- rand (-30) 30
+>                         ; n0 <- lfNoise0 KR r0
+>                         ; let m = lag (roundE (n0 * 7 + 66 + r1) 1) 0.2
+>                           in return (midiCPS m) } }
+>     ; mk_s = do { f <- fmap recip mk_f
+>                 ; r <- rand (-1) 1
+>                 ; x <- do { n0 <- pinkNoise AR
+>                           ; n1 <- lfNoise1 KR 8
+>                           ; return (n0 * max 0 (n1 * dmul + dadd)) }
+>                 ; return (pan2 (combL x 0.02 f 3) r 1) } }
+> in do { g <- chain 5 rapf =<< fmap sum (replicateM 4 mk_s)
+>       ; audition (out 0 (leakDC g 0.995)) }
+
+{ var amp = 0.07
+; var density = MouseX.kr(0.01, 1, 'linear', 0.1)
+; var dmul = density.reciprocal * 0.5 * amp
+; var dadd = amp - dmul
+; var rapf = { arg i
+             ; var r = Array.fill(2, { Rand(0, 0.05) })
+             ; AllpassN.ar(i, 0.05, r, 1) }
+; var mk_f = { var i0 = IRand.new(0, 2)
+             ; var r0 = Select.kr(i0, [1, 0.5, 0.25])
+             ; var r1 = Rand.new(-30, 30)
+             ; var n0 = LFNoise0.kr(r0)
+             ; var m = Lag.kr((n0 * 7 + 66 + r1).round(1), 0.2)
+             ; m.midicps }
+; var mk_s = { var f = mk_f.value.reciprocal
+             ; var r = Rand.new(-1, 1)
+             ; var n0 = PinkNoise.ar()
+             ; var n1 = LFNoise1.kr(8)
+             ; var x = n0 * 0.max(n1 * dmul + dadd)
+             ; Pan2.ar(CombL.ar(x, 0.02, f, 3), r, 1) }
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/analog-bubbles.lhs
@@ -0,0 +1,16 @@
+analog bubbles (jmcc)
+
+> let { o = lfSaw KR (mce2 8 7.23) 0 * 3 + 80
+>     ; f = lfSaw KR 0.4 0 * 24 + o
+>     ; s = sinOsc AR (midiCPS f) 0 * 0.04 }
+> in audition (out 0 (combN s 0.2 0.2 4))
+
+{ var o = LFSaw.kr([8, 7.23], 0, 3, 80)
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/babbling-brook.lhs
@@ -0,0 +1,28 @@
+babbling brook (jmcc)
+
+> let b f m a g = do { n1 <- brownNoise AR
+>                    ; n2 <- brownNoise AR
+>                    ; let n3 = lpf n2 f * m + a
+>                      in return (rhpf (onePole n1 0.99) n3 0.03 * g) }
+> in do { x <- clone 2 (b 14 400 500 0.006)
+>       ; y <- clone 2 (b 20 800 1000 0.010)
+>       ; audition (out 0 (x + y)) }
+
+{ var b = { arg f, m, a, g 
+          ; { var n1 = OnePole.ar(BrownNoise.ar, 0.99)
+            ; var n2 = LPF.ar(BrownNoise.ar, f) 
+            ; RHPF.ar(n1, n2 * m + a, 0.03, g) } }
+; var x = b.value(14, 400, 500, 0.006) ! 2
+; 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/bit-reduction.lhs b/Help/Graphs/bit-reduction.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/bit-reduction.lhs
@@ -0,0 +1,35 @@
+bit reduction (adc)
+
+sample rate decrease
+
+> do { f <- lfNoise2 KR 8
+>    ; nh <- lfNoise2 KR 3
+>    ; let { src = blip AR (f * 200 + 300) (nh * 10 + 20)
+>          ; sr = mouseX KR 1000 (sampleRate * 0.1) Exponential 0.2 }
+>      in audition (out 0 (latch src (impulse AR sr 0))) }
+
+{ var f = LFNoise2.kr(8)
+; var nh = LFNoise2.kr(3)
+; var src = Blip.ar(f * 200 + 300, nh * 10 + 20)
+; var sr = MouseX.kr(1000, s.sampleRate * 0.1, 'exponential', 0.2)
+; Out.ar(0, Latch.ar(src, Impulse.ar(sr, 0))) }.play
+
+bit rate decrease
+
+> do { f <- lfNoise2 KR 8
+>    ; nh <- lfNoise2 KR 3
+>    ; let { src = blip AR (f * 200 + 300) (nh * 10 + 20)
+>          ; sr = mouseX KR 1000 (sampleRate * 0.1) Exponential 0.2
+>          ; bit_sz = mouseY KR 1 24 Exponential 0.2
+>          ; down_sample = latch src (impulse AR sr 0)
+>          ; bit_redux = roundE down_sample (0.5 ** bit_sz) }
+>      in audition (out 0 (mce2 down_sample bit_redux)) }
+
+{ var f = LFNoise2.kr(8)
+; var nh = LFNoise2.kr(3)
+; var src = Blip.ar(f * 200 + 300, nh * 10 + 20)
+; var sr = MouseX.kr(1000, s.sampleRate * 0.1, 'exponential', 0.2)
+; var bit_sz = MouseY.kr(1, 24, 'exponential', 0.2) 
+; var down_sample = Latch.ar(src, Impulse.ar(sr, 0))
+; var bit_redux = down_sample.round(0.5 ** bit_sz)
+; Out.ar(0, [down_sample, bit_redux]) }.play
diff --git a/Help/Graphs/bowed-string.lhs b/Help/Graphs/bowed-string.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/bowed-string.lhs
@@ -0,0 +1,47 @@
+bowed string (jmcc)
+
+> let { rrand l r = getStdRandom (randomR (l, r)) 
+>     ; choose l = fmap (l !!) (rrand 0 (length l - 1))
+>     ; root = 5
+>     ; scale = map (+ root) [0, 2, 4, 5, 7, 9, 11] 
+>     ; oct = [24, 36, 48, 60, 72, 84] }
+> in do { n0 <- clone 2 (brownNoise AR)
+>       ; r0 <- expRand 0.125 0.5
+>       ; r1 <- rand 0.7 0.9
+>       ; r2 <- replicateM 12 (rand 1.0 3.0)
+>       ; f <- fmap midiCPS (liftM2 (+) (choose scale) (choose oct))
+>       ; n1 <- lfNoise1 KR r0
+>       ; let { x = n0 * 0.007 * max 0 (n1 * 0.6 + 0.4)
+>             ; geom n i z = take n (iterate (* z) i)
+>             ; iota n i z = take n (iterate (+ z) i)
+>             ; d = klankSpec (iota 12 f f) (geom 12 1 r1) r2
+>             ; k = klank x 1 0 1 d }
+>         in audition (out 0 (softClip (k * 0.1))) }
+
+{ var root = 5
+; var scale = #[0, 2, 4, 5, 7, 9, 11] + root
+; var oct = #[24, 36, 48, 60, 72, 84]
+; var f = (scale.choose + oct.choose).midicps
+; var n0 = BrownNoise.ar().dup
+; var r0 = ExpRand.new(0.125, 0.5)
+; var n1 = LFNoise1.kr(r0)
+; var r1 = Rand.new(0.7,0.9)
+; var r2 = Array.fill(12, { Rand.new(1.0, 3.0) })
+; var x = n0 * 0.007 * max(0, n1 * 0.6 + 0.4)
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/ccomb.lhs
@@ -0,0 +1,38 @@
+ccomb (rd)
+
+> let { rng l r i = linLin i (-1) 1 l r
+>     ; lwr = 48
+>     ; flwr = midiCPS lwr
+>     ; spart t = do { n <- liftM (rng lwr 72.0) (lfNoise2 KR 0.1)
+>                    ; e <- liftM (decay2 t 0.01) (tRand 0.05 0.75 t)
+>                    ; x <- liftM (* e) (whiteNoise AR)
+>                    ; m <- lfNoise2 KR 0.1
+>                    ; let f = lag (midiCPS n) 0.25
+>                      in return (combC x (recip flwr) (recip f) (rng 1 8 m)) } }
+> in do { t <- dust KR (mce2 0.75 0.35)
+>       ; audition . (out 0) . (* 0.1) . sum =<< replicateM 12 (spart t) }
+
+{ var lwr = 48
+; var flwr = lwr.midicps
+; var spart = { arg t
+              ; { var n = LFNoise2.kr(0.1).range(lwr, 72.0)
+                ; var e = Decay2.kr(t, 0.01, TRand.kr(0.05, 0.75, t))
+                ; var x = WhiteNoise.ar() * e
+                ; var m = LFNoise2.kr(0.1)
+                ; var f = Lag.kr(n.midicps, 0.25)
+                ; 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/chain-saw.lhs b/Help/Graphs/chain-saw.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/chain-saw.lhs
@@ -0,0 +1,51 @@
+chain saw (jrhb)
+
+[this graph generates long chains of unit generators and may require
+increasing the stack limit of the haskell run time system]
+
+> let { rrand l r = getStdRandom (randomR (l, r)) :: IO Double
+>     ; coin n a b = do { m <- rrand 0.0 1.0
+>                       ; return (if m > n then a else b) }
+>     ; exprange s l r = linExp s (-1) 1 l r
+>     ; chain n fn = foldr (<=<) return (replicate n fn)
+>     ; mceProduct = mceEdit (\l -> [product l])
+>     ; clipu s = clip2 s 1
+>     ; dup a = mce2 a a
+>     ; f s1 = do { xr <- liftM dup (expRand 0.1 2)
+>                 ; n1 <- lfNoise1 KR xr
+>                 ; n2 <- lfNoise1 KR xr
+>                 ; n3 <- lfNoise1 KR xr
+>                 ; f1 <- coin 0.6 (exprange n1 0.01 10) (exprange n2 10 50)
+>                 ; s2 <- coin 0.5 (1 - s1) (mceReverse s1)
+>                 ; let { f2 = linExp s1 (-1) 1 f1 (f1 * exprange n3 2 10)
+>                       ; u1 = lfSaw KR f2 0 
+>                       ; u2 = lfSaw KR (f1 * 0.1) 0 * 0.1 + 1 }
+>                   in return . clipu =<< coin 0.5 (u1 * s2) (u1 * u2) }
+>     ; inp = lfSaw KR (0.2 * mce2 1 1.1) 0
+>     ; b_freq = mce [70, 800, 9000, 5242] }
+> in do { ff <- chain 16 f inp
+>       ; let { c_saw = mceProduct (saw AR (exprange ff 6 11000))
+>             ; b_saw = dup (mix (bpf c_saw b_freq 0.2)) }
+>         in audition (out 0 (b_saw * 0.3)) }
+
+{ var f = { arg s1
+          ; var rate = ExpRand.new(0.1, 2).dup
+          ; var n1 = { LFNoise1.kr(rate).exprange(0.01, 10) }
+          ; var n2 = { LFNoise1.kr(rate).exprange(10, 50) }
+          ; var n3 = LFNoise1.kr(rate).exprange(2, 10)
+          ; var f1 = if(0.6.coin) { n1.value } { n2.value }
+          ; var s2 = [1 - s1, s1.reverse].choose
+          ; var f2 = LinExp.kr(s1, -1, 1, f1, f1 * n3)
+          ; var u1 = LFSaw.kr(f2, 0)
+          ; var u2 = LFSaw.kr(f1 * 0.1, 0, 0.1, 1)
+          ; var u3 = if(0.5.coin) { u1 * s2 } { u1 * u2 }
+          ; u3.clip2(1) }
+; var g = { arg func, n
+          ; n.do { func = func <> func }
+          ; func }
+; var inp = LFSaw.kr(0.2 * [1, 1.1], 0)
+; var b_freq = [70, 800, 9000, 5242]
+; var ff = g.(f, 4).value(inp)
+; var c_saw = Saw.ar(ff.exprange(6, 11000)).product
+; var b_saw = BPF.ar(c_saw, b_freq, 0.2).sum.dup
+; Out.ar(0, b_saw * 0.3) }.play
diff --git a/Help/Graphs/chrd.lhs b/Help/Graphs/chrd.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/chrd.lhs
@@ -0,0 +1,33 @@
+chrd (rd)
+
+> let chrd = do { r0 <- rand 0.05 0.5
+>               ; [r1, r2] <- replicateM 2 (rand (-1) 1)
+>               ; r3 <- rand 0.15 0.35
+>               ; r4 <- rand 0.005 0.01
+>               ; let { m = mce [60, 65, 72, 77, 79, 84]
+>                     ; ds = 3
+>                     ; d = mce (map (* ds) [5, 4, 5, 7, 4, 5])
+>                     ; f = midiCPS (xLine KR m (m + r0) d DoNothing)
+>                     ; z = envTrapezoid 0 r3 d r4
+>                     ; e = envGen KR 1 1 0 1 DoNothing z
+>                     ; p = xLine KR r1 r2 d DoNothing
+>                     ; o = fSinOsc AR f 0 }
+>                 in return (mix (pan2 o p e)) }
+> in audition . out 0 . mix =<< clone 9 chrd
+
+{ var chrd = { var r0 = Rand.new(0.05, 0.5)
+             ; var r1 = Rand.new(-1, 1)
+             ; var r2 = Rand.new(-1, 1)
+             ; var r3 = Rand.new(0.15, 0.35)
+             ; var r4 = Rand.new(0.005, 0.01)
+             ; var m = [60, 65, 72, 77, 79, 84]
+             ; var ds = 3
+             ; var d = [5, 4, 5, 7, 4, 5] * ds
+             ; var f = XLine.kr(m, m + r0, d).midicps
+             ; var z_ = Env.linen(r3 * d, 0, (1 - r3) * d, r4)
+             ; var z = Env.sine(d.maxItem, r4)
+             ; var e = EnvGen.kr(z, 1, 1, 0, 1)
+             ; var p = XLine.kr(r1, r2, d)
+             ; var o = SinOsc.ar(f, 0)
+             ; Mix.ar(Pan2.ar(o, p, e)) }
+; Out.ar(0, Mix.fill(9, chrd)) }.play
diff --git a/Help/Graphs/cricket.lhs b/Help/Graphs/cricket.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/cricket.lhs
@@ -0,0 +1,33 @@
+cricket (rd)
+
+> do { r1 <- clone 2 (rand 10 13)
+>    ; r2 <- clone 2 (rand 10 13)
+>    ; r3 <- clone 2 (rand 4 7)
+>    ; let { t = impulse KR 0.7 0
+>          ; e = decay2 (impulse KR r1 0) 0.001 0.005
+>          ; f = sinOsc KR r2 0 * e * r3 }
+>      in do { r4 <- clone 2 (tRand 2220 2227 t)
+>            ; audition (out 0 (sinOsc AR r4 0 * f * 0.25)) } }
+
+{ var r1 = Array.fill(2, { Rand.new(10, 13) })
+; var r2 = Array.fill(2, { Rand.new(10, 13) })
+; var r3 = Array.fill(2, { Rand.new(4, 7) })
+; var t = Impulse.kr(0.7, 0)
+; var e = Decay2.kr(Impulse.kr(r1, 0), 0.001, 0.005)
+; 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/crotale.lhs b/Help/Graphs/crotale.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/crotale.lhs
@@ -0,0 +1,333 @@
+crotale (rd)
+
+> let { crotale = ( [ 35.45676040649414
+>                   , 128.59849548339844
+>                   , 346.9721984863281
+>                   , 483.5544128417969
+>                   , 1049.2449951171875
+>                   , 1564.0279541015625
+>                   , 1756.3399658203125
+>                   , 3391.666015625
+>                   , 3451.802001953125
+>                   , 3497.261962890625
+>                   , 3596.89794921875
+>                   , 3696.739013671875
+>                   , 3835.235107421875
+>                   , 3845.955078125
+>                   , 4254.85107421875
+>                   , 4407.533203125
+>                   , 4415.26416015625
+>                   , 4552.865234375
+>                   , 5538.076171875
+>                   , 5637.73681640625
+>                   , 5690.2978515625
+>                   , 5728.0068359375
+>                   , 5764.27685546875
+>                   , 5824.4189453125
+>                   , 6377.60498046875
+>                   , 6544.35009765625
+>                   , 6807.14404296875
+>                   , 6994.97021484375
+>                   , 7026.84619140625
+>                   , 7144.5859375
+>                   , 7269.61279296875
+>                   , 7393.6708984375
+>                   , 7897.259765625
+>                   , 8040.4580078125
+>                   , 8157.77099609375
+>                   , 8225.01953125
+>                   , 9126.150390625
+>                   , 9488.529296875
+>                   , 9916.408203125
+>                   , 10155.599609375
+>                   , 11715.9599609375
+>                   , 12111.830078125
+>                   , 12339.990234375
+>                   , 12417.669921875
+>                   , 12459.2802734375
+>                   , 12618.330078125
+>                   , 13116.490234375
+>                   , 13201.1298828125
+>                   , 13297.830078125
+>                   , 13533.75 ]
+>                 , [ 0.0012827360769733787
+>                   , 0.0008040848188102245
+>                   , 0.017361238598823547
+>                   , 0.004835359752178192
+>                   , 0.004413491114974022
+>                   , 0.004110544919967651
+>                   , 0.0003338181704748422
+>                   , 0.0036140112206339836
+>                   , 0.006919348146766424
+>                   , 0.0003224937245249748
+>                   , 0.0006031467346474528
+>                   , 0.06686479598283768
+>                   , 0.000605064386036247
+>                   , 0.003602313343435526
+>                   , 0.0002835785271599889
+>                   , 0.015243238769471645
+>                   , 0.020536603406071663
+>                   , 0.016677580773830414
+>                   , 0.0009245267719961703
+>                   , 0.20205098390579224
+>                   , 0.0012542791664600372
+>                   , 0.012705927714705467
+>                   , 0.0002523190632928163
+>                   , 0.0004866079252678901
+>                   , 0.0006429700297303498
+>                   , 0.0007763264584355056
+>                   , 0.2081160992383957
+>                   , 0.0024918108247220516
+>                   , 0.00193469924852252
+>                   , 0.005231771152466536
+>                   , 0.0069242212921381
+>                   , 0.001203975174576044
+>                   , 0.2050020843744278
+>                   , 0.04060448706150055
+>                   , 0.0038344631902873516
+>                   , 0.002189427148550749
+>                   , 0.18056060373783112
+>                   , 0.002192433224990964
+>                   , 0.006516554858535528
+>                   , 0.009982921183109283
+>                   , 0.004745401442050934
+>                   , 0.046154771000146866
+>                   , 0.000510294979903847
+>                   , 0.0018905038014054298
+>                   , 0.0019782145973294973
+>                   , 0.006729386281222105
+>                   , 0.0023426134139299393
+>                   , 0.0024002245627343655
+>                   , 0.03515550494194031
+>                   , 0.0014084168942645192 ]
+>                 , [ 5.203680992126465
+>                   , 1.7034343481063843
+>                   , 40.16516876220703
+>                   , 27.282501220703125
+>                   , 0.8950523138046265
+>                   , 42.84742736816406
+>                   , 2.6603667736053467
+>                   , 15.7678861618042
+>                   , 6.848367214202881
+>                   , 3.2325007915496826
+>                   , 1.7343382835388184
+>                   , 2.0202419757843018
+>                   , 4.7279052734375
+>                   , 9.400103569030762
+>                   , 0.7102512717247009
+>                   , 37.494625091552734
+>                   , 36.24879455566406
+>                   , 29.172658920288086
+>                   , 3.891019344329834
+>                   , 4.757885456085205
+>                   , 3.851426124572754
+>                   , 20.90781021118164
+>                   , 3.732874870300293
+>                   , 2.3834102153778076
+>                   , 10.443285942077637
+>                   , 8.795611381530762
+>                   , 20.98564338684082
+>                   , 18.01180076599121
+>                   , 25.297883987426758
+>                   , 14.819819450378418
+>                   , 42.39189910888672
+>                   , 2.9485135078430176
+>                   , 11.043763160705566
+>                   , 49.55165100097656
+>                   , 29.882694244384766
+>                   , 10.527188301086426
+>                   , 23.5572452545166
+>                   , 26.55561637878418
+>                   , 45.099605560302734
+>                   , 22.550390243530273
+>                   , 36.46126174926758
+>                   , 11.826201438903809
+>                   , 16.818185806274414
+>                   , 14.903121948242188
+>                   , 32.81113815307617
+>                   , 43.1389045715332
+>                   , 12.289558410644531
+>                   , 11.498942375183105
+>                   , 10.465788841247559
+>                   , 24.93169593811035 ] )
+>     ; pinkNoise' = Sound.SC3.UGen.Base.pinkNoise
+>     ; tRand' = Sound.SC3.UGen.Base.tRand
+>     ; tiRand' = Sound.SC3.UGen.Base.tiRand
+>     ; dust' = Sound.SC3.UGen.Base.dust
+>     ; (cf, ca, cd) = crotale
+>     ; ps = mce [-12, -5, 0, 2, 4, 5, 7, 12]
+>     ; n = pinkNoise' (uid 0) AR
+>     ; t = dust' (uid 0) KR 3
+>     ; fs = select (tiRand' (uid 0) 0 7 t) ps
+>     ; g = tRand' (uid 0) 0 1 t
+>     ; fo = tRand' (uid 1) 0 1 t
+>     ; ds = tRand' (uid 2) 2 7 t
+>     ; p = tRand' (uid 3) (-1) 1 t
+>     ; s = decay2 t 0.06 0.01 * n * g
+>     ; k = dynKlank s (midiRatio fs) fo ds (klankSpec cf ca (map recip cd)) }
+> in audition (out 0 (pan2 k p 1))
+
+{ var crotale = [ [ 35.45676040649414
+                  , 128.59849548339844
+                  , 346.9721984863281
+                  , 483.5544128417969
+                  , 1049.2449951171875
+                  , 1564.0279541015625
+                  , 1756.3399658203125
+                  , 3391.666015625
+                  , 3451.802001953125
+                  , 3497.261962890625
+                  , 3596.89794921875
+                  , 3696.739013671875
+                  , 3835.235107421875
+                  , 3845.955078125
+                  , 4254.85107421875
+                  , 4407.533203125
+                  , 4415.26416015625
+                  , 4552.865234375
+                  , 5538.076171875
+                  , 5637.73681640625
+                  , 5690.2978515625
+                  , 5728.0068359375
+                  , 5764.27685546875
+                  , 5824.4189453125
+                  , 6377.60498046875
+                  , 6544.35009765625
+                  , 6807.14404296875
+                  , 6994.97021484375
+                  , 7026.84619140625
+                  , 7144.5859375
+                  , 7269.61279296875
+                  , 7393.6708984375
+                  , 7897.259765625
+                  , 8040.4580078125
+                  , 8157.77099609375
+                  , 8225.01953125
+                  , 9126.150390625
+                  , 9488.529296875
+                  , 9916.408203125
+                  , 10155.599609375
+                  , 11715.9599609375
+                  , 12111.830078125
+                  , 12339.990234375
+                  , 12417.669921875
+                  , 12459.2802734375
+                  , 12618.330078125
+                  , 13116.490234375
+                  , 13201.1298828125
+                  , 13297.830078125
+                  , 13533.75 ]
+                , [ 0.0012827360769733787
+                  , 0.0008040848188102245
+                  , 0.017361238598823547
+                  , 0.004835359752178192
+                  , 0.004413491114974022
+                  , 0.004110544919967651
+                  , 0.0003338181704748422
+                  , 0.0036140112206339836
+                  , 0.006919348146766424
+                  , 0.0003224937245249748
+                  , 0.0006031467346474528
+                  , 0.06686479598283768
+                  , 0.000605064386036247
+                  , 0.003602313343435526
+                  , 0.0002835785271599889
+                  , 0.015243238769471645
+                  , 0.020536603406071663
+                  , 0.016677580773830414
+                  , 0.0009245267719961703
+                  , 0.20205098390579224
+                  , 0.0012542791664600372
+                  , 0.012705927714705467
+                  , 0.0002523190632928163
+                  , 0.0004866079252678901
+                  , 0.0006429700297303498
+                  , 0.0007763264584355056
+                  , 0.2081160992383957
+                  , 0.0024918108247220516
+                  , 0.00193469924852252
+                  , 0.005231771152466536
+                  , 0.0069242212921381
+                  , 0.001203975174576044
+                  , 0.2050020843744278
+                  , 0.04060448706150055
+                  , 0.0038344631902873516
+                  , 0.002189427148550749
+                  , 0.18056060373783112
+                  , 0.002192433224990964
+                  , 0.006516554858535528
+                  , 0.009982921183109283
+                  , 0.004745401442050934
+                  , 0.046154771000146866
+                  , 0.000510294979903847
+                  , 0.0018905038014054298
+                  , 0.0019782145973294973
+                  , 0.006729386281222105
+                  , 0.0023426134139299393
+                  , 0.0024002245627343655
+                  , 0.03515550494194031
+                  , 0.0014084168942645192 ]
+                , [ 5.203680992126465
+                  , 1.7034343481063843
+                  , 40.16516876220703
+                  , 27.282501220703125
+                  , 0.8950523138046265
+                  , 42.84742736816406
+                  , 2.6603667736053467
+                  , 15.7678861618042
+                  , 6.848367214202881
+                  , 3.2325007915496826
+                  , 1.7343382835388184
+                  , 2.0202419757843018
+                  , 4.7279052734375
+                  , 9.400103569030762
+                  , 0.7102512717247009
+                  , 37.494625091552734
+                  , 36.24879455566406
+                  , 29.172658920288086
+                  , 3.891019344329834
+                  , 4.757885456085205
+                  , 3.851426124572754
+                  , 20.90781021118164
+                  , 3.732874870300293
+                  , 2.3834102153778076
+                  , 10.443285942077637
+                  , 8.795611381530762
+                  , 20.98564338684082
+                  , 18.01180076599121
+                  , 25.297883987426758
+                  , 14.819819450378418
+                  , 42.39189910888672
+                  , 2.9485135078430176
+                  , 11.043763160705566
+                  , 49.55165100097656
+                  , 29.882694244384766
+                  , 10.527188301086426
+                  , 23.5572452545166
+                  , 26.55561637878418
+                  , 45.099605560302734
+                  , 22.550390243530273
+                  , 36.46126174926758
+                  , 11.826201438903809
+                  , 16.818185806274414
+                  , 14.903121948242188
+                  , 32.81113815307617
+                  , 43.1389045715332
+                  , 12.289558410644531
+                  , 11.498942375183105
+                  , 10.465788841247559
+                  , 24.93169593811035 ] ]
+; var cf = crotale[0]
+; var ca = crotale[1]
+; var cd = crotale[2]
+; var ps = [-12, -5, 0, 2, 4, 5, 7, 12]
+; var n = PinkNoise.ar()
+; var t = Dust.kr(3)
+; var fs = Select.kr(TIRand.kr(0, 7, t), ps)
+; var g = TRand.kr(0, 1, t)
+; var fo = TRand.kr(0, 1, t)
+; var ds = TRand.kr(2, 7, t)
+; var p = TRand.kr(-1, 1, t)
+; var s = Decay2.kr(t, 0.06, 0.01) * n * g
+; var k = DynKlank.ar(`[cf, ca, cd.reciprocal], s, fs.midiratio, fo, ds)
+; Out.ar(0, Pan2.ar(k, p, 1)) }.play
diff --git a/Help/Graphs/cut-outs.lhs b/Help/Graphs/cut-outs.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/cut-outs.lhs
@@ -0,0 +1,37 @@
+cut-outs (rd)
+
+> let { t = impulse AR 22 0 * (sinOsc KR 0.5 0 + 1)
+>     ; x = mouseX KR 0.005 0.12 Exponential 0.1
+>     ; y = mouseY KR 0.01 0.52 Exponential 0.1 
+>     ; n = do { n1 <- lfNoise0 KR 2
+>              ; n2 <- coinGate (0.05 + n1 + y * 0.4 + t * 0.5) (t * 0.5)
+>              ; n3 <- tExpRand (mce2 500 900) 1600 t
+>              ; return (ringz n2 n3 x) } }
+> in do { s <- liftM sum (replicateM 3 n)
+>       ; b <- tRand 0 1 =<< dust KR 8
+>       ; audition (mrg [out 0 b, out 0 (clip2 s (in' 1 KR 0) * 0.25)]) }
+
+{ var t = Impulse.ar(22, 0) * (SinOsc.kr(0.5, 0) + 1)
+; var x = MouseX.kr(0.005, 0.12, 'exponential', 0.1)
+; var y = MouseY.kr(0.01, 0.52, 'exponential', 0.1)
+; var n = { var n1 = LFNoise0.kr(2)
+          ; var n2 = CoinGate.ar(0.05 + n1 + (y * 0.4) + (t * 0.5), t * 0.5)
+          ; var n3 = TExpRand.ar([500, 900], 1600, t)
+          ; Ringz.ar(n2, n3, x) }
+; var s = Mix.fill(3, n)
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/cymbalism.lhs
@@ -0,0 +1,26 @@
+cymbalism (jmcc)
+
+> let p = 15
+> in do { f1 <- rand 500 2500
+>       ; f2 <- rand 0 8000
+>       ; let y = do { f <- replicateM p (rand f1 (f1 + f2))
+>                    ; rt <- replicateM p (rand 1 5)
+>                    ; return (klankSpec f (replicate p 1) rt) }
+>         in do { z <- clone 2 y
+>               ; n <- liftM (* 0.03) (whiteNoise AR)
+>               ; tf <- rand 0.5 3.5
+>               ; let { t = impulse AR tf 0
+>                     ; s = decay t 0.004 * n
+>                     ; k = klank s 1 0 1 (mceTranspose z) }
+>                 in audition (out 0 k) } }
+
+{ var p = 15
+; var f1 = Rand.new(500, 2500)
+; var f2 = Rand.new(0, 8000)
+; var y = { var f = Array.fill(p, { f1 + Rand.new(0, f2) } )
+          ; 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
diff --git a/Help/Graphs/deep-sea.lhs b/Help/Graphs/deep-sea.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/deep-sea.lhs
@@ -0,0 +1,37 @@
+deep sea (jrhb)
+
+> let { rand' = Sound.SC3.UGen.Base.rand
+>     ; lfNoise1' = Sound.SC3.UGen.Base.lfNoise1
+>     ; lfNoise2' = Sound.SC3.UGen.Base.lfNoise2
+>     ; range s l r = let m = (r - l) * 0.5 in mulAdd s m (m + l)
+>     ; amp = 1
+>     ; pan = 0
+>     ; variation = 0.9
+>     ; n = rand' (uid 0) 7 46
+>     ; dt1 = 25.0 + rand' (uid 1) (-1.7) 1.7
+>     ; dt2 = (dt1 + lfNoise2' (uid 0) KR 2) * variation * 0.001
+>     ; freq = 901 + rand' (uid 2) 0 65
+>     ; t = impulse AR (recip dt2) 0 * 100
+>     ; count = pulseCount t 0
+>     ; mul = count <* n
+>     ; u1 = bpf (mul * t) freq 1 * 0.1
+>     ; freq2 = freq * ((count `modE` range (lfNoise1' (uid 0) KR 1) 2 20) + 1)
+>     ; u2 = bpf u1 freq2 1 * 0.2 }
+> in audition (mrg [ detectSilence u2 0.0001 0.2 RemoveSynth
+>                  , out 0 (pan2 u2 pan (amp * 10)) ])
+
+{ var amp = 1
+; var pan = 0
+; var variation = 0.9
+; var n = Rand.new(7, 46)
+; var dt1 = 25.0 + Rand.new(-1.7, 1.7)
+; var dt2 = (dt1 + LFNoise2.kr(2)) * variation * 0.001
+; var freq = 901 + Rand.new(0, 65)
+; var t = Impulse.ar(dt2.reciprocal, 0, 100)
+; var count = PulseCount.ar(t, 0)
+; var mul = count < n
+; var u1 = BPF.ar(mul * t, freq, 1) * 0.1
+; var freq2 = freq * ((count % LFNoise1.kr(1).range(2, 20)) + 1)
+; var u2 = BPF.ar(u1, freq2, 1) * 0.2
+; DetectSilence.ar(u2, 0.0001, 0.2, 2)
+; Out.ar(0, Pan2.ar(u2, pan, amp * 10)) }.play
diff --git a/Help/Graphs/demanding-studies.lhs b/Help/Graphs/demanding-studies.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/demanding-studies.lhs
@@ -0,0 +1,23 @@
+demanding studies (jmcc)
+
+> do { s1 <- drand dinf (mce [72, 75, 79, 82])
+>    ; s2 <- drand 1 (mce [82, 84, 86])
+>    ; s2 <- 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])
+>          ; 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 s3 = Dseq.new([72, 75, 79, s2], inf)
+; var x = MouseX.kr(5, 13, 'linear', 0.2)
+; var tr = Impulse.kr(x, 0)
+; var f = Demand.kr(tr, 0, [(s1 - 12).midicps, s3.midicps])
+; var o1 = SinOsc.ar(f + [0, 0.7], 0)
+; var o2 = Saw.ar(f + [0, 0.7]) * 0.3
+; var o3 = (o1 + o2).distort.log.distort.cubed
+; Out.ar(0, o3 * 0.1) }.play
diff --git a/Help/Graphs/dial-history.lhs b/Help/Graphs/dial-history.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/dial-history.lhs
@@ -0,0 +1,50 @@
+dial history (jrhb)
+
+> let { mfv = [[697, 770, 852, 941], [1209, 1336, 1477, 1633]]
+>     ; numbers = [[3, 1]] ++ [[a, b] | a <- [0..2], b <- [0..2]]
+>     ; range s l r = linLin s 0 1 l r
+>     ; mce_r = mce . map mce 
+>     ; mce_mrg = mrg . mceProxies }
+> in do { n <- dwhite dinf 7 12
+>       ; w <- dwhite 1 2 7
+>       ; b <- dbrown n 0.1 0.2 0.01
+>       ; rate <- dseq dinf (mce2 w b)
+>       ; q <- dseq dinf (mce [1..10])
+>       ; g1 <- grayNoise AR
+>       ; g2 <- grayNoise AR
+>       ; d <- lfdNoise3 KR 0.5
+>       ; let { tr = trig (tDuty KR rate 0 DoNothing q) 0.09
+>             ; pat = latch tr tr
+>             ; x = mouseX KR 0 1 Linear 0.2
+>             ; h = hasher (pat * x)
+>             ; which = trunc (range h 0 (constant (length numbers))) 1
+>             ; both = select which (mce_r numbers)
+>             ; 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)))) }
+
+{ var mfv = [[697, 770, 852, 941], [1209, 1336, 1477, 1633]]
+; var numbers = [[3, 1]] ++ {: [a, b], a <- (0..2), b <- (0..2) }.all
+; var n = Dwhite.new(7, 12, inf)
+; var w = Dwhite.new(2, 7, 1)
+; var b = Dbrown.new(0.1, 0.2, 0.01, n)
+; var rate = Dseq.new([w, b], inf)
+; var q = Dseq.new((1..10), inf)
+; var trig = Trig.kr(TDuty.kr(rate, 0, q), 0.09)
+; var pat = Latch.kr(trig, trig)
+; var x = MouseX.kr(0, 1, 'linear', 0.2)
+; var h = Hasher.kr(pat * x)
+; var which = h.range(0, numbers.size).trunc.(1)
+; var both = Select.kr(which, numbers)
+; var dial = Select.kr(both, mfv.flop)
+; var sig = SinOsc.ar(dial, 0) * 0.05 * trig
+; var d = LFDNoise3.kr(0.5)
+; var dsig = DelayC.ar(sig, 0.2, d.range(0, 0.01))
+; var g1 = GrayNoise.ar
+; var g2 = GrayNoise.ar
+; var z = Silent.ar(1)
+; var hiss = g1 * 0.01 + HPF.ar(g2 * 0.02, 3000)
+; Out.ar(0, [z, dsig + hiss]) }.play
diff --git a/Help/Graphs/discretion.lhs b/Help/Graphs/discretion.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/discretion.lhs
@@ -0,0 +1,25 @@
+discretion (rd)
+
+> let { mkls bp t = envGen KR 1 1 0 1 RemoveSynth (envCoord bp t 1 EnvLin)
+>     ; part = do { 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)
+>                 ; let { t = 21
+>                       ; f_ = mkls [(0, f1), (0.33, f2), (1, f3)] t
+>                       ; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/drummer.lhs
@@ -0,0 +1,32 @@
+drummer (thor magnusson)
+
+> do { n <- whiteNoise AR
+>    ; let { tempo = 4
+>          ; dup a = mce2 a a 
+>          ; tr = impulse AR tempo 0
+>          ; tr_2 = pulseDivider tr 4 2
+>          ; tr_4 = pulseDivider tr 4 0
+>          ; snare = n * decay2 tr_2 0.005 0.5
+>          ; bass = sinOsc AR 60 0 * decay2 tr_4 0.005 0.5
+>          ; hihat = hpf n 10000 * decay2 tr 0.005 0.5 }
+>      in audition (out 0 (pan2 (snare + bass + hihat) 0 0.4)) }
+
+{ var tempo = 4
+; var n = WhiteNoise.ar()
+; var tr = Impulse.ar(tempo, 0)
+; var tr_2 = PulseDivider.ar(tr, 4, 2)
+; var tr_4 = PulseDivider.ar(tr, 4, 0)
+; var snare = n * Decay2.ar(tr_2, 0.005, 0.5)
+; 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/eggcrate.lhs b/Help/Graphs/eggcrate.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/eggcrate.lhs
@@ -0,0 +1,26 @@
+eggcrate (rd)
+
+> 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] }
+> in do { [x, y] <- replicateM 2 (brownNoise KR)
+>       ; t <- dust KR 2.4
+>       ; [f0, f1] <- replicateM 2 (tChoose t p)
+>       ; let { f = linLin (eggcrate x y) (-1) 1 f0 f1
+>             ; a = linLin x (-1) 1 0 0.1 }
+>         in audition (out 0 (pan2 (mix (sinOsc AR f 0)) y a)) }
+
+{ var eggcrate = { arg u, v
+                 ; (u * pi).cos * (v * pi).sin }
+; var p = [64, 72, 96, 128, 256, 6400, 7200, 8400, 9600]
+; var x = BrownNoise.kr()
+; var y = BrownNoise.kr()
+; var t = Dust.kr(2.4)
+; var f0 = TChoose.kr(t, p)
+; var f1 = TChoose.kr(t, p)
+; var f = LinLin.kr(eggcrate.value(x, y), -1, 1, f0, f1)
+; var a = LinLin.kr(x, -1, 1, 0, 0.1)
+; Out.ar(0, Pan2.ar(Mix.ar(SinOsc.ar(f, 0)), y, a)) }.play
diff --git a/Help/Graphs/forest-sounds.lhs b/Help/Graphs/forest-sounds.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/forest-sounds.lhs
@@ -0,0 +1,24 @@
+forest sounds (paul jones)
+
+> let insects = do { n1 <- brownNoise AR
+>                  ; n2 <- lfNoise2 KR 50
+>                  ; let o = sinOsc KR (n2 * 50 + 50) 0 * 100 + 2000
+>                    in return (bpf n1 o 0.001 * 10) }
+> in audition . (out 0) =<< clone 2 insects
+
+{ var insects = { var n1 = BrownNoise.ar
+                ; var n2 = LFNoise2.kr(50)
+                ; var o = SinOsc.kr(n2 * 50 + 50, 0) * 100 + 2000
+                ; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/fwalk.lhs
@@ -0,0 +1,25 @@
+fwalk (rd)
+
+> let { n = [ 40.0, 47.0, 42.0, 40.0, 50.0
+>           , 43.0, 35.0, 43.0, 40.0, 47.0
+>           , 45.0, 35.0, 43.0, 42.0, 59.0
+>           , 48.0, 40.0, 47.0, 52.0, 45.0 ]
+>     ; m = [ 40.0, 40.0, 42.0, 47.0, 50.0
+>           , 35.0, 43.0, 43.0, 40.0, 45.0
+>           , 42.0, 35.0, 48.0, 47.0, 43.0
+>           , 40.0, 59.0, 45.0, 47.0, 52.0 ] 
+>     ; a = map (\b -> b_alloc b 20 1) [0, 1]
+>     ; s = map (\(b, d) -> b_setn1 b 0 d) [(0, n), (1, m)]
+>     ; 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
+>                          ; f' = f + r2
+>                          ; o1 = blip AR (midiCPS (r + f)) 12
+>                          ; o2 = blip AR (midiCPS (r + f')) 12 }
+>                      in return ((o1 + o2) * decay2 t 0.3 1.2 * 0.1) } }
+> in withSC3 (\fd -> do { f1 <- fwalk 24
+>                       ; f2 <- fwalk 36
+>                       ; mapM_ (async fd) a
+>                       ; mapM_ (send fd) s
+>                       ; play fd (out 0 (f1 + f2)) })
diff --git a/Help/Graphs/h-chatter.lhs b/Help/Graphs/h-chatter.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/h-chatter.lhs
@@ -0,0 +1,63 @@
+h-chatter (rd)
+
+> let { wrp i l r = linLin i (-1) 1 l r
+>     ; mma m a = return . (+ a)  . (* m)
+>     ; h0 = do { n <- mma 5 5 =<< lfNoise0 KR 1
+>               ; a <- mma 0.2 1.2 =<< lfNoise2 KR n
+>               ; b <- mma 0.15 0.15 =<< lfNoise2 KR n
+>               ; let { f = 40
+>                     ; h = henonN AR (mce2 f (f * 0.5)) a b 0 0 }
+>                 in return (saw AR (h * 3200 + 1600) * 0.35) }
+>     ; h1 = do { n0 <- lfNoise0 KR 32
+>               ; n1 <- lfNoise0 KR 2
+>               ; let { a = mouseX KR 1.2 1.4 Linear 0.1
+>                     ; b = mouseY KR 0.2 0.3 Linear 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 (p * 2)) h }
+>                 in return (pan2 o l g * 0.35) } }
+> in audition . out 0 =<< liftM2 (+) h0 h1
+
+{ var h0 = { var n = LFNoise0.kr(1, 5, 5)
+           ; var a = LFNoise0.kr(1, 0.2, 1.2)
+           ; var b = LFNoise0.kr(1, 0.15, 0.15)
+           ; var f = 40
+           ; var h = HenonN.ar([f, f * 0.5], a, b, 0, 0)
+           ; Saw.ar(h * 3200 + 1600) * 0.35 }
+; var h1 = { var n0 = LFNoise0.kr(32)
+           ; var n1 = LFNoise0.kr(2)
+           ; var a = MouseX.kr(1.2, 1.4, 'linear', 0.1)
+           ; var b = MouseY.kr(0.2, 0.3, 'linear', 0.1)
+           ; var h = n0.range(1, 32)
+           ; var p = n1.range(2400, 3200)
+           ; var l = n1.range(-0.75, 0.75)
+           ; var g = n1.range(0.55, 0.85)
+           ; var f = 40
+           ; 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/half-life.lhs b/Help/Graphs/half-life.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/half-life.lhs
@@ -0,0 +1,15 @@
+half-life (jrhb)
+
+> let { t_half = 3.92
+>     ; n_atoms = 1e+5
+>     ; n = max 0 (n_atoms - pulseCount (localIn 2 AR) 0) }
+> in do { activity <- dust AR (n * log 2 / t_half)
+>       ; audition (mrg [ localOut activity
+>                       , out 0 activity ]) }
+
+{ var t_half = 3.92
+; var n_atoms = 1e+5
+; var n = max(0, n_atoms - PulseCount.ar(LocalIn.ar(2), 0))
+; var activity = Dust.ar(n * 2.log / t_half)
+; LocalOut.ar(activity)
+; Out.ar(0, activity) }.play
diff --git a/Help/Graphs/harmonic-swimming.lhs b/Help/Graphs/harmonic-swimming.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/harmonic-swimming.lhs
@@ -0,0 +1,34 @@
+harmonic swimming (jmcc)
+
+> let { a = 0.02
+>     ; f = 50
+>     ; p = 20
+>     ; l = line KR 0 (- a) 60 DoNothing 
+>     ; o h = do { r <- clone 2 (rand 2 8)
+>                ; n <- lfNoise1 KR r
+>                ; let e = max 0 (n * a + l)
+>                  in return (fSinOsc AR (f * (h + 1)) 0 * e) } }
+> in audition . out 0 . sum =<< mapM o [0..p]
+
+{ var a = 0.02
+; var f = 50
+; var p = 20
+; var l = Line.kr(0, a.neg, 60, 0)
+; var o = { arg h
+          ; var r = 6 + [Rand.new(-4, 4), Rand.new(-4, 4)]
+          ; var n = LFNoise1.kr(r)
+          ; 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/harmonic-tumbling.lhs b/Help/Graphs/harmonic-tumbling.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/harmonic-tumbling.lhs
@@ -0,0 +1,20 @@
+harmonic tumbling (jmcc)
+
+> let { f = 80
+>     ; p = 10
+>     ; t = xLine KR (mce2 10 11) 0.1 60 DoNothing
+>     ; o h = do { n <- dust KR t
+>                ; r <- rand 0 0.5
+>                ; let e = decay2 (n * 0.02) 0.005 r
+>                  in return (fSinOsc AR (f * (h + 1)) 0 * e) } }
+> in audition . out 0 . sum =<< mapM o [0..p]
+
+{ var f = 80
+; var p = 10
+; var t = XLine.kr([10, 11], 0.1, 60, doneAction: 0)
+; var o = { arg h
+          ; var n = Dust.kr(t)
+          ; var r = Rand.new(0, 0.5)
+          ; var e = Decay2.kr(n * 0.02, 0.005, r)
+          ; FSinOsc.ar(f * (h + 1), 0) * e }
+; Out.ar(0, (0..p).collect(o).sum) }.play
diff --git a/Help/Graphs/hh-808.lhs b/Help/Graphs/hh-808.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/hh-808.lhs
@@ -0,0 +1,23 @@
+hh-808 (ryan at wabdo.com)
+
+> let { freeVerb i mx room damp = mkFilter "FreeVerb" [i, mx, room, damp] 1
+>     ; 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
+>     ; s = mix (lfPulse AR (mce (map (* 4.09) freqs)) 0 0.5)
+>     ; f = [ \a -> ((a ==* 6.0) * 0.6) + ((a ==* 2.0) * 0.2) + ((a ==* 1.0) * 0.9)
+>           , \a -> (a * pulseEnv) + ((mix (lfPulse AR (mce freqs) 0 0.55)) * 0.9)
+>           , \a -> rlpf a 7000 0.6
+>           , \a -> rhpf a 6800 1.5
+>           , \a -> rhpf a 6800 1.5
+>           , \a -> rhpf a 1200 1.5
+>           , \a -> a + freeVerb a 0.33 0.5 0.5
+>           , \a -> let { c = map EnvNum [0, -0.5, 0, -50]
+>                       ; e = env [0, 1, 0.4, 0, 0] [2, time, 50, 500] c 0 0 }
+>                   in a * envGen AR 1 1 0 (1/1000) RemoveSynth e
+>           , \a -> mce [a, delayN a 0.005 0.005] ]
+>     ; (>>>) = flip (.) }
+> in audition (out 0 (foldl1 (>>>) f s * 2))
+
+http://www.create.ucsb.edu/pipermail/sc-users/2007-August/036131.html
diff --git a/Help/Graphs/implosion.lhs b/Help/Graphs/implosion.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/implosion.lhs
@@ -0,0 +1,38 @@
+implosion (rd)
+
+> let { mkls bp t = let e = envCoord bp t 1 EnvLin
+>                   in envGen KR 1 1 0 1 RemoveSynth e
+>     ; mkrmp l r t = mkls [(0, l), (1, r)] t
+>     ; wrp i l r = linLin i (-1) 1 l r
+>     ; pmr_n rt l0 l1 r0 r1 d = let { le = mkrmp l0 r0 d
+>                                    ; re = mkrmp l1 r1 d }
+>                                in do { n <- whiteNoise rt
+>                                      ; return (wrp n le re) } }
+> in do { n0 <- rand (-1) 0
+>       ; n1 <- rand 0 1
+>       ; 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 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/k-ppr.lhs
@@ -0,0 +1,50 @@
+k-ppr (rd)
+
+> let { wrp i l r = linLin i (-1) 1 l r
+>     ; x = mouseX KR 0.05 0.35 Linear 0.1
+>     ; y = mouseY KR 0.15 0.75 Linear 0.1
+>     ; ti = lfTri KR x 0
+>     ; tf = wrp ti 100 200
+>     ; t = impulse AR tf 0
+>     ; stream lf rf ld rd g = 
+>         do { r1 <- rand 9 18
+>            ; let t' = pulseDivider t r1 0
+>              in do { r2 <- tRand lf (wrp ti lf rf) t'
+>                    ; r3 <- tRand ld rd t'
+>                    ; return (ringz (decay2 t' 0.01 0.5) r2 (r3 * y) * g) } } 
+>     ; s1 = stream 3140 6240 0.050 0.005 0.15 
+>     ; s2 = stream 0400 9000 0.005 0.005 0.15 }
+> in audition . out 0 =<< liftM2 (+) (clone 2 s1) (clone 2 s2)
+
+{ var x = MouseX.kr(0.05, 0.35, 'linear', 0.1)
+; var y = MouseY.kr(0.15, 0.75, 'linear', 0.1)
+; var ti = LFTri.kr(x, 0)
+; var tf = ti.range(100, 200)
+; var t = Impulse.ar(tf, 0)
+; var stream = { arg lf, rf, ld, rd, g
+               ; { var r1 = Rand.new(9, 18)
+                 ; var t_ = PulseDivider.ar(t, r1, 0)
+                 ; var r2 = TRand.ar(lf, ti.range(lf, rf), t_)
+                 ; var r3 = TRand.ar(ld, rd, t_)
+                 ; Ringz.ar(Decay2.ar(t_, 0.01, 0.5), r2, r3 * y) * g } }
+; 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/karplus-strong.lhs b/Help/Graphs/karplus-strong.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/karplus-strong.lhs
@@ -0,0 +1,37 @@
+karplus strong (alex mclean)
+
+> let { aA = ( "aA" 
+>            , [800, 1150, 2800, 3500, 4950]
+>            , [0, -4  , -20, -36 , -60]
+>            , [80, 90,  120, 130, 140] )
+>     ; aU = ( "aU" 
+>            , [325, 700, 2530, 3500, 4950]
+>            , [0, -12 , -30, -40, -64]
+>            , [50, 60,  170, 180, 200] )
+>     ; cs (_, c1, c2, c3) = c1 ++ c2 ++ c3
+>     ; vf i s = let { f = in' 5 KR i
+>                    ; a = in' 5 KR (i + 5)
+>                    ; b = in' 5 KR (i + 10) }
+>                in mix (resonz s f (b / f) * dbAmp a)
+>     ; ks n d = let { x = mouseX KR 0 0.01 Linear 0.1 {- delay -}
+>                    ; y = mouseY KR 0.85 1 Linear 0.1 {- blend / gain -}
+>                    ; ugenIf a b c = (a * b) + ((1 - a) * c)
+>                    ; n0 = (n / 2) + 0.5
+>                    ; probSwitch i prob = ugenIf (n0 >* prob) i (negate i)
+>                    ; laggedDelay = lag x 0.01
+>                    ; o = sinOsc AR 200 0
+>                    ; a0 = decay d 0.025 * o
+>                    ; a1 = localIn 1 AR + (a0 * (y - 0.25))
+>                    ; a2 = delayN a1 0.01 laggedDelay
+>                    ; a3 = delay1 a2
+>                    ; a4 = (a2 + a3) / 2.0
+>                    ; a5 = probSwitch a4 y
+>                    ; a6 = vf (toggleFF d * 15) a5
+>                    ; a7 = a6 * 1.5 }
+>               in mrg [localOut (a5 * 0.99), out 0 (mce [a7, a7])] }
+> in withSC3 (\fd -> do { send fd (c_setn [(0,cs aA), (15, cs aU)])
+>                       ; n <- whiteNoise AR
+>                       ; d <- dust KR 4
+>                       ; play fd (ks n d) })
+
+Variant on http://doc.gold.ac.uk/~ma503am/alex/vocable-source-released/
diff --git a/Help/Graphs/klink.lhs b/Help/Graphs/klink.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/klink.lhs
@@ -0,0 +1,37 @@
+klink (rd)
+
+> do { n1 <- lfNoise0 KR (mce2 0.5 1.5)
+>    ; let { o = sinOsc KR n1 0
+>          ; f = mce2 2 3
+>          ; a = abs (slope o) * f
+>          ; t = impulse AR a 0
+>          ; i = decay2 t 0.01 0.1
+>          ; x = mouseX KR 960 3620 Exponential 0.2
+>          ; y = mouseY KR 0.5 2.0 Linear 0.2 }
+>      in do { n2 <- tRand x 3940 t
+>            ; n3 <- tRand 0.005 0.275 t
+>            ; audition (out 0 (ringz i n2 (n3 * y))) } }
+
+{ var n1 = LFNoise0.kr([0.5, 1.5])
+; var o = SinOsc.kr(n1, 0)
+; var f = [2, 3]
+; var a = Slope.kr(o).abs * f
+; var t = Impulse.ar(a, 0)
+; var i = Decay2.ar(t, 0.01, 0.1)
+; var x = MouseX.kr(960, 3620, 'exponential', 0.2)
+; var y = MouseY.kr(0.5, 2.0, 'linear', 0.2)
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/lf-pulses.lhs
@@ -0,0 +1,22 @@
+lf pulses (rd)
+
+> do { n0 <- lfNoise0 AR (mce2 20 40)
+>    ; n1 <- lfNoise0 AR (mce2 5 10)
+>    ; let { x = mouseX KR 0.012 0.19 Exponential 0.1
+>          ; f = formlet (blip AR 10 12) (n0 * 43 + 700) 0.005 x 
+>          ; o = sinOsc AR 40 0 * n1 }
+>      in audition (out 0 (clip2 (leakDC (f + o) 0.995) 0.75)) }
+
+{ var n0 = LFNoise0.ar([20, 40])
+; var n1 = LFNoise0.ar([5, 10])
+; var x = MouseX.kr(0.012, 0.19, 'exponential', 0.1)
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/lfo-modulation.lhs
@@ -0,0 +1,16 @@
+lfo modulation (jmcc)
+
+> let { o = fSinOsc KR 0.05 0 * 80 + 160
+>     ; p = fSinOsc KR (mce2 0.6 0.7) 0 * 3600 + 4000
+>     ; s = rlpf (lfPulse AR o 0 0.4 * 0.05) p 0.2 }
+> in audition (out 0 (combL s 0.3 (mce2 0.2 0.25) 2))
+
+{ var o = FSinOsc.kr(0.05, 0, 80, 160)
+; 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/modal-space.lhs b/Help/Graphs/modal-space.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/modal-space.lhs
@@ -0,0 +1,52 @@
+modal space (jmcc)
+
+> let { b = 0
+>     ; p = [0, 2, 3.2, 5, 7, 9, 10] 
+>     ; x = mouseX KR 0 15 Linear 0.1
+>     ; k = degreeToKey 0 x 12
+>     ; c n r = let { o = sinOsc AR (midiCPS (r + k + n * 0.04)) 0 * 0.1
+>                   ; t = lfPulse AR (midiCPS (mce2 48 55)) 0.15 0.5
+>                   ; f = midiCPS (sinOsc KR 0.1 0 * 10 + r)
+>                   ; d = rlpf t f 0.1 * 0.1
+>                   ; m = o + d }
+>               in combN m 0.31 0.31 2 + m }
+> in withSC3 (\fd -> do { async fd (b_alloc b (length p) 1)
+>                       ; send fd (b_setn1 b 0 p)
+>                       ; n <- clone 2 (lfNoise1 KR 3)
+>                       ; play fd (out 0 ((c n 48 + c n 72) * 0.25)) })
+
+{ var s = Server.default
+; var b = 0
+; var p = FloatArray[0, 2, 3.2, 5, 7, 9, 10]
+; var x = MouseX.kr(0, 15, 'linear', 0.1)
+; var k = DegreeToKey.kr(b, x, 12)
+; var c = { arg n, r
+          ; var o = SinOsc.ar((r + k + (n * 0.04)).midicps, 0) * 0.1
+          ; var t = LFPulse.ar([48, 55].midicps, 0.15, 0.5)
+          ; var f = (SinOsc.kr(0.1, 0) * 10 + r).midicps
+          ; var d = RLPF.ar(t, f, 0.1) * 0.1
+          ; var m = o + d
+          ; CombN.ar(m, 0.31, 0.31, 2) + m }
+; var n = LFNoise1.kr([3, 3])
+; var b_setn1 = { arg b, i, p
+                ; ["/b_setn", b, i, p.size] ++ p }
+; s.sendMsg("/b_alloc", b, p.size, 1, b_setn1.value(b, 0, p).asRawOSC)
+; Out.ar(0, (c.value(n, 48) + c.value(n, 72)) * 0.25) }.play
+
+(let* ((b 0)
+       (p (list 0 2 3.2 5 7 9 10))
+       (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))
+		   (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)))
+       (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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/moto-rev.lhs
@@ -0,0 +1,13 @@
+moto rev (jmcc)
+
+> let { f = sinOsc KR 0.2 0 * 10 + 21
+>     ; s = lfPulse AR f (mce2 0 0.1) 0.1 }
+> in audition (out 0 (clip2 (rlpf s 100 0.1) 0.4))
+
+{ 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/mouse-clatter.lhs
@@ -0,0 +1,37 @@
+mouse clatter (rd)
+
+> let { x = mouseX KR 100 12000 Linear 0.1
+>     ; y = mouseY KR 0.01 0.15 Linear 0.1 }
+> in do { n1 <- lfNoise0 KR (mce [3, 3.25])
+>       ; let { t = impulse KR (n1 * 16 + 18) 0
+>             ; s = do { n2 <- tRand 0.005 y t
+>                      ; n3 <- whiteNoise AR
+>                      ; n4 <- tRand 10 x t
+>                      ; n5 <- tRand 0 1 t
+>                      ; n6 <- tExpRand 0.15 1 t
+>                      ; o <- let e = decay2 t 0.01 n2
+>                             in return (bpf (n3 * e) n4 n5)
+>                      ; n7 <- pv_RandComb (fft' 10 o) n6 t
+>                      ; return (o * 0.05 + ifft' n7) } }
+>         in withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                               ; play fd . out 0 =<< s }) }
+
+(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)))
+       (t (Impulse kr (MulAdd n1 16 18) 0))
+       (n2 (TRand 0.005 y t))
+       (n3 (WhiteNoise ar))
+       (n4 (TRand 10 x t))
+       (n5 (TRand 0.0 1.0 t))
+       (n6 (TExpRand 0.15 1.0 t))
+       (e (Decay2 t 0.01 n2))
+       (o (BPF (Mul n3 e) n4 n5))
+       (n7 (PV_RandComb (FFT* 10 o) n6 t))
+       (s (Add (Mul o 0.05) (IFFT* n7))))
+  (with-sc3
+   (lambda (fd)
+     (->< fd (/b_alloc 10 2048 1))
+     (play fd (Out 0 s)))))
+
+
diff --git a/Help/Graphs/noise-burst-sweep.lhs b/Help/Graphs/noise-burst-sweep.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/noise-burst-sweep.lhs
@@ -0,0 +1,15 @@
+noise burst sweep (jmcc)
+
+> do { n <- clone 2 (whiteNoise AR)
+>    ; let { lfoRate = mouseX KR 10 60 Exponential 0.2
+>          ; amp = max 0 (lfSaw KR lfoRate (-1))
+>          ; cfreq = mouseY KR 400 8000 Exponential 0.2
+>          ; freq = sinOsc KR 0.2 0 * cfreq + (1.05 * cfreq) }
+>      in audition (out 0 (resonz (n * amp) freq 0.1)) }
+
+{ var n = WhiteNoise.ar ! 2
+; var lfoRate = MouseX.kr(10, 60, 'exponential', 0.2)
+; var amp = max(0, LFSaw.kr(lfoRate, -1))
+; var cfreq = MouseY.kr(400, 8000, 'exponential', 0.2)
+; var freq = SinOsc.kr(0.2, 0) * cfreq + (1.05 * cfreq)
+; Out.ar(0, Resonz.ar(n * amp, freq, 0.1)) }.play
diff --git a/Help/Graphs/one-line.lhs b/Help/Graphs/one-line.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/one-line.lhs
@@ -0,0 +1,16 @@
+one-line (lance putnam)
+
+> let { lfs = lfSaw AR (mce2 1 0.99) (mce2 0 0.6) * 2000 + 2000
+>     ; lfs_t = trunc lfs (mce2 400 600) * mce2 1 (-1)
+>     ; f = onePole (mix lfs_t) 0.98 }
+> in audition (out 0 (pan2 (sinOsc AR f 0) 0 0.1))
+
+{ var lfs = LFSaw.ar([1, 0.99], [0, 0.6], 2000, 2000)
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/oscillator-cluster.lhs
@@ -0,0 +1,70 @@
+oscillator cluster (rd)
+
+> let { rng i l r = linLin i (-1) 1 l r
+>     ; ln a b d = line KR a b d RemoveSynth
+>     ; xln a b d = xLine KR a b d RemoveSynth
+>     ; rln r a b d = liftM (\n -> ln (a + n) b d) (rand 0 r)
+>     ; rxln r a b d = liftM (\n -> xln (a + n) b d) (rand 0 r)
+>     ; prt d a cf = do { r1 <- rand cf (cf + 2)
+>                       ; r2 <- rln 1 5 0.01 d
+>                       ; r3 <- rln 10 20 0 d
+>                       ; r4 <- rand 0.1 0.2
+>                       ; let { f = mce2 cf r1 + sinOsc KR r2 0 * r3
+>                             ; o = fSinOsc AR f 0
+>                             ; e = decay2 (impulse AR 0 0) r4 d * a }
+>                        in return (o * e) }
+>     ; np = 12
+>     ; fp = replicateM np (rand 220 660) }
+> in do { d <- rand 4 7
+>       ; a <- rand 0.01 0.05
+>       ; audition . (out 0) . sum =<< mapM (prt d a) =<< fp }
+
+{ var ln = { arg a, b, d
+           ; Line.kr(a, b, d, 1) }
+; var xln = { arg a, b, d
+            ; XLine.kr(a, b, d, 1) }
+; var rln = { arg r, a, b, d
+            ; var n = Rand.new(0, r)
+            ; ln.value(a + n, b, d) }
+; var rxln = { arg r, a, b, d
+             ; var n = Rand.new(0, r)
+             ; xln.value(a + n, b, d) }
+; var prt = { arg d, a
+            ; { arg cf
+              ; var r1 = Rand.new(cf, cf + 2)
+              ; var r2 = rln.value(1, 5, 0.01, d)
+              ; var r3 = rln.value(10, 20, 0, d)
+              ; var r4 = Rand.new(0.1, 0.2)
+              ; var f = [cf, r1] + (SinOsc.kr(r2, 0) * r3)
+              ; var o = FSinOsc.ar(f, 0)
+              ; var e = Decay2.ar(Impulse.ar(0, 0), r4, d) * a
+              ; o * e } }
+; var np = 12
+; var fp = Array.fill(np, { Rand.new(220, 660) })
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/pattern-buffer.lhs
@@ -0,0 +1,23 @@
+pattern buffer (rd)
+
+> 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)
+>     ; 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 
+>     ; rs h = do { r0 <- rrand 0 nf
+>                 ; r1 <- rrand 0.0 1.0
+>                 ; send h (b_set1 10 r0 r1) } }
+> in do { r1 <- replicateM c (rrand 36 96)
+>       ; r2 <- replicateM c (rrand (-1.0) 1.0)
+>       ; r3 <- rrand 0 1
+>       ; n1 <- tRand 0.02 0.08 t
+>       ; let { e = decay2 t 0.01 n1
+>             ; f = midiCPS (tseq r1)
+>             ; l = tseq r2
+>             ; o = [sinOsc AR f 0, saw AR f] !! r3 }
+>         in withSC3 (\fd -> do { async fd (b_alloc 10 (nf * 2) 1)
+>                               ; replicateM_ c (rs fd)
+>                               ; play fd (out 0 (pan2 o l e)) }) }
diff --git a/Help/Graphs/plucked-strings.lhs b/Help/Graphs/plucked-strings.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/plucked-strings.lhs
@@ -0,0 +1,20 @@
+plucked strings (jmcc)
+
+> let { s = do { n0 <- pinkNoise AR
+>              ; r1 <- rand (-1) 1
+>              ; im <- i
+>              ; dt' <- dt
+>              ; let t = decay im 0.1 * n0 * 0.1
+>                in return (pan2 (combL t dt' dt' 4) r1 1) }
+>     ; i = do { r0 <- rand 2 2.2
+>              ; n0 <- dust AR 0.5
+>              ; r1 <- rand 0.05 0.15
+>              ; r2 <- rand 0 (pi * 2)
+>              ; r3 <- iRand 0 2
+>              ; let { s0 = impulse AR r0 0.3
+>                    ; s1 = n0 * 0.3
+>                    ; s2 = impulse AR (sinOsc KR r1 r2 * 5 + 5.2) 0.3 }
+>                in return (select r3 (mce [s0, s1, s2])) }
+>     ; dt = do { r0 <- rand 60 90
+>               ; return (1 / (midiCPS (floorE r0))) } }
+> in audition . out 0 . sum =<< replicateM 5 s
diff --git a/Help/Graphs/police-state.lhs b/Help/Graphs/police-state.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/police-state.lhs
@@ -0,0 +1,48 @@
+police state (jmcc)
+
+> let node = do { r0 <- rand 0.02 0.12
+>               ; r1 <- rand 0 (pi*2)
+>               ; r2 <- rand 0 600
+>               ; r3 <- rand 700 1300
+>               ; r4 <- rand (-1) 1
+>               ; r5 <- rand 80 120
+>               ; n0 <- lfNoise2 AR r5
+>               ; let f = sinOsc KR r0 r1 * r2 + r3
+>                 in return (pan2 (sinOsc AR f 0 * n0 * 0.1) r4 1) }
+> in do { nodes <- clone 4 node
+>       ; n0 <- clone 2 (lfNoise2 KR 0.4)
+>       ; n1 <- lfNoise2 AR (n0 * 90 + 620)
+>       ; n2 <- lfNoise2 KR (mce2 0.3 0.301)
+>       ; let e = n1 * (n2 * 0.15 + 0.18)
+>         in audition (out 0 (combL (mix nodes + e) 0.3 0.3 3)) }
+
+{ var node = { var r0 = Rand.new(0.02, 0.12)
+             ; var r1 = Rand.new(0, 2pi)
+             ; var r2 = Rand.new(0, 600)
+             ; var r3 = 1000 + Rand.new(-300, 300)
+             ; var r4 = Rand.new(-1, 1)
+             ; var r5 = 100 + Rand.new(-20, 20)
+             ; var n0 = LFNoise2.ar(r5)
+             ; var f = SinOsc.kr(r0, r1, r2, r3)
+             ; Pan2.ar(SinOsc.ar(f, 0) * n0 * 0.1, r4, 1) }
+; var n0 = LFNoise2.kr([0.4, 0.4])
+; var n1 = LFNoise2.ar(n0 * 90 + 620)
+; 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/pulsing-bottles.lhs b/Help/Graphs/pulsing-bottles.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/pulsing-bottles.lhs
@@ -0,0 +1,14 @@
+pulsing bottles (jmcc)
+
+> let { r = do { n <- whiteNoise AR
+>              ; r0 <- rand 4 14
+>              ; r1 <- rand 0 0.7
+>              ; r2 <- rand 400 7400
+>              ; return (resonz (n * lfPulse KR r0 0 0.25 * r1) r2 0.01) }
+>     ; s = do { f <- rand 0.1 0.5
+>              ; p <- rand 0 (pi * 2)
+>              ; return (sinOsc KR f p) }
+>     ; u = do { r' <- r
+>              ; s' <- s
+>              ; return (pan2 r' s' 1) } }
+> in audition . out 0 . sum =<< replicateM 6 u
diff --git a/Help/Graphs/record-scratcher.lhs b/Help/Graphs/record-scratcher.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/record-scratcher.lhs
@@ -0,0 +1,29 @@
+record scratcher (josh parmenter)
+
+> 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
+>     ; 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 }
+> in withSC3 (\fd -> do { async fd (b_allocRead 0 fn 0 0)
+>                       ; play fd (out 0 (dup (scr * e))) })
+
+{ var fn = "/home/rohan/audio/metal.wav"
+; var b = 0
+; var gate = 1
+; var e = Env.new([0, 1, 0], [0.1, 0.1], \sin, 1, nil)
+; var env = EnvGen.kr(e, gate, doneAction: 2)
+; var x = MouseX.kr(-10, 10, 'linear', 0.2)
+; var dx = x - DelayN.kr(x, 0.1, 0.1)
+; var bdx = MouseButton.kr(1, 0, 0.3) + dx
+; var bdxr = bdx * BufRateScale.kr(b)
+; var scr = PlayBuf.ar(1, b, bdxr, 0, 0, 1)
+; var s = Server.default
+; s.sendMsg("/b_allocRead", b, fn, 0, 0)
+; Out.ar(0, (scr * env).dup ) }.play
diff --git a/Help/Graphs/red-frik.lhs b/Help/Graphs/red-frik.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/red-frik.lhs
@@ -0,0 +1,29 @@
+red frik (f0)
+
+> let red tr n = 
+>     do { r1 <- tRand 0.3 3 tr
+>        ; r2 <- tRand 0.3 5 tr
+>        ; r3 <- tRand 0 0.5 tr
+>        ; r4 <- tRand 0.49 0.56 tr
+>        ; r5 <- tRand 0.3 0.6 tr
+>        ; r6 <- tRand 0.3 0.5 tr
+>        ; let { o1 = fSinOsc KR r2 0 * r3 + r4
+>              ; o2 = fSinOsc KR o1 r5 * r6 }
+>          in return (rhpf n r1 o2) }
+> in do { n <- clone 2 (brownNoise AR)
+>       ; let tr = impulse KR 0.1 0
+>         in audition . out 0 =<< red tr n }
+
+{ var red = { arg tr, n
+            ; var r1 = TRand.kr(0.3, 3, tr)
+            ; var r2 = TRand.kr(0.3, 5, tr)
+            ; var r3 = TRand.kr(0, 0.5, tr)
+            ; var r4 = TRand.kr(0.49, 0.56, tr)
+            ; var r5 = TRand.kr(0.3, 0.6, tr)
+            ; var r6 = TRand.kr(0.3, 0.5, tr)
+            ; var o1 = FSinOsc.kr(r2, 0, r3, r4)
+            ; var o2 = FSinOsc.kr(o1, r5, r6)
+            ; RHPF.ar(n, r1, o2) }
+; var n = [BrownNoise.ar, BrownNoise.ar]
+; var tr = Impulse.kr(0.1, 0)
+; Out.ar(0, red.value(tr, n)) }.play
diff --git a/Help/Graphs/reverberated-sine-percussion.lhs b/Help/Graphs/reverberated-sine-percussion.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/reverberated-sine-percussion.lhs
@@ -0,0 +1,34 @@
+reverberated sine percussion (jmcc)
+
+> let { d = 6
+>     ; c = 5
+>     ; a = 4
+>     ; s_ = do { n <- dust AR (2 / constant d)
+>               ; r <- rand 0 3000
+>               ; return (resonz (n * 50) (200 + r) 0.003) }
+>     ; x_ i = do { r <- clone 2 (rand 0 0.05)
+>                 ; return (allpassN i 0.05 r 1) } 
+>     ; chain n f = foldl (>=>) return (replicate n f) }
+> in do { s <- liftM sum (replicateM d s_)
+>       ; y <- let z = delayN s 0.048 0.48
+>              in do { r <- clone c (rand 0 0.1)
+>                    ; n <- lfNoise1 KR r
+>                    ; return (mix (combL z 0.1 (n * 0.04 + 0.05) 15)) }
+>       ; x <- chain a x_ y
+>       ; audition (out 0 (s + x * 0.2)) }
+
+{ var d = 6
+; var c = 5
+; var a = 4
+; var s_ = { var n = Dust.ar(2 / d)
+           ; var r = Rand.new(0, 3000)
+           ; Resonz.ar(n * 50, 200 + r, 0.003) }
+; var s = Mix.ar(Array.fill(d, s_))
+; var z = DelayN.ar(s, 0.048)
+; var y_ = LFNoise1.kr(Array.fill(c, { Rand.new(0, 0.1) }), 0.04, 0.05)
+; var y = Mix.ar(CombL.ar(z, 0.1, y_, 15))
+; var x = y
+; var x_ = { var r = [Rand.new(0, 0.05), Rand.new(0, 0.05)]
+           ; x = AllpassN.ar(x, 0.050, r, 1) }
+; a.do(x_)
+; Out.ar(0, s + (0.2 * x)) }.play
diff --git a/Help/Graphs/s-chirp.lhs b/Help/Graphs/s-chirp.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/s-chirp.lhs
@@ -0,0 +1,43 @@
+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
+>     ; 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]
+>       ; 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)
+>       ; o <- let { k = degreeToKey 0 d 12
+>                  ; f = midiCPS (b + k + n)
+>                  ; m = e * sinOsc AR f 0 * 0.2
+>                  ; u = pulseDivider t 9 0 }
+>              in do { r0 <- tRand 0.0075 0.125 u
+>                    ; r1 <- tRand 0.05 0.15 u
+>                    ; return (m * 0.5 + allpassC m 0.15 r0 r1) }
+>       ; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/sample-and-hold-liquidities.lhs
@@ -0,0 +1,29 @@
+sample and hold liquidities (jmcc)
+
+> let { wn = Sound.SC3.UGen.Base.whiteNoise
+>     ; r = mouseX KR 1 200 Exponential 0.1
+>     ; t = recip r
+>     ; c = impulse KR r 0.4
+>     ; cf = mouseY KR 100 8000 Exponential 0.1
+>     ; f = latch (wn (uid 0) KR * cf * 0.5 + cf) c
+>     ; p = latch (wn (uid 1) KR) c
+>     ; i = pan2 (sinOsc AR f 0 * decay2 c (t * 0.1) (t * 0.9)) p 1 }
+> in audition (out 0 (combN i 0.3 0.3 2))
+
+{ var r = MouseX.kr(1, 200, 'exponential', 0.1)
+; var t = r.reciprocal
+; var c = Impulse.kr(r, 0.4)
+; var cf = MouseY.kr(100, 8000, 'exponential', 0.1)
+; var f = Latch.kr(WhiteNoise.kr * cf * 0.5 + cf, c)
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/scratchy.lhs
@@ -0,0 +1,20 @@
+scratchy (jmcc)
+
+> do { n <- clone 2 (brownNoise AR)
+>    ; let f = max (n * 0.5 - 0.49) 0 * 20
+>      in audition (out 0 (rhpf f 5000 1)) }
+
+{ var n = BrownNoise.ar([0.5, 0.5])
+; 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
+>     ; f m = bn (uid m) AR * 0.5 - 0.49
+>     ; n = mce [f 0, f 1] }
+> in audition (out 0 (rhpf (max n 0 * 20) 5000 1))
diff --git a/Help/Graphs/scritto.lhs b/Help/Graphs/scritto.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/scritto.lhs
@@ -0,0 +1,123 @@
+scritto (rd)
+
+> let { scritto = [ ( "sA" 
+>                   , [800, 1150, 2900, 3900, 4950]
+>                   , [0, -6,  -32, -20, -50]
+>                   , [80, 90,  120, 130, 140] )
+>                 , ( "sE" 
+>                   , [350, 2000, 2800, 3600, 4950]
+>                   , [0, -20, -15, -40, -56]
+>                   , [60, 100, 120, 150, 200] )
+>                 , ( "sI" 
+>                   , [270, 2140, 2950, 3900, 4950]
+>                   , [0, -12 , -26 , -26 , -44]
+>                   , [60, 90,  100, 120, 120] )
+>                 , ( "sO" 
+>                   , [450, 800,  2830, 3800, 4950]
+>                   , [0, -11 , -22 , -22 , -50]
+>                   , [70, 80,  100, 130, 135] )
+>                 , ( "sU" 
+>                   , [325, 700,  2700, 3800, 4950]
+>                   , [0, -16, -35, -40, -60]
+>                   , [50, 60,  170, 180, 200] )
+>                 , ( "aA" 
+>                   , [800, 1150, 2800, 3500, 4950]
+>                   , [0, -4  , -20, -36 , -60]
+>                   , [80, 90,  120, 130, 140] )
+>                 , ( "aE" 
+>                   , [400, 1600, 2700, 3300, 4950]
+>                   , [0, -24 , -30, -35, -60]
+>                   , [60, 80,  120, 150, 200] )
+>                 , ( "aI" 
+>                   , [350, 1700, 2700, 3700, 4950]
+>                   , [0, -20, -30, -36 , -60]
+>                   , [50, 100, 120, 150, 200] )
+>                 , ( "aO" 
+>                   , [450, 800,  2830, 3500, 4950]
+>                   , [0, -9  , -16 , -28 , -55]
+>                   , [70, 80,  100, 130, 135] )
+>                 , ( "aU" 
+>                   , [325, 700, 2530, 3500, 4950]
+>                   , [0, -12 , -30, -40, -64]
+>                   , [50, 60,  170, 180, 200] )
+>                 , ( "ctA"
+>                   , [660, 1120, 2750, 3000, 3350]
+>                   , [0, -6  , -23 , -24 , -38]
+>                   , [80, 90,  120, 130, 140] )
+>                 , ( "ctE"
+>                   , [440, 1800, 2700, 3000, 3300]
+>                   , [0, -14 , -18 , -20, -20]
+>                   , [70, 80,  100, 120, 120] )
+>                 , ( "ctI"
+>                   , [270, 1850, 2900, 3350, 3590]
+>                   , [0, -24 , -24 , -36 , -36]
+>                   , [40, 90,  100, 120, 120] )
+>                 , ( "ctO"
+>                   , [430, 820,  2700, 3000, 3300]
+>                   , [0, -10, -26 , -22 , -34]
+>                   , [40, 80,  100, 120, 120] )
+>                 , ( "ctU"
+>                   , [370, 630,  2750, 3000, 3400]
+>                   , [0, -20, -23 , -30, -34]
+>                   , [40, 60,  100, 120, 120] )
+>                 , ( "tA" 
+>                   , [650, 1080, 2650, 2900, 3250]
+>                   , [0, -6   , -7  , -8 , -22]
+>                   , [80, 90,  120, 130, 140] )
+>                 , ( "tE" 
+>                   , [400, 1700, 2600, 3200, 3580]
+>                   , [0, -14 , -12 , -14 , -20]
+>                   , [70, 80,  100, 120, 120] )
+>                 , ( "tI" 
+>                   , [290, 1870, 2800, 3250, 3540]
+>                   , [0, -15, -18 , -20, -30]
+>                   , [40, 90,  100, 120, 120] )
+>                 , ( "tO" 
+>                   , [400, 800,  2600, 2800, 3000]
+>                   , [0, -10, -12 , -12 , -26]
+>                   , [40, 80,  100, 120, 120] )
+>                 , ( "tU" 
+>                   , [350, 600,  2700, 2900, 3300]
+>                   , [0, -20, -17 , -14 , -26]
+>                   , [40, 60,  100, 120, 120] )
+>                 , ( "bA" 
+>                   , [600, 1040, 2250, 2450, 2750]
+>                   , [0, -7   , -9  , -9 , -20]
+>                   , [60, 70,  110, 120, 130] )
+>                 , ( "bE" 
+>                   , [400, 1620, 2400, 2800, 3100]
+>                   , [0, -12  , -9 , -12 , -18]
+>                   , [40, 80,  100, 120, 120] )
+>                 , ( "bI" 
+>                   , [250, 1750, 2600, 3050, 3340]
+>                   , [0, -30, -16 , -22 , -28]
+>                   , [60, 90,  100, 120, 120] )
+>                 , ( "bO" 
+>                   , [400, 750,  2400, 2600, 2900]
+>                   , [0, -11 , -21 , -20, -40]
+>                   , [40, 80,  100, 120, 120] )
+>                 , ( "bU" 
+>                   , [350, 600,  2400, 2675, 2950]
+>                   , [0, -20, -32 , -28 , -36]
+>                   , [40, 80,  100, 120, 120] ) ]
+>     ; s_msg n (_, f, a, b) = b_setn1 n 0 (f ++ a ++ b)
+>     ; s_alloc fd (s, b) = do { async fd (b_alloc b 15 1)
+>                              ; send fd (s_msg b s) }
+>     ; buf_at b n = bufRd 1 KR b (mce [n .. n + 4]) NoLoop NoInterpolation
+>     ; v_filter i f a b = resonz i f (b / f) * dbAmp a
+>     ; v_filter_b bi i = v_filter i (buf_at bi 0) (buf_at bi 5) (buf_at bi 10)
+>     ; mk_instr bx = do 
+>         { n <- lfNoise2 KR 3
+>         ; let { t = impulse AR (n * 9 + 9) 0
+>               ; i d = do { n1 <- tRand 0.02 0.06 t
+>                          ; n2 <- tiRand 30 52 t
+>                          ; n3 <- tiRand 16 32 t
+>                          ; let { p = pulseDivider t d 0
+>                                ; b = blip AR (midiCPS n2) n3 }
+>                            in return (decay2 p 0.01 n1 * b * 12) }
+>               ; bi = linLin n (-1) 1 0 bx
+>               ; voice = mix . v_filter_b bi }
+>           in return . out 0 . mce . map voice =<< mapM i [1, 2] } }
+> in withSC3 (\fd -> do { mapM_ (s_alloc fd) (zip scritto [0..])
+>                       ; let n = constant (length scritto)
+>                         in audition =<< mk_instr n })
diff --git a/Help/Graphs/shepard-tones.lhs b/Help/Graphs/shepard-tones.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/shepard-tones.lhs
@@ -0,0 +1,39 @@
+shepard tones (alberto de campo)
+
+> let { indxs n l r = let i = (r - l) / n 
+>                     in [l, l + i .. r - i]
+>     ; hanningWindow n = 
+>           let { lp = pi * (-0.5)
+>               ; rp = lp + 2 * pi 
+>               ; hf i = sin i * 0.5 + 0.5 }
+>           in map hf (indxs n lp rp)
+>     ; square x = x * x
+>     ; ampTable = map square (hanningWindow 1024) 
+>     ; amp_f i = (0.5 ** i) * 20000
+>     ; freqTable = map amp_f (indxs 1024 0 10)
+>     ; ratescale = 1024 / 44100 / 10
+>     ; rate = 0.1
+>     ; ph = phasor AR 0 (rate * ratescale) 0 1024 0
+>     ; phases = mce (map (\n -> n * 0.1 * 1024 + ph) [0..9])
+>     ; freqs = bufRdC 1 AR 1 phases Loop
+>     ; amps = bufRdC 1 AR 2 phases Loop
+>     ; tone = mix (sinOsc AR freqs 0 * amps) * 0.1 }
+> in withSC3 (\fd -> do { async fd (b_alloc 1 1024 1)
+>                       ; async fd (b_alloc 2 1024 1)
+>                       ; send fd (b_setn1 1 0 freqTable)
+>                       ; send fd (b_setn1 2 0 ampTable)
+>                       ; audition (out 0 tone) })
+
+{ var ampTable = Signal.hanningWindow(1024).squared
+; var amp_f = { arg i; 0.5 ** i * 20000 }
+; var freqTable = Signal.newClear(1024).waveFill(amp_f, 0, 10)
+; var b1 = Buffer.loadCollection(s, freqTable)
+; var b2 = Buffer.loadCollection(s, ampTable)
+; var ratescale = 1024 / 44100 / 10
+; var rate = 0.1
+; var ph = Phasor.ar(0, rate * ratescale, 0, 1024, 0)
+; var phases = (0..9) * 0.1 * 1024 + ph
+; var freqs = BufRd.ar(1, b1.bufnum, phases)
+; var amps = BufRd.ar(1, b2.bufnum, phases)
+; var tone = Mix.ar(SinOsc.ar(freqs) * amps) * 0.1 
+; Out.ar(0, tone)}.play
diff --git a/Help/Graphs/shifting-pulses.lhs b/Help/Graphs/shifting-pulses.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/shifting-pulses.lhs
@@ -0,0 +1,31 @@
+shifting pulses (rd)
+
+> do { [n0, n1, n2] <- replicateM 3 (clone 2 (brownNoise KR))
+>    ; t <- dust KR 0.75
+>    ; let { warp i = linLin i (-1) 1
+>          ; l = latch t t
+>          ; p = pulse AR (warp n0 2 (mce2 11 15)) 0.01 * 0.1 
+>          ; f = warp n1 300 1800 
+>          ; rq = warp n2 0.01 2 }
+>      in audition (out 0 (l * rlpf p f rq)) }
+
+{ var n0 = BrownNoise.kr.dup
+; var n1 = BrownNoise.kr.dup
+; var n2 = BrownNoise.kr.dup
+; var t = Dust.kr(0.75)
+; var l = Latch.kr(t, t)
+; var p = Pulse.ar(n0.range(2, [11, 15]), 0.01) * 0.1 
+; 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/snare-909.lhs b/Help/Graphs/snare-909.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/snare-909.lhs
@@ -0,0 +1,43 @@
+snare-909 (jmcc)
+
+> let { snr tr n v =
+>       let { e a b = envGen AR tr 1 0 1 DoNothing (envPerc a b)
+>           ; e1 = e 0.0005 0.055
+>           ; e2 = e 0.0005 0.075
+>           ; e3 = e 0.0005 0.4
+>           ; e4 = e 0.0005 0.283
+>           ; t1 = lfTri AR 330 0
+>           ; t2 = lfTri AR 185 0
+>           ; x1 = lpf n 7040 * 0.1 + v
+>           ; x2 = hpf x1 523
+>           ; m1 = t1 * e1 * 0.25 + t2 * e2 * 0.25
+>           ; m2 = x1 * e3 * 0.20 + x2 * e4 * 0.20 }
+>       in m1 + m2
+>     ; x = mouseX KR 1 4 Linear 0.2
+>     ; y = mouseY KR 0.25 0.75 Exponential 0.2
+>     ; t = impulse KR (3 * x) 0 }
+> in do { n <- whiteNoise AR
+>       ; v <- tRand 0.25 1.0 t
+>       ; audition (out 0 (pan2 (snr t n v) 0 y)) }
+
+{ var snr =
+      { arg tr, n, v
+      ; var e = { arg a, b
+                ; EnvGen.ar(Env.perc(a, b), tr, 1, 0, 1, 0) }
+      ; var e1 = e.value(0.0005, 0.055)
+      ; var e2 = e.value(0.0005, 0.075)
+      ; var e3 = e.value(0.0005, 0.4)
+      ; var e4 = e.value(0.0005, 0.283)
+      ; var t1 = LFTri.ar(330, 0)
+      ; var t2 = LFTri.ar(185, 0)
+      ; var x1 = LPF.ar(n, 7040) * (0.1 + v)
+      ; var x2 = HPF.ar(x1, 523)
+      ; var m1 = (t1 * e1 * 0.25) + (t2 * e2 * 0.25)
+      ; var m2 = (x1 * e3 * 0.20) + (x2 * e4 * 0.20)
+      ; m1 + m2 }
+; var x = MouseX.kr(1, 4, 'linear', 0.2)
+; var y = MouseY.kr(0.25, 0.75, 'exponential', 0.2)
+; var t = Impulse.kr(3 * x, 0)
+; var n = WhiteNoise.ar
+; var v = TRand.kr(0.25, 1.0, t)
+; Out.ar(0, Pan2.ar(snr.value(t, n, v), 0, y)) }.play
diff --git a/Help/Graphs/spe.lhs b/Help/Graphs/spe.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/spe.lhs
@@ -0,0 +1,19 @@
+spe (jmcc)
+
+> let { chain n f = foldl (>=>) return (replicate n f)
+>     ; rapf i = do { r <- clone 2 (rand 0 0.05)
+>                   ; return (allpassN i 0.05 r 4) }
+>     ; src = let { t = impulse KR 9 0
+>                 ; e = envGen KR t 0.1 0 1 DoNothing (envPerc 0.1 1)
+>                 ; s = mce [ 00, 03, 02, 07
+>                           , 08, 32, 16, 18
+>                           , 00, 12, 24, 32 ] }
+>             in do { n <- lfNoise1 KR 1
+>                   ; m <- dseq dinf s
+>                   ; let { f = midiCPS (demand t 0 m + 32)
+>                         ; o = lfSaw AR f 0 * e
+>                         ; rq = midiCPS (n * 36 + 110) }
+>                     in return (rlpf o rq 0.1) } }
+> in audition . (out 0) =<< chain 4 rapf =<< src
+
+[variant of graph in streams & patterns tutorial]
diff --git a/Help/Graphs/sprinkler.lhs b/Help/Graphs/sprinkler.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/sprinkler.lhs
@@ -0,0 +1,21 @@
+sprinkler (jmcc)
+
+> do { n <- whiteNoise AR
+>    ;  let { f = lfPulse KR 0.09 0 0.16 * 10 + 7
+>           ; t = lfPulse KR f 0 0.25 * 0.1 }
+>       in audition (out 0 (bpz2 (n * t))) }
+
+{ var f = LFPulse.kr(0.09, 0, 0.16, 10, 7)
+; 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
+>     ; f = lfPulse KR 0.09 0 0.16 * 10 + 7
+>     ; t = lfPulse KR f 0 0.25 * 0.1 }
+> in audition (out 0 (bpz2 (n * t)))
diff --git a/Help/Graphs/strummable-guitar.lhs b/Help/Graphs/strummable-guitar.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/strummable-guitar.lhs
@@ -0,0 +1,24 @@
+strummable guitar (jmcc)
+
+> let { scale = [ 52, 57, 62, 67, 71, 76 ]
+>     ; str i = let { x = mouseX KR 0 1 Linear 0.2
+>                   ; t = abs (hpz1 (x >* (0.25 + constant i * 0.1)))
+>                   ; e = decay t 0.05
+>                   ; n = Sound.SC3.UGen.Base.pinkNoise (uid 0) AR * e
+>                   ; dt = 1 / (midiCPS (scale !! i))
+>                   ; s = combL n dt dt 4 }
+>               in pan2 s (constant i * 0.2 - 0.5) 1
+>     ; strs = mixFill (length scale) str }
+> in audition (out 0 (leakDC (lpf strs 12000) 0.995))
+
+{ var scale = [ 52, 57, 62, 67, 71, 76 ]
+; var str = { arg i
+            ; var x = MouseX.kr(0, 1, 'linear', 0.2)
+            ; var t = HPZ1.kr(x > (0.25 + (i * 0.1))).abs
+            ; var e = Decay.kr(t, 0.05)
+            ; var n = PinkNoise.ar * e
+            ; var dt = scale.at(i).midicps.reciprocal
+            ; var s = CombL.ar(n, dt, dt, 4)
+            ; Pan2.ar(s, i * 0.2 - 0.5, 1) }
+; var strs = Mix.fill(scale.size, str)
+; Out.ar(0, LeakDC.ar(LPF.ar(strs, 12000), 0.995)) }.play
diff --git a/Help/Graphs/sweepy-noise.lhs b/Help/Graphs/sweepy-noise.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/sweepy-noise.lhs
@@ -0,0 +1,14 @@
+sweepy noise (jmcc)
+
+> do { n <- clone 2 (whiteNoise AR)
+>    ; let { lfoDepth = mouseY KR 200 8000 Exponential 0.1
+>          ; lfoRate = mouseX KR 4 60 Exponential 0.1
+>          ; freq = lfSaw KR lfoRate 0 * lfoDepth + (lfoDepth * 1.2)
+>          ; 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 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
diff --git a/Help/Graphs/synthetic-piano.lhs b/Help/Graphs/synthetic-piano.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/synthetic-piano.lhs
@@ -0,0 +1,30 @@
+synthetic piano (jmcc)
+
+> let p = do { n <- iRand 36 90
+>            ; f <- rand 0.1 0.5
+>            ; ph <- rand 0 (pi * 2)
+>            ; let { s = impulse AR f ph * 0.1
+>                  ; e = decay2 s 0.008 0.04
+>                  ; c i = do { n0 <- lfNoise2 AR 3000
+>                             ; let { o = [-0.05, 0, 0.04] !! i
+>                                   ; dt = 1 / (midiCPS (n + o)) }
+>                               in return (combL (n0 * e) dt dt 6) }
+>                  ; l = ((n - 36) / 27) - 1 }
+>              in do { c_ <- mixFillM 3 c
+>                    ; return (pan2 c_ l 1) } }
+> in audition . out 0 =<< mixFillM 6 (const p)
+
+{ var p = { var n = IRand.new(36, 90)
+          ; var f = Rand.new(0.1, 0.5)
+          ; var ph = Rand.new(0, pi * 2)
+          ; var s = Impulse.ar(f, ph) * 0.1
+          ; var e = Decay2.ar(s, 0.008, 0.04)
+          ; var c = { arg i
+                    ; var n0 = LFNoise2.ar(3000)
+                    ; var o = [-0.05, 0, 0.04].at(i)
+                    ; var dt = 1 / (n + o).midicps
+                    ; CombL.ar(n0 * e, dt, dt, 6) }
+          ; var l = ((n - 36) / 27) - 1
+          ; var c_ = Mix.fill(3, c)
+          ; Pan2.ar(c_, l, 1) }
+; Out.ar(0, Mix.fill(6, p)) }.play
diff --git a/Help/Graphs/tank.lhs b/Help/Graphs/tank.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/tank.lhs
@@ -0,0 +1,60 @@
+tank (jmcc)
+
+> let { r_allpass i = do { r <- clone 2 (rand 0.005 0.02)
+>                        ; return (allpassN i 0.03 r 1) }
+>     ; chain n f = foldl (>=>) return (replicate n f)
+>     ; pling = do { d <- dust AR 0.2
+>                  ; f <- expRand 300 2200
+>                  ; p <- rand (-1) 1
+>                  ; let { s1 = cubed (fSinOsc AR f 0)
+>                        ; s2 = decay2 d 0.1 0.5 * 0.1 * s1 }
+>                    in return (pan2 s2 p 1) }
+>     ; bang = do { d <- dust AR 0.01
+>                 ; n <- brownNoise AR
+>                 ; return (pan2 (decay2 d 0.04 0.3 * n) 0 1) }
+>     ; tank i = do { r1 <- clone 2 (rand 0.01 0.05)
+>                   ; r2 <- clone 2 (rand 0.03 0.15)
+>                   ; let { l0 = localIn 2 AR * 0.98
+>                         ; l1 = onePole l0 0.33
+>                         ; [l1l, l1r] = mceChannels l1
+>                         ; l2 = rotate2 l1l l1r 0.23
+>                         ; l3 = allpassN l2 0.05 r1 2
+>                         ; l4 = delayN l3 0.3 (mce [0.17, 0.23])
+>                         ; l5 = allpassN l4 0.05 r2 2              
+>                         ; l6 = leakDC l5 0.995
+>                         ; l7 = l6 + i }
+>                     in return (mrg [l7, localOut l7]) }
+>     ; signal = do { s <- liftM2 (+) bang (mixFillM 8 (const pling))
+>                   ; chain 4 r_allpass s } }
+> in audition . out 0 =<< tank =<< signal
+
+{ var r_allpass = { arg signal 
+                  ; var r = { Rand.new(0.005, 0.02) }.dup
+                  ; AllpassN.ar(signal, 0.03, r, 1); }
+; var pling = { var d = Dust.ar(0.2)
+              ; var f = ExpRand.new(300, 2200)
+              ; var p = Rand.new(-1, 1)
+              ; var s1 = FSinOsc.ar(f, 0).cubed
+              ; var s2 = Decay2.ar(d, 0.1, 0.5) * 0.1 * s1
+              ; Pan2.ar(s2, p, 1) }
+; var bang = { var d = Dust.ar(0.01)
+             ; var n = BrownNoise.ar
+             ; Pan2.ar(Decay2.ar(d, 0.04, 0.3) * n, 0, 1) }
+; var tank = { arg i
+             ; var r1 = { Rand.new(0.01,0.05) }.dup
+             ; var r2 = { Rand.new(0.03,0.15) }.dup
+             ; var l0 = LocalIn.ar(2) * 0.98
+             ; var l1 = OnePole.ar(l0, 0.33)
+             ; var l2 = Rotate2.ar(l1[0], l1[1], 0.23)
+             ; var l3 = AllpassN.ar(l2, 0.05, r1, 2)
+             ; var l4 = DelayN.ar(l3, 0.3, [0.17,0.23])
+             ; var l5 = AllpassN.ar(l4, 0.05, r2, 2)
+             ; var l6 = LeakDC.ar(l5, 0.995)
+             ; var l7 = l6 + i
+             ; LocalOut.ar(l7)
+             ; l7 }
+; var signal = Mix.fill(12, pling) + bang.value
+; 4.do({ signal = r_allpass.value(signal) })
+; Out.ar(0, tank.value(signal)) }.play
+
+http://create.ucsb.edu/pipermail/sc-users/2004-April/009692.html
diff --git a/Help/Graphs/theremin.lhs b/Help/Graphs/theremin.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/theremin.lhs
@@ -0,0 +1,28 @@
+theremin (jmcc)
+
+> let { mod = 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
+>     ; a = sinOsc AR f' 0 * x }
+> in audition (out 0 (pan2 a 0 1))
+
+{ var mod = 7
+; var detune = 0
+; var x = MouseX.kr(0, 0.9, 'linear', 0.2)
+; var y = MouseY.kr(4000, 200, 'exponential', 0.8)
+; var f = y + detune
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/three-cpsw.lhs
@@ -0,0 +1,31 @@
+three-cpsw (rd)
+
+> do { t <- dust KR (mce2 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
+>    ; let { f = f1 * mce2 9000 12000 + 9500
+>          ; o = saw AR f + saw AR (f * dh) + saw AR (f * dt) }
+>      in audition (out 0 (clip2 (o * a) 0.75)) }
+
+{ var t = Dust.kr([12, 18])
+; var f0 = TRand.kr(1, 64, t)
+; var f1 = LFNoise0.kr(f0)
+; var a = TRand.kr(0.0, 0.5, t)
+; var dt = TRand.kr(0.975, 1.025, t)
+; var dh = TRand.kr(0.750, 0.7505, t)
+; 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/tsort.lhs b/Help/Graphs/tsort.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/tsort.lhs
@@ -0,0 +1,26 @@
+tsort (jmcc)
+
+This simple graph tests the topological sort of the unit generator
+graph, it ought only to use a minimal number of interconnect buffers.
+
+The below 369 node graph works with 'scsynth -u 57110 -w 2'.  
+
+(Note that graphs loaded from disk during startup will grow the number
+of interconnect buffers, so to test this we must delete all graphs that
+would otherwise be loaded.)
+
+> let { n = 122
+>     ; c = envCoord [(0,0), (0.15, 1), (6, 0)] 1 1 EnvLin
+>     ; e = envGen KR 1 1 0 1 RemoveSynth c
+>     ; f o = sinOsc AR (440 + constant o) 0 * 0.001
+>     ; 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/what-was-i-thinking.lhs b/Help/Graphs/what-was-i-thinking.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/what-was-i-thinking.lhs
@@ -0,0 +1,46 @@
+what was i thinking? (jmcc)
+
+> do { n0 <- lfNoise1 KR 0.2
+>    ; n1 <- lfNoise1 KR 0.157
+>    ; let { p = pulse AR f (n1 * 0.4 + 0.5) * 0.04
+>          ; i = lfPulse AR 0.1 0 0.05 * impulse AR 8 0 * 500
+>          ; d = decay i 2
+>          ; f = max (sinOsc KR 4 0 + 80) d
+>          ; z = rlpf p (n0 * 2000 + 2400) 0.2
+>          ; c x = do { r <- rand 0 0.3
+>                     ; n <- lfNoise1 KR r
+>                     ; return (combL x 0.06 (n * 0.025 + 0.035) 1) }
+>          ; y = z * 0.6 }
+>      in do { z0 <- clone 2 (c y)
+>            ; z1 <- clone 2 (c y)
+>            ; audition (out 0 (z + mce [mix z0, mix z1])) } }
+
+{ var n0 = LFNoise1.kr(0.2, 2000, 2400)
+; var n1 = LFNoise1.kr(0.157, 0.4, 0.5)
+; var i = LFPulse.ar(0.1, 0, 0.05) * Impulse.ar(8, 0) * 500
+; var d = Decay.ar(i, 2)
+; var f = max(SinOsc.kr(4, 0) + 80, d)
+; var p = Pulse.ar(f, n1) * 0.04
+; var z = RLPF.ar(p, n0, 0.2)
+; var c = { arg i
+          ; var r = Rand.new(0, 0.3)
+          ; var n = LFNoise1.kr(r, 0.025, 0.035)
+          ; CombL.ar(i, 0.06, n, 1) }
+; 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/wind-metals.lhs b/Help/Graphs/wind-metals.lhs
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/wind-metals.lhs
@@ -0,0 +1,39 @@
+wind metals (jmcc)
+
+> let n = 6
+> in do { base <- expRand 60 4000
+>       ; range <- rand 500 8000
+>       ; n0 <- clone 2 (brownNoise AR)
+>       ; r0 <- expRand 0.125 0.5
+>       ; n1 <- lfNoise1 KR r0
+>       ; f <- replicateM n (rand base (base + range))
+>       ; dt <- replicateM n (rand 0.1 2)
+>       ; let { exc = n0 * 0.007 * max 0 (n1 * 0.75 + 0.25)
+>             ; k = klankSpec f (replicate n 1) dt
+>             ; s = klank exc 1 0 1 k }
+>         in audition (out 0 (softClip (s * 0.1))) }
+
+{ var n = 6
+; var base = ExpRand.new(60, 4000)
+; var range = Rand.new(500.0, 8000.0)
+; var n0 = BrownNoise.ar([0.007, 0.007])
+; var r0 = ExpRand.new(0.125, 0.5)
+; var n1 = LFNoise1.kr(r0, 0.75, 0.25)
+; var exc = n0 * max(0, n1)
+; var f = Array.fill(n, { Rand.new(0, range) + base })
+; 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
new file mode 100644
--- /dev/null
+++ b/Help/Graphs/xy-interference.lhs
@@ -0,0 +1,26 @@
+xy-interference (rd)
+
+> let { x = mouseX KR 20 22000 Linear (mce2 0.005 0.025)
+>     ; y = mouseY KR 20 22000 Linear (mce2 0.005 0.075)
+>     ; nd = do { n <- lfNoise0 KR (mce2 5 9)
+>               ; let { a = sinOsc AR (x + n) 0
+>                     ; b = sinOsc AR y 0 }
+>                 in return (a * b) } }
+> in audition . (out 0) . sum =<< replicateM 3 nd
+
+{ var x = MouseX.kr(20, 22000, 'linear', [0.005, 0.025])
+; var y = MouseY.kr(20, 22000, 'linear', [0.005, 0.075])
+; var nd = { var n = LFNoise0.kr([5, 9])
+           ; var a = SinOsc.ar(x + n, 0)
+           ; 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
@@ -126,27 +126,51 @@
 
 * Multiple line expressions
 
-To evaluate expressions that don't fit on one line select the region
-and type C-cC-e (Haskell SuperCollider -> Expression -> Run region).
-To select a region use the mouse or place the cursor at one end, type
-C-[Space] then move the cursor to the other end.
+There are two variants for expressions that are written over multiple
+lines.
 
-> let f = sinOsc AR (xLine KR 1 1000 9 RemoveSynth) 0 * 200 + 800
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+To evaluate an expression that is written without using the Haskell
+layout rules select the region and type C-cC-e (Haskell SuperCollider
+-> Expression -> Run multiple lines).  To select a region use the
+mouse or place the cursor at one end, type C-[Space] then move the
+cursor to the other end.
 
+> let { f0 = xLine KR 1 1000 9 RemoveSynth
+>     ; f1 = sinOsc AR f0 0 * 200 + 800 }
+> in audition (out 0 (sinOsc AR f1 0 * 0.1))
+
+To evaluate a multiple line expression written using the layout rules
+as applicable within a do block, select the region and type C-cC-r
+(Haskell SuperCollider -> Expression -> Run region).
+
+> let f0 = xLine KR 1 1000 9 RemoveSynth
+>     f1 = sinOsc AR f0 0 * 200 + 800
+> audition (out 0 (sinOsc AR f1 0 * 0.1))
+
 This writes the region in a do block in a procedure to a temporary
 file, /tmp/hsc3.lhs, loads the file and then runs the procedure.  The
 preamble imports the modules listed at the emacs variable
 hsc3-modules.
 
+ghci understands import expressions, so to add a module to
+the current scope it is enough to type C-cC-c at an appropriate
+location.  If hsc3-dot is installed, the following lines will
+make a drawing.
+
+> import Sound.SC3.UGen.Dot
+
+> let { o = control KR "bus" 0
+>     ; f = mouseX KR 440 880 Exponential 0.1 }
+> in draw (out o (sinOsc AR f 0))
+
 * Help Files
 
-To find help on a UGen or on a SuperCollider server command place the
-cursor over the identifier and type C-cC-h (Haskell SuperCollider ->
-Help -> Haskell SuperCollider help).  This opens the help file, which
-ought to have working examples in it, the above graph is in the sinOsc
-help file, the s_new help file explains what arguments are required
-and what they mean.
+To find help on a unit generator or on a SuperCollider server command
+place the cursor over the identifier and type C-cC-h (Haskell
+SuperCollider -> Help -> Haskell SuperCollider help).  This opens the
+help file, which ought to have working examples in it, the above graph
+is in the sinOsc help file, the s_new help file explains what
+arguments are required and what they mean.
 
 The Haskell SuperCollider help files are derived from the help files
 distributed with SuperCollider, the text is re-formatted to read well
@@ -156,6 +180,30 @@
 Sound.OpenSoundControl modules, to build type:
 
   $ runhaskell Setup.lhs haddock
+
+* Identifier lookup & hasktags
+
+The emacs command M-. (find-tag) looks up an identifier in
+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 
+and type:
+
+  $ find Sound -name '*.*hs' | xargs hasktags -e
+
+To use the hsc3 tags table type `M-x visit-tags-table', or add
+an entry to ~/.emacs:
+
+  (setq tags-table-list '("~/sw/hsc3"))
+
+* Example Unit Generator Graphs
+
+The Help/Graphs 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
+supercollider language versions.
 
 * User configuration files
 
diff --git a/Help/UGen/Analysis/amplitude.help.lhs b/Help/UGen/Analysis/amplitude.help.lhs
--- a/Help/UGen/Analysis/amplitude.help.lhs
+++ b/Help/UGen/Analysis/amplitude.help.lhs
@@ -2,8 +2,10 @@
 
 Amplitude follower. Tracks the peak amplitude of a signal.
 
-> let s = in' 1 AR numOutputBuses
-> audition (out 0 (pulse AR 90 0.3 * amplitude KR s 0.1 0.1))
+> let { s = in' 1 AR numOutputBuses
+>     ; a = amplitude KR s 0.1 0.1 }
+> in audition (out 0 (pulse AR 90 0.3 * a))
 
-> let s = in' 1 AR numOutputBuses
-> audition (out 0 (sinOsc AR (amplitude KR s 0.1 0.1 * 1200 + 400) 0 * 0.3))
+> let { s = in' 1 AR numOutputBuses
+>     ; f = amplitude KR s 0.1 0.1 * 1200 + 400 }
+> in audition (out 0 (sinOsc AR f 0 * 0.3))
diff --git a/Help/UGen/Analysis/compander.help.lhs b/Help/UGen/Analysis/compander.help.lhs
--- a/Help/UGen/Analysis/compander.help.lhs
+++ b/Help/UGen/Analysis/compander.help.lhs
@@ -38,38 +38,38 @@
 
 Example signal to process.
 
-> let e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
->     p = mix (pulse AR (MCE [80, 81]) 0.3)
-> audition (out 0 (e * p))
+> let { e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
+>     ; p = mix (pulse AR (mce [80, 81]) 0.3) }
+> in audition (out 0 (e * p))
 
 Noise gate
 
-> let e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
->     p = mix (pulse AR (MCE [80, 81]) 0.3)
->     z = e * p
->     x = mouseX KR 0.01 1 Linear 0.1
-> audition (out 0 (MCE [z, compander z z x 10 1 0.01 0.01]))
+> let { e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
+>     ; p = mix (pulse AR (mce [80, 81]) 0.3)
+>     ; z = e * p
+>     ; x = mouseX KR 0.01 1 Linear 0.1 }
+> in audition (out 0 (mce [z, compander z z x 10 1 0.01 0.01]))
 
 Compressor
 
-> let e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
->     p = mix (pulse AR (MCE [80, 81]) 0.3)
->     z = e * p
->     x = mouseX KR 0.01 1 Linear 0.1
-> audition (out 0 (MCE [z, compander z z x 1 0.5 0.01 0.01]))
+> let { e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
+>     ; p = mix (pulse AR (mce [80, 81]) 0.3)
+>     ; z = e * p
+>     ; x = mouseX KR 0.01 1 Linear 0.1 }
+> in audition (out 0 (mce [z, compander z z x 1 0.5 0.01 0.01]))
 
 Limiter
 
-> let e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
->     p = mix (pulse AR (MCE [80, 81]) 0.3)
->     z = e * p
->     x = mouseX KR 0.01 1 Linear 0.1
-> audition (out 0 (MCE [z, compander z z x 1 0.1 0.01 0.01]))
+> let { e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
+>     ; p = mix (pulse AR (mce [80, 81]) 0.3)
+>     ; z = e * p
+>     ; x = mouseX KR 0.01 1 Linear 0.1 }
+> in audition (out 0 (mce [z, compander z z x 1 0.1 0.01 0.01]))
 
 Sustainer
 
-> let e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
->     p = mix (pulse AR (MCE [80, 81]) 0.3)
->     z = e * p
->     x = mouseX KR 0.01 1 Linear 0.1
-> audition (out 0 (MCE [z, compander z z x 0.1 1.0 0.01 0.01]))
+> let { e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
+>     ; p = mix (pulse AR (mce [80, 81]) 0.3)
+>     ; z = e * p
+>     ; x = mouseX KR 0.01 1 Linear 0.1 }
+> in audition (out 0 (mce [z, compander z z x 0.1 1.0 0.01 0.01]))
diff --git a/Help/UGen/Analysis/pitch.help.lhs b/Help/UGen/Analysis/pitch.help.lhs
--- a/Help/UGen/Analysis/pitch.help.lhs
+++ b/Help/UGen/Analysis/pitch.help.lhs
@@ -17,14 +17,14 @@
 maxFreq = 4000, execFreq = 100, maxBinsPerOctave = 16, median = 1,
 ampThreshold = 0.01, peakThreshold = 0.5, downSample = 1.
 
-> let x = mouseX KR 220 660 Linear 0.1
->     y = mouseY KR 0.05 0.25 Linear 0.1
->     s = sinOsc AR x 0 * y
->     a = amplitude KR s 0.05 0.05
->     f = pitch s 440 60 4000 100 16 7 0.02 0.5 1
-> audition (out 0 (MCE [s, sinOsc AR (mceChannel 0 f / 2) 0 * a]))
+> let { x = mouseX KR 220 660 Linear 0.1
+>     ; y = mouseY KR 0.05 0.25 Linear 0.1
+>     ; s = sinOsc AR x 0 * y
+>     ; a = amplitude KR s 0.05 0.05
+>     ; f = pitch s 440 60 4000 100 16 7 0.02 0.5 1 }
+> in audition (out 0 (mce [s, sinOsc AR (mceChannel 0 f / 2) 0 * a]))
 
-> let s = in' 1 AR numOutputBuses
->     a = amplitude KR s 0.1 0.1
->     f = pitch s 440 60 4000 100 16 7 0.02 0.5 1
-> audition (out 0 (MCE [s, sinOsc AR (mceChannel 0 f) 0 * a]))
+> let { s = in' 1 AR numOutputBuses
+>     ; a = amplitude KR s 0.1 0.1
+>     ; f = pitch s 440 60 4000 100 16 7 0.02 0.5 1 }
+> in audition (out 0 (mce [s, sinOsc AR (mceChannel 0 f) 0 * a]))
diff --git a/Help/UGen/Analysis/runningSum.help.lhs b/Help/UGen/Analysis/runningSum.help.lhs
--- a/Help/UGen/Analysis/runningSum.help.lhs
+++ b/Help/UGen/Analysis/runningSum.help.lhs
@@ -8,4 +8,4 @@
           (initialisation rate)
 
 > let a = runningSum (in' 1 AR numOutputBuses) 40 * (1/40)
-> audition (out 0 (sinOsc AR 440 0 * a))
+> in audition (out 0 (sinOsc AR 440 0 * a))
diff --git a/Help/UGen/Analysis/slope.help.lhs b/Help/UGen/Analysis/slope.help.lhs
--- a/Help/UGen/Analysis/slope.help.lhs
+++ b/Help/UGen/Analysis/slope.help.lhs
@@ -10,8 +10,10 @@
 In the example below a is quadratic noise, b first derivative line
 segments, and c second derivative constant segments.
 
-> a <- lfNoise2 KR 2
-> let s = 1/2
->     b = slope a * s
->     c = slope b * squared s
-> audition (out 0 (mix (sinOsc AR (MCE [a, b, c] * 220 + 220) 0 * (1/3))))
+> do { a <- lfNoise2 KR 2
+>    ; let { s = 1/2
+>          ; b = slope a * s
+>          ; c = slope b * squared s 
+>          ; f = mce [a, b, c] * 220 + 220
+>          ; o = sinOsc AR f 0 * (1/3) }
+>      in audition (out 0 (mix o)) }
diff --git a/Help/UGen/Analysis/zeroCrossing.help.lhs b/Help/UGen/Analysis/zeroCrossing.help.lhs
--- a/Help/UGen/Analysis/zeroCrossing.help.lhs
+++ b/Help/UGen/Analysis/zeroCrossing.help.lhs
@@ -10,4 +10,4 @@
 in - input signal.
 
 > let a = sinOsc AR (sinOsc KR 1 0 * 600 + 700) 0 * 0.1
-> audition (out 0 (MCE [a, impulse AR (zeroCrossing a) 0 * 0.25]))
+> in audition (out 0 (mce [a, impulse AR (zeroCrossing a) 0 * 0.25]))
diff --git a/Help/UGen/Buffer/bufAllpassC.help.lhs b/Help/UGen/Buffer/bufAllpassC.help.lhs
--- a/Help/UGen/Buffer/bufAllpassC.help.lhs
+++ b/Help/UGen/Buffer/bufAllpassC.help.lhs
@@ -18,10 +18,9 @@
             negative, thus emphasizing only odd harmonics at an
             octave lower.
 
-> withSC3 (\fd -> do send fd (b_alloc 0 44100 1)
->                    wait fd "/done")
+> withSC3 (\fd -> async fd (b_alloc 0 44100 1))
 
-> d <- dust AR 1
-> n <- whiteNoise AR
-> let x = decay d 0.2 * n * 0.25
-> audition (out 0 (bufAllpassC 0 x 0.25 6))
+> do { d <- dust AR 1
+>    ; n <- whiteNoise AR
+>    ; let x = decay d 0.2 * n * 0.25
+>      in audition (out 0 (bufAllpassC 0 x 0.25 6)) }
diff --git a/Help/UGen/Buffer/bufCombC.help.lhs b/Help/UGen/Buffer/bufCombC.help.lhs
--- a/Help/UGen/Buffer/bufCombC.help.lhs
+++ b/Help/UGen/Buffer/bufCombC.help.lhs
@@ -16,10 +16,9 @@
             negative, thus emphasizing only odd harmonics at an
             octave lower.
 
-> withSC3 (\fd -> do send fd (b_alloc 0 44100 1)
->                    wait fd "/done")
+> withSC3 (\fd -> async fd (b_alloc 0 44100 1))
 
-> d <- dust AR 1
-> n <- whiteNoise AR
-> let x = decay d 0.2 * n * 0.25
-> audition (out 0 (bufCombC 0 x 0.25 6))
+> do { d <- dust AR 1
+>    ; n <- whiteNoise AR
+>    ; let x = decay d 0.2 * n * 0.25
+>      in audition (out 0 (bufCombC 0 x 0.25 6)) }
diff --git a/Help/UGen/Buffer/bufDelayC.help.lhs b/Help/UGen/Buffer/bufDelayC.help.lhs
--- a/Help/UGen/Buffer/bufDelayC.help.lhs
+++ b/Help/UGen/Buffer/bufDelayC.help.lhs
@@ -14,10 +14,9 @@
 in        - the input signal.
 delaytime - delay time in seconds.
 
-> withSC3 (\fd -> do send fd (b_alloc 0 44100 1)
->                    wait fd "/done")
+> withSC3 (\fd -> async fd (b_alloc 0 44100 1))
 
-> d <- dust AR 1
-> n <- whiteNoise AR
-> let x = decay d 0.5 * n * 0.3
-> audition (out 0 (bufDelayC 0 x 0.2 + x))
+> do { d <- dust AR 1
+>    ; n <- whiteNoise AR
+>    ; let x = decay d 0.5 * n * 0.3
+>      in audition (out 0 (bufDelayC 0 x 0.2 + x)) }
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
@@ -2,9 +2,8 @@
 
 Current duration of buffer.
 
-> withSC3 (\fd -> do send fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0)
->                    wait fd "/done")
+> withSC3 (\fd -> async fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0))
 
-> let t = impulse AR (recip (bufDur KR 0)) 0
->     p = sweep t (bufSampleRate KR 0)
-> audition (out 0 (bufRdL 1 AR 0 p NoLoop))
+> let { t = impulse AR (recip (bufDur KR 0)) 0
+>     ; p = sweep t (bufSampleRate KR 0) }
+> in audition (out 0 (bufRdL 1 AR 0 p NoLoop))
diff --git a/Help/UGen/Buffer/bufFrames.help.lhs b/Help/UGen/Buffer/bufFrames.help.lhs
--- a/Help/UGen/Buffer/bufFrames.help.lhs
+++ b/Help/UGen/Buffer/bufFrames.help.lhs
@@ -2,12 +2,13 @@
 
 Current duration of buffer.
 
-> withSC3 (\fd -> do send fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0)
->                    wait fd "/done")
+> withSC3 (\fd -> async fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0))
 
 > let p = phasor AR 0 (bufRateScale KR 0) 0 (bufFrames KR 0) 0
-> audition (out 0 (bufRdL 1 AR 0 p NoLoop))
+> in audition (out 0 (bufRdL 1 AR 0 p NoLoop))
 
-> let r = MCE [0.05, 0.075 .. 0.15]
->     p = k2A (mouseX KR 0 (bufFrames KR 0) Linear r)
-> audition (out 0 (mix (bufRdL 1 AR 0 p NoLoop)))
+Mouse location drags play head.
+
+> let { r = mce [0.05, 0.075 .. 0.15]
+>     ; p = k2A (mouseX KR 0 (bufFrames KR 0) Linear r) }
+> in audition (out 0 (mix (bufRdL 1 AR 0 p NoLoop)))
diff --git a/Help/UGen/Buffer/bufRateScale.help.lhs b/Help/UGen/Buffer/bufRateScale.help.lhs
--- a/Help/UGen/Buffer/bufRateScale.help.lhs
+++ b/Help/UGen/Buffer/bufRateScale.help.lhs
@@ -3,9 +3,8 @@
 Buffer rate scaling in respect to server samplerate.  Returns a
 ratio by which the playback of a soundfile is to be scaled.
 
-> withSC3 (\fd -> do send fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0)
->                    wait fd "/done")
+> withSC3 (\fd -> async fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0))
 
-> let r = 1.25 * bufRateScale KR 0
->     p = phasor AR 0 r 0 (bufFrames KR 0) 0
-> audition (out 0 (bufRdL 1 AR 0 p NoLoop))
+> let { r = 1.25 * bufRateScale KR 0
+>     ; p = phasor AR 0 r 0 (bufFrames KR 0) 0 }
+> in audition (out 0 (bufRdL 1 AR 0 p NoLoop))
diff --git a/Help/UGen/Buffer/bufRd.help.lhs b/Help/UGen/Buffer/bufRd.help.lhs
--- a/Help/UGen/Buffer/bufRd.help.lhs
+++ b/Help/UGen/Buffer/bufRd.help.lhs
@@ -13,11 +13,11 @@
 > withSC3 (\fd -> send fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0))
 
 > let phase = (sinOsc AR 0.1 0 * bufFrames KR 0)
-> audition (out 0 (bufRd 1 AR 0 phase Loop NoInterpolation))
+> in audition (out 0 (bufRd 1 AR 0 phase Loop NoInterpolation))
 
 There are constructors, bufRdN, bufRdL, and bufRdC for the fixed
 cases.
 
-> let x = mouseX KR (MCE [5, 10]) 100 Linear 0.1
-> n <- lfNoise1 AR x
-> audition (out 0 (bufRdL 1 AR 0 (n * bufFrames KR 0) Loop))
+> let x = mouseX KR (mce [5, 10]) 100 Linear 0.1
+> in do { n <- lfNoise1 AR x
+>       ; audition (out 0 (bufRdL 1 AR 0 (n * bufFrames KR 0) Loop)) }
diff --git a/Help/UGen/Buffer/bufSampleRate.help.lhs b/Help/UGen/Buffer/bufSampleRate.help.lhs
--- a/Help/UGen/Buffer/bufSampleRate.help.lhs
+++ b/Help/UGen/Buffer/bufSampleRate.help.lhs
@@ -2,11 +2,10 @@
 
 Buffer sample rate.
 
-> withSC3 (\fd -> do send fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0)
->                    wait fd "/done")
+> withSC3 (\fd -> async fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0))
 
 Compare a sine tone derived from sample rate of a buffer with a
 440Hz tone.
 
-> let f = MCE [bufSampleRate KR 0 * 0.01, 440]
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> let f = mce [bufSampleRate KR 0 * 0.01, 440]
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Buffer/detectIndex.help.lhs b/Help/UGen/Buffer/detectIndex.help.lhs
--- a/Help/UGen/Buffer/detectIndex.help.lhs
+++ b/Help/UGen/Buffer/detectIndex.help.lhs
@@ -5,16 +5,15 @@
 
 Allocate and set values at buffer 10.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 6 1)
->                    wait fd "/done"
->                    send fd (b_setn 10 [(0, [2, 3, 4, 0, 1, 5])]))
+> withSC3 (\fd -> do { async fd (b_alloc 10 6 1)
+>                    ; send fd (b_setn 10 [(0, [2, 3, 4, 0, 1, 5])]) })
 
 Find indexes and map to an audible frequency range.
 
-> let n = 6
->     x = floorE (mouseX KR 0 n Linear 0.1)
->     i = detectIndex 10 x
-> audition (out 0 (sinOsc AR (linExp i 0 n 200 700) 0 * 0.1))
+> let { n = 6
+>     ; x = floorE (mouseX KR 0 n Linear 0.1)
+>     ; i = detectIndex 10 x }
+> in audition (out 0 (sinOsc AR (linExp i 0 n 200 700) 0 * 0.1))
 
 Free buffer.
 
diff --git a/Help/UGen/Buffer/index.help.lhs b/Help/UGen/Buffer/index.help.lhs
--- a/Help/UGen/Buffer/index.help.lhs
+++ b/Help/UGen/Buffer/index.help.lhs
@@ -6,14 +6,13 @@
 
 Allocate and set values at buffer 10.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 6 1)
->                    wait fd "/done"
->                    send fd (b_setn 10 [(0, [50, 100, 200, 400, 800, 1600])]))
+> withSC3 (\fd -> do { async fd (b_alloc 10 6 1)
+>                    ; send fd (b_setn 10 [(0, [50, 100, 200, 400, 800, 1600])]) })
 
 Index into the above buffer for frequency values.
 
 > let f = index 10 (lfSaw KR 2 3 * 4)
-> audition (out 0 (sinOsc AR (MCE [f, f * 9]) 0 * 0.1))
+> in audition (out 0 (sinOsc AR (mce [f, f * 9]) 0 * 0.1))
 
 Free buffer.
 
diff --git a/Help/UGen/Buffer/indexInBetween.help.lhs b/Help/UGen/Buffer/indexInBetween.help.lhs
--- a/Help/UGen/Buffer/indexInBetween.help.lhs
+++ b/Help/UGen/Buffer/indexInBetween.help.lhs
@@ -4,18 +4,17 @@
 
 Allocate and set values at buffer 10.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 6 1)
->                    wait fd "/done"
->                    send fd (b_setn 10 [(0, [200, 210, 400, 430, 600, 800])]))
+> withSC3 (\fd -> do { async fd (b_alloc 10 6 1)
+>                    ; send fd (b_setn 10 [(0, [200, 210, 400, 430, 600, 800])]) })
 
 Index into the above buffer for frequency values.
 
-> let f0 = mouseX KR 200 900 Linear 0.1
->     i = indexInBetween 10 f0
->     l0 = index 10 i
->     l1 = index 10 (i + 1)
->     f1 = linLin (frac i) 0 1 l0 l1
-> audition (out 0 (sinOsc AR (MCE [f0, f1]) 0 * 0.1))
+> let { f0 = mouseX KR 200 900 Linear 0.1
+>     ; i = indexInBetween 10 f0
+>     ; l0 = index 10 i
+>     ; l1 = index 10 (i + 1)
+>     ; f1 = linLin (frac i) 0 1 l0 l1 }
+> in audition (out 0 (sinOsc AR (mce [f0, f1]) 0 * 0.1))
 
 Free buffer.
 
diff --git a/Help/UGen/Buffer/osc.help.lhs b/Help/UGen/Buffer/osc.help.lhs
--- a/Help/UGen/Buffer/osc.help.lhs
+++ b/Help/UGen/Buffer/osc.help.lhs
@@ -15,30 +15,29 @@
 Note about wavetables: OscN requires the b_gen sine1 wavetable flag
 to be OFF.  Osc requires the b_gen sine1 wavetable flag to be ON.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 512 1)
->                    wait fd "/done"
->                    send fd (b_gen 10 "sine1" [1 + 2 + 4, 1, 1/2, 1/3, 1/4, 1/5]))
+> withSC3 (\fd -> do { async fd (b_alloc 10 512 1)
+>                    ; send fd (b_gen 10 "sine1" [1 + 2 + 4, 1, 1/2, 1/3, 1/4, 1/5]) })
 
 > audition (out 0 (osc AR 10 220 0 * 0.1))
 
 Modulate freq
 
 > let f = xLine KR 2000 200 1 DoNothing
-> audition (out 0 (osc AR 10 f 0 * 0.1))
+> in audition (out 0 (osc AR 10 f 0 * 0.1))
 
 Modulate freq
 
 > let f = osc AR 10 (xLine KR 1 1000 9 RemoveSynth) 0 * 200 + 800
-> audition (out 0 (osc AR 10 f 0 * 0.1))
+> in audition (out 0 (osc AR 10 f 0 * 0.1))
 
 Modulate phase
 
 > let p = osc AR 10 (xLine KR 20 8000 10 RemoveSynth) 0 * 2 * pi
-> audition (out 0 (osc AR 10 800 p * 0.1))
+> in audition (out 0 (osc AR 10 800 p * 0.1))
 
 Change the buffer while its playing
 
 > audition (out 0 (osc AR 10 220 0 * 0.1))
 
-> r <- getStdRandom (randomR (0.0,1.0))
-> withSC3 (\fd -> send fd (b_gen 10 "sine1" [1 + 2 + 4, 1, r, 1/4]))
+> do { r <- getStdRandom (randomR (0.0,1.0))
+>    ; withSC3 (\fd -> send fd (b_gen 10 "sine1" [1 + 2 + 4, 1, r, 1/4])) }
diff --git a/Help/UGen/Buffer/playBuf.help.lhs b/Help/UGen/Buffer/playBuf.help.lhs
--- a/Help/UGen/Buffer/playBuf.help.lhs
+++ b/Help/UGen/Buffer/playBuf.help.lhs
@@ -30,8 +30,7 @@
 Allocate buffer.
 
 > let fileName = "/home/rohan/audio/metal.wav"
-> withSC3 (\fd -> do send fd (b_allocRead 10 fileName 0 0)
->                    wait fd "/done")
+> in withSC3 (\fd -> async fd (b_allocRead 10 fileName 0 0))
 
 Play once only.
 
@@ -44,24 +43,24 @@
 Trigger playback at each pulse.
 
 > let t = impulse KR 2 0
-> audition (out 0 (playBuf 1 10 (bufRateScale KR 10) t 0 NoLoop))
+> in audition (out 0 (playBuf 1 10 (bufRateScale KR 10) t 0 NoLoop))
 
 Trigger playback at each pulse (diminishing intervals).
 
-> let f = xLine KR 0.1 100 10 RemoveSynth
->     t = impulse KR f 0
-> audition (out 0 (playBuf 1 10 (bufRateScale KR 10) t 0 NoLoop))
+> let { f = xLine KR 0.1 100 10 RemoveSynth
+>     ; t = impulse KR f 0 }
+> in audition (out 0 (playBuf 1 10 (bufRateScale KR 10) t 0 NoLoop))
 
 Loop playback, accelerating pitch.
 
 > let r = xLine KR 0.1 100 60 RemoveSynth
-> audition (out 0 (playBuf 1 10 r 1 0 Loop))
+> in audition (out 0 (playBuf 1 10 r 1 0 Loop))
 
 Sine wave control of playback rate, negative rate plays backwards.
 
-> let f = xLine KR 0.2 8 30 RemoveSynth
->     r = fSinOsc KR f 0 * 3 + 0.6
-> audition (out 0 (playBuf 1 10 (bufRateScale KR 10 * r) 1 0 Loop))
+> let { f = xLine KR 0.2 8 30 RemoveSynth
+>     ; r = fSinOsc KR f 0 * 3 + 0.6 }
+> in audition (out 0 (playBuf 1 10 (bufRateScale KR 10 * r) 1 0 Loop))
 
 Release buffer.
 
diff --git a/Help/UGen/Buffer/vOsc.help.lhs b/Help/UGen/Buffer/vOsc.help.lhs
--- a/Help/UGen/Buffer/vOsc.help.lhs
+++ b/Help/UGen/Buffer/vOsc.help.lhs
@@ -23,25 +23,24 @@
 
 Allocate and fill tables 0 to 7.
 
-> let square a = a * a
->     harmonics i = map f [0 .. n - 1]
->         where n = square (i + 1)
->               f j = square ((n - j) / n)
->     setup fd i = do let i' = fromIntegral i
->                     send fd (b_alloc i 1024 1)
->                     wait fd "/done"
->                     send fd (b_gen i "sine1" (1 + 2 + 4 : harmonics i'))
-> withSC3 (\fd -> mapM_ (setup fd) [0 .. 7])
+> let { square a = a * a
+>     ; harmonics i = let { n = square (i + 1)
+>                         ; f j = square ((n - j) / n) }
+>                     in map f [0 .. n - 1]
+>     ; setup fd i = do { i' <- return (fromIntegral i)
+>                       ; async fd (b_alloc i 1024 1)
+>                       ; send fd (b_gen i "sine1" (1 + 2 + 4 : harmonics i')) } }
+> in withSC3 (\fd -> mapM_ (setup fd) [0 .. 7])
 
 Oscillator at buffers 0 through 7, mouse selects buffer.
 
 > let x = mouseX KR 0 7 Linear 0.1
-> audition (out 0 (vOsc AR x (MCE [120, 121]) 0 * 0.3))
+> in audition (out 0 (vOsc AR x (mce [120, 121]) 0 * 0.3))
 
 Reallocate buffers while oscillator is running.
 
-> let rrand l r = getStdRandom (randomR (l,r))
->     rrandl n l r = replicateM n (rrand l r)
->     resetTable fd i = do h <- rrandl 12 0 1
->                          send fd (b_gen i "sine1" (1 + 2 + 4 : h))
-> withSC3 (\fd -> mapM_ (resetTable fd) [0 .. 7])
+> let { rrand l r = getStdRandom (randomR (l,r))
+>     ; rrandl n l r = replicateM n (rrand l r)
+>     ; resetTable fd i = do { h <- rrandl 12 0 1
+>                            ; send fd (b_gen i "sine1" (1 + 2 + 4 : h)) } }
+> in withSC3 (\fd -> mapM_ (resetTable fd) [0 .. 7])
diff --git a/Help/UGen/Chaos/cuspL.help.lhs b/Help/UGen/Chaos/cuspL.help.lhs
--- a/Help/UGen/Chaos/cuspL.help.lhs
+++ b/Help/UGen/Chaos/cuspL.help.lhs
@@ -17,13 +17,13 @@
 
 Mouse-controlled parameters.
 
-> let x = mouseX KR 0.9 1.1 Linear 0.1
->     y = mouseY KR 1.8 2.0 Linear 0.1
-> audition (out 0 (cuspL AR (sampleRate / 4) x y 0 * 0.3))
+> let { x = mouseX KR 0.9 1.1 Linear 0.1
+>     ; y = mouseY KR 1.8 2.0 Linear 0.1 }
+> in audition (out 0 (cuspL AR (sampleRate / 4) x y 0 * 0.3))
 
 As frequency control.
 
-> let x = mouseX KR 0.9 1.1 Linear 0.1
->     y = mouseY KR 1.8 2.0 Linear 0.1
->     n = cuspL AR 40 x y 0 * 0.3
-> audition (out 0 (sinOsc AR (n * 800 + 900) 0 * 0.4))
+> let { x = mouseX KR 0.9 1.1 Linear 0.1
+>     ; y = mouseY KR 1.8 2.0 Linear 0.1
+>     ; n = cuspL AR 40 x y 0 * 0.3 }
+> in audition (out 0 (sinOsc AR (n * 800 + 900) 0 * 0.4))
diff --git a/Help/UGen/Chaos/fbSineC.help.lhs b/Help/UGen/Chaos/fbSineC.help.lhs
--- a/Help/UGen/Chaos/fbSineC.help.lhs
+++ b/Help/UGen/Chaos/fbSineC.help.lhs
@@ -29,19 +29,21 @@
 Increase feedback
 
 > let fb = line KR 0.01 4 10 DoNothing
-> audition (out 0 (fbSineC AR sampleRate 1 fb 1.1 0.5 0.1 0.1 * 0.2))
+> in audition (out 0 (fbSineC AR sampleRate 1 fb 1.1 0.5 0.1 0.1 * 0.2))
 
 Increase phase multiplier
 
 > let a = line KR 1 2 10 DoNothing
-> audition (out 0 (fbSineC AR sampleRate 1 0 a 0.5 0.1 0.1 * 0.2))
+> in audition (out 0 (fbSineC AR sampleRate 1 0 a 0.5 0.1 0.1 * 0.2))
 
 Randomly modulate parameters
 
-> let x = mouseX KR 1 12 Linear 0.1
-> n0 <- return . (+ 1e4)  . (* 1e4)  =<< lfNoise2 KR x
-> n1 <- return . (+ 33)   . (* 32)   =<< lfNoise2 KR x
-> n2 <- return . (+ 0)    . (* 0.5)  =<< lfNoise2 KR x
-> n3 <- return . (+ 1.05) . (* 0.05) =<< lfNoise2 KR x
-> n4 <- return . (+ 0.3)  . (* 0.3)  =<< lfNoise2 KR x
-> audition (out 0 (fbSineC AR n0 n1 n2 n3 n4 0.1 0.1 * 0.2))
+> let { madd a m = return . (+ a) . (* m)
+>     ; x = mouseX KR 1 12 Linear 0.1 
+>     ; n = lfNoise2 KR x }
+> in do { n0 <- madd 1e4 1e4 =<< n
+>       ; n1 <- madd 33 32 =<< n
+>       ; n2 <- madd 0 0.5 =<< n
+>       ; n3 <- madd 1.05 0.05 =<< n
+>       ; n4 <- madd 0.3 0.3 =<< n
+>       ; audition (out 0 (fbSineC AR n0 n1 n2 n3 n4 0.1 0.1 * 0.2)) }
diff --git a/Help/UGen/Chaos/henonN.help.lhs b/Help/UGen/Chaos/henonN.help.lhs
--- a/Help/UGen/Chaos/henonN.help.lhs
+++ b/Help/UGen/Chaos/henonN.help.lhs
@@ -19,23 +19,24 @@
 With default initial parameters.
 
 > let x = mouseX KR 20 sampleRate Linear 0.1
-> audition (out 0 (henonN AR x 1.4 0.3 0 0 * 0.1))
+> in audition (out 0 (henonN AR x 1.4 0.3 0 0 * 0.1))
 
 With mouse-control of parameters.
 
-> let x = mouseX KR 1 1.4 Linear 0.1
->     y = mouseY KR 0 0.3 Linear 0.1
-> audition (out 0 (henonN AR (sampleRate / 4) x y 0 0 * 0.1))
+> let { x = mouseX KR 1 1.4 Linear 0.1
+>     ; y = mouseY KR 0 0.3 Linear 0.1 }
+> in audition (out 0 (henonN AR (sampleRate / 4) x y 0 0 * 0.1))
 
 With randomly modulate parameters.
 
-> n0 <- return . (+ 1.20) . (* 0.20) =<< lfNoise2 KR 1
-> n1 <- return . (+ 0.15) . (* 0.15) =<< lfNoise2 KR 1
-> audition (out 0 (henonN AR (sampleRate / 8) n0 n1 0 0 * 0.1))
+> do { n0 <- return . (+ 1.20) . (* 0.20) =<< lfNoise2 KR 1
+>    ; n1 <- return . (+ 0.15) . (* 0.15) =<< lfNoise2 KR 1
+>    ; audition (out 0 (henonN AR (sampleRate / 8) n0 n1 0 0 * 0.1)) }
 
 As a frequency control.
 
-> let x = mouseX KR 1 1.4 Linear 0.1
->     y = mouseY KR 0 0.3 Linear 0.1
->     f = 40
-> audition (out 0 (sinOsc AR (henonN AR f x y 0 0 * 800 + 900) 0 * 0.4))
+> let { x = mouseX KR 1 1.4 Linear 0.1
+>     ; y = mouseY KR 0 0.3 Linear 0.1
+>     ; f0 = 40 
+>     ; f = henonN AR f0 x y 0 0 * 800 + 900 }
+> in audition (out 0 (sinOsc AR f 0 * 0.4))
diff --git a/Help/UGen/Chaos/latoocarfianC.help.lhs b/Help/UGen/Chaos/latoocarfianC.help.lhs
--- a/Help/UGen/Chaos/latoocarfianC.help.lhs
+++ b/Help/UGen/Chaos/latoocarfianC.help.lhs
@@ -23,14 +23,14 @@
 sclang default initial parameters.
 
 > let x = mouseX KR 20 sampleRate Linear 0.1
-> audition (out 0 (latoocarfianC AR x 1 3 0.5 0.5 0.5 0.5 * 0.2))
+> in audition (out 0 (latoocarfianC AR x 1 3 0.5 0.5 0.5 0.5 * 0.2))
 
 Randomly modulate all parameters.
 
-> [n0, n1, n2, n3] <- replicateM 4 (lfNoise2 KR 2)
-> let f = sampleRate / 4
->     a = n0 * 1.5 + 1.5
->     b = n1 * 1.5 + 1.5
->     c = n2 * 0.5 + 1.5
->     d = n2 * 0.5 + 1.5
-> audition (out 0 (latoocarfianC AR f a b c d 0.5 0.5 * 0.2))
+> do { [n0, n1, n2, n3] <- replicateM 4 (lfNoise2 KR 2)
+>    ; let { f = sampleRate / 4
+>          ; a = n0 * 1.5 + 1.5
+>          ; b = n1 * 1.5 + 1.5
+>          ; c = n2 * 0.5 + 1.5
+>          ; d = n3 * 0.5 + 1.5 }
+>      in audition (out 0 (latoocarfianC AR f a b c d 0.5 0.5 * 0.2)) }
diff --git a/Help/UGen/Chaos/linCongC.help.lhs b/Help/UGen/Chaos/linCongC.help.lhs
--- a/Help/UGen/Chaos/linCongC.help.lhs
+++ b/Help/UGen/Chaos/linCongC.help.lhs
@@ -21,12 +21,12 @@
 Default initial parameters.
 
 > let x = mouseX KR 20 sampleRate Linear 0.1
-> audition (out 0 (linCongC AR x 1.1 0.13 1 0 * 0.2))
+> in audition (out 0 (linCongC AR x 1.1 0.13 1 0 * 0.2))
 
 Randomly modulate parameters.
 
-> [n0, n1, n2, m] <- mapM (lfNoise2 KR) [1.0, 0.1, 0.1, 0.1]
-> let f = n0 * 1e4 + 1e4
->     a = n1 * 0.5 + 1.4
->     c = n2 * 0.1 + 0.1
-> audition (out 0 (linCongC AR f a c m 0 * 0.2))
+> do { [n0, n1, n2, m] <- mapM (lfNoise2 KR) [1.0, 0.1, 0.1, 0.1]
+>    ; let { f = n0 * 1e4 + 1e4
+>          ; a = n1 * 0.5 + 1.4
+>          ; c = n2 * 0.1 + 0.1 }
+>      in audition (out 0 (linCongC AR f a c m 0 * 0.2)) }
diff --git a/Help/UGen/Chaos/logistic.help.lhs b/Help/UGen/Chaos/logistic.help.lhs
--- a/Help/UGen/Chaos/logistic.help.lhs
+++ b/Help/UGen/Chaos/logistic.help.lhs
@@ -4,4 +4,4 @@
 
 Implements the equation: y1 = param * y1 * (1.0 - y1)
 
-> logistic AR 3.5699457 1000.0 0.01
+> audition (out 0 (logistic AR 3.5699457 1000.0 0.01))
diff --git a/Help/UGen/Chaos/lorenzL.help.lhs b/Help/UGen/Chaos/lorenzL.help.lhs
--- a/Help/UGen/Chaos/lorenzL.help.lhs
+++ b/Help/UGen/Chaos/lorenzL.help.lhs
@@ -22,17 +22,19 @@
 Vary frequency
 
 > let x = mouseX KR 20 sampleRate Linear 0.1
-> audition (out 0 (lorenzL AR x 10 27 2.667 0.05 0.1 0 0 * 0.3))
+> in audition (out 0 (lorenzL AR x 10 27 2.667 0.05 0.1 0 0 * 0.3))
 
 Randomly modulate params
 
-> n0 <- return . (+ 10) . (* 2)   =<< lfNoise0 KR 1
-> n1 <- return . (+ 38) . (* 20)  =<< lfNoise0 KR 1
-> n2 <- return . (+ 2)  . (* 1.5) =<< lfNoise0 KR 1
-> audition (out 0 (lorenzL AR sampleRate n0 n1 n2 0.05 0.1 0 0 * 0.2))
+> let { madd a m = return . (+ a) . (* m)
+>     ; n = lfNoise0 KR 1 }
+> in do { n0 <- madd 10 2 =<< n
+>       ; n1 <- madd 38 20 =<< n
+>       ; n2 <- madd 2 1.5 =<< n
+>       ; audition (out 0 (lorenzL AR sampleRate n0 n1 n2 0.05 0.1 0 0 * 0.2)) }
 
 As frequency control
 
-> let x = mouseX KR 1 200 Linear 0.1
->     n = lorenzL AR x 10 28 2.667 0.05 0.1 0 0 
-> audition (out 0 (sinOsc AR (lag n 0.003 * 800 + 900) 0 * 0.4))
+> let { x = mouseX KR 1 200 Linear 0.1
+>     ; n = lorenzL AR x 10 28 2.667 0.05 0.1 0 0 }
+> in audition (out 0 (sinOsc AR (lag n 0.003 * 800 + 900) 0 * 0.4))
diff --git a/Help/UGen/Chaos/quadN.help.lhs b/Help/UGen/Chaos/quadN.help.lhs
--- a/Help/UGen/Chaos/quadN.help.lhs
+++ b/Help/UGen/Chaos/quadN.help.lhs
@@ -13,8 +13,8 @@
 > audition (out 0 (quadC AR 4000 1 (-1) (-0.75) 0 * 0.2))
 
 > let x = mouseX KR 3.5441 4 Linear 0.1
-> audition (out 0 (quadC AR 4000 (negate x) x 0 0.1 * 0.4))
+> in audition (out 0 (quadC AR 4000 (negate x) x 0 0.1 * 0.4))
 
-> let x = mouseX KR 3.5441 4 Linear 0.1
->     f = quadC AR 4 (negate x) x 0 0.1 * 800 + 900
-> audition (out 0 (sinOsc AR f 0 * 0.4))
+> let { x = mouseX KR 3.5441 4 Linear 0.1
+>     ; f = quadC AR 4 (negate x) x 0 0.1 * 800 + 900 }
+> in audition (out 0 (sinOsc AR f 0 * 0.4))
diff --git a/Help/UGen/Demand/dbrown.help.lhs b/Help/UGen/Demand/dbrown.help.lhs
--- a/Help/UGen/Demand/dbrown.help.lhs
+++ b/Help/UGen/Demand/dbrown.help.lhs
@@ -12,8 +12,8 @@
 Dibrown returns integer values.  The arguments can be a number or
 any other ugen.
 
-> n <- dbrown 32 0 15 1
-> let x = mouseX KR 1 40 Exponential 0.1
->     t = impulse KR x 0
->     f = demand t 0 n * 30 + 340
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> do { n <- dbrown dinf 0 15 1
+>    ; let { x = mouseX KR 1 40 Exponential 0.1
+>          ; t = impulse KR x 0
+>          ; f = demand t 0 n * 30 + 340 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Demand/dbufrd.help.lhs b/Help/UGen/Demand/dbufrd.help.lhs
--- a/Help/UGen/Demand/dbufrd.help.lhs
+++ b/Help/UGen/Demand/dbufrd.help.lhs
@@ -6,37 +6,32 @@
 phase   - index into the buffer (demand ugen or any other ugen)
 loop    - loop when phase exceeds number of frames in buffer
 
-Example
-
 > let n = randomRs (200.0, 500.0) (mkStdGen 0)
-> withSC3 (\fd -> do send fd (b_alloc 10 24 1)
->                    wait fd "/done"
->                    send fd (b_setn 10 [(0, take 24 n)]))
-> s <- dseq 3 (MCE [0, 3, 5, 0, 3, 7, 0, 5, 9])
-> b <- dbrown 5 0 23 1
-> p <- dseq 8192 (MCE [s, b])
-> t <- dust KR 10
-> r <- dbufrd 10 p Loop
-> audition (out 0 (sinOsc AR (demand t 0 r) 0 * 0.1))
+> in do { withSC3 (\fd -> do { async fd (b_alloc 10 24 1)
+>                            ; send fd (b_setn 10 [(0, take 24 n)]) })
+>       ; s <- dseq 3 (mce [0, 3, 5, 0, 3, 7, 0, 5, 9])
+>       ; b <- dbrown 5 0 23 1
+>       ; p <- dseq dinf (mce [s, b])
+>       ; t <- dust KR 10
+>       ; r <- dbufrd 10 p Loop
+>       ; audition (out 0 (sinOsc AR (demand t 0 r) 0 * 0.1)) }
 
 Buffer as a time pattern (requires buffer 10 as allocated above).
 
-> let i = randomRs (0, 2) (mkStdGen 0)
->     n = map ([1, 0.5, 0.25] !!) i
-> withSC3 (\fd -> do send fd (b_alloc 11 24 1)
->                    wait fd "/done"
->                    send fd (b_setn 11 [(0, take 24 n)]))
-> s <- dseq 3 (MCE [0, 3, 5, 0, 3, 7, 0, 5, 9])
-> b <- dbrown 5 0 23 1
-> p <- dseq 8192 (MCE [s, b])
-> j <- dseries 8192 0 1
-> d <- dbufrd 11 j Loop
-> l <- dbufrd 10 p Loop
-> audition (out 0 (sinOsc AR (duty KR (d * 0.5) 0 DoNothing l) 0 * 0.1))
+> let { i = randomRs (0, 2) (mkStdGen 0)
+>     ; n = map ([1, 0.5, 0.25] !!) i }
+> in do { withSC3 (\fd -> do { async fd (b_alloc 11 24 1)
+>                            ; send fd (b_setn 11 [(0, take 24 n)]) })
+>       ; s <- dseq 3 (mce [0, 3, 5, 0, 3, 7, 0, 5, 9])
+>       ; b <- dbrown 5 0 23 1
+>       ; p <- dseq dinf (mce [s, b])
+>       ; j <- dseries dinf 0 1
+>       ; d <- dbufrd 11 j Loop
+>       ; l <- dbufrd 10 p Loop
+>       ; let f = duty KR (d * 0.5) 0 DoNothing l
+>         in audition (out 0 (sinOsc AR f 0 * 0.1)) }
 
 Free buffers
 
-> withSC3 (\fd -> do send fd (b_free 10)
->                    wait fd "/done"
->                    send fd (b_free 11)
->                    wait fd "/done")
+> withSC3 (\fd -> do { async fd (b_free 10)
+>                    ; async fd (b_free 11) })
diff --git a/Help/UGen/Demand/dbufwr.help.lhs b/Help/UGen/Demand/dbufwr.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/Demand/dbufwr.help.lhs
@@ -0,0 +1,29 @@
+dbufwr bufnum phase input loop
+
+Buffer demand ugen.  All inputs can be either 
+demand ugen or any other ugen.
+
+bufnum - buffer number to read from (single channel buffer)
+phase  - index into the buffer
+input  - single channel input
+loop   - when phase exceeds number of frames in buffer, 
+         loops when set to 1 (default :1)
+
+> do { s1 <- dseries 30 0 3
+>    ; s2 <- dseries 30 0 1
+>    ; s3 <- dseries 16 1 1
+>    ; s4 <- dwhite 8 1 16 
+>    ; s5 <- dseq dinf (mce2 s3 s4)
+>    ; wt <- dust KR 1                  {- write trigger -}
+>    ; rp <- dseries dinf 0 1           {- read pointer -}
+>    ; wp <- dseq dinf (mce2 s1 s2)     {- write pointer -}
+>    ; r <- dbufrd 0 rp Loop            {- reader -}
+>    ; w <- dbufwr 0 wp (s5 * 60) Loop  {- writer -}
+>    ; let { d = demand wt 0 w
+>          ; f = lag (demand (impulse KR 16 0) 0 r) 0.01
+>          ; o = sinOsc AR (f * mce2 1 1.01) 0 * 0.1
+>          ; g = mrg [d, out 0 o]
+>          ; run fd = do { async fd (b_alloc 0 24 1)
+>                        ; send fd (b_setn 0 [(0, (replicate 24 210))])
+>                        ; play fd g } }
+>      in withSC3 run }
diff --git a/Help/UGen/Demand/demand.help.lhs b/Help/UGen/Demand/demand.help.lhs
--- a/Help/UGen/Demand/demand.help.lhs
+++ b/Help/UGen/Demand/demand.help.lhs
@@ -14,14 +14,16 @@
 
 reset - Resets the list of ugens when triggered.
 
-> r <- dust KR 1
-> s <- dgeom 64 (midiCPS 72) (midiRatio 1)
-> let t = impulse KR 10 0
->     f = demand t r s
-> audition (out 0 (max (cubed (sinOsc AR (MCE [f, f + 0.7]) 0)) 0 * 0.1))
+> do { r <- dust KR 1
+>    ; s <- dgeom dinf (midiCPS 72) (midiRatio 1)
+>    ; let { t = impulse KR 10 0
+>          ; f = demand t r s 
+>          ; o = sinOsc AR (mce [f, f + 0.7]) 0 }
+>      in audition (out 0 (max (cubed o) 0 * 0.1)) }
 
-> n <- diwhite 8192 60 72
-> let t = impulse KR 10 0
->     s = midiCPS n
->     f = demand t 0 s
-> audition (out 0 (cubed (cubed (sinOsc AR (MCE [f, f + 0.7]) 0)) * 0.1))
+> do { n <- diwhite dinf 60 72
+>    ; let { t = impulse KR 10 0
+>          ; s = midiCPS n
+>          ; f = demand t 0 s
+>          ; o = sinOsc AR (mce [f, f + 0.7]) 0 }
+>      in audition (out 0 (cubed (cubed o) * 0.1)) }
diff --git a/Help/UGen/Demand/demandEnvGen.help.lhs b/Help/UGen/Demand/demandEnvGen.help.lhs
--- a/Help/UGen/Demand/demandEnvGen.help.lhs
+++ b/Help/UGen/Demand/demandEnvGen.help.lhs
@@ -25,17 +25,15 @@
 
 Frequency ramp, exponential curve.
 
-> let inf_sc = 9e8
-> l <- dseq inf_sc (MCE [440, 9600])
-> let y = mouseY KR 0.01 3 Exponential 0.1
->     f = demandEnvGen AR l y 2 0 1 1 1 0 1 DoNothing
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> do { l <- dseq dinf (mce2 440 9600)
+>    ; let { y = mouseY KR 0.01 3 Exponential 0.1
+>          ; f = demandEnvGen AR l y 2 0 1 1 1 0 1 DoNothing }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
 
 Frequency envelope with random times.
 
-> let inf_sc = 9e8
-> l <- dseq inf_sc (MCE [204, 400, 201, 502, 300, 200])
-> t <- drand inf_sc (MCE [1.01, 0.2, 0.1, 2.0])
-> let y = mouseY KR 0.01 3 Exponential 0.1
->     f = demandEnvGen AR l (t * y) 7 0 1 1 1 0 1 DoNothing
-> audition (out 0 (sinOsc AR (f * MCE [1, 1.01]) 0 * 0.1))
+> do { l <- dseq dinf (mce [204, 400, 201, 502, 300, 200])
+>    ; t <- drand dinf (mce [1.01, 0.2, 0.1, 2.0])
+>    ; let { y = mouseY KR 0.01 3 Exponential 0.1
+>          ; f = demandEnvGen AR l (t * y) 7 0 1 1 1 0 1 DoNothing }
+>      in audition (out 0 (sinOsc AR (f * mce2 1 1.01) 0 * 0.1)) }
diff --git a/Help/UGen/Demand/dgeom.help.lhs b/Help/UGen/Demand/dgeom.help.lhs
--- a/Help/UGen/Demand/dgeom.help.lhs
+++ b/Help/UGen/Demand/dgeom.help.lhs
@@ -8,8 +8,8 @@
 
 The arguments can be a number or any other ugen
 
-> n <- dgeom 15 1 1.2
-> let x = mouseX KR 1 40 Exponential 0.1
->     t = impulse KR x 0
->     f = demand t 0 n * 30 + 340
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> do { n <- dgeom 15 1 1.2
+>    ; let { x = mouseX KR 1 40 Exponential 0.1
+>          ; t = impulse KR x 0
+>          ; f = demand t 0 n * 30 + 340 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Demand/drand.help.lhs b/Help/UGen/Demand/drand.help.lhs
--- a/Help/UGen/Demand/drand.help.lhs
+++ b/Help/UGen/Demand/drand.help.lhs
@@ -9,8 +9,8 @@
 Dxrand never plays the same value twice, whereas Drand chooses any
 value in the list.
 
-> n <- drand 32 (MCE [1,3,2,7,8])
-> let x = mouseX KR 1 400 Exponential 0.1
->     t = impulse KR x 0
->     f = demand t 0 n * 30 + 340
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> do { n <- drand dinf (mce [1, 3, 2, 7, 8])
+>    ; let { x = mouseX KR 1 400 Exponential 0.1
+>          ; t = impulse KR x 0
+>          ; f = demand t 0 n * 30 + 340 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Demand/dseq.help.lhs b/Help/UGen/Demand/dseq.help.lhs
--- a/Help/UGen/Demand/dseq.help.lhs
+++ b/Help/UGen/Demand/dseq.help.lhs
@@ -5,8 +5,16 @@
 array   - array of values or other ugens
 length  - number of repeats
 
-> n <- dseq 3 (MCE [1,3,2,7,8])
-> let x = mouseX KR 1 40 Exponential 0.1
->     t = impulse KR x 0
->     f = demand t 0 n * 30 + 340
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> do { n <- dseq 3 (mce [1, 3, 2, 7, 8])
+>    ; let { x = mouseX KR 1 40 Exponential 0.1
+>          ; t = impulse KR x 0
+>          ; f = demand t 0 n * 30 + 340 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
+
+At audio rate.
+
+> do { n <- dseq dinf (mce [1,3,2,7,8,32,16,18,12,24])
+>    ; let { x = mouseX KR 1 10000 Exponential 0.1
+>          ; t = impulse AR x 0
+>          ; f = demand t 0 n * 30 + 340 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Demand/dser.help.lhs b/Help/UGen/Demand/dser.help.lhs
--- a/Help/UGen/Demand/dser.help.lhs
+++ b/Help/UGen/Demand/dser.help.lhs
@@ -5,8 +5,8 @@
 array  - array of values or other ugens
 length - number of values to return
 
-> a <- dser 8192 (MCE [1, 3, 2, 7, 8])
-> let x = mouseX KR 1 40 Exponential 0.1
->     t = impulse KR x 0
->     f = demand t 0 a * 30 + 340
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> do { a <- dser 7 (mce [1, 3, 2, 7, 8])
+>    ; let { x = mouseX KR 1 40 Exponential 0.1
+>          ; t = impulse KR x 0
+>          ; f = demand t 0 a * 30 + 340 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Demand/dseries.help.lhs b/Help/UGen/Demand/dseries.help.lhs
--- a/Help/UGen/Demand/dseries.help.lhs
+++ b/Help/UGen/Demand/dseries.help.lhs
@@ -8,8 +8,8 @@
 
 The arguments can be a number or any other ugen
 
-> n <- dseries 15 0 1
-> let x = mouseX KR 1 40 Exponential 0.1
->     t = impulse KR x 0
->     f = demand t 0 n * 30 + 340
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> do { n <- dseries 15 0 1
+>    ; let { x = mouseX KR 1 40 Exponential 0.1
+>          ; t = impulse KR x 0
+>          ; f = demand t 0 n * 30 + 340 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Demand/dswitch1.help.lhs b/Help/UGen/Demand/dswitch1.help.lhs
--- a/Help/UGen/Demand/dswitch1.help.lhs
+++ b/Help/UGen/Demand/dswitch1.help.lhs
@@ -5,10 +5,10 @@
 index	- which of the inputs to return
 array	- array of values or other ugens
 
-> let x = mouseX KR 0 4 Linear 0.1
->     y = mouseY KR 1 15 Linear 0.1
-> w <- dwhite 2 0 3
-> n <- dswitch1 x (MCE [1, 3, y, 2, w])
-> let t = impulse KR 3 0
->     f = demand t 0 n * 30 + 340
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> let { x = mouseX KR 0 4 Linear 0.1
+>     ; y = mouseY KR 1 15 Linear 0.1
+>     ; t = impulse KR 3 0 }
+> in do { w <- dwhite dinf 20 23
+>       ; n <- dswitch1 x (mce [1, 3, y, 2, w])
+>       ; let f = demand t 0 n * 30 + 340
+>         in audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Demand/duty.help.lhs b/Help/UGen/Demand/duty.help.lhs
--- a/Help/UGen/Demand/duty.help.lhs
+++ b/Help/UGen/Demand/duty.help.lhs
@@ -20,14 +20,14 @@
 
 level - demand ugen providing the output values.
 
-> n0 <- drand 8192 (MCE [0.01, 0.2, 0.4])
-> n1 <- dseq 8192 (MCE [204, 400, 201, 502, 300, 200])
-> let f = duty KR n0 0 RemoveSynth n1
-> audition (out 0 (sinOsc AR (f * MCE [1, 1.01]) 0 * 0.1))
+> do { n0 <- drand dinf (mce [0.01, 0.2, 0.4])
+>    ; n1 <- dseq dinf (mce [204, 400, 201, 502, 300, 200])
+>    ; let f = duty KR n0 0 RemoveSynth n1
+>      in audition (out 0 (sinOsc AR (f * mce2 1 1.01) 0 * 0.1)) }
 
 Using control rate signal, mouseX, to determine duration.
 
-> let x = mouseX KR 0.001 2 Linear 0.1
-> n <- dseq 8192 (MCE [204, 400, 201, 502, 300, 200])
-> let f = duty KR x 0 RemoveSynth n
-> audition (out 0 (sinOsc AR (f * MCE [1, 1.01]) 0 * 0.1))
+> do { n <- dseq dinf (mce [204, 400, 201, 502, 300, 200])
+>    ; let { x = mouseX KR 0.001 2 Linear 0.1
+>          ; f = duty KR x 0 RemoveSynth n }
+>      in audition (out 0 (sinOsc AR (f * mce2 1 1.01) 0 * 0.1)) }
diff --git a/Help/UGen/Demand/dwhite.help.lhs b/Help/UGen/Demand/dwhite.help.lhs
--- a/Help/UGen/Demand/dwhite.help.lhs
+++ b/Help/UGen/Demand/dwhite.help.lhs
@@ -11,8 +11,8 @@
 Diwhite returns integer values.  The arguments can be a number or
 any other ugen
 
-> n <- dwhite 32 0 15
-> let x = mouseX KR 1 40 Exponential 0.1
->     t = impulse KR x 0
->     f = demand t 0 n * 30 + 340
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> do { n <- dwhite dinf 0 15
+>    ; let { x = mouseX KR 1 40 Exponential 0.1
+>          ; t = impulse KR x 0
+>          ; f = demand t 0 n * 30 + 340 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
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
@@ -25,27 +25,24 @@
 
 Play a little rhythm
 
-> let inf = 1E+9
-> d <- dseq inf (MCE [0.1, 0.2, 0.4, 0.3])
-> audition (out 0 (tDuty AR d 0 DoNothing 1))
+> do { d <- dseq dinf (mce [0.1, 0.2, 0.4, 0.3])
+>    ; audition (out 0 (tDuty AR d 0 DoNothing 1)) }
 
 Amplitude changes
 
-> let inf = 1E+9
-> d0 <- dseq inf (MCE [0.1, 0.2, 0.4, 0.3])
-> d1 <- dseq inf (MCE [0.1, 0.4, 0.01, 0.5, 1.0])
-> audition (out 0 (ringz (tDuty AR d0 0 DoNothing d1) 1000 0.1))
+> 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)) }
 
 Mouse control.
 
-> let inf = 1E+9
-> d <- dseq inf (MCE [0.1, 0.4, 0.01, 0.5, 1.0])
-> let x = mouseX KR 0.001 1 Linear 0.1
-> audition (out 0 (ringz (tDuty AR x 0 DoNothing d) 1000 0.1))
+> 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)) }
 
 Note that the 440 is the long pitch.
 
-> d0 <- dser 12 (MCE [0.1, 0.3])
-> d1 <- dser 12 (MCE [440, 880])
-> let t = tDuty AR d0 0 RemoveSynth d1
-> audition (out 0 (sinOsc AR (latch t t) 0 * 0.1))
+> do { d0 <- dser 12 (mce [0.1, 0.3])
+>    ; d1 <- dser 12 (mce [440, 880])
+>    ; let t = tDuty AR d0 0 RemoveSynth d1
+>      in audition (out 0 (sinOsc AR (latch t t) 0 * 0.1)) }
diff --git a/Help/UGen/Envelope/detectSilence.help.lhs b/Help/UGen/Envelope/detectSilence.help.lhs
--- a/Help/UGen/Envelope/detectSilence.help.lhs
+++ b/Help/UGen/Envelope/detectSilence.help.lhs
@@ -3,5 +3,6 @@
 If the signal at `in' falls below `amp' for `time' seconds then
 `doneAction' is raised.
 
-> let s = sinOsc AR 440 0 * mouseY KR 0 0.4 Linear 0.1
-> audition (MRG [detectSilence s 0.1 0.2 RemoveSynth, out 0 s])
+> let { s = sinOsc AR 440 0 * mouseY KR 0 0.4 Linear 0.1
+>     ; d = detectSilence s 0.1 0.2 RemoveSynth }
+> in audition (mrg [out 0 s, d])
diff --git a/Help/UGen/Envelope/done.help.lhs b/Help/UGen/Envelope/done.help.lhs
--- a/Help/UGen/Envelope/done.help.lhs
+++ b/Help/UGen/Envelope/done.help.lhs
@@ -3,7 +3,8 @@
 Outputs a unit signal if the 'done' flag of the unit at `src' is
 set, else output zero.
 
-> let x   = mouseX KR (-1) 1 Linear 0.1
->     env = linen x 0.1 0.1 0.5 DoNothing
-> audition (out 0 (MCE [ done env * sinOsc AR 880 0 * 0.1
->                       , sinOsc AR 440 0 * env]))
+> let { x = mouseX KR (-1) 1 Linear 0.1
+>     ; e = linen x 0.1 0.1 0.5 DoNothing 
+>     ; o1 = sinOsc AR 880 0 * 0.1
+>     ; o2 = sinOsc AR 440 0 * e }
+> in audition (out 0 (mce [ done e * o1, o2 ]))
diff --git a/Help/UGen/Envelope/envGen.help.lhs b/Help/UGen/Envelope/envGen.help.lhs
--- a/Help/UGen/Envelope/envGen.help.lhs
+++ b/Help/UGen/Envelope/envGen.help.lhs
@@ -30,24 +30,24 @@
 
 Percussive envelope
 
-> let p = envPerc 0.01 1 1 [EnvNum (-4), EnvNum (-4)]
->     e = envGen KR 1 0.1 0 1 RemoveSynth p
-> audition (out 0 (sinOsc AR 440 0 * e))
+> let { p = envPerc 0.01 1
+>     ; e = envGen KR 1 0.1 0 1 RemoveSynth p }
+> in audition (out 0 (sinOsc AR 440 0 * e))
 
 Sine envelope
 
-> let s = envSine 9 0.1
->     e = envGen KR 1 1 0 1 RemoveSynth s
-> audition (out 0 (sinOsc AR 440 0 * e))
+> let { s = envSine 9 0.1
+>     ; e = envGen KR 1 1 0 1 RemoveSynth s }
+> in audition (out 0 (sinOsc AR 440 0 * e))
 
 Co-ordinate (break-point) envelope
 
-> let c = envCoord [(0,0), (0.5, 0.1), (0.55, 1), (1, 0)] 9 0.1 EnvLin
->     e = envGen KR 1 1 0 1 RemoveSynth c
-> audition (out 0 (sinOsc AR 440 0 * e))
+> let { c = envCoord [(0,0), (0.5, 0.1), (0.55, 1), (1, 0)] 9 0.1 EnvLin
+>     ; e = envGen KR 1 1 0 1 RemoveSynth c }
+> in audition (out 0 (sinOsc AR 440 0 * e))
 
 Trapezoidal envelope
 
-> let t = envTrapezoid 0.05 0.95 3 0.1
->     e = envGen KR 1 1 0 1 RemoveSynth t
-> audition (out 0 (sinOsc AR 440 0 * e))
+> let { t = envTrapezoid 0.05 0.95 3 0.1
+>     ; e = envGen KR 1 1 0 1 RemoveSynth t }
+> in audition (out 0 (sinOsc AR 440 0 * e))
diff --git a/Help/UGen/Envelope/free.help.lhs b/Help/UGen/Envelope/free.help.lhs
--- a/Help/UGen/Envelope/free.help.lhs
+++ b/Help/UGen/Envelope/free.help.lhs
@@ -5,13 +5,11 @@
 trig   - when triggered, frees node
 nodeID - node to be freed
 
-> withSC3 (\fd -> do let a = out 0 (sinOsc AR 880 0 * 0.1)
->                    send fd (d_recv (graphdef "a" (graph a)))
->                    wait fd "/done"
->                    n0 <- pinkNoise AR
->                    n1 <- dust AR 2
->                    let b = MRG [out 1 (n0 * 0.1), free n1 1001]
->                    send fd (d_recv (graphdef "b" (graph b)))
->                    wait fd "/done"
->                    send fd (s_new "a" 1001 AddToTail 0 [])
->                    send fd (s_new "b" (-1) AddToTail 0 []))
+> let { a = out 0 (sinOsc AR 880 0 * 0.1) 
+>     ; b = do { n0 <- pinkNoise AR
+>              ; n1 <- dust AR 2
+>              ; return (mrg [out 1 (n0 * 0.1), free n1 1001]) } }
+> in withSC3 (\fd -> do { async fd . d_recv . graphdef "a" . graph $ a
+>                       ; async fd . d_recv . graphdef "b" . graph =<< b
+>                       ; send fd (s_new "a" 1001 AddToTail 0 [])
+>                       ; send fd (s_new "b" (-1) AddToTail 0 []) } )
diff --git a/Help/UGen/Envelope/freeSelf.help.lhs b/Help/UGen/Envelope/freeSelf.help.lhs
--- a/Help/UGen/Envelope/freeSelf.help.lhs
+++ b/Help/UGen/Envelope/freeSelf.help.lhs
@@ -3,6 +3,7 @@
 Free enclosing synth when the input signal crosses from non-positive
 to positive.
 
-> let a = freeSelf (mouseX KR (-1) 1 Linear 0.1)
-> let b = out 0 (sinOsc AR 440 0 * 0.1)
-> audition (MRG [a, b])
+> do { n <- dust KR 0.5
+>    ; let { a = freeSelf n
+>          ; b = out 0 (sinOsc AR 440 0 * 0.1) }
+>      in audition (mrg [a, b]) }
diff --git a/Help/UGen/Envelope/freeSelfWhenDone.help.lhs b/Help/UGen/Envelope/freeSelfWhenDone.help.lhs
--- a/Help/UGen/Envelope/freeSelfWhenDone.help.lhs
+++ b/Help/UGen/Envelope/freeSelfWhenDone.help.lhs
@@ -2,10 +2,10 @@
 
 Free the synth when the 'done' flag of the unit at `src' is set.
 
-> let x = mouseX KR (-1) 1 Linear 0.1
->     e = linen x 1 0.1 1 RemoveSynth
-> audition (out 0 (sinOsc AR 440 0 * e))
+> let { x = mouseX KR (-1) 1 Linear 0.1
+>     ; e = linen x 1 0.1 1 RemoveSynth }
+> in audition (out 0 (sinOsc AR 440 0 * e))
 
-> let x = mouseX KR (-1) 1 Linear 0.1
->     e = linen x 1 0.1 1 DoNothing
-> audition (MRG [freeSelfWhenDone e, out 0 (sinOsc AR 440 0 * e)])
+> let { x = mouseX KR (-1) 1 Linear 0.1
+>     ; e = linen x 1 0.1 1 DoNothing }
+> in audition (mrg [freeSelfWhenDone e, out 0 (sinOsc AR 440 0 * e)])
diff --git a/Help/UGen/Envelope/line.help.lhs b/Help/UGen/Envelope/line.help.lhs
--- a/Help/UGen/Envelope/line.help.lhs
+++ b/Help/UGen/Envelope/line.help.lhs
@@ -9,4 +9,5 @@
 Note: The SC3 UGen reorders the mul and add inputs to precede the
 doneAction input.
 
-> audition (out 0 (sinOsc AR (line KR 200 17000 5 RemoveSynth) 0 * 0.1))
+> let f = line KR 200 17000 5 RemoveSynth
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Envelope/linen.help.lhs b/Help/UGen/Envelope/linen.help.lhs
--- a/Help/UGen/Envelope/linen.help.lhs
+++ b/Help/UGen/Envelope/linen.help.lhs
@@ -7,9 +7,9 @@
 when the gate is opened.
 
 > let e = linen (impulse KR 2 0) 0.01 0.6 0.4 DoNothing
-> audition (out 0 (e * sinOsc AR 440 0 * 0.1))
+> in audition (out 0 (e * sinOsc AR 440 0 * 0.1))
 
-> let x = mouseX KR (-1) 1 Linear 0.1
->     y = mouseY KR 0.1 0.5 Linear 0.1
->     e = linen x 1 x 1.0 DoNothing
-> audition (out 0 (sinOsc AR 440 0 * e))
+> let { x = mouseX KR (-1) 1 Linear 0.1
+>     ; y = mouseY KR 0.1 0.5 Linear 0.1
+>     ; e = linen x 1 y 1.0 DoNothing }
+> in audition (out 0 (sinOsc AR 440 0 * e))
diff --git a/Help/UGen/Envelope/pause.help.lhs b/Help/UGen/Envelope/pause.help.lhs
--- a/Help/UGen/Envelope/pause.help.lhs
+++ b/Help/UGen/Envelope/pause.help.lhs
@@ -5,14 +5,13 @@
 gate   - when gate is 0,  node is paused, when 1 it runs
 nodeID - node to be paused
 
-> let f  = Control KR "f" 440
->     g  = Control KR "g" 1
->     a  = MRG [out 0 (sinOsc AR f 0 * 0.1), pause g 1001]
->     a' = graphdef "a" (graph a)
-> withSC3 (\fd -> do send fd (d_recv a')
->                    wait fd "/done"
->                    send fd (s_new "a" 1001 AddToTail 0 [])
->                    send fd (s_new "a" 1002 AddToTail 0 [("f", 880)]))
+> let { f  = control KR "f" 440
+>     ; g  = control KR "g" 1
+>     ; a  = mrg [out 0 (sinOsc AR f 0 * 0.1), pause g 1001]
+>     ; a' = graphdef "a" (graph a) }
+> in withSC3 (\fd -> do { async fd (d_recv a')
+>                       ; send fd (s_new "a" 1001 AddToTail 0 [])
+>                       ; send fd (s_new "a" 1002 AddToTail 0 [("f", 880)]) } )
 
 Request that node 1002 pause node 1001.
 
diff --git a/Help/UGen/Envelope/pauseSelf.help.lhs b/Help/UGen/Envelope/pauseSelf.help.lhs
--- a/Help/UGen/Envelope/pauseSelf.help.lhs
+++ b/Help/UGen/Envelope/pauseSelf.help.lhs
@@ -3,8 +3,9 @@
 Pause enclosing synth when input signal crosses from non-positive to
 positive.
 
-> let x = mouseX KR (-1) 1 Linear 0.1
-> audition (MRG [pauseSelf x, out 0 (sinOsc AR 440 0 * 0.1)])
+> let { x = mouseX KR (-1) 1 Linear 0.1
+>     ; o = sinOsc AR 440 0 * 0.1 }
+> in audition (mrg [pauseSelf x, out 0 o])
 
 Run paused node (assuming no intermediate node is created).
 
diff --git a/Help/UGen/Envelope/pauseSelfWhenDone.help.lhs b/Help/UGen/Envelope/pauseSelfWhenDone.help.lhs
--- a/Help/UGen/Envelope/pauseSelfWhenDone.help.lhs
+++ b/Help/UGen/Envelope/pauseSelfWhenDone.help.lhs
@@ -2,10 +2,11 @@
 
 Pauses the synth when the 'done' flag of the unit at `src' is set.
 
-> let x = mouseX KR (-1) 1 Linear 0.1
->     e = linen x 1 0.1 1 PauseSynth
-> audition (out 0 (sinOsc AR 440 0 * e))
+> let { x = mouseX KR (-1) 1 Linear 0.1
+>     ; e = linen x 1 0.1 1 PauseSynth }
+> in audition (out 0 (sinOsc AR 440 0 * e))
 
-> let x = mouseX KR (-1) 1 Linear 0.1
->     e = linen x 1 0.1 1 DoNothing
-> audition (MRG [pauseSelfWhenDone e, out 0 (sinOsc AR 440 0 * e)])
+> let { x = mouseX KR (-1) 1 Linear 0.1
+>     ; e = linen x 1 0.1 1 DoNothing 
+>     ; o = sinOsc AR 440 0 * e }
+> in audition (mrg [pauseSelfWhenDone e, out 0 o])
diff --git a/Help/UGen/Envelope/xLine.help.lhs b/Help/UGen/Envelope/xLine.help.lhs
--- a/Help/UGen/Envelope/xLine.help.lhs
+++ b/Help/UGen/Envelope/xLine.help.lhs
@@ -13,4 +13,6 @@
 Note: The sclang interface reorders the mul and add inputs to precede
 the doneAction input.
 
-> audition (out 0 (sinOsc AR (xLine KR 200 17000 10 RemoveSynth) 0 * 0.1))
+> let { f = xLine KR 200 17000 10 RemoveSynth
+>     ; o = sinOsc AR f 0 * 0.1 }
+> in audition (out 0 o)
diff --git a/Help/UGen/FFT/convolution.help.lhs b/Help/UGen/FFT/convolution.help.lhs
--- a/Help/UGen/FFT/convolution.help.lhs
+++ b/Help/UGen/FFT/convolution.help.lhs
@@ -8,6 +8,6 @@
 kernel    - processing kernel.
 framesize - size of FFT frame, must be a power of two
 
-> let i = in' 2 AR numOutputBuses
-> k <- whiteNoise AR
-> audition (out 0 (convolution i k 2048 * 0.1))
+> do { k <- whiteNoise AR
+>    ; let i = in' 2 AR numOutputBuses
+>      in audition (out 0 (convolution i k 2048 * 0.1)) }
diff --git a/Help/UGen/FFT/fft.help.lhs b/Help/UGen/FFT/fft.help.lhs
--- a/Help/UGen/FFT/fft.help.lhs
+++ b/Help/UGen/FFT/fft.help.lhs
@@ -1,4 +1,5 @@
-fft buffer in
+fft buffer in hopSize windowType active
+fft' buffer in
 
 Fast fourier transform.  The fast fourier transform analyzes the
 frequency content of a signal.  fft uses a local buffer for holding
@@ -8,14 +9,15 @@
 The fft and pv_* UGens run at control rate, the ifft UGen at audio
 rate.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> n <- whiteNoise AR
-> audition (out 0 (ifft' (fft' 10 (n * 0.05))))
+fft' is a variant FFT constructor with default values for hop size,
+window type, and active status
 
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> let s0 = sinOsc KR 0.08 0 * 6 + 6.2
->     s1 = sinOsc KR (squared s0) 0 * 100 + 800
->     s2 = sinOsc AR s1 0
-> audition (out 0 (ifft' (fft' 10 s2) * 0.25))
+> withSC3 (\fd -> async fd (b_alloc 10 2048 1))
+
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (ifft' (fft' 10 (n * 0.05)))) }
+
+> let { s0 = sinOsc KR 0.08 0 * 6 + 6.2
+>     ; s1 = sinOsc KR (squared s0) 0 * 100 + 800
+>     ; s2 = sinOsc AR s1 0 }
+> in audition (out 0 (ifft' (fft' 10 s2) * 0.25))
diff --git a/Help/UGen/FFT/ifft.help.lhs b/Help/UGen/FFT/ifft.help.lhs
--- a/Help/UGen/FFT/ifft.help.lhs
+++ b/Help/UGen/FFT/ifft.help.lhs
@@ -1,6 +1,9 @@
-ifft buffer
+ifft buffer windowType
+ifft' buffer
 
 Inverse Fast Fourier Transform.  The inverse fast fourier transform
 converts from frequency content to a signal.
+
+ifft' is a variant with the default window type.
 
 See fft.
diff --git a/Help/UGen/FFT/packFFT.help.lhs b/Help/UGen/FFT/packFFT.help.lhs
--- a/Help/UGen/FFT/packFFT.help.lhs
+++ b/Help/UGen/FFT/packFFT.help.lhs
@@ -32,6 +32,7 @@
 UnpackFFT first - essentially creating our FFT data from scratch.
 
 > withSC3 (\fd -> send fd (b_alloc 10 512 1))
+
 > let n = 100
 >     range :: UGen -> UGen -> UGen -> UGen
 >     range u l r = linLin u (-1) 1 l r
@@ -47,7 +48,7 @@
 > let m3 = zipWith (*) m2 i
 >     p = replicate n 0.0
 >     c1 = fft' 10 (fSinOsc AR 440 0)
->     mkC = Constant . fromIntegral
->     c2 = packFFT c1 512 0 (mkC n - 1) 1 (packFFTSpec m3 p)
+>     ci = constant . fromIntegral
+>     c2 = packFFT c1 512 0 (ci n - 1) 1 (packFFTSpec m3 p)
 >     s = ifft' c2
-> audition (out 0 (MCE [s, s]))
+> audition (out 0 (mce [s, s]))
diff --git a/Help/UGen/FFT/pv_BinScramble.help.lhs b/Help/UGen/FFT/pv_BinScramble.help.lhs
--- a/Help/UGen/FFT/pv_BinScramble.help.lhs
+++ b/Help/UGen/FFT/pv_BinScramble.help.lhs
@@ -10,13 +10,12 @@
 trig   - a trigger selects a new random ordering.
 
 > let fileName = "/home/rohan/audio/metal.wav"
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done"
->                    send fd (b_allocRead 12 fileName 0 0)
->                    wait fd "/done")
-> let a = playBuf 1 12 (bufRateScale KR 12) 1 0 Loop
->     f = fft' 10 a
->     x = mouseX KR 0.0 1.0 Linear 0.1
->     y = mouseY KR 0.0 1.0 Linear 0.1
-> g <- pv_BinScramble f x y (impulse KR 4 0)
-> audition (out 0 (pan2 (ifft' g) 0 0.5))
+> in withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                       ; async fd (b_allocRead 12 fileName 0 0) })
+
+> let { a = playBuf 1 12 (bufRateScale KR 12) 1 0 Loop
+>     ; f = fft' 10 a
+>     ; x = mouseX KR 0.0 1.0 Linear 0.1
+>     ; y = mouseY KR 0.0 1.0 Linear 0.1 }
+> in do { g <- pv_BinScramble f x y (impulse KR 4 0)
+>       ; audition (out 0 (pan2 (ifft' g) 0 0.5)) }
diff --git a/Help/UGen/FFT/pv_BinShift.help.lhs b/Help/UGen/FFT/pv_BinShift.help.lhs
--- a/Help/UGen/FFT/pv_BinShift.help.lhs
+++ b/Help/UGen/FFT/pv_BinShift.help.lhs
@@ -4,12 +4,12 @@
 crude frequency shifter/scaler.  Shifts the leftmost bin at `buffer'
 by `shift' places, the distance between subsequent bins is `stretch'.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> let x  = mouseX KR (-10) 100 Linear 0.1
->     y  = mouseY KR 1 4 Linear 0.1
->     s0 = sinOsc KR 0.08 0 * 6 + 6.2
->     s1 = sinOsc KR (squared s0) 0 * 100 + 800
->     s2 = sinOsc AR s1 0
->     pv = pv_BinShift (fft' 10 s2) y x
-> audition (out 0 (pan2 (ifft' pv) 0 0.1))
+> withSC3 (\fd -> async fd (b_alloc 10 2048 1))
+
+> let { x  = mouseX KR (-10) 100 Linear 0.1
+>     ; y  = mouseY KR 1 4 Linear 0.1
+>     ; s0 = sinOsc KR 0.08 0 * 6 + 6.2
+>     ; s1 = sinOsc KR (squared s0) 0 * 100 + 800
+>     ; s2 = sinOsc AR s1 0
+>     ; pv = pv_BinShift (fft' 10 s2) y x }
+> in audition (out 0 (pan2 (ifft' pv) 0 0.1))
diff --git a/Help/UGen/FFT/pv_BinWipe.help.lhs b/Help/UGen/FFT/pv_BinWipe.help.lhs
--- a/Help/UGen/FFT/pv_BinWipe.help.lhs
+++ b/Help/UGen/FFT/pv_BinWipe.help.lhs
@@ -12,16 +12,14 @@
 if  wipe < 0 then it begins replacing with bins from inB from the top down.
 
 > let fileName = "/home/rohan/audio/metal.wav"
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done"
->                    send fd (b_alloc 11 2048 1)
->                    wait fd "/done"
->                    send fd (b_allocRead 12 fileName 0 0)
->                    wait fd "/done")
-> n <- whiteNoise AR
-> let b = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
->     f = fft' 10 (n * 0.2)
->     g = fft' 11 b
->     x = mouseX KR 0.0 1.0 Linear 0.1
->     h = pv_BinWipe f g x
-> audition (out 0 (pan2 (ifft' h) 0 0.5))
+> in withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                       ; async fd (b_alloc 11 2048 1)
+>                       ; async fd (b_allocRead 12 fileName 0 0) })
+
+> do { n <- whiteNoise AR
+>    ; let { b = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
+>          ; f = fft' 10 (n * 0.2)
+>          ; g = fft' 11 b
+>          ; x = mouseX KR 0.0 1.0 Linear 0.1
+>          ; h = pv_BinWipe f g x }
+>      in audition (out 0 (pan2 (ifft' h) 0 0.5)) }
diff --git a/Help/UGen/FFT/pv_BrickWall.help.lhs b/Help/UGen/FFT/pv_BrickWall.help.lhs
--- a/Help/UGen/FFT/pv_BrickWall.help.lhs
+++ b/Help/UGen/FFT/pv_BrickWall.help.lhs
@@ -4,8 +4,8 @@
 from -1 to 0 the UGen acts as a low-pass filter, from 0 to 1 it acts
 as a high pass filter.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> n <- whiteNoise AR
-> let x = mouseX KR (-1) 1 Linear 0.1
-> audition (out 0 (ifft' (pv_BrickWall (fft' 10 (n * 0.2)) x)))
+> withSC3 (\fd -> async fd (b_alloc 10 2048 1))
+
+> do { n <- whiteNoise AR
+>    ; let x = mouseX KR (-1) 1 Linear 0.1
+>      in audition (out 0 (ifft' (pv_BrickWall (fft' 10 (n * 0.2)) x))) }
diff --git a/Help/UGen/FFT/pv_ConformalMap.help.lhs b/Help/UGen/FFT/pv_ConformalMap.help.lhs
--- a/Help/UGen/FFT/pv_ConformalMap.help.lhs
+++ b/Help/UGen/FFT/pv_ConformalMap.help.lhs
@@ -9,22 +9,22 @@
 real   - real part of a.
 imag   - imaginary part of a.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 1024 1)
->                    wait fd "/done")
-> let i = in' 1 AR numOutputBuses * 0.5
->     x = mouseX KR (-1) 1 Linear 0.1
->     y = mouseY KR (-1) 1 Linear 0.1
-> audition (out 0 (pan2 (ifft' (pv_ConformalMap (fft' 10 i) x y)) 0 1))
+> withSC3 (\fd -> async fd (b_alloc 10 1024 1))
 
+> let { i = in' 1 AR numOutputBuses * 0.5
+>     ; x = mouseX KR (-1) 1 Linear 0.1
+>     ; y = mouseY KR (-1) 1 Linear 0.1 }
+> in audition (out 0 (pan2 (ifft' (pv_ConformalMap (fft' 10 i) x y)) 0 1))
+
 With filtering.
 
-> withSC3 (\fd -> do send fd (b_alloc 0 2048 1)
->                    wait fd "/done")
-> let o = MCE [1, 1.1, 1.5, 1.78, 2.45, 6.7, 8] * 220
->     f = sinOsc KR (MCE [0.16, 0.33, 0.41]) 0 * 10 + o
->     s = mix (lfSaw AR f 0) * 0.3
->     x = mouseX KR 0.01  2.0 Linear 0.1
->     y = mouseY KR 0.01 10.0 Linear 0.1
->     c = fft' 0 s
->     m = ifft' (pv_ConformalMap c x y)
-> audition (out 0 (pan2 (combN m 0.1 0.1 10 * 0.5 + m) 0 1))
+> withSC3 (\fd -> async fd (b_alloc 0 2048 1))
+
+> let { o = mce [1, 1.1, 1.5, 1.78, 2.45, 6.7, 8] * 220
+>     ; f = sinOsc KR (mce [0.16, 0.33, 0.41]) 0 * 10 + o
+>     ; s = mix (lfSaw AR f 0) * 0.3
+>     ; x = mouseX KR 0.01  2.0 Linear 0.1
+>     ; y = mouseY KR 0.01 10.0 Linear 0.1
+>     ; c = fft' 0 s
+>     ; m = ifft' (pv_ConformalMap c x y) }
+> in audition (out 0 (pan2 (combN m 0.1 0.1 10 * 0.5 + m) 0 1))
diff --git a/Help/UGen/FFT/pv_Copy.help.lhs b/Help/UGen/FFT/pv_Copy.help.lhs
--- a/Help/UGen/FFT/pv_Copy.help.lhs
+++ b/Help/UGen/FFT/pv_Copy.help.lhs
@@ -11,11 +11,10 @@
 
 Proof of concept, silence
 
-> withSC3 (\fd -> do send fd (b_alloc 0 2048 1)
->                    wait fd "/done"
->                    send fd (b_alloc 1 2048 1)
->                    wait fd "/done")
-> i <- lfClipNoise AR 100
-> let c0 = fft' 0 i
->     c1 = pv_Copy c0 1
-> audition (out 0 (ifft' c0 - ifft' c1))
+> withSC3 (\fd -> do { async fd (b_alloc 0 2048 1)
+>                    ; async fd (b_alloc 1 2048 1) })
+
+> do { i <- lfClipNoise AR 100
+>    ; let { c0 = fft' 0 i
+>          ; c1 = pv_Copy c0 1 }
+>      in audition (out 0 (ifft' c0 - ifft' c1)) }
diff --git a/Help/UGen/FFT/pv_Diffuser.help.lhs b/Help/UGen/FFT/pv_Diffuser.help.lhs
--- a/Help/UGen/FFT/pv_Diffuser.help.lhs
+++ b/Help/UGen/FFT/pv_Diffuser.help.lhs
@@ -7,12 +7,11 @@
 trig   - a trigger selects a new set of random values.
 
 > let fileName = "/home/rohan/audio/metal.wav"
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done"
->                    send fd (b_allocRead 12 fileName 0 0)
->                    wait fd "/done")
-> let a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
->     f = fft' 10 a
->     x = mouseX KR 0 1 Linear 0.1
->     h = pv_Diffuser f (x >* 0.5)
-> audition (out 0 (ifft' h * 0.5))
+> in withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                       ; async fd (b_allocRead 12 fileName 0 0) })
+
+> let { a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
+>     ; f = fft' 10 a
+>     ; x = mouseX KR 0 1 Linear 0.1
+>     ; h = pv_Diffuser f (x >* 0.5) }
+> in audition (out 0 (ifft' h * 0.5))
diff --git a/Help/UGen/FFT/pv_LocalMax.help.lhs b/Help/UGen/FFT/pv_LocalMax.help.lhs
--- a/Help/UGen/FFT/pv_LocalMax.help.lhs
+++ b/Help/UGen/FFT/pv_LocalMax.help.lhs
@@ -7,12 +7,11 @@
 threshold - magnitude threshold.
 
 > let fileName = "/home/rohan/audio/metal.wav"
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done"
->                    send fd (b_allocRead 12 fileName 0 0)
->                    wait fd "/done")
-> let a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
->     f = fft' 10 a
->     x = mouseX KR 0 100 Linear 0.1
->     h = pv_LocalMax f x
-> audition (out 0 (ifft' h * 0.5))
+> in withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                       ; async fd (b_allocRead 12 fileName 0 0) })
+
+> let { a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
+>     ; f = fft' 10 a
+>     ; x = mouseX KR 0 100 Linear 0.1
+>     ; h = pv_LocalMax f x }
+> in audition (out 0 (ifft' h * 0.5))
diff --git a/Help/UGen/FFT/pv_MagAbove.help.lhs b/Help/UGen/FFT/pv_MagAbove.help.lhs
--- a/Help/UGen/FFT/pv_MagAbove.help.lhs
+++ b/Help/UGen/FFT/pv_MagAbove.help.lhs
@@ -5,23 +5,20 @@
 dependant on the buffer size.
 
 > let fileName = "/home/rohan/audio/metal.wav"
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done"
->                    send fd (b_allocRead 12 fileName 0 0)
->                    wait fd "/done")
-> let a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
->     f = fft' 10 a
->     x = mouseX KR 0 100 Linear 0.1
->     h = pv_MagAbove f x
-> audition (out 0 (ifft' h * 0.5))
+> in withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                       ; async fd (b_allocRead 12 fileName 0 0) })
 
+> let { a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
+>     ; f = fft' 10 a
+>     ; x = mouseX KR 0 100 Linear 0.1
+>     ; h = pv_MagAbove f x }
+> in audition (out 0 (ifft' h * 0.5))
+
 Synthesised input.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> let a = sinOsc KR (squared (sinOsc KR 0.08 0 * 6 + 6.2)) 0 * 100 + 800
->     b = sinOsc AR a 0
->     f = fft' 10 b
->     x = mouseX KR 0 1024 Linear 0.1
->     h = pv_MagAbove f x
-> audition (out 0 (ifft' h * 0.5))
+> let { a = sinOsc KR (squared (sinOsc KR 0.08 0 * 6 + 6.2)) 0 * 100 + 800
+>     ; b = sinOsc AR a 0
+>     ; f = fft' 10 b
+>     ; x = mouseX KR 0 1024 Linear 0.1
+>     ; h = pv_MagAbove f x }
+> in audition (out 0 (ifft' h * 0.5))
diff --git a/Help/UGen/FFT/pv_MagBelow.help.lhs b/Help/UGen/FFT/pv_MagBelow.help.lhs
--- a/Help/UGen/FFT/pv_MagBelow.help.lhs
+++ b/Help/UGen/FFT/pv_MagBelow.help.lhs
@@ -5,23 +5,20 @@
 dependant on the buffer size.
 
 > let fileName = "/home/rohan/audio/metal.wav"
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done"
->                    send fd (b_allocRead 12 fileName 0 0)
->                    wait fd "/done")
-> let a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
->     f = fft' 10 a
->     x = mouseX KR 0 100 Linear 0.1
->     h = pv_MagBelow f x
-> audition (out 0 (ifft' h * 0.5))
+> in withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                       ; async fd (b_allocRead 12 fileName 0 0) })
 
+> let { a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
+>     ; f = fft' 10 a
+>     ; x = mouseX KR 0 100 Linear 0.1
+>     ; h = pv_MagBelow f x }
+> in audition (out 0 (ifft' h * 0.5))
+
 Synthesised input.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> let a = sinOsc KR (squared (sinOsc KR 0.08 0 * 6 + 6.2)) 0 * 100 + 800
->     b = sinOsc AR a 0
->     f = fft' 10 b
->     x = mouseX KR 0 1024 Linear 0.1
->     h = pv_MagBelow f x
-> audition (out 0 (ifft' h * 0.5))
+> let { a = sinOsc KR (squared (sinOsc KR 0.08 0 * 6 + 6.2)) 0 * 100 + 800
+>     ; b = sinOsc AR a 0
+>     ; f = fft' 10 b
+>     ; x = mouseX KR 0 1024 Linear 0.1
+>     ; h = pv_MagBelow f x }
+> in audition (out 0 (ifft' h * 0.5))
diff --git a/Help/UGen/FFT/pv_MagClip.help.lhs b/Help/UGen/FFT/pv_MagClip.help.lhs
--- a/Help/UGen/FFT/pv_MagClip.help.lhs
+++ b/Help/UGen/FFT/pv_MagClip.help.lhs
@@ -4,23 +4,20 @@
 threshold.
 
 > let fileName = "/home/rohan/audio/metal.wav"
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done"
->                    send fd (b_allocRead 12 fileName 0 0)
->                    wait fd "/done")
-> let a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
->     f = fft' 10 a
->     x = mouseX KR 0 5 Linear 0.1
->     h = pv_MagBelow f x
-> audition (out 0 (ifft' h * 0.5))
+> in withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                       ; async fd (b_allocRead 12 fileName 0 0) })
 
+> let { a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
+>     ; f = fft' 10 a
+>     ; x = mouseX KR 0 5 Linear 0.1
+>     ; h = pv_MagBelow f x }
+> in audition (out 0 (ifft' h * 0.5))
+
 Synthesised input.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> let a = sinOsc KR (squared (sinOsc KR 0.08 0 * 6 + 6.2)) 0 * 100 + 800
->     b = sinOsc AR a 0
->     f = fft' 10 b
->     x = mouseX KR 0 128 Linear 0.1
->     h = pv_MagClip f x
-> audition (out 0 (ifft' h * 0.5))
+> let { a = sinOsc KR (squared (sinOsc KR 0.08 0 * 6 + 6.2)) 0 * 100 + 800
+>     ; b = sinOsc AR a 0
+>     ; f = fft' 10 b
+>     ; x = mouseX KR 0 128 Linear 0.1
+>     ; h = pv_MagClip f x }
+> in audition (out 0 (ifft' h * 0.5))
diff --git a/Help/UGen/FFT/pv_MagFreeze.help.lhs b/Help/UGen/FFT/pv_MagFreeze.help.lhs
--- a/Help/UGen/FFT/pv_MagFreeze.help.lhs
+++ b/Help/UGen/FFT/pv_MagFreeze.help.lhs
@@ -4,23 +4,20 @@
 threshold.
 
 > let fileName = "/home/rohan/audio/metal.wav"
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done"
->                    send fd (b_allocRead 12 fileName 0 0)
->                    wait fd "/done")
-> let a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
->     f = fft' 10 a
->     x = mouseX KR 0 1 Linear 0.1
->     h = pv_MagFreeze f (x >* 0.5)
-> audition (out 0 (ifft' h * 0.5))
+> in withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                       ; async fd (b_allocRead 12 fileName 0 0) })
 
+> let { a = playBuf 1 12 (bufRateScale KR 12) 0 0 Loop
+>     ; f = fft' 10 a
+>     ; x = mouseX KR 0 1 Linear 0.1
+>     ; h = pv_MagFreeze f (x >* 0.5) }
+> in audition (out 0 (ifft' h * 0.5))
+
 Synthesised input.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> let a = sinOsc KR (squared (sinOsc KR 0.08 0 * 6 + 6.2)) 0 * 100 + 800
->     b = sinOsc AR a 0
->     f = fft' 10 b
->     x = mouseX KR 0 1 Linear 0.1
->     h = pv_MagFreeze f (x >* 0.5)
-> audition (out 0 (ifft' h * 0.5))
+> let { a = sinOsc KR (squared (sinOsc KR 0.08 0 * 6 + 6.2)) 0 * 100 + 800
+>     ; b = sinOsc AR a 0
+>     ; f = fft' 10 b
+>     ; x = mouseX KR 0 1 Linear 0.1
+>     ; h = pv_MagFreeze f (x >* 0.5) }
+> in audition (out 0 (ifft' h * 0.5))
diff --git a/Help/UGen/FFT/pv_RandComb.help.lhs b/Help/UGen/FFT/pv_RandComb.help.lhs
--- a/Help/UGen/FFT/pv_RandComb.help.lhs
+++ b/Help/UGen/FFT/pv_RandComb.help.lhs
@@ -5,10 +5,10 @@
 buffer = fft buffer.  wipe = clear bins from input in a random
 order (0, 1).  trig = select new random ordering.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> let x = mouseX KR 0.6 0.95 Linear 0.1
->     t = impulse KR 0.4 0
-> n <- whiteNoise AR
-> c <- pv_RandComb (fft' 10 (n * 0.5)) x t
-> audition (out 0 (pan2 (ifft' c) 0 1))
+> withSC3 (\fd -> async fd (b_alloc 10 2048 1))
+
+> let { x = mouseX KR 0.6 0.95 Linear 0.1
+>     ; t = impulse KR 0.4 0 }
+> in do { n <- whiteNoise AR
+>       ; c <- pv_RandComb (fft' 10 (n * 0.5)) x t
+>       ; audition (out 0 (pan2 (ifft' c) 0 1)) }
diff --git a/Help/UGen/FFT/pv_RandWipe.help.lhs b/Help/UGen/FFT/pv_RandWipe.help.lhs
--- a/Help/UGen/FFT/pv_RandWipe.help.lhs
+++ b/Help/UGen/FFT/pv_RandWipe.help.lhs
@@ -6,21 +6,20 @@
 bins from bufferB in a random order (0, 1).  trig = select new
 random ordering.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done"
->                    send fd (b_alloc 11 2048 1)
->                    wait fd "/done")
-> let n0 = randomRs (400.0, 1000.0) (mkStdGen 0)
->     n1 = randomRs (80.0, 400.0) (mkStdGen 1)
->     n2 = randomRs (0.0, 8.0) (mkStdGen 2)
->     o0 = map (\n -> lfSaw AR n 0 * 0.1) (take 6 n0)
->     o1 = map (\n -> lfPulse AR n 0.0 0.2) (take 6 n1)
->     o2 = map (\n -> sinOsc KR n 0 * 0.2) (take 6 n2)
->     a  = mix (MCE o0)
->     b  = mix (MCE (zipWith (\p s -> p * (max s 0.0)) o1 o2))
->     f  = fft' 10 a
->     g  = fft' 11 b
->     x  = mouseX KR 0 1 Linear 0.1
->     y  = mouseY KR 0 1 Linear 0.1
-> h <- pv_RandWipe f g x (y >* 0.5)
-> audition (out 0 (pan2 (ifft' h) 0 0.5))
+> withSC3 (\fd -> do { async fd (b_alloc 10 2048 1)
+>                    ; async fd (b_alloc 11 2048 1) })
+
+> let { n0 = randomRs (400.0, 1000.0) (mkStdGen 0)
+>     ; n1 = randomRs (80.0, 400.0) (mkStdGen 1)
+>     ; n2 = randomRs (0.0, 8.0) (mkStdGen 2)
+>     ; o0 = map (\n -> lfSaw AR n 0 * 0.1) (take 6 n0)
+>     ; o1 = map (\n -> lfPulse AR n 0.0 0.2) (take 6 n1)
+>     ; o2 = map (\n -> sinOsc KR n 0 * 0.2) (take 6 n2)
+>     ; a = mix (mce o0)
+>     ; b = mix (mce (zipWith (\p s -> p * (max s 0.0)) o1 o2))
+>     ; f = fft' 10 a
+>     ; g = fft' 11 b
+>     ; x = mouseX KR 0 1 Linear 0.1
+>     ; y = mouseY KR 0 1 Linear 0.1 }
+> in do { h <- pv_RandWipe f g x (y >* 0.5)
+>       ; audition (out 0 (pan2 (ifft' h) 0 0.5)) }
diff --git a/Help/UGen/FFT/pv_RectComb.help.lhs b/Help/UGen/FFT/pv_RectComb.help.lhs
--- a/Help/UGen/FFT/pv_RectComb.help.lhs
+++ b/Help/UGen/FFT/pv_RectComb.help.lhs
@@ -1,17 +1,15 @@
 pv_RectComb buffer numTeeth phase width
 
-> n <- whiteNoise AR
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> let x = mouseX KR 0 0.5 Linear 0.1
->     y = mouseY KR 0 0.5 Linear 0.1
->     c = pv_RectComb (fft' 10 (n * 0.3)) 8 x y
-> audition (out 0 (pan2 (ifft' c) 0 1))
+> withSC3 (\fd -> async fd (b_alloc 10 2048 1))
 
-> n <- whiteNoise AR
-> withSC3 (\fd -> do send fd (b_alloc 10 2048 1)
->                    wait fd "/done")
-> let p = lfTri KR 0.097 0 *   0.4  + 0.5
->     w = lfTri KR 0.240 0 * (-0.5) + 0.5
->     c = pv_RectComb (fft' 10 (n * 0.3)) 8 p w
-> audition (out 0 (pan2 (ifft' c) 0 1))
+> do { n <- whiteNoise AR
+>    ; let { x = mouseX KR 0 0.5 Linear 0.1
+>          ; y = mouseY KR 0 0.5 Linear 0.1
+>          ; c = pv_RectComb (fft' 10 (n * 0.3)) 8 x y }
+>      in audition (out 0 (pan2 (ifft' c) 0 1)) }
+
+> do { n <- whiteNoise AR
+>    ; let { p = lfTri KR 0.097 0 *   0.4  + 0.5
+>          ; w = lfTri KR 0.240 0 * (-0.5) + 0.5
+>          ; c = pv_RectComb (fft' 10 (n * 0.3)) 8 p w }
+>      in audition (out 0 (pan2 (ifft' c) 0 1)) }
diff --git a/Help/UGen/FFT/pvcollect.help.lhs b/Help/UGen/FFT/pvcollect.help.lhs
--- a/Help/UGen/FFT/pvcollect.help.lhs
+++ b/Help/UGen/FFT/pvcollect.help.lhs
@@ -19,17 +19,20 @@
 Note that this procedure can be relatively CPU-heavy, depending on
 how you use it.
 
-> withSC3 (\fd -> do let async p m = send p m >> wait p "/done"
->                    async fd (b_alloc 10 1024 1)
->                    async fd (b_allocRead 11 "/home/rohan/audio/metal.wav" 0 0))
-> let no_op m p _ = (m, p)
->     combf m p i = ((modE i 7.0 ==* 0) * m, p)
->     spectral_delay m p _ = (m + delayN m 1 v, p)
->         where v = linLin (lfPar KR 0.5 0) (-1) 1 0.1 1
->     bpf_sweep nf m p i = ((e <* 10) * m, p)
->         where e = abs (i - (linLin (lfPar KR 0.1 0) (-1) 1 2 (nf / 20)))
->     nf = 1024
->     sf = playBuf 1 11 (bufRateScale KR 11) 1 0 Loop
->     c1 = fft' 10 sf
->     c2 = pvcollect c1 nf spectral_delay 0 250 0
-> audition (out 0 (0.1 * ifft' c2))
+> let fileName = "/home/rohan/audio/metal.wav"
+> in withSC3 (\fd -> do { async fd (b_alloc 10 1024 1)
+>                       ; async fd (b_allocRead 11 fileName 0 0) })
+
+> let { no_op m p _ = (m, p)
+>     ; combf m p i = ((modE i 7.0 ==* 0) * m, p)
+>     ; spectral_delay m p _ = let { l = lfPar KR 0.5 0
+>                                  ; v = linLin l (-1) 1 0.1 1 }
+>                              in (m + delayN m 1 v, p)
+>     ; nf = 1024
+>     ; bpf_sweep m p i = let { l = lfPar KR 0.1 0
+>                             ; e = abs (i - (linLin l (-1) 1 2 (nf / 20))) }
+>                         in ((e <* 10) * m, p)
+>     ; sf = playBuf 1 11 (bufRateScale KR 11) 1 0 Loop
+>     ; c1 = fft' 10 sf
+>     ; c2 = pvcollect c1 nf spectral_delay 0 250 0 }
+> in audition (out 0 (0.1 * ifft' c2))
diff --git a/Help/UGen/Filter/allpassN.help.lhs b/Help/UGen/Filter/allpassN.help.lhs
--- a/Help/UGen/Filter/allpassN.help.lhs
+++ b/Help/UGen/Filter/allpassN.help.lhs
@@ -11,33 +11,33 @@
 state sound ...
 
 > let dly = xLine KR 0.0001 0.01 20 RemoveSynth
-> n <- whiteNoise AR
-> audition (out 0 (allpassC (n * 0.1) 0.01 dly 0.2))
+> in do { n <- whiteNoise AR
+>       ; audition (out 0 (allpassC (n * 0.1) 0.01 dly 0.2)) }
 
 ...these examples add the input to the effected sound so that you
 can hear the effect of the phase comb.
 
-> n <- whiteNoise AR
-> let dly = xLine KR 0.0001 0.01 20 RemoveSynth
-> audition (out 0 ((n + allpassN (n * 0.1) 0.01 dly 0.2) * 0.1))
+> do { n <- whiteNoise AR
+>    ; let dly = xLine KR 0.0001 0.01 20 RemoveSynth
+>      in audition (out 0 ((n + allpassN (n * 0.1) 0.01 dly 0.2) * 0.1)) }
 
 Linear variant
 
-> n <- whiteNoise AR
-> let dly = xLine KR 0.0001 0.01 20 RemoveSynth
-> audition (out 0 ((n + allpassL (n * 0.1) 0.01 dly 0.2) * 0.1))
+> do { n <- whiteNoise AR
+>    ; let dly = xLine KR 0.0001 0.01 20 RemoveSynth
+>      in audition (out 0 ((n + allpassL (n * 0.1) 0.01 dly 0.2) * 0.1)) }
 
 Cubic variant
 
-> n <- whiteNoise AR
-> let dly = xLine KR 0.0001 0.01 20 RemoveSynth
-> audition (out 0 ((n + allpassC (n * 0.1) 0.01 dly 0.2) * 0.1))
+> do { n <- whiteNoise AR
+>    ; let dly = xLine KR 0.0001 0.01 20 RemoveSynth
+>      in audition (out 0 ((n + allpassC (n * 0.1) 0.01 dly 0.2) * 0.1)) }
 
 Used as an echo - doesn't really sound different than Comb, but it
 outputs the input signal immediately (inverted) and the echoes are
 lower in amplitude.
 
-> n <- whiteNoise AR
-> d <- dust AR 1
-> let src = decay (d * 0.5) 0.2 * n
-> audition (out 0 (allpassN src 0.2 0.2 3))
+> do { n <- whiteNoise AR
+>    ; d <- dust AR 1
+>    ; let src = decay (d * 0.5) 0.2 * n
+>      in audition (out 0 (allpassN src 0.2 0.2 3)) }
diff --git a/Help/UGen/Filter/bpf.help.lhs b/Help/UGen/Filter/bpf.help.lhs
--- a/Help/UGen/Filter/bpf.help.lhs
+++ b/Help/UGen/Filter/bpf.help.lhs
@@ -7,9 +7,9 @@
 rq    - the reciprocal of Q, ie. bandwidth / cutoffFreq
 
 > let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
-> audition (out 0 (bpf (saw AR 200 * 0.5) f 0.3 ))
+> in audition (out 0 (bpf (saw AR 200 * 0.5) f 0.3 ))
 
-> n <- whiteNoise AR
-> let x = mouseX KR 220 440 Exponential 0.1
-> let y = mouseY KR 0 0.01 Linear 0.1
-> audition (out 0 (bpf n (MCE [x, 550 - x]) y))
+> do { n <- whiteNoise AR
+>    ; let { x = mouseX KR 220 440 Exponential 0.1
+>          ; y = mouseY KR 0.01 0.2 Linear 0.1 }
+>      in audition (out 0 (bpf n (mce [x, 550 - x]) y)) }
diff --git a/Help/UGen/Filter/bpz2.help.lhs b/Help/UGen/Filter/bpz2.help.lhs
--- a/Help/UGen/Filter/bpz2.help.lhs
+++ b/Help/UGen/Filter/bpz2.help.lhs
@@ -3,5 +3,5 @@
 Two zero fixed midpass.  This filter cuts out 0 Hz and the Nyquist
 frequency.
 
-> n <- whiteNoise AR
-> audition (out 0 (bpz2 (n * 0.25)))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (bpz2 (n * 0.25))) }
diff --git a/Help/UGen/Filter/brf.help.lhs b/Help/UGen/Filter/brf.help.lhs
--- a/Help/UGen/Filter/brf.help.lhs
+++ b/Help/UGen/Filter/brf.help.lhs
@@ -3,4 +3,4 @@
 Second order Butterworth band reject filter.
 
 > let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3800 + 4000
-> audition (out 0 (brf (saw AR 200 * 0.1) f 0.3))
+> in audition (out 0 (brf (saw AR 200 * 0.1) f 0.3))
diff --git a/Help/UGen/Filter/combN.help.lhs b/Help/UGen/Filter/combN.help.lhs
--- a/Help/UGen/Filter/combN.help.lhs
+++ b/Help/UGen/Filter/combN.help.lhs
@@ -10,27 +10,27 @@
 Comb used as a resonator. The resonant fundamental is equal to
 reciprocal of the delay time.
 
-> n <- whiteNoise AR
-> let dt = xLine KR 0.0001 0.01 20 RemoveSynth
-> audition (out 0 (combN (n * 0.1) 0.01 dt 0.2))
+> do { n <- whiteNoise AR
+>    ; let dt = xLine KR 0.0001 0.01 20 RemoveSynth
+>      in audition (out 0 (combN (n * 0.1) 0.01 dt 0.2)) }
 
-> n <- whiteNoise AR
-> let dt = xLine KR 0.0001 0.01 20 RemoveSynth
-> audition (out 0 (combL (n * 0.1) 0.01 dt 0.2))
+> do { n <- whiteNoise AR
+>    ; let dt = xLine KR 0.0001 0.01 20 RemoveSynth
+>      in audition (out 0 (combL (n * 0.1) 0.01 dt 0.2)) }
 
-> n <- whiteNoise AR
-> let dt = xLine KR 0.0001 0.01 20 RemoveSynth
-> audition (out 0 (combC (n * 0.1) 0.01 dt 0.2))
+> do { n <- whiteNoise AR
+>    ; let dt = xLine KR 0.0001 0.01 20 RemoveSynth
+>      in audition (out 0 (combC (n * 0.1) 0.01 dt 0.2)) }
 
 With negative feedback:
 
-> n <- whiteNoise AR
-> let dt = xLine KR 0.0001 0.01 20 RemoveSynth
-> audition (out 0 (combC (n * 0.1) 0.01 dt (-0.2)))
+> do { n <- whiteNoise AR
+>    ; let dt = xLine KR 0.0001 0.01 20 RemoveSynth
+>      in audition (out 0 (combC (n * 0.1) 0.01 dt (-0.2))) }
 
 Used as an echo.
 
-> d <- dust AR 1
-> n <- whiteNoise AR
-> let i = decay (d * 0.5) 0.2 * n
-> audition (out 0 (combC i 0.2 0.2 3))
+> do { d <- dust AR 1
+>    ; n <- whiteNoise AR
+>    ; let i = decay (d * 0.5) 0.2 * n
+>      in audition (out 0 (combC i 0.2 0.2 3)) }
diff --git a/Help/UGen/Filter/decay.help.lhs b/Help/UGen/Filter/decay.help.lhs
--- a/Help/UGen/Filter/decay.help.lhs
+++ b/Help/UGen/Filter/decay.help.lhs
@@ -8,6 +8,6 @@
 
 Used as an envelope.
 
-> let s = impulse AR (xLine KR 1 50 20 RemoveSynth) 0.25
-> n <- pinkNoise AR
-> audition (out 0 (decay s 0.2 * n))
+> do { n <- pinkNoise AR
+>    ; let s = impulse AR (xLine KR 1 50 20 RemoveSynth) 0.25
+>      in audition (out 0 (decay s 0.2 * n)) }
diff --git a/Help/UGen/Filter/decay2.help.lhs b/Help/UGen/Filter/decay2.help.lhs
--- a/Help/UGen/Filter/decay2.help.lhs
+++ b/Help/UGen/Filter/decay2.help.lhs
@@ -8,12 +8,12 @@
 
 Used as an envelope
 
-> let s = fSinOsc AR 600 0 * 0.25
->     f = xLine KR 1 50 20 RemoveSynth
-> audition (out 0 (decay2 (impulse AR f 0.25) 0.01 0.2 * s))
+> let { s = fSinOsc AR 600 0 * 0.25
+>     ; f = xLine KR 1 50 20 RemoveSynth }
+> in audition (out 0 (decay2 (impulse AR f 0) 0.01 0.2 * s))
 
 Compare the above with Decay used as the envelope.
 
-> let s = fSinOsc AR 600 0 * 0.25
->     f = xLine KR 1 50 20 RemoveSynth
-> audition (out 0 (decay (impulse AR f 0.25) 0.2 * s))
+> let { s = fSinOsc AR 600 0 * 0.25
+>     ; f = xLine KR 1 50 20 RemoveSynth }
+> in audition (out 0 (decay (impulse AR f 0) 0.2 * s))
diff --git a/Help/UGen/Filter/degreeToKey.help.lhs b/Help/UGen/Filter/degreeToKey.help.lhs
--- a/Help/UGen/Filter/degreeToKey.help.lhs
+++ b/Help/UGen/Filter/degreeToKey.help.lhs
@@ -11,16 +11,15 @@
 in     - the input signal.
 octave - the number of steps per octave in the scale.
 
-> withSC3 (\fd -> do send fd (b_alloc 0 7 1)
->                    wait fd "/done"
->                    send fd (b_setn 0 [(0, [0, 2, 3.2, 5, 7, 9, 10])]))
+> withSC3 (\fd -> do { async fd (b_alloc 0 7 1)
+>                    ; send fd (b_setn 0 [(0, [0, 2, 3.2, 5, 7, 9, 10])]) })
 
-> n <- lfNoise1 KR (MCE [3, 3.05])
-> let x = mouseX KR 0 15 Linear 0.1
->     k = degreeToKey 0 x 12
->     f b = combN m 0.31 0.31 2 + m
->         where o = sinOsc AR (midiCPS (b + k + n * 0.04)) 0 * 0.1
->               t = lfPulse AR (midiCPS (MCE [48, 55])) 0.15 0.5
->               d = rlpf t (midiCPS (sinOsc KR 0.1 0 * 10 + b)) 0.1 * 0.1
->               m = o + d
-> audition (out 0 ((f 48 + f 72) * 0.25))
+> do { n <- lfNoise1 KR (mce [3, 3.05])
+>    ; let { x = mouseX KR 0 15 Linear 0.1
+>          ; k = degreeToKey 0 x 12
+>          ; f b = let { o = sinOsc AR (midiCPS (b + k + n * 0.04)) 0 * 0.1
+>                      ; t = lfPulse AR (midiCPS (mce [48, 55])) 0.15 0.5
+>                      ; d = rlpf t (midiCPS (sinOsc KR 0.1 0 * 10 + b)) 0.1 * 0.1
+>                      ; m = o + d }
+>                  in combN m 0.31 0.31 2 + m }
+>      in audition (out 0 ((f 48 + f 72) * 0.25)) }
diff --git a/Help/UGen/Filter/delay1.help.lhs b/Help/UGen/Filter/delay1.help.lhs
--- a/Help/UGen/Filter/delay1.help.lhs
+++ b/Help/UGen/Filter/delay1.help.lhs
@@ -3,4 +3,4 @@
 Fixed Single sample delay.
 
 > let s = impulse AR 1 0
-> audition (out 0 (s + (delay1 s)))
+> in audition (out 0 (s + (delay1 s)))
diff --git a/Help/UGen/Filter/delay2.help.lhs b/Help/UGen/Filter/delay2.help.lhs
--- a/Help/UGen/Filter/delay2.help.lhs
+++ b/Help/UGen/Filter/delay2.help.lhs
@@ -3,4 +3,4 @@
 Fixed two sample delay.
 
 > let s = impulse AR 1 0
-> audition (out 0 (s + (delay2 s)))
+> in audition (out 0 (s + (delay2 s)))
diff --git a/Help/UGen/Filter/delayN.help.lhs b/Help/UGen/Filter/delayN.help.lhs
--- a/Help/UGen/Filter/delayN.help.lhs
+++ b/Help/UGen/Filter/delayN.help.lhs
@@ -9,17 +9,17 @@
 envelope for the WhiteNoise input source.  The input is
 mixed with the delay.
 
-> d <- dust AR 1
-> n <- whiteNoise AR
-> let z = decay d 0.3 * n
->     x = mouseX KR 0.0 0.2 Linear 0.1
-> audition (out 0 (z + delayN z 0.2 x))
+> do { d <- dust AR 1
+>    ; n <- whiteNoise AR
+>    ; let { z = decay d 0.3 * n
+>          ; x = mouseX KR 0.0 0.2 Linear 0.1 }
+>      in audition (out 0 (z + delayN z 0.2 x)) }
 
 The delay time can be varied at control rate.
 An oscillator either reinforcing or cancelling
 with the delayed copy of itself.
 
-> let o = sinOsc AR 320 0 * 0.1
->     l = 0.005
->     x = mouseX KR 0.0 l Linear 0.15
-> audition (out 0 (o + delayN o l x))
+> let { o = sinOsc AR 320 0 * 0.1
+>     ; l = 0.005
+>     ; x = mouseX KR 0.0 l Linear 0.15 }
+> in audition (out 0 (o + delayN o l x))
diff --git a/Help/UGen/Filter/formlet.help.lhs b/Help/UGen/Filter/formlet.help.lhs
--- a/Help/UGen/Filter/formlet.help.lhs
+++ b/Help/UGen/Filter/formlet.help.lhs
@@ -5,9 +5,9 @@
 > audition (out 0 (formlet (impulse AR 20 0.5) 1000 0.01 0.1))
 
 > let f = xLine KR 10 400 8 RemoveSynth
-> audition (out 0 (formlet (blip AR f 1000 * 0.1) 1000 0.01 0.1))
+> in audition (out 0 (formlet (blip AR f 1000 * 0.1) 1000 0.01 0.1))
 
 Modulating formant frequency.
 
 > let s = blip AR (sinOsc KR 5 0 * 20 + 300) 1000 * 0.1
-> audition (out 0 (formlet s (xLine KR 1500 700 8 RemoveSynth) 0.005 0.04))
+> in audition (out 0 (formlet s (xLine KR 1500 700 8 RemoveSynth) 0.005 0.04))
diff --git a/Help/UGen/Filter/fos.help.lhs b/Help/UGen/Filter/fos.help.lhs
--- a/Help/UGen/Filter/fos.help.lhs
+++ b/Help/UGen/Filter/fos.help.lhs
@@ -5,9 +5,9 @@
 Same as OnePole.
 
 > let x = lfTri AR 0.4 0 * 0.99
-> audition (out 0 (fos (lfSaw AR 200 0 * 0.2) (1 - (abs x)) 0 x))
+> in audition (out 0 (fos (lfSaw AR 200 0 * 0.2) (1 - (abs x)) 0 x))
 
 Same as OneZero
 
 > let x = lfTri AR 0.4 0 * 0.99
-> audition (out 0 (fos (lfSaw AR 200 0 * 0.2) (1 - (abs x)) x 0))
+> in audition (out 0 (fos (lfSaw AR 200 0 * 0.2) (1 - (abs x)) x 0))
diff --git a/Help/UGen/Filter/freqShift.help.lhs b/Help/UGen/Filter/freqShift.help.lhs
--- a/Help/UGen/Filter/freqShift.help.lhs
+++ b/Help/UGen/Filter/freqShift.help.lhs
@@ -12,28 +12,28 @@
 
 shifting a 100Hz tone by 1 Hz rising to 500Hz
 
-> let i = sinOsc AR 100 0
->     s = xLine KR 1 500 5 RemoveSynth
-> audition (out 0 (freqShift i s 0 * 0.1))
+> let { i = sinOsc AR 100 0
+>     ; s = xLine KR 1 500 5 RemoveSynth }
+> in audition (out 0 (freqShift i s 0 * 0.1))
 
 shifting a complex tone by 1 Hz rising to 500Hz
 
-> let d = klangSpec [101, 303, 606, 808] [1, 1, 1, 1] [1, 1, 1, 1]
->     i = klang AR 1 0 d
->     s = xLine KR 1 500 5 RemoveSynth
-> audition (out 0 (freqShift i s 0 * 0.1))
+> let { d = klangSpec [101, 303, 606, 808] [1, 1, 1, 1] [1, 1, 1, 1]
+>     ; i = klang AR 1 0 d
+>     ; s = xLine KR 1 500 5 RemoveSynth }
+> in audition (out 0 (freqShift i s 0 * 0.1))
 
 modulating shift and phase
 
-> s <- lfNoise2 AR 0.3
-> let i = sinOsc AR 10 0
->     p = linLin (sinOsc AR 500 0) (-1) 1 0 (2 * pi)
-> audition (out 0 (freqShift i (s * 1500) p * 0.1))
+> do { s <- lfNoise2 AR 0.3
+>    ; let { i = sinOsc AR 10 0
+>          ; p = linLin (sinOsc AR 500 0) (-1) 1 0 (2 * pi) }
+>      in audition (out 0 (freqShift i (s * 1500) p * 0.1)) }
 
 shifting bandpassed noise
 
-> n1 <- whiteNoise AR
-> n2 <- lfNoise0 AR 5.5
-> let i = bpf n1 1000 0.001
->     s = n2 * 1000
-> audition (out 0 (freqShift i s 0 * 32))
+> do { n1 <- whiteNoise AR
+>    ; n2 <- lfNoise0 AR 5.5
+>    ; let { i = bpf n1 1000 0.001
+>          ; s = n2 * 1000 }
+>      in audition (out 0 (freqShift i s 0 * 32)) }
diff --git a/Help/UGen/Filter/hpf.help.lhs b/Help/UGen/Filter/hpf.help.lhs
--- a/Help/UGen/Filter/hpf.help.lhs
+++ b/Help/UGen/Filter/hpf.help.lhs
@@ -3,4 +3,4 @@
 Second order Butterworth highpass filter.
 
 > let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
-> audition (out 0 (hpf (saw AR 200 * 0.2) f))
+> in audition (out 0 (hpf (saw AR 200 * 0.2) f))
diff --git a/Help/UGen/Filter/hpz1.help.lhs b/Help/UGen/Filter/hpz1.help.lhs
--- a/Help/UGen/Filter/hpz1.help.lhs
+++ b/Help/UGen/Filter/hpz1.help.lhs
@@ -2,5 +2,5 @@
 
 Two point difference filter.
 
-> n <- whiteNoise AR
-> audition (out 0 (hpz1 (n * 0.25)))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (hpz1 (n * 0.25))) }
diff --git a/Help/UGen/Filter/hpz2.help.lhs b/Help/UGen/Filter/hpz2.help.lhs
--- a/Help/UGen/Filter/hpz2.help.lhs
+++ b/Help/UGen/Filter/hpz2.help.lhs
@@ -2,5 +2,5 @@
 
 Two zero fixed highpass filter.
 
-> n <- whiteNoise AR
-> audition (out 0 (hpz2 (n * 0.25)))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (hpz2 (n * 0.25))) }
diff --git a/Help/UGen/Filter/klank.help.lhs b/Help/UGen/Filter/klank.help.lhs
--- a/Help/UGen/Filter/klank.help.lhs
+++ b/Help/UGen/Filter/klank.help.lhs
@@ -20,4 +20,18 @@
              initialization time.
 
 > let s = klankSpec [800, 1071, 1153, 1723] [1, 1, 1, 1] [1, 1, 1, 1]
-> audition (out 0 (klank (impulse AR 2 0 * 0.1) 1 0 1 s))
+> in audition (out 0 (klank (impulse AR 2 0 * 0.1) 1 0 1 s))
+
+There is a limited form of multiple channel expansion possible
+at 'specification' input, below three equal dimensional 
+specifications are tranposed and force expansion in a sensible manner.
+
+> let { u = [1, 1, 1, 1]
+>     ; p = [200, 171, 153, 172]
+>     ; q = [930, 971, 953, 1323]
+>     ; r = [8900, 16062, 9013, 7892]
+>     ; k = mce [klankSpec p u u, klankSpec q u u, klankSpec r u u]
+>     ; s = mceTranspose k
+>     ; i = mce [2, 2.07, 2.13]
+>     ; t = impulse AR i 0 * 0.1 }
+> in audition (out 0 (mix (klank t 1 0 1 s)))
diff --git a/Help/UGen/Filter/lag.help.lhs b/Help/UGen/Filter/lag.help.lhs
--- a/Help/UGen/Filter/lag.help.lhs
+++ b/Help/UGen/Filter/lag.help.lhs
@@ -3,4 +3,4 @@
 A simple averaging filter.
 
 > let x = mouseX KR 220 440 Linear 0.2
-> audition (out 0 (sinOsc AR (MCE [x, lag x 1]) 0 * 0.1))
+> in audition (out 0 (sinOsc AR (mce [x, lag x 1]) 0 * 0.1))
diff --git a/Help/UGen/Filter/lag2.help.lhs b/Help/UGen/Filter/lag2.help.lhs
--- a/Help/UGen/Filter/lag2.help.lhs
+++ b/Help/UGen/Filter/lag2.help.lhs
@@ -3,4 +3,4 @@
 Lag2 is the same as lag KR (lag KR s t) t.
 
 > let x = mouseX KR 220 440 Exponential 0.1
-> audition (out 0 (sinOsc AR (MCE [x, lag2 x 1]) 0 * 0.1))
+> in audition (out 0 (sinOsc AR (mce [x, lag2 x 1]) 0 * 0.1))
diff --git a/Help/UGen/Filter/lag3.help.lhs b/Help/UGen/Filter/lag3.help.lhs
--- a/Help/UGen/Filter/lag3.help.lhs
+++ b/Help/UGen/Filter/lag3.help.lhs
@@ -3,4 +3,4 @@
 Lag3 is the same as lag KR (lag KR (lag KT s t) t) t.
 
 > let x = mouseX KR 220 440 Exponential 0.1
-> audition (out 0 (sinOsc AR (MCE [x, lag3 x 1]) 0 * 0.1))
+> in audition (out 0 (sinOsc AR (mce [x, lag3 x 1]) 0 * 0.1))
diff --git a/Help/UGen/Filter/latch.help.lhs b/Help/UGen/Filter/latch.help.lhs
--- a/Help/UGen/Filter/latch.help.lhs
+++ b/Help/UGen/Filter/latch.help.lhs
@@ -6,21 +6,21 @@
 trig - trigger. The trigger can be any signal. A trigger happens when the
        signal changes from non-positive to positive.
 
-> n <- whiteNoise AR
-> let i = impulse AR 9 0
-> let l = latch n i
-> audition (out 0 (blip AR (l * 400 + 500) 4 * 0.2))
+> do { n <- whiteNoise AR
+>    ; let { i = impulse AR 9 0
+>          ; l = latch n i }
+>      in audition (out 0 (blip AR (l * 400 + 500) 4 * 0.2)) }
 
 The above is just meant as example. LFNoise0 is a faster way to
 generate random steps :
 
-> n <- lfNoise0 KR 9
-> audition (out 0 (blip AR (n * 400 + 500) 4 * 0.2))
+> do { n <- lfNoise0 KR 9
+>    ; audition (out 0 (blip AR (n * 400 + 500) 4 * 0.2)) }
 
 http://create.ucsb.edu/pipermail/sc-users/2006-December/029991.html
 
-> n0 <- lfNoise2 KR 8
-> n1 <- lfNoise2 KR 3
-> let s = blip AR (n0 * 200 + 300) (n1 * 10 + 20)
->     x = mouseX KR 1000 (sampleRate * 0.1) Exponential 0.1
-> audition (out 0 (latch s (impulse AR x 0)))
+> do { n0 <- lfNoise2 KR 8
+>    ; n1 <- lfNoise2 KR 3
+>    ; let { s = blip AR (n0 * 200 + 300) (n1 * 10 + 20)
+>          ; x = mouseX KR 1000 (sampleRate * 0.1) Exponential 0.1 }
+>      in audition (out 0 (latch s (impulse AR x 0))) }
diff --git a/Help/UGen/Filter/leakDC.help.lhs b/Help/UGen/Filter/leakDC.help.lhs
--- a/Help/UGen/Filter/leakDC.help.lhs
+++ b/Help/UGen/Filter/leakDC.help.lhs
@@ -4,4 +4,4 @@
 input signal.  coef - leak coefficient.
 
 > let a = lfPulse AR 800 0.5 0.5 * 0.1
-> audition (out 0 (MCE [a, leakDC a 0.995]))
+> in audition (out 0 (mce [a, leakDC a 0.995]))
diff --git a/Help/UGen/Filter/linExp.help.lhs b/Help/UGen/Filter/linExp.help.lhs
--- a/Help/UGen/Filter/linExp.help.lhs
+++ b/Help/UGen/Filter/linExp.help.lhs
@@ -10,11 +10,11 @@
 dsthi - upper limit of output range.
 
 > let f = linExp (mouseX KR 0 1 Linear 0.2) 0 1 440 660
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
 
 The destination range may be k-rate.
 
-> let x = mouseX KR 0 1 Linear 0.2
->     y = mouseY KR 220 440 Linear 0.2
->     f = linExp x 0 1 y 660
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> let { x = mouseX KR 0 1 Linear 0.2
+>     ; y = mouseY KR 220 440 Linear 0.2
+>     ; f = linExp x 0 1 y 660 }
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Filter/linLin.help.lhs b/Help/UGen/Filter/linLin.help.lhs
--- a/Help/UGen/Filter/linLin.help.lhs
+++ b/Help/UGen/Filter/linLin.help.lhs
@@ -9,11 +9,11 @@
 dsthi - upper limit of output range.
 
 > let f = linLin (mouseX KR 0 1 Linear 0.2) 0 1 440 660
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
 
 The destination range may be k-rate.
 
-> let x = mouseX KR 0 1 Linear 0.2
->     y = mouseY KR 220 440 Linear 0.2
->     f = linLin x 0 1 y 660
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> let { x = mouseX KR 0 1 Linear 0.2
+>     ; y = mouseY KR 220 440 Linear 0.2
+>     ; f = linLin x 0 1 y 660 }
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Filter/lpf.help.lhs b/Help/UGen/Filter/lpf.help.lhs
--- a/Help/UGen/Filter/lpf.help.lhs
+++ b/Help/UGen/Filter/lpf.help.lhs
@@ -3,9 +3,9 @@
 Second order Butterworth lowpass filter.
 
 > let f = xLine KR 0.7 300 20 RemoveSynth
-> audition (out 0 (lpf (saw AR 200 * 0.1) (fSinOsc KR f 0 * 3600 + 4000)))
+> in audition (out 0 (lpf (saw AR 200 * 0.1) (fSinOsc KR f 0 * 3600 + 4000)))
 
 Control rate filtering.
 
 > let ctl = lpf (lfPulse KR 8 0 0.5) (mouseX KR 2 50 Exponential 0.1)
-> audition (out 0 (sinOsc AR (ctl * 200 + 400) 0 * 0.1))
+> in audition (out 0 (sinOsc AR (ctl * 200 + 400) 0 * 0.1))
diff --git a/Help/UGen/Filter/lpz1.help.lhs b/Help/UGen/Filter/lpz1.help.lhs
--- a/Help/UGen/Filter/lpz1.help.lhs
+++ b/Help/UGen/Filter/lpz1.help.lhs
@@ -2,5 +2,5 @@
 
 Two point average filter
 
-> n <- whiteNoise AR
-> audition (out 0 (lpz1 (n * 0.25)))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (lpz1 (n * 0.25))) }
diff --git a/Help/UGen/Filter/lpz2.help.lhs b/Help/UGen/Filter/lpz2.help.lhs
--- a/Help/UGen/Filter/lpz2.help.lhs
+++ b/Help/UGen/Filter/lpz2.help.lhs
@@ -2,5 +2,5 @@
 
 Two zero fixed lowpass filter
 
-> n <- whiteNoise AR
-> audition (out 0 (lpz2 (n * 0.25)))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (lpz2 (n * 0.25))) }
diff --git a/Help/UGen/Filter/mantissaMask.help.lhs b/Help/UGen/Filter/mantissaMask.help.lhs
--- a/Help/UGen/Filter/mantissaMask.help.lhs
+++ b/Help/UGen/Filter/mantissaMask.help.lhs
@@ -8,4 +8,4 @@
 bits - the number of mantissa bits to preserve. a number from 0 to 23.
 
 > let s = sinOsc AR (sinOsc KR 0.2 0 * 400 + 500) 0 * 0.4
-> audition (out 0 (mantissaMask s 3))
+> in audition (out 0 (mantissaMask s 3))
diff --git a/Help/UGen/Filter/median.help.lhs b/Help/UGen/Filter/median.help.lhs
--- a/Help/UGen/Filter/median.help.lhs
+++ b/Help/UGen/Filter/median.help.lhs
@@ -4,21 +4,22 @@
 
 Signal with impulse noise.
 
-> n <- dust2 AR 100
-> audition (out 0 (median 3 (saw AR 500 * 0.1 + n * 0.9)))
+> do { n <- dust2 AR 100
+>    ; audition (out 0 (median 3 (saw AR 500 * 0.1 + n * 0.9))) }
 
 The median length can be increased for longer duration noise.
 
-> n <- dust2 AR 100
-> audition (out 0 (median 5 (saw AR 500 * 0.1 + lpz1 (n * 0.9))))
+> do { n <- dust2 AR 100
+>    ; audition (out 0 (median 5 (saw AR 500 * 0.1 + lpz1 (n * 0.9)))) }
 
 Long Median filters begin chopping off the peaks of the waveform
 
 > let x = sinOsc AR 1000 0 * 0.2
-> audition (out 0 (MCE [x, median 31 x]))
+> in audition (out 0 (mce [x, median 31 x]))
 
 Another noise reduction application. Use Median filter for high
 frequency noise.  Use LeakDC for low frequency noise.
 
-> n <- whiteNoise AR
-> audition (out 0 (leakDC (median 31 (n * 0.1 + sinOsc AR 800 0 * 0.1)) 0.9))
+> do { n <- whiteNoise AR
+>    ; let s = median 31 (n * 0.1 + sinOsc AR 800 0 * 0.1)
+>      in audition (out 0 (leakDC s 0.9)) }
diff --git a/Help/UGen/Filter/moogFF.help.lhs b/Help/UGen/Filter/moogFF.help.lhs
--- a/Help/UGen/Filter/moogFF.help.lhs
+++ b/Help/UGen/Filter/moogFF.help.lhs
@@ -14,13 +14,13 @@
 Fontana, F. (2007) Preserving the Digital Structure of the Moog
 VCF. In Proc. ICMC07, Copenhagen, 25-31 August 2007
 
-> n <- whiteNoise AR
-> let y = mouseY KR 100 10000 Exponential 0.1
->     x = mouseX KR 0 4 Linear 0.1
-> audition (out 0 (moogFF (n * 0.1) y x 0))
+> do { n <- whiteNoise AR
+>    ; let { y = mouseY KR 100 10000 Exponential 0.1
+>          ; x = mouseX KR 0 4 Linear 0.1 }
+>      in audition (out 0 (moogFF (n * 0.1) y x 0)) }
 
-> n <- lfNoise0 KR 0.43
-> let p = pulse AR (MCE [40, 121]) (MCE [0.3, 0.7])
->     f = linLin (sinOsc KR (linLin n 0 1 0.001 2.2) 0) (-1) 1 30 4200
->     y = mouseY KR 1 4 Linear 0.1
-> audition (out 0 (moogFF p f (0.83 * y) 0))
+> do { n <- lfNoise0 KR 0.43
+>    ; let { p = pulse AR (mce [40, 121]) (mce [0.3, 0.7])
+>          ; f = linLin (sinOsc KR (linLin n 0 1 0.001 2.2) 0) (-1) 1 30 4200
+>          ; y = mouseY KR 1 4 Linear 0.1 }
+>      in audition (out 0 (moogFF p f (0.83 * y) 0)) }
diff --git a/Help/UGen/Filter/normalizer.help.lhs b/Help/UGen/Filter/normalizer.help.lhs
--- a/Help/UGen/Filter/normalizer.help.lhs
+++ b/Help/UGen/Filter/normalizer.help.lhs
@@ -2,6 +2,6 @@
 
 Flattens dynamics.
 
-> let s = fSinOsc AR 500 0
->     z = decay2 (impulse AR 8 (lfSaw KR 0.25 (-0.6) * 0.7)) 0.001 0.3 * s
-> audition (out 0 (MCE [z, normalizer z 0.4 0.01]))
+> let { s = fSinOsc AR 500 0
+>     ; z = decay2 (impulse AR 8 (lfSaw KR 0.25 (-0.6) * 0.7)) 0.001 0.3 * s }
+> in audition (out 0 (mce [z, normalizer z 0.4 0.01]))
diff --git a/Help/UGen/Filter/onePole.help.lhs b/Help/UGen/Filter/onePole.help.lhs
--- a/Help/UGen/Filter/onePole.help.lhs
+++ b/Help/UGen/Filter/onePole.help.lhs
@@ -6,11 +6,12 @@
 in   - input signal to be processed
 coef - feedback coefficient. Should be between -1 and +1
 
-> n <- whiteNoise AR
-> audition (out 0 (onePole (n * 0.5) 0.95))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (onePole (n * 0.5) 0.95)) }
 
-> n <- whiteNoise AR
-> audition (out 0 (onePole (n * 0.5) (-0.95)))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (onePole (n * 0.5) (-0.95))) }
 
-> n <- whiteNoise AR
-> audition (out 0 (onePole (n * 0.5) (line KR (-0.99) 0.99 10 RemoveSynth)))
+> do { n <- whiteNoise AR
+>    ; let c = line KR (-0.99) 0.99 10 RemoveSynth
+>      in audition (out 0 (onePole (n * 0.5) c)) }
diff --git a/Help/UGen/Filter/oneZero.help.lhs b/Help/UGen/Filter/oneZero.help.lhs
--- a/Help/UGen/Filter/oneZero.help.lhs
+++ b/Help/UGen/Filter/oneZero.help.lhs
@@ -2,11 +2,12 @@
 
 One zero filter
 
-> n <- whiteNoise AR
-> audition (out 0 (oneZero (n * 0.5) 0.5))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (oneZero (n * 0.5) 0.5)) }
 
-> n <- whiteNoise AR
-> audition (out 0 (oneZero (n * 0.5) (-0.5)))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (oneZero (n * 0.5) (-0.5))) }
 
-> n <- whiteNoise AR
-> audition (out 0 (oneZero (n * 0.5) (line KR (-0.5) 0.5 10 RemoveSynth)))
+> do { n <- whiteNoise AR
+>    ; let c = line KR (-0.5) 0.5 10 RemoveSynth
+>      in audition (out 0 (oneZero (n * 0.5) c)) }
diff --git a/Help/UGen/Filter/pitchShift.help.lhs b/Help/UGen/Filter/pitchShift.help.lhs
--- a/Help/UGen/Filter/pitchShift.help.lhs
+++ b/Help/UGen/Filter/pitchShift.help.lhs
@@ -2,6 +2,6 @@
 
 A simple time domain pitch shifter.
 
-> let r = mouseX KR 0.5 2.0 Linear 0.1
->     d = mouseY KR 0.0 0.1 Linear 0.1
-> audition (out 0 (pitchShift (sinOsc AR 440 0) 0.2 r d 0))
+> let { r = mouseX KR 0.5 2.0 Linear 0.1
+>     ; d = mouseY KR 0.0 0.1 Linear 0.1 }
+> in audition (out 0 (pitchShift (sinOsc AR 440 0) 0.2 r d 0))
diff --git a/Help/UGen/Filter/pluck.help.lhs b/Help/UGen/Filter/pluck.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/Filter/pluck.help.lhs
@@ -0,0 +1,43 @@
+pluck in tr maxdelaytime delaytime decaytime coef
+
+Karplus-Strong synthesis.
+
+in - an excitation signal
+
+tr - upon a negative to positive transition, the excitation signal
+     will be fed into the delay line
+
+maxdelaytime - the max delay time in seconds (initializes the
+               internal delay buffer).
+
+delaytime - delay time in seconds.
+
+decaytime - time for the echoes to decay by 60 decibels. Negative
+            times emphasize odd partials.
+
+coef - the coef of the internal OnePole filter. Values should be
+       between -1 and +1 (larger values will be unstable... so be
+       careful!).
+
+Excitation signal is WhiteNoise, triggered twice a second with
+varying OnePole coef.
+
+> do { n <- whiteNoise AR
+>    ; let { t = impulse KR 9 0
+>          ; x = mouseX KR (-0.999) 0.999 Linear 0.1
+>          ; y = mouseY KR 0.1 1 Linear 0.1
+>          ; dl = 1 / 440 }
+>      in audition (out 0 (pluck (n * 0.25) t dl (dl * y) 10 x)) }
+
+> let n = 25
+> in do { f <- clone n (rand 0.05 0.2)
+>       ; p <- clone n (rand 0 1)
+>       ; w <- clone n (whiteNoise AR)
+>       ; fi <- clone n (rand 10 12)
+>       ; coef <- rand 0.01 0.2
+>       ; l <- clone n (rand (-1) 1)
+>       ; let { x = mouseX KR 60 1000 Exponential 0.1
+>             ; o = linLin (sinOsc KR f p) (-1) 1 x 3000
+>             ; i = impulse KR fi 0
+>             ; ks = pluck (w * 0.1) i 0.01 (1 / o) 2 coef }
+>         in audition (out 0 (leakDC (mix (pan2 ks l 1)) 0.995)) }
diff --git a/Help/UGen/Filter/resonz.help.lhs b/Help/UGen/Filter/resonz.help.lhs
--- a/Help/UGen/Filter/resonz.help.lhs
+++ b/Help/UGen/Filter/resonz.help.lhs
@@ -8,24 +8,28 @@
 reciprocal of Q is used rather than Q because it saves a divide
 operation inside the unit generator.
 
-in - input signal to be processed
-freq - resonant frequency in Hertz
-rq - bandwidth ratio (reciprocal of Q). rq = bandwidth / centerFreq
+    in - input signal to be processed
+  freq - resonant frequency in Hertz
+    rq - bandwidth ratio (reciprocal of Q). 
+         rq = bandwidth / centerFreq
 
-> n <- whiteNoise AR
-> audition (out 0 (resonz (n * 0.5) 2000 0.1))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (resonz (n * 0.5) 2000 0.1)) }
 
 Modulate frequency
 
-> n <- whiteNoise AR
-> audition (out 0 (resonz (n * 0.5) (xLine KR 1000 8000 10 RemoveSynth) 0.05))
+> do { n <- whiteNoise AR
+>    ; let f = xLine KR 1000 8000 10 RemoveSynth
+>      in audition (out 0 (resonz (n * 0.5) f 0.05)) }
 
 Modulate bandwidth
 
-> n <- whiteNoise AR
-> audition (out 0 (resonz (n * 0.5) 2000 (xLine KR 1 0.001 8 RemoveSynth)))
+> do { n <- whiteNoise AR
+>    ; let bw = xLine KR 1 0.001 8 RemoveSynth
+>      in audition (out 0 (resonz (n * 0.5) 2000 bw)) }
 
 Modulate bandwidth opposite direction
 
-> n <- whiteNoise AR
-> audition (out 0 (resonz (n * 0.5) 2000 (xLine KR 0.001 1 8 RemoveSynth)))
+> do { n <- whiteNoise AR
+>    ; let bw = xLine KR 0.001 1 8 RemoveSynth
+>      in audition (out 0 (resonz (n * 0.5) 2000 bw)) }
diff --git a/Help/UGen/Filter/rhpf.help.lhs b/Help/UGen/Filter/rhpf.help.lhs
--- a/Help/UGen/Filter/rhpf.help.lhs
+++ b/Help/UGen/Filter/rhpf.help.lhs
@@ -3,4 +3,4 @@
 A resonant high pass filter.
 
 > let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
-> audition (out 0 (rhpf (saw AR 200 * 0.1) f 0.2))
+> in audition (out 0 (rhpf (saw AR 200 * 0.1) f 0.2))
diff --git a/Help/UGen/Filter/ringz.help.lhs b/Help/UGen/Filter/ringz.help.lhs
--- a/Help/UGen/Filter/ringz.help.lhs
+++ b/Help/UGen/Filter/ringz.help.lhs
@@ -5,26 +5,27 @@
 decay time. One Ringz is equivalent to one component of the Klank
 UGen.
 
-> n <- dust AR 3
-> audition (out 0 (ringz (n * 0.3) 2000 2))
+> do { n <- dust AR 3
+>    ; audition (out 0 (ringz (n * 0.3) 2000 2)) }
 
-> n <- whiteNoise AR
-> audition (out 0 (ringz (n * 0.005) 2000 0.5))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (ringz (n * 0.005) 2000 0.5)) }
 
 Modulate frequency
 
-> n <- whiteNoise AR
-> audition (out 0 (ringz (n * 0.005) (xLine KR 100 3000 10 RemoveSynth) 0.5))
+> do { n <- whiteNoise AR
+>    ; let f = xLine KR 100 3000 10 RemoveSynth
+>      in audition (out 0 (ringz (n * 0.005) f 0.5)) }
 
 > let f = xLine KR 100 3000 10 RemoveSynth
-> audition (out 0 (ringz (impulse AR 6 0.3) f 0.5))
+> in audition (out 0 (ringz (impulse AR 6 0.3) f 0.5))
 
 Modulate ring time
 
 > let rt = xLine KR 4 0.04 8 RemoveSynth
-> audition (out 0 (ringz (impulse AR 6 0.3) 2000 rt))
+> in audition (out 0 (ringz (impulse AR 6 0.3) 2000 rt))
 
 Modulate ring time opposite direction
 
 > let rt = xLine KR 0.04 4 8 RemoveSynth
-> audition (out 0 (ringz (impulse AR 6 0.3) 2000 rt))
+> in audition (out 0 (ringz (impulse AR 6 0.3) 2000 rt))
diff --git a/Help/UGen/Filter/rlpf.help.lhs b/Help/UGen/Filter/rlpf.help.lhs
--- a/Help/UGen/Filter/rlpf.help.lhs
+++ b/Help/UGen/Filter/rlpf.help.lhs
@@ -3,4 +3,4 @@
 A resonant low pass filter.
 
 > let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
-> audition (out 0 (rlpf (saw AR 200 * 0.1) f 0.2))
+> in audition (out 0 (rlpf (saw AR 200 * 0.1) f 0.2))
diff --git a/Help/UGen/Filter/select.help.lhs b/Help/UGen/Filter/select.help.lhs
--- a/Help/UGen/Filter/select.help.lhs
+++ b/Help/UGen/Filter/select.help.lhs
@@ -2,16 +2,17 @@
 
 The output is selected from an array of inputs.
 
-> let n = 3/2
->     a = MCE [sinOsc AR 440 0, saw AR 440, pulse AR 440 0.1]
-> audition (out 0 (select (lfSaw KR 1 0 * n + n) a * 0.2))
+> let { n = 3/2
+>     ; a = mce [sinOsc AR 440 0, saw AR 440, pulse AR 440 0.1] }
+> in audition (out 0 (select (lfSaw KR 1 0 * n + n) a * 0.2))
 
 Note: all input ugens are continously running. This may not be the
 most efficient way if each input is cpu-expensive.
 
 Here used as a sequencer:
 
-> let n = 10
->     a = MCE [517, 403, 89, 562, 816, 107, 241, 145, 90, 224]
->     c = n / 2
-> audition (out 0 (saw AR (select (lfSaw KR 0.5 0 * c + c) a) * 0.2))
+> let { n = 10
+>     ; a = mce [517, 403, 89, 562, 816, 107, 241, 145, 90, 224]
+>     ; c = n / 2 
+>     ; f = select (lfSaw KR 0.5 0 * c + c) a }
+> in audition (out 0 (saw AR f * 0.2))
diff --git a/Help/UGen/Filter/shaper.help.lhs b/Help/UGen/Filter/shaper.help.lhs
--- a/Help/UGen/Filter/shaper.help.lhs
+++ b/Help/UGen/Filter/shaper.help.lhs
@@ -8,8 +8,7 @@
 
 in     - the input signal.
 
-> withSC3 (\fd -> do send fd (b_alloc 10 512 1)
->                    wait fd "/done"
->                    send fd (b_gen 10 "cheby" [0, 1, 0, 1, 1, 0, 1])
->                    wait fd "/done")
-> audition (out 0 (shaper 10 (sinOsc AR 300 0 * line KR 0 1 6 RemoveSynth) * 0.5))
+> let s = sinOsc AR 300 0 * line KR 0 1 6 RemoveSynth
+> in withSC3 (\fd -> do { async fd (b_alloc 10 512 1)
+>                       ; async fd (b_gen 10 "cheby" [0, 1, 0, 1, 1, 0, 1])
+>                       ; audition (out 0 (shaper 10 s * 0.5)) })
diff --git a/Help/UGen/Filter/sos.help.lhs b/Help/UGen/Filter/sos.help.lhs
--- a/Help/UGen/Filter/sos.help.lhs
+++ b/Help/UGen/Filter/sos.help.lhs
@@ -6,8 +6,8 @@
 
 Same as TwoPole
 
-> let theta = line KR (0.2 * pi) pi 5 RemoveSynth
->     rho = line KR 0.6 0.99 5 RemoveSynth
->     b1 = 2 * rho * cos theta
->     b2 = - (rho * rho)
-> audition (out 0 (sos (lfSaw AR 200 0 * 0.1) 1 0 0 b1 b2))
+> let { theta = line KR (0.2 * pi) pi 5 RemoveSynth
+>     ; rho = line KR 0.6 0.99 5 RemoveSynth
+>     ; b1 = 2 * rho * cos theta
+>     ; b2 = - (rho * rho) }
+> in audition (out 0 (sos (lfSaw AR 200 0 * 0.1) 1 0 0 b1 b2))
diff --git a/Help/UGen/Filter/twoPole.help.lhs b/Help/UGen/Filter/twoPole.help.lhs
--- a/Help/UGen/Filter/twoPole.help.lhs
+++ b/Help/UGen/Filter/twoPole.help.lhs
@@ -4,9 +4,9 @@
 access to setting of pole location.  For general purposes Resonz is
 better.
 
-> n <- whiteNoise AR
-> audition (out 0 (twoPole (n * 0.005) 2000 0.95))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (twoPole (n * 0.005) 2000 0.95)) }
 
-> n <- whiteNoise AR
-> let f = xLine KR 800 8000 8 RemoveSynth
-> audition (out 0 (twoPole (n * 0.005) f 0.95))
+> do { n <- whiteNoise AR
+>    ; let f = xLine KR 800 8000 8 RemoveSynth
+>      in audition (out 0 (twoPole (n * 0.005) f 0.95)) }
diff --git a/Help/UGen/Filter/twoZero.help.lhs b/Help/UGen/Filter/twoZero.help.lhs
--- a/Help/UGen/Filter/twoZero.help.lhs
+++ b/Help/UGen/Filter/twoZero.help.lhs
@@ -2,5 +2,6 @@
 
 Two zero filter
 
-> n <- whiteNoise AR
-> audition (out 0 (twoZero (n * 0.125) (xLine KR 20 20000 8 RemoveSynth) 1))
+> do { n <- whiteNoise AR
+>    ; let f = xLine KR 20 20000 8 RemoveSynth
+>      in audition (out 0 (twoZero (n * 0.125) f 1)) }
diff --git a/Help/UGen/Filter/wrapIndex.help.lhs b/Help/UGen/Filter/wrapIndex.help.lhs
--- a/Help/UGen/Filter/wrapIndex.help.lhs
+++ b/Help/UGen/Filter/wrapIndex.help.lhs
@@ -9,10 +9,9 @@
 bufnum - index of the buffer
 in     - the input signal.
 
-> withSC3 (\fd -> do send fd (b_alloc 0 6 1)
->                    wait fd "/done"
->                    send fd (b_setn 0 [(0, [200, 300, 400, 500, 600, 800])]))
+> withSC3 (\fd -> do { async fd (b_alloc 0 6 1)
+>                    ; send fd (b_setn 0 [(0, [200, 300, 400, 500, 600, 800])]) })
 
-> let x = mouseX KR 0 18 Linear 0.1
->     f = wrapIndex 0 x
-> audition (out 0 (sinOsc AR f 0 * 0.5))
+> let { x = mouseX KR 0 18 Linear 0.1
+>     ; f = wrapIndex 0 x }
+> in audition (out 0 (sinOsc AR f 0 * 0.5))
diff --git a/Help/UGen/Granular/grainBuf.help.lhs b/Help/UGen/Granular/grainBuf.help.lhs
--- a/Help/UGen/Granular/grainBuf.help.lhs
+++ b/Help/UGen/Granular/grainBuf.help.lhs
@@ -29,14 +29,14 @@
 envb - the buffer number containing a singal to use for the
        grain envelope. -1 uses a built-in Hanning envelope.
 
-> withSC3 (\fd -> send fd (b_allocRead 10 "/home/rohan/audio/metal.wav" 0 0))
-> n1 <- lfNoise1 KR 500
-> n2 <- lfNoise2 KR 0.1
-> let b = 10
->     e = -1
->     x = mouseX KR (-1) 1 Linear 0.1
->     y = mouseY KR 10 45 Linear 0.1
->     i = impulse KR y 0
->     r = linLin n1 (-1) 1 0.5 2
->     p = linLin n2 (-1) 1 0 1
-> audition (out 0 (grainBuf 2 i 0.1 b r p 2 x e))
+> do { withSC3 (\fd -> send fd (b_allocRead 10 "/home/rohan/audio/metal.wav" 0 0))
+>    ; n1 <- lfNoise1 KR 500
+>    ; n2 <- lfNoise2 KR 0.1
+>    ; let { b = 10
+>          ; e = -1
+>          ; x = mouseX KR (-1) 1 Linear 0.1
+>          ; y = mouseY KR 10 45 Linear 0.1
+>          ; i = impulse KR y 0
+>          ; r = linLin n1 (-1) 1 0.5 2
+>          ; p = linLin n2 (-1) 1 0 1 }
+>      in audition (out 0 (grainBuf 2 i 0.1 b r p 2 x e)) }
diff --git a/Help/UGen/Granular/grainFM.help.lhs b/Help/UGen/Granular/grainFM.help.lhs
--- a/Help/UGen/Granular/grainFM.help.lhs
+++ b/Help/UGen/Granular/grainFM.help.lhs
@@ -26,11 +26,11 @@
 envbuf - the buffer number containing a singal to use for the grain
          envelope. -1 uses a built-in Hanning envelope.
 
-> n1 <- whiteNoise KR
-> n2 <- lfNoise1 KR 500
-> let x = mouseX KR (-0.5) 0.5 Linear 0.1
->     y = mouseY KR 0 400 Linear 0.1
->     f = n1 * y + 440
->     t = impulse KR 10 0
->     i = linLin n2 (-1) 1 1 10
-> audition (out 0 (grainFM 2 t 0.1 f 200 i x (-1) * 0.1))
+> do { n1 <- whiteNoise KR
+>    ; n2 <- lfNoise1 KR 500
+>    ; let { x = mouseX KR (-0.5) 0.5 Linear 0.1
+>          ; y = mouseY KR 0 400 Linear 0.1
+>          ; f = n1 * y + 440
+>          ; t = impulse KR 10 0 
+>          ; i = linLin n2 (-1) 1 1 10 }
+>      in audition (out 0 (grainFM 2 t 0.1 f 200 i x (-1) * 0.1)) }
diff --git a/Help/UGen/Granular/grainIn.help.lhs b/Help/UGen/Granular/grainIn.help.lhs
--- a/Help/UGen/Granular/grainIn.help.lhs
+++ b/Help/UGen/Granular/grainIn.help.lhs
@@ -20,8 +20,9 @@
 envbuf - the buffer number containing a singal to use for the
          grain envelope. -1 uses a built-in Hanning envelope.
 
-> n <- pinkNoise AR
-> let x = mouseX KR (-0.5) 0.5 Linear 0.1
->     y = mouseY KR 5 25 Linear 0.1
->     t = impulse KR y 0
-> audition (out 0 (grainIn 2 t 0.1 n x (-1) * 0.1))
+> do { n <- pinkNoise AR
+>    ; let { x = mouseX KR (-0.5) 0.5 Linear 0.1
+>          ; y = mouseY KR 5 25 Linear 0.1
+>          ; t = impulse KR y 0 
+>          ; g = grainIn 2 t 0.1 n x (-1) * 0.1 }
+>      in audition (out 0 g) }
diff --git a/Help/UGen/Granular/grainSin.help.lhs b/Help/UGen/Granular/grainSin.help.lhs
--- a/Help/UGen/Granular/grainSin.help.lhs
+++ b/Help/UGen/Granular/grainSin.help.lhs
@@ -20,9 +20,9 @@
 envbuf - the buffer number containing a singal to use for the grain
          envelope. -1 uses a built-in Hanning envelope.
 
-> n <- whiteNoise KR
-> let x = mouseX KR (-0.5) 0.5 Linear 0.1
->     y = mouseY KR 0 400 Linear 0.1
->     f = n * y + 440
->     t = impulse KR 10 0
-> audition (out 0 (grainSin 2 t 0.1 f x (-1) * 0.1))
+> do { n <- whiteNoise KR
+>    ; let { x = mouseX KR (-0.5) 0.5 Linear 0.1
+>          ; y = mouseY KR 0 400 Linear 0.1
+>          ; f = n * y + 440
+>          ; t = impulse KR 10 0 }
+>      in audition (out 0 (grainSin 2 t 0.1 f x (-1) * 0.1)) }
diff --git a/Help/UGen/Granular/warp1.help.lhs b/Help/UGen/Granular/warp1.help.lhs
--- a/Help/UGen/Granular/warp1.help.lhs
+++ b/Help/UGen/Granular/warp1.help.lhs
@@ -33,8 +33,8 @@
          = no interpolation. 2 = linear. 4 = cubic interpolation
          (more computationally intensive).
 
-> withSC3 (\fd -> send fd (b_allocRead 10 "/home/rohan/audio/metal.wav" 0 0))
-> let p = linLin (lfSaw KR 0.05 0) (-1) 1 0 1
->     x = mouseX KR 0.5 2 Linear 0.1
->     w = warp1 1 10 p x 0.1 (-1) 8 0.1 2
-> audition (out 0 w)
+> do { withSC3 (\fd -> send fd (b_allocRead 10 "/home/rohan/audio/metal.wav" 0 0))
+>    ; let { p = linLin (lfSaw KR 0.05 0) (-1) 1 0 1
+>          ; x = mouseX KR 0.5 2 Linear 0.1
+>          ; w = warp1 1 10 p x 0.1 (-1) 8 0.1 2 }
+>      in audition (out 0 w) }
diff --git a/Help/UGen/IO/in.help.lhs b/Help/UGen/IO/in.help.lhs
--- a/Help/UGen/IO/in.help.lhs
+++ b/Help/UGen/IO/in.help.lhs
@@ -8,16 +8,16 @@
 
 Patching input to output, with delay.
 
-> let i = in' 2 AR numOutputBuses
->     d = delayN i 0.5 0.5
-> audition (out 0 (i + d))
+> let { i = in' 2 AR numOutputBuses
+>     ; d = delayN i 0.5 0.5 }
+> in audition (out 0 (i + d))
 
-Write noise to bus 10, then read it out.  The MRG is ordered.
+Write noise to bus 10, then read it out.  The multiple root graph is ordered.
 
-> n <- pinkNoise AR
-> let wr = out 10 (n * 0.3)
->     rd = out 0 (in' 1 AR 10)
-> audition (MRG [rd, wr])
+> do { n <- pinkNoise AR
+>    ; let { wr = out 10 (n * 0.3)
+>          ; rd = out 0 (in' 1 AR 10) }
+>      in audition (mrg [rd, wr]) }
 
 Reading a control bus.
 
diff --git a/Help/UGen/IO/inFeedback.help.lhs b/Help/UGen/IO/inFeedback.help.lhs
--- a/Help/UGen/IO/inFeedback.help.lhs
+++ b/Help/UGen/IO/inFeedback.help.lhs
@@ -25,34 +25,34 @@
 
 Audio feedback modulation.
 
-> let f = inFeedback 1 0 * 1300 + 300
->     s = sinOsc AR f 0 * 0.4
-> audition (out 0 s)
+> let { f = inFeedback 1 0 * 1300 + 300
+>     ; s = sinOsc AR f 0 * 0.4 }
+> in audition (out 0 s)
 
 Evaluate these in either order and hear both tones.
 
-> let b = numInputBuses + numOutputBuses
->     s = inFeedback 1 b
-> audition (out 0 s)
+> let { b = numInputBuses + numOutputBuses
+>     ; s = inFeedback 1 b }
+> in audition (out 0 s)
 
-> let b  = numInputBuses + numOutputBuses
->     s0 = out b (sinOsc AR 220 0 * 0.1)
->     s1 = out 0 (sinOsc AR 660 0 * 0.1)
-> audition (MRG [s0, s1])
+> let { b  = numInputBuses + numOutputBuses
+>     ; s0 = out b (sinOsc AR 220 0 * 0.1)
+>     ; s1 = out 0 (sinOsc AR 660 0 * 0.1) }
+> in audition (mrg [s0, s1])
 
 Doubters consult this.
 
-> let b = numInputBuses + numOutputBuses
->     s = in' 1 AR b
-> audition (out 0 s)
+> let { b = numInputBuses + numOutputBuses
+>     ; s = in' 1 AR b }
+> in audition (out 0 s)
 
 Resonator, see localOut for variant.
 
-> let b = numInputBuses + numOutputBuses
->     p = inFeedback 1 b
->     i = impulse AR 1 0
->     d = delayC (i + (p * 0.995)) 1 (recip 440 - recip controlRate)
-> audition (MRG [offsetOut b d, offsetOut 0 p])
+> let { b = numInputBuses + numOutputBuses
+>     ; p = inFeedback 1 b
+>     ; i = impulse AR 1 0
+>     ; d = delayC (i + (p * 0.995)) 1 (recip 440 - recip controlRate) }
+> in audition (mrg [offsetOut b d, offsetOut 0 p])
 
 Compare with oscillator.
 
diff --git a/Help/UGen/IO/inTrig.help.lhs b/Help/UGen/IO/inTrig.help.lhs
--- a/Help/UGen/IO/inTrig.help.lhs
+++ b/Help/UGen/IO/inTrig.help.lhs
@@ -8,11 +8,11 @@
 
 Run an oscillator with the trigger at bus 10.
 
-> let t = inTrig 1 10
->     e = envGen KR t t 0 1 DoNothing envPerc'
-> audition (out 0 (sinOsc AR 440 0 * e))
+> let { t = inTrig 1 10
+>     ; e = envGen KR t t 0 1 DoNothing (envPerc 0.01 1) }
+> in audition (out 0 (sinOsc AR 440 0 * e))
 
 Set bus 10, each set will trigger a ping.
 
 > let c_set1 i n = c_set [(i,n)]
-> withSC3 (\fd -> send fd (c_set1 10 0.1))
+> in withSC3 (\fd -> send fd (c_set1 10 0.1))
diff --git a/Help/UGen/IO/lagIn.lhs b/Help/UGen/IO/lagIn.lhs
--- a/Help/UGen/IO/lagIn.lhs
+++ b/Help/UGen/IO/lagIn.lhs
@@ -2,7 +2,7 @@
 
 Smooth a control rate input signal.
 
-> withSC3 (\fd -> do send fd (c_set [(10, 200)])
->                    play fd (sinOsc AR (lagIn 1 10 1) 0 * 0.1)
->                    threadDelay 500000
->                    send fd (c_set [(10, 2000)]))
+> 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/localIn.help.lhs b/Help/UGen/IO/localIn.help.lhs
--- a/Help/UGen/IO/localIn.help.lhs
+++ b/Help/UGen/IO/localIn.help.lhs
@@ -10,8 +10,9 @@
 only be one audio rate and one control rate LocalIn per SynthDef.  The
 audio can be written to the bus using LocalOut.
 
-> n <- whiteNoise AR
-> let a0 = decay (impulse AR 0.3 0) 0.1 * n * 0.2
->     a1 = localIn 2 AR + MCE [a0, 0]
->     a2 = delayN a1 0.2 0.2
-> audition (MRG [localOut (mceReverse a2 * 0.8), out 0 a2])
+> do { n <- whiteNoise AR
+>    ; let { a0 = decay (impulse AR 0.3 0) 0.1 * n * 0.2
+>          ; a1 = localIn 2 AR + mce [a0, 0]
+>          ; a2 = delayN a1 0.2 0.2 
+>          ; a3 = mceEdit reverse a2 * 0.8 }
+>      in audition (mrg [localOut a3, out 0 a2]) }
diff --git a/Help/UGen/IO/localOut.help.lhs b/Help/UGen/IO/localOut.help.lhs
--- a/Help/UGen/IO/localOut.help.lhs
+++ b/Help/UGen/IO/localOut.help.lhs
@@ -17,18 +17,19 @@
 20Hz), or where sample accurate alignment is required. See the
 resonator example below.
 
-> n <- whiteNoise AR
-> let a0 = decay (impulse AR 0.3 0) 0.1 * n * 0.2
->     a1 = localIn 2 AR + MCE [a0, 0]
->     a2 = delayN a1 0.2 0.2
-> audition (MRG [localOut (mceReverse a2 * 0.8), out 0 a2])
+> do { n <- whiteNoise AR
+>    ; let { a0 = decay (impulse AR 0.3 0) 0.1 * n * 0.2
+>          ; a1 = localIn 2 AR + mce [a0, 0]
+>          ; a2 = delayN a1 0.2 0.2
+>          ; a3 = mceEdit reverse a2 * 0.8 }
+>      in audition (mrg [localOut a3, out 0 a2]) }
 
 Resonator, must subtract blockSize for correct tuning
 
-> let p = localIn 1 AR
->     i = impulse AR 1 0
->     d = delayC (i + (p * 0.995)) 1 (recip 440 - recip controlRate)
-> audition (MRG [offsetOut 0 p, localOut d])
+> let { p = localIn 1 AR
+>     ; i = impulse AR 1 0
+>     ; d = delayC (i + (p * 0.995)) 1 (recip 440 - recip controlRate) }
+> in audition (mrg [offsetOut 0 p, localOut d])
 
 Compare with oscillator.
 
diff --git a/Help/UGen/IO/mouseX.help.lhs b/Help/UGen/IO/mouseX.help.lhs
--- a/Help/UGen/IO/mouseX.help.lhs
+++ b/Help/UGen/IO/mouseX.help.lhs
@@ -1,8 +1,7 @@
 mouseX rate minval maxval warp lag
 
-Cursor UGen
-
 Report mouse location on root window of the machine that the synthesis
 server is running on.
 
-> audition (out 0 (sinOsc AR (mouseX KR 40 10000 Exponential 0.2) 0 * 0.1))
+> let x = mouseX KR 40 10000 Exponential 0.2
+> in audition (out 0 (sinOsc AR x 0 * 0.1))
diff --git a/Help/UGen/IO/mouseY.help.lhs b/Help/UGen/IO/mouseY.help.lhs
--- a/Help/UGen/IO/mouseY.help.lhs
+++ b/Help/UGen/IO/mouseY.help.lhs
@@ -3,6 +3,6 @@
 Report mouse location on root window of the machine that the
 synthesis server is running on.
 
-> let freq = mouseX KR 20 2000 Exponential 0.1
-> let ampl = mouseY KR 0.01 0.1 Linear 0.1
-> audition (out 0 (sinOsc AR freq 0 * ampl))
+> let { freq = mouseX KR 20 2000 Exponential 0.1
+>     ; ampl = mouseY KR 0.01 0.1 Linear 0.1 }
+> in audition (out 0 (sinOsc AR freq 0 * ampl))
diff --git a/Help/UGen/IO/offsetOut.help.lhs b/Help/UGen/IO/offsetOut.help.lhs
--- a/Help/UGen/IO/offsetOut.help.lhs
+++ b/Help/UGen/IO/offsetOut.help.lhs
@@ -3,10 +3,10 @@
 Output signal to a bus, the sample offset within the bus is kept
 exactly.  This ugen is used where sample accurate output is needed.
 
-> let a = offsetOut 0 (impulse AR 5 0)
->     b = out 0 (sinOsc AR 60 0 * 0.1)
-> audition (MRG [a,b])
+> let { a = offsetOut 0 (impulse AR 5 0)
+>     ; b = out 0 (sinOsc AR 60 0 * 0.1) }
+> in audition (mrg [a, b])
 
-> let a = out 0 (impulse AR 5 0)
->     b = out 0 (sinOsc AR 60 0 * 0.1)
-> audition (MRG [a,b])
+> let { a = out 0 (impulse AR 5 0)
+>     ; b = out 0 (sinOsc AR 60 0 * 0.1) }
+> in audition (mrg [a, b])
diff --git a/Help/UGen/IO/out.help.lhs b/Help/UGen/IO/out.help.lhs
--- a/Help/UGen/IO/out.help.lhs
+++ b/Help/UGen/IO/out.help.lhs
@@ -4,4 +4,4 @@
 The user is responsible for making sure that the number of channels
 match and that there are no conflicts.
 
-> audition (out 0 (sinOsc AR (MCE [330, 331]) 0 * 0.1))
+> audition (out 0 (sinOsc AR (mce [330, 331]) 0 * 0.1))
diff --git a/Help/UGen/IO/replaceOut.help.lhs b/Help/UGen/IO/replaceOut.help.lhs
--- a/Help/UGen/IO/replaceOut.help.lhs
+++ b/Help/UGen/IO/replaceOut.help.lhs
@@ -2,14 +2,14 @@
 
 Send signal to a bus, overwrite existing signal.
 
-> let a = out 0 (sinOsc AR (MCE [330, 331]) 0 * 0.1)
->     b = replaceOut 0 (sinOsc AR (MCE [880, 881]) 0 * 0.1)
->     c = out 0 (sinOsc AR (MCE [120, 121]) 0 * 0.1)
-> audition (MRG [a, b, c])
+> let { a = out 0 (sinOsc AR (mce [330, 331]) 0 * 0.1)
+>     ; b = replaceOut 0 (sinOsc AR (mce [880, 881]) 0 * 0.1)
+>     ; c = out 0 (sinOsc AR (mce [120, 121]) 0 * 0.1) }
+> in audition (mrg [a, b, c])
 
 Compare to:
 
-> let a = out 0 (sinOsc AR (MCE [330, 331]) 0 * 0.1)
->     b = out 0 (sinOsc AR (MCE [880, 881]) 0 * 0.1)
->     c = out 0 (sinOsc AR (MCE [120, 121]) 0 * 0.1)
-> audition (MRG [a, b, c])
+> let { a = out 0 (sinOsc AR (mce [330, 331]) 0 * 0.1)
+>     ; b = out 0 (sinOsc AR (mce [880, 881]) 0 * 0.1)
+>     ; c = out 0 (sinOsc AR (mce [120, 121]) 0 * 0.1) }
+> in audition (mrg [a, b, c])
diff --git a/Help/UGen/IO/xOut.help.lhs b/Help/UGen/IO/xOut.help.lhs
--- a/Help/UGen/IO/xOut.help.lhs
+++ b/Help/UGen/IO/xOut.help.lhs
@@ -2,10 +2,10 @@
  
 Send signal to a bus, crossfading with existing contents.
 
-> let p a b = sinOsc AR (MCE [a, b]) 0 * 0.1
->     x     = mouseX KR 0 1 Linear 0.1
->     y     = mouseY KR 0 1 Linear 0.1
-> audition (MRG [ out  0   (p 220 221)
->               , xOut 0 x (p 330 331)
->               , xOut 0 y (p 440 441)
->               , out  0   (p 120 121)])
+> let { p a b = sinOsc AR (mce [a, b]) 0 * 0.1
+>     ; x = mouseX KR 0 1 Linear 0.1
+>     ; y = mouseY KR 0 1 Linear 0.1 }
+> in audition (mrg [ out  0   (p 220 221)
+>                  , xOut 0 x (p 330 331)
+>                  , xOut 0 y (p 440 441)
+>                  , out  0   (p 120 121)])
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
@@ -4,5 +4,5 @@
 
 Compare a sine tone derived from sample rate with a 440Hz tone.
 
-> let f = MCE [sampleRate * 0.01, 440]
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> let f = mce [sampleRate * 0.01, 440]
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Information/subsampleOffset.help.lhs b/Help/UGen/Information/subsampleOffset.help.lhs
--- a/Help/UGen/Information/subsampleOffset.help.lhs
+++ b/Help/UGen/Information/subsampleOffset.help.lhs
@@ -18,18 +18,18 @@
 impulses are adjacent, on the right, they are exactly 1 sample apart.
 View this with an oscilloscope.
 
-> let a = Control KR "a" 0
->     i = impulse AR 2000 0 * 0.3
->     d = sampleDur
->     x = 4
->     o = (1 - subsampleOffset) + mouseX KR 0 a Linear 0.1
->     r = delayC i (d * (1 + x)) (d * (o + x))
->     g = offsetOut 0 r
-> withSC3 (\fd -> do send fd (d_recv (graphdef "s" (graph g)))
->                    wait fd "/done"
->                    t <- utc
->                    let t' = t + 0.2
->                        dt = 1 / 44100.0
->                        m n = s_new "s" (-1) AddToTail 1 [("a", n)]
->                    send fd (Bundle t' [m 3])
->                    send fd (Bundle (t' + dt) [m 0]))
+> let { a = control KR "a" 0
+>     ; i = impulse AR 2000 0 * 0.3
+>     ; d = sampleDur
+>     ; x = 4
+>     ; o = (1 - subsampleOffset) + mouseX KR 0 a Linear 0.1
+>     ; r = delayC i (d * (1 + x)) (d * (o + x))
+>     ; g = offsetOut 0 r }
+> in withSC3 (\fd -> do { async fd (d_recv (graphdef "s" (graph g)))
+>                       ; t <- utc
+>                       ; let { t' = t + 0.2
+>                             ; dt = 1 / 44100.0
+>                             ; m n = s_new "s" (-1) AddToTail 1 [("a", n)] }
+>                         in do { send fd (Bundle t' [m 3])
+>                                 ; send fd (Bundle (t' + dt) [m 0]) } })
+
diff --git a/Help/UGen/Math/amClip.help.lhs b/Help/UGen/Math/amClip.help.lhs
--- a/Help/UGen/Math/amClip.help.lhs
+++ b/Help/UGen/Math/amClip.help.lhs
@@ -2,5 +2,5 @@
 
 0 when b <= 0, a*b when b > 0
 
-> n <- whiteNoise AR
-> audition (out 0 (amClip n (fSinOsc KR 1 0 * 0.2)))
+> do { n <- whiteNoise AR
+>    ; audition (out 0 (amClip n (fSinOsc KR 1 0 * 0.2))) }
diff --git a/Help/UGen/Math/atan2.help.lhs b/Help/UGen/Math/atan2.help.lhs
--- a/Help/UGen/Math/atan2.help.lhs
+++ b/Help/UGen/Math/atan2.help.lhs
@@ -8,11 +8,11 @@
 azimuth, or direction angle, of the sound source.  Assume speakers
 at +/- 45 degrees and clip the direction to between those.
 
-> let x = 10
->     y = lfSaw KR (1 / 6) 0 * 100
->     d = hypot x y
->     a = 40 / (squared d)
->     s = rlpf (fSinOsc AR 200 0 * lfPulse AR 31.3 0 0.4) 400 0.3
->     z = Sound.SC3.atan2 y x
->     l = clip2 (z / (pi / 2)) 1
-> audition (out 0 (pan2 (delayL s (110 / 344) (d / 344)) l a))
+> let { x = 10
+>     ; y = lfSaw KR (1 / 6) 0 * 100
+>     ; d = hypot x y
+>     ; a = 40 / (squared d)
+>     ; s = rlpf (fSinOsc AR 200 0 * lfPulse AR 31.3 0 0.4) 400 0.3
+>     ; z = atan2E y x
+>     ; l = clip2 (z / (pi / 2)) 1 }
+> in audition (out 0 (pan2 (delayL s (110 / 344) (d / 344)) l a))
diff --git a/Help/UGen/Math/difSqr.help.lhs b/Help/UGen/Math/difSqr.help.lhs
--- a/Help/UGen/Math/difSqr.help.lhs
+++ b/Help/UGen/Math/difSqr.help.lhs
@@ -4,12 +4,12 @@
 more efficient than using separate unit generators for each
 operation.
 
-> let a = fSinOsc AR 800 0
->     b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
-> audition (out 0 (difSqr a b * 0.125))
+> let { a = fSinOsc AR 800 0
+>     ; b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0 }
+> in audition (out 0 (difSqr a b * 0.125))
 
 Written out:
 
-> let a = fSinOsc AR 800 0
->     b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
-> audition (out 0 ((a * a - b * b) * 0.125))
+> let { a = fSinOsc AR 800 0
+>     ; b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0 }
+> in audition (out 0 ((a * a - b * b) * 0.125))
diff --git a/Help/UGen/Math/distort.help.lhs b/Help/UGen/Math/distort.help.lhs
--- a/Help/UGen/Math/distort.help.lhs
+++ b/Help/UGen/Math/distort.help.lhs
@@ -2,6 +2,6 @@
 
 Nonlinear distortion.
 
-> let e = xLine KR 0.1 10 10 DoNothing
->     o = fSinOsc AR 500 0.0
-> audition (out 0 (distort (o * e) * 0.25))
+> let { e = xLine KR 0.1 10 10 DoNothing
+>     ; o = fSinOsc AR 500 0.0 }
+> in audition (out 0 (distort (o * e) * 0.25))
diff --git a/Help/UGen/Math/hypot.help.lhs b/Help/UGen/Math/hypot.help.lhs
--- a/Help/UGen/Math/hypot.help.lhs
+++ b/Help/UGen/Math/hypot.help.lhs
@@ -3,24 +3,24 @@
 Returns the square root of the sum of the squares of a and b. Or
 equivalently, the distance from the origin to the point (x, y).
 
-> let x = mouseX KR 0 0.1 Linear 0.1
->     y = mouseY KR 0 0.1 Linear 0.1
-> audition (out 0 (sinOsc AR 440 0 * hypot x y))
+> let { x = mouseX KR 0 0.1 Linear 0.1
+>     ; y = mouseY KR 0 0.1 Linear 0.1 }
+> in audition (out 0 (sinOsc AR 440 0 * hypot x y))
 
 Object travels 200 meters in 6 secs (=120kph) passing 10 meters
 from the listener.  The speed of sound is 344 meters/sec.
 
-> let x = 10
->     y = lfSaw KR (1 / 6) 0 * 100
->     d = hypot x y
->     v = slope d
->     r = (344 - v) / 344
->     a = 10 / (squared d)
-> audition (out 0 (fSinOsc AR (1000 * r) 0 * a))
+> let { x = 10
+>     ; y = lfSaw KR (1 / 6) 0 * 100
+>     ; d = hypot x y
+>     ; v = slope d
+>     ; r = (344 - v) / 344
+>     ; a = 10 / (squared d) }
+> in audition (out 0 (fSinOsc AR (1000 * r) 0 * a))
 
-> let x = 10
->     y = lfSaw KR (1 / 6) 0 * 100
->     d = hypot x y
->     a = 40 / (squared d)
->     s = rlpf (fSinOsc AR 200 0 * lfPulse AR 31.3 0 0.4) 400 0.3
-> audition (out 0 (delayL s (110 / 344) (d / 344) * a))
+> let { x = 10
+>     ; y = lfSaw KR (1 / 6) 0 * 100
+>     ; d = hypot x y
+>     ; a = 40 / (squared d)
+>     ; s = rlpf (fSinOsc AR 200 0 * lfPulse AR 31.3 0 0.4) 400 0.3 }
+> in audition (out 0 (delayL s (110 / 344) (d / 344) * a))
diff --git a/Help/UGen/Math/ring1.help.lhs b/Help/UGen/Math/ring1.help.lhs
--- a/Help/UGen/Math/ring1.help.lhs
+++ b/Help/UGen/Math/ring1.help.lhs
@@ -6,6 +6,6 @@
 
 See also Mul, Ring1, Ring2, Ring3, Ring4.
 
-> let a = fSinOsc AR 800 0
->     b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
-> audition (out 0 (ring1 a b * 0.125))
+> let { a = fSinOsc AR 800 0
+>     ; b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0 }
+> in audition (out 0 (ring1 a b * 0.125))
diff --git a/Help/UGen/Math/softClip.help.lhs b/Help/UGen/Math/softClip.help.lhs
--- a/Help/UGen/Math/softClip.help.lhs
+++ b/Help/UGen/Math/softClip.help.lhs
@@ -3,6 +3,6 @@
 Nonlinear distortion.  Distortion with a perfectly linear region
 from -0.5 to +0.5.
 
-> let e = xLine KR 0.1 10 10 DoNothing
->     o = fSinOsc AR 500 0.0
-> audition (out 0 (softClip (o * e) * 0.25))
+> let { e = xLine KR 0.1 10 10 DoNothing
+>     ; o = fSinOsc AR 500 0.0 }
+> in audition (out 0 (softClip (o * e) * 0.25))
diff --git a/Help/UGen/Math/sumSqr.help.lhs b/Help/UGen/Math/sumSqr.help.lhs
--- a/Help/UGen/Math/sumSqr.help.lhs
+++ b/Help/UGen/Math/sumSqr.help.lhs
@@ -3,12 +3,12 @@
 Return the value of (a*a) + (b*b). This is more efficient than
 using separate unit generators for each operation.
 
-> let a = fSinOsc AR 800 0
->     b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
-> audition (out 0 (sumSqr a b * 0.125))
+> let { a = fSinOsc AR 800 0
+>     ; b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0 }
+> in audition (out 0 (sumSqr a b * 0.125))
 
 Written out:
 
-> let a = fSinOsc AR 800 0
->     b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
-> audition (out 0 ((a * a + b * b) * 0.125))
+> let { a = fSinOsc AR 800 0
+>     ; b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0 }
+> in audition (out 0 ((a * a + b * b) * 0.125))
diff --git a/Help/UGen/Math/thresh.help.lhs b/Help/UGen/Math/thresh.help.lhs
--- a/Help/UGen/Math/thresh.help.lhs
+++ b/Help/UGen/Math/thresh.help.lhs
@@ -2,5 +2,5 @@
 
 Signal thresholding.  0 when a < b, otherwise a.
 
-> n <- lfNoise0 AR 50
-> audition (out 0 (thresh (n * 0.5) 0.45))
+> do { n <- lfNoise0 AR 50
+>    ; audition (out 0 (thresh (n * 0.5) 0.45)) }
diff --git a/Help/UGen/Noise/brownNoise.help.lhs b/Help/UGen/Noise/brownNoise.help.lhs
--- a/Help/UGen/Noise/brownNoise.help.lhs
+++ b/Help/UGen/Noise/brownNoise.help.lhs
@@ -3,10 +3,11 @@
 Generates noise whose spectrum falls off in power by 6 dB per
 octave.
 
-> n <- brownNoise AR
-> audition (out 0 (n * 0.1))
+> do { n <- brownNoise AR
+>    ; audition (out 0 (n * 0.1)) }
 
 > audition . (out 0) . (* 0.1) =<< whiteNoise AR
 
-> n <- brownNoise KR
-> audition (out 0 (sinOsc AR (linExp n (-1) 1 64 9600) 0 * 0.1))
+> do { n <- brownNoise KR
+>    ; let o = sinOsc AR (linExp n (-1) 1 64 9600) 0 * 0.1
+>      in audition (out 0 o) }
diff --git a/Help/UGen/Noise/coinGate.help.lhs b/Help/UGen/Noise/coinGate.help.lhs
--- a/Help/UGen/Noise/coinGate.help.lhs
+++ b/Help/UGen/Noise/coinGate.help.lhs
@@ -3,6 +3,6 @@
 When it receives a trigger, it tosses a coin, and either passes the
 trigger or doesn't.
 
-> g <- coinGate 0.2 (impulse KR 10 0)
-> f <- tRand 300.0 400.0 g
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> do { g <- coinGate 0.2 (impulse KR 10 0)
+>    ; f <- tRand 300.0 400.0 g
+>    ; audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Noise/dust.help.lhs b/Help/UGen/Noise/dust.help.lhs
--- a/Help/UGen/Noise/dust.help.lhs
+++ b/Help/UGen/Noise/dust.help.lhs
@@ -6,4 +6,4 @@
 > audition . (out 0) . (* 0.25) =<< dust AR 200
 
 > let d = xLine KR 20000 2 10 RemoveSynth
-> audition . (out 0) . (* 0.15) =<< dust AR d
+> in audition . (out 0) . (* 0.15) =<< dust AR d
diff --git a/Help/UGen/Noise/dust2.help.lhs b/Help/UGen/Noise/dust2.help.lhs
--- a/Help/UGen/Noise/dust2.help.lhs
+++ b/Help/UGen/Noise/dust2.help.lhs
@@ -3,8 +3,8 @@
 Generates random impulses from -1 to +1.  The `density' is in
 impulses per second.
 
-> n <- dust2 AR 200
-> audition (out 0 (n * 0.5))
+> do { n <- dust2 AR 200
+>    ; audition (out 0 (n * 0.5)) }
 
 > let d = xLine KR 20000 2 10 RemoveSynth
-> audition . (out 0 ) . (* 0.15) =<< dust2 AR d
+> in audition . (out 0 ) . (* 0.15) =<< dust2 AR d
diff --git a/Help/UGen/Noise/expRand.help.lhs b/Help/UGen/Noise/expRand.help.lhs
--- a/Help/UGen/Noise/expRand.help.lhs
+++ b/Help/UGen/Noise/expRand.help.lhs
@@ -4,5 +4,5 @@
 distributions from `lo' to `hi'.
 
 > let a = line KR 0.5 0 0.01 RemoveSynth
-> f <- expRand 100.0 8000.0
-> audition (out 0 (fSinOsc AR f 0 * a))
+> in do { f <- expRand 100.0 8000.0
+>       ; audition (out 0 (fSinOsc AR f 0 * a)) }
diff --git a/Help/UGen/Noise/iRand.help.lhs b/Help/UGen/Noise/iRand.help.lhs
--- a/Help/UGen/Noise/iRand.help.lhs
+++ b/Help/UGen/Noise/iRand.help.lhs
@@ -3,5 +3,6 @@
 Generates a single random integer value in uniform distribution
 from `lo' to `hi'.
 
-> f <- iRand 200 1200
-> audition (out 0 (fSinOsc AR f 0 * (line KR 0.2 0 0.1 RemoveSynth)))
+> do { f <- iRand 200 1200
+>      ; let e = line KR 0.2 0 0.1 RemoveSynth
+>        in audition (out 0 (fSinOsc AR f 0 * e)) }
diff --git a/Help/UGen/Noise/lfClipNoise.help.lhs b/Help/UGen/Noise/lfClipNoise.help.lhs
--- a/Help/UGen/Noise/lfClipNoise.help.lhs
+++ b/Help/UGen/Noise/lfClipNoise.help.lhs
@@ -10,9 +10,9 @@
 Modulate frequency
 
 > let f = xLine KR 1000 10000 10 RemoveSynth
-> audition . (out 0) . (* 0.05) =<< lfClipNoise AR f
+> in audition . (out 0) . (* 0.05) =<< lfClipNoise AR f
 
 Use as frequency control
 
-> n <- lfClipNoise KR 4 
-> audition (out 0 (sinOsc AR (n * 200 + 600) 0 * 0.1))
+> do { n <- lfClipNoise KR 4 
+>    ; audition (out 0 (sinOsc AR (n * 200 + 600) 0 * 0.1)) }
diff --git a/Help/UGen/Noise/lfNoise0.help.lhs b/Help/UGen/Noise/lfNoise0.help.lhs
--- a/Help/UGen/Noise/lfNoise0.help.lhs
+++ b/Help/UGen/Noise/lfNoise0.help.lhs
@@ -8,8 +8,8 @@
 Modulate frequency.
 
 > let f = xLine KR 1000 10000 10 RemoveSynth
-> n <- lfNoise0 AR f
-> audition (out 0 (n * 0.05))
+> in do { n <- lfNoise0 AR f
+>       ; audition (out 0 (n * 0.05)) }
 
 Use as frequency control.
 
diff --git a/Help/UGen/Noise/lfNoise1.help.lhs b/Help/UGen/Noise/lfNoise1.help.lhs
--- a/Help/UGen/Noise/lfNoise1.help.lhs
+++ b/Help/UGen/Noise/lfNoise1.help.lhs
@@ -11,10 +11,11 @@
 Modulate frequency.
 
 > let f = xLine KR 1000 10000 10 RemoveSynth
-> n <- lfNoise1 AR f
-> audition (out 0 (n * 0.05))
+> in do { n <- lfNoise1 AR f
+>       ; audition (out 0 (n * 0.05)) }
 
 Use as frequency control.
 
-> f <- lfNoise1 KR 4 
-> audition (out 0 (sinOsc AR (f * 400 + 450) 0 * 0.1))
+> do { n <- lfNoise1 KR 4 
+>    ; let f = n * 400 + 450
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Noise/lfNoise2.help.lhs b/Help/UGen/Noise/lfNoise2.help.lhs
--- a/Help/UGen/Noise/lfNoise2.help.lhs
+++ b/Help/UGen/Noise/lfNoise2.help.lhs
@@ -9,10 +9,10 @@
 Modulate frequency.
 
 > let f = xLine KR 1000 10000 10 RemoveSynth
-> n <- lfNoise2 AR f
-> audition (out 0 (n * 0.05))
+> in do { n <- lfNoise2 AR f
+>       ; audition (out 0 (n * 0.05)) }
 
 Use as frequency control.
 
-> f <- lfNoise2 KR 4 
-> audition (out 0 (sinOsc AR (f * 400 + 450) 0 * 0.1))
+> do { f <- lfNoise2 KR 4 
+>    ; audition (out 0 (sinOsc AR (f * 400 + 450) 0 * 0.1)) }
diff --git a/Help/UGen/Noise/lfdClipNoise.help.lhs b/Help/UGen/Noise/lfdClipNoise.help.lhs
--- a/Help/UGen/Noise/lfdClipNoise.help.lhs
+++ b/Help/UGen/Noise/lfdClipNoise.help.lhs
@@ -16,17 +16,17 @@
 lfdClipNoise changes smoothly.
 
 > let x = mouseX KR 0.1 1000 Exponential 0.2
-> n <- lfdClipNoise AR x
-> audition (out 0 (sinOsc AR (n * 200 + 500) 0 * 0.05))
+> in do { n <- lfdClipNoise AR x
+>       ; audition (out 0 (sinOsc AR (n * 200 + 500) 0 * 0.05)) }
 
 > let x = mouseX KR 0.1 1000 Exponential 0.2
-> n <- lfClipNoise AR x
-> audition (out 0 (sinOsc AR (n * 200 + 500) 0 * 0.05))
+> in do { n <- lfClipNoise AR x
+>       ; audition (out 0 (sinOsc AR (n * 200 + 500) 0 * 0.05)) }
 
 lfClipNoise quantizes time steps at high freqs, lfdClipNoise does not:
 
 > let f = xLine KR 1000 20000 10 RemoveSynth
-> audition . (out 0) . (* 0.05) =<< lfdClipNoise AR f
+> in audition . (out 0) . (* 0.05) =<< lfdClipNoise AR f
 
 > let f = xLine KR 1000 20000 10 RemoveSynth
-> audition . (out 0) . (* 0.05) =<< lfClipNoise AR f
+> in audition . (out 0) . (* 0.05) =<< lfClipNoise AR f
diff --git a/Help/UGen/Noise/lfdNoise0.help.lhs b/Help/UGen/Noise/lfdNoise0.help.lhs
--- a/Help/UGen/Noise/lfdNoise0.help.lhs
+++ b/Help/UGen/Noise/lfdNoise0.help.lhs
@@ -15,23 +15,23 @@
 LFDNoise changes smoothly.
 
 > let x = mouseX KR 0.1 1000 Exponential 0.2
-> audition . (out 0) . (* 0.1) =<< lfdNoise0 AR x
+> in audition . (out 0) . (* 0.1) =<< lfdNoise0 AR x
 
 > let x = mouseX KR 0.1 1000 Exponential 0.2
-> audition . (out 0) . (* 0.1) =<< lfNoise0 AR x
+> in audition . (out 0) . (* 0.1) =<< lfNoise0 AR x
 
 silent for 2 secs before going up in freq
 
 > let f = xLine KR 0.5 10000 3 RemoveSynth
-> audition . (out 0) . (* 0.1) =<< lfdNoise0 AR f
+> in audition . (out 0) . (* 0.1) =<< lfdNoise0 AR f
 
 > let f = xLine KR 0.5 10000 3 RemoveSynth
-> audition . (out 0) . (* 0.1) =<< lfNoise0 AR f
+> in audition . (out 0) . (* 0.1) =<< lfNoise0 AR f
 
 LFNoise quantizes time steps at high freqs, LFDNoise does not:
 
 > let f = xLine KR 1000 20000 10 RemoveSynth
-> audition . (out 0) . (* 0.1) =<< lfdNoise0 AR f
+> in audition . (out 0) . (* 0.1) =<< lfdNoise0 AR f
 
 > let f = xLine KR 1000 20000 10 RemoveSynth
-> audition . (out 0) . (* 0.1) =<< lfNoise0 AR f
+> in audition . (out 0) . (* 0.1) =<< lfNoise0 AR f
diff --git a/Help/UGen/Noise/linRand.help.lhs b/Help/UGen/Noise/linRand.help.lhs
--- a/Help/UGen/Noise/linRand.help.lhs
+++ b/Help/UGen/Noise/linRand.help.lhs
@@ -4,5 +4,6 @@
 lo to hi, skewed towards lo if minmax < 0, otherwise skewed towards
 hi.
 
-> f <- linRand 200.0 10000.0 (MCE [-1, 1])
-> audition (out 0 (fSinOsc AR f 0 * line KR 0.4 0 0.01 RemoveSynth))
+> do { f <- linRand 200.0 10000.0 (mce [-1, 1])
+>    ; let e = line KR 0.4 0 0.01 RemoveSynth
+>      in audition (out 0 (fSinOsc AR f 0 * e)) }
diff --git a/Help/UGen/Noise/nRand.help.lhs b/Help/UGen/Noise/nRand.help.lhs
--- a/Help/UGen/Noise/nRand.help.lhs
+++ b/Help/UGen/Noise/nRand.help.lhs
@@ -8,5 +8,6 @@
 n = 3 : smooth hump
 as n increases, distribution converges towards gaussian
 
-> n <- nRand 1200.0 4000.0 (MCE [2, 5])
-> audition (out 0 (fSinOsc AR n 0 * line KR 0.2 0 0.01 RemoveSynth))
+> do { n <- nRand 1200.0 4000.0 (mce [2, 5])
+>    ; let e = line KR 0.2 0 0.01 RemoveSynth
+>      in audition (out 0 (fSinOsc AR n 0 * e)) }
diff --git a/Help/UGen/Noise/rand.help.lhs b/Help/UGen/Noise/rand.help.lhs
--- a/Help/UGen/Noise/rand.help.lhs
+++ b/Help/UGen/Noise/rand.help.lhs
@@ -4,8 +4,8 @@
 hi.  It generates this when the SynthDef first starts playing, and
 remains fixed for the duration of the synth's existence.
 
-> f <- rand 200 1200
-> l <- rand (-1) 1
-> let e = line KR 0.2 0 0.1 RemoveSynth
->     o = fSinOsc AR f 0
-> audition (out 0 (pan2 (o * e) l 1))
+> do { f <- rand 200 1200
+>    ; l <- rand (-1) 1
+>    ; let { e = line KR 0.2 0 0.1 RemoveSynth
+>          ; o = fSinOsc AR f 0 }
+>      in audition (out 0 (pan2 (o * e) l 1)) }
diff --git a/Help/UGen/Noise/tExpRand.help.lhs b/Help/UGen/Noise/tExpRand.help.lhs
--- a/Help/UGen/Noise/tExpRand.help.lhs
+++ b/Help/UGen/Noise/tExpRand.help.lhs
@@ -5,5 +5,5 @@
 positive values lo and hi must both have the same sign and be
 non-zero.
 
-> f <- tExpRand 300.0 3000.0 =<< dust KR 10
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> do { f <- tExpRand 300.0 3000.0 =<< dust KR 10
+>    ; audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Noise/tRand.help.lhs b/Help/UGen/Noise/tRand.help.lhs
--- a/Help/UGen/Noise/tRand.help.lhs
+++ b/Help/UGen/Noise/tRand.help.lhs
@@ -3,5 +3,6 @@
 Generates a random float value in uniform distribution from lo each
 time the trig signal changes from nonpositive to positive values
 
-> f <- tRand (MCE [200, 1600]) (MCE [500, 3000]) =<< dust KR (MCE [5, 12])
-> audition (out 0 (sinOsc AR f 0 * 0.2))
+> do { t <- dust KR (mce [5, 12])
+>    ; f <- tRand (mce [200, 1600]) (mce [500, 3000]) t
+>    ; audition (out 0 (sinOsc AR f 0 * 0.2)) }
diff --git a/Help/UGen/Noise/tiRand.help.lhs b/Help/UGen/Noise/tiRand.help.lhs
--- a/Help/UGen/Noise/tiRand.help.lhs
+++ b/Help/UGen/Noise/tiRand.help.lhs
@@ -4,9 +4,10 @@
 hi each time the trig signal changes from nonpositive to positive
 values
 
-> l <- tiRand (-1) 1 =<< dust KR 10
-> n <- pinkNoise AR
-> audition (out 0 (pan2 (n * 0.1) l 1))
+> do { l <- tiRand (-1) 1 =<< dust KR 10
+>    ; n <- pinkNoise AR
+>    ; audition (out 0 (pan2 (n * 0.1) l 1)) }
 
-> f <- tiRand 4 12 =<< dust KR 10
-> audition (out 0 (sinOsc AR (f * 150 + (MCE [0,1])) 0 * 0.1))
+> do { n <- tiRand 4 12 =<< dust KR 10
+>    ; let f = n * 150 + (mce [0,1])
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Noise/whiteNoise.help.lhs b/Help/UGen/Noise/whiteNoise.help.lhs
--- a/Help/UGen/Noise/whiteNoise.help.lhs
+++ b/Help/UGen/Noise/whiteNoise.help.lhs
@@ -3,3 +3,25 @@
 Generates noise whose spectrum has equal power at all frequencies.
 
 > audition . (out 0) . (* 0.05) =<< whiteNoise AR
+
+Random filtered noise bursts.
+
+> do { n <- whiteNoise AR
+>    ; t <- dust AR (mce [3, 7])
+>    ; f <- tExpRand 20 1800 t
+>    ; bw <- tExpRand 0.001 1 t
+>    ; let { e = decay2 t 0.01 0.2
+>          ; r = resonz (n * e) f bw }
+>      in audition (out 0 r) }
+
+The same graph, without using do notation.
+
+> whiteNoise AR >>= \n -> 
+> dust AR (mce [3, 7]) >>= \t -> 
+> tExpRand 20 1800 t >>= \f ->
+> tExpRand 0.001 1 t >>= \bw -> 
+> let { e = decay2 t 0.01 0.2
+>     ; r = resonz (n * e) f bw }
+> in audition (out 0 r)
+
+ 
diff --git a/Help/UGen/Oscillator/fSinOsc.help.lhs b/Help/UGen/Oscillator/fSinOsc.help.lhs
--- a/Help/UGen/Oscillator/fSinOsc.help.lhs
+++ b/Help/UGen/Oscillator/fSinOsc.help.lhs
@@ -14,11 +14,11 @@
 
 Note the phase argument, which was not in the SC2 variant.
 
-> audition (out 0 (fSinOsc AR (MCE [440, 550]) 0 * 0.05))
+> audition (out 0 (fSinOsc AR (mce [440, 550]) 0 * 0.05))
 
 > audition (out 0 (fSinOsc AR (xLine KR 200 4000 1 RemoveSynth) 0 * 0.1))
 
 Loses amplitude towards the end
 
 > let f = fSinOsc AR (xLine KR 4 401 8 RemoveSynth)
-> audition (out 0 (fSinOsc AR (f 0 * 200 + 800) 0 * 0.1))
+> in audition (out 0 (fSinOsc AR (f 0 * 200 + 800) 0 * 0.1))
diff --git a/Help/UGen/Oscillator/formant.help.lhs b/Help/UGen/Oscillator/formant.help.lhs
--- a/Help/UGen/Oscillator/formant.help.lhs
+++ b/Help/UGen/Oscillator/formant.help.lhs
@@ -9,8 +9,8 @@
 
 Modulate formant frequency, fundamental frequency stays constant.
 
-> let f = MCE [200, 300, 400, 500]
-> audition (out 0 (formant AR f (xLine KR 400 4000 8 RemoveSynth) 200 * 0.125))
+> let f = mce [200, 300, 400, 500]
+> in audition (out 0 (formant AR f (xLine KR 400 4000 8 RemoveSynth) 200 * 0.125))
 
 Modulate width frequency, other frequencies stay constant.
 
diff --git a/Help/UGen/Oscillator/gendy1.help.lhs b/Help/UGen/Oscillator/gendy1.help.lhs
--- a/Help/UGen/Oscillator/gendy1.help.lhs
+++ b/Help/UGen/Oscillator/gendy1.help.lhs
@@ -67,107 +67,107 @@
 knum=12.
 
 > let g = gendy1 AR 1 1 1 1 440 660 0.5 0.5 12 12
-> audition (out 0 (pan2 g 0 0.15))
+> in audition (out 0 (pan2 g 0 0.15))
 
 Wandering bass
 
 > let g = gendy1 AR 1 1 1.0 1.0 30 100 0.3 0.05 5 5
-> audition (out 0 (pan2 g 0 0.15))
+> in audition (out 0 (pan2 g 0 0.15))
 
 Play me	
 
-> let x = mouseX KR 100 1000 Exponential 0.1
->     g = gendy1 AR 1 1 1.0 1.0 30 100 0.3 0.05 5 5
-> audition (out 0 (pan2 (rlpf g 500 0.3 * 0.2) 0 0.25))
+> let { x = mouseX KR 100 1000 Exponential 0.1
+>     ; g = gendy1 AR 1 1 1.0 1.0 30 100 0.3 0.05 5 5 }
+> in audition (out 0 (pan2 (rlpf g 500 0.3 * 0.2) 0 0.25))
 
 Scream!
 
-> let x = mouseX KR 220 440 Exponential 0.1
->     y = mouseY KR 0.0 1.0 Linear 0.1
-> audition (out 0 (pan2 (gendy1 AR 2 3 1 1 x (8 * x) y y 7 7) 0.0 0.3))
+> let { x = mouseX KR 220 440 Exponential 0.1
+>     ; y = mouseY KR 0.0 1.0 Linear 0.1 }
+> in audition (out 0 (pan2 (gendy1 AR 2 3 1 1 x (8 * x) y y 7 7) 0.0 0.3))
 
 1 CP = random noise
 
 > let g = gendy1 AR 1 1 1 1 440 660 0.5 0.5 1 1
-> audition (out 0 (pan2 g 0 0.15))
+> in audition (out 0 (pan2 g 0 0.15))
 
 2 CPs = an oscillator
 
 > let g = gendy1 AR 1 1 1 1 440 660 0.5 0.5 2 2 
-> audition (out 0 (pan2 g 0 0.15))
+> in audition (out 0 (pan2 g 0 0.15))
 
 Used as an LFO
 
-> let ad = sinOsc KR 0.10 0 * 0.49 + 0.51
->     dd = sinOsc KR 0.13 0 * 0.49 + 0.51
->     as = sinOsc KR 0.17 0 * 0.49 + 0.51
->     ds = sinOsc KR 0.19 0 * 0.49 + 0.51
->     g  = gendy1 KR 2 4 ad dd 3.4 3.5 as ds 10 10
-> audition (out 0 (pan2 (sinOsc AR (g * 50 + 350) 0) 0.0 0.3))
+> let { ad = sinOsc KR 0.10 0 * 0.49 + 0.51
+>     ; dd = sinOsc KR 0.13 0 * 0.49 + 0.51
+>     ; as = sinOsc KR 0.17 0 * 0.49 + 0.51
+>     ; ds = sinOsc KR 0.19 0 * 0.49 + 0.51
+>     ; g = gendy1 KR 2 4 ad dd 3.4 3.5 as ds 10 10 }
+> in audition (out 0 (pan2 (sinOsc AR (g * 50 + 350) 0) 0.0 0.3))
 
 Wasp
 
 > let ad = sinOsc KR 0.1 0 * 0.1 + 0.9
-> audition (out 0 (pan2 (gendy1 AR 0 0 ad 1.0 50 1000 1 0.005 12 12) 0.0 0.2))
+> in audition (out 0 (pan2 (gendy1 AR 0 0 ad 1.0 50 1000 1 0.005 12 12) 0.0 0.2))
 
 Modulate distributions. Change of pitch as distributions change
 the duration structure and spectrum
 
-> let x = mouseX KR 0 7 Linear 0.1
->     y = mouseY KR 0 7 Linear 0.1
->     g = gendy1 AR x y 1 1 440 660 0.5 0.5 12 12
-> audition (out 0 (pan2 g 0 0.2))
+> let { x = mouseX KR 0 7 Linear 0.1
+>     ; y = mouseY KR 0 7 Linear 0.1
+>     ; g = gendy1 AR x y 1 1 440 660 0.5 0.5 12 12 }
+> in audition (out 0 (pan2 g 0 0.2))
 
 Modulate number of CPs.
 
-> let x = mouseX KR 1 13 Linear 0.1
->     g = gendy1 AR 1 1 1 1 440 660 0.5 0.5 12 x
-> audition (out 0 (pan2 g 0 0.2))
+> let { x = mouseX KR 1 13 Linear 0.1
+>     ; g = gendy1 AR 1 1 1 1 440 660 0.5 0.5 12 x }
+> in audition (out 0 (pan2 g 0 0.2))
 
 Self modulation.
 
-> let x  = mouseX KR 1   13 Linear 0.1
->     y  = mouseY KR 0.1 10 Linear 0.1
->     g0 = gendy1 AR 5 4 0.3 0.7 0.1 y 1.0 1.0 5 5
->     g1 = gendy1 AR 1 1 1 1 440 (g0 * 500 + 600) 0.5 0.5 12 x
-> audition (out 0 (pan2 g1 0 0.2))
+> let { x = mouseX KR 1   13 Linear 0.1
+>     ; y = mouseY KR 0.1 10 Linear 0.1
+>     ; g0 = gendy1 AR 5 4 0.3 0.7 0.1 y 1.0 1.0 5 5
+>     ; g1 = gendy1 AR 1 1 1 1 440 (g0 * 500 + 600) 0.5 0.5 12 x }
+> in audition (out 0 (pan2 g1 0 0.2))
 
 Use SINUS to track any oscillator and take CP positions from it use
 adParam and ddParam as the inputs to sample.
 
-> let p = lfPulse KR 100 0 0.4
->     s = sinOsc KR 30 0 * 0.5
->     g = gendy1 AR 6 6 p s 440 660 0.5 0.5 12 12
-> audition (out 0 (pan2 g 0 0.2))
+> let { p = lfPulse KR 100 0 0.4
+>     ; s = sinOsc KR 30 0 * 0.5
+>     ; g = gendy1 AR 6 6 p s 440 660 0.5 0.5 12 12 }
+> in audition (out 0 (pan2 g 0 0.2))
 
 Near the corners are interesting.
 
-> let x = mouseX KR 0 200 Linear 0.1
->     y = mouseY KR 0 200 Linear 0.1
->     p = lfPulse KR x 0 0.4
->     s = sinOsc KR y 0 * 0.5
->     g = gendy1 AR 6 6 p s 440 660 0.5 0.5 12 12
-> audition (out 0 (pan2 g 0 0.2))
+> let { x = mouseX KR 0 200 Linear 0.1
+>     ; y = mouseY KR 0 200 Linear 0.1
+>     ; p = lfPulse KR x 0 0.4
+>     ; s = sinOsc KR y 0 * 0.5
+>     ; g = gendy1 AR 6 6 p s 440 660 0.5 0.5 12 12 }
+> in audition (out 0 (pan2 g 0 0.2))
 
 Texture
 
-> let f _ = do f  <- rand 130 160.3
->              r0 <- rand 0 6
->              r1 <- rand 0 6
->              l  <- rand (-1) 1
->              let ad = sinOsc KR 0.10 0 * 0.49 + 0.51
->                  dd = sinOsc KR 0.13 0 * 0.49 + 0.51
->                  as = sinOsc KR 0.17 0 * 0.49 + 0.51
->                  ds = sinOsc KR 0.19 0 * 0.49 + 0.51
->                  g  = gendy1 AR r0 r1 ad dd f f as ds 12 12
->                  o  = sinOsc AR (g * 200 + 400) 0
->              return (pan2 o l 0.1)
-> m <- mapM f [0..9]
-> audition (out 0 (mix (MCE m)))
+> let node = do { f  <- rand 130 160.3
+>               ; r0 <- rand 0 6
+>               ; r1 <- rand 0 6
+>               ; l  <- rand (-1) 1
+>               ; let { ad = sinOsc KR 0.10 0 * 0.49 + 0.51
+>                     ; dd = sinOsc KR 0.13 0 * 0.49 + 0.51
+>                     ; as = sinOsc KR 0.17 0 * 0.49 + 0.51
+>                     ; ds = sinOsc KR 0.19 0 * 0.49 + 0.51
+>                     ; g = gendy1 AR r0 r1 ad dd f f as ds 12 12
+>                     ; o = sinOsc AR (g * 200 + 400) 0 }
+>                 in return (pan2 o l 0.1) }
+> in do { m <- replicateM 9 node
+>       ; audition (out 0 (mix (mce m))) }
 
 Try durscale 10.0 and 0.0 too.
 
-> let x = mouseX KR 10 700 Linear 0.1
->     y = mouseY KR 50 1000 Linear 0.1
->     g = gendy1 AR 2 3 1 1 1 x 0.5 0.1 10 10
-> audition (out 0 (pan2 (combN (resonz g y 0.1) 0.1 0.1 5) 0.0 0.6))
+> let { x = mouseX KR 10 700 Linear 0.1
+>     ; y = mouseY KR 50 1000 Linear 0.1
+>     ; g = gendy1 AR 2 3 1 1 1 x 0.5 0.1 10 10 }
+> in audition (out 0 (pan2 (combN (resonz g y 0.1) 0.1 0.1 5) 0.0 0.6))
diff --git a/Help/UGen/Oscillator/impulse.help.lhs b/Help/UGen/Oscillator/impulse.help.lhs
--- a/Help/UGen/Oscillator/impulse.help.lhs
+++ b/Help/UGen/Oscillator/impulse.help.lhs
@@ -8,7 +8,7 @@
 > audition (out 0 (impulse AR 800 0 * 0.1))
 
 > let f = xLine KR 800 10 5 RemoveSynth
-> audition (out 0 (impulse AR f 0.0 * 0.1))
+> in audition (out 0 (impulse AR f 0.0 * 0.1))
 
 > let f = mouseY KR 4 8 Linear 0.1
-> audition (out 0 (impulse AR f (MCE [0, mouseX KR 0 1 Linear 0.1]) * 0.1))
+> in audition (out 0 (impulse AR f (mce [0, mouseX KR 0 1 Linear 0.1]) * 0.1))
diff --git a/Help/UGen/Oscillator/klang.help.lhs b/Help/UGen/Oscillator/klang.help.lhs
--- a/Help/UGen/Oscillator/klang.help.lhs
+++ b/Help/UGen/Oscillator/klang.help.lhs
@@ -3,7 +3,7 @@
 Bank of fixed oscillators.  spec is constructed using klangSpec, which
 takes lists of frequency, amplitude and phase.
 
-> let f = [440,550..1100]
->     a = take 7 (cycle [0.05, 0.02])
->     p = replicate 7 0
-> audition (out 0 (klang AR 1 0 (klangSpec f a p)))
+> let { f = [440,550..1100]
+>     ; a = take 7 (cycle [0.05, 0.02])
+>     ; p = replicate 7 0 }
+> in audition (out 0 (klang AR 1 0 (klangSpec f a p)))
diff --git a/Help/UGen/Oscillator/pulse.help.lhs b/Help/UGen/Oscillator/pulse.help.lhs
--- a/Help/UGen/Oscillator/pulse.help.lhs
+++ b/Help/UGen/Oscillator/pulse.help.lhs
@@ -4,13 +4,17 @@
 
 Modulate frequency
 
-> audition (out 0 (pulse AR (xLine KR 40 4000 6 RemoveSynth) 0.1 * 0.1))
+> let f = xLine KR 40 4000 6 RemoveSynth
+> in audition (out 0 (pulse AR f 0.1 * 0.1))
 
 Modulate pulse width
 
-> audition (out 0 (pulse AR 200 (line KR 0.01 0.99 8 RemoveSynth) * 0.1))
+> let w = line KR 0.01 0.99 8 RemoveSynth
+> in audition (out 0 (pulse AR 200 w * 0.1))
 
-Two band limited square waves thru a resonant low pass filter
+Two band limited square waves through a resonant 
+low pass filter
 
-> let p = pulse AR (MCE [100, 250]) 0.5 * 0.1
-> audition (out 0 (rlpf p (xLine KR 8000 400 5 RemoveSynth) 0.05))
+> let { p = pulse AR (mce [100, 250]) 0.5 * 0.1
+>     ; f = xLine KR 8000 400 5 RemoveSynth }
+> in audition (out 0 (rlpf p f 0.05))
diff --git a/Help/UGen/Oscillator/saw.help.lhs b/Help/UGen/Oscillator/saw.help.lhs
--- a/Help/UGen/Oscillator/saw.help.lhs
+++ b/Help/UGen/Oscillator/saw.help.lhs
@@ -7,4 +7,4 @@
 Two band limited sawtooth waves thru a resonant low pass filter
 
 > let f = xLine KR 8000 400 5 DoNothing
-> audition (out 0 (rlpf (saw AR (MCE [100, 250]) * 0.1) f 0.05))
+> in audition (out 0 (rlpf (saw AR (mce [100, 250]) * 0.1) f 0.05))
diff --git a/Help/UGen/Oscillator/sinOsc.help.lhs b/Help/UGen/Oscillator/sinOsc.help.lhs
--- a/Help/UGen/Oscillator/sinOsc.help.lhs
+++ b/Help/UGen/Oscillator/sinOsc.help.lhs
@@ -15,9 +15,9 @@
 Modulate freq
 
 > let f = sinOsc AR (xLine KR 1 1000 9 RemoveSynth) 0 * 200 + 800
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
 
 Modulate phase
 
 > let p = sinOsc AR (xLine KR 20 8000 10 RemoveSynth) 0 * 2 * pi
-> audition (out 0 (sinOsc AR 800 p * 0.1))
+> in audition (out 0 (sinOsc AR 800 p * 0.1))
diff --git a/Help/UGen/Oscillator/tGrains.help.lhs b/Help/UGen/Oscillator/tGrains.help.lhs
--- a/Help/UGen/Oscillator/tGrains.help.lhs
+++ b/Help/UGen/Oscillator/tGrains.help.lhs
@@ -34,30 +34,29 @@
          interpolation, (2) linear interpolation, or (4) cubic
          interpolation.
 
-> let sync fd msg = send fd msg >> wait fd "/done"
-> withSC3 (\fd -> sync fd (b_allocRead 10 "/home/rohan/audio/metal.wav" 0 0))
+> withSC3 (\fd -> async fd (b_allocRead 10 "/home/rohan/audio/metal.wav" 0 0))
 
-> let tRate = mouseY KR 2 200 Exponential 0.1
->     ctr   = mouseX KR 0 (bufDur KR 10) Linear 0.1
->     tr    = impulse AR tRate 0
-> audition (out 0 (tGrains 2 tr 10 1 ctr (4 / tRate) 0 0.1 2))
+> let { tRate = mouseY KR 2 200 Exponential 0.1
+>     ; ctr = mouseX KR 0 (bufDur KR 10) Linear 0.1
+>     ; tr = impulse AR tRate 0 }
+> in audition (out 0 (tGrains 2 tr 10 1 ctr (4 / tRate) 0 0.1 2))
 
-> let b = 10
->     trate = mouseY KR 8 120 Exponential 0.1
->     dur = 4 / trate
-> clk <- dust AR trate
-> r <- tRand 0 0.01 clk
-> let x = mouseX KR 0 (bufDur KR b) Linear 0.1
->     pos = x + r
-> pan <- return . (* 0.6) =<< whiteNoise KR
-> audition (out 0 (tGrains 2 clk b 1 pos dur pan 0.1 2))
+> let { b = 10
+>     ; trate = mouseY KR 8 120 Exponential 0.1
+>     ; dur = 4 / trate }
+> in do { clk <- dust AR trate
+>       ; r <- tRand 0 0.01 clk
+>       ; pan <- return . (* 0.6) =<< whiteNoise KR
+>       ; let { x = mouseX KR 0 (bufDur KR b) Linear 0.1
+>             ; pos = x + r }
+>         in audition (out 0 (tGrains 2 clk b 1 pos dur pan 0.1 2)) }
 
-> let b = 10
->     trate = mouseY KR 2 120 Exponential 0.1
->     dur = 1.2 / trate
->     clk = impulse AR trate 0
->     pos = mouseX KR 0 (bufDur KR b) Linear 0.1
-> pan <- return . (* 0.6) =<< whiteNoise KR
-> n <- whiteNoise KR
-> let rate = shiftLeft 1.2 (roundE (n * 3) 1)
-> audition (out 0 (tGrains 2 clk b rate pos dur pan 0.1 2))
+> let { b = 10
+>     ; trate = mouseY KR 2 120 Exponential 0.1
+>     ; dur = 1.2 / trate
+>     ; clk = impulse AR trate 0
+>     ; pos = mouseX KR 0 (bufDur KR b) Linear 0.1 }
+> in do { n0 <- whiteNoise KR
+>       ; n1 <- whiteNoise KR
+>       ; let rate = shiftLeft 1.2 (roundE (n0 * 3) 1)
+>         in audition (out 0 (tGrains 2 clk b rate pos dur (n1 * 0.6) 0.25 2)) }
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,13 +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
-> d <- dust AR x
-> let a = MCE [sinOsc AR 220 0,
->              saw AR 440,
->              pulse AR 110 0.1]
-> audition (out 0 (twChoose d a (MCE [0.5, 0.35, 0.15]) 0 * 0.1))
+> let { twChoose t a w n = select (twindex t n w) a
+>     ; 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] 
+>             ; w = mce [0.5, 0.35, 0.15] }
+>         in audition (out 0 (twChoose d a w 0 * 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
@@ -6,16 +6,16 @@
 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
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> 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))
 
 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
-> audition (out 0 (sinOsc AR f 0 * 0.1))
+> 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 }
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Panner/linPan2.help.lhs b/Help/UGen/Panner/linPan2.help.lhs
--- a/Help/UGen/Panner/linPan2.help.lhs
+++ b/Help/UGen/Panner/linPan2.help.lhs
@@ -2,7 +2,7 @@
 
 Two channel linear pan.  See Pan2.
 
-> n <- pinkNoise AR
-> audition (out 0 (linPan2 n (fSinOsc KR 2 0) 0.1))
+> do { n <- pinkNoise AR
+>    ; audition (out 0 (linPan2 n (fSinOsc KR 2 0) 0.1)) }
 
 > audition (out 0 (linPan2 (fSinOsc AR 800 0) (fSinOsc KR 3 0) 0.1))
diff --git a/Help/UGen/Panner/pan2.help.lhs b/Help/UGen/Panner/pan2.help.lhs
--- a/Help/UGen/Panner/pan2.help.lhs
+++ b/Help/UGen/Panner/pan2.help.lhs
@@ -3,8 +3,10 @@
 Two channel equal power panner.  The pan position is bipolar, -1 is
 left, +1 is right.  The level is a control rate input.
 
-> n <- pinkNoise AR
-> audition (out 0 (pan2 n (fSinOsc KR 2 0) 0.3))
+> do { n <- pinkNoise AR
+>    ; audition (out 0 (pan2 n (fSinOsc KR 2 0) 0.3)) }
 
-> n <- pinkNoise AR
-> audition (out 0 (pan2 n (mouseX KR (-1) 1 Linear 0.2) (mouseY KR 0 1 Linear 0.2)))
+> do { n <- pinkNoise AR
+>    ; let { x = mouseX KR (-1) 1 Linear 0.2
+>          ; y = mouseY KR 0 1 Linear 0.2 }
+>      in audition (out 0 (pan2 n x y)) }
diff --git a/Help/UGen/Panner/rotate2.help.lhs b/Help/UGen/Panner/rotate2.help.lhs
--- a/Help/UGen/Panner/rotate2.help.lhs
+++ b/Help/UGen/Panner/rotate2.help.lhs
@@ -21,12 +21,13 @@
 
 Rotation of stereo sound, via LFO.
 
-> x <- pinkNoise AR
-> let y = lfTri AR 800 0 * lfPulse KR 3 0 0.3 * 0.2
-> audition (out 0 (rotate2 x y (lfSaw KR 0.1 0)))
+> do { x <- pinkNoise AR
+>    ; let y = lfTri AR 800 0 * lfPulse KR 3 0 0.3 * 0.2
+>      in audition (out 0 (rotate2 x y (lfSaw KR 0.1 0))) }
 
 Rotation of stereo sound, via mouse.
 
-> let x = mix $ lfSaw AR (MCE [198..201]) 0 * 0.1
->     y = sinOsc AR 900 0 * lfPulse KR 3 0 0.3 * 0.2
-> audition (out 0 (rotate2 x y (mouseX KR 0 2 Linear 0.2)))
+> let { x = mix $ lfSaw AR (mce [198..201]) 0 * 0.1
+>     ; y = sinOsc AR 900 0 * lfPulse KR 3 0 0.3 * 0.2 
+>     ; p = mouseX KR 0 2 Linear 0.2 }
+> in audition (out 0 (rotate2 x y p))
diff --git a/Help/UGen/Panner/splay.help.lhs b/Help/UGen/Panner/splay.help.lhs
--- a/Help/UGen/Panner/splay.help.lhs
+++ b/Help/UGen/Panner/splay.help.lhs
@@ -4,13 +4,13 @@
 
 spread -    0 = mono, 1 = stereo
 level  -    0 = silent, 1 = unit gain (equal power level compensated)
-center -    -1 = left, 1 = right
+center -   -1 = left, 1 = right
 
-> let i = 6
-> r <- replicateM i (rand 10 20)
-> n <- lfNoise2 KR (MCE r)
-> let ci = Constant . fromIntegral
->     x = mouseX KR (-1) 1 Linear 0.1
->     y = mouseY KR 1 0 Linear 0.1
->     o = sinOsc AR (n * 200 + (MCE [1 .. ci i] + 3 * 100)) 0
-> audition (out 0 (splay o y 0.2 x))
+> do { i <- return 6
+>    ; r <- replicateM i (rand 10 20)
+>    ; n <- lfNoise2 KR (mce r)
+>    ; let { ci = constant . fromIntegral
+>          ; x = mouseX KR (-1) 1 Linear 0.1
+>          ; y = mouseY KR 1 0 Linear 0.1
+>          ; o = sinOsc AR (n * 200 + (mce [1 .. ci i] + 3 * 100)) 0 }
+>      in audition (out 0 (splay o y 0.2 x)) }
diff --git a/Help/UGen/Trigger/gate.help.lhs b/Help/UGen/Trigger/gate.help.lhs
--- a/Help/UGen/Trigger/gate.help.lhs
+++ b/Help/UGen/Trigger/gate.help.lhs
@@ -3,4 +3,4 @@
 The signal at `in' is passed while `trig' is greater than zero.
 
 > let t = lfPulse AR 1 0 0.1
-> audition (out 0 (gate (fSinOsc AR 500 0 * 0.25) t))
+> in audition (out 0 (gate (fSinOsc AR 500 0 * 0.25) t))
diff --git a/Help/UGen/Trigger/inRange.help.lhs b/Help/UGen/Trigger/inRange.help.lhs
--- a/Help/UGen/Trigger/inRange.help.lhs
+++ b/Help/UGen/Trigger/inRange.help.lhs
@@ -9,6 +9,7 @@
 lo - low threshold
 hi - high threshold
 
-> n <- brownNoise AR
-> let x = mouseX KR 1 2 Linear 0.1
-> audition (out 0 (inRange (sinOsc KR x 0 * 0.2) (-0.15) 0.15 * n * 0.1))
+> do { n <- brownNoise AR
+>      ; let { x = mouseX KR 1 2 Linear 0.1 
+>            ; o = sinOsc KR x 0 * 0.2 }
+>      in audition (out 0 (inRange o (-0.15) 0.15 * n * 0.1)) }
diff --git a/Help/UGen/Trigger/lastValue.help.lhs b/Help/UGen/Trigger/lastValue.help.lhs
--- a/Help/UGen/Trigger/lastValue.help.lhs
+++ b/Help/UGen/Trigger/lastValue.help.lhs
@@ -3,7 +3,8 @@
 Output the last value before the input changed more than a threshhold.
 
 > let x = mouseX KR 100 400 Linear 0.1
-> audition (out 0 (sinOsc AR (lastValue x 40) 0 * 0.1))
+> in audition (out 0 (sinOsc AR (lastValue x 40) 0 * 0.1))
 
-> let x = mouseX KR 0.1 4 Linear 0.1
-> audition (out 0 (sinOsc AR (abs (lastValue x 0.5 - x) * 400 + 200) 0 * 0.2))
+> let { x = mouseX KR 0.1 4 Linear 0.1
+>     ; f = abs (lastValue x 0.5 - x) * 400 + 200 }
+> in audition (out 0 (sinOsc AR f 0 * 0.2))
diff --git a/Help/UGen/Trigger/mostChange.help.lhs b/Help/UGen/Trigger/mostChange.help.lhs
--- a/Help/UGen/Trigger/mostChange.help.lhs
+++ b/Help/UGen/Trigger/mostChange.help.lhs
@@ -2,6 +2,7 @@
 
 Output the input that changed most.
 
-> n <- lfNoise0 KR 1
-> let x = mouseX KR 200 300 Linear 0.1
-> audition (out 0 (sinOsc AR (mostChange (n * 400 + 900) x) 0 * 0.1))
+> do { n <- lfNoise0 KR 1
+>    ; let { x = mouseX KR 200 300 Linear 0.1
+>          ; f = mostChange (n * 400 + 900) x }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
diff --git a/Help/UGen/Trigger/peak.help.lhs b/Help/UGen/Trigger/peak.help.lhs
--- a/Help/UGen/Trigger/peak.help.lhs
+++ b/Help/UGen/Trigger/peak.help.lhs
@@ -3,6 +3,7 @@
 Outputs the maximum value read at the `trig' input until `reset' is
 triggered.
 
-> t <- dust AR 20
-> let r = impulse AR 0.4 0
-> audition (out 0 (sinOsc AR (peak t r * 500 + 200) 0 * 0.2))
+> do { t <- dust AR 20
+>    ; let { r = impulse AR 0.4 0
+>          ; f = peak t r * 500 + 200 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.2)) }
diff --git a/Help/UGen/Trigger/phasor.help.lhs b/Help/UGen/Trigger/phasor.help.lhs
--- a/Help/UGen/Trigger/phasor.help.lhs
+++ b/Help/UGen/Trigger/phasor.help.lhs
@@ -1,4 +1,4 @@
-phasor trig rate start end resetPos
+phasor rate trig rate start end resetPos
 
 Triggered linear ramp between two levels.  Starts a linear ramp
 when trig input crosses from non-positive to positive.
@@ -13,8 +13,9 @@
 
 phasor controls sine frequency: end frequency matches a second sine wave.
 
-> let rate = mouseX KR 0.2 2 Exponential 0.1
->     trig = impulse AR rate 0
->     sr   = sampleRate
->     x    = phasor AR trig (rate / sr) 0 1 0
-> audition (out 0 (sinOsc AR (MCE [linLin x 0 1 600 1000, 1000]) 0 * 0.2))
+> let { rate = mouseX KR 0.2 2 Exponential 0.1
+>     ; tr = impulse AR rate 0
+>     ; sr = sampleRate
+>     ; x = phasor AR tr (rate / sr) 0 1 0 
+>     ; f = mce [linLin x 0 1 600 1000, 1000] }
+> in audition (out 0 (sinOsc AR f 0 * 0.2))
diff --git a/Help/UGen/Trigger/pulseDivider.help.lhs b/Help/UGen/Trigger/pulseDivider.help.lhs
--- a/Help/UGen/Trigger/pulseDivider.help.lhs
+++ b/Help/UGen/Trigger/pulseDivider.help.lhs
@@ -4,9 +4,8 @@
 at its input.  A trigger happens when the signal changes from
 non-positive to positive.
 
-> let p = impulse AR 8 0
->     d = pulseDivider p (MCE [4,7]) 0
->     a = sinOsc AR 1200 0 * decay2 p 0.005 0.1
->     b = sinOsc AR 600  0 * decay2 d 0.005 0.5
-> audition (out 0 (a + b * 0.4))
-
+> let { p = impulse AR 8 0
+>     ; d = pulseDivider p (mce [4,7]) 0
+>     ; a = sinOsc AR 1200 0 * decay2 p 0.005 0.1
+>     ; b = sinOsc AR 600  0 * decay2 d 0.005 0.5 }
+> in audition (out 0 (a + b * 0.4))
diff --git a/Help/UGen/Trigger/runningMax.help.lhs b/Help/UGen/Trigger/runningMax.help.lhs
--- a/Help/UGen/Trigger/runningMax.help.lhs
+++ b/Help/UGen/Trigger/runningMax.help.lhs
@@ -7,6 +7,7 @@
 in   - input signal
 trig - reset the output value to the current input value
 
-> n <- dust AR 20
-> let t = impulse AR 0.4 0
-> audition (out 0 (sinOsc AR (runningMax n t * 500 + 200) 0 * 0.2))
+> do { n <- dust AR 20
+>    ; let { t = impulse AR 0.4 0
+>          ; f = runningMax n t * 500 + 200 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.2)) }
diff --git a/Help/UGen/Trigger/runningMin.help.lhs b/Help/UGen/Trigger/runningMin.help.lhs
--- a/Help/UGen/Trigger/runningMin.help.lhs
+++ b/Help/UGen/Trigger/runningMin.help.lhs
@@ -7,11 +7,13 @@
 in   - input signal
 trig - reset the output value to the current input value
 
-> n <- dust AR 20
-> let t = impulse AR 0.4 0
-> audition (out 0 (sinOsc AR (runningMin n t * 500 + 200) 0 * 0.2))
+> do { n <- dust AR 20
+>    ; let { t = impulse AR 0.4 0
+>          ; f = runningMin n t * 500 + 200 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.2)) }
 
-> let o = sinOsc KR 2 0
->     x = mouseX KR 0.01 10 Exponential 0.1
->     t = impulse AR x 0
-> audition (out 0 (sinOsc AR (runningMin o t * 500 + 200) 0 * 0.2))
+> let { o = sinOsc KR 2 0
+>     ; x = mouseX KR 0.01 10 Exponential 0.1
+>     ; t = impulse AR x 0 
+>     ; f = runningMin o t * 500 + 200 }
+> in audition (out 0 (sinOsc AR f 0 * 0.2))
diff --git a/Help/UGen/Trigger/sendTrig.lhs b/Help/UGen/Trigger/sendTrig.lhs
--- a/Help/UGen/Trigger/sendTrig.lhs
+++ b/Help/UGen/Trigger/sendTrig.lhs
@@ -12,14 +12,13 @@
 value - a UGen or float that will be polled at the time of trigger,
         and its value passed with the trigger message
 
-> withSC3 (\fd -> do send fd (notify True)
->                    wait fd "/done")
+> withSC3 (\fd -> async fd (notify True))
 
-> s <- lfNoise0 KR 10
-> audition (MRG [sendTrig s 0 s, out 0 (sinOsc AR (s * 200 + 500) 0 * 0.1)])
+> 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 -> do { tr <- wait fd "/tr"
+>                    ; putStrLn (show tr) })
 
-> withSC3 (\fd -> do send fd (notify False)
->                    wait fd "/done")
+> withSC3 (\fd -> async fd (notify False))
diff --git a/Help/UGen/Trigger/setResetFF.help.lhs b/Help/UGen/Trigger/setResetFF.help.lhs
--- a/Help/UGen/Trigger/setResetFF.help.lhs
+++ b/Help/UGen/Trigger/setResetFF.help.lhs
@@ -9,7 +9,7 @@
 trig  - trigger sets output to one
 reset - trigger resets output to zero
 
-> n <- brownNoise AR
-> d0 <- dust AR 5
-> d1 <- dust AR 5
-> audition (out 0 (setResetFF d0 d1 * n * 0.2))
+> do { n <- brownNoise AR
+>    ; d0 <- dust AR 5
+>    ; d1 <- dust AR 5
+>    ; audition (out 0 (setResetFF d0 d1 * n * 0.2)) }
diff --git a/Help/UGen/Trigger/stepper.help.lhs b/Help/UGen/Trigger/stepper.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/Trigger/stepper.help.lhs
@@ -0,0 +1,53 @@
+stepper trig reset min max step resetval
+
+Stepper pulse counter.  Each trigger increments a counter which is
+output as a signal. The counter wraps between min and max.
+
+trig - trigger. Trigger can be any signal. A trigger happens when the
+       signal changes from non-positive to positive.
+
+reset - resets the counter to resetval when triggered.
+
+min - minimum value of the counter.
+
+max - maximum value of the counter.
+
+step - step value each trigger. May be negative.
+
+resetval - value to which the counter is reset when it receives a
+           reset trigger. If nil, then this is patched to min.
+
+> let { i = impulse KR 10 0
+>     ; f = stepper i 0 4 16 (-3) 4 * 100 }
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
+
+> let { compose = foldl (flip (.)) id
+>     ; noisec n l r = randomRs (l,r) (mkStdGen n)
+>     ; rvb s r0 r1 r2 = let f dl1 dl2 dc i = allpassN i 0.05 (mce [dl1,dl2]) dc
+>                        in compose (take 5 (zipWith3 f r0 r1 r2)) s
+>     ; rvb' s = rvb s (noisec 0 0 0.05) (noisec 1 0 0.05) (noisec 2 1.5 2.0)
+>     ; stpr = let { rate = mouseX KR 1 5 Exponential 0.1
+>                  ; clock = impulse KR rate 0
+>                  ; envl = decay2 clock 0.002 2.5
+>                  ; indx = stepper clock 0 0 15 1 0
+>                  ; freq = bufRdN 1 KR 10 indx Loop
+>                  ; ffreq = lag2 freq 0.1 + mce [0, 0.3]
+>                  ; lfo = sinOsc KR 0.2 (mce [0, pi/2]) * 0.0024 + 0.0025
+>                  ; top = mix (lfPulse AR (freq * mce [1, 1.5, 2]) 0 0.3)
+>                  ; chn = [ \s -> rlpf s ffreq 0.3 * envl
+>                          , \s -> rlpf s ffreq 0.3 * envl
+>                          , \s -> s * 0.5
+>                          , \s -> combL s 1 (0.66 / rate) 2 * 0.8 + s
+>                          , \s -> s + (rvb' s * 0.3)
+>                          , \s -> leakDC s 0.1
+>                          , \s -> delayL s 0.1 lfo + s
+>                          , \s -> onePole s 0.9 ] }
+>       in compose chn top
+>     ; stprInit fd = let n = [ 97.999, 195.998, 523.251, 466.164, 195.998
+>                             , 233.082, 87.307, 391.995, 87.307, 261.626
+>                             , 195.998, 77.782, 233.082, 195.998, 97.999
+>                             , 155.563]
+>                     in do { async fd (b_alloc 10 128 1)
+>                           ; send fd (b_setn 10 [(0, n)]) } }
+> in withSC3 (\fd -> do { stprInit fd
+>                       ; audition (out 0 stpr) })
diff --git a/Help/UGen/Trigger/sweep.help.lhs b/Help/UGen/Trigger/sweep.help.lhs
--- a/Help/UGen/Trigger/sweep.help.lhs
+++ b/Help/UGen/Trigger/sweep.help.lhs
@@ -5,30 +5,33 @@
 	
 Using sweep to modulate sine frequency
 
-> let x = mouseX KR 0.5 20 Exponential 0.1
->     t = impulse KR x 0
-> audition (out 0 (sinOsc AR (sweep t 700 + 500) 0 * 0.2))
+> let { x = mouseX KR 0.5 20 Exponential 0.1
+>     ; t = impulse KR x 0 
+>     ; f = sweep t 700 + 500 }
+> in audition (out 0 (sinOsc AR f 0 * 0.2))
 
 Using sweep to index into a buffer
 
 > withSC3 (\fd -> send fd (b_allocRead 0 "/home/rohan/audio/metal.wav" 0 0))
 
-> let x = mouseX KR 0.5 20 Exponential 0.1
->     t = impulse AR x 0
-> audition (out 0 (bufRdL 1 AR 0 (sweep t (bufSampleRate KR 0)) NoLoop))
+> let { x = mouseX KR 0.5 20 Exponential 0.1
+>     ; t = impulse AR x 0
+>     ; p = sweep t (bufSampleRate KR 0) }
+> in audition (out 0 (bufRdL 1 AR 0 p NoLoop))
 
 Backwards, variable offset
 
-> n <- lfNoise0 KR 15
-> let x = mouseX KR 0.5 10 Exponential 0.1
->     t = impulse AR x 0
->     r = bufSampleRate KR 0
->     p = sweep t (negate r) + (bufFrames KR 0 * n)
-> audition (out 0 (bufRdL 1 AR 0 p NoLoop))
+> do { n <- lfNoise0 KR 15
+>    ; let { x = mouseX KR 0.5 10 Exponential 0.1
+>          ; t = impulse AR x 0
+>          ; r = bufSampleRate KR 0
+>          ; p = sweep t (negate r) + (bufFrames KR 0 * n) }
+>      in audition (out 0 (bufRdL 1 AR 0 p NoLoop)) }
 
 Raising rate
 
-> let x = mouseX KR 0.5 10 Exponential 0.1
->     t = impulse AR x 0
->     r = sweep t 2 + 0.5
-> audition (out 0 (bufRdL 1 AR 0 (sweep t (bufSampleRate KR 0 * r)) NoLoop))
+> let { x = mouseX KR 0.5 10 Exponential 0.1
+>     ; t = impulse AR x 0
+>     ; r = sweep t 2 + 0.5
+>     ; p = sweep t (bufSampleRate KR 0 * r) }
+> in audition (out 0 (bufRdL 1 AR 0 p NoLoop))
diff --git a/Help/UGen/Trigger/tDelay.help.lhs b/Help/UGen/Trigger/tDelay.help.lhs
--- a/Help/UGen/Trigger/tDelay.help.lhs
+++ b/Help/UGen/Trigger/tDelay.help.lhs
@@ -6,6 +6,7 @@
 trigger   - input trigger signal.
 delayTime - delay time in seconds.
 
-> let z  = impulse AR 2 0
->     z' = tDelay z 0.5
-> audition (out 0 (MCE [z * 0.1, toggleFF z' * sinOsc AR 440 0 * 0.1]))
+> let { z = impulse AR 2 0
+>     ; z' = tDelay z 0.5 
+>     ; o = sinOsc AR 440 0 * 0.1 }
+> in audition (out 0 (mce [z * 0.1, toggleFF z' * o]))
diff --git a/Help/UGen/Trigger/timer.help.lhs b/Help/UGen/Trigger/timer.help.lhs
--- a/Help/UGen/Trigger/timer.help.lhs
+++ b/Help/UGen/Trigger/timer.help.lhs
@@ -6,4 +6,4 @@
 the higher the frequency
 
 > let t = impulse KR (mouseX KR 0.5 20 Exponential 0.1) 0
-> audition (out 0 (sinOsc AR (timer t * 500 + 500) 0 * 0.2))
+> in audition (out 0 (sinOsc AR (timer t * 500 + 500) 0 * 0.2))
diff --git a/Help/UGen/Trigger/toggleFF.help.lhs b/Help/UGen/Trigger/toggleFF.help.lhs
--- a/Help/UGen/Trigger/toggleFF.help.lhs
+++ b/Help/UGen/Trigger/toggleFF.help.lhs
@@ -4,5 +4,5 @@
 
 trig - trigger input
 
-> t <- dust AR (xLine KR 1 1000 60 DoNothing)
-> audition (out 0 (sinOsc AR (toggleFF t * 400 + 800) 0 * 0.1))
+> do { t <- dust AR (xLine KR 1 1000 60 DoNothing)
+>    ; audition (out 0 (sinOsc AR (toggleFF t * 400 + 800) 0 * 0.1)) }
diff --git a/Help/UGen/Trigger/trig.help.lhs b/Help/UGen/Trigger/trig.help.lhs
--- a/Help/UGen/Trigger/trig.help.lhs
+++ b/Help/UGen/Trigger/trig.help.lhs
@@ -2,5 +2,6 @@
 
 When `in' is trigerred output the trigger value for `dur' seconds.
 
-> d <- dust AR 1
-> audition (out 0 (trig d 0.2 * fSinOsc AR 800 0 * 0.5))
+> do { d <- dust AR 1
+>    ; let o = fSinOsc AR 800 0 * 0.5
+>      in audition (out 0 (trig d 0.2 * o)) }
diff --git a/Help/UGen/Trigger/trig1.help.lhs b/Help/UGen/Trigger/trig1.help.lhs
--- a/Help/UGen/Trigger/trig1.help.lhs
+++ b/Help/UGen/Trigger/trig1.help.lhs
@@ -2,5 +2,5 @@
 
 When `in' is trigered output a unit signal for `dur' seconds.
 
-> d <- dust AR 1
-> audition (out 0 (trig1 d 0.2 * fSinOsc AR 800 0 * 0.2))
+> do { d <- dust AR 1
+>    ; audition (out 0 (trig1 d 0.2 * fSinOsc AR 800 0 * 0.2)) }
diff --git a/Help/hsc3.help.lhs b/Help/hsc3.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/hsc3.help.lhs
@@ -0,0 +1,597 @@
+* Abstract
+
+This document describes the hsc3 haskell
+bindings to the supercollider synthesis
+server.
+
+The bindings allow haskell to be used
+to write unit generator graphs, to control
+the supercollider synthesiser interactively
+while it is running, and to write scores for
+offline rendering.
+
+For detailed introductory materials on
+haskell and supercollider, see
+
+  http://haskell.org/
+  http://audiosynth.com/
+
+* Questions, Dartmouth, 2002
+
+| What should a computer music language do?
+| ...
+| Is a specialized computer music language
+| even necessary? (McCartney, 2002)
+
+These questions are asked in a paper that
+documents a reimplementation of the supercollider
+language for real time audio synthesis (McCartney,
+1998).
+
+The redesigned system consists of two parts, an
+elegant, efficient, and musically neutral real
+time audio synthesiser in the music-n family
+(Mathews, 1961), and a language interpreter in the
+smalltalk family (Goldberg, 1983).
+
+The interpreter and synthesiser communicate using
+the open sound control protocol (Wright & Freed,
+1997).
+
+Using this model of discrete communicating
+processes, the computer music language is relieved
+of many onerous tasks.
+
+In part the question is rhetorical, given an
+appropriately designed and implemented
+synthesiser, the control language need not be
+particularly specialised.
+
+* What needs to be done
+
+The requirements are rather minimal.
+
+An open sound control protocol implementation and
+a usable notation for server commands.
+
+A unit generator graph protocol implementation and
+a usable notation for writing graphs.
+
+For interactive use a suitably responsive run time
+system, where suitable is a function of the kind
+of work being done.
+
+* Questions, San Dimas, 1965
+
+| (1) What are declarative languages?
+| ...
+| (4) How can we use them to program?
+| (5) How can we implement them?
+| (Strachey, in Landin, 1966)
+
+(1) Haskell is a non-strict (Wadler, 1996) and
+    purely functional (Sabry, 1993) language, one
+    result of many years of research into these
+    questions (Hudak et al, 2007).
+
+(4) Computation in haskell is structured using a
+    small number of simple type classes; monads
+    (Wadler, 1990), applicative functors (McBride
+    and Paterson, 2007) & arrows (Hughes, 2000).
+
+(5) The glasgow haskell system includes both an
+    optimizing compiler generating efficient
+    machine programs and a bytecode generator and
+    intepreter for interative use.
+
+In the authors experience the glasgow run-time
+system is adequate for real-time control of the
+supercollider synthesiser, capable of generating
+high density & low latency control streams such as
+those required for waveset synthesis etc.
+
+* Types, Unit Generators, Parametric Polymorphism
+
+In haskell polymorphism is provided by type
+classes (Wadler & Blott, 1989).
+
+Type class polymorphism is parametric, as distinct
+from the ad hoc polymorphism of supercollider
+language (Strachey, 1967).
+
+Since unit generators are a sort of numerical
+value, we wish to make their representation
+amenable to the standard haskell numerical type
+classes.
+
+These give signatures such as:
+
+> (+) :: (Num a) => a -> a -> a
+
+meaning that a value can only be summed with a
+value of the same type, and that the resulting
+value must also be of the same type.
+
+This implies that the type of a unit generator
+must be inclusive, since we wish to combine
+constants, control inputs, and actual unit
+generators operating at varying rates and with
+varying numbers of input and output ports.
+
+This leads us to a representation that is simple
+but somewhat uninformative, and delays evaluating
+unit generator graph correctness to run-time.
+
+We note that a more rigorous type representation
+is possible, either in standard haskell or using
+one of the many implemented type system
+extensions, and could be layered either above or
+below the current representation.
+
+* Multiple channel expansion
+
+The supercollider language implements a very
+elegant rule for composing graphs from nodes with
+different numbers of channels.  The model is
+referred to as multiple channel expansion, a
+behaviour that, although it can become confusing
+in deeply nested uses, is very intuitive for
+simple cases.
+
+The simple type representation of unit generators
+allows us to implement the multiple channel
+expansion model in much the same way as in the
+supercollider language
+
+Unit generators with multiple outputs, such
+as pan2, are represented as a specific kind
+of unit generator value, an ordered set of
+proxies.
+
+We can also write these sets directly using
+the 'mce' function.
+
+Multiple channel expansion flows downward
+through unit generator graphs.
+
+In the expression below, the frequency input
+causes two sinOsc unit generators to be created.
+
+> let { x = mouseX KR (-1) 1 Linear 0.1
+>     ; o1 = pulse AR 440 0.1
+>     ; o2 = sinOsc AR (mce [110, 2300]) 0 * 0.1 }
+> in audition (out 0 (pan2 o1 x 0.1 + o2))
+
+This is turn causes the (*) function to
+expands and perform channel matching, that is
+to duplicate the right hand side input as
+required.
+
+The (+) function is also expanded, since the
+left and right hand sides are of equal degree
+there is not replication of inputs.
+
+The out function does not expand, since it is
+defined to flatten one layer of mce values at
+it's second input to support a variable number
+of input channels; it would however expand on
+mce at the first argument, or nested mce at the
+second.
+
+Equal inputs do also push the expansion
+downwards, however in complex graphs this
+seems occasionally unreliable.
+
+> let f = (mce2 440 440)
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
+
+* Multiply add inputs, Haskell Curry, and cloning
+
+The supercollider language provides optional multiply
+and add inputs for most unit generator constructors.
+
+Optional arguments do not interact well with the
+haskell behaviour of treating functions as monadic.
+
+That is, one way to write the number thirteen is:
+
+> let { sum_squares x y = x * x + y * y
+>     ; f = sum_squares 2 }
+> in f 3
+
+The absent multiply add inputs can in most cases be
+simply re-written using (*) and (+).
+
+The expression:
+
+| { Out.ar(0, SinOsc.ar(440, 0, 0.1, 0.05)) }.play
+
+is equivalent to:
+
+> audition (out 0 (sinOsc AR 440 0 * 0.1 + 0.05))
+
+However there is a subtle distinction in behaviour
+relating to multiple channel expansion.
+
+The supercollider language expression:
+
+| { var a = WhiteNoise.ar([0.1, 0.05])
+| ; var b = PinkNoise.ar * [0.1, 0.05]
+| ; Out.ar(0, a + b) }.play
+
+describes a graph with two WhiteNoise nodes
+and a single PinkNoise node.
+
+We note that this distinction is only relevant
+for non-deterministic unit generators.
+
+To write this simple graph in haskell we can use
+the clone function:
+
+> let f = liftM (* mce [0.1, 0.05])
+> in do { a <- f (clone 2 (whiteNoise AR))
+>       ; b <- f (pinkNoise AR)
+>       ; audition (out 0 (a + b)) }
+
+which is defined in relation to the standard
+monad functions replicateM and liftM.
+
+| clone :: (UId m) => Int -> m UGen -> m UGen
+| clone n u = liftM mce (replicateM n u)
+
+* Multiple Root Graphs
+
+The mrg function, pronounced multiple root graph,
+allows us to write unit generator graphs with
+multiple sink nodes.
+
+Consider the freeSelf unit generator:
+
+> do { n <- dust KR 0.5
+>    ; let { a = freeSelf n
+>          ; b = out 0 (sinOsc AR 440 0 * 0.1) }
+>      in audition (mrg [a, b]) }
+
+In order to allow multiple root graphs to be
+freely composed we implement a leftmost rule,
+whereby the leftmost root need not be a sink
+node, in which case the mrg node may be used
+as an input node.
+
+Consider a simple ping pong delay filter:
+
+> let ppd s = let { a = localIn 2 AR + mce [s, 0]
+>                 ; b = delayN a 0.2 0.2
+>                 ; c = mceEdit reverse b * 0.8 }
+>             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)) }
+
+* Literals, Overloading, Coercion, Constants
+
+This is a somewhat subtle distinction.  Numeric
+literals in haskell are overloaded, not coerced.
+The numerical type classes provide two functions:
+
+> fromInteger :: (Num a) => Integer -> a
+
+and
+
+> fromRational :: (Fractional a) => Rational -> a
+
+which are implicitly applied to all integer and
+rational literals respectively.
+
+It is for this reason that we can write:
+
+> sinOsc AR 440.0 0 * 0.1
+
+but must explicitly construct constants from values
+of a concrete numerical type using the constant
+function.
+
+> let { f = 440.0 :: Double
+>     ; p = 0 :: Int
+>     ; a = 0.1 :: Float }
+> in sinOsc AR (constant f) (constant p) * (constant a)
+
+* Unit generators are comparable
+
+In haskell the Eq and Ord type classes define
+equality and ordering operators.
+
+In unit generator graphs these operators have a
+somewhat different meaning, and require a different
+type signature.
+
+For instance the greater-than operator defines a
+unit generator that is zero for sample values
+where the comparison fails, and one when it
+succeeds.
+
+Since the Ord type gives the signature:
+
+| (>) :: (Ord a) => a -> a -> Bool
+
+we define a variant with a star suffix, such
+that:
+
+> let { x = mouseX KR 3 45 Exponential 0.1
+>     ; t = sinOsc AR x 0 >* 0
+>     ; d = envTriangle 0.01 0.1
+>     ; e = envGen AR t 1 0 1 DoNothing d
+>     ; f = 220 + 880 * (toggleFF t)
+>     ; o = sinOsc AR f 0 }
+> in audition (out 0 (o * e))
+
+is a sequence of low and high tones.
+
+For functions where the signature is
+consistent with the meaning of the unit
+generator operator we use the haskell name.
+
+| max :: (Ord a) => a -> a -> a
+
+> let { l = fSinOsc AR 500 0 * 0.25
+>     ; r = fSinOsc AR 0.5 0 * 0.23 }
+> in audition (out 0 (l `max` r))
+
+* Observable Sharing, Pure Noise
+
+The haskell expression:
+
+> let { a = sinOsc AR 440 0
+>     ; b = sinOsc AR 440 0
+>     ; c = a - b }
+> in audition (out 0 c)
+
+denotes a graph that has three nodes: sinOsc, (-)
+and out.
+
+  # UGens                     Int 3
+  # Synths                    Int 1
+
+The graph constructor, when traversing the
+structure denoted by (out 0 c), cannot distinguish
+between a and b, they are the same value.
+
+In other words, it is the same graph as if we had
+written:
+
+> let { x = sinOsc AR 440 0
+>     ; y = x - x }
+> in audition (out 0 y)
+
+Expressions with the same notation have the same
+value.
+
+This is acceptable for deterministic unit
+generators, such as sinOsc, but of course fails
+for non-deterministic unit generators such as
+whiteNoise, and for demand rate sources such as
+dseq.
+
+In supercollider language, the graph
+
+| { var a = WhiteNoise.ar
+| ; var b = WhiteNoise.ar
+| ; var c = a - b
+| ; Out.ar(0, c * 0.1) }.play
+
+does not describe silence, it describes white
+noise.
+
+We read WhiteNoise.ar as a computation that
+constructs a value, not as an expression that
+denotes a value.
+
+In procedural languages we are familiar with many
+different types of equality.  Scheme has eq?, eqv?
+and equal?, supercollider language has == and ===.
+
+| { var a = "x"
+| ; var b = "x"
+| ; [a == b, a === b] }.value
+
+In a purely functional language expressions denote
+values, and equal expressions denote the same
+value.  Therefore the graph given by the haskell
+expression:
+
+> let { z = uid 0
+>     ; n = Sound.SC3.UGen.Base.whiteNoise z
+>     ; a = n AR
+>     ; b = n AR
+>     ; c = a - b }
+> in audition (out 0 (c * 0.1))
+
+describes silence.  To describe white noise we
+would need to distinguish a and b, which can only
+be done by providing non-equal identifiers in
+place of z.
+
+The whiteNoise function used above is written
+using a fully qualified name because it is not the
+whiteNoise function provided by Sound.SC3, that
+function has the signature:
+
+> whiteNoise :: (UId m) => Rate -> m UGen
+
+where UId is defined as:
+
+> class (Monad m) => UId m where
+>     generateUId :: m Int
+
+The signature indicates that whiteNoise is a
+function from a Rate value to an (m UGen)
+value.
+
+* Non-determinism, monadic structure, do notation
+
+It is quite clear that a value of type (m UGen) is
+not of type UGen.
+
+Compare the whiteNoise signature with that of the
+deterministic sin oscillator:
+
+> sinOsc :: Rate -> UGen -> UGen -> UGen
+
+We can write a white noise graph using this
+function as:
+
+> do { a <- whiteNoise AR
+>    ; b <- whiteNoise AR
+>    ; let c = a - b
+>      in audition (out 0 (c * 0.1)) }
+
+which brings us more or less to the supercollider
+language notation, with the exception that there
+are two distinct binding notations, one for
+computations and one for expressions.
+
+The type system does not allow us to confuse these
+two bindings.
+
+The do notation allows us to write expressions
+that involve computations using a familiar and
+readable right to left binding notation.
+
+The above expression is equal to:
+
+> whiteNoise AR >>= \a ->
+> whiteNoise AR >>= \b ->
+> let c = a - b
+> in audition (out 0 (c * 0.1))
+
+where (>>=) is the monadic bind function, and (\x
+-> y) is the syntax for function definition
+(ie. {|x| y} in supercollider language.  The
+signature for bind is:
+
+> (>>=) :: (Monad m) => m a -> (a -> m b) -> m b
+
+which indicates that the value bound in the
+function definition can only be accessed in a
+function that produces a value in the same monad.
+
+The audition function has an appropriate
+signature:
+
+> audition :: UGen -> IO ()
+
+since IO is an instance of the UId class.
+
+It is the type of audition that determines the
+type of a, the type is inferred so there is no
+need to write it.
+
+* Demand Rate, Sharing Again
+
+Demand rate UGens are similarly not functions only
+of their arguments.
+
+In the supercollider language expression below the
+left and right channels have different signals,
+despite each receiving the same input unit
+generator.
+
+| { var a = Dseq([1, 3, 2, 7, 8], 3)
+| ; var t = Impulse.kr(5,0)
+| ; var f = Demand.kr(t, 0, [a, a]) * 30 + 340
+| ; Out.ar(0, SinOsc.ar(f, 0) * 0.1) }.play
+
+The distinction here concerns multiple
+reads from a single demand rate source, ie.
+it is not that the source is non-deterministic,
+it is rather that each read request consumes
+the value it reads.
+
+Therefore in haskell demand rate unit generators have
+similar constructor functions to non-deterministic
+unit generators, in order that we can distinguish:
+
+> do { a <- dseq 3 (mce [1, 3, 2, 7, 8])
+>    ; let { t = impulse KR 5 0
+>          ; f = demand t 0 (mce [a, a]) * 30 + 340 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
+
+which is the same graph as given in supercollider
+language above, from:
+
+> do { a <- clone 2 (dseq 3 (mce [1, 3, 2, 7, 8]))
+>    ; let { t = impulse KR 5 0
+>          ; f = demand t 0 a * 30 + 340 }
+>      in audition (out 0 (sinOsc AR f 0 * 0.1)) }
+
+which gives an equal sequence of tones in each
+channel.
+
+* References
+
++ A. Goldberg and D. Robson.  Smalltalk-80: The
+  language and its implementation.
+  Addison-Wesley, Reading, MA, 1983.
+
++ P. Hudak, J. Hughes, S. P. Jones, and P. Wadler.
+  A History of Haskell: being lazy with class.  In
+  The Third ACM SIGPLAN History of Programming
+  Languages Conference, San Diego, California,
+  June 2007.  Association for Computing Machinery.
+
++ John Hughes. Generalising monads to arrows.
+  Sci. Comput. Program., 37(1-3):67-111, 2000.
+
++ P. Landin.  The next 700 programming languages.
+  Communications of the ACM, 9(3):157-164, March
+  1966.  Presented at the ACM Programming and
+  Pragmatics Conference, August 1965.
+
++ M. V. Mathews.  An Acoustical Compiler for Music
+  and Psychological Stimuli.  AT&T Bell
+  Laboratories Technical Journal, 40:677-694,
+  1961.
+
++ C. McBride and R. Paterson.  Applicative
+  Programming with Effects.  Journal of Functional
+  Programming, 17(4), 2007.
+
++ J. McCarthy.  Recursive functions of symbolic
+  expressions and their computation by machine.
+  Communications of the ACM, 3(4):184-195, 1960.
+
++ J. McCartney.  Continued evolution of the
+  SuperCollider real time synthesis environment.
+  In Proceedings of the International Computer
+  Music Conference, pages 133-136. International
+  Computer Music Association, 1998.
+
++ J. McCartney.  Rethinking the Computer Music
+  Language: SuperCollider.  Computer Music
+  Journal, 26(4):61-68, 2002.
+
++ Amr Sabry. What is a Purely Functional Language?
+  Journal of Functional Programming, 1(1), 1993.
+
++ C. Strachey.  Fundamental Concepts in
+  Programming Languages.  Higher-Order and
+  Symbolic Computation, 13:11-49, 2000.
+
++ Philip Wadler. Lazy versus strict.  ACM
+  Comput. Surv., 28(2):318-320, 1996.
+
++ P. Wadler.  Comprehending Monads.  In Conference
+  on Lisp and Funcional Programming, Nice, France,
+  June 1990. ACM.
+
++ P. Wadler and S. Blott.  How to make ad hoc
+  polymorphism less ad hoc.  In Proceedings of
+  16th ACM Symposium on Principles of Programming
+  Languages, pages 60-76, January 1989.
+
++ M. Wright and A. Freed.  Open Sound Control: A
+  New Protocol for Communicating with Sound
+  Synthesizers.  In Proceedings of the
+  International Computer Music Conference, pages
+  101-104.  International Computer Music
+  Association, 1997.
diff --git a/README b/README
new file mode 100644
--- /dev/null
+++ b/README
@@ -0,0 +1,13 @@
+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://haskell.org/
+  http://audiosynth.com/
+  http://gnu.org/software/emacs/
+
+(c) rohan drape, 2006-2008, GPL.2, http://gnu.org/copyleft/
diff --git a/Sound/SC3/Server.hs b/Sound/SC3/Server.hs
--- a/Sound/SC3/Server.hs
+++ b/Sound/SC3/Server.hs
@@ -1,11 +1,11 @@
 module Sound.SC3.Server ( module Sound.SC3.Server.Command
-                        , module Sound.SC3.Server.Graphdef
+                        , module Sound.SC3.Server.Synthdef
                         , module Sound.SC3.Server.Play
                         , module Sound.SC3.Server.Status
                         , module Sound.SC3.Server.NRT ) where
 
 import Sound.SC3.Server.Command
-import Sound.SC3.Server.Graphdef
+import Sound.SC3.Server.Synthdef
 import Sound.SC3.Server.Play
 import Sound.SC3.Server.Status
 import Sound.SC3.Server.NRT
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,6 +1,6 @@
 module Sound.SC3.Server.Command where
 
-import Sound.OpenSoundControl (OSC(..), Datum(..))
+import Sound.OpenSoundControl
 import Sound.SC3.Server.Utilities
 import Data.Word (Word8)
 
@@ -8,76 +8,76 @@
 
 -- | 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" (mkDuples 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" (mkDuples 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 : mkTriples 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 : mkDuples 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 : mkTriples 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" (mkDuples 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 : mkDuples 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 : mkDuples 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 : mkDuples 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" (mkDuples 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" (mkTriples 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" (mkDuples 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 : mkTriples 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 : mkDuples 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 : mkDuples 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" (mkTriples 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" (mkDuples 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" (mkDuples 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,33 @@
 
 -- | 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.
 sync :: Int -> OSC
-sync sid = Message "/sync" [Int sid]
+sync sid = message "/sync" [int sid]
+
+-- * Variants to simplify common cases.
+
+-- | Set single sample value.
+b_set1 :: Int -> Int -> Double -> OSC
+b_set1 nid i x = b_set nid [(i,x)]
+
+-- | Set a range of sample values.
+b_setn1 :: Int -> Int -> [Double] -> OSC
+b_setn1 nid i xs = b_setn nid [(i,xs)]
 
 -- Local Variables:
 -- truncate-lines:t
diff --git a/Sound/SC3/Server/Graphdef.hs b/Sound/SC3/Server/Graphdef.hs
deleted file mode 100644
--- a/Sound/SC3/Server/Graphdef.hs
+++ /dev/null
@@ -1,54 +0,0 @@
-module Sound.SC3.Server.Graphdef (graphdef) where
-
-import Sound.OpenSoundControl.Byte
-import Sound.OpenSoundControl.Cast
-import Sound.SC3.UGen.UGen (UGen(..), Special(..))
-import Sound.SC3.UGen.Rate (rateId)
-import Sound.SC3.UGen.Graph
-
-import Data.Word
-import qualified Data.ByteString.Lazy as B
-
--- | Byte-encode Input value.
-encode_input :: Input -> B.ByteString
-encode_input (Input u p) = B.append (encode_i16 u) (encode_i16 p)
-
--- | Byte-encode Control value.
-encode_control :: Graph -> UGen -> B.ByteString
-encode_control g c@(Control _ n _) = B.concat [ B.pack (str_pstr n)
-                                              , encode_i16 (nodeIndex g c)]
-encode_control _ _  = error "encode_control: illegal input"
-
--- | Byte-encode UGen value.
-encode_ugen :: Graph -> UGen -> B.ByteString
-encode_ugen g (UGen r n i o s _) = B.concat [ B.pack (str_pstr n)
-                                            , encode_i8 (rateId r)
-                                            , encode_i16 (length i)
-                                            , encode_i16 (length o)
-                                            , encode_i16 s'
-                                            , B.concat i'
-                                            , B.concat o' ]
-    where i' = map (encode_input . makeInput g) i
-          o' = map (encode_i8 . rateId) o
-          (Special s') = s
-encode_ugen _ _ = error "encode_ugen: illegal input"
-
--- | Construct instrument definition bytecode.
-encode_graphdef :: String -> Graph -> B.ByteString
-encode_graphdef s g = B.concat [ encode_str "SCgf"
-                               , encode_i32 0
-                               , encode_i16 1
-                               , B.pack (str_pstr s)
-                               , encode_i16 (length n)
-                               , B.concat (map (encode_f32 . constantValue) n)
-                               , encode_i16 (length c)
-                               , B.concat (map (encode_f32 . controlDefault) c)
-                               , encode_i16 (length c)
-                               , B.concat (map (encode_control g) c)
-                               , encode_i16 (length u)
-                               , B.concat (map (encode_ugen g) u) ]
-    where (Graph n c u _) = g
-
--- | Construct instrument definition bytecode.
-graphdef :: String -> Graph -> [Word8]
-graphdef s g = B.unpack (encode_graphdef s g)
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
@@ -1,15 +1,16 @@
-module Sound.SC3.Server.Play (play, stop, reset, withSC3, audition) where
+module Sound.SC3.Server.Play ( play, stop, reset, async
+                             , withSC3, audition ) where
 
 import Sound.OpenSoundControl
-import Sound.SC3.UGen.UGen (UGen(..))
-import Sound.SC3.UGen.Graph (graph)
-import Sound.SC3.Server.Graphdef (graphdef)
-import Sound.SC3.Server.Command (AddAction(AddToTail), s_new, d_recv, g_new, g_freeAll)
+import Sound.SC3.UGen.UGen (UGen)
+import Sound.SC3.Server.Synthdef
+import Sound.SC3.Server.Command
 
--- | Construct an instrument definition, send /d_recv and /s_new messages to scsynth.
+-- | Construct an instrument definition, send /d_recv and /s_new
+-- | messages to scsynth.
 play :: Transport t => t -> UGen -> IO OSC
-play fd u = do let g = graphdef "Anonymous" (graph u)
-               send fd (d_recv g) 
+play fd u = do let d = synthdef "Anonymous" u
+               send fd (d_recv d) 
                r <- wait fd "/done"
                send fd (s_new "Anonymous" (-1) AddToTail 1 [])
                return r
@@ -18,6 +19,10 @@
 stop :: Transport t => t -> IO ()
 stop fd = send fd (g_freeAll [1])
 
+-- | Send an osc message and wait for a reply.
+async :: Transport t => t -> OSC -> IO OSC
+async fd m = send fd m >> wait fd "/done"
+
 -- | Free all nodes and re-create group node with id 1.
 reset :: Transport t => t -> IO ()
 reset fd = do send fd (g_freeAll [0])
@@ -29,4 +34,4 @@
 
 -- | withSC3 . play
 audition :: UGen -> IO ()
-audition g = withSC3 (\fd -> play fd g) >> return ()
+audition u = withSC3 (\fd -> play fd u) >> return ()
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
@@ -14,8 +14,10 @@
                 "Sample Rate (Actual)        "]
 
 statusInfo :: OSC -> [String]
-statusInfo (Message "status.reply" l) = map show (tail l)
-statusInfo _                          = error "non status.reply message"
+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)
diff --git a/Sound/SC3/Server/Synthdef.hs b/Sound/SC3/Server/Synthdef.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Server/Synthdef.hs
@@ -0,0 +1,236 @@
+module Sound.SC3.Server.Synthdef ( Node(..), FromPort(..), Graph(..)
+                                  , synth, synthdef ) where
+
+import qualified Data.ByteString.Lazy as B
+import qualified Data.IntMap as M
+import Data.Char (ord)
+import Data.List
+import Data.Word
+import Sound.OpenSoundControl.Byte
+import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UGen.Predicate
+import Sound.SC3.UGen.Rate
+
+type NodeId = Int
+type PortIndex = Int
+
+-- | Type to represent unit generator graph.
+data Graph = Graph { nextId :: NodeId
+                   , constants :: [Node]
+                   , controls :: [Node]
+                   , ugens :: [Node] }
+            deriving (Eq, Show)
+
+-- | Type to represent nodes in unit generator graph.
+data Node = NodeC { node_id :: NodeId
+                  , node_c_value :: Double }
+          | NodeK { node_id :: NodeId
+                  , node_k_rate :: Rate
+                  , node_k_name :: Name
+                  , node_k_default :: Double }
+          | NodeU { node_id :: NodeId
+                  , node_u_rate :: Rate
+                  , node_u_name :: Name
+                  , node_u_inputs :: [FromPort]
+                  , node_u_outputs :: [Output]
+                  , node_u_special :: Special
+                  , node_u_ugenid :: Maybe UGenId }
+          | NodeP { node_id :: NodeId 
+                  , node_p_node :: Node
+                  , node_p_index :: PortIndex }
+            deriving (Eq, Show)
+
+-- | Type to represent the left hand side of an edge in a unit
+--   generator graph.
+data FromPort = C NodeId
+              | K NodeId
+              | U NodeId PortIndex
+                deriving (Eq, Show)
+
+as_from_port :: Node -> FromPort
+as_from_port (NodeC n _) = C n
+as_from_port (NodeK n _ _ _) = K n
+as_from_port (NodeU n _ _ _ _ _ _) = U n 0
+as_from_port (NodeP _ u p) = U (node_id u) p
+
+-- The empty graph.
+empty_graph :: Graph
+empty_graph = Graph 0 [] [] []
+
+-- Predicate to locate constant.
+find_c_p :: Double -> Node -> Bool
+find_c_p x (NodeC _ y) = x == y
+find_c_p _ _ = error "find_c_p"
+
+-- Insert a constant node into the graph.
+push_c :: Double -> Graph -> (Node, Graph)
+push_c x g = let n = NodeC (nextId g) x
+             in (n, g { constants = n : constants g
+                      , nextId = nextId g + 1 })
+
+-- Either find existing constant node, or insert a new node.
+mk_node_c :: UGen -> Graph -> (Node, Graph)
+mk_node_c (Constant x) g =
+    let y = find (find_c_p x) (constants g)
+    in maybe (push_c x g) (\y' -> (y', g)) y
+mk_node_c _ _ = error "mk_node_c"
+
+-- Predicate to locate control, names must be unique.
+find_k_p :: Name -> 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 (r, nm, d) g =
+    let n = NodeK (nextId g) r nm d
+    in (n, g { controls = n : controls g
+             , nextId = nextId g + 1 })
+
+-- Either find existing control node, or insert a new node.
+mk_node_k :: UGen -> Graph -> (Node, Graph)
+mk_node_k (Control r nm d) g =
+    let y = find (find_k_p nm) (controls g)
+    in maybe (push_k (r, nm, d) g) (\y' -> (y', g)) y
+mk_node_k _ _ = error "mk_node_k"
+
+acc :: [UGen] -> [Node] -> Graph -> ([Node], Graph)
+acc [] n g = (reverse n, g)
+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)
+
+-- Predicate to locate primitive, names must be unique.
+find_u_p :: UGenParts -> Node -> Bool
+find_u_p (r, n, i, o, s, d) (NodeU _ r' n' i' o' s' d')
+    = r == r' && n == n' && i == i' && o == o' && s == s' && d == d'
+find_u_p _ _ = error "find_u_p"
+
+-- Insert a primitive node into the graph.
+push_u :: UGenParts -> Graph -> (Node, Graph)
+push_u (r, nm, i, o, s, d) g =
+    let n = NodeU (nextId g) r nm i o s d
+    in (n, g { ugens = n : ugens g
+             , nextId = nextId g + 1 })
+
+-- Either find existing control node, or insert a new node.
+mk_node_u :: UGen -> Graph -> (Node, Graph)
+mk_node_u (Primitive r nm i o s d) g =
+    let (i', g') = acc i [] g
+        i'' = map as_from_port i'
+        u = (r, nm, i'', o, s, d)
+        y = find (find_u_p u) (ugens g')
+    in maybe (push_u u g') (\y' -> (y', g')) y
+mk_node_u _ _ = error "mk_node_u"
+
+-- Proxies do not get stored in the graph.
+mk_node_p :: Node -> PortIndex -> Graph -> (Node, Graph)
+mk_node_p n p g = let z = nextId g
+                  in (NodeP z n p, g { nextId = z + 1 })
+
+mk_node :: UGen -> Graph -> (Node, Graph)
+mk_node u g 
+    | isConstant u = mk_node_c u g
+    | isControl u = mk_node_k u g
+    | isUGen u = mk_node_u u g
+    | isProxy u = let (n, g') = mk_node_u (proxySource u) g
+                  in mk_node_p n (proxyIndex u) g'
+    | isMRG u = let (_, g') = mk_node (mrgRight u) g
+                in mk_node (mrgLeft u) g'
+    | otherwise = error "mk_node"
+
+type Map = M.IntMap Int
+type Maps = (Map, Map, Map)
+
+-- Generate maps from node identifiers to synthdef indexes.
+mk_maps :: Graph -> Maps
+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..]) )
+
+-- Locate index in map give node identifer.
+fetch :: NodeId -> Map -> Int
+fetch = M.findWithDefault (error "fetch")
+
+data Input = Input Int Int
+             deriving (Eq, Show)
+
+-- Construct input form required by byte-code generator.
+make_input :: Maps -> FromPort -> Input
+make_input (cs, _, _) (C n) = Input (-1) (fetch n cs)
+make_input (_, ks, _) (K n) = Input 0 (fetch n ks)
+make_input (_, _, us) (U n p) = Input (fetch n us) p
+
+-- Byte-encode input value.
+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 _) =
+    B.concat [ B.pack (str_pstr nm)
+             , encode_i16 (fetch n ks) ]
+encode_node_k _ _ = error "encode_node_k"
+
+-- Byte-encode primitive node.
+encode_node_u :: Maps -> Node -> B.ByteString
+encode_node_u m (NodeU _ r nm i o s _) =
+    B.concat [ B.pack (str_pstr nm)
+             , encode_i8 (rateId r)
+             , encode_i16 (length i)
+             , encode_i16 (length o)
+             , encode_i16 s'
+             , B.concat i'
+             , B.concat o' ]
+    where i' = map (encode_input . make_input m) i
+          o' = map (encode_i8 . rateId) o
+          (Special s') = s
+encode_node_u _ _ = error "encode_ugen: illegal input"
+
+-- Construct instrument definition bytecode.
+encode_graphdef :: String -> Graph -> B.ByteString
+encode_graphdef s g =
+    B.concat [ encode_str "SCgf"
+             , encode_i32 0
+             , encode_i16 1
+             , B.pack (str_pstr s)
+             , encode_i16 (length cs)
+             , B.concat (map (encode_f32 . node_c_value) cs)
+             , encode_i16 (length ks)
+             , B.concat (map (encode_f32 . node_k_default) ks)
+             , encode_i16 (length ks)
+             , B.concat (map (encode_node_k mm) ks)
+             , encode_i16 (length us)
+             , B.concat (map (encode_node_u mm) us) ]
+    where (Graph _ cs ks us) = g
+          mm = mk_maps g
+
+-- Construct implicit control unit generator node (k-rate only).
+implicit :: Int -> Node
+implicit n = NodeU (-1) KR "Control" [] (replicate n KR) (Special 0) Nothing
+
+-- Transform mce nodes to mrg nodes
+prepare_root :: UGen -> UGen
+prepare_root u 
+    | 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/UGen.hs b/Sound/SC3/UGen.hs
--- a/Sound/SC3/UGen.hs
+++ b/Sound/SC3/UGen.hs
@@ -1,6 +1,7 @@
 module Sound.SC3.UGen (module Sound.SC3.UGen.Analysis,
                        module Sound.SC3.UGen.Buffer,
                        module Sound.SC3.UGen.Chaos,
+                       module Sound.SC3.UGen.Composite,
                        module Sound.SC3.UGen.Demand,
                        module Sound.SC3.UGen.Demand.Monadic,
                        module Sound.SC3.UGen.Envelope,
@@ -9,13 +10,11 @@
                        module Sound.SC3.UGen.FFT,
                        module Sound.SC3.UGen.FFT.Monadic,
                        module Sound.SC3.UGen.Filter,
-                       module Sound.SC3.UGen.Graph,
                        module Sound.SC3.UGen.Granular,
                        module Sound.SC3.UGen.Information,
                        module Sound.SC3.UGen.IO,
                        module Sound.SC3.UGen.MachineListening,
                        module Sound.SC3.UGen.Math,
-                       module Sound.SC3.UGen.Mix,
                        module Sound.SC3.UGen.Noise.Monadic,
                        module Sound.SC3.UGen.Operator,
                        module Sound.SC3.UGen.Oscillator,
@@ -31,6 +30,7 @@
 import Sound.SC3.UGen.Analysis
 import Sound.SC3.UGen.Buffer
 import Sound.SC3.UGen.Chaos
+import Sound.SC3.UGen.Composite
 import Sound.SC3.UGen.Demand
 import Sound.SC3.UGen.Demand.Monadic
 import Sound.SC3.UGen.Envelope
@@ -39,13 +39,11 @@
 import Sound.SC3.UGen.FFT
 import Sound.SC3.UGen.FFT.Monadic
 import Sound.SC3.UGen.Filter
-import Sound.SC3.UGen.Graph
 import Sound.SC3.UGen.Granular
 import Sound.SC3.UGen.Information
 import Sound.SC3.UGen.IO
 import Sound.SC3.UGen.Math
 import Sound.SC3.UGen.MachineListening
-import Sound.SC3.UGen.Mix
 import Sound.SC3.UGen.Noise.Monadic
 import Sound.SC3.UGen.Operator
 import Sound.SC3.UGen.Oscillator
diff --git a/Sound/SC3/UGen/Base.hs b/Sound/SC3/UGen/Base.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/Base.hs
@@ -0,0 +1,7 @@
+module Sound.SC3.UGen.Base (module Sound.SC3.UGen.Demand.Base,
+                            module Sound.SC3.UGen.FFT.Base,
+                            module Sound.SC3.UGen.Noise.Base) where
+
+import Sound.SC3.UGen.Demand.Base
+import Sound.SC3.UGen.FFT.Base
+import Sound.SC3.UGen.Noise.Base
diff --git a/Sound/SC3/UGen/Composite.hs b/Sound/SC3/UGen/Composite.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/Composite.hs
@@ -0,0 +1,46 @@
+module Sound.SC3.UGen.Composite where
+
+import Sound.SC3.UGen.Filter
+import Sound.SC3.UGen.Oscillator
+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
+
+-- | Collapse multiple channel expansion by summing.
+mix :: UGen -> UGen
+mix u | isMCE u = sum (mceProxies u)
+      | otherwise = u
+
+-- | Construct and sum a set of UGens.
+mixFill :: Int -> (Int -> UGen) -> UGen
+mixFill n f = mix (mce (map f [0..n-1]))
+
+-- | Monadic variant on mixFill.
+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
+
+-- | 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))
+    where n = fromIntegral (mceDegree i)
+          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
+
+-- | PM oscillator.
+pmOsc :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+pmOsc r cf mf pm mp = sinOsc r cf (sinOsc r mf mp * pm)
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,14 +1,20 @@
 module Sound.SC3.UGen.Demand where
 
 import Sound.SC3.UGen.Rate (Rate)
-import Sound.SC3.UGen.UGen (UGen)
+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)
 
+-- | Infinte repeat counter for demand rate unit generators.
+dinf :: UGen
+dinf = Constant 9E8
+
 -- | Demand results from demand rate ugens.
 demand :: UGen -> UGen -> UGen -> UGen
-demand t r d = mkFilterKeyed "Demand" 0 [t, r, d] 1
+demand t r d = mkFilterKeyed "Demand" 0 (t : r : d') (length d')
+    where d' = mceChannels d
 
 -- | Demand envlope generator.
 demandEnvGen :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> DoneAction -> UGen
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
@@ -10,6 +10,10 @@
 dbufrd :: UGenId -> UGen -> UGen -> Loop -> UGen
 dbufrd z b p l = mkOscId z DR "Dbufrd" [b, p, fromLoop 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
+
 -- | Demand rate white noise.
 dwhite :: UGenId -> UGen -> UGen -> UGen -> UGen
 dwhite z l lo hi = mkOscId z DR "Dwhite" [l, lo, hi] 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,6 +1,6 @@
 module Sound.SC3.UGen.Demand.Monadic where
 
-import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UGen (UGen)
 import Sound.SC3.UGen.UGen.Construct
 import qualified Sound.SC3.UGen.Demand.Base as D
 import Sound.SC3.UGen.UId
@@ -9,6 +9,10 @@
 -- | Buffer demand ugen.
 dbufrd :: (UId m) => UGen -> UGen -> Loop -> m UGen
 dbufrd = liftU3 D.dbufrd
+
+-- | Buffer write on demand unit generator.
+dbufwr :: (UId m) => UGen -> UGen -> UGen -> Loop -> m UGen
+dbufwr = liftU4 D.dbufwr
 
 -- | Demand rate white noise.
 dwhite :: (UId m) => UGen -> UGen -> UGen -> m UGen
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 (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,6 +1,6 @@
 module Sound.SC3.UGen.Envelope where
 
-import Sound.SC3.UGen.UGen (UGen(..))
+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)
@@ -25,7 +25,7 @@
 
 -- | Free node on done action at source.
 freeSelfWhenDone :: UGen -> UGen
-freeSelfWhenDone i = mkFilter "FreeSelfWhenDone" [i] 0
+freeSelfWhenDone i = mkFilter "FreeSelfWhenDone" [i] 1
 
 -- | Pause specified node on trigger.
 pause :: UGen -> UGen -> UGen
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,6 +1,6 @@
 module Sound.SC3.UGen.Envelope.Construct where
 
-import Sound.SC3.UGen.UGen (UGen(..))
+import Sound.SC3.UGen.UGen (UGen)
 import Sound.SC3.UGen.UGen.Math ()
 import Sound.SC3.UGen.Math ((>=*), (<=*))
 import Sound.SC3.UGen.Enum (EnvCurve(..))
@@ -21,16 +21,13 @@
     where l = map (* amp) (map snd bp)
           t = map (* dur) (d_dx (map fst bp))
 
--- | Trapezoidal envelope generator.
-envTrapezoid ::
-     UGen {- ^ @shape@ determines the sustain time as a proportion of @dur@:
-               zero is a triangular envelope, one a rectangular envelope. -}
-  -> UGen {- ^ @skew@ determines the attack\/decay ratio:
-               zero is an immediate attack and a slow decay,
-               one a slow attack and an immediate decay. -}
-  -> UGen {- ^ @dur@ -}
-  -> UGen {- ^ @amplitude@ -}
-  -> [UGen]
+{- | Trapezoidal envelope generator.  The arguments are: 1. @shape@
+determines the sustain time as a proportion of @dur@, zero is a
+triangular envelope, one a rectangular envelope; 2. @skew@ determines
+the attack\/decay ratio, zero is an immediate attack and a slow decay,
+one a slow attack and an immediate decay; 3. @duration@ in seconds;
+4. @amplitude@ as linear gain.  -}
+envTrapezoid :: UGen -> UGen -> UGen -> UGen -> [UGen]
 envTrapezoid shape skew dur amp = envCoord bp dur amp EnvLin
     where x1 = skew * (1 - shape)
           bp = [ (0, skew <=* 0)
@@ -38,22 +35,23 @@
                , (shape + x1, 1)
                , (1, skew >=* 1) ]
 
-envPerc :: UGen -> UGen -> UGen -> [EnvCurve] -> [UGen]
-envPerc atk rls lvl crv = env [0.0, lvl, 0.0] [atk, rls] crv (-1.0) (-1.0)
+envPerc' :: UGen -> UGen -> UGen -> [EnvCurve] -> [UGen]
+envPerc' atk rls lvl crv = env [0.0, lvl, 0.0] [atk, rls] crv (-1.0) (-1.0)
 
-envPerc' :: [UGen]
-envPerc' = envPerc 0.01 1.0 1.0 (dbl (EnvNum (-4.0)))
+-- | Percussive envelope, with attack, release, level and curve inputs.
+envPerc :: UGen -> UGen -> [UGen]
+envPerc atk rls = envPerc' atk rls 1.0 (dbl (EnvNum (-4.0)))
 
--- Triangular envelope parameter constructor.
+-- | Triangular envelope, with duration and level inputs.
 envTriangle :: UGen -> UGen -> [UGen]
 envTriangle dur lvl =
    env [0.0, lvl, 0.0] (dbl (dur / 2.0)) (dbl EnvLin) (-1.0) (-1.0)
 
--- Sine envelope parameter constructor.
+-- | Sine envelope, with duration and level inputs.
 envSine :: UGen -> UGen -> [UGen]
 envSine dur lvl =
    env [0.0, lvl, 0.0] (dbl (dur / 2.0)) (dbl EnvSin) (-1.0) (-1.0)
 
--- Linear envelope parameter constructor.
+-- | Linear envelope parameter constructor.
 envLinen :: UGen -> UGen -> UGen -> UGen -> [EnvCurve] -> [UGen]
 envLinen aT sT rT l c = env [0, l, l, 0] [aT, sT, rT] c (-1) (-1)
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,7 +1,7 @@
 module Sound.SC3.UGen.FFT where
 
 import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.UGen
+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
@@ -13,7 +13,7 @@
 -- | Variant FFT constructor with default values for hop size, window
 -- | type, and active status.
 fft' :: UGen -> UGen -> UGen
-fft' buf i = fft buf i (Constant 0.5) 0 1
+fft' buf i = fft buf i 0.5 0 1
 
 -- | Inverse Fast Fourier Transform.
 ifft :: UGen -> UGen -> UGen
@@ -30,19 +30,19 @@
 -- | Pack demand-rate FFT bin streams into an FFT chain.
 packFFT :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 packFFT b sz from to z mp = mkOscMCE KR "PackFFT" [b, sz, from, to, z, n] mp 1
-    where n = Constant (fromIntegral (mceDegree mp))
+    where n = constant (mceDegree mp)
 
 -- | Format magnitude and phase data data as required for packFFT.
 packFFTSpec :: [UGen] -> [UGen] -> UGen
-packFFTSpec m p = MCE (interleave m p)
+packFFTSpec m p = mce (interleave m p)
     where interleave x y = concat (zipWith (\a b -> [a,b]) x y)
 
 pvcollect :: UGen -> UGen -> (UGen -> UGen -> UGen -> (UGen, UGen)) -> UGen -> UGen -> UGen -> UGen
 pvcollect c nf f from to z = packFFT c nf from to z mp
   where m = unpackFFT c nf from to 0
-	p = unpackFFT c nf from to 1
-	i = [from .. to]
-	e = zipWith3 f m p i
+        p = unpackFFT c nf from to 1
+        i = [from .. to]
+        e = zipWith3 f m p i
         mp = (uncurry packFFTSpec) (unzip e)
 
 pv_Add :: UGen -> UGen -> UGen
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,6 +1,6 @@
 module Sound.SC3.UGen.FFT.Monadic where
 
-import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UGen (UGen)
 import Sound.SC3.UGen.UGen.Construct
 import qualified Sound.SC3.UGen.FFT.Base as F
 import Sound.SC3.UGen.UId
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,6 +1,6 @@
 module Sound.SC3.UGen.Filter where
 
-import Sound.SC3.UGen.UGen (UGen(MCE))
+import Sound.SC3.UGen.UGen (UGen, mce)
 import Sound.SC3.UGen.UGen.Construct (mkFilter, mkFilterMCE)
 import Data.List (transpose)
 
@@ -130,7 +130,7 @@
 
 -- | Format frequency, amplitude and decay time data as required for klank.
 klankSpec :: [UGen] -> [UGen] -> [UGen] -> UGen
-klankSpec f a p = MCE ((concat . transpose) [f, a, p])
+klankSpec f a p = mce ((concat . transpose) [f, a, p])
 
 -- | Simple averaging filter.
 lag :: UGen -> UGen -> UGen
@@ -215,6 +215,10 @@
 -- | 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
+
+-- | Karplus-Strong synthesis.
+pluck :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pluck i tr mdl dl dc coef = mkFilter "Pluck" [i, tr, mdl, dl, dc, coef] 1
 
 -- | Trigger counter.
 pulseCount :: UGen -> UGen -> UGen
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,21 +1,26 @@
 module Sound.SC3.UGen.Granular where
 
-import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.Rate (Rate(AR))
+import Sound.SC3.UGen.UGen (UGen)
 import Sound.SC3.UGen.UGen.Construct
 
+-- | Granular synthesis with sound stored in a buffer.
 grainBuf :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 grainBuf nc t d s r p i l e = mkOsc AR "GrainBuf" [t, d, s, r, p, i, l, e] nc
 
+-- | Granular synthesis with frequency modulated sine tones.
 grainFM :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 grainFM nc t d c m i l e = mkOsc AR "GrainFM" [t, d, c, m, i, l, e] nc
 
+-- | Granulate an input signal.
 grainIn :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 grainIn nc t d i l e = mkOsc AR "GrainIn" [t, d, i, l, e] nc
 
+-- | Granular synthesis with sine tones.
 grainSin :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 grainSin nc t d f l e = mkOsc AR "GrainSin" [t, d, f, l, e] nc
 
+-- | Warp a buffer with a time pointer.
 warp1 :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 warp1 nc b p f w e o r i = mkOsc AR "Warp1" [b, p, f, w, e, o, r, i] nc
 
diff --git a/Sound/SC3/UGen/Graph.hs b/Sound/SC3/UGen/Graph.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/Graph.hs
+++ /dev/null
@@ -1,87 +0,0 @@
-module Sound.SC3.UGen.Graph ( Graph(..), Input(..), Terminal(..), Edge(..)
-                            , graph
-                            , nodeIndex
-                            , makeInput ) where
-
-import Sound.SC3.UGen.Rate (Rate(KR))
-import Sound.SC3.UGen.UGen (UGen(..), Special(..), UGenId(..))
-import Sound.SC3.UGen.UGen.Predicate
-
-import Data.Maybe (fromMaybe)
-import Data.List (nub, elemIndex)
-
-data Terminal = Terminal UGen Int deriving (Eq, Show)
-data Edge = Edge Terminal Terminal deriving (Eq, Show)
-data Graph = Graph [UGen] [UGen] [UGen] [Edge] 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@(UGen _ _ i _ _ _) = u : concatMap nodes i
-nodes (Proxy u _)          = u : nodes u
-nodes (MCE u)              = concatMap nodes u
-nodes (MRG u)              = concatMap nodes u
-nodes u                    = [u]
-
--- | Construct implicit control UGen (k-rate only).
-implicit :: Int -> UGen
-implicit n = UGen KR "Control" [] (replicate n KR) (Special 0) (UGenId 0)
-
--- | Generate the set of edges given the complete set of UGens.
-edges :: [UGen] -> [Edge]
-edges us = concatMap ugenEdges us
-    where ugenEdges u@(UGen _ _ i _ _ _) = map f i'
-               where g (v,_) = or [isUGen v, isProxy v, isControl v, isMRG v]
-                     n = length i - 1
-                     i' = filter g $ zip i [0..n]
-                     f (k, j) = Edge (terminal k) (Terminal u j)
-          ugenEdges _ = []
-
--- | Construct a UGen graph.
-graph :: UGen -> Graph
-graph root = Graph n c u' (edges 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@(UGen _ _ _ _ _ _) = 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@(UGen _ _ _ _ _ _) = 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 g u                    = error ("makeInput: illegal input: " ++ show (g,u))
-
--- | Construct a terminal value, the port index is set for proxied
--- | UGens.
-terminal :: UGen -> Terminal
-terminal (Proxy u n) = Terminal u n
-terminal u = Terminal u 0
diff --git a/Sound/SC3/UGen/Graph/Naive.hs b/Sound/SC3/UGen/Graph/Naive.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/Graph/Naive.hs
@@ -0,0 +1,73 @@
+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,7 +1,7 @@
 module Sound.SC3.UGen.IO where
 
-import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.UGen
+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)
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
@@ -3,7 +3,8 @@
 import Data.List
 import Data.Maybe
 import Sound.SC3.UGen.Rate (Rate(KR))
-import Sound.SC3.UGen.UGen (UGen(Constant))
+import Sound.SC3.UGen.UGen (UGen)
+import Sound.SC3.UGen.Math ()
 import Sound.SC3.UGen.UGen.Construct (mkOsc)
 
 -- | Autocorrelation beat tracker.
@@ -16,7 +17,7 @@
 
 -- | Translate onset type string to constant UGen value.
 onsetType :: String -> UGen
-onsetType s = Constant (fromIntegral (maybe 3 id (findIndex (== s) t)))
+onsetType s = fromIntegral (maybe 3 id (findIndex (== s) t))
     where t = ["power", "magsum", "complex", "rcomplex", "phase", "wphase", "mkl"]
 
 -- | Onset detector.
@@ -25,8 +26,7 @@
 
 -- | Onset detector with default values for minor parameters.
 onsets' :: UGen -> UGen -> UGen -> UGen
-onsets' c t o = onsets c t o (f 1.0) (f 0.1) (f 10.0) (f 11.0) (f 1.0)
-    where f = Constant
+onsets' c t o = onsets c t o 1.0 0.1 10.0 11.0 1.0
 
 -- | Key tracker.
 keyTrack :: UGen -> UGen -> UGen -> UGen -> UGen
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,7 +1,7 @@
 module Sound.SC3.UGen.Math where
 
 import Sound.SC3.UGen.Operator
-import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.UGen (UGen)
 import Sound.SC3.UGen.UGen.Construct
 import Sound.SC3.UGen.UGen.Math ()
 
@@ -10,237 +10,237 @@
 
 -- | Variant on Eq class, result is of the same type as the values compared.
 class EqE a where
-    (==*)  :: a -> a -> a
-    (/=*)  :: a -> a -> a
+    (==*) :: a -> a -> a
+    (/=*) :: a -> a -> a
 
 instance EqE Double where
     a ==* b = if a == b then 1.0 else 0.0
     a /=* b = if a /= b then 1.0 else 0.0
 
 instance EqE UGen where
-    (==*)  = mkBinaryOperator EQ_ (==*)
-    (/=*)  = mkBinaryOperator NE (/=*)
+    (==*) = mkBinaryOperator EQ_ (==*)
+    (/=*) = mkBinaryOperator NE (/=*)
 
 -- | Variant on Ord class, result is of the same type as the values compared.
 class OrdE a where
-    (<*)  :: a -> a -> a
+    (<*) :: a -> a -> a
     (<=*) :: a -> a -> a
-    (>*)  :: a -> a -> a
+    (>*) :: a -> a -> a
     (>=*) :: a -> a -> a
 
 instance OrdE Double where
-    a <* b   = if a < b   then 1.0 else 0.0
-    a <=* b  = if a <= b  then 1.0 else 0.0
-    a >* b   = if a > b   then 1.0 else 0.0
-    a >=* b  = if a >= b  then 1.0 else 0.0
+    a <* b = if a < b   then 1.0 else 0.0
+    a <=* b = if a <= b  then 1.0 else 0.0
+    a >* b = if a > b   then 1.0 else 0.0
+    a >=* b = if a >= b  then 1.0 else 0.0
 
 instance OrdE UGen where
-    (<*)  = mkBinaryOperator LT_ (<*)
+    (<*) = mkBinaryOperator LT_ (<*)
     (<=*) = mkBinaryOperator LE (<=*)
-    (>*)  = mkBinaryOperator GT_ (>*)
+    (>*) = mkBinaryOperator GT_ (>*)
     (>=*) = mkBinaryOperator GE (>=*)
 
 -- | Unary operator class.
-class (Floating a) => UnaryOp a where
-    notE           :: a -> a
-    isNil          :: a -> a
-    notNil         :: a -> a
-    bitNot         :: a -> a
-    asFloat        :: a -> a
-    asInt          :: a -> a
-    ceil           :: a -> a
-    floorE         :: a -> a
-    frac           :: a -> a
-    squared        :: a -> a
-    cubed          :: a -> a
-    midiCPS        :: a -> a
-    cpsMIDI        :: a -> a
-    midiRatio      :: a -> a
-    ratioMIDI      :: a -> a
-    dbAmp          :: a -> a
-    ampDb          :: a -> a
-    octCPS         :: a -> a
-    cpsOct         :: a -> a
-    log2           :: a -> a
-    log10          :: a -> a
-    distort        :: a -> a
-    softClip       :: a -> a
-
-instance UnaryOp Double where
-    notE a      = if a >  0.0 then 0.0 else 1.0
-    isNil a     = if a == 0.0 then 0.0 else 1.0
-    notNil a    = if a /= 0.0 then 0.0 else 1.0
-    bitNot      = undefined
-    asFloat     = undefined
-    asInt       = undefined
-    ceil a      = fromIntegral (ceiling a :: Integer)
-    floorE a    = fromIntegral (floor a   :: Integer)
-    frac        = undefined
-    squared a   = a * a
-    cubed   a   = a * a * a
-    midiCPS a   = 440.0 * (2.0 ** ((a - 69.0) * (1.0 / 12.0)))
-    cpsMIDI a   = (log2 (a * (1.0 / 440.0)) * 12.0) + 69.0
+class (Floating a, Ord a) => UnaryOp a where
+    ampDb :: a -> a
+    ampDb a = (log10 a) * 20
+    asFloat :: a -> a
+    asFloat = undefined
+    asInt :: a -> a
+    asInt = undefined
+    bitNot :: a -> a
+    bitNot = undefined
+    ceil :: a -> a
+    cpsMIDI :: a -> a
+    cpsMIDI a = (log2 (a * (1.0 / 440.0)) * 12.0) + 69.0
+    cpsOct :: a -> a
+    cpsOct a = log2 (a * (1.0 / 440.0)) + 4.75
+    cubed :: a -> a
+    cubed   a = a * a * a
+    dbAmp :: a -> a
+    dbAmp a = 10 ** (a * 0.05)
+    distort :: a -> a
+    distort = undefined
+    floorE :: a -> a
+    frac :: a -> a
+    frac = undefined
+    isNil :: a -> a
+    isNil a = if a == 0.0 then 0.0 else 1.0
+    log10 :: a -> a
+    log10 a = logBase 10 a
+    log2 :: a -> a
+    log2 a = logBase 2 a
+    midiCPS :: a -> a
+    midiCPS a = 440.0 * (2.0 ** ((a - 69.0) * (1.0 / 12.0)))
+    midiRatio :: a -> a
     midiRatio a = 2.0 ** (a * (1.0 / 12.0))
+    notE :: a -> a
+    notE a = if a >  0.0 then 0.0 else 1.0
+    notNil :: a -> a
+    notNil a = if a /= 0.0 then 0.0 else 1.0
+    octCPS :: a -> a
+    octCPS a = 440.0 * (2.0 ** (a - 4.75))
+    ratioMIDI :: a -> a
     ratioMIDI a = 12.0 * (log2 a)
-    dbAmp a     = 10 ** (a * 0.05)
-    ampDb a     = (log10 a) * 20
-    octCPS a    = 440.0 * (2.0 ** (a - 4.75))
-    cpsOct a    = log2 (a * (1.0 / 440.0)) + 4.75
-    log2 a      = logBase 2 a
-    log10 a     = logBase 10 a
-    distort     = undefined
-    softClip    = undefined
+    softClip :: a -> a
+    softClip = undefined
+    squared :: a -> a
+    squared a = a * a
 
+instance UnaryOp Double where
+    ceil a = fromIntegral (ceiling a :: Integer)
+    floorE a = fromIntegral (floor a :: Integer)
+
 instance UnaryOp UGen where
-    notE           = mkUnaryOperator Not notE
-    isNil          = mkUnaryOperator IsNil isNil
-    notNil         = mkUnaryOperator NotNil notNil
-    bitNot         = mkUnaryOperator BitNot bitNot
-    asFloat        = mkUnaryOperator AsFloat asFloat
-    asInt          = mkUnaryOperator AsInt asInt
-    ceil           = mkUnaryOperator Ceil ceil
-    floorE         = mkUnaryOperator Floor floorE
-    frac           = mkUnaryOperator Frac frac
-    squared        = mkUnaryOperator Squared squared
-    cubed          = mkUnaryOperator Cubed cubed
-    midiCPS        = mkUnaryOperator MIDICPS midiCPS
-    cpsMIDI        = mkUnaryOperator CPSMIDI cpsMIDI
-    midiRatio      = mkUnaryOperator MIDIRatio midiRatio
-    ratioMIDI      = mkUnaryOperator RatioMIDI ratioMIDI
-    dbAmp          = mkUnaryOperator DbAmp dbAmp
-    ampDb          = mkUnaryOperator AmpDb ampDb
-    octCPS         = mkUnaryOperator OctCPS octCPS
-    cpsOct         = mkUnaryOperator CPSOct cpsOct
-    log2           = mkUnaryOperator Log2 log2
-    log10          = mkUnaryOperator Log10 log10
-    distort        = mkUnaryOperator Distort distort
-    softClip       = mkUnaryOperator SoftClip softClip
+    ampDb = mkUnaryOperator AmpDb ampDb
+    asFloat = mkUnaryOperator AsFloat asFloat
+    asInt = mkUnaryOperator AsInt asInt
+    bitNot = mkUnaryOperator BitNot bitNot
+    ceil = mkUnaryOperator Ceil ceil
+    cpsMIDI = mkUnaryOperator CPSMIDI cpsMIDI
+    cpsOct = mkUnaryOperator CPSOct cpsOct
+    cubed = mkUnaryOperator Cubed cubed
+    dbAmp = mkUnaryOperator DbAmp dbAmp
+    distort = mkUnaryOperator Distort distort
+    floorE = mkUnaryOperator Floor floorE
+    frac = mkUnaryOperator Frac frac
+    isNil = mkUnaryOperator IsNil isNil
+    log10 = mkUnaryOperator Log10 log10
+    log2 = mkUnaryOperator Log2 log2
+    midiCPS = mkUnaryOperator MIDICPS midiCPS
+    midiRatio = mkUnaryOperator MIDIRatio midiRatio
+    notE = mkUnaryOperator Not notE
+    notNil = mkUnaryOperator NotNil notNil
+    octCPS = mkUnaryOperator OctCPS octCPS
+    ratioMIDI = mkUnaryOperator RatioMIDI ratioMIDI
+    softClip = mkUnaryOperator SoftClip softClip
+    squared = mkUnaryOperator Squared squared
 
 -- | Binary operator class.
-class (Floating a) => BinaryOp a where
-    iDiv           :: a -> a -> a
-    modE           :: a -> a -> a
-    bitAnd         :: a -> a -> a
-    bitOr          :: a -> a -> a
-    bitXOr         :: a -> a -> a
-    lcmE           :: a -> a -> a
-    gcdE           :: a -> a -> a
-    roundE         :: a -> a -> a
-    roundUp        :: a -> a -> a
-    trunc          :: a -> a -> a
-    atan2E         :: a -> a -> a
-    hypot          :: a -> a -> a
-    hypotx         :: a -> a -> a
-    shiftLeft      :: a -> a -> a
-    shiftRight     :: a -> a -> a
-    unsignedShift  :: a -> a -> a
-    fill           :: a -> a -> a
-    ring1          :: a -> a -> a
-    ring2          :: a -> a -> a
-    ring3          :: a -> a -> a
-    ring4          :: a -> a -> a
-    difSqr         :: a -> a -> a
-    sumSqr         :: a -> a -> a
-    sqrDif         :: a -> a -> a
-    sqrSum         :: a -> a -> a
-    absDif         :: a -> a -> a
-    thresh         :: a -> a -> a
-    amClip         :: a -> a -> a
-    scaleNeg       :: a -> a -> a
-    clip2          :: a -> a -> a
-    excess         :: a -> a -> a
-    fold2          :: a -> a -> a
-    wrap2          :: a -> a -> a
-    firstArg       :: a -> a -> a
-    randRange      :: a -> a -> a
-    exprandRange   :: a -> a -> a
+class (Floating a, Ord a) => BinaryOp a where
+    absDif :: a -> a -> a
+    absDif a b = abs (a - b)
+    amClip :: a -> a -> a
+    amClip a b = if b <= 0 then 0 else a * b
+    atan2E :: a -> a -> a
+    atan2E a b = atan (b/a)
+    bitAnd :: a -> a -> a
+    bitAnd = undefined
+    bitOr :: a -> a -> a
+    bitOr = undefined
+    bitXOr :: a -> a -> a
+    bitXOr = undefined
+    clip2 :: a -> a -> a
+    clip2 a b = clip_ a (-b) b
+    difSqr :: a -> a -> a
+    difSqr a b = (a*a) - (b*b)
+    excess :: a -> a -> a
+    excess a b = a - clip_ a (-b) b
+    exprandRange :: a -> a -> a
+    exprandRange = undefined
+    fill :: a -> a -> a
+    fill = undefined
+    firstArg :: a -> a -> a
+    firstArg a _ = a
+    fold2 :: a -> a -> a
+    gcdE :: a -> a -> a
+    gcdE = undefined
+    hypot :: a -> a -> a
+    hypot = undefined
+    hypotx :: a -> a -> a
+    hypotx = undefined
+    iDiv :: a -> a -> a
+    iDiv = undefined
+    lcmE :: a -> a -> a
+    lcmE = undefined
+    modE :: a -> a -> a
+    randRange :: a -> a -> a
+    randRange = undefined
+    ring1 :: a -> a -> a
+    ring1 a b = a * b + a
+    ring2 :: a -> a -> a
+    ring2 a b = a * b + a + b
+    ring3 :: a -> a -> a
+    ring3 a b = a * a * b
+    ring4 :: a -> a -> a
+    ring4 a b = a * a * b - a * b * b
+    roundE :: a -> a -> a
+    roundUp :: a -> a -> a
+    scaleNeg :: a -> a -> a
+    scaleNeg a b = (abs a - a) * b' + a where b' = 0.5 * b + 0.5
+    shiftLeft :: a -> a -> a
+    shiftLeft = undefined
+    shiftRight :: a -> a -> a
+    shiftRight = undefined
+    sqrDif :: a -> a -> a
+    sqrDif a b = (a-b) * (a-b)
+    sqrSum :: a -> a -> a
+    sqrSum a b = (a+b) * (a+b)
+    sumSqr :: a -> a -> a
+    sumSqr a b = (a*a) + (b*b)
+    thresh :: a -> a -> a
+    thresh a b = if a <  b then 0 else a
+    trunc :: a -> a -> a
+    trunc = undefined
+    unsignedShift :: a -> a -> a
+    unsignedShift = undefined
+    wrap2 :: a -> a -> a
 
 instance BinaryOp Double where
-    iDiv               = undefined
-    modE a b           = n - floorE n where n = a / b
-    bitAnd             = undefined
-    bitOr              = undefined
-    bitXOr             = undefined
-    lcmE               = undefined
-    gcdE               = undefined
-    roundE a b         = if b == 0 then a else floorE (a/b + 0.5) * b
-    roundUp a b        = if b == 0 then a else ceil (a/b + 0.5) * b
-    trunc              = undefined
-    atan2E a b         = atan (b/a)
-    hypot              = undefined
-    hypotx             = undefined
-    shiftLeft          = undefined
-    shiftRight         = undefined
-    unsignedShift      = undefined
-    fill               = undefined
-    ring1 a b          = a * b + a
-    ring2 a b          = a * b + a + b
-    ring3 a b          = a * a * b
-    ring4 a b          = a * a * b - a * b * b
-    difSqr a b         = (a*a) - (b*b)
-    sumSqr a b         = (a*a) + (b*b)
-    sqrSum a b         = (a+b) * (a+b)
-    sqrDif a b         = (a-b) * (a-b)
-    absDif a b         = abs (a - b)
-    thresh a b         = if a <  b then 0 else a
-    amClip a b         = if b <= 0 then 0 else a * b
-    scaleNeg a b       = (abs a - a) * b' + a where b' = 0.5 * b + 0.5
-    clip2 a b          = clip_ a (-b) b
-    excess a b         = a - clip_ a (-b) b
-    fold2 a b          = fold a (-b) b
-    wrap2 a b          = wrap a (-b) b
-    firstArg a _       = a
-    randRange          = undefined
-    exprandRange       = undefined
+    fold2 a b = fold a (-b) b
+    modE a b = n - floorE n where n = a / b
+    roundE a b = if b == 0 then a else floorE (a/b + 0.5) * b
+    roundUp a b = if b == 0 then a else ceil (a/b + 0.5) * b
+    wrap2 a b = wrap a (-b) b
 
 instance BinaryOp UGen where
-    iDiv           = mkBinaryOperator IDiv undefined
-    modE           = mkBinaryOperator Mod modE
-    bitAnd         = mkBinaryOperator BitAnd undefined
-    bitOr          = mkBinaryOperator BitOr undefined
-    bitXOr         = mkBinaryOperator BitXor undefined
-    lcmE           = mkBinaryOperator LCM undefined
-    gcdE           = mkBinaryOperator GCD undefined
-    roundE         = mkBinaryOperator Round undefined
-    roundUp        = mkBinaryOperator RoundUp undefined
-    trunc          = mkBinaryOperator Trunc undefined
-    atan2E         = mkBinaryOperator Atan2 undefined
-    hypot          = mkBinaryOperator Hypot undefined
-    hypotx         = mkBinaryOperator Hypotx undefined
-    shiftLeft      = mkBinaryOperator ShiftLeft undefined
-    shiftRight     = mkBinaryOperator ShiftRight undefined
-    unsignedShift  = mkBinaryOperator UnsignedShift undefined
-    fill           = mkBinaryOperator Fill undefined
-    ring1          = mkBinaryOperator Ring1 undefined
-    ring2          = mkBinaryOperator Ring2 undefined
-    ring3          = mkBinaryOperator Ring3 undefined
-    ring4          = mkBinaryOperator Ring4 undefined
-    difSqr         = mkBinaryOperator DifSqr undefined
-    sumSqr         = mkBinaryOperator SumSqr undefined
-    sqrSum         = mkBinaryOperator SqrSum undefined
-    sqrDif         = mkBinaryOperator SqrDif undefined
-    absDif         = mkBinaryOperator AbsDif undefined
-    thresh         = mkBinaryOperator Thresh undefined
-    amClip         = mkBinaryOperator AMClip undefined
-    scaleNeg       = mkBinaryOperator ScaleNeg undefined
-    clip2          = mkBinaryOperator Clip2 undefined
-    excess         = mkBinaryOperator Excess undefined
-    fold2          = mkBinaryOperator Fold2 undefined
-    wrap2          = mkBinaryOperator Wrap2 undefined
-    firstArg       = mkBinaryOperator FirstArg undefined
-    randRange      = mkBinaryOperator RandRange undefined
-    exprandRange   = mkBinaryOperator ExpRandRange undefined
+    iDiv = mkBinaryOperator IDiv undefined
+    modE = mkBinaryOperator Mod modE
+    bitAnd = mkBinaryOperator BitAnd undefined
+    bitOr = mkBinaryOperator BitOr undefined
+    bitXOr = mkBinaryOperator BitXor undefined
+    lcmE = mkBinaryOperator LCM undefined
+    gcdE = mkBinaryOperator GCD undefined
+    roundE = mkBinaryOperator Round undefined
+    roundUp = mkBinaryOperator RoundUp undefined
+    trunc = mkBinaryOperator Trunc undefined
+    atan2E = mkBinaryOperator Atan2 undefined
+    hypot = mkBinaryOperator Hypot undefined
+    hypotx = mkBinaryOperator Hypotx undefined
+    shiftLeft = mkBinaryOperator ShiftLeft undefined
+    shiftRight = mkBinaryOperator ShiftRight undefined
+    unsignedShift = mkBinaryOperator UnsignedShift undefined
+    fill = mkBinaryOperator Fill undefined
+    ring1 = mkBinaryOperator Ring1 undefined
+    ring2 = mkBinaryOperator Ring2 undefined
+    ring3 = mkBinaryOperator Ring3 undefined
+    ring4 = mkBinaryOperator Ring4 undefined
+    difSqr = mkBinaryOperator DifSqr undefined
+    sumSqr = mkBinaryOperator SumSqr undefined
+    sqrSum = mkBinaryOperator SqrSum undefined
+    sqrDif = mkBinaryOperator SqrDif undefined
+    absDif = mkBinaryOperator AbsDif undefined
+    thresh = mkBinaryOperator Thresh undefined
+    amClip = mkBinaryOperator AMClip undefined
+    scaleNeg = mkBinaryOperator ScaleNeg undefined
+    clip2 = mkBinaryOperator Clip2 undefined
+    excess = mkBinaryOperator Excess undefined
+    fold2 = mkBinaryOperator Fold2 undefined
+    wrap2 = mkBinaryOperator Wrap2 undefined
+    firstArg = mkBinaryOperator FirstArg undefined
+    randRange = mkBinaryOperator RandRange undefined
+    exprandRange = mkBinaryOperator ExpRandRange undefined
 
 wrap :: (UnaryOp a, Ord a) => a -> a -> a -> a
 wrap a b c = if a >= b && a <= c then a else a - r * floorE (a-b)/r 
-        where r = c - b
+    where r = c - b
 
 fold :: (UnaryOp a, Ord a) => a -> a -> a -> a
 fold a b c = if a >= b && a <= c then a else y' + b
-    where r  = c - b
+    where r = c - b
           r' = r + r
-          x  = a - b
-          y  = x - r' * floorE x/r'
+          x = a - b
+          y = x - r' * floorE x/r'
           y' = if y >= r then r' - y else y
 
 clip_ :: (Ord a) => a -> a -> a -> a
diff --git a/Sound/SC3/UGen/Mix.hs b/Sound/SC3/UGen/Mix.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/Mix.hs
+++ /dev/null
@@ -1,31 +0,0 @@
-module Sound.SC3.UGen.Mix (mix, mixFill, freqShift, splay) where
-
-import Sound.SC3.UGen.Filter
-import Sound.SC3.UGen.Oscillator
-import Sound.SC3.UGen.Panner
-import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.UGen
-import Sound.SC3.UGen.UGen.Math ()
-import Sound.SC3.UGen.UGen.MCE
-
--- | Collapse MCE by summing.
-mix :: UGen -> UGen
-mix (MCE u)  = foldl1 (+) u
-mix u        = u
-
--- | Construct and sum a set of UGens.
-mixFill :: Int -> (Int -> UGen) -> UGen
-mixFill n f = mix (MCE (map f [0..n-1]))
-
--- | 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
-
--- | 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))
-    where n = fromIntegral (mceDegree i)
-          m = n - 1
-          p = map ( (+ (-1.0)) . (* (2 / m)) ) [0 .. m]
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
@@ -56,6 +56,10 @@
 lfdNoise2 :: UGenId -> Rate -> UGen -> UGen
 lfdNoise2 z r freq = mkOscId z r "LFDNoise2" [freq] 1
 
+-- | Dynamic cubic noise
+lfdNoise3 :: UGenId -> Rate -> UGen -> UGen
+lfdNoise3 z r freq = mkOscId z r "LFDNoise3" [freq] 1
+
 -- | Step noise.
 lfNoise0 :: UGenId -> Rate -> UGen -> UGen
 lfNoise0 z r freq = mkOscId z r "LFNoise0" [freq] 1
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,7 +1,7 @@
 module Sound.SC3.UGen.Noise.Monadic where
 
-import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.UGen
+import Sound.SC3.UGen.Rate (Rate)
+import Sound.SC3.UGen.UGen (UGen)
 import Sound.SC3.UGen.UGen.Construct
 import qualified Sound.SC3.UGen.Noise.Base as N
 import Sound.SC3.UGen.UId
@@ -57,6 +57,10 @@
 -- | Dynamic quadratic noise
 lfdNoise2 :: (UId m) => Rate -> UGen -> m UGen
 lfdNoise2 = liftU2 N.lfdNoise2
+
+-- | Dynamic cubic noise
+lfdNoise3 :: (UId m) => Rate -> UGen -> m UGen
+lfdNoise3 = liftU2 N.lfdNoise3
 
 -- | Step noise.
 lfNoise0 :: (UId m) => Rate -> UGen -> m UGen
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,7 +1,7 @@
 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 (UGen, mce)
 import Sound.SC3.UGen.UGen.Construct (mkOsc, mkOscMCE)
 import Data.List(transpose)
 
@@ -31,7 +31,7 @@
 
 -- | Format frequency, amplitude and phase data as required for klang.
 klangSpec :: [UGen] -> [UGen] -> [UGen] -> UGen
-klangSpec f a p = MCE ((concat . transpose) [f, a, p])
+klangSpec f a p = mce ((concat . transpose) [f, a, p])
 
 -- | Upsample control rate signal to audio rate.
 k2A :: UGen -> UGen
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,5 +1,9 @@
 module Sound.SC3.UGen.UGen ( Name, UGenId(..), UGen(..), Output, Special(..)
-                           , clone ) where
+                           , constant, control
+                           , mce, mce2
+                           , mrg, mrg2
+                           , proxy
+                           , clone, uid ) where
 
 import Control.Monad (liftM, replicateM)
 import Sound.SC3.UGen.Rate (Rate)
@@ -13,18 +17,53 @@
           | Control { controlRate_ :: Rate
                     , controlName :: Name
                     , controlDefault :: Double }
-          | UGen { ugenRate :: Rate
-                 , ugenName :: Name
-                 , ugenInputs :: [UGen]
-                 , ugenOuputs :: [Output]
-                 , ugenSpecial :: Special
-                 , ugenId :: UGenId }
+          | Primitive { ugenRate :: Rate
+                      , ugenName :: Name
+                      , ugenInputs :: [UGen]
+                      , ugenOutputs :: [Output]
+                      , ugenSpecial :: Special
+                      , ugenId :: Maybe UGenId }
           | Proxy { proxySource :: UGen
                   , proxyIndex :: Int }
           | MCE { mceProxies :: [UGen] }
-          | MRG { mrgRoots :: [UGen] }
+          | MRG { mrgLeft :: UGen 
+                , mrgRight :: UGen }
             deriving (Eq, Show)
 
+-- | UGen identifier constructor.
+uid :: Int -> UGenId
+uid = UGenId
+
+-- | Constant value constructor.
+constant :: (Real a) => a -> UGen
+constant = Constant . realToFrac
+
+-- | Control input constructor.
+control :: Rate -> Name -> Double -> UGen
+control = Control
+
+-- | Multiple channel expansion constructor.
+mce :: [UGen] -> UGen
+mce = MCE
+
+-- | Multiple channel expansion for two inputs.
+mce2 :: UGen -> UGen -> UGen
+mce2 x y = mce [x, y]
+
+-- | 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
+
+proxy :: UGen -> Int -> UGen
+proxy = Proxy
+
 -- | Clone UGen.
 clone :: (UId m) => Int -> m UGen -> m UGen
-clone n u = liftM MCE (replicateM n u)
+clone n u = liftM mce (replicateM n u)
+
diff --git a/Sound/SC3/UGen/UGen/Construct.hs b/Sound/SC3/UGen/UGen/Construct.hs
--- a/Sound/SC3/UGen/UGen/Construct.hs
+++ b/Sound/SC3/UGen/UGen/Construct.hs
@@ -9,89 +9,107 @@
 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.
-proxy :: UGen -> UGen
-proxy (MCE l) = MCE (map proxy l)
-proxy u@(UGen _ _ _ o _ _) = case o of
-                               (_:_:_) -> MCE (map (Proxy u) [0..(length o - 1)])
-                               _       -> u
-proxy (MRG (x:xs)) = MRG (proxy x : xs)
-proxy _ = error "proxy: illegal ugen"
+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 (Constant _) = IR
-rateOf (Control r _ _) = r
-rateOf (UGen r _ _ _ _ _) = r
-rateOf (Proxy u _) = rateOf u
-rateOf (MCE u) = maximum (map rateOf u)
-rateOf (MRG (u:_)) = rateOf u
-rateOf _ = undefined
+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 (UGen _ _ _ o _ _) = null o
-isSink (MCE u) = all isSink u
-isSink (MRG (l:_)) = isSink l
-isSink _ = False
+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 -> UGenId -> UGen
-mkUGen r n i o s z = proxy (mceExpand u)
-    where u = UGen r n (map checkInput i) o s z
+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) (UGenId 0)
+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 _ f (Constant a) = Constant (f a)
-mkUnaryOperator i _ a = mkOperator "UnaryOpUGen" [a] (fromEnum i)
+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 _ f (Constant a) (Constant b) = Constant (f a b)
-mkBinaryOperator i _ a b = mkOperator "BinaryOpUGen" [a, b] (fromEnum i)
+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)
 
--- | Oscillator constructor.
-mkOscId :: UGenId -> Rate -> Name -> [UGen] -> Int -> UGen
-mkOscId z r c i o = mkUGen r c i (replicate o r) (Special 0) z
+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 = mkOscId (UGenId 0)
+mkOsc = mkOsc_ Nothing
 
--- | Variant oscillator constructor with MCE collapsing input.
-mkOscMCEId :: UGenId -> Rate -> Name -> [UGen] -> UGen -> Int -> UGen
-mkOscMCEId z r c i j o = mkOscId z r c (i ++ mceChannels j) o
+-- | 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 = mkOscMCEId (UGenId 0)
+mkOscMCE = mkOscMCE_ Nothing
 
--- | Filter UGen constructor.
-mkFilterId :: UGenId -> Name -> [UGen] -> Int -> UGen
-mkFilterId z c i o = mkUGen r c i o' (Special 0) z
+-- | 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 = mkFilterId (UGenId 0)
+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) (UGenId 0)
+mkFilterKeyed c k i o = mkUGen r c i o' (Special 0) Nothing
     where r = rateOf (i !! k)
           o' = replicate o r
 
diff --git a/Sound/SC3/UGen/UGen/MCE.hs b/Sound/SC3/UGen/UGen/MCE.hs
--- a/Sound/SC3/UGen/UGen/MCE.hs
+++ b/Sound/SC3/UGen/UGen/MCE.hs
@@ -9,31 +9,31 @@
 -- | Number of channels to expand to.
 mceDegree :: UGen -> Int
 mceDegree (MCE l) = length l
-mceDegree _       = error "mceDegree: illegal ugen"
-
--- | Is expansion required, ie. are any inputs MCE values.
-mceRequired :: UGen -> Bool
-mceRequired (UGen _ _ i _ _ _) = not (null (filter isMCE i))
-mceRequired (MCE l)            = any mceRequired l
-mceRequired _                  = False
+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 u       = replicate n u
+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 (UGen r n i o s d) = MCE (map f i')
-    where f j = UGen r n j o s d
+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)
+          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 u       = if mceRequired u then mceExpand (mceTransform u) else u
+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
@@ -47,10 +47,14 @@
 -- | Obtain indexed channel at MCE.
 mceChannel :: Int -> UGen -> UGen
 mceChannel n (MCE l) = l !! n
-mceChannel _ _       = error "mceChannel: non MCE value"
+mceChannel _ _ = error "mceChannel: non MCE value"
 
 -- | Output channels of UGen as a list.
 mceChannels :: UGen -> [UGen]
 mceChannels (MCE l) = l
-mceChannels u       = [u]
+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
--- a/Sound/SC3/UGen/UGen/Math.hs
+++ b/Sound/SC3/UGen/UGen/Math.hs
@@ -12,12 +12,12 @@
     (*)            = mkBinaryOperator Mul (*)
     abs            = mkUnaryOperator Abs abs
     signum         = mkUnaryOperator Sign signum
-    fromInteger a  = Constant (fromInteger a)
+    fromInteger    = Constant . fromInteger
 
 instance Fractional UGen where
     recip          = mkUnaryOperator Recip recip
     (/)            = mkBinaryOperator FDiv (/)
-    fromRational a = Constant (fromRational a)
+    fromRational   = Constant . fromRational
 
 instance Floating UGen where
     pi             = Constant pi
@@ -67,7 +67,7 @@
 instance Enum UGen where
     succ u                = u + 1
     pred u                = u - 1
-    toEnum i              = Constant (fromIntegral i)
+    toEnum i              = constant i
     fromEnum (Constant n) = truncate n
     fromEnum _            = error "cannot enumerate non-constant UGens"
     enumFrom              = iterate (+1)
@@ -77,7 +77,7 @@
         where p = if n' >= n then (>=) else (<=)
 
 instance Random UGen where
-    randomR (Constant l, Constant r) g = (Constant n, g') 
-        where (n, g') = randomR (l,r) g
-    randomR _                        _ = error "randomR: non constant (l,r)"
-    random g = randomR (-1.0,1.0) g
+    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
--- a/Sound/SC3/UGen/UGen/Predicate.hs
+++ b/Sound/SC3/UGen/UGen/Predicate.hs
@@ -14,8 +14,8 @@
 
 -- | UGen predicate.
 isUGen :: UGen -> Bool
-isUGen (UGen _ _ _ _ _ _) = True
-isUGen _                  = False
+isUGen (Primitive _ _ _ _ _ _) = True
+isUGen _ = False
 
 -- | Proxy predicate.
 isProxy :: UGen -> Bool
@@ -29,6 +29,6 @@
 
 -- | MRG predicate.
 isMRG :: UGen -> Bool
-isMRG (MRG _) = True
-isMRG _       = False
+isMRG (MRG _ _) = True
+isMRG _ = False
 
diff --git a/emacs/hsc3.el b/emacs/hsc3.el
--- a/emacs/hsc3.el
+++ b/emacs/hsc3.el
@@ -1,4 +1,4 @@
-;; hsc3.el - (c) rohan drape, 2006-2007
+;; hsc3.el - (c) rohan drape, 2006-2008
 
 ;; This mode is implemented as a derivation of `haskell' mode,
 ;; indentation and font locking is courtesy that mode.  The
@@ -123,10 +123,20 @@
   (let* ((s (buffer-substring (line-beginning-position)
 			      (line-end-position)))
 	 (s* (if hsc3-literate-p
-		 (substring s 2)
+		 (hsc3-unlit s)
 	       s)))
     (hsc3-send-string s*)))
 
+(defun hsc3-run-multiple-lines ()
+  "Send the current region to the interpreter as a single line."
+  (interactive)
+  (let* ((s (buffer-substring-no-properties (region-beginning)
+					    (region-end)))
+	 (s* (if hsc3-literate-p
+		 (hsc3-unlit s)
+	       s)))
+    (hsc3-send-string (replace-regexp-in-string "\n" " " s*))))
+
 (defun hsc3-run-region ()
   "Place the region in a do block and compile."
   (interactive)
@@ -180,7 +190,8 @@
   (define-key map [?\C-c ?\C-k] 'hsc3-reset-scsynth)
   (define-key map [?\C-c ?\C-w] 'hsc3-status-scsynth)
   (define-key map [?\C-c ?\C-c] 'hsc3-run-line)
-  (define-key map [?\C-c ?\C-e] 'hsc3-run-region)
+  (define-key map [?\C-c ?\C-e] 'hsc3-run-multiple-lines)
+  (define-key map [?\C-c ?\C-r] 'hsc3-run-region)
   (define-key map [?\C-c ?\C-l] 'hsc3-load-buffer)
   (define-key map [?\C-c ?\C-i] 'hsc3-interrupt-haskell)
   (define-key map [?\C-c ?\C-m] 'hsc3-run-main)
@@ -195,7 +206,8 @@
   (local-set-key [?\C-c ?\C-k] 'hsc3-reset-scsynth)
   (local-set-key [?\C-c ?\C-w] 'hsc3-status-scsynth)
   (local-set-key [?\C-c ?\C-c] 'hsc3-run-line)
-  (local-set-key [?\C-c ?\C-e] 'hsc3-run-region)
+  (local-set-key [?\C-c ?\C-e] 'hsc3-run-multiple-lines)
+  (local-set-key [?\C-c ?\C-r] 'hsc3-run-region)
   (local-set-key [?\C-c ?\C-l] 'hsc3-load-buffer)
   (local-set-key [?\C-c ?\C-i] 'hsc3-interrupt-haskell)
   (local-set-key [?\C-c ?\C-m] 'hsc3-run-main)
@@ -218,6 +230,8 @@
     '("Run main" . hsc3-run-main))
   (define-key map [menu-bar hsc3 expression run-region]
     '("Run region" . hsc3-run-region))
+  (define-key map [menu-bar hsc3 expression run-multiple-lines]
+    '("Run multiple lines" . hsc3-run-multiple-lines))
   (define-key map [menu-bar hsc3 expression run-line]
     '("Run line" . hsc3-run-line))
   (define-key map [menu-bar hsc3 scsynth]
diff --git a/hsc3.cabal b/hsc3.cabal
--- a/hsc3.cabal
+++ b/hsc3.cabal
@@ -1,7 +1,7 @@
 Name:             hsc3
-Version:          0.1.1
+Version:          0.2
 License:          GPL
-Copyright:        Rohan Drape, 2006-2007
+Copyright:        Rohan Drape, 2006-2008
 Author:           Rohan Drape
 Maintainer:       rd@slavepianos.org
 Stability:        Experimental
@@ -9,11 +9,124 @@
 Synopsis:         Haskell SuperCollider
 Description:      Haskell client for the SuperCollider synthesis server
 Category:         Sound
-Tested-With:      GHC==6.4.1, GHC==6.8.2
-Cabal-Version:    >=1.2
+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
 
-Data-files:       emacs/hsc3.el
+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
@@ -115,6 +228,7 @@
                   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
@@ -205,6 +319,7 @@
                   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
@@ -322,63 +437,10 @@
                   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
-
-Flag splitBase
-  description: Choose the new smaller, split-up base package.
-
-Library
-  Build-Depends:  binary, bytestring, hosc>=0.1 && <0.2, network
-  If flag(splitBase)
-    Build-Depends: base >= 2, random
-  Else
-    Build-Depends: base >= 1.0 && < 2
-
-  GHC-Options:     -Wall -fno-warn-orphans
-  Exposed-modules: Sound.SC3
-                   Sound.SC3.UGen
-                   Sound.SC3.UGen.Analysis
-                   Sound.SC3.UGen.Buffer
-                   Sound.SC3.UGen.Chaos
-                   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
-                   Sound.SC3.UGen.Granular
-                   Sound.SC3.UGen.Information
-                   Sound.SC3.UGen.IO
-                   Sound.SC3.UGen.MachineListening
-                   Sound.SC3.UGen.Math
-                   Sound.SC3.UGen.Mix
-                   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.Graphdef
-                   Sound.SC3.Server.Play
-                   Sound.SC3.Server.Status
-                   Sound.SC3.Server.NRT
-  Other-modules:   Sound.SC3.Server.Utilities
-                   Sound.SC3.UGen.Utilities
