diff --git a/Help/Server/b_alloc.help.lhs b/Help/Server/b_alloc.help.lhs
--- a/Help/Server/b_alloc.help.lhs
+++ b/Help/Server/b_alloc.help.lhs
@@ -1,11 +1,18 @@
-> Sound.SC3.Server.Help.viewServerHelp "/b_alloc"
+    Sound.SC3.Server.Help.viewServerHelp "/b_alloc"
 
 Buffer indices are not restricted by the number of available buffers
-at the server.  Below allocates a buffer at index 8192.
+at the server.  Below allocates a buffer at index 2 ^ 15.
 
-> withSC3 (async (b_alloc_setn1 8192 0 [0,3,7,10]))
+> import Sound.SC3 {- hsc3 -}
 
-> let {x = mouseX KR 0 9 Linear 0.1
->     ;k = degreeToKey 8192 x 12
->     ;o = sinOsc AR (midiCPS (48 + k)) 0 * 0.1}
-> in audition (out 0 o)
+> b0 :: Num n => n
+> b0 = 2 ^ 15
+
+> m0 = b_alloc_setn1 b0 0 [0,3,7,10]
+
+    withSC3 (async m0)
+
+> g0 =
+>     let x = mouseX KR 0 9 Linear 0.1
+>         k = degreeToKey b0 x 12
+>     in sinOsc AR (midiCPS (48 + k)) 0 * 0.1
diff --git a/Help/Server/b_allocRead.help.lhs b/Help/Server/b_allocRead.help.lhs
--- a/Help/Server/b_allocRead.help.lhs
+++ b/Help/Server/b_allocRead.help.lhs
@@ -1,12 +1,14 @@
-> Sound.SC3.Server.Help.viewServerHelp "/b_allocRead"
+    Sound.SC3.Server.Help.viewServerHelp "/b_allocRead"
 
-> import Sound.SC3
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
 
 Read a large audio file into a buffer.
 
-> let fn = "/home/rohan/data/audio/xenakis/jonchaies.wav"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
+> fn = "/home/rohan/data/audio/xenakis/jonchaies.wav"
 
+    withSC3 (async (b_allocRead 0 fn 0 0))
+
 Audio data is loaded in IEEE 32-bit form, so in-memory storage can be
 greater than on-disk storage.
 
@@ -18,27 +20,32 @@
 162M    data/audio/xenakis/jonchaies.wav
 $
 
-> round ((16 * 60 * 44100 * 4 * 2) / (1024 * 1024)) == 323
-> round ((42271320 * 2 * 4) / (1024 * 1024)) == 323
+    round ((16 * 60 * 44100 * 4 * 2) / (1024 * 1024)) == 323
+    round ((42271320 * 2 * 4) / (1024 * 1024)) == 323
 
 Query buffer.
 
-> withSC3 (do {send (b_query [0])
->             ;r <- waitReply "/b_info"
->             ;liftIO (print r)})
+> q0 :: Connection UDP ()
+> q0 = do
+>      sendMessage (b_query [0])
+>      r <- waitReply "/b_info"
+>      liftIO (print r)
 
+    withSC3 q0
+
 Play buffer.
 
-> let {n = 257; s = bufRateScale KR n}
-> in audition (out 0 (playBuf 1 AR n s 1 0 NoLoop RemoveSynth))
+> g0 =
+>     let n = 257
+>         s = bufRateScale KR n
+>     in playBuf 1 AR n s 1 0 NoLoop RemoveSynth
 
 Re-read file into buffer with the same identifier.  The existing
 buffer is freed but not before further memory is allocated,
 intermediate in-memory use is greater than final memory use.
 
-> let fn = "/home/rohan/data/audio/xenakis/jonchaies.wav"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
+    withSC3 (async (b_allocRead 0 fn 0 0))
 
 Free buffer.  Memory is immediately made free.
 
-> withSC3 (async (b_free 0))
+    withSC3 (async (b_free 0))
diff --git a/Help/Server/b_allocReadChannel.help.lhs b/Help/Server/b_allocReadChannel.help.lhs
--- a/Help/Server/b_allocReadChannel.help.lhs
+++ b/Help/Server/b_allocReadChannel.help.lhs
@@ -1,1 +1,29 @@
 > Sound.SC3.Server.Help.viewServerHelp "/b_allocReadChannel"
+
+> import Sound.SC3
+
+Read an audio file with many channels (here 2000)
+
+> let fn = "/home/rohan/sw/hsc3-sf/au/mc-12-2000.au"
+
+> withSC3 (async (b_allocRead 0 fn 0 0))
+
+Query buffer
+
+> withSC3 (b_query1_unpack 0)
+
+Read only specified channels
+
+> withSC3 (async (b_allocReadChannel 0 fn 0 0 [0..1023]))
+
+Query buffer
+
+> withSC3 (b_query1_unpack 0)
+
+Examine buffer
+
+> import Data.List {- base -}
+> import Data.List.Split {- split -}
+> let (nf,nc) = (12,1024)
+> d <- withSC3 (b_getn1_data_segment 128 0 (0,nf * nc))
+> (putStrLn . unlines . transpose . chunksOf nc . map (\n -> if n > 0 then '1' else '0')) d
diff --git a/Help/Server/b_free.help.lhs b/Help/Server/b_free.help.lhs
--- a/Help/Server/b_free.help.lhs
+++ b/Help/Server/b_free.help.lhs
@@ -1,9 +1,11 @@
-> Sound.SC3.Server.Help.viewServerHelp "/b_free"
+    Sound.SC3.Server.Help.viewServerHelp "/b_free"
 
+> import Sound.SC3 {- hsc3 -}
+
 It is safe to free un-allocated buffers.
 
-> withSC3 (async (b_free (2 ^ 15)))
+    withSC3 (async (b_free (2 ^ 15)))
 
 There is no multiple buffer form.
 
-> withSC3 (mapM_ (\k -> async (b_free k)) [0..256])
+    withSC3 (mapM_ (\k -> async (b_free k)) [0..256])
diff --git a/Help/Server/b_query.help.lhs b/Help/Server/b_query.help.lhs
--- a/Help/Server/b_query.help.lhs
+++ b/Help/Server/b_query.help.lhs
@@ -15,6 +15,12 @@
 >             ;r <- waitReply "/b_info"
 >             ;liftIO (print r)})
 
+Variant that unpacks the result.
+
+Query is of (buffer-id/int,#-frames/int,#-channels/int,sample-rate/float).
+
+> withSC3 (b_query1_unpack 0)
+
 Play buffer
 
 > audition (out 0 (osc AR 0 220 0 * 0.1))
diff --git a/Help/Server/c_get.help.lhs b/Help/Server/c_get.help.lhs
--- a/Help/Server/c_get.help.lhs
+++ b/Help/Server/c_get.help.lhs
@@ -1,7 +1,7 @@
 > Sound.SC3.Server.Help.viewServerHelp "/c_get"
 
 > import Sound.OSC {- hosc -}
-> import Sound.SC3.ID {- hsc3 -}
+> import Sound.SC3 {- hsc3 -}
 
 > audition (out 0 (tRand 'α' 220 2200 (dust 'β' KR 1)))
 
diff --git a/Help/Server/dumpOSC.help.lhs b/Help/Server/dumpOSC.help.lhs
--- a/Help/Server/dumpOSC.help.lhs
+++ b/Help/Server/dumpOSC.help.lhs
@@ -1,8 +1,15 @@
-> Sound.SC3.Server.Help.viewServerHelp "/dumpOSC"
+    Sound.SC3.Server.Help.viewServerHelp "/dumpOSC"
 
-> import Sound.SC3.ID
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
 
-> withSC3 (send (dumpOSC TextPrinter))
-> audition (out 0 (sinOsc AR (rand 'α' 440 880) 0 * 0.1))
-> withSC3 reset
-> withSC3 (send (dumpOSC NoPrinter))
+> ex_01 :: Transport m => m ()
+> ex_01 = do
+>   sendMessage (dumpOSC TextPrinter)
+>   play (out 0 (sinOsc AR (rand 'α' 440 880) 0 * 0.1))
+>   pauseThread 1.0
+>   reset
+>   sendMessage (dumpOSC NoPrinter)
+
+    withSC3 ex_01
+    withSC3 (sendMessage (dumpOSC TextPrinter))
diff --git a/Help/Server/g_freeAll.help.lhs b/Help/Server/g_freeAll.help.lhs
--- a/Help/Server/g_freeAll.help.lhs
+++ b/Help/Server/g_freeAll.help.lhs
@@ -1,1 +1,8 @@
-> Sound.SC3.Server.Help.viewServerHelp "/g_freeAll"
+    > Sound.SC3.Server.Help.viewServerHelp "/g_freeAll"
+
+> import Sound.OSC
+> import Sound.SC3
+
+> m1 = g_freeAll [0]
+
+     > withSC3 (sendMessage m1)
diff --git a/Help/Server/g_queryTree.help.lhs b/Help/Server/g_queryTree.help.lhs
--- a/Help/Server/g_queryTree.help.lhs
+++ b/Help/Server/g_queryTree.help.lhs
@@ -1,28 +1,27 @@
-> Sound.SC3.Server.Help.viewServerHelp "/g_queryTree"
+    > Sound.SC3.Server.Help.viewServerHelp "/g_queryTree"
 
 > import Sound.OSC {- hosc -}
 > import Sound.SC3 {- hsc3 -}
+> import qualified Data.Tree as T {- containers -}
 
-> let d = let {f = control KR "freq" 440
->             ;o = saw AR f * 0.05}
->         in synthdef "saw" (out 0 o)
+> d_0 =
+>     let f = control KR "freq" 440
+>         o = saw AR f * 0.05
+>     in synthdef "saw" (out 0 o)
 
-> withSC3 (async (d_recv d) >>
->          send (g_new [(100,AddToTail,1)]) >>
->          send (s_new0 "saw" 1000 AddToTail 100))
+> m_0 = [d_recv d_0,g_new [(100,AddToTail,1)],s_new0 "saw" 1000 AddToTail 100]
 
-> r <- withSC3 (send (g_queryTree [(0,True)]) >>
->               waitReply "/g_queryTree.reply")
+    > withSC3 (mapM_ maybe_async m_0)
 
-> print r
+> run_query_tree = withSC3 (g_queryTree1_unpack 0)
 
-> withSC3 (send (g_dumpTree [(0,True)]))
+    > qt <- run_query_tree
+    > print qt
+    > withSC3 (sendMessage (g_dumpTree [(0,True)]))
+    > queryNode_to_group_seq qt
 
-There is support for extracting the node tree into standard haskell
+There is support for extracting the node tree into the standard haskell
 tree data type.
 
-> import qualified Data.Tree as T {- containers -}
-
-> let tr = queryTree_rt (queryTree (messageDatum r))
-
-> putStrLn (unlines ["::TREE::",T.drawTree (fmap query_node_pp tr)])
+    > r_tr = queryTree_rt qt
+    > putStrLn (unlines ["::TREE::",T.drawTree (fmap query_node_pp r_tr)])
diff --git a/Help/Server/n_query.help.lhs b/Help/Server/n_query.help.lhs
--- a/Help/Server/n_query.help.lhs
+++ b/Help/Server/n_query.help.lhs
@@ -1,16 +1,14 @@
 > Sound.SC3.Server.Help.viewServerHelp "/n_query"
 
-> import Sound.OSC
-> import Sound.SC3
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
 
 > let d = let {f = control KR "freq" 440
 >             ;o = saw AR f * 0.1}
 >         in synthdef "saw" (out 0 o)
 
-> withSC3 (async (d_recv d) >>
->          send (s_new0 "saw" 1000 AddToTail 1))
+> withSC3 (async (d_recv d) >> send (s_new0 "saw" 1000 AddToTail 1))
 
-> r <- withSC3 (send (n_query [1000]) >>
->               waitReply "/n_info")
+> r <- withSC3 (withNotifications (send (n_query [1000]) >> waitReply "/n_info"))
 
 > print r
diff --git a/Help/Server/notify.help.lhs b/Help/Server/notify.help.lhs
--- a/Help/Server/notify.help.lhs
+++ b/Help/Server/notify.help.lhs
@@ -1,10 +1,17 @@
-> Sound.SC3.Server.Help.viewServerHelp "/notify"
+     Sound.SC3.Server.Help.viewServerHelp "/notify"
 
-> import Sound.OSC
-> import Sound.SC3.ID
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
 
-> let g = synthdef "g" (out 0 (sinOsc AR (rand 'a' 440 880) 0 * 0.1))
-> in withSC3 (async (d_recv g))
+> g_01 = sinOsc AR (rand 'α' 440 880) 0 * 0.1
 
-> withSC3 (withNotifications (do {send (s_new "g" (-2) AddToHead 1 [])
->                                ;waitReply "/n_go"}))
+> s_01 = synthdef "g" (out 0 g_01)
+
+> m_01 = s_new "g" (-1) AddToHead 1 []
+
+> f_01 :: DuplexOSC m => m Message
+> f_01 = do
+>   async_ (d_recv s_01)
+>   withNotifications (sendMessage m_01 >> waitReply "/n_go")
+
+    withSC3 (f_01 >>= \r -> liftIO (print r))
diff --git a/Help/UGen/Analysis/amplitude.help.lhs b/Help/UGen/Analysis/amplitude.help.lhs
deleted file mode 100644
--- a/Help/UGen/Analysis/amplitude.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Amplitude"
-> Sound.SC3.UGen.DB.ugenSummary "Amplitude"
-
-> import Sound.SC3
-
-> let {s = soundIn 4
->     ;a = amplitude KR s 0.01 0.01}
-> in audition (out 0 (pulse AR 90 0.3 * a))
-
-> let {s = soundIn 4
->     ;f = amplitude KR s 0.5 0.5 * 1200 + 400}
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
-
-> let {s = soundIn 4
->     ;a = amplitude AR s 0.5 0.05}
-> in audition (out 0 (s * a))
diff --git a/Help/UGen/Analysis/compander.help.lhs b/Help/UGen/Analysis/compander.help.lhs
deleted file mode 100644
--- a/Help/UGen/Analysis/compander.help.lhs
+++ /dev/null
@@ -1,33 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Compander"
-> Sound.SC3.UGen.DB.ugenSummary "Compander"
-
-> import Sound.SC3
-
-Example signal to process.
-> let z = 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 e * p
-
-> let z = soundIn 4
-
-> audition (out 0 z)
-
-Noise gate (no hold, no hysteresis)
-> let x = mouseX KR 0.01 0.15 Linear 0.1
-> in audition (out 0 (mce [z, compander z z x 10 1 0.002 0.15]))
-
-Compressor
-> let x = mouseX KR 0.01 1 Linear 0.1
-> in audition (out 0 (mce [z, compander z z x 1 (1/3) 0.01 0.01]))
-
-Expander
-> let x = mouseX KR 0.01 1 Linear 0.1
-> in audition (out 0 (mce [z, compander z z x 1 3 0.01 0.1]))
-
-Limiter
-> let x = mouseX KR 0.01 1 Linear 0.1
-> in audition (out 0 (mce [z, compander z z x 1 (1/10) 0.01 0.01]))
-
-Sustainer
-> let x = mouseX KR 0.01 0.15 Linear 0.1
-> in audition (out 0 (mce [z, compander z z x (1/3) 1.0 0.01 0.05]))
diff --git a/Help/UGen/Analysis/pitch.help.lhs b/Help/UGen/Analysis/pitch.help.lhs
deleted file mode 100644
--- a/Help/UGen/Analysis/pitch.help.lhs
+++ /dev/null
@@ -1,27 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Pitch"
-> Sound.SC3.UGen.DB.ugenSummary "Pitch"
-
-> import Sound.SC3
-
-> 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 0}
-> in audition (out 0 (mce [s, sinOsc AR (mceChannel 0 f / 2) 0 * a]))
-
-> let {s = soundIn 4
->     ;a = amplitude KR s 0.1 0.1
->     ;f = pitch s 440 60 4000 100 16 7 0.02 0.5 1 0}
-> in audition (out 0 (mce [s, sinOsc AR (mceChannel 0 f) 0 * a]))
-
-Comparison of input frequency (x) and tracked oscillator frequency (f).
-Output is printed to the console by scsynth.
-> let {x = mouseX KR 440 880 Exponential 0.1
->     ;o = sinOsc AR x 0 * 0.1
->     ;[f,_] = mceChannels (pitch o 440 60 4000 100 16 7 0.02 0.5 1 0)
->     ;r = sinOsc AR f 0 * 0.1
->     ;t = impulse KR 4 0
->     ;pf = poll t f (label "f") 0
->     ;px = poll t x (label "x") 0}
-> in audition (mrg [out 0 (mce2 o r),pf,px])
diff --git a/Help/UGen/Analysis/runningSum.help.lhs b/Help/UGen/Analysis/runningSum.help.lhs
deleted file mode 100644
--- a/Help/UGen/Analysis/runningSum.help.lhs
+++ /dev/null
@@ -1,25 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RunningSum"
-> Sound.SC3.UGen.DB.ugenSummary "RunningSum"
-
-> import Sound.SC3
-
-distorts of course - would need scaling
-> audition (out 0 (runningSum (soundIn 4) 40))
-
-Running Average over x samples
-> let {x = 100
->     ;o = runningSum (lfSaw AR 440 0) x * recip x}
-> in audition (out 0 o)
-
-RMS Power
-> let {input = lfSaw AR 440 0
->     ;numsamp = 30
->     ;o = runningSum (input * input) numsamp / (sqrt numsamp)}
-> in audition (out 0 o)
-
-composite UGen
-> audition (out 0 (runningSumRMS (soundIn 4) 40))
-
-> let {z = soundIn 4
->     ;a = runningSum z 40}
-> in audition (out 0 (sinOsc AR 440 0 * a * 0.1))
diff --git a/Help/UGen/Analysis/slope.help.lhs b/Help/UGen/Analysis/slope.help.lhs
deleted file mode 100644
--- a/Help/UGen/Analysis/slope.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Slope"
-> Sound.SC3.UGen.DB.ugenSummary "Slope"
-
-> import Sound.SC3.ID
-
-> let {a = lfNoise2 'a' KR 2 {- quadratic noise -}
->     ;s = 1/2
->     ;b = slope a * s {- first derivative, line segments -}
->     ;c = slope b * squared s {- second derivative, constant segments -}
->     ;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
deleted file mode 100644
--- a/Help/UGen/Analysis/zeroCrossing.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "ZeroCrossing"
-> Sound.SC3.UGen.DB.ugenSummary "ZeroCrossing"
-
-> import Sound.SC3
-
-> let a = sinOsc AR (sinOsc KR 1 0 * 600 + 700) 0 * 0.1
-> 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
deleted file mode 100644
--- a/Help/UGen/Buffer/bufAllpassC.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BufAllpassC"
-> Sound.SC3.UGen.DB.ugenSummary "BufAllpassC"
-
-> import Sound.SC3.ID
-
-Allocate buffer
-> withSC3 (async (b_alloc 0 44100 1))
-
-Filtered decaying noise bursts
-> let {d = dust 'a' AR 1
->     ;n = whiteNoise 'a' AR
->     ;x = decay d 0.2 * n * 0.25}
-> in audition (out 0 (bufAllpassC 0 x 0.25 6))
diff --git a/Help/UGen/Buffer/bufAllpassL.help.lhs b/Help/UGen/Buffer/bufAllpassL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufAllpassL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See bufAllpassC
diff --git a/Help/UGen/Buffer/bufAllpassN.help.lhs b/Help/UGen/Buffer/bufAllpassN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufAllpassN.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See bufAllpassC
diff --git a/Help/UGen/Buffer/bufChannels.help.lhs b/Help/UGen/Buffer/bufChannels.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufChannels.help.lhs
+++ /dev/null
@@ -1,2 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BufChannels"
-> Sound.SC3.UGen.DB.ugenSummary "BufChannels"
diff --git a/Help/UGen/Buffer/bufCombC.help.lhs b/Help/UGen/Buffer/bufCombC.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufCombC.help.lhs
+++ /dev/null
@@ -1,30 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BufCombC"
-> Sound.SC3.UGen.DB.ugenSummary "BufCombC"
-
-> import Sound.SC3.ID
-
-Allocate buffer zero (required for examples below)
-> withSC3 (async (b_alloc 0 44100 1))
-
-Filtered decaying noise bursts
-> let {d = dust 'a' AR 1
->     ;n = whiteNoise 'a' AR
->     ;x = decay d 0.2 * n * 0.25}
-> in audition (out 0 (bufCombC 0 x 0.25 6))
-
-Comb filter as resonator. The resonant fundamental is equal to
-reciprocal of the delay time.
-> let {n = whiteNoise 'a' AR
->     ;dt = xLine KR 0.0001 0.01 20 RemoveSynth}
-> in audition (out 0 (bufCombC 0 (n * 0.1) dt 0.2))
-
-With negative feedback
-> let {n = whiteNoise 'a' AR
->     ;dt = xLine KR 0.0001 0.01 20 RemoveSynth}
-> in audition (out 0 (bufCombC 0 (n * 0.1) dt (-0.2)))
-
-Used as an echo.
-> let {d = dust 'a' AR 1
->     ;n = whiteNoise 'a' AR
->     ;i = decay (d * 0.5) 0.2 * n}
-> in audition (out 0 (bufCombC 0 i 0.2 3))
diff --git a/Help/UGen/Buffer/bufCombL.help.lhs b/Help/UGen/Buffer/bufCombL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufCombL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See bufCombC
diff --git a/Help/UGen/Buffer/bufCombN.help.lhs b/Help/UGen/Buffer/bufCombN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufCombN.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See bufCombC
diff --git a/Help/UGen/Buffer/bufDelayC.help.lhs b/Help/UGen/Buffer/bufDelayC.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufDelayC.help.lhs
+++ /dev/null
@@ -1,21 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BufDelayC"
-> Sound.SC3.UGen.DB.ugenSummary "BufDelayC"
-
-> import Sound.SC3.ID
-
-Allocate buffer zero (required for examples below)
-> withSC3 (async (b_alloc 0 44100 1))
-
-Dust randomly triggers Decay to create an exponential decay envelope
-for the WhiteNoise input source.  The input is mixed with the delay.
-> let {t = dust 'a' AR 1
->     ;n = whiteNoise 'a' AR
->     ;d = decay t 0.5 * n * 0.3}
-> in audition (out 0 (bufDelayC 0 d 0.2 + d))
-
-Mouse control for delay time
-> let {t = dust 'a' AR 1
->     ;n = whiteNoise 'b' AR
->     ;d = decay t 0.3 * n
->     ;x = mouseX KR 0.0 0.2 Linear 0.1}
-> in audition (out 0 (d + bufDelayC 0 d x))
diff --git a/Help/UGen/Buffer/bufDelayL.help.lhs b/Help/UGen/Buffer/bufDelayL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufDelayL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See bufDelayC
diff --git a/Help/UGen/Buffer/bufDelayN.help.lhs b/Help/UGen/Buffer/bufDelayN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufDelayN.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See bufDelayC
diff --git a/Help/UGen/Buffer/bufDur.help.lhs b/Help/UGen/Buffer/bufDur.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufDur.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BufDur"
-> Sound.SC3.UGen.DB.ugenSummary "BufDur"
-
-> import Sound.SC3
-
-Load sound file to buffer zero (required for examples)
-
-> let fn = "/home/rohan/data/audio/pf-c5.aif"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-Read without loop, trigger reset based on buffer duration
-
-> 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
deleted file mode 100644
--- a/Help/UGen/Buffer/bufFrames.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BufFrames"
-> Sound.SC3.UGen.DB.ugenSummary "BufFrames"
-
-> import Sound.SC3
-
-Load sound file to buffer zero (required for examples)
-> let fn = "/home/rohan/data/audio/pf-c5.aif"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-Read without loop, trigger reset based on buffer duration
-> let p = phasor AR 0 (bufRateScale KR 0) 0 (bufFrames KR 0) 0
-> in audition (out 0 (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
deleted file mode 100644
--- a/Help/UGen/Buffer/bufRateScale.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BufRateScale"
-> Sound.SC3.UGen.DB.ugenSummary "BufRateScale"
-
-> import Sound.SC3.ID
-
-Load sound file to buffer zero (required for examples)
-> let fn = "/home/rohan/data/audio/pf-c5.aif"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-Read buffer at 3/4 reported sample rate.
-> let {r = 0.75 * 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
deleted file mode 100644
--- a/Help/UGen/Buffer/bufRd.help.lhs
+++ /dev/null
@@ -1,38 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BufRd"
-> Sound.SC3.UGen.DB.ugenSummary "BufRd"
-
-> import Sound.SC3.ID {- hsc3 -}
-
-Load sound file to buffer zero (required for examples)
-
-> let fn = "/home/rohan/data/audio/pf-c5.aif"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-Phasor as phase input
-
-> let {sc = bufRateScale KR 0
->     ;tr = impulse AR (recip (bufDur KR 0)) 0
->     ;ph = phasor AR tr sc 0 (bufFrames KR 0) 0}
-> in audition (out 0 (bufRdL 1 AR 0 ph NoLoop))
-
-Audio rate sine oscillator as phase input
-
-> let phase = sinOsc AR 0.1 0 * bufFrames KR 0 * bufRateScale KR 0
-> in audition (out 0 (bufRd 1 AR 0 phase Loop NoInterpolation))
-
-There are constructors, bufRd{N|L|C}, for the fixed cases.
-
-> let {x = mouseX KR (mce [5, 10]) 100 Linear 0.1
->     ;n = lfNoise1 'α' AR x}
-> in audition (out 0 (bufRdL 1 AR 0 (n * bufFrames KR 0 * bufRateScale KR 0) Loop))
-
-Allocate and generate (non-wavetable) buffer
-
-> withSC3 (do {_ <- async (b_alloc 11 256 1)
->             ;let f = [Normalise,Clear]
->              in send (b_gen_sine1 11 f [1,1/2,1/3,1/4,1/5])})
-
-Fixed frequency wavetable oscillator
-
-> let phase = linLin (saw AR 440) (-1) 1 0 1 * bufFrames KR 11
-> in audition (out 0 (bufRd 1 AR 11 phase Loop NoInterpolation * 0.1))
diff --git a/Help/UGen/Buffer/bufSampleRate.help.lhs b/Help/UGen/Buffer/bufSampleRate.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/bufSampleRate.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BufSampleRate"
-> Sound.SC3.UGen.DB.ugenSummary "BufSampleRate"
-
-> import Sound.SC3
-
-Load sound file to buffer zero (required for examples)
-> let fn = "/home/rohan/data/audio/pf-c5.aif"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-Sine tone derived from sample rate of buffer an 440Hz tone.
-> 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
deleted file mode 100644
--- a/Help/UGen/Buffer/detectIndex.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DetectIndex"
-> Sound.SC3.UGen.DB.ugenSummary "DetectIndex"
-
-> import Sound.SC3
-
-Allocate and set values at buffer ten
-> withSC3 (async (b_alloc_setn1 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}
-> in audition (out 0 (sinOsc AR (linExp i 0 n 200 700) 0 * 0.1))
-
-Free buffer.
-> withSC3 (send (b_free 10))
diff --git a/Help/UGen/Buffer/index.help.lhs b/Help/UGen/Buffer/index.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/index.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Index"
-> Sound.SC3.UGen.DB.ugenSummary "Index"
-
-> import Sound.SC3
-
-Allocate and set values at buffer ten
-> withSC3 (async (b_alloc_setn1 10 0 [50,100,200,400,800,1600]))
-
-Index buffer for frequency values
-> let f = index 10 (lfSaw KR 2 3 * 4)
-> in audition (out 0 (sinOsc AR (mce [f,f * 9]) 0 * 0.1))
-
-Free buffer
-> withSC3 (send (b_free 10))
diff --git a/Help/UGen/Buffer/indexInBetween.help.lhs b/Help/UGen/Buffer/indexInBetween.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/indexInBetween.help.lhs
+++ /dev/null
@@ -1,18 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "IndexInBetween"
-> Sound.SC3.UGen.DB.ugenSummary "IndexInBetween"
-
-> import Sound.SC3
-
-Allocate and set values at buffer ten
-> withSC3 (async (b_alloc_setn1 10 0 [200,210,400,430,600,800]))
-
-Index into 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}
-> in audition (out 0 (sinOsc AR (mce [f0,f1]) 0 * 0.1))
-
-Free buffer
-> withSC3 (send (b_free 10))
diff --git a/Help/UGen/Buffer/osc.help.lhs b/Help/UGen/Buffer/osc.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/osc.help.lhs
+++ /dev/null
@@ -1,45 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Osc"
-> Sound.SC3.UGen.DB.ugenSummary "Osc"
-
-> import Sound.SC3
-
-Allocate and generate wavetable buffer
-
-> withSC3 (do {_ <- async (b_alloc 10 512 1)
->             ;let f = [Normalise,Wavetable,Clear]
->              in send (b_gen_sine1 10 f [1,1/2,1/3,1/4,1/5])})
-
-Fixed frequency wavetable oscillator
-
-> audition (out 0 (osc AR 10 220 0 * 0.1))
-
-Modulate frequency
-
-> let f = xLine KR 2000 200 1 DoNothing
-> in audition (out 0 (osc AR 10 f 0 * 0.1))
-
-As frequency modulator
-
-> let f = osc AR 10 (xLine KR 1 1000 9 RemoveSynth) 0 * 200 + 800
-> in audition (out 0 (osc AR 10 f 0 * 0.1))
-
-As phase modulatulator
-
-> let p = osc AR 10 (xLine KR 20 8000 10 RemoveSynth) 0 * 2 * pi
-> in audition (out 0 (osc AR 10 800 p * 0.1))
-
-Fixed frequency wavetable oscillator
-
-> audition (out 0 (osc AR 10 220 0 * 0.1))
-
-Change the wavetable while its playing
-
-> let f = [Normalise,Wavetable,Clear]
-> in withSC3 (send (b_gen_sine1 10 f [1,0.6,1/4]))
-
-Send directly calculated wavetable
-
-> import Sound.SC3.Lang.Collection {- hsc3-lang -}
-> import Sound.SC3.Lang.Math.Window
-> let t = to_wavetable (triangular_table 512)
-> withSC3 (send (b_setn1 10 0 t))
diff --git a/Help/UGen/Buffer/playBuf.help.lhs b/Help/UGen/Buffer/playBuf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/playBuf.help.lhs
+++ /dev/null
@@ -1,85 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PlayBuf"
-> Sound.SC3.UGen.DB.ugenSummary "PlayBuf"
-
-> import Sound.SC3
-
-Load sound file to buffer zero (single channel file required for examples)
-
-> let fn = "/home/rohan/data/audio/pf-c5.aif"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-Play once only.
-
-> let s = bufRateScale KR 0
-> in audition (out 0 (playBuf 1 AR 0 s 1 0 NoLoop RemoveSynth))
-
-Play in infinite loop.
-
-> let s = bufRateScale KR 0
-> in audition (out 0 (playBuf 1 AR 0 s 1 0 Loop DoNothing))
-
-Trigger playback at each pulse.
-
-> let {t = impulse KR 2 0
->     ;s = bufRateScale KR 0}
-> in audition (out 0 (playBuf 1 AR 0 s t 0 NoLoop DoNothing))
-
-Trigger playback at each pulse (diminishing intervals).
-
-> let {f = xLine KR 0.1 100 10 RemoveSynth
->     ;t = impulse KR f 0
->     ;s = bufRateScale KR 0}
-> in audition (out 0 (playBuf 1 AR 0 s t 0 NoLoop DoNothing))
-
-Loop playback, accelerating pitch.
-
-> let r = xLine KR 0.1 100 60 RemoveSynth
-> in audition (out 0 (playBuf 1 AR 0 r 1 0 Loop DoNothing))
-
-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
->     ;s = bufRateScale KR 0 * r}
-> in audition (out 0 (playBuf 1 AR 0 s 1 0 Loop DoNothing))
-
-Release buffer.
-
-> withSC3 (send (b_free 0))
-
-Channel mismatch, single channel buffer, two channel playBuf, result
-is silence and channel mismatch message in server log.
-
-> let fn = "/home/rohan/data/audio/pf-c5.aif"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-> let s = bufRateScale KR 0
-> in audition (out 0 (playBuf 2 AR 0 s 1 0 Loop DoNothing))
-
-Graph will sound after loading a two channel signal to buffer, and
-stop again after loading a single channel sound file.
-
-> let fn = "/home/rohan/data/audio/sp/tinguely.aif"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-Scan sequence of buffers:
-
-> let {n = 29 * 6
->     ;b = mouseX KR 0 n Linear 0.2
->     ;r = bufRateScale KR b}
-> in audition (out 0 (playBuf 1 AR b r 1 0 Loop DoNothing))
-
-In sclanguage:
-
-{var fn = "/home/rohan/data/audio/pf-c5.aif"
-;s.sendMsg("/b_allocRead",0,fn,0,0)}.value
-
-{var sc = BufRateScale.kr(0)
-;Out.ar(0,PlayBuf.ar(2,0,sc,1,0,1,0))}.play
-
-{var fn = "/home/rohan/data/audio/sp/tinguely.aif"
-;s.sendMsg("/b_allocRead",0,fn,0,0)}.value
-
-{var b = MouseX.kr(32,64,0,0.2)
-;var r = BufRateScale.kr(b)
-;Out.ar(0,PlayBuf.ar(1,b,r,1,0,1,0))}.play
diff --git a/Help/UGen/Buffer/recordBuf.help.lhs b/Help/UGen/Buffer/recordBuf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/recordBuf.help.lhs
+++ /dev/null
@@ -1,25 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RecordBuf"
-> Sound.SC3.UGen.DB.ugenSummary "RecordBuf"
-
-> import Sound.SC3
-
-Allocate a buffer (assume SR of 48k)
-
-> withSC3 (async (b_alloc 0 (48000 * 4) 1))
-
-Record for four seconds (until end of buffer)
-
-> let o = formant AR (xLine KR 400 1000 4 DoNothing) 2000 800 * 0.125
-> in audition (mrg2 (out 0 o)
->                   (recordBuf AR 0 0 1 0 1 NoLoop 1 RemoveSynth o))
-
-Play it back
-
-> let p = playBuf 1 AR 0 1 1 0 NoLoop RemoveSynth
-> in audition (out 0 p)
-
-Mix second signal equally with existing signal, replay to hear
-
-> let o = formant AR (xLine KR 200 1000 4 DoNothing) 2000 800 * 0.125
-> in audition (mrg2 (out 0 o)
->                   (recordBuf AR 0 0 0.5 0.5 1 NoLoop 1 RemoveSynth o))
diff --git a/Help/UGen/Buffer/vOsc.help.lhs b/Help/UGen/Buffer/vOsc.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/vOsc.help.lhs
+++ /dev/null
@@ -1,31 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "VOsc"
-> Sound.SC3.UGen.DB.ugenSummary "VOsc"
-
-> import Sound.SC3
-
-Allocate and fill tables 0 to 7.
-
-> let {square a = a * a
->     ;bf = [Normalise,Wavetable,Clear]
->     ;harm i = let {n = square (i + 1)
->                   ;f j = square ((n - j) / n)}
->                in map f [0 .. n - 1]
->     ;setup i = do {i' <- return (fromIntegral i)
->                   ;_ <- async (b_alloc i 1024 1)
->                   ;send (b_gen_sine1 i bf (harm i'))}}
-> in withSC3 (mapM_ setup [0 .. 7])
-
-Oscillator at buffers 0 through 7, mouse selects buffer.
-
-> let {x = mouseX KR 0 7 Linear 0.1
->     ;y = mouseY KR 0.01 0.2 Exponential 0.2}
-> in audition (out 0 (vOsc AR x (mce [120, 121]) 0 * y))
-
-> import Sound.SC3.Lang.Random.IO {- hsc3-lang -}
-
-Reallocate buffers while oscillator is running.
-
-> let {bf = [Normalise,Wavetable,Clear]
->     ;resetTable i = do {h <- nrrand 12 0 1
->                        ;send (b_gen_sine1 i bf h)}}
-> in withSC3 (mapM_ resetTable [0 .. 7])
diff --git a/Help/UGen/Buffer/vOsc3.help.lhs b/Help/UGen/Buffer/vOsc3.help.lhs
deleted file mode 100644
--- a/Help/UGen/Buffer/vOsc3.help.lhs
+++ /dev/null
@@ -1,24 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "VOsc3"
-> Sound.SC3.UGen.DB.ugenSummary "VOsc3"
-
-> import Sound.SC3
-
-allocate and fill tables 0 to 7.
-
-> let {square a = a * a
->     ;bf = [Normalise,Wavetable,Clear]
->     ;harm i = let {n = square (i + 1)
->                   ;f j = square ((n - j) / n)}
->                in map f [0 .. n - 1]
->     ;setup i = do {i' <- return (fromIntegral i)
->                   ;_ <- async (b_alloc i 1024 1)
->                   ;send (b_gen_sine1 i bf (harm i'))}}
-> in withSC3 (mapM_ setup [0 .. 7])
-
-oscillator at buffers 0 through 7, mouse selects buffer.
-
-> let {x = mouseX KR 0 7 Linear 0.1
->     ;y = mouseY KR 0.01 0.2 Exponential 0.2
->     ;o1 = vOsc3 AR x 120 121 129
->     ;o2 = vOsc3 AR x 119 123 127}
-> in audition (out 0 (mce2 o1 o2 * y))
diff --git a/Help/UGen/Chaos/crackle.help.lhs b/Help/UGen/Chaos/crackle.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/crackle.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Crackle"
-> Sound.SC3.UGen.DB.ugenSummary "Crackle"
-
-> import Sound.SC3
-
-> audition (out 0 (crackle AR 1.95 * 0.2))
-
-Modulate chaos parameter
-
-> audition (out 0 (crackle AR (line KR 1.0 2.0 3 RemoveSynth) * 0.2))
diff --git a/Help/UGen/Chaos/cuspL.help.lhs b/Help/UGen/Chaos/cuspL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/cuspL.help.lhs
+++ /dev/null
@@ -1,19 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "CuspL"
-> Sound.SC3.UGen.DB.ugenSummary "CuspL"
-
-> import Sound.SC3
-
-Vary frequency
-> let x = mouseX KR 20 sampleRate Linear 0.1
-> in audition (out 0 (cuspL AR x 1.0 1.99 0 * 0.3))
-
-Mouse-controlled parameters.
-> 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}
-> in audition (out 0 (sinOsc AR (n * 800 + 900) 0 * 0.4))
diff --git a/Help/UGen/Chaos/cuspN.help.lhs b/Help/UGen/Chaos/cuspN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/cuspN.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See cuspL
diff --git a/Help/UGen/Chaos/fbSineC.help.lhs b/Help/UGen/Chaos/fbSineC.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/fbSineC.help.lhs
+++ /dev/null
@@ -1,29 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FBSineC"
-> Sound.SC3.UGen.DB.ugenSummary "FBSineC"
-
-> import Sound.SC3.ID
-
-SC3 default values.
-> let o = fbSineC AR (sampleRate / 4) 1 0.1 1.1 0.5 0.1 0.1 * 0.2
-> in audition (out 0 o)
-
-Increase feedback
-> let {fb = line KR 0.01 4 10 DoNothing
->     ;o = fbSineC AR sampleRate 1 fb 1.1 0.5 0.1 0.1 * 0.2}
-> in audition (out 0 o)
-
-Increase phase multiplier
-> let {a = line KR 1 2 10 DoNothing
->     ;o = fbSineC AR sampleRate 1 0 a 0.5 0.1 0.1 * 0.2}
-> in audition (out 0 o)
-
-Randomly modulate parameters
-> let {madd a m = (+ a) . (* m)
->     ;x = mouseX KR 1 12 Linear 0.1
->     ;n e = lfNoise2 e KR x
->     ;n0 = madd 1e4 1e4 (n 'a')
->     ;n1 = madd 33 32 (n 'b')
->     ;n2 = madd 0 0.5 (n 'c')
->     ;n3 = madd 1.05 0.05 (n 'd')
->     ;n4 = madd 0.3 0.3 (n 'e')}
-> in audition (out 0 (fbSineC AR n0 n1 n2 n3 n4 0.1 0.1 * 0.2))
diff --git a/Help/UGen/Chaos/fbSineL.help.lhs b/Help/UGen/Chaos/fbSineL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/fbSineL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See fbSineC
diff --git a/Help/UGen/Chaos/fbSineN.help.lhs b/Help/UGen/Chaos/fbSineN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/fbSineN.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See fbSineC
diff --git a/Help/UGen/Chaos/gbmanL.help.lhs b/Help/UGen/Chaos/gbmanL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/gbmanL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See GbmanN
diff --git a/Help/UGen/Chaos/gbmanN.help.lhs b/Help/UGen/Chaos/gbmanN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/gbmanN.help.lhs
+++ /dev/null
@@ -1,20 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "GbmanN"
-> Sound.SC3.UGen.DB.ugenSummary "GbmanN"
-
-> import Sound.SC3
-
-default initial params
-> let x = mouseX KR 20 sampleRate Linear 0.2
-> in audition (out 0 (gbmanN AR x 1.2 2.1 * 0.1))
-
-change initial params
-> let x = mouseX KR 20 sampleRate Linear 0.2
-> in audition (out 0 (gbmanN AR x (-0.7) (-2.7) * 0.1))
-
-wait for it...
-> let x = mouseX KR 20 sampleRate Linear 0.2
-> in audition (out 0 (gbmanN AR x 1.2 2.0002 * 0.1))
-
-as a frequency control
-> let f = gbmanN AR 40 1.2 2.1 * 400 + 500
-> in audition (out 0 (sinOsc AR f 0 * 0.4))
diff --git a/Help/UGen/Chaos/henonC.help.lhs b/Help/UGen/Chaos/henonC.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/henonC.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See henonN
diff --git a/Help/UGen/Chaos/henonL.help.lhs b/Help/UGen/Chaos/henonL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/henonL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See henonN
diff --git a/Help/UGen/Chaos/henonN.help.lhs b/Help/UGen/Chaos/henonN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/henonN.help.lhs
+++ /dev/null
@@ -1,25 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "HenonN"
-> Sound.SC3.UGen.DB.ugenSummary "HenonN"
-
-> import Sound.SC3.ID
-
-With SC3 default initial parameters.
-> let x = mouseX KR 20 sampleRate Linear 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}
-> in audition (out 0 (henonN AR (sampleRate / 4) x y 0 0 * 0.1))
-
-With randomly modulated parameters.
-> let {n0 = lfNoise2 'a' KR 1 * 0.20 + 1.20
->     ;n1 = lfNoise2 'a' KR 1 * 0.15 + 0.15}
-> in 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
->     ;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
deleted file mode 100644
--- a/Help/UGen/Chaos/latoocarfianC.help.lhs
+++ /dev/null
@@ -1,18 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LatoocarfianC"
-> Sound.SC3.UGen.DB.ugenSummary "LatoocarfianC"
-
-> import Sound.SC3.ID
-
-SC3 default initial parameters.
-> let x = mouseX KR 20 sampleRate Linear 0.1
-> in audition (out 0 (latoocarfianC AR x 1 3 0.5 0.5 0.5 0.5 * 0.2))
-
-Randomly modulate all parameters.
-> let {[n0,n1,n2,n3] = map (\e -> lfNoise2 e KR 5) "abcd"
->     ;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
->     ;o = latoocarfianC AR f a b c d 0.5 0.5 * 0.2}
-> in audition (out 0 o)
diff --git a/Help/UGen/Chaos/linCongC.help.lhs b/Help/UGen/Chaos/linCongC.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/linCongC.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LinCongC"
-> Sound.SC3.UGen.DB.ugenSummary "LinCongC"
-
-> import Sound.SC3.ID
-
-Default SC3 initial parameters.
-> let x = mouseX KR 20 sampleRate Linear 0.1
-> in audition (out 0 (linCongC AR x 1.1 0.13 1 0 * 0.2))
-
-Randomly modulate parameters.
-> let {fr = [1,0.1,0.1,0.1]
->     ;[n0,n1,n2,m] = map (\(i,j) -> lfNoise2 i KR j) (zip "abde" fr)
->     ;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/linCongL.help.lhs b/Help/UGen/Chaos/linCongL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/linCongL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See linCongC
diff --git a/Help/UGen/Chaos/linCongN.help.lhs b/Help/UGen/Chaos/linCongN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/linCongN.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See linCongC
diff --git a/Help/UGen/Chaos/logistic.help.lhs b/Help/UGen/Chaos/logistic.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/logistic.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Logistic"
-> Sound.SC3.UGen.DB.ugenSummary "Logistic"
-
-> import Sound.SC3
-
-SC3 default parameters
-> audition (out 0 (logistic AR 3 1000 0.5))
-
-Onset of chaos
-> audition (out 0 (logistic AR (line KR 3.55 3.6 5 DoNothing) 1000 0.01))
-
-Mouse control
-> let {x = mouseX KR 3 3.99 Linear 0.1
->     ;y = mouseY KR 10 10000 Exponential 0.1}
-> in audition (out 0 (logistic AR x y 0.25 * 0.5))
diff --git a/Help/UGen/Chaos/lorenzL.help.lhs b/Help/UGen/Chaos/lorenzL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/lorenzL.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LorenzL"
-> Sound.SC3.UGen.DB.ugenSummary "LorenzL"
-
-> import Sound.SC3.ID
-
-Vary frequency
-> let x = mouseX KR 20 sampleRate Linear 0.1
-> in audition (out 0 (lorenzL AR x 10 27 2.667 0.05 0.1 0 0 * 0.3))
-
-Randomly modulate params
-> let {madd a m = (+ a) . (* m)
->     ;n e = lfNoise0 e KR 0.5
->     ;n0 = madd 10 2 (n 'a')
->     ;n1 = madd 38 20 (n 'b')
->     ;n2 = madd 2 1.5 (n 'c')
->     ;o = lorenzL AR sampleRate n0 n1 n2 0.05 0.1 0 0 * 0.2}
-> in audition (out 0 o)
-
-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}
-> in audition (out 0 (sinOsc AR (lag n 0.003 * 800 + 900) 0 * 0.4))
diff --git a/Help/UGen/Chaos/quadC.help.lhs b/Help/UGen/Chaos/quadC.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/quadC.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See quadN
diff --git a/Help/UGen/Chaos/quadL.help.lhs b/Help/UGen/Chaos/quadL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/quadL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See quadN
diff --git a/Help/UGen/Chaos/quadN.help.lhs b/Help/UGen/Chaos/quadN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/quadN.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "QuadN"
-> Sound.SC3.UGen.DB.ugenSummary "QuadN"
-
-> import Sound.SC3
-
-> audition (out 0 (quadC AR 4000 1 (-1) (-0.75) 0 * 0.2))
-
-> let x = mouseX KR 3.5441 4 Linear 0.1
-> 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}
-> in audition (out 0 (sinOsc AR f 0 * 0.4))
diff --git a/Help/UGen/Chaos/rossler.help.lhs b/Help/UGen/Chaos/rossler.help.lhs
deleted file mode 100644
--- a/Help/UGen/Chaos/rossler.help.lhs
+++ /dev/null
diff --git a/Help/UGen/Control/mrg2.help.lhs b/Help/UGen/Control/mrg2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Control/mrg2.help.lhs
+++ /dev/null
@@ -1,24 +0,0 @@
-> :t mrg2
-
-> import Sound.SC3
-
-mrg2 defines a node indicating a multiple root graph.
-> let {l = out 0 (sinOsc AR 300 0 * 0.1)
->     ;r = out 1 (sinOsc AR 900 0 * 0.1)}
-> in audition (mrg2 l r)
-
-there is a leftmost rule, so that mrg nodes need not
-be terminal.
-> let {l = sinOsc AR 300 0 * 0.1
->     ;r = out 1 (sinOsc AR 900 0 * 0.1)}
-> in audition (out 0 (mrg2 l r))
-
-the leftmost node may be an mce node
-> let {l = sinOsc AR (mce2 300 400) 0 * 0.1
->     ;r = out 1 (sinOsc AR 900 0 * 0.1)}
-> in audition (out 0 (mrg2 l r))
-
-the implementation is not thorough
-> let {l = sinOsc AR (mce2 300 400) 0 * 0.1
->     ;r = out 1 (sinOsc AR 900 0 * 0.1)}
-> in audition (out 0 (mrg2 l r + mrg2 l r))
diff --git a/Help/UGen/Control/trigControl.help.lhs b/Help/UGen/Control/trigControl.help.lhs
deleted file mode 100644
--- a/Help/UGen/Control/trigControl.help.lhs
+++ /dev/null
@@ -1,38 +0,0 @@
-> import Sound.SC3 {- hsc3 -}
-
-Graph with the three types of non-audio controls.
-
-> let u = let {freq = control KR "freq" 440
->             ;phase = control IR "phase" 0
->             ;gate = tr_control "gate" 1
->             ;amp = control KR "amp" 0.1
->             ;e = envGen KR gate amp 0 1 DoNothing (envASR 0.01 0.1 1 EnvLin)}
->         in sinOsc AR freq phase * e
-
-Make a drawing
-
-> import Sound.SC3.UGen.Dot {- hsc3-ugen -}
-
-> draw (out 0 u)
-
-Listen
-
-> audition_at (10,AddToHead,1) (out 0 u)
-
-Set frequency and the trigger gate.
-
-> withSC3 (send (n_set1 10 "freq" 2200))
-
-> withSC3 (send (n_set1 10 "gate" 1))
-
-Make a control rate graph to write freq and gate values.
-
-> let c = out 0 (mce2 (tRand 'α' 220 2200 (dust 'β' KR 1)) (dust 'γ' KR 3))
-
-Add it _before_ the node it will map to, the trigger is only on the bus for the current cycle.
-
-> audition_at (-1,AddBefore,10) c
-
-Map the control values at the audio graph.
-
-> withSC3 (send (n_map 10 [("freq",0),("gate",1)]))
diff --git a/Help/UGen/Demand/dbrown.help.lhs b/Help/UGen/Demand/dbrown.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dbrown.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dbrown"
-> Sound.SC3.UGen.DB.ugenSummary "Dbrown"
-
-> import Sound.SC3.ID
-
-> let {n = dbrown 'α' dinf 0 15 1
->     ;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
deleted file mode 100644
--- a/Help/UGen/Demand/dbufrd.help.lhs
+++ /dev/null
@@ -1,40 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dbufrd"
-> Sound.SC3.UGen.DB.ugenSummary "Dbufrd"
-
-> import Sound.SC3.ID {- hsc3 -}
-> import System.Random {- random -}
-
-setup pattern at buffer 10
-
-> let n = randomRs (200.0,500.0) (mkStdGen 0)
-> in withSC3 (async (b_alloc_setn1 10 0 (take 24 n)))
-
-pattern as frequency input
-
-> let {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}
-> in audition (out 0 (sinOsc AR (demand t 0 r) 0 * 0.1))
-
-setup time pattern
-
-> let {i = randomRs (0,2) (mkStdGen 0)
->     ;n = map ([1,0.5,0.25] !!) i}
-> in withSC3 (async (b_alloc_setn1 11 0 (take 24 n)))
-
-requires buffers 10 and 11 as allocated above
-
-> let {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
->     ;f = duty KR (d * 0.5) 0 DoNothing l}
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
-
-free buffers
-
-> withSC3 (async (b_free 10) >> async (b_free 11))
diff --git a/Help/UGen/Demand/dbufwr.help.lhs b/Help/UGen/Demand/dbufwr.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dbufwr.help.lhs
+++ /dev/null
@@ -1,23 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dbufwr"
-> Sound.SC3.UGen.DB.ugenSummary "Dbufwr"
-
-> import Sound.SC3 {- hsc3 -}
-> import qualified Sound.SC3.Monad as M {- hsc3 -}
-
-> do {s1 <- M.dseries 30 0 3
->    ;s2 <- M.dseries 30 0 1
->    ;s3 <- M.dseries 16 1 1
->    ;s4 <- M.dwhite 8 1 16
->    ;s5 <- M.dseq dinf (mce2 s3 s4)
->    ;wt <- M.dust KR 1                  {- write trigger -}
->    ;rp <- M.dseries dinf 0 1           {- read pointer -}
->    ;wp <- M.dseq dinf (mce2 s1 s2)     {- write pointer -}
->    ;r <- M.dbufrd 0 rp Loop            {- reader -}
->    ;w <- M.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 = do {_ <- async (b_alloc_setn1 0 0 (replicate 24 210))
->                   ;play g}}
->     in withSC3 run}
diff --git a/Help/UGen/Demand/demand.help.lhs b/Help/UGen/Demand/demand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/demand.help.lhs
+++ /dev/null
@@ -1,32 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Demand"
-> Sound.SC3.UGen.DB.ugenSummary "Demand"
-
-> import Sound.SC3.ID
-> import qualified Sound.SC3.Monad as M
-
-> do {r <- M.dust KR 1
->    ;s <- M.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))}
-
-> let {n = diwhite 'α' dinf 60 72
->     ;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))
-
-audio rate (poll output is equal for x1 and x2)
-
-> let {i = lfNoise2 'α' AR 8000
->     ;d = dseq 'β' dinf (mce [i])
->     ;x = mouseX KR 1 3000 Exponential 0.2
->     ;t = impulse AR x 0
->     ;x1 = demand t 0 d
->     ;x2 = latch i t
->     ;s = mce2 x1 x2
->     ;p = poll t s (mce2 (label "x1") (label "x2")) 0
->     ;o = sinOsc AR (s * 300 + 400) 0 * 0.1}
-> in audition (mrg2 (out 0 o) p)
diff --git a/Help/UGen/Demand/demandEnvGen.help.lhs b/Help/UGen/Demand/demandEnvGen.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/demandEnvGen.help.lhs
+++ /dev/null
@@ -1,91 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DemandEnvGen"
-> Sound.SC3.UGen.DB.ugenSummary "DemandEnvGen"
-
-> import Sound.SC3.ID
-
-Frequency ramp, exponential curve.
-
-> let {l = dseq 'α' dinf (mce2 440 9600)
->     ;y = mouseY KR 0.01 3 Exponential 0.2
->     ;s = env_curve_shape EnvExp
->     ;f = demandEnvGen AR l y s 0 1 1 1 0 1 DoNothing}
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
-
-Frequency envelope with random times.
-
-> let {l = dseq 'α' dinf (mce [204,400,201,502,300,200])
->     ;t = drand 'β' dinf (mce [1.01,0.2,0.1,2.0])
->     ;y = mouseY KR 0.01 3 Exponential 0.2
->     ;s = env_curve_shape EnvCub
->     ;f = demandEnvGen AR l (t * y) s 0 1 1 1 0 1 DoNothing}
-> in audition (out 0 (sinOsc AR (f * mce2 1 1.01) 0 * 0.1))
-
-Frequency modulation
-
-> let {n = dwhite 'α' dinf 200 1000
->     ;x = mouseX KR (-0.01) (-4) Linear 0.2
->     ;y = mouseY KR 1 3000 Exponential 0.2
->     ;s = env_curve_shape (EnvNum undefined)
->     ;f = demandEnvGen AR n (sampleDur * y) s x 1 1 1 0 1 DoNothing
->     ;o = sinOsc AR f 0 * 0.1}
-> in audition (out 0 o)
-
-Short sequence with doneAction, linear
-
-> let {l = dseq 'α' 1 (mce [1300,500,800,300,400])
->     ;s = env_curve_shape EnvLin
->     ;f = demandEnvGen KR l 2 s 0 1 1 1 0 1 RemoveSynth}
-> in audition (out 0 (sinOsc AR (f * mce2 1 1.01) 0 * 0.1))
-
-Gate, mouse x on right side of screen toggles gate
-
-> let {n = roundTo (dwhite 'α' dinf 300 1000) 100
->     ;x = mouseX KR 0 1 Linear 0.2
->     ;g = x >* 0.5
->     ;f = demandEnvGen AR n 0.1 5 0.3 g 1 1 0 1 DoNothing
->     ;o = sinOsc AR (f * mce2 1 1.21) 0 * 0.1}
-> in audition (out 0 o)
-
-gate
-mouse x on right side of screen toggles sample and hold
-mouse button does hard reset
-
-> let {l = dseq 'α' 2 (mce [dseries 'β' 5 400 200,500,800,530,4000,900])
->     ;x = mouseX KR 0 1 Linear 0.2
->     ;g = (x >* 0.5) - 0.1
->     ;b = mouseButton KR 0 1 0.2
->     ;r = (b >* 0.5) * 2
->     ;s = env_curve_shape EnvSin
->     ;f = demandEnvGen KR l 0.1 s 0 g r 1 0 1 DoNothing
->     ;o = sinOsc AR (f * mce2 1 1.001) 0 * 0.1}
-> in audition (out 0 o)
-
-initialise coordinate buffer
-layout is (initial-level,duration,level,..,loop-duration)
-
-> withSC3 (async (b_alloc_setn1 0 0 [0,0.5,0.1,0.5,1,0.01]))
-
-> let {b = 0
->     ;l_i = dseries 'β' dinf 0 2
->     ;d_i = dseries 'γ' dinf 1 2
->     ;l = dbufrd 'δ' b l_i Loop
->     ;d = dbufrd 'ε' b d_i Loop
->     ;s = env_curve_shape EnvLin
->     ;e = demandEnvGen KR l d s 0 1 1 1 0 5 RemoveSynth
->     ;f = midiCPS (60 + (e * 12))}
-> in audition (out 0 (sinOsc AR (f * mce2 1 1.01) 0 * 0.1))
-
-change envelope by setting values or indeed reallocating buffer
-
-> withSC3 (send (b_set1 0 1 0.1))
-> withSC3 (async (b_alloc_setn1 0 0 [0.5,0.9,0.1,0.1,1,0.01]))
-
-read envelope break-points from buffer, here simply duration/level pairs.
-the behavior is odd if the curve is zero (ie. flat segments).
-
-> let {b = asLocalBuf 'α' [61,1,60,2,72,1,55,5,67,9,67]
->     ;lvl = dbufrd 'β' b (dseries 'γ' 6 0 2) Loop
->     ;dur = dbufrd 'δ' b (dseries 'ε' 5 1 2) Loop
->     ;e = demandEnvGen KR lvl dur 1 0 1 1 1 0 1 RemoveSynth
->     ;o = sinOsc AR (midiCPS e) 0 * 0.1}
-> in audition (out 0 o)
diff --git a/Help/UGen/Demand/dgeom.help.lhs b/Help/UGen/Demand/dgeom.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dgeom.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dgeom"
-> Sound.SC3.UGen.DB.ugenSummary "Dgeom"
-
-> import Sound.SC3.ID
-
-> let {n = dgeom 'α' 15 1 1.2
->     ;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/dibrown.help.lhs b/Help/UGen/Demand/dibrown.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dibrown.help.lhs
+++ /dev/null
@@ -1,4 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dibrown"
-> Sound.SC3.UGen.DB.ugenSummary "Dibrown"
-
-See dbrown
diff --git a/Help/UGen/Demand/diwhite.help.lhs b/Help/UGen/Demand/diwhite.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/diwhite.help.lhs
+++ /dev/null
@@ -1,4 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Diwhite"
-> Sound.SC3.UGen.DB.ugenSummary "Diwhite"
-
-See dwhite
diff --git a/Help/UGen/Demand/drand.help.lhs b/Help/UGen/Demand/drand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/drand.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Drand"
-> Sound.SC3.UGen.DB.ugenSummary "Drand"
-
-> import Sound.SC3.ID
-
-> let {n = drand 'α' dinf (mce [1, 3, 2, 7, 8])
->     ;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
deleted file mode 100644
--- a/Help/UGen/Demand/dseq.help.lhs
+++ /dev/null
@@ -1,36 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dseq"
-> Sound.SC3.UGen.DB.ugenSummary "Dseq"
-
-> import Sound.SC3.ID
-
-> let {n = dseq 'α' 3 (mce [1, 3, 2, 7, 8])
->     ;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.
-
-> let {n = dseq 'α' dinf (mce [1,3,2,7,8,32,16,18,12,24])
->     ;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))
-
-The SC2 Sequencer UGen is somewhat like the sequ function below
-
-> let {sequ e s tr = demand tr 0 (dseq e dinf (mce s))
->     ;t = impulse AR 6 0
->     ;n0 = sequ 'α' [60,62,63,58,48,55] t
->     ;n1 = sequ 'β' [63,60,48,62,55,58] t
->     ;o = lfSaw AR (midiCPS (mce2 n0 n1)) 0 * 0.1}
-> in audition (out 0 o)
-
-Rather than MCE expansion at /tr/, it can be clearer to view /tr/ as a
-functor.
-
-> let {tr = impulse KR (mce [2,3,5]) 0
->     ;f t = demand t 0 (dseq t dinf (mce [60,63,67,69]))
->     ;m = mceMap f tr
->     ;o = sinOsc AR (midiCPS m) 0 * 0.1}
-> in audition (out 0 (splay o 1 1 0 True))
diff --git a/Help/UGen/Demand/dser.help.lhs b/Help/UGen/Demand/dser.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dser.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dser"
-> Sound.SC3.UGen.DB.ugenSummary "Dser"
-
-> import Sound.SC3.ID
-
-> let {a = dser 'α' 7 (mce [1, 3, 2, 7, 8])
->     ;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
deleted file mode 100644
--- a/Help/UGen/Demand/dseries.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dseries"
-> Sound.SC3.UGen.DB.ugenSummary "Dseries"
-
-> import Sound.SC3.ID
-
-> let {n = dseries 'α' 15 0 1
->     ;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/dshuf.help.lhs b/Help/UGen/Demand/dshuf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dshuf.help.lhs
+++ /dev/null
@@ -1,18 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dshuf"
-> Sound.SC3.UGen.DB.ugenSummary "Dshuf"
-
-> import Sound.SC3.ID {- hsc3 -}
-
-> let {a = dseq 'α' dinf (dshuf 'β' 3 (mce [1,3,2,7,8.5]))
->     ;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))
-
-> import Sound.SC3.UGen.External.RDU.ID {- sc3-rdu -}
-
-> let {a = dseq 'α' dinf (dshuf 'β' 5 (randN 81 'γ' 0 10))
->     ;x = mouseX KR 1 10000 Exponential 0.1
->     ;t = impulse AR 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/dstutter.help.lhs b/Help/UGen/Demand/dstutter.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dstutter.help.lhs
+++ /dev/null
@@ -1,24 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dstutter"
-> Sound.SC3.UGen.DB.ugenSummary "Dstutter"
-
-> import Sound.SC3.ID
-
-> let {inp = dseq 'α' dinf (mce [1,2,3])
->     ;nse = diwhite 'β' dinf 2 8
->     ;rep = dstutter 'γ' nse inp
->     ;trg = impulse KR (mouseX KR 1 40 Exponential 0.2) 0
->     ;frq = demand trg 0 rep * 30 + 340}
-> in audition (out 0 (sinOsc AR frq 0 * 0.1))
-
-https://www.listarc.bham.ac.uk/lists/sc-users/msg14775.html
-
-> let {a z = let {xr = dxrand z dinf (mce [0.1,0.2,0.3,0.4,0.5])
->                ;lf = dstutter z 2 xr
->                ;du = duty AR lf 0 DoNothing lf
->                ;tr = abs (hpz1 du) >* 0
->                ;ph = sweep tr (1/du)}
->            in linExp ph 0 1 (rand z 50 100) (rand z 500 2000)
->     ;f = mce (map a ['a'..'h'])
->     ;[s0,s1] = mceChannels (splay (sinOsc AR f 0) 1 1 0 True)
->     ;o = limiter (rotate2 s0 s1 (lfSaw KR 0.1 0)) 1 1e-2}
-> in audition (out 0 (o * 0.25))
diff --git a/Help/UGen/Demand/dswitch.help.lhs b/Help/UGen/Demand/dswitch.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dswitch.help.lhs
+++ /dev/null
@@ -1,27 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dswitch"
-> Sound.SC3.UGen.DB.ugenSummary "Dswitch"
-
-> import Sound.SC3
-
-> do {a0 <- dwhiteM 2 3 4
->    ;a1 <- dwhiteM 2 0 1
->    ;a2 <- dseqM 2 (mce [1,1,1,0])
->    ;i <- dseqM 2 (mce [0,1,2,1,0])
->    ;d <- dswitchM i (mce [a0,a1,a2])
->    ;let {t = impulse KR 4 0
->         ;f = demand t 0 d * 300 + 400
->         ;o = sinOsc AR f 0 * 0.1}
->      in audition (out 0 o)}
-
-compare with dswitch1
-
-> do {a0 <- dwhiteM 2 3 4
->    ;a1 <- dwhiteM 2 0 1
->    ;a2 <- dseqM 2 (mce [1,1,1,0])
->    ;i <- dseqM 2 (mce [0,1,2,1,0])
->    ;d <- dswitch1M i (mce [a0,a1,a2])
->    ;let {t = impulse KR 4 0
->         ;f = demand t 0 d * 300 + 400
->         ;o = sinOsc AR f 0 * 0.1}
->      in audition (out 0 o)}
-
diff --git a/Help/UGen/Demand/dswitch1.help.lhs b/Help/UGen/Demand/dswitch1.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dswitch1.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dswitch1"
-> Sound.SC3.UGen.DB.ugenSummary "Dswitch1"
-
-> import Sound.SC3.ID
-
-> let {x = mouseX KR 0 4 Linear 0.1
->     ;y = mouseY KR 1 15 Linear 0.1
->     ;t = impulse KR 3 0
->     ;w = dwhite 'α' dinf 20 23
->     ;n = dswitch1 'β' x (mce [1, 3, y, 2, w])
->     ;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
deleted file mode 100644
--- a/Help/UGen/Demand/duty.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Duty"
-> Sound.SC3.UGen.DB.ugenSummary "Duty"
-
-> import Sound.SC3
-> import qualified Sound.SC3.Monad as M
-
-> do {n0 <- M.drand dinf (mce [0.01,0.2,0.4])
->    ;n1 <- M.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 {n = dseq 'α' dinf (mce [204,400,201,502,300,200])
->     ;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
deleted file mode 100644
--- a/Help/UGen/Demand/dwhite.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dwhite"
-> Sound.SC3.UGen.DB.ugenSummary "Dwhite"
-
-> import Sound.SC3
-
-> let {n = dwhite 'α' 30 0 15
->     ;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/dwrand.help.lhs b/Help/UGen/Demand/dwrand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dwrand.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dwrand"
-> Sound.SC3.UGen.DB.ugenSummary "Dwrand"
-
-> import Sound.SC3
-
-> let {n = dwrand 'α' dinf (mce [0.3,0.2,0.1,0.2,0.2]) (mce [1,3,2,7,8])
->     ;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/dxrand.help.lhs b/Help/UGen/Demand/dxrand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/dxrand.help.lhs
+++ /dev/null
@@ -1,33 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dxrand"
-> Sound.SC3.UGen.DB.ugenSummary "Dxrand"
-
-> import Sound.SC3.ID
-
-Select to draw graphs, or not...
-> let drw = Sound.SC3.UGen.Dot.draw :: UGen -> IO ()
-> let drw = const (return ()) :: UGen -> IO ()
-
-> let {i = mce [0.2,0.4,dseq 'α' 2 (mce [0.1,0.1])]
->     ;d = dxrand 'β' dinf i
->     ;t = tDuty AR d 0 DoNothing (dwhite 'γ' dinf 0.5 1) 0}
-> in audition (out 0 t) >> drw t
-
-The list inputs to demand rate ugens may operate at different rates.
-The variants i' and i'' below ought to generate the same graph.  A
-simple-minded mce rule sets the rate of the operator primitive to the
-maximum rate of the inputs and then does not revise this after mce
-transformation, where it may be lower.  The hsc3 constructors attempt
-to get this right!
-
-> let {i = mce [0.2,0.4,dseq 'α' 2 (mce [0.1,0.1])]
->     ;i' = mceMap (* 0.5) i
->     ;i'' = i * 0.5
->     ;d = dxrand 'β' dinf i''
->     ;t = tDuty AR d 0 DoNothing (dwhite 'γ' dinf 0.5 1) 0}
-> in audition (out 0 t) >> drw t
-
-> let {n = dxrand 'α' dinf (mce [1, 3, 2, 7, 8])
->     ;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)) >> drw f
diff --git a/Help/UGen/Demand/tDuty.help.lhs b/Help/UGen/Demand/tDuty.help.lhs
deleted file mode 100644
--- a/Help/UGen/Demand/tDuty.help.lhs
+++ /dev/null
@@ -1,44 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TDuty"
-> Sound.SC3.UGen.DB.ugenSummary "TDuty"
-
-> import Sound.SC3.ID
-
-Play a little rhythm
-
-> let d = dseq 'α' dinf (mce [0.1, 0.2, 0.4, 0.3])
-> in audition (out 0 (tDuty AR d 0 DoNothing 1 0))
-
-Amplitude changes
-
-> let {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])
->     ;s = ringz (tDuty AR d0 0 DoNothing d1 1) 1000 0.1}
-> in audition (out 0 s)
-
-Mouse control.
-
-> let {d = dseq 'α' dinf (mce [0.1, 0.4, 0.01, 0.5, 1.0])
->     ;x = mouseX KR 0.003 1 Exponential 0.1
->     ;s = ringz (tDuty AR x 0 DoNothing d 1) 1000 0.1 * 0.5}
-> in audition (out 0 s)
-
-Note that the 440 is the shorter pitch, since gap is set to false
-
-> let {d0 = dser 'α' 12 (mce [0.1, 0.3])
->     ;d1 = dser 'β' 12 (mce [440, 880])
->     ;t = tDuty AR d0 0 RemoveSynth d1 0}
-> in audition (out 0 (sinOsc AR (latch t t) 0 * 0.1))
-
-Abstraction
-
-> import Data.List
-
-> let {bp n d act = let {(e,t) = unzip d
->                       ;mk z l = dser z n (mce l)
->                       ;sq = tDuty AR (mk 'α' t) 0 act (mk 'β' e) 0}
->                   in latch sq sq
->     ;bp' d = bp (genericLength d) d
->     ;tm m = let f (e,t) = (e,t * m) in map f
->     ;f1 = midiCPS (bp 35 (tm 0.125 [(60,1),(63,1),(67,2),(68,1),(62,1)]) RemoveSynth)
->     ;f2 = midiCPS (bp' [(60,1),(63,0.5),(67,0.5),(68,1),(62,1)] DoNothing)}
-> in audition (out 0 (sinOsc AR (mce2 f1 f2) 0 * 0.1))
diff --git a/Help/UGen/DiskIO/diskIn.help.lhs b/Help/UGen/DiskIO/diskIn.help.lhs
deleted file mode 100644
--- a/Help/UGen/DiskIO/diskIn.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DiskIn"
-> Sound.SC3.UGen.DB.ugenSummary "DiskIn"
-
-> import Sound.SC3
-
-> let {fn = "/home/rohan/data/audio/pf-c5.snd"
->     ;nc = 1
->     ;gr = out 0 (diskIn nc 0 Loop)}
-> in withSC3 (do {_ <- async (b_alloc 0 65536 nc)
->                ;_ <- async (b_read 0 fn 0 (-1) 0 True)
->                ;play gr})
-
-> withSC3 (do {reset
->             ;_ <- async (b_close 0)
->             ;async (b_free 0)})
diff --git a/Help/UGen/DiskIO/diskOut.help.lhs b/Help/UGen/DiskIO/diskOut.help.lhs
deleted file mode 100644
--- a/Help/UGen/DiskIO/diskOut.help.lhs
+++ /dev/null
@@ -1,41 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DiskOut"
-> Sound.SC3.UGen.DB.ugenSummary "DiskOut"
-
-> import Sound.OSC {- hosc -}
-> import Sound.SC3.ID {- hsc3 -}
-
-Example graph
-
-> let gr = let d = xLine KR 20000 2 10 RemoveSynth
->          in dust 'α' AR d * 0.15
-
-> let gr = soundIn 0
-
-Check incoming signal (either graph above or the outside world)
-
-> audition (out 0 gr)
-
-Record incoming signal (or above...), print some informational traces...
-
-> let trace str = liftIO (putStrLn str)
-
-> withSC3 (do {trace "b_alloc & b_write"
->             ;_ <- async (b_alloc 0 65536 1)
->             ;_ <- async (b_write 0 "/tmp/disk-out.aiff" Aiff PcmInt16 (-1) 0 True)
->             ;trace "record for 10 seconds"
->             ;playSynthdef 2001 (synthdef "disk-out" (diskOut 0 gr))
->             ;pauseThread 10
->             ;trace "stop recording and tidy up"
->             ;send (n_free [2001])
->             ;_ <- async (b_close 0)
->             ;_ <- async (b_free 0)
->             ;return ()})
-
-Listen to recording (on loop...)
-
-> let {fn = "/tmp/disk-out.aiff"
->     ;nc = 1
->     ;gr = out 0 (diskIn nc 0 Loop)}
-> in withSC3 (do {_ <- async (b_alloc 0 65536 nc)
->                ;_ <- async (b_read 0 fn 0 (-1) 0 True)
->                ;play gr})
diff --git a/Help/UGen/DiskIO/vDiskIn.help.lhs b/Help/UGen/DiskIO/vDiskIn.help.lhs
deleted file mode 100644
--- a/Help/UGen/DiskIO/vDiskIn.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "VDiskIn"
-> Sound.SC3.UGen.DB.ugenSummary "VDiskIn"
-
-> import Sound.SC3 {- hsc3 -}
-
-> let {fn = "/home/rohan/data/audio/pf-c5.snd"
->     ;nc = 1
->     ;gr = out 0 (vDiskIn nc 0 (sinOsc KR 0.25 0 * 0.25 + 1) Loop)}
-> in withSC3 (do {_ <- async (b_alloc 0 8192 nc)
->                ;_ <- async (b_read 0 fn 0 (-1) 0 True)
->                ;play gr})
-
-> withSC3 (do {reset
->             ;_ <- async (b_close 0)
->             ;_ <- async (b_free 0)
->             ;return ()})
diff --git a/Help/UGen/Envelope/detectSilence.help.lhs b/Help/UGen/Envelope/detectSilence.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/detectSilence.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DetectSilence"
-> Sound.SC3.UGen.DB.ugenSummary "DetectSilence"
-
-> import Sound.SC3
-
-> let {s = sinOsc AR 440 0 * mouseY KR 0 0.2 Linear 0.1
->     ;d = detectSilence s 0.1 0.1 RemoveSynth}
-> in audition (mrg [out 0 s,d])
diff --git a/Help/UGen/Envelope/done.help.lhs b/Help/UGen/Envelope/done.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/done.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Done"
-> Sound.SC3.UGen.DB.ugenSummary "Done"
-
-> import Sound.SC3
-
-> 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/envADSR.help.lhs b/Help/UGen/Envelope/envADSR.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envADSR.help.lhs
+++ /dev/null
@@ -1,60 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Env.*adsr"
-> :i Sound.SC3.ADSR
-> :t Sound.SC3.envADSR_r
-> :t Sound.SC3.envADSR
-
-> import Sound.SC3 {- hsc3 -}
-
-{SinOsc.ar * EnvGen.kr(Env.adsr(0.75, 2.75, 0.1, 7.25, 1, -4, 0))}.draw;
-
-> let g = let {c = control KR "env-gate" 1
->             ;p = envADSR 0.75 2.75 0.1 7.25 1 (EnvNum (-4)) 0
->             ;e = envGen KR c 1 0 1 DoNothing p}
->         in sinOsc AR 440 0 * e * 0.1
-
-> audition (out 0 g)
-
-> withSC3 (send (n_set1 (-1) "env-gate" 0))
-> withSC3 (send (n_set1 (-1) "env-gate" 1))
-> withSC3 (send (n_free [-1]))
-
-> import Sound.SC3.Plot {- hsc3 -}
-
-> plotEnvelope [envADSR 0.75 0.75 0.5 0.75 1 (EnvNum (-4)) 0
->              ,envADSR 0.02 0.2 0.25 1 1 (EnvNum (-4)) 0
->              ,envADSR 0.001 0.2 0.25 1 1 (EnvNum (-4)) 0
->              ,envADSR 0 2 1 0.1 0.5 EnvSin 0
->              ,envADSR 0.001 1.54 1 0.001 0.4 EnvSin 0]
-
-There is a record variant:
-
-> let {g = control KR "gate" 1
->     ;c = EnvNum (-4)
->     ;r = ADSR {adsr_attackTime = 0.75
->               ,adsr_decayTime = 0.75
->               ,adsr_sustainLevel = 0.5
->               ,adsr_releaseTime = 0.75
->               ,adsr_peakLevel = 1
->               ,adsr_curve = (c,c,c)
->               ,adsr_bias = 0}
->     ;p = envADSR_r r
->     ;e = envGen KR g 0.1 0 1 DoNothing p}
-> in audition (out 0 (sinOsc AR 440 0 * e))
-
-> withSC3 (send (n_set1 (-1) "gate" 0))
-> withSC3 (send (n_set1 (-1) "gate" 1))
-> withSC3 (send (n_free [-1]))
-
-SC3 comparison:
-
-Env.adsr.asArray == [0,3,2,-99,1,0.01,5,-4,0.5,0.3,5,-4,0,1,5,-4];
-
-> let r = [0,3,2,-99,1,0.01,5,-4,0.5,0.3,5,-4,0,1,5,-4]
-> in envelope_sc3_array (envADSR 0.01 0.3 0.5 1 1 (EnvNum (-4)) 0) == Just r
-
-> let r = [0,3,2,-99,1,0.3,5,-4,0.1,0.4,5,-4,0,1.2,5,-4]
-> in envelope_sc3_array (envADSR 0.3 0.4 0.1 1.2 1 (EnvNum (-4)) 0) == Just r
-
-x = {|gate=0, freq=440 | EnvGen.kr(Env.adsr,gate) * SinOsc.ar(freq,0) * 0.1}.play
-x.set(\gate,1);
-x.set(\gate,0);
diff --git a/Help/UGen/Envelope/envASR.help.lhs b/Help/UGen/Envelope/envASR.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envASR.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Env.*asr"
-> :i Sound.SC3.ASR
-
-> import Sound.SC3
-
-> let {g = control KR "env-gate" 1
->     ;p = envASR 0.01 1 1 (EnvNum (-4))
->     ;e = envGen KR g 0.1 0 1 RemoveSynth p}
-> in audition (out 0 (sinOsc AR 440 0 * e))
-
-> withSC3 (send (n_set1 (-1) "env-gate" 0))
-
-> import Sound.SC3.Plot
-
-> plotEnvelope [envASR 0.1 1 1 (EnvNum (-4))
->              ,envASR 0.3 0.25 1 EnvSin
->              ,envASR 0.01 0.5 1.25 EnvLin]
diff --git a/Help/UGen/Envelope/envCoord.help.lhs b/Help/UGen/Envelope/envCoord.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envCoord.help.lhs
+++ /dev/null
@@ -1,48 +0,0 @@
-> import Sound.SC3
-> :t envCoord
-
-co-ordinate (break-point) envelope
-
-> let {c = EnvLin
->     ;p = envCoord [(0,0),(0.5,0.1),(0.55,1),(1,0)] 9 0.1 c
->     ;e = envGen KR 1 1 0 1 RemoveSynth p}
-> in audition (out 0 (sinOsc AR 440 0 * e))
-
-line segments, set target value & transition time and trigger
-
-> let {tr = tr_control "tr" 1
->     ;st = control KR "st" 440
->     ;en = control KR "en" 880
->     ;tm = control KR "tm" 2
->     ;p = envCoord [(0,st),(tm,en)] 1 1 EnvLin
->     ;e = envGen KR tr 1 0 1 DoNothing p}
-> in audition (out 0 (sinOsc AR e 0 * 0.2))
-
-> withSC3 (send (n_set (-1) [("en",550),("tm",4),("tr",1)]))
-> withSC3 (send (n_set (-1) [("en",990),("tm",1),("tr",1)]))
-> withSC3 (send (n_set (-1) [("en",110),("tm",2),("tr",1)]))
-
-> import Sound.SC3.ID
-
-likewise, but internal graph triggers and randomises line end points
-
-> let {tr = dust 'α' KR 2
->     ;st = 440
->     ;en = tRand 'β' 300 900 tr
->     ;tm = tRand 'γ' 0.5 1.5 tr
->     ;p = envCoord [(0,st),(tm,en)] 1 1 EnvLin
->     ;e = envGen KR tr 1 0 1 DoNothing p}
-> in audition (out 0 (sinOsc AR e 0 * 0.2))
-
-plotting
-
-> import Sound.SC3.Plot
-
-> let {c0 = [(0,0),(0.35,0.1),(0.55,1),(1,0)]
->     ;c1 = [(0,0),(0.15,0.6),(0.35,0.2),(1,0)]
->     ;c2 = [(0,0),(0.65,0.3),(0.85,0.7),(1,0)]
->     ;c3 = [(0,0.1),(0.25,0.6),(0.5,0.4),(1,0.4)]}
-> in plotEnvelope [envCoord c0 9 0.1 EnvLin
->                 ,envCoord c1 6 0.1 EnvSin
->                 ,envCoord c2 5 0.1 EnvCub
->                 ,envCoord c3 7 0.1 EnvStep]
diff --git a/Help/UGen/Envelope/envGate.help.lhs b/Help/UGen/Envelope/envGate.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envGate.help.lhs
+++ /dev/null
@@ -1,30 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "EnvGate"
-
-> import Sound.SC3
-
-Make envGate, giving the /default/ arguments, as used by envGate'.
-
-> let {k = control KR
->     ;e = envGate 1 (k "gate" 1) (k "fadeTime" 0.02) RemoveSynth EnvSin}
-> in audition (out 0 (lpf (saw AR 200) 600 * 0.1 * e))
-
-Set fade time, then release gate.
-
-> withSC3 (send (n_set1 (-1) "fadeTime" 2))
-> withSC3 (send (n_set1 (-1) "gate" 0))
-
-The same, but built in defaults.
-
-> let e = envGate'
-> in audition (out 0 (lpf (saw AR 200) 600 * 0.1 * e))
-
-Several envGate nodes can coexist in one synth, but if they are the
-same they're shared (as ever).
-
-> let {e = envGate'
->     ;s1 = lpf (saw AR 80) 600 * e
->     ;s2 = rlpf (saw AR 200 * 0.5) (6000 * e + 60) 0.1 * e}
-> in audition (out 0 (mce2 s1 s2 * 0.1))
-
-> withSC3 (send (n_set1 (-1) "fadeTime" 5))
-> withSC3 (send (n_set1 (-1) "gate" 0))
diff --git a/Help/UGen/Envelope/envGen.help.lhs b/Help/UGen/Envelope/envGen.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envGen.help.lhs
+++ /dev/null
@@ -1,33 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "EnvGen"
-> Sound.SC3.UGen.DB.ugenSummary "EnvGen"
-
-At least the following envelope constructors are provided:
-envPerc, envSine, envCoord, envTrapezoid, and envLinen.
-
-> import Sound.SC3 {- hsc3 -}
-
-env_circle joins the end of the envelope to the start
-
-> let {e = Envelope [6000,700,100] [1,1] [EnvExp,EnvLin] Nothing Nothing
->     ;f = envGen KR 1 1 0 1 DoNothing (env_circle e 0 EnvLin)
->     ;o = sinOsc AR f 0 * 0.1 + impulse AR 1 0}
-> in audition (out 0 o)
-
-Env([6000,700,100],[1,1],['exp','lin']).circle.asArray
-
-> let {e = Envelope [6000,700,100] [1,1] [EnvExp,EnvLin] Nothing Nothing
->     ;r = [0,4,3,0,6000,0,1,0,700,1,2,0,100,1,1,0,0,9e8,1,0]}
-> in envelope_sc3_array (env_circle e 0 EnvLin) == Just r
-
-Env([0,1],[0.1]).asArray == [0,1,-99,-99,1,0.1,1,0]
-
-> let e = (Envelope [0,1] [0.1] [EnvLin] Nothing Nothing)
-> in envelope_sc3_array e == Just [0,1,-99,-99,1,0.1,1,0]
-
-https://www.listarc.bham.ac.uk/lists/sc-users/msg14815.html
-
-> let {n = range 0.01 0.1 (lfNoise1 'α' KR 2)
->     ;e = Envelope [0,1] [n] [EnvLin] Nothing (Just 0)
->     ;a = envGen AR 1 1 0 1 DoNothing (env_circle e 0 EnvLin)
->     ;o = sinOsc AR (a * 400 + 500) 0 * 0.1}
-> in audition (out 0 o)
diff --git a/Help/UGen/Envelope/envLinen.help.lhs b/Help/UGen/Envelope/envLinen.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envLinen.help.lhs
+++ /dev/null
@@ -1,26 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Env.*linen"
-> :i Sound.SC3.LINEN
-> :t envLinen
-
-> import Sound.SC3
-
-> let {t = envLinen 0.4 2 0.4 0.1
->     ;e = envGen KR 1 1 0 1 RemoveSynth t}
-> in audition (out 0 (sinOsc AR 440 0 * e))
-
-> import Sound.SC3.Plot
-
-> plotEnvelope [envLinen 0 1 0 0.4
->              ,envelope_normalise (envLinen 0 2 0 0.5)
->              ,envLinen 0.4 2 0.4 0.6
->              ,envLinen 0.6 1 1.2 0.7]
-
-> let e = envLinen 0 1 0 1
-> in (envelope_duration e
->    ,envelope_segment_ix e 0
->    ,envelope_segment_ix e 1
->    ,envelope_segment e 0
->    ,envelope_segment e 1
->    ,envelope_at e 0
->    ,envelope_at e 1
->    ,envelope_render 10 e)
diff --git a/Help/UGen/Envelope/envPerc.help.lhs b/Help/UGen/Envelope/envPerc.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envPerc.help.lhs
+++ /dev/null
@@ -1,19 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Env.*perc"
-> :t envPerc'
-
-> import Sound.SC3 {- hsc3 -}
-
-> let {a = 0.1
->     ;p = envPerc 0.01 1
->     ;e = envGen KR 1 a 0 1 RemoveSynth p }
-> in audition (out 0 (sinOsc AR 440 0 * e))
-
-> let {a = 0.1
->     ;c = EnvNum (-4)
->     ;p = envPerc' 0.01 1 a (c,c)
->     ;e = envGen KR 1 1 0 1 RemoveSynth p }
-> in audition (out 0 (sinOsc AR 440 0 * e))
-
-> import Sound.SC3.Plot {- hsc3-plot -}
-
-> plotEnvelope [envPerc 0.05 1,envPerc 0.2 0.75]
diff --git a/Help/UGen/Envelope/envSine.help.lhs b/Help/UGen/Envelope/envSine.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envSine.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Env.*sine"
-> :t Sound.SC3.envSine
-
-> import Sound.SC3 {- hsc3 -}
-
-> let {s = envSine 9 0.1
->     ;e = envGen KR 1 1 0 1 RemoveSynth s}
-> in audition (out 0 (sinOsc AR 440 0 * e))
-
-> import Sound.SC3.Plot {- hsc3-plot -}
-
-> plotEnvelope [envSine 9 1,envSine 3 0.25]
diff --git a/Help/UGen/Envelope/envStep.help.lhs b/Help/UGen/Envelope/envStep.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envStep.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Env.*step"
-> :i Sound.SC3.envStep
-
-> import Sound.SC3 {- hsc3 -}
-
-> let {env = envStep [0.0,0.5,0.7,1.0,0.9,0.0] [0.5,0.1,0.2,1.0,1.5,3] Nothing Nothing
->     ;envgen = envGen AR 1 1 0 1 RemoveSynth env
->     ;o = sinOsc AR (envgen * 1000 + 440) 0 * (envgen + 1) * 0.1}
-> in audition (out 0 o)
-
-major scale, accelerating
-
-> let {env = envStep [0,2,4,5,7,9,11,12] (take 8 (iterate (* 0.75) 1)) Nothing Nothing
->     ;envgen = envGen AR 1 1 0 1 DoNothing env
->     ;o = sinOsc AR (midiCPS (envgen + 60)) 0 * 0.1}
-> in audition (out 0 o)
-
-draw envelope
-
-> import Sound.SC3.Plot
-
-> plotEnvelope [envStep [0,2,4,5,7,9,11,12] (take 8 (iterate (* 0.75) 1)) Nothing Nothing]
diff --git a/Help/UGen/Envelope/envTrapezoid.help.lhs b/Help/UGen/Envelope/envTrapezoid.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envTrapezoid.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> :t Sound.SC3.envTrapezoid
-
-> import Sound.SC3
-
-> 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))
-
-> let e = [0,3,-99,-99,0.1,0.5,1,0,0.1,0,1,0,0,1.5,1,0]
-> in envelope_sc3_array (envTrapezoid 0 0.25 2 0.1) == Just e
-
-> import Sound.SC3.Plot
-> plotEnvelope [envTrapezoid 0.75 0.25 2 1,envTrapezoid 0.25 0.75 3 0.5]
diff --git a/Help/UGen/Envelope/envTriangle.help.lhs b/Help/UGen/Envelope/envTriangle.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/envTriangle.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Env.*triangle"
-> :t envTriangle
-
-> import Sound.SC3
-
-> let {t = envTriangle 1 0.1
->     ;e = envGen KR 1 1 0 1 RemoveSynth t}
-> in audition (out 0 (sinOsc AR 440 0 * e))
-
-> import Sound.SC3.Plot
-> plotEnvelope [envTriangle 1 1,envTriangle 0.25 0.5]
diff --git a/Help/UGen/Envelope/free.help.lhs b/Help/UGen/Envelope/free.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/free.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Free"
-> Sound.SC3.UGen.DB.ugenSummary "Free"
-
-> import Sound.SC3.ID
-
-> let {a = out 0 (sinOsc AR 880 0 * 0.1)
->     ;n0 = pinkNoise 'a' AR
->     ;n1 = dust 'b' AR 20
->     ;b = mrg [out 1 (n0 * 0.1), free n1 1001]}
-> in withSC3 (do {_ <- async (d_recv (synthdef "a" a))
->                ;_ <- async (d_recv (synthdef "b" b))
->                ;send (s_new "a" 1001 AddToTail 1 [])
->                ;send (s_new "b" (-1) AddToTail 1 [])})
diff --git a/Help/UGen/Envelope/freeSelf.help.lhs b/Help/UGen/Envelope/freeSelf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/freeSelf.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FreeSelf"
-> Sound.SC3.UGen.DB.ugenSummary "FreeSelf"
-
-> import Sound.SC3.ID
-
-> let {n = dust 'a' KR 0.5
->     ;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
deleted file mode 100644
--- a/Help/UGen/Envelope/freeSelfWhenDone.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FreeSelfWhenDone"
-> Sound.SC3.UGen.DB.ugenSummary "FreeSelfWhenDone"
-
-> import Sound.SC3
-
-using RemoveSynth doneAction
-> 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))
-
-using FreeSelfWhenDone UGen
-> 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/iEnvGen.help.lhs b/Help/UGen/Envelope/iEnvGen.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/iEnvGen.help.lhs
+++ /dev/null
@@ -1,25 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "IEnvGen"
-> Sound.SC3.UGen.DB.ugenSummary "IEnvGen"
-
-> import Sound.SC3.ID
-
-> let {l = [0,0.6,0.3,1.0,0]
->     ;t = [0.1,0.02,0.4,1.1]
->     ;c = [EnvLin,EnvExp,EnvNum (-6),EnvSin]
->     ;e = Envelope l t c Nothing Nothing
->     ;x = mouseX KR 0 (sum t) Linear 0.2
->     ;g = iEnvGen KR x e
->     ;o = sinOsc AR (g * 500 + 440) 0 * 0.1}
-> in audition (out 0 o)
-
-index with an SinOsc ... mouse controls amplitude of SinOsc
-use offset so negative values of SinOsc will map into the Env
-
-> let {l = [-1,-0.7,0.7,1]
->     ;t = [0.8666,0.2666,0.8668]
->     ;c = [EnvLin,EnvLin]
->     ;e = Envelope l t c Nothing Nothing
->     ;x = mouseX KR 0 1 Linear 0.2
->     ;o = (sinOsc AR 440 0 + 1) * x
->     ;g = iEnvGen AR o e * 0.1}
-> in audition (out 0 g)
diff --git a/Help/UGen/Envelope/line.help.lhs b/Help/UGen/Envelope/line.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/line.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Line"
-> Sound.SC3.UGen.DB.ugenSummary "Line"
-
-#SC3 reorders the mul and add inputs to precede the doneAction input.
-
-> import Sound.SC3
-
-> let f = line KR 200 17000 5 RemoveSynth
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
-
-Demonstrate RemoveGroup done-action.
-
-> withSC3 (send (g_new [(10,AddToTail,1)]))
-
-> let f = line KR 200 (mce2 209 211) 5 RemoveGroup
-> in audition_at (-1,AddToTail,10) (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Envelope/linen.help.lhs b/Help/UGen/Envelope/linen.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/linen.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Linen"
-> Sound.SC3.UGen.DB.ugenSummary "Linen"
-
-> import Sound.SC3
-
-> let e = linen (impulse KR 2 0) 0.01 0.6 0.4 DoNothing
-> 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 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
deleted file mode 100644
--- a/Help/UGen/Envelope/pause.help.lhs
+++ /dev/null
@@ -1,18 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Pause"
-> Sound.SC3.UGen.DB.ugenSummary "Pause"
-
-> import Sound.SC3
-
-> 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' = synthdef "a" a}
-> in withSC3 (do {_ <- async (d_recv a')
->                ;send (s_new "a" 1001 AddToTail 1 [])
->                ;send (s_new "a" 1002 AddToTail 1 [("f",880)])})
-
-Request that node 1002 pause node 1001.
-> withSC3 (send (n_set 1002 [("g",0)]))
-
-Restart node 1001.
-> withSC3 (send (n_set 1002 [("g",1)]))
diff --git a/Help/UGen/Envelope/pauseSelf.help.lhs b/Help/UGen/Envelope/pauseSelf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/pauseSelf.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PauseSelf"
-> Sound.SC3.UGen.DB.ugenSummary "PauseSelf"
-
-> import Sound.SC3
-
-> 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).
-> withSC3 (send (n_run [(-1, True)]))
diff --git a/Help/UGen/Envelope/pauseSelfWhenDone.help.lhs b/Help/UGen/Envelope/pauseSelfWhenDone.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/pauseSelfWhenDone.help.lhs
+++ /dev/null
@@ -1,19 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PauseSelfWhenDone"
-> Sound.SC3.UGen.DB.ugenSummary "PauseSelfWhenDone"
-
-> import Sound.SC3
-
-using PauseSynth done action
-> 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))
-
-Run paused node (assuming no intermediate node is created).
-> withSC3 (send (n_run [(-1, True)]))
-
-> 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])
-
-> withSC3 (send (n_run [(-1, True)]))
diff --git a/Help/UGen/Envelope/xLine.help.lhs b/Help/UGen/Envelope/xLine.help.lhs
deleted file mode 100644
--- a/Help/UGen/Envelope/xLine.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "XLine"
-> Sound.SC3.UGen.DB.ugenSummary "XLine"
-
-# SC3 reorders mul and add inputs to precede the doneAction input.
-
-> import Sound.SC3
-
-> 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/External/atari2600.help.lhs b/Help/UGen/External/atari2600.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/atari2600.help.lhs
+++ /dev/null
@@ -1,68 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Atari2600"
-> Sound.SC3.UGen.DB.ugenSummary "Atari2600"
-
-> import Sound.SC3 {- hsc3 -}
-
-> audition (out 0 (atari2600 1 2 3 4 5 5 1))
-> audition (out 0 (atari2600 2 3 10 10 5 5 1))
-
-> let {x = mouseX KR 0 15 Linear 0.1
->     ;y = mouseY KR 0 15 Linear 0.1}
-> in audition (out 0 (atari2600 x y 10 10 5 5 1))
-
-> let {x = mouseX KR 0 31 Linear 0.1
->     ;y = mouseY KR 0 31 Linear 0.1}
-> in audition (out 0 (atari2600 2 3 x y 5 5 1))
-
-> let {x = mouseX KR 0 15 Linear 0.1
->     ;y = mouseY KR 0 15 Linear 0.1}
-> in audition (out 0 (atari2600 2 3 10 10 x y 1))
-
-> let {x = mouseX KR 0 15 Linear 0.1
->     ;o1 = sinOsc KR 0.35 0 * 7.5 + 7.5
->     ;y = mouseY KR 0 31 Linear 0.1
->     ;o2 = sinOsc KR 0.3 0 * 5.5 + 5.5}
-> in audition (out 0 (atari2600 x o1 10 y o2 5 1))
-
-> let ati = let {gate' = control KR "gate" 1
->               ;tone0 = control KR "tone0" 5
->               ;tone1 = control KR "tone1" 8
->               ;freq0 = control KR "freq0" 10
->               ;freq1 = control KR "freq1" 20
->               ;rate = control KR "rate" 1
->               ;amp = control KR "amp" 1
->               ;pan = control KR "pan" 0
->               ;e = envASR 0.01 amp 0.05 (EnvNum (-4))
->               ;eg = envGen KR gate' 1 0 1 RemoveSynth e
->               ;z = atari2600 tone0 tone1 freq0 freq1 15 15 rate
->               ;o = out 0 (pan2 (z * eg) pan 1)}
->           in synthdef "atari2600" o
-
-> import Sound.SC3.Lang.Pattern
-
-> let p = [(K_instr,psynth ati)
->         ,(K_dur,0.125)
->         ,(K_amp,0.5)
->         ,(K_param "tone0",pseq [pn 3 64,pn 2 128,pn 10 8] inf)
->         ,(K_param "tone1",pseqn [32,12] [8,pwhite 'α' 0 15 inf] inf)
->         ,(K_param "freq0",pseqn [17,4,3] [10,prand 'β' [1,2,3] inf,10] inf)
->         ,(K_param "freq1",pseq1 [10,3,pwrand 'γ' [20,1] [0.6,0.4] inf] inf)]
-> in audition (pbind p)
-
-> let p = [(K_instr,psynth ati)
->         ,(K_dur,pseq [0.25,0.25,0.25,0.45] inf)
->         ,(K_amp,0.5)
->         ,(K_param "tone0",pseq [pseq [2,5] 32,pseq [3,5] 32] inf)
->         ,(K_param "tone1",14)
->         ,(K_param "freq0",pseq [pbrown 'α' 28 31 1 32,pbrown 'β' 23 26 3 32] inf)
->         ,(K_param "freq1",pseq [pn 10 16,pn 11 16] inf)]
-> in audition (pbind p)
-
-> let p = [(K_instr,psynth ati)
->         ,(K_dur,pbrown 'α' 0.1 0.15 0.1 inf)
->         ,(K_amp,0.5)
->         ,(K_param "tone0",1)
->         ,(K_param "tone1",2)
->         ,(K_param "freq0",pseqn [2,1] [24,pwrand 'β' [20,23] [0.6,0.4] inf] inf)
->         ,(K_param "freq1",pseqn [1,1,1] [1,3,pwrand 'γ' [2,1] [0.6,0.4] inf] inf)]
-> in audition (pbind p)
diff --git a/Help/UGen/External/atsNoiSynth.help.lhs b/Help/UGen/External/atsNoiSynth.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/atsNoiSynth.help.lhs
+++ /dev/null
@@ -1,27 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "AtsNoiSynth"
-> Sound.SC3.UGen.DB.ugenSummary "AtsNoiSynth"
-
-> import Sound.SC3
-
-segmented file loader
-> let load_data b i d =
->         if length d < 512
->         then send (b_setn1 b i d)
->         else do {send (b_setn1 b i (take 512 d))
->                 ;load_data b (i + 512) (drop 512 d)}
-
-read file
-> ats <- atsRead "/home/rohan/cvs/tn/tn-56/ats/metal.ats"
-
-run re-synthesis
-> let {d = atsData ats
->     ;h = atsHeader ats
->     ;x = mouseX KR 0.05 1.5 Linear 0.2
->     ;y = mouseY KR 0 1 Linear 0.2
->     ;np = constant (atsNPartials h)
->     ;f = x / constant (atsAnalysisDuration h)
->     ;ptr = clip (lfSaw AR f 1 * 0.5 + 0.5) 0 1
->     ;rs = atsNoiSynth 10 np 0 1 ptr (1 - y) y 1 0 25 0 1}
-> in withSC3 (do {_ <- async (b_alloc 10 (length d) 1)
->                ;load_data 10 0 d
->                ;play (out 0 rs)})
diff --git a/Help/UGen/External/atsSynth.help.lhs b/Help/UGen/External/atsSynth.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/atsSynth.help.lhs
+++ /dev/null
@@ -1,30 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "AtsSynth"
-> Sound.SC3.UGen.DB.ugenSummary "AtsSynth"
-
-> import Sound.SC3
-
-read file
-> ats <- atsRead "/home/rohan/cvs/tn/tn-56/ats/metal.ats"
-
-show header
-> atsHeader ats
-
-data loader that works in segments (udp packet limits)
-> let load_data b i d =
->         if length d < 512
->         then send (b_setn1 b i d)
->         else do {send (b_setn1 b i (take 512 d))
->                 ;load_data b (i + 512) (drop 512 d)}
-
-simple re-synthesiser
-> let {h = atsHeader ats
->     ;d = atsData ats
->     ;x = mouseX KR 0.05 1.5 Linear 0.2
->     ;y = mouseY KR 0.25 2.0 Linear 0.2
->     ;np = constant (atsNPartials h)
->     ;f = x / constant (atsAnalysisDuration h)
->     ;ptr = lfSaw AR f 1 * 0.5 + 0.5
->     ;rs = atsSynth 10 np 0 1 (clip ptr 0 1) y 0}
-> in withSC3 (do {_ <- async (b_alloc 10 (length d) 1)
->                ;load_data 10 0 d
->                ;play (out 0 rs)})
diff --git a/Help/UGen/External/ay.help.lhs b/Help/UGen/External/ay.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/ay.help.lhs
+++ /dev/null
@@ -1,33 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "AY"
-> Sound.SC3.UGen.DB.ugenSummary "AY"
-
-> import Sound.SC3.ID
-> import qualified Sound.SC3.Monad as M
-
-> audition (out 0 (ay 1777 1666 1555 1 7 15 15 15 4 1 0))
-
-> let { tonea = mouseY KR 10 3900 Exponential 0.2
->     ; toneb = mouseX KR 10 3900 Exponential 0.2
->     ; ctl = 3
->     ; vola = 14
->     ; volb = 14
->     ; volc = 0
->     ; s = ay tonea toneb 1555 1 ctl vola volb volc 4 1 0 }
-> in audition (out 0 (pan2 s 0 0.25))
-
-> let {rate = mouseX KR 0.1 10 Linear 0.2
->     ;rng l r i = return (linLin i (-1) 1 l r)
->     ;mk_ctl l r = M.lfdNoise3 KR rate >>= rng l r
->     ;mk_ctl_0 l r = M.lfdNoise0 KR rate >>= rng l r}
-> in do {tonea <- mk_ctl 10 3900
->       ;toneb <- mk_ctl 10 3900
->       ;tonec <- mk_ctl 10 3900
->       ;n <- mk_ctl 0 31
->       ;ctl <- mk_ctl_0 0 31
->       ;vola <- mk_ctl 0 15
->       ;volb <- mk_ctl 0 15
->       ;volc <- mk_ctl 0 15
->       ;efreq <- mk_ctl 0 4095
->       ;estyle <- mk_ctl 0 15
->       ;let s = ay tonea toneb tonec n ctl vola volb volc efreq estyle 0
->        in audition (out 0 (pan2 s 0 0.5))}
diff --git a/Help/UGen/External/concat.help.lhs b/Help/UGen/External/concat.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/concat.help.lhs
+++ /dev/null
@@ -1,20 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Concat"
-> Sound.SC3.UGen.DB.ugenSummary "Concat"
-
-> import Sound.SC3.ID
-
-> let fileName = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (async (b_allocRead 12 fileName 0 0))
-
-Granulator
-> let {y0 = mouseY KR 0.01 1 Linear 0.2
->     ;y1 = mouseY KR 12 100 Linear 0.2
->     ;n = lfNoise0 'α' KR y0 * 3 + 4.5
->     ;k = saw AR (sinOsc KR n 0 * 10 + y1)
->     ;i = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
->     ;x0 = mouseX KR 0.01 0.1 Linear 0.2
->     ;y2 = mouseY KR 0 0.1 Linear 0.2
->     ;c :: UGen
->     ;c = concat' k i 2 2 2 x0 0 y2 1 0.5 0 0
->     ;o = out 0 (pan2 c 0 1)}
-> in audition o
diff --git a/Help/UGen/External/coyote.help.lhs b/Help/UGen/External/coyote.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/coyote.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Coyote"
-> Sound.SC3.UGen.DB.ugenSummary "Coyote"
-
-> import Sound.SC3.ID
-
-> let {i = soundIn 4
->     ;c = coyote KR i 0.2 0.2 0.01 0.5 0.05 0.05
->     ;o = pinkNoise 'a' AR * decay c 1}
-> in audition (out 0 (mce2 i o))
diff --git a/Help/UGen/External/dPW3Tri.help.lhs b/Help/UGen/External/dPW3Tri.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/dPW3Tri.help.lhs
+++ /dev/null
@@ -1,42 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DPW3Tri"
-> Sound.SC3.UGen.DB.ugenSummary "DPW3Tri"
-
-> import Sound.SC3.ID
-
-distortion creeps in under 200Hz
-> let o = dPW3Tri AR (xLine KR 2000 20 10 DoNothing)
-> in audition (out 0 (o * 0.1))
-
-very fast sweeps can have transient distortion effects
-> let o = dPW3Tri AR (mouseX KR 200 12000 Exponential 0.2)
-> in audition (out 0 (o * 0.1))
-
-compare
-> let o = lfTri AR (mouseX KR 200 12000 Exponential 0.2) 0
-> in audition (out 0 (o * 0.1))
-
-(for randN)
-> import Sound.SC3.UGen.External.RDU.ID
-
-less efficient than LFTri
-> let f = randN 50 'a' 50 5000
-> in audition (out 0 (splay (dPW3Tri AR f) 1 0.1 0 True))
-
-> let f = randN 50 'a' 50 5000
-> in audition (out 0 (splay (lfTri AR f 0) 1 0.1 0 True))
-
-triangle is integration of square wave
-> let {f = mouseX KR 440 8800 Exponential 0.2
->     ;o = pulse AR f 0.5
->     ;s = integrator o 0.99}
-> in audition (out 0 (s * 0.05))
-
-differentiation of triangle is square
-> let {f = mouseX KR 440 8800 Exponential 0.2
->     ;o = dPW3Tri AR f
->     ;s = hpz1 (o * 2)}
-> in audition (out 0 (s * 0.25))
-
-compare
-> let f = mouseX KR 440 8800 Exponential 0.2
-> in audition (out 0 (pulse AR f 0.5 * 0.1))
diff --git a/Help/UGen/External/dWGPlucked2.help.lhs b/Help/UGen/External/dWGPlucked2.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/dWGPlucked2.help.lhs
+++ /dev/null
@@ -1,37 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DWGPlucked2"
-> Sound.SC3.UGen.DB.ugenSummary "DWGPlucked2"
-
-> import Sound.SC3.ID
-
-self deleting
-> let {amp = 0.5
->     ;gate = 1
->     ;freq = 440
->     ;c3 = 20
->     ;pan = 0
->     ;e = Envelope
->      [0,1,1,0] [0.001,0.006,0.0005]
->      (map EnvNum [5,-5,-8]) Nothing Nothing
->     ;i = amp * lfClipNoise 'α' AR 2000 * envGen AR gate 1 0 1 DoNothing e
->     ;s = dWGPlucked2 AR freq amp gate 0.1 1 c3 i 0.1 1.008 0.55 0.01
->     ;z = detectSilence s 0.001 0.1 RemoveSynth}
-> in audition (out 0 (mrg2 (pan2 s pan 0.1) z))
-
-re-sounding
-> let {sequ e s tr = demand tr 0 (dseq e dinf (mce s))
->     ;d = dseq 'α' dinf (mce [1,1,2,1,1,1,2,3,1,1,1,1,2,3,4] * 0.175)
->     ;t = tDuty AR d 0 DoNothing 1 0
->     ;amp = tRand 'β' 0.01 0.25 t
->     ;n0 = sequ 'γ' [60,62,63,58,48,55] t
->     ;n1 = sequ 'δ' [63,60,48,62,55,58] t
->     ;freq = midiCPS (mce2 n0 n1)
->     ;c3 = tRand 'ε' 300 1400 t
->     ;pan = tRand 'ζ' (-1) 1 t
->     ;e_dt = tRand 'η' 0.05 0.150 t
->     ;mt = tRand 'θ' 0.992 1.008 t
->     ;pp = tRand 'ι' 0.05 0.15 t
->     ;dt = tRand 'κ' 0.25 1.75 t
->     ;env = decay2 t 0.001 e_dt * lfClipNoise 'λ' AR 2000
->     ;i = amp * lfClipNoise 'μ' AR 2000 * env
->     ;ps = dWGPlucked2 AR freq amp 1 pp (1 / dt) c3 i 0.1 mt 0.55 0.01}
-> in audition (out 0 (pan2 ps pan 0.1))
diff --git a/Help/UGen/External/dfm1.help.lhs b/Help/UGen/External/dfm1.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/dfm1.help.lhs
+++ /dev/null
@@ -1,18 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DFM1"
-> Sound.SC3.UGen.DB.ugenSummary "DFM1"
-
-> import Sound.SC3.ID
-
-Play it with the mouse
-
-> let { n = pinkNoise 'α' AR * 0.5
->     ; x = mouseX KR 80 5000 Exponential 0.1
->     ; y = mouseX KR 0.1 1.2 Linear 0.1 }
-> in audition (out 0 (dfm1 n x y 1 0 3e-4))
-
-Bass...
-
-> let { i = pulse AR 100 0.5 * 0.4 + pulse AR 100.1 0.5 * 0.4
->     ; f = range 80 2000 (sinOsc KR (range 0.2 5 (sinOsc KR 0.3 0)) 0)
->     ; s = dfm1 i f 1.1 2 0 3e-4 * 0.1 }
-> in audition (out 0 (mce2 s s))
diff --git a/Help/UGen/External/disintegrator.help.lhs b/Help/UGen/External/disintegrator.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/disintegrator.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Disintegrator"
-> Sound.SC3.UGen.DB.ugenSummary "Disintegrator"
-
-> import Sound.SC3
-
-> let {x = mouseX KR 0 1 Linear 0.2
->     ;y = mouseY KR 0 1 Linear 0.2
->     ;s = sinOsc AR (mce2 400 404) 0 * 0.2
->     ;o = disintegrator 'α' s x y}
-> in audition (out 0 o)
diff --git a/Help/UGen/External/envDetect.help.lhs b/Help/UGen/External/envDetect.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/envDetect.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "EnvDetect"
-> Sound.SC3.UGen.DB.ugenSummary "EnvDetect"
-
-> import Sound.SC3.ID
-
-> let {i = soundIn 4
->     ;c = envDetect AR i 0.01 0.1
->     ;p = pitch i 440 60 4000 100 16 1 0.01 0.5 1 0
->     ;f = mceChannel 0 p * 3
->     ;e = lagUD (mceChannel 1 p) 0 0.1
->     ;o = pinkNoise 'α' AR * c + sinOsc AR f 0 * c * e}
-> in audition (out 0 (mce2 i o))
diff --git a/Help/UGen/External/envFollow.help.lhs b/Help/UGen/External/envFollow.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/envFollow.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "EnvFollow"
-> Sound.SC3.UGen.DB.ugenSummary "EnvFollow"
-
-> import Sound.SC3.ID
-
-> let {z = soundIn 4
->     ;d = mouseX KR 0.990 0.999 Linear 0.2
->     ;c = envFollow KR z d
->     ;o = pinkNoise 'α' AR * c}
-> in audition (out 0 (mce2 z o))
diff --git a/Help/UGen/External/fm7.help.lhs b/Help/UGen/External/fm7.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/fm7.help.lhs
+++ /dev/null
@@ -1,81 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FM7"
-> Sound.SC3.UGen.DB.ugenSummary "FM7"
-
-> import Sound.SC3
-
-> let {c = [[xLine KR 300 310 4 DoNothing,0,1]
->          ,[xLine KR 300 310 8 DoNothing,0,1]
->          ,[0,0,1]
->          ,[0,0,1]
->          ,[0,0,1]
->          ,[0,0,1] ]
->     ;m = [[line KR 0 0.001 2 DoNothing,line KR 0.1 0 4 DoNothing,0,0,0,0]
->          ,[line KR 0 6 1 DoNothing,0,0,0,0,0]
->          ,[0,0,0,0,0,0]
->          ,[0,0,0,0,0,0]
->          ,[0,0,0,0,0,0]
->          ,[0,0,0,0,0,0] ]
->     ;[l,r,_,_,_,_] = mceChannels (fm7 c m)}
-> in audition (out 0 (mce2 l r * 0.1))
-
-An algorithmically generated graph courtesy f0.
-> let { x = [[[0.0,-1/3,-1.0,0.0]
->            ,[0.75,0.75,0.0,-0.5]
->            ,[-0.5,-0.25,0.25,-0.75]
->            ,[-0.5,1.0,1.0,1.0]
->            ,[0.0,1/6,-0.75,-1.0]
->            ,[0.5,0.5,-0.5,1/3]]
->           ,[[-1/3,0.5,-0.5,-0.5]
->            ,[0.5,0.75,0.25,0.75]
->            ,[-15/18,0.25,-1.0,0.5]
->            ,[1.5,0.25,0.25,-0.25]
->            ,[-2/3,-2/3,-1.0,-0.5]
->            ,[-1.0,0.0,-15/18,-1/3]]
->           ,[[0.25,-0.5,-0.5,-1.0]
->            ,[-0.5,1.0,-1.5,0.0]
->            ,[-1.0,-1.5,-0.5,0.0]
->            ,[0.5,-1.0,7/6,-0.5]
->            ,[15/18,-0.75,-1.5,0.5]
->            ,[0.25,-1.0,0.5,1.0]]
->           ,[[1.0,1/3,0.0,-0.75]
->            ,[-0.25,0.0,0.0,-0.5]
->            ,[-0.5,-0.5,0.0,0.5]
->            ,[1.0,0.75,0.5,0.5]
->            ,[0.0,1.5,-0.5,0.0]
->            ,[1.0,0.0,-0.25,-0.5]]
->           ,[[0.5,-0.25,0.0,1/3]
->            ,[0.25,-0.75,1/3,-1.0]
->            ,[-0.25,-0.5,0.25,-7/6]
->            ,[0.0,0.25,0.5,1/6]
->            ,[-1.0,-0.5,15/18,-0.5]
->            ,[15/18,-0.75,-0.5,0.0]]
->           ,[[0.0,-0.75,-1/6,0.0]
->            ,[1.0,0.5,0.5,0.0]
->            ,[-0.5,0.0,-0.5,0.0]
->            ,[-0.5,-1/6,0.0,0.5]
->            ,[-0.25,1/6,-0.75,0.25]
->            ,[-7/6,-4/3,-1/6,1.5]]]
->     ; y = [[[0.0,-0.5,1.0,0.0]
->            ,[-0.5,1.0,0.5,-0.5]
->            ,[0.0,1/3,1.0,1.0]]
->           ,[[-0.5,0.5,1.0,1.0]
->            ,[0.0,1/3,0.0,1.5]
->            ,[-0.5,15/18,1.0,0.0]]
->           ,[[0.25,-2/3,0.25,0.0]
->            ,[0.5,-0.5,-0.5,-0.5]
->            ,[0.5,-0.5,-0.75,15/18]]
->           ,[[-0.25,1.0,0.0,1/3]
->            ,[-1.25,-0.25,0.5,0.0]
->            ,[0.0,-1.25,-0.25,-0.5]]
->           ,[[0.75,-0.25,1.5,0.0]
->            ,[0.25,-1.5,0.5,0.5]
->            ,[-0.5,-0.5,-0.5,-0.25]]
->           ,[[0.0,0.5,-0.5,0.25]
->            ,[0.25,0.5,-1/3,0.0]
->            ,[1.0,0.5,-1/6,0.5]]]
->     ; cs = map (map (\[f,p,m,a] -> sinOsc AR f p * m + a)) x
->     ; ms = map (map (\[f,w,m,a] -> pulse AR f w * m + a)) y
->     ; [c1,c2,c3,_,c4,c5] = mceChannels (fm7 cs ms)
->     ; g3 = linLin (lfSaw KR 0.1 0) (-1) 1 0 (dbAmp (-12))
->     ; g5 = dbAmp (-3) }
-> in audition (out 0 (mce [c1 + c3 * g3 + c5 * g5,c2 + c4 + c5 * g5]))
diff --git a/Help/UGen/External/fmGrain.help.lhs b/Help/UGen/External/fmGrain.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/fmGrain.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FMGrain"
-> Sound.SC3.UGen.DB.ugenSummary "FMGrain"
-
-> import Sound.SC3.ID
-
-> let {t = impulse AR 20 0
->     ;n = linLin (lfNoise1 'α' KR 1) (-1) 1 1 10
->     ;s = envSine 9 0.1
->     ;e = envGen KR 1 1 0 1 RemoveSynth s
->     ;o = fmGrain t 0.2 440 220 n * e}
-> in audition (out 0 o)
diff --git a/Help/UGen/External/fmGrainB.help.lhs b/Help/UGen/External/fmGrainB.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/fmGrainB.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FMGrainB"
-> Sound.SC3.UGen.DB.ugenSummary "FMGrainB"
-
-> import Sound.SC3.ID
-
-> withSC3 (do {_ <- async (b_alloc 10 512 1)
->             ;let f = [Normalise,Wavetable,Clear]
->              in send (b_gen_sine2 10 f [(0.5,0.1)])})
-
-> let {t = impulse AR 20 0
->     ;n = linLin (lfNoise1 'a' KR 1) (-1) 1 1 10
->     ;s = envSine 9 0.1
->     ;e = envGen KR 1 1 0 1 RemoveSynth s
->     ;o = fmGrainB t 0.2 440 220 n 10 * e}
-> in audition (out 0 o)
diff --git a/Help/UGen/External/lfBrownNoise.help.lhs b/Help/UGen/External/lfBrownNoise.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/lfBrownNoise.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFBrownNoise2"
-> Sound.SC3.UGen.DB.ugenSummary "LFBrownNoise2"
-
-> import Sound.SC3.ID
-
-Modulate frequency.
-> let {x = mouseX KR 0 5 Linear 0.2
->     ;n = lfBrownNoise2 'α' AR 1000 1 x}
-> in audition (out 0 (n * 0.25))
-
-Use as frequency control.
-> let f = lfBrownNoise2 'α' KR 8 0.2 0 * 400 + 450
-> in audition (out 0 (sinOsc AR f 0 * 0.2))
diff --git a/Help/UGen/External/lpcSynth.help.lhs b/Help/UGen/External/lpcSynth.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/lpcSynth.help.lhs
+++ /dev/null
@@ -1,31 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LPCSynth"
-> Sound.SC3.UGen.DB.ugenSummary "LPCSynth"
-
-> import Sound.SC3.ID
-
-> let load_data b i d =
->         if length d < 512
->         then send (b_setn1 b i d)
->         else do {send (b_setn1 b i (take 512 d))
->                 ;load_data b (i + 512) (drop 512 d)}
-
-> :t load_data
-
-> let lpc_instr b n lpc =
->         let {x = mouseX KR 0.05 1.5 Linear 0.2
->             ;y = mouseY KR 0.25 2.0 Linear 0.2
->             ;f = x / constant (lpcAnalysisDuration (lpcHeader lpc))
->             ;ptr = lfSaw AR f 1 * 0.5 + 0.5
->             ;[cps, rms, err] = mceChannels (lpcVals AR b ptr)
->             ;nh = floorE (22000 / cps)
->             ;voc = blip AR (cps * y) nh * (1 - err)
->             ;s = lpcSynth b (voc + (n * err * 20)) ptr}
->         in s * 1e-5 * rms
-
-> do {lpc <- lpcRead "/home/rohan/cvs/tn/tn-56/lpc/fate.lpc"
->    ;let {n = pinkNoise 'a' AR
->         ;d = map realToFrac (lpcSC3 lpc)
->         ;s = lpc_instr 10 n lpc}
->     in withSC3 (do {_ <- async (b_alloc 10 (length d) 1)
->                    ;load_data 10 0 d
->                    ;play (out 0 s)})}
diff --git a/Help/UGen/External/lpcVals.help.lhs b/Help/UGen/External/lpcVals.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/lpcVals.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See lpcSynth
diff --git a/Help/UGen/External/lti.help.lhs b/Help/UGen/External/lti.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/lti.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LTI"
-> Sound.SC3.UGen.DB.ugenSummary "LTI"
-
-> import Sound.SC3.ID
-
-> let {a = [0.02,-0.01]
->     ;b = [1,0.7,0,0,0,0,-0.8,0,0,0,0,0.9,0,0,0,-0.5,0,0,0,0,0,0,0.25,0.1,0.25]
->     ;z = pinkNoise 'a' AR * 0.1 {- soundIn 4 -}
->     ;f = lti AR z (asLocalBuf 'a' a) (asLocalBuf 'b' b)}
-> in audition (out 0 f)
diff --git a/Help/UGen/External/membraneCircle.help.lhs b/Help/UGen/External/membraneCircle.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/membraneCircle.help.lhs
+++ /dev/null
@@ -1,19 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MembraneCircle"
-> Sound.SC3.UGen.DB.ugenSummary "MembraneCircle"
-
-> import Sound.SC3.ID
-
-Excite the mesh with some pink noise, triggered by an
-impulse generator.  mouseX is tension and impulse frequency,
-mouseY is duration of excitation, release-time and amplitude.
-> let {x = mouseX KR 0 1 Linear 0.2
->     ;y = mouseY KR 1e-9 1 Exponential 0.2
->     ;loss = linLin y 0 1 0.999999 0.999
->     ;wobble = sinOsc KR 2 0
->     ;tension = linLin x 0 1 0.01 0.1 + (wobble * 0.0001)
->     ;p = envPerc 0.0001 y
->     ;tr = impulse KR (linLin x 0 1 3 9) 0
->     ;e = envGen KR tr (linLin y 0 1 0.05 0.25) 0 0.1 DoNothing p
->     ;m = membraneCircle
->     ;n = pinkNoise 'α' AR}
-> in audition (out (mce2 0 1) (m (n * e) tension loss))
diff --git a/Help/UGen/External/membraneHexagon.help.lhs b/Help/UGen/External/membraneHexagon.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/membraneHexagon.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See membraneCircle
diff --git a/Help/UGen/External/metro.help.lhs b/Help/UGen/External/metro.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/metro.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Metro"
-> Sound.SC3.UGen.DB.ugenSummary "Metro"
-
-> import Sound.SC3.ID
-
-> audition (out 0 (metro AR 60 1))
-
-> let {b = xLine KR 60 120 5 DoNothing
->     ;m = metro KR b 1
->     ;o = sinOsc AR 440 0 * 0.1}
-> in audition (out 0 (decay m 0.2 * o))
-
-> let {b = range 30 240 (lfNoise2 'α' KR 0.2)
->     ;n = dseq 'β' dinf (mce [1,0.25,0.5,0.25])
->     ;a = decay (metro KR b n) 0.2 * sinOsc AR 440 0 * 0.1}
-> in audition (out 0 a)
diff --git a/Help/UGen/External/mzPokey.help.lhs b/Help/UGen/External/mzPokey.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/mzPokey.help.lhs
+++ /dev/null
@@ -1,31 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MZPokey"
-> Sound.SC3.UGen.DB.ugenSummary "MZPokey"
-
-> import Sound.SC3
-> import qualified Sound.SC3.Lang.Math as M
-
-> let b = fromIntegral . M.parseBits :: (String -> UGen)
-> let bln = line KR 0 255 5 RemoveSynth
-> let mz1 i j = mzPokey i j 0 0 0 0 0 0 0
-> let mz1c i j c = mzPokey i j 0 0 0 0 0 0 c
-
-> audition (out 0 (mz1 bln (b "00001111")))
-> audition (out 0 (mz1 bln (b "00101111")))
-> audition (out 0 (mz1 bln (b "10101111")))
-> audition (out 0 (mz1c bln (b "10101111") (b "00000001")))
-> audition (out 0 (mz1c bln (b "10101111") (b "01000001")))
-
-> let mz2c i j p q c = mzPokey i j p q 0 0 0 0 c
-> let bX = mouseX KR 0 255 Linear 0.1
-> let bY = mouseY KR 0 255 Linear 0.1
-
-> audition (out 0 (mz2c bX (b "10101010") bY (b "10101010") (b "00000001")))
-
-> let mz4pc (f1,c1) (f2,c2) (f3,c3) (f4,c4) c = mzPokey f1 c1 f2 c2 f3 c3 f4 c4 c
-
-> let { v1 = (bX,b "11000111")
->     ; v2 = (bY,b "11100111")
->     ; v3 = (sinOsc KR 0.4 0 * 127.5 + 127.5,b "11000111")
->     ; v4 = (sinOsc KR 0.5 0 * 127.5 + 127.5,b "01000111")
->     ; m = mz4pc v1 v2 v3 v4 (b "00000000") }
-> in audition (out 0 (mce2 m m))
diff --git a/Help/UGen/External/playBufCF.help.lhs b/Help/UGen/External/playBufCF.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/playBufCF.help.lhs
+++ /dev/null
@@ -1,33 +0,0 @@
-wslib: external/composite
-
-> import Sound.SC3.ID
-
-Load sound file to buffer zero (single channel file required for examples)
-
-> let {fn' = "/home/rohan/data/audio/pf-c5.aif"
->     ;fn = "/home/rohan/opt/share/SuperCollider/sounds/a11wlk01.wav"}
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-control-rate trigger and start-position inputs
-
-> let {b = 0
->     ;r = bufRateScale KR b
->     ;tr = impulse KR 2 0
->     ;wn = whiteNoise 'α' KR
->     ;sp = linLin wn (-1) 1 0 (bufFrames KR b - (0.5 * 44100))
->     ;o = playBufCF 1 b r tr sp NoLoop 0.1 2
->     ;o' = playBuf 1 AR b r tr sp NoLoop DoNothing}
-> in audition (out 0 (mce2 o o'))
-
-demand ugens inputs
-
-> let {b = 0
->     ;r = drand 'α' dinf (mce [0.95,1,1.05])
->     ;tr = dwhite 'β' dinf 0.1 0.3
->     ;sp = dbrown 'γ' dinf 0 0.95 0.1 * bufFrames KR b
->     ;o = playBufCF 1 b r tr sp NoLoop 2 5}
-> in audition (out 0 o)
-
-for drawings...
-
-> import Sound.SC3.UGen.Dot {- hsc3-dot -}
diff --git a/Help/UGen/External/pv_BufRd.help.lhs b/Help/UGen/External/pv_BufRd.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/pv_BufRd.help.lhs
+++ /dev/null
@@ -1,32 +0,0 @@
-> import Sound.SC3
-
-allocate anazlysis buffer and load soundfile
-
-> let {p = "/home/rohan/opt/share/SuperCollider/sounds/a11wlk01.wav"
->     ;f = 1024 {- frame size -}
->     ;h = 0.25 {- hop size -}
->     ;p_dur = 4.2832879818594 {- duration (in seconds) of p -}
->     ;b_size = pv_calcPVRecSize p_dur f h 48000}
-> in withSC3 (do {_ <- async (b_alloc 0 b_size 1)
->                ;async (b_allocRead 1 p 0 0)})
-
-do the analysis and store to buffer.  the window type and overlaps are
-important for resynthesis parameters
-
-> let {rec_buf = 0
->     ;au_buf = 1
->     ;l_buf = localBuf 'α' 1024 1;
->     ;rt = bufRateScale KR au_buf
->     ;i = playBuf 1 AR au_buf rt 1 0 NoLoop RemoveSynth
->     ;c0 = fft l_buf i 0.25 1 1 0
->     ;c1 = pv_RecordBuf c0 rec_buf 0 1 0 0.25 1}
-> in audition (mrg2 (out 0 (dc AR 0)) c1)
-
-play analysis back
-
-> let {rec_buf = 0
->     ;l_buf = localBuf 'α' 1024 1
->     ;x = mouseX KR 0 1 Linear 0.2
->     ;c0 = pv_BufRd l_buf rec_buf x
->     ;s = ifft c0 1 0}
-> in audition (out 0 s)
diff --git a/Help/UGen/External/pv_Invert.help.lhs b/Help/UGen/External/pv_Invert.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/pv_Invert.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_Invert"
-> Sound.SC3.UGen.DB.ugenSummary "PV_Invert"
-
-> import Sound.SC3.ID
-
-> let {s = sinOsc AR 440 0 * 0.4
->     ;n = pinkNoise 'α' AR * 0.1
->     ;i = s + n
->     ;c0 = fft' 10 i
->     ;c1 = pv_Invert c0
->     ;run = do {_ <- async (b_alloc 10 2048 1)
->               ;play (out 0 (mce2 i (ifft' c1) * 0.5))}}
-> in withSC3 run
diff --git a/Help/UGen/External/qitch.help.lhs b/Help/UGen/External/qitch.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/qitch.help.lhs
+++ /dev/null
@@ -1,21 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Qitch"
-> Sound.SC3.UGen.DB.ugenSummary "Qitch"
-
-> import Sound.SC3.ID
-> import System.FilePath
-
-Load required data file (edit path as required)
-> let {d = "/home/rohan/opt/share/SuperCollider/Extensions/SC3plugins"
->     ;qf = d </> "PitchDetection/extraqitchfiles/QspeckernN2048SR48000.wav"}
-> in withSC3 (async (b_allocRead 10 qf 0 0))
-
-Comparison of input frequency (x) and tracked oscillator frequency (f).
-Output is printed to the console by scsynth.
-> let {x = mouseX KR 440 880 Exponential 0.1
->     ;o = sinOsc AR x 0 * 0.1
->     ;[f,e] = mceChannels (qitch KR o 10 1e-2 1 0 0 2500)
->     ;r = sinOsc AR f 0 * 0.1
->     ;t = impulse KR 4 0
->     ;pf = poll t f (label "f") 0
->     ;px = poll t x (label "x") 0}
-> in audition (mrg [out 0 (mce2 o r),pf,px])
diff --git a/Help/UGen/External/sms.help.lhs b/Help/UGen/External/sms.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/sms.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SMS"
-> Sound.SC3.UGen.DB.ugenSummary "SMS"
-
-> import Sound.SC3
-
-sine reconstruction left channel, noises on right
-> let {z= soundIn 4
->     ;y = mouseY KR 1 50 Linear 0.2
->     ;x = mouseX KR 0.5 4 Linear 0.2
->     ;o = sms z 50 y 8 0.3 x 0 0 0 1 (-1)}
-> in audition (out 0 o)
diff --git a/Help/UGen/External/squiz.help.lhs b/Help/UGen/External/squiz.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/squiz.help.lhs
+++ /dev/null
@@ -1,27 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Squiz"
-> Sound.SC3.UGen.DB.ugenSummary "Squiz"
-
-> import Sound.SC3
-
-Squiz of sin oscillator
-
-> let {o = sinOsc AR 440 0
->     ;x = mouseX KR 1 10 Exponential 0.2
->     ;y = mouseY KR 1 10 Linear 0.2
->     ;s = squiz o x y 0.1 * 0.1}
-> in audition (out 0 s)
-
-Load sound file to buffer zero
-
-> let {fn' = "/home/rohan/data/audio/pf-c5.aif"
->     ;fn = "/home/rohan/opt/share/SuperCollider/sounds/a11wlk01.wav"}
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-Squiz of audio file.
-
-> let {r = bufRateScale KR 0
->     ;p = playBuf 1 AR 0 (r * 0.5) 1 0 Loop DoNothing
->     ;x = mouseX KR 1 100 Exponential 0.2
->     ;y = mouseY KR 1 10 Linear 0.2
->     ;o = squiz p x y 0.1 * 0.5}
-> in audition (out 0 o)
diff --git a/Help/UGen/External/stkBowed.help.lhs b/Help/UGen/External/stkBowed.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/stkBowed.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "StkBowed"
-> Sound.SC3.UGen.DB.ugenSummary "StkBowed"
-
-> import Sound.SC3
-
-no longer working...
-> let g = toggleFF (impulse KR 1 0)
-> in audition (out 0 (stkBowed AR 220 64 64 64 64 64 g 1 1))
diff --git a/Help/UGen/External/stkFlute.help.lhs b/Help/UGen/External/stkFlute.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/stkFlute.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "StkFlute"
-> Sound.SC3.UGen.DB.ugenSummary "StkFlute"
-
-> import Sound.SC3
-
-> let { bp = line KR 76 32 3 RemoveSynth
->     ; ng = line KR 16 64 3 DoNothing }
-> in audition (out 0 (stkFlute AR 400 64 ng 16 16 bp 1))
diff --git a/Help/UGen/External/stkMandolin.help.lhs b/Help/UGen/External/stkMandolin.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/stkMandolin.help.lhs
+++ /dev/null
@@ -1,24 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "StkMandolin"
-> Sound.SC3.UGen.DB.ugenSummary "StkMandolin"
-
-> import Control.Monad
-> import Sound.SC3.ID
-> import qualified Sound.SC3.Monad as M
-
-requires "../../rawwaves/mand1.raw"
-> let {x = mouseX KR 0.25 4 Linear 0.2
->     ;tr = impulse KR x 0 - 0.5 }
-> in do {mn <- M.tRand 54 66 tr
->       ;[bs, pp, dm, dt, at] <- replicateM 5 (M.tRand 0 127 tr)
->       ;audition (out 0 (stkMandolin AR (midiCPS mn) bs pp dm dt at tr))}
-
-> let {x = mouseX KR 3 16 Linear 0.2
->     ;t = impulse KR x 0 - 0.5
->     ;tr = pulseDivider t 6 0 }
-> in do {mn <- M.tIRand 54 66 t
->       ;bs <- M.tRand 72 94 tr
->       ;pp <- M.tRand 32 42 tr
->       ;dm <- M.tRand 64 72 tr
->       ;dt <- M.tRand 0 4 tr
->       ;at <- M.tRand 2 8 tr
->       ;audition (out 0 (stkMandolin AR (midiCPS mn) bs pp dm dt at t))}
diff --git a/Help/UGen/External/stkModalBar.help.lhs b/Help/UGen/External/stkModalBar.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/stkModalBar.help.lhs
+++ /dev/null
@@ -1,29 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "StkModalBar"
-> Sound.SC3.UGen.DB.ugenSummary "StkModalBar"
-
-> import Control.Monad
-> import Sound.SC3.ID
-> import qualified Sound.SC3.Monadic as M
-
-requires "../../rawwaves/marmstk1.raw"
-> let {x = mouseX KR 0.25 4 Linear 0.2
->     ;tr = impulse KR x 0 - 0.5
->     ;tR = M.tRand 0 127 tr}
-> in do {i <- M.tRand 0 9 tr
->       ;mn <- M.tIRand 25 96 tr
->       ;[sh,sp,vg,vf,mx,v] <- replicateM 6 tR
->       ;let s = stkModalBar AR (midiCPS mn) i sh sp vg vf mx v tr
->        in audition (out 0 s)}
-
-> let {x = mouseX KR 1 6 Linear 0.2
->     ;t = impulse KR x 0 - 0.5
->     ;tr = pulseDivider t 6 0}
-> in do {mn <- M.tIRand 52 64 t
->       ;sh <- M.tRand 4 8 tr
->       ;sp <- M.tRand 54 68 tr
->       ;vg <- M.tRand 66 98 tr
->       ;vf <- M.tRand 4 12 tr
->       ;mx <- M.tRand 0 1 tr
->       ;v <- M.tRand 16 48 tr
->       ;let s = stkModalBar AR (midiCPS mn) 1 sh sp vg vf mx v t
->        in audition (out 0 s)}
diff --git a/Help/UGen/External/stkShakers.help.lhs b/Help/UGen/External/stkShakers.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/stkShakers.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "StkShakers"
-> Sound.SC3.UGen.DB.ugenSummary "StkShakers"
-
-> import Control.Monad
-> import Sound.SC3.ID
-> import qualified Sound.SC3.Monadic as M
-
-> let {x = mouseX KR 0.25 4 Linear 0.2
->     ;tr = impulse KR x 0 - 0.5}
-> in do {i <- M.tRand 0 23 tr
->       ;[e,sd,no,rf] <- replicateM 4 (M.tRand 0 127 tr)
->       ;audition (out 0 (stkShakers AR i e sd no rf tr))}
-
-> let tr = impulse KR 1 0 - 0.5
-> in audition (out 0 (stkShakers AR 4 64 64 64 64 tr))
diff --git a/Help/UGen/External/streson.help.lhs b/Help/UGen/External/streson.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/streson.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Streson"
-> Sound.SC3.UGen.DB.ugenSummary "Streson"
-
-> import Sound.SC3
-
-> let {dt = recip (linExp (lfCub KR 0.1 (0.5 * pi)) (-1) 1 280 377)
->     ;s = streson (lfSaw AR (mce2 220 180) 0 * 0.2) dt 0.9 * 0.3}
-> in audition (out 0 s)
diff --git a/Help/UGen/External/switchDelay.help.lhs b/Help/UGen/External/switchDelay.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/switchDelay.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SwitchDelay"
-> Sound.SC3.UGen.DB.ugenSummary "SwitchDelay"
-
-> import Sound.SC3
-
-simple feedback delay
-> audition (out 0 (switchDelay (soundIn 4) 1 1 1 0.99 20))
-
-change the buffer read pointer periodically.
-> let {ix = stepper (impulse KR 0.5 0) 0 0 3 1 0
->     ;dt = select ix (mce [0.02,0.1,0.725,0.25])
->     ;sd = switchDelay (soundIn 4) 1 1 dt 0.99 20}
-> in audition (out 0 sd)
diff --git a/Help/UGen/External/tBetaRand.help.lhs b/Help/UGen/External/tBetaRand.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/tBetaRand.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TBetaRand"
-> Sound.SC3.UGen.DB.ugenSummary "TBetaRand"
-
-> import Sound.SC3.ID
-
-> let {t = dust 'α' KR 10
->     ;f = tBetaRand 'β' 300 3000 0.1 0.1 t
->     ;o = sinOsc AR f 0 * 0.1}
-> in audition (out 0 o)
-
-mouse control of parameters
-> let {t = dust 'α' KR 10
->     ;p1 = mouseX KR 1 5 Linear 0.2
->     ;p2 = mouseY KR 1 5 Linear 0.2
->     ;f = tBetaRand 'β' 300 3000 p1 p2 t
->     ;o = sinOsc AR f 0 * 0.1}
-> in audition (out 0 o)
diff --git a/Help/UGen/External/tBrownRand.help.lhs b/Help/UGen/External/tBrownRand.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/tBrownRand.help.lhs
+++ /dev/null
@@ -1,18 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TBrownRand"
-> Sound.SC3.UGen.DB.ugenSummary "TBrownRand"
-
-> import Sound.SC3.ID
-
-> let {t = dust 'α' KR 10
->     ;dist = mouseX KR 0 5 Linear 0.2
->     ;f = tBrownRand 'β' 300 3000 1 dist t
->     ;o = sinOsc AR f 0 * 0.1}
-> in audition (out 0 o)
-
-> let {t = dust 'α' KR 10
->     ;n = tBrownRand 'β' 0 1 0.2 0 t
->     ;f = linExp n 0 1 300 3000
->     ;o = sinOsc AR f 0
->     ;l = tBrownRand 'γ' (-1) 1 1 4 t
->     ;p = pan2 o l 0.1}
-> in audition (out 0 p)
diff --git a/Help/UGen/External/tGaussRand.help.lhs b/Help/UGen/External/tGaussRand.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/tGaussRand.help.lhs
+++ /dev/null
@@ -1,19 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TGaussRand"
-> Sound.SC3.UGen.DB.ugenSummary "TGaussRand"
-
-> import Sound.SC3.ID
-
-> let {t = dust 'α' KR 10
->     ;f = tGaussRand 'β' 300 3000 t
->     ;o = sinOsc AR f 0
->     ;l = tGaussRand 'γ' (-1) 1 t
->     ;p = pan2 o l 0.1}
-> in audition (out 0 p)
-
-compare to tRand
-> let {t = dust 'α' KR 10
->     ;f = tRand 'β' 300 3000 t
->     ;o = sinOsc AR f 0
->     ;l = tRand 'γ' (-1) 1 t
->     ;p = pan2 o l 0.1}
-> in audition (out 0 p)
diff --git a/Help/UGen/External/tartini.help.lhs b/Help/UGen/External/tartini.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/tartini.help.lhs
+++ /dev/null
@@ -1,19 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Tartini"
-> Sound.SC3.UGen.DB.ugenSummary "Tartini"
-
-> import Sound.SC3.ID
-
-Comparison of input frequency (x) and tracked oscillator frequency (f).
-> let {x = mouseX KR 440 880 Exponential 0.1
->     ;o = lfSaw AR x 0 * 0.05 {- sinOsc AR x 0 * 0.1 -}
->     ;[f,e] = mceChannels (tartini KR o 0.2 2048 0 1024 0.5)
->     ;r = sinOsc AR f 0 * 0.1
->     ;t = impulse KR 4 0
->     ;pf = poll t f (label "f") 0
->     ;px = poll t x (label "x") 0}
-> in audition (mrg [out 0 (mce2 o r),pf,px])
-
-Fast test of live pitch tracking, not careful with amplitude of input
-> let {z = soundIn 4
->     ;[f,e] = mceChannels (tartini KR z 0.2 2048 0 1024 0.5)}
-> in audition (out 0 (saw AR f * 0.05 * e))
diff --git a/Help/UGen/External/tpv.help.lhs b/Help/UGen/External/tpv.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/tpv.help.lhs
+++ /dev/null
@@ -1,25 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TPV"
-> Sound.SC3.UGen.DB.ugenSummary "TPV"
-
-> import Sound.SC3
-
-> let fft_sz = 2048::Int
-> let hop_sz = fft_sz `div` 2
-> let fn = "/home/rohan/data/audio/pf-c5.snd"
-> let fn = "/home/rohan/data/audio/material/tyndall/var/talking-fragments/0001.WAV"
-> let tpv' b i = tpv (fft b i 0.5 1 1 0) (constant fft_sz) (constant hop_sz)
-
-> withSC3 (do {_ <- async (b_alloc 0 fft_sz 1)
->             ;async (b_allocRead 1 fn 0 0)})
-
-> let {i = playBuf 1 AR 1 (bufRateScale KR 1) 1 0 Loop DoNothing
->     ;x = mouseX KR 1 70 Linear 0.1
->     ;y = mouseY KR 0.25 3 Linear 0.1
->     ;o = tpv' 0 i 70 x y 4 0.2}
-> in audition (out 0 (mce2 (i * 0.1) o))
-
-> let {i = playBuf 1 AR 1 (bufRateScale KR 1) 1 0 Loop DoNothing
->     ;x = mouseX KR 0.1 100 Linear 0.1
->     ;y = mouseY KR (-20) 40 Linear 0.1
->     ;o = tpv' 0 i 50 50 1 x (dbAmp y)}
-> in audition (out 0 (pan2 o 0 1))
diff --git a/Help/UGen/External/vosim.help.lhs b/Help/UGen/External/vosim.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/vosim.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "VOSIM"
-> Sound.SC3.UGen.DB.ugenSummary "VOSIM"
-
-> import Sound.SC3.ID
-
-> let {p = tRand 'α' 0 1 (impulse AR 6 0)
->     ;t = impulse AR (9 * ( 1 + ( p >* 0.95))) 0
->     ;x = mouseX KR 0.25 2 Linear 0.2
->     ;y = mouseY KR 0.25 0.75 Linear 0.2
->     ;z = 9
->     ;rng i = linLin i (-1) 1
->     ;mk_n e = rng (lfNoise2 e KR z) 0.25 2
->     ;tR e ll rl = tRand e (mce ll) (mce rl)
->     ;f = tR 'β' [40,120,220] [440,990,880] t
->     ;n = tR 'γ' [4] [8,16,32] t
->     ;d = tR 'δ' [0.2,0.4,0.6] [0.6,0.8,1] t
->     ;a = tR 'ε' [0] [0.05,0.15,0.25] t
->     ;l = tR 'ζ' [-1] [1] t
->     ;xn = mk_n 'η'
->     ;yn = mk_n 'θ'
->     ;v = vosim t (f * x * xn) n (d * y * yn) * a}
-> in audition (out 0 (pan2 (mix v) l 1))
diff --git a/Help/UGen/External/waveTerrain.help.lhs b/Help/UGen/External/waveTerrain.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/waveTerrain.help.lhs
+++ /dev/null
@@ -1,74 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "WaveTerrain"
-> Sound.SC3.UGen.DB.ugenSummary "WaveTerrain"
-
-> import Sound.SC3.ID {- hsc3 -}
-> import Sound.SC3.Plot {- hsc3-plot -}
-
-Terrain function
-
-> let z (x,y) = let {a = x ** 2
->                   ;b = abs (sin (10 * y)) ** (1/3)}
-> in 2 * (a + b) - 1
-
-Create terrain given function.
-
-> let t z = let {w = 100 {- width -}
->               ;h = 50 {- height -}
->               ;tk n = take (round n)
->               ;xs = tk w [0,1/w ..]
->               ;ys = tk h [0,1/h ..]
->               ;ix = map (\y -> map (\x -> (x,y)) xs) ys
->               ;add_z = map (\(x,y) -> (x,y,z (x,y)))}
->           in concatMap add_z ix
-
-Confirm terrain
-
-> plot_p3_pt [t z]
-
-Create table.
-
-> let t' = map (\(_,_,z) -> z) (t z)
-
-Confirm table
-
-> plotTable [t']
-
-Send table to scsynth
-
-> withSC3 (async (b_alloc_setn1 0 0 t'))
-
-Hear terrain
-
-> let {x' = mouseX KR 1 200 Exponential 0.2
->     ;y' = mouseY KR 1 300 Exponential 0.2
->     ;x = abs (sinOsc AR x' 0) + lfNoise2 'α' AR 2
->     ;y = abs (sinOsc AR y' (pi / 2))
->     ;b = 0
->     ;o = waveTerrain AR b x y 100 50}
-> in audition (out 0 o)
-
-Alternate terrain function.
-
-> let z (x,y) = let {a = (cos(5 * x + 1.7)) ** 3
->                   ;b = abs (sin (23 * y)) ** (1/3)}
->               in (a - b)
-
-Free buffer
-
-> withSC3 (async (b_free 0))
-
-Gerate mesh given terrain given function.
-
-> let t z = let {w = 100 {- width -}
->               ;h = 50 {- height -}
->               ;tk n = take (round n)
->               ;xs = tk w [0,1/w ..]
->               ;ys = tk h [0,1/h ..]
->               ;ix0 = map (\y -> map (\x -> (x,y)) xs) ys
->               ;ix1 = map (\x -> map (\y -> (x,y)) ys) xs
->               ;add_z = map (\(x,y) -> (x,y,z (x,y)))}
->           in (map add_z ix0,map add_z ix1)
-
-Confirm terrain mesh
-
-> plot_p3_ln ((\(p,q) -> p ++ q) (t z))
diff --git a/Help/UGen/External/zitaRev1.help.lhs b/Help/UGen/External/zitaRev1.help.lhs
deleted file mode 100644
--- a/Help/UGen/External/zitaRev1.help.lhs
+++ /dev/null
@@ -1,34 +0,0 @@
-faust2supercollider zita_rev1.dsp
-http://kokkinizita.linuxaudio.org/linuxaudio/zita-rev1-doc/quickguide.html
-
-delay, lin,   0.02,    0.1,     0.04
-xover, log,  50.0,  1000.0,   200.0
-rtlow, log,   1.0,     8.0,     3.0
-rtmid, log,   1.0,     8.0,     2.0
-fdamp, log,   1.5e3,  24.0e3,   6.0e3
-eq1fr, log,  40.0,     2.5e3, 160.0
-eq1gn, lin, -15.0,    15.0,     0.0
-eq2fr, log, 160.0,    10.0e3,   2.5e3
-eq2gn, lin, -15.0,    15.0,     0.0
-opmix, lin,   0.0,     1.0,     0.5
-level, lin,  -9.0,     9.0,   -20.0
-
-> import Sound.SC3
-
-default settings
-> let {i = soundIn 4
->     ;o = zitaRev1 i i 0.04 200 3 2 6000 160 0 2500 0 0.5 (-6)}
-> in audition (out 0 o)
-
-longer
-> let {i = soundIn 4
->     ;o = zitaRev1 i i 0.08 200 6 4 6000 190 (-6) 3500 6 0.5 0}
-> in audition (out 0 o)
-
-longer still
-> let {i = soundIn 4
->     ;o = zitaRev1 i i 0.1 200 6 8 6000 190 (-6) 3500 6 0.5 0}
-> in audition (out 0 o)
-
-hsc3-db
-> Sound.SC3.UGen.DB.u_summary zitaRev1_dsc
diff --git a/Help/UGen/FFT/convolution.help.lhs b/Help/UGen/FFT/convolution.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/convolution.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Convolution"
-> Sound.SC3.UGen.DB.ugenSummary "Convolution"
-
-> import Sound.SC3.ID
-
-> let {k = whiteNoise 'a' AR
->     ;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
deleted file mode 100644
--- a/Help/UGen/FFT/fft.help.lhs
+++ /dev/null
@@ -1,21 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FFT"
-> Sound.SC3.UGen.DB.ugenSummary "FFT"
-> :t fft'
-
-> import Sound.SC3.ID
-
-Non-local buffer
-
-> withSC3 (async (b_alloc 10 2048 1))
-
-Variants with default values
-
-> let n = whiteNoise 'α' AR
-> in audition (out 0 (ifft' (fft' 10 (n * 0.05))))
-
-Local buffer allocating fft variant
-
-> 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 (ffta 'α' 2048 s2 0.5 0 1 0) 0 0 * 0.25))
diff --git a/Help/UGen/FFT/fftTrigger.help.lhs b/Help/UGen/FFT/fftTrigger.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/fftTrigger.help.lhs
+++ /dev/null
@@ -1,2 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FFTTrigger"
-> Sound.SC3.UGen.DB.ugenSummary "FFTTrigger"
diff --git a/Help/UGen/FFT/ifft.help.lhs b/Help/UGen/FFT/ifft.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/ifft.help.lhs
+++ /dev/null
@@ -1,5 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "IFFT"
-> Sound.SC3.UGen.DB.ugenSummary "IFFT"
-> :t ifft'
-
-# ifft' is a variant with the default window type and size
diff --git a/Help/UGen/FFT/packFFT.help.lhs b/Help/UGen/FFT/packFFT.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/packFFT.help.lhs
+++ /dev/null
@@ -1,23 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PackFFT"
-> Sound.SC3.UGen.DB.ugenSummary "PackFFT"
-
-> import Sound.SC3.ID
-> import Sound.SC3.UGen.Protect
-
-> withSC3 (async (b_alloc 10 512 1))
-
-> let {n = 100
->     ;square a = a * a
->     ;r1 = let f = expRand 'α' 0.1 1
->           in linLin (fSinOsc KR f 0) (-1) 1 0 1
->     ;m1 = uclone' 'β' n r1
->     ;m2 = zipWith (*) m1 (map square [1.0, 0.99 ..])
->     ;r2 = let r = iRand 'γ' (-3) 5
->           in lfPulse KR (2 ** r) 0 0.3
->     ;i = uclone' 'δ' n r2
->     ;m3 = zipWith (*) m2 i
->     ;p = replicate n 0.0
->     ;c1 = fft' 10 (fSinOsc AR 440 0)
->     ;c2 = packFFT c1 512 0 (constant n - 1) 1 (packFFTSpec m3 p)
->     ;s = ifft' c2}
-> in audition (out 0 (mce [s,s]))
diff --git a/Help/UGen/FFT/partConv.help.lhs b/Help/UGen/FFT/partConv.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/partConv.help.lhs
+++ /dev/null
@@ -1,23 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PartConv"
-> Sound.SC3.UGen.DB.ugenSummary "PartConv"
-
-> import Sound.SC3.ID
-
-> let { fft_size = 2048
->     ; ir_file = "/home/rohan/data/audio/reverbs/chapel.wav"
->     ; ir_length = 62494 {- frame count of ir_file -}
->     ; accum_size = pc_calcAccumSize fft_size ir_length
->     ; ir_td_b = 10 {- time domain -}
->     ; ir_fd_b = 11 {- frequency domain -}
->     ; target_b = 12 {- source signal -}
->     ; target_file = "/home/rohan/data/audio/pf-c5.snd"
->     ; c = constant
->     ; g = let { i = playBuf 1 AR (c target_b) 1 0 0 Loop DoNothing
->               ; pc = partConv i (c fft_size) (c ir_fd_b) }
->           in out 0 (pc * 0.1) }
-> in withSC3 (do
->     {_ <- async (b_allocRead ir_td_b ir_file 0 ir_length)
->     ;_ <- async (b_alloc ir_fd_b accum_size 1)
->     ;send (pc_preparePartConv ir_fd_b ir_td_b fft_size)
->     ;_ <- async (b_allocRead target_b target_file 0 0)
->     ;play g })
diff --git a/Help/UGen/FFT/pv_BinDelay.help.lhs b/Help/UGen/FFT/pv_BinDelay.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/pv_BinDelay.help.lhs
+++ /dev/null
@@ -1,57 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_BinDelay"
-> Sound.SC3.UGen.DB.ugenSummary "PV_BinDelay"
-
-> import Sound.SC3
-
-function to allocate buffers (fft,delay,feedback)
-
-> let mk_b sz = withSC3 (do {_ <- async (b_alloc 10 (sz * 2) 1)
->                           ;_ <- async (b_alloc 11 sz 1)
->                           ;async (b_alloc 12 sz 1)})
-
-allocate buffers (number of bins)
-
-> mk_b 128
-
-function to generate bindelay filter
-
-> let mk_u z = let {maxdel = 0.5
->                  ;c1 = fft 10 z 0.25 0 1 0
->                  ;c2 = pv_BinDelay c1 maxdel 11 12 0.25}
->              in z + ifft c2 0 0
-
-start filter
-
-> audition (out 0 (mk_u (soundIn 4)))
-
-set delay times (unary)
-
-> withSC3 (send (b_fill 11 [(0,128,0.25)]))
-
-set feedback gain
-
-> withSC3 (send (b_fill 12 [(0,128,0.75)]))
-
-function to generate sin table of n places in range (l,r)
-
-> let gen_sin l r n ph =
->     let f x = range l r (sin ((x / n) * 2 * pi + ph))
->     in map f [0..n]
-
-set delay times (sin)
-
-> withSC3 (send (b_setn1 11 0 (gen_sin 0 0.35 128 0)))
-
-set feedback gain (sin)
-
-> withSC3 (send (b_setn1 12 0 (gen_sin 0.75 0.95 128 pi)))
-
-modulate delay times (lfo)
-
-> let o = range 0.15 0.35 (blip KR (1/23) 3)
-> in audition (recordBuf KR 11 0 1 0 1 Loop 1 DoNothing o)
-
-modulate feedback gains (lfo)
-
-> let o = range 0.75 0.95 (blip KR (1/25) 5)
-> in audition (recordBuf KR 12 0 1 0 1 Loop 1 DoNothing o)
diff --git a/Help/UGen/FFT/pv_BinScramble.help.lhs b/Help/UGen/FFT/pv_BinScramble.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/pv_BinScramble.help.lhs
+++ /dev/null
@@ -1,25 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_BinScramble"
-> Sound.SC3.UGen.DB.ugenSummary "PV_BinScramble"
-
-> import Sound.SC3.ID
-
-> let fileName = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
->                ;async (b_allocRead 12 fileName 0 0)})
-
-> let {a = playBuf 1 AR 12 (bufRateScale KR 12) 1 0 Loop DoNothing
->     ;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)}
-> in audition (out 0 (pan2 (ifft' g) 0 0.5))
-
-careful - feedback loop!
-> let {a = soundIn (mce2 4 5) * 4
->     ;f = fft' 10 a
->     ;x = mouseX KR 0.15 1 Linear 0.1
->     ;y = mouseY KR 0.15 1 Linear 0.1
->     ;i = impulse KR (lfNoise0 'α' KR 2 * 8 + 10) 0
->     ;g = pv_BinScramble 'β' f x y i
->     ;h = ifft' g}
-> in audition (out 0 (pan2 h 0 0.5))
diff --git a/Help/UGen/FFT/pv_BinShift.help.lhs b/Help/UGen/FFT/pv_BinShift.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/pv_BinShift.help.lhs
+++ /dev/null
@@ -1,25 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_BinShift"
-> Sound.SC3.UGen.DB.ugenSummary "PV_BinShift"
-
-> import Sound.SC3.ID
-
-allocate buffer
-> withSC3 (async (b_alloc 10 2048 1))
-
-source signal (oscillators)
-> let z = let {s0 = sinOsc KR 0.08 0 * 6 + 6.2
->             ;s1 = sinOsc KR (squared s0) 0 * 100 + 800}
->         in sinOsc AR s1 0 * 0.2
-
-source signal (the world)
-> let z = soundIn 4
-
-default values
-> audition (out 0 (ifft' (pv_BinShift (fft' 10 z) 1 0 0)))
-
-mouse control
-> let {x = mouseX KR (-10) 100 Linear 0.1
->     ;y = mouseY KR 1 4 Linear 0.1
->     ;b = mouseButton KR 0 1 0.2
->     ;pv = pv_BinShift (fft' 10 z) y x b}
-> in audition (out 0 (ifft' pv))
diff --git a/Help/UGen/FFT/pv_BinWipe.help.lhs b/Help/UGen/FFT/pv_BinWipe.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/pv_BinWipe.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_BinWipe"
-> Sound.SC3.UGen.DB.ugenSummary "PV_BinWipe"
-
-> import Sound.SC3.ID
-
-> let fileName = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
->                ;_ <- async (b_alloc 11 2048 1)
->                ;async (b_allocRead 12 fileName 0 0)})
-
-> let {n = whiteNoise 'α' AR
->     ;b = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
->     ;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
deleted file mode 100644
--- a/Help/UGen/FFT/pv_BrickWall.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_BrickWall"
-> Sound.SC3.UGen.DB.ugenSummary "PV_BrickWall"
-
-> import Sound.SC3.ID
-
-> withSC3 (async (b_alloc 10 2048 1))
-
-> let {n = whiteNoise 'α' AR
->     ;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
deleted file mode 100644
--- a/Help/UGen/FFT/pv_ConformalMap.help.lhs
+++ /dev/null
@@ -1,26 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_ConformalMap"
-> Sound.SC3.UGen.DB.ugenSummary "PV_ConformalMap"
-
-> import Sound.SC3.ID
-
-> withSC3 (async (b_alloc 10 1024 1))
-
-> let { i = soundIn 4
->     ; 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 (async (b_alloc 0 2048 1))
-
-> let z = 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}
->         in mix (lfSaw AR f 0) * 0.3
-
-> let z = soundIn 4
-
-> let {x = mouseX KR 0.01  2.0 Linear 0.1
->     ;y = mouseY KR 0.01 10.0 Linear 0.1
->     ;c = fft' 0 z
->     ;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_Diffuser.help.lhs b/Help/UGen/FFT/pv_Diffuser.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/pv_Diffuser.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_Diffuser"
-> Sound.SC3.UGen.DB.ugenSummary "PV_Diffuser"
-
-> import Sound.SC3.ID
-
-> let fileName = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
->                ;async (b_allocRead 12 fileName 0 0)})
-
-> let z = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
-
-> let z = soundIn 4
-
-> let {f = fft' 10 z
->     ;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_HainsworthFoote.help.lhs b/Help/UGen/FFT/pv_HainsworthFoote.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/pv_HainsworthFoote.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_HainsworthFoote"
-> Sound.SC3.UGen.DB.ugenSummary "PV_HainsworthFoote"
-
-> import Sound.SC3.ID
-
-> let {i = soundIn 4
->     ;b = localBuf 'α' 2048 1
->     ;f = fft' b i
->     ;x = mouseX KR 0.5 1.25 Linear 0.2
->     ;h = pv_HainsworthFoote f 1 0 x 0.04
->     ;o = sinOsc AR (mrg2 440 445) 0 * decay (h * 0.1) 0.1}
-> in audition (out 0 (o + i))
diff --git a/Help/UGen/FFT/pv_LocalMax.help.lhs b/Help/UGen/FFT/pv_LocalMax.help.lhs
deleted file mode 100644
--- a/Help/UGen/FFT/pv_LocalMax.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_LocalMax"
-> Sound.SC3.UGen.DB.ugenSummary "PV_LocalMax"
-
-> import Sound.SC3.ID
-
-> let fileName = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
->                ;async (b_allocRead 12 fileName 0 0)})
-
-> let { a = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
->     ; 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
deleted file mode 100644
--- a/Help/UGen/FFT/pv_MagAbove.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_MagAbove"
-> Sound.SC3.UGen.DB.ugenSummary "PV_MagAbove"
-
-> import Sound.SC3.ID
-
-> let fileName = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
->                ;async (b_allocRead 12 fileName 0 0) })
-
-> let {a = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
->     ;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.
-> 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
deleted file mode 100644
--- a/Help/UGen/FFT/pv_MagBelow.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_MagBelow"
-> Sound.SC3.UGen.DB.ugenSummary "PV_MagBelow"
-
-> import Sound.SC3.ID
-
-> let fileName = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
->                ;async (b_allocRead 12 fileName 0 0)})
-
-> let { a = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
->     ; 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.
-> 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
deleted file mode 100644
--- a/Help/UGen/FFT/pv_MagClip.help.lhs
+++ /dev/null
@@ -1,25 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_MagClip"
-> Sound.SC3.UGen.DB.ugenSummary "PV_MagClip"
-
-> import Sound.SC3.ID
-
-> let fileName = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
->                ;async (b_allocRead 12 fileName 0 0)})
-
-File input
-> let z = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
-
-Synthesised input.
-> let z = let {f0 = squared (sinOsc KR 0.08 0 * 6 + 6.2)
->             ;f1 = sinOsc KR f0 0 * 100 + 800}
->         in sinOsc AR f1 0
-
-Outside world
-> let z = soundIn 4
-
-> let {f = fft' 10 z
->     ;c = 128
->     ;x = mouseX KR 0 c 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
deleted file mode 100644
--- a/Help/UGen/FFT/pv_MagFreeze.help.lhs
+++ /dev/null
@@ -1,31 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_MagFreeze"
-> Sound.SC3.UGen.DB.ugenSummary "PV_MagFreeze"
-
-> import Sound.SC3.ID {- hsc3 -}
-
-Load audio file.
-
-> let fileName = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
->                ;async (b_allocRead 12 fileName 0 0)})
-
-File as signal...
-
-> let z = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
-
-Synthesised signal...
-
-> let z = let {o1 = sinOsc KR 0.08 0
->             ;o2 = sinOsc KR (squared (o1 * 6 + 6.2)) 0 * 100 + 800}
->         in sinOsc AR o2 0
-
-Outside world signal...
-
-> let z = soundIn 4
-
-Process (freeze) 'z'...
-
-> let {f = fft' 10 z
->     ;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
deleted file mode 100644
--- a/Help/UGen/FFT/pv_RandComb.help.lhs
+++ /dev/null
@@ -1,19 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_RandComb"
-> Sound.SC3.UGen.DB.ugenSummary "PV_RandComb"
-
-> import Sound.SC3.ID
-
-allocate buffer
-> withSC3 (async (b_alloc 10 2048 1))
-
-noise signal
-> let z = whiteNoise 'a' AR * 0.5
-
-outside world
-> let z = soundIn 4
-
-processor
-> let {t = impulse KR 0.1 0
->     ;x = mouseX KR 0.6 0.95 Linear 0.1
->     ;c = pv_RandComb 'a' (fft' 10 z) x t}
-> in 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
deleted file mode 100644
--- a/Help/UGen/FFT/pv_RandWipe.help.lhs
+++ /dev/null
@@ -1,23 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_RandWipe"
-> Sound.SC3.UGen.DB.ugenSummary "PV_RandWipe"
-
-> import Sound.SC3.ID
-> import qualified System.Random as R
-
-> withSC3 (do {_ <- async (b_alloc 10 2048 1)
->             ;async (b_alloc 11 2048 1)})
-
-> let { n0 = R.randomRs (400.0, 1000.0) (R.mkStdGen 0)
->     ; n1 = R.randomRs (80.0, 400.0) (R.mkStdGen 1)
->     ; n2 = R.randomRs (0.0, 8.0) (R.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 'a' f g x (y >* 0.5) }
-> in 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
deleted file mode 100644
--- a/Help/UGen/FFT/pv_RectComb.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_RectComb"
-> Sound.SC3.UGen.DB.ugenSummary "PV_RectComb"
-
-> import Sound.SC3.ID
-
-> withSC3 (async (b_alloc 10 2048 1))
-
-noise source
-> let z = whiteNoise 'a' AR * 0.3
-
-outside world
-> let z = soundIn 4
-
-> let {x = mouseX KR 0 0.5 Linear 0.1
->     ;y = mouseY KR 0 0.5 Linear 0.1
->     ;c = pv_RectComb (fft' 10 z) 8 x y}
-> in audition (out 0 (pan2 (ifft' c) 0 1))
-
-> 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 z) 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
deleted file mode 100644
--- a/Help/UGen/FFT/pvcollect.help.lhs
+++ /dev/null
@@ -1,52 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_ChainUGen.pvcollect"
-> :t pvcollect
-
-> import Data.List {- base -}
-> import Sound.SC3 {- hsc3 -}
-
-> let fileName = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (do {_ <- async (b_alloc 10 1024 1)
->                ;async (b_allocRead 11 fileName 0 0)})
-
-> let 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)
-
-> let bpf_sweep nf 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)
-
-> let pv_g nf cf =
->   let {no_op m p _ = (m,p)
->       ;combf m p i = ((modE i 7.0 ==* 0) * m,p)
->       ;sf = playBuf 1 AR 11 (bufRateScale KR 11) 1 0 Loop DoNothing
->       ;c1 = fft' 10 sf
->       ;c2 = pvcollect c1 nf cf 0 250 0}
->   in out 0 (0.1 * ifft' c2)
-
-> let pv_au nf cf =
->   let {no_op m p _ = (m,p)
->       ;combf m p i = ((modE i 7.0 ==* 0) * m,p)
->       ;c1 = fft' 10 (soundIn 0)
->       ;c2 = pvcollect c1 nf cf 0 250 0}
->   in out 0 (0.1 * ifft' c2)
-
-> let r = unlines ["number of constants       : 257"
->                 ,"number of controls        : 0"
->                 ,"control rates             : []"
->                 ,"number of unit generators : 1013"
->                 ,"unit generator rates      : [(KR,5),(AR,4),(DR,1004)]"]
-> in r `isPrefixOf` synthstat (pv_g 1024 spectral_delay)
-
-> synthstat (pv_g 1024 (bpf_sweep 1024))
-> audition (pv_g 1024 spectral_delay)
-> audition (pv_g 1024 (bpf_sweep 1024))
-
-> audition (pv_au 1024 spectral_delay)
-> audition (pv_au 1024 (bpf_sweep 1024))
-
-> import Sound.SC3.UGen.Dot {- hsc3-dot -}
-
-> draw_svg (pv_g 1024 (bpf_sweep 1024))
diff --git a/Help/UGen/Filter/allpassC.help.lhs b/Help/UGen/Filter/allpassC.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/allpassC.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See allPassN
diff --git a/Help/UGen/Filter/allpassL.help.lhs b/Help/UGen/Filter/allpassL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/allpassL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See allPassN
diff --git a/Help/UGen/Filter/allpassN.help.lhs b/Help/UGen/Filter/allpassN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/allpassN.help.lhs
+++ /dev/null
@@ -1,39 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "AllpassN"
-> Sound.SC3.UGen.DB.ugenSummary "AllpassN"
-
-> import Sound.SC3
-
-Since the allpass delay has no audible effect as a resonator on steady
-state sound ...
-
-> let {dly = xLine KR 0.0001 0.01 20 RemoveSynth
->     ;n = whiteNoise 'a' AR}
-> in 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.
-
-> let {n = whiteNoise 'a' AR
->     ;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
-
-> let {n = whiteNoise 'a' AR
->     ;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
-
-> let {n = whiteNoise 'a' AR
->     ;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.
-
-> let {n = whiteNoise 'a' AR
->     ;d = dust 'a' AR 1
->     ;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/bBandPass.help.lhs b/Help/UGen/Filter/bBandPass.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/bBandPass.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BBandPass"
-> Sound.SC3.UGen.DB.ugenSummary "BBandPass"
-
-> import Sound.SC3
-
-> let { i = soundIn 4
->     ; f = mouseX KR 20 20000 Exponential 0.2
->     ; bw = mouseY KR 0 10 Linear 0.2 }
-> in audition (out 0 (bBandPass i f bw))
diff --git a/Help/UGen/Filter/bBandStop.help.lhs b/Help/UGen/Filter/bBandStop.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/bBandStop.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BBandStop"
-> Sound.SC3.UGen.DB.ugenSummary "BBandStop"
-
-> import Sound.SC3
-
-> let {i = soundIn (mce2 0 1)
->     ;f = mouseX KR 20 20000 Exponential 0.2
->     ;bw = mouseY KR 0 10 Linear 0.2}
-> in audition (out 0 (bBandStop i f bw))
-
-> let {i = sinOsc AR 1000 (mce2 0 0)
->     ;f = mouseX KR 800 1200 Exponential 0.2
->     ;bw = mouseY KR 0 10 Linear 0.2}
-> in audition (out 0 (bBandStop i f bw))
diff --git a/Help/UGen/Filter/bHiPass.help.lhs b/Help/UGen/Filter/bHiPass.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/bHiPass.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BHiPass"
-> Sound.SC3.UGen.DB.ugenSummary "BHiPass"
-
-> import Sound.SC3
-
-> let { i = soundIn (mce2 0 1)
->     ; f = mouseX KR 10 20000 Exponential 0.2
->     ; rq = mouseY KR 0 1 Linear 0.2 }
-> in audition (out 0 (bHiPass i f rq))
diff --git a/Help/UGen/Filter/bHiShelf.help.lhs b/Help/UGen/Filter/bHiShelf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/bHiShelf.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BHiShelf"
-> Sound.SC3.UGen.DB.ugenSummary "BHiShelf"
-
-> import Sound.SC3
-
-> let { i = soundIn 4
->     ; f = mouseX KR 2200 18000 Exponential 0.2
->     ; db = mouseY KR 18 (-18) Linear 0.2 }
-> in audition (out 0 (bHiShelf i f 1 db))
-
-> let { i = soundIn 4
->     ; f = mouseX KR 2200 18000 Exponential 0.2
->     ; rs = mouseY KR 0.1 1 Linear 0.2 }
-> in audition (out 0 (bHiShelf i f rs 6))
diff --git a/Help/UGen/Filter/bLowPass.help.lhs b/Help/UGen/Filter/bLowPass.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/bLowPass.help.lhs
+++ /dev/null
@@ -1,23 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BLowPass"
-> Sound.SC3.UGen.DB.ugenSummary "BLowPass"
-> :t bLowPassCoef
-
-> import Sound.SC3.ID
-
-> let { i = soundIn (mce2 0 1)
->     ; f = mouseX KR 10 20000 Exponential 0.2
->     ; rq = mouseY KR 0 1 Linear 0.2 }
-> in audition (out 0 (bLowPass i f rq))
-
-> let { i = mix (saw AR (mce [0.99, 1, 1.01] * 440) * 0.3)
->     ; f = mouseX KR 100 20000 Exponential 0.2
->     ; rq = mouseY KR 0.1 1 Linear 0.2 }
-> in audition (out 0 (bLowPass i f rq))
-
-Calculate coefficients and use sos.
-> let { i = mix (saw AR (mce [0.99, 1, 1.01] * 440) * 0.3)
->     ; f = mouseX KR 100 20000 Exponential 0.2
->     ; rq = mouseY KR 0.1 1 Linear 0.2
->     ; (a0, a1, a2, b1, b2) = bLowPassCoef sampleRate f rq
->     ; flt ip = sos ip a0 a1 a2 b1 b2 }
-> in audition (out 0 (flt (flt i)))
diff --git a/Help/UGen/Filter/bLowShelf.help.lhs b/Help/UGen/Filter/bLowShelf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/bLowShelf.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BLowShelf"
-> Sound.SC3.UGen.DB.ugenSummary "BLowShelf"
-
-> import Sound.SC3.ID
-
-> let { i = soundIn (mce2 0 1)
->     ; f = mouseX KR 40 6000 Exponential 0.2
->     ; rs = 1
->     ; db = mouseY KR 24 (-24) Linear 0.2 }
-> in audition (out 0 (bLowShelf i f rs db))
-
-> let { i = soundIn (mce2 0 1)
->     ; f = mouseX KR 20 6000 Exponential 0.2
->     ; rs = mouseY KR 0.1 1 Linear 0.2
->     ; db = 6}
-> in audition (out 0 (bLowShelf i f rs db))
diff --git a/Help/UGen/Filter/bPeakEQ.help.lhs b/Help/UGen/Filter/bPeakEQ.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/bPeakEQ.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BPeakEQ"
-> Sound.SC3.UGen.DB.ugenSummary "BPeakEQ"
-
-> import Sound.SC3.ID
-
-> let { i = soundIn 4
->     ; f = mouseX KR 2200 18000 Exponential 0.2
->     ; db = mouseY KR 12 (-12) Linear 0.2 }
-> in audition (out 0 (bPeakEQ i f 0.8 db))
-
-> let { i = soundIn 4
->     ; f = mouseX KR 2200 18000 Exponential 0.2
->     ; rq = mouseY KR 10 0.4 Linear 0.2 }
-> in audition (out 0 (bPeakEQ i f rq 6))
diff --git a/Help/UGen/Filter/bpf.help.lhs b/Help/UGen/Filter/bpf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/bpf.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BPF"
-> Sound.SC3.UGen.DB.ugenSummary "BPF"
-
-> import Sound.SC3.ID
-
-> let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
-> in audition (out 0 (bpf (saw AR 200 * 0.5) f 0.3 ))
-
-> let { n = whiteNoise 'a' AR
->     ; 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
deleted file mode 100644
--- a/Help/UGen/Filter/bpz2.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BPZ2"
-> Sound.SC3.UGen.DB.ugenSummary "BPZ2"
-
-> import Sound.SC3.ID
-
-> let n = whiteNoise 'a' AR
-> in audition (out 0 (bpz2 (n * 0.25)))
diff --git a/Help/UGen/Filter/brf.help.lhs b/Help/UGen/Filter/brf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/brf.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BRF"
-> Sound.SC3.UGen.DB.ugenSummary "BRF"
-
-> import Sound.SC3.ID
-
-> let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3800 + 4000
-> in audition (out 0 (brf (saw AR 200 * 0.1) f 0.3))
diff --git a/Help/UGen/Filter/changed.help.lhs b/Help/UGen/Filter/changed.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/changed.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Changed"
-> Sound.SC3.UGen.DB.ugenSummary "Changed"
-
-> import Sound.SC3.ID
-
-simple composition of hpz1 and >*
-
-> let {s = lfNoise0 'α' KR 2
->     ;c = changed s 0
->     ;c' = decay2 c 0.01 0.5
->     ;o = sinOsc AR (440 + mce2 s c' * 440) 0 * 0.1}
-> in audition (out 0 o)
diff --git a/Help/UGen/Filter/clip.help.lhs b/Help/UGen/Filter/clip.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/clip.help.lhs
+++ /dev/null
@@ -1,4 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Clip"
-> Sound.SC3.UGen.DB.ugenSummary "Clip"
-
-> audition (out 0 (clip (sinOsc AR 440 0 * 0.4) (-0.25) 0.25))
diff --git a/Help/UGen/Filter/combC.help.lhs b/Help/UGen/Filter/combC.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/combC.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See combN
diff --git a/Help/UGen/Filter/combL.help.lhs b/Help/UGen/Filter/combL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/combL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See combN
diff --git a/Help/UGen/Filter/combN.help.lhs b/Help/UGen/Filter/combN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/combN.help.lhs
+++ /dev/null
@@ -1,32 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "CombN"
-> Sound.SC3.UGen.DB.ugenSummary "CombN"
-
-> import Sound.SC3.ID {- hsc3 -}
-
-Comb filter as resonator. The resonant fundamental is equal to
-reciprocal of the delay time.
-
-> let {n = whiteNoise 'α' AR
->     ;dt = xLine KR 0.0001 0.01 20 RemoveSynth}
-> in audition (out 0 (combN (n * 0.1) 0.01 dt 0.2))
-
-> let {n = whiteNoise 'α' AR
->     ;dt = xLine KR 0.0001 0.01 20 RemoveSynth}
-> in audition (out 0 (combL (n * 0.1) 0.01 dt 0.2))
-
-> let {n = whiteNoise 'α' AR
->     ;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
-
-> let {n = whiteNoise 'α' AR
->     ;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.
-
-> let {d = dust 'α' AR 1
->     ;n = whiteNoise 'β' AR
->     ;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
deleted file mode 100644
--- a/Help/UGen/Filter/decay.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Decay"
-> Sound.SC3.UGen.DB.ugenSummary "Decay"
-
-> import Sound.SC3.ID
-
-Used as an envelope.
-> let {n = pinkNoise 'a' AR
->     ;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
deleted file mode 100644
--- a/Help/UGen/Filter/decay2.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Decay2"
-> Sound.SC3.UGen.DB.ugenSummary "Decay2"
-
-> import Sound.SC3
-
-Used as an envelope
-
-> 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}
-> 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
deleted file mode 100644
--- a/Help/UGen/Filter/degreeToKey.help.lhs
+++ /dev/null
@@ -1,20 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DegreeToKey"
-> Sound.SC3.UGen.DB.ugenSummary "DegreeToKey"
-
-> import Sound.SC3.ID
-
-allocate & initialise buffer zero
-
-> withSC3 (async (b_alloc_setn1 0 0 [0,2,3.2,5,7,9,10]))
-
-modal space, mouse x controls discrete pitch in dorian mode
-
-> let {n = lfNoise1 'α' KR (mce [3,3.05])
->     ;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
deleted file mode 100644
--- a/Help/UGen/Filter/delay1.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Delay1"
-> Sound.SC3.UGen.DB.ugenSummary "Delay1"
-
-> let s = impulse AR 1 0
-> in audition (out 0 (s + (delay1 s)))
-
-original, subtract delayed from original
-> let z = dust 'a' AR 1000
-> in audition (out 0 (mce2 z (z - delay1 z)))
diff --git a/Help/UGen/Filter/delay2.help.lhs b/Help/UGen/Filter/delay2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/delay2.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Delay2"
-> Sound.SC3.UGen.DB.ugenSummary "Delay2"
-
-> import Sound.SC3.ID
-
-> let s = impulse AR 1 0
-> in audition (out 0 (s + (delay2 s)))
diff --git a/Help/UGen/Filter/delayC.help.lhs b/Help/UGen/Filter/delayC.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/delayC.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See delayN
diff --git a/Help/UGen/Filter/delayL.help.lhs b/Help/UGen/Filter/delayL.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/delayL.help.lhs
+++ /dev/null
@@ -1,1 +0,0 @@
-See delayN
diff --git a/Help/UGen/Filter/delayN.help.lhs b/Help/UGen/Filter/delayN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/delayN.help.lhs
+++ /dev/null
@@ -1,19 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DelayN"
-> Sound.SC3.UGen.DB.ugenSummary "DelayN"
-
-> import Sound.SC3.ID
-
-Dust randomly triggers Decay to create an exponential decay envelope
-for the WhiteNoise input source.  The input is mixed with the delay.
-> let {d = dust 'a' AR 1
->     ;n = whiteNoise 'b' AR
->     ;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 }
-> in audition (out 0 (o + delayN o l x))
diff --git a/Help/UGen/Filter/dynKlank.help.lhs b/Help/UGen/Filter/dynKlank.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/dynKlank.help.lhs
+++ /dev/null
@@ -1,40 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DynKlank"
-> Sound.SC3.UGen.DB.ugenSummary "DynKlank"
-
-> import Sound.SC3.ID {- hsc3 -}
-
-{s=`[[800,1071,1153,1723],nil,[1,1,1,1]]
-;DynKlank.ar(,Impulse.ar(2,0,0.1))}.play
-
-> let s = klankSpec [800,1071,1153,1723] [1,1,1,1] [1,1,1,1]
-> in audition (out 0 (dynKlank (impulse AR 2 0 * 0.1) 1 0 1 s))
-
-{s=`[[800,1071,1353,1723],nil,[1,1,1,1]]
-;DynKlank.ar(s,Dust.ar(8,0.1))}.play
-
-> let s = klankSpec [800,1071,1353,1723] [1,1,1,1] [1,1,1,1]
-> in audition (out 0 (dynKlank (dust 'α' AR 8 * 0.1) 1 0 1 s))
-
-{s=`[[800,1071,1353,1723],nil,[1,1,1,1]]
-;DynKlank.ar(s,PinkNoise.ar(0.007))}.play
-
-> let s = klankSpec [800,1071,1353,1723] [1,1,1,1] [1,1,1,1]
-> in audition (out 0 (dynKlank (pinkNoise 'α' AR * 0.007) 1 0 1 s))
-
-{s=`[[200,671,1153,1723],nil,[1,1,1,1]]
-;a=[0.007,0.007]
-;DynKlank.ar(s,PinkNoise.ar(a))}.play;
-
-> let {s = klankSpec [200,671,1153,1723] [1,1,1,1] [1,1,1,1]
->     ;a = mce2 0.007 0.007}
-> in audition (out 0 (dynKlank (pinkNoise 'α' AR * a) 1 0 1 s))
-
-Change frequencies (x) and ring-times (y) with mouse.
-
-> let {x = mouseX KR 0.5 2 Exponential 0.2
->     ;f = map (* x) [800,1071,1153,1723]
->     ;y = mouseY KR 0.1 10 Exponential 0.2
->     ;d = map (* y) [1,1,1,1]
->     ;s = klankSpec f [1,1,1,1] d
->     ;i = impulse AR 2 0 * 0.1}
-> in audition (out 0 (dynKlank i 1 0 1 s))
diff --git a/Help/UGen/Filter/formlet.help.lhs b/Help/UGen/Filter/formlet.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/formlet.help.lhs
+++ /dev/null
@@ -1,32 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Formlet"
-> Sound.SC3.UGen.DB.ugenSummary "Formlet"
-
-> import Sound.SC3.ID {- hsc3 -}
-
-> audition (out 0 (formlet (impulse AR 20 0.5) 1000 0.01 0.1))
-
-> let f = xLine KR 10 400 8 RemoveSynth
-> 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
->     ;ff = xLine KR 1500 700 8 RemoveSynth}
-> in audition (out 0 (formlet s ff 0.005 0.04))
-
-Mouse control of frequency and decay time.
-
-> let {s = blip AR (sinOsc KR 5 0 * 20 + 300) 1000 * 0.1
->     ;x = mouseX KR 0.01 0.2 Exponential 0.2
->     ;y = mouseY KR 700 2000 Exponential 0.2
->     ;o = formlet s y 0.005 x}
-> in audition (out 0 o)
-
-and again...
-
-> let {s = dust 'α' KR (mce2 10 11)
->     ;x = mouseX KR 0.1 2 Exponential 0.2
->     ;y = mouseY KR 7 200 Exponential 0.2
->     ;f = formlet s y 0.005 x
->     ;o = sinOsc AR (f * 200 + mce2 500 600 - 100) 0 * 0.2}
-> in audition (out 0 o)
diff --git a/Help/UGen/Filter/fos.help.lhs b/Help/UGen/Filter/fos.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/fos.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FOS"
-> Sound.SC3.UGen.DB.ugenSummary "FOS"
-
-> import Sound.SC3.ID
-
-Same as OnePole.
-> let x = lfTri AR 0.4 0 * 0.99
-> 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
-> in audition (out 0 (fos (lfSaw AR 200 0 * 0.2) (1 - (abs x)) x 0))
diff --git a/Help/UGen/Filter/freeVerb.help.lhs b/Help/UGen/Filter/freeVerb.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/freeVerb.help.lhs
+++ /dev/null
@@ -1,20 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FreeVerb"
-> Sound.SC3.UGen.DB.ugenSummary "FreeVerb"
-
-> import Sound.SC3
-
-> let {i = impulse AR 1 0
->     ;c = lfCub AR 1200 0
->     ;s = decay i 0.25 * c * 0.1
->     ;x = mouseX KR 0 1 Linear 0.1
->     ;y = mouseY KR 0 1 Linear 0.1
->     ;r = freeVerb s y x 0.5}
-> in audition (out 0 r)
-
-Process input channels
-> let {i = soundIn (mce2 0 1)
->     ;c = mceChannel
->     ;x = mouseX KR 0 1 Linear 0.1
->     ;y = mouseY KR 0 1 Linear 0.1
->     ;r = freeVerb2 (c 0 i) (c 1 i) y x 0.5}
-> in audition (out 0 r)
diff --git a/Help/UGen/Filter/freqShift.help.lhs b/Help/UGen/Filter/freqShift.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/freqShift.help.lhs
+++ /dev/null
@@ -1,45 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FreqShift"
-> Sound.SC3.UGen.DB.ugenSummary "FreqShift"
-
-> import Sound.SC3.ID {- hcs3 -}
-
-Shifting a 100Hz tone by 1 Hz rising to 500Hz
-
-> 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}
-> in audition (out 0 (freqShift i s 0 * 0.1))
-
-Modulating shift and phase
-
-> let {s = lfNoise2 'α' AR 0.3
->     ;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
-
-> let {n1 = whiteNoise 'α' AR
->     ;n2 = lfNoise0 'β' AR 5.5
->     ;i = bpf n1 1000 0.001
->     ;s = n2 * 1000}
-> in audition (out 0 (freqShift i s 0 * 32))
-
-{a=Blip.ar(60,4,LFGauss.ar(4,1/8))
-;a=a/4+LocalIn.ar(2)
-;a=FreqShift.ar(a,LFNoise0.kr(1/4,90))
-;LocalOut.ar(DelayC.ar(a,1,0.1,0.9))
-;a}.play
-
-> let {e = lfGauss AR 4 (1/8) 0 Loop DoNothing
->     ;o = blip AR 60 4 * e
->     ;a = o / 4 + localIn 2 AR
->     ;s = freqShift a (lfNoise0 'α' KR (1/4) * 90) 0
->     ;z = delayC s 1 0.1 * 0.9}
-> in audition (mrg2 (out 0 s) (localOut z))
diff --git a/Help/UGen/Filter/gVerb.help.lhs b/Help/UGen/Filter/gVerb.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/gVerb.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "GVerb"
-> Sound.SC3.UGen.DB.ugenSummary "GVerb"
-
-> import Sound.SC3.ID
-
-> let {i = impulse AR 1 0
->     ;c = lfCub AR 1200 0
->     ;s = decay i 0.25 * c * 0.1
->     ;r = gVerb s 10 3 0.5 0.5 15 1 0.7 0.5 300}
-> in audition (out 0 r)
diff --git a/Help/UGen/Filter/hasher.help.lhs b/Help/UGen/Filter/hasher.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/hasher.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Hasher"
-> Sound.SC3.UGen.DB.ugenSummary "Hasher"
-
-> import Sound.SC3.ID
-
-noise
-> audition (out 0 (hasher (line AR 0 1 1 RemoveSynth) * 0.2))
-
-remap x
-> let {x = mouseX KR 0 10 Linear 0.2
->     ;f = hasher (roundTo x 1) * 300 + 500}
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Filter/hpf.help.lhs b/Help/UGen/Filter/hpf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/hpf.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "HPF"
-> Sound.SC3.UGen.DB.ugenSummary "HPF"
-
-> import Sound.SC3.ID
-
-> let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
-> 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
deleted file mode 100644
--- a/Help/UGen/Filter/hpz1.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "HPZ1"
-> Sound.SC3.UGen.DB.ugenSummary "HPZ1"
-
-> import Sound.SC3.ID
-
-> let n = whiteNoise 'a' AR
-> in audition (out 0 (hpz1 (n * 0.25)))
diff --git a/Help/UGen/Filter/hpz2.help.lhs b/Help/UGen/Filter/hpz2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/hpz2.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "HPZ2"
-> Sound.SC3.UGen.DB.ugenSummary "HPZ2"
-
-> import Sound.SC3.ID
-
-> let n = whiteNoise 'a' AR
-> in audition (out 0 (hpz2 (n * 0.25)))
diff --git a/Help/UGen/Filter/klank.help.lhs b/Help/UGen/Filter/klank.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/klank.help.lhs
+++ /dev/null
@@ -1,31 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Klank"
-> Sound.SC3.UGen.DB.ugenSummary "Klank"
-
-> import Sound.SC3 {- hsc3 -}
-
-The function klankSpec can help create the 'spec' entry.
-
-> let s = klankSpec' [800,1071,1153,1723] [1,1,1,1] [1,1,1,1]
-> in audition (out 0 (klank (impulse AR 2 0 * 0.1) 1 0 1 s))
-
-A variant spec function takes non-UGen inputs
-
-> let {f = [800::Double,1071,1153,1723]
->     ;u = [1,1,1,1]
->     ;s = klankSpec' f u u}
-> 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 transposed 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
->     ;l = mce [-1,0,1]}
-> in audition (out 0 (mix (pan2 (klank t 1 0 1 s) l 1)))
diff --git a/Help/UGen/Filter/lag.help.lhs b/Help/UGen/Filter/lag.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/lag.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Lag"
-> Sound.SC3.UGen.DB.ugenSummary "Lag"
-
-> import Sound.SC3
-
-used to lag pitch
-
-> let x = mouseX KR 220 440 Linear 0.2
-> 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
deleted file mode 100644
--- a/Help/UGen/Filter/lag2.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Lag2"
-> Sound.SC3.UGen.DB.ugenSummary "Lag2"
-
-> import Sound.SC3
-
-> let x = mouseX KR 220 440 Exponential 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
deleted file mode 100644
--- a/Help/UGen/Filter/lag3.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Lag3"
-> Sound.SC3.UGen.DB.ugenSummary "Lag3"
-
-> import Sound.SC3
-
-> let x = mouseX KR 220 440 Exponential 0.1
-> in audition (out 0 (sinOsc AR (mce [x, lag3 x 1]) 0 * 0.1))
diff --git a/Help/UGen/Filter/lagUD.help.lhs b/Help/UGen/Filter/lagUD.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/lagUD.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LagUD"
-> Sound.SC3.UGen.DB.ugenSummary "LagUD"
-
-> import Sound.SC3
-
-lag pitch, slower down (5 seconds) than up (1 second)
-
-> let {x = mouseX KR 220 440 Linear 0.2
->     ;o = sinOsc AR (mce2 x (lagUD x 1 5)) 0 * 0.1}
-> in audition (out 0 o)
diff --git a/Help/UGen/Filter/latch.help.lhs b/Help/UGen/Filter/latch.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/latch.help.lhs
+++ /dev/null
@@ -1,21 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Latch"
-> Sound.SC3.UGen.DB.ugenSummary "Latch"
-
-> import Sound.SC3.Monadic
-
-> 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 :
-> 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
-> 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
deleted file mode 100644
--- a/Help/UGen/Filter/leakDC.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LeakDC"
-> Sound.SC3.UGen.DB.ugenSummary "LeakDC"
-
-> import Sound.SC3
-
-> let a = lfPulse AR 800 0 0.5 * 0.1 + 0.5
-> in audition (out 0 (mce [a,leakDC a 0.995]))
diff --git a/Help/UGen/Filter/limiter.help.lhs b/Help/UGen/Filter/limiter.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/limiter.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Limiter"
-> Sound.SC3.UGen.DB.ugenSummary "Limiter"
-
-> import Sound.SC3
-
-example signal
-> let z = let i = impulse AR 8 0 * lfSaw KR 0.25 0 * (-0.6) + 0.7
->         in decay2 i 0.001 0.3 * fSinOsc AR 500 0
-
-unprocessed
-> audition (out 0 z)
-
-limited
-> audition (out 0 (limiter z 0.4 0.01))
diff --git a/Help/UGen/Filter/linExp.help.lhs b/Help/UGen/Filter/linExp.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/linExp.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LinExp"
-> Sound.SC3.UGen.DB.ugenSummary "LinExp"
-
-> let f = linExp (mouseX KR 0 1 Linear 0.2) 0 1 440 660
-> 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}
-> 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
deleted file mode 100644
--- a/Help/UGen/Filter/linLin.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LinLin"
-> Sound.SC3.UGen.DB.ugenSummary "LinLin"
-
-> import Sound.SC3
-
-> let f = linLin (mouseX KR 0 1 Linear 0.2) 0 1 440 660
-> 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 }
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
-
-> import Sound.SC3.ID
-
-Modulating source and destination values.
-> let {n = lfNoise2 'a' AR 80
->     ;x = mouseX KR 200 8000 Linear 0.2
->     ;y = mouseY KR 200 8000 Linear 0.2
->     ;f = linLin n (sinOsc KR 0.2 0) (sinOsc KR 0.2543 0) x y}
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Filter/linXFade2.help.lhs b/Help/UGen/Filter/linXFade2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/linXFade2.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LinXFade2"
-> Sound.SC3.UGen.DB.ugenSummary "LinXFade2"
-
-> import Sound.SC3.ID
-
-> let o = linXFade2 (saw AR 440) (sinOsc AR 440 0) (lfTri KR 0.1 0) * 0.1
-> in audition (out 0 o)
-
-> let o = linXFade2 (fSinOsc AR 800 0 * 0.2)
->                   (pinkNoise 'α' AR * 0.2)
->                   (fSinOsc KR 1 0)
-> in audition (out 0 o)
diff --git a/Help/UGen/Filter/lpf.help.lhs b/Help/UGen/Filter/lpf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/lpf.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LPF"
-> Sound.SC3.UGen.DB.ugenSummary "LPF"
-
-> import Sound.SC3
-
-> let {f = xLine KR 0.7 300 20 RemoveSynth
->     ;ff = fSinOsc KR f 0 * 3600 + 4000}
-> in audition (out 0 (lpf (saw AR 200 * 0.1) ff))
-
-Control rate filtering.
-> let ctl = lpf (lfPulse KR 8 0 0.5) (mouseX KR 2 50 Exponential 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
deleted file mode 100644
--- a/Help/UGen/Filter/lpz1.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LPZ1"
-> Sound.SC3.UGen.DB.ugenSummary "LPZ1"
-
-> import Sound.SC3.ID
-
-> let n = whiteNoise 'a' AR * 0.1
-> in audition (out 0 (mce2 n (lpz1 n)))
diff --git a/Help/UGen/Filter/lpz2.help.lhs b/Help/UGen/Filter/lpz2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/lpz2.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LPZ2"
-> Sound.SC3.UGen.DB.ugenSummary "LPZ2"
-
-> import Sound.SC3.ID
-
-> let n = whiteNoise 'a' AR
-> in audition (out 0 (lpz2 (n * 0.25)))
diff --git a/Help/UGen/Filter/mantissaMask.help.lhs b/Help/UGen/Filter/mantissaMask.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/mantissaMask.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MantissaMask"
-> Sound.SC3.UGen.DB.ugenSummary "MantissaMask"
-
-> import Sound.SC3
-
-> let s = sinOsc AR (sinOsc KR 0.2 0 * 400 + 500) 0 * 0.4
-> in audition (out 0 (mantissaMask s 3))
diff --git a/Help/UGen/Filter/median.help.lhs b/Help/UGen/Filter/median.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/median.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Median"
-> Sound.SC3.UGen.DB.ugenSummary "Median"
-
-> import Sound.SC3.ID
-
-Signal with impulse noise.
-> let n = dust2 'a' AR 100
-> in audition (out 0 (median 3 (saw AR 500 * 0.1 + n * 0.9)))
-
-The median length can be increased for longer duration noise.
-> let n = dust2 'a' AR 100
-> in 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
-> 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.
-> let {n = whiteNoise 'a' AR
->     ;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/midEQ.help.lhs b/Help/UGen/Filter/midEQ.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/midEQ.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MidEQ"
-> Sound.SC3.UGen.DB.ugenSummary "MidEQ"
-
-> import Sound.SC3.ID
-
-> let f = midiCPS (fSinOsc KR 1 0 * 24 + 84)
-> in audition (out 0 (midEQ (saw AR 200 * 0.2) f 0.3 12))
-
-> let {i = pinkNoise 'a' AR * 0.2 + sinOsc AR 600 0 * 0.1
->     ;f = sinOsc KR 0.2 (0.5 * pi) * 2 + 600}
-> in audition (out 0 (midEQ i f 0.01 (-24)))
diff --git a/Help/UGen/Filter/moogFF.help.lhs b/Help/UGen/Filter/moogFF.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/moogFF.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MoogFF"
-> Sound.SC3.UGen.DB.ugenSummary "MoogFF"
-
-> import Sound.SC3.ID
-
-> let {n = whiteNoise 'a' AR
->     ;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))
-
-Note distortion at high gain.
-> let {x = mouseX KR 100 20000 Exponential 0.1
->     ;y = mouseY KR 0.1 4.0 Linear 0.1
->     ;i = mix (saw AR (mce [0.99, 1, 1.01] * 440)) * 0.3 }
-> in audition (out 0 (moogFF i x y 0))
-
-> let {n = lfNoise0 'a' KR 0.43
->     ;p = pulse AR (mce [40, 121]) (mce [0.3, 0.7])
->     ;f0 = linLin n 0 1 0.001 2.2
->     ;f = linLin (sinOsc KR f0 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
deleted file mode 100644
--- a/Help/UGen/Filter/normalizer.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Normalizer"
-> Sound.SC3.UGen.DB.ugenSummary "Normalizer"
-
-> import Sound.SC3
-
-> let {s = fSinOsc AR 500 0
->     ;t = impulse AR 8 (lfSaw KR 0.25 (-0.6) * 0.7)
->     ;z = decay2 t 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
deleted file mode 100644
--- a/Help/UGen/Filter/onePole.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "OnePole"
-> Sound.SC3.UGen.DB.ugenSummary "OnePole"
-
-> import Sound.SC3.ID
-
-> let n = whiteNoise 'a' AR
-> in audition (out 0 (onePole (n * 0.5) 0.95))
-
-> let n = whiteNoise 'a' AR
-> in audition (out 0 (onePole (n * 0.5) (-0.95)))
-
-> let {n = whiteNoise 'a' AR
->     ;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
deleted file mode 100644
--- a/Help/UGen/Filter/oneZero.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "OneZero"
-> Sound.SC3.UGen.DB.ugenSummary "OneZero"
-
-> import Sound.SC3.ID
-
-> let n = whiteNoise 'a' AR
-> in audition (out 0 (oneZero (n * 0.5) 0.5))
-
-> let n = whiteNoise 'a' AR
-> in audition (out 0 (oneZero (n * 0.5) (-0.5)))
-
-> let {n = whiteNoise 'a' AR
->     ;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
deleted file mode 100644
--- a/Help/UGen/Filter/pitchShift.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PitchShift"
-> Sound.SC3.UGen.DB.ugenSummary "PitchShift"
-
-> import Sound.SC3
-
-> let {s = sinOsc AR 440 0 * 0.1
->     ;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 s 0.2 r d 0))
-
-> let {s = soundIn 4
->     ;pd = mouseX KR 0.0 0.1 Linear 0.1
->     ;td = mouseY KR 0.0 0.1 Linear 0.1}
-> in audition (out 0 (pitchShift s 0.2 (mce2 1.0 1.5) pd td))
diff --git a/Help/UGen/Filter/pluck.help.lhs b/Help/UGen/Filter/pluck.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/pluck.help.lhs
+++ /dev/null
@@ -1,30 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Pluck"
-> Sound.SC3.UGen.DB.ugenSummary "Pluck"
-
-> import Sound.SC3.ID {- hsc3 -}
-
-Excitation signal is white noise, triggered twice a second with
-varying OnePole coef.
-
-> let {n = whiteNoise 'α' AR
->     ;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))
-
-> import Sound.SC3.UGen.Protect {- hsc3 -}
-
-> let {n = 50
->     ;udup = uclone 'α'
->     ;f = udup n (rand 'β' 0.05 0.2)
->     ;p = udup n (rand 'γ' 0 1)
->     ;w = udup n (whiteNoise 'δ' AR)
->     ;fi = udup n (rand 'ε' 10 12)
->     ;coef = rand 'ζ' 0.01 0.2
->     ;l = udup n (rand 'η' (-1) 1)
->     ;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/ramp.help.lhs b/Help/UGen/Filter/ramp.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/ramp.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Ramp"
-> Sound.SC3.UGen.DB.ugenSummary "Ramp"
-
-> import Sound.SC3
-
-Used to lag pitch
-
-> let {o = lfPulse KR 4 0 0.5 * 50 + 400
->     ;l = line KR 0 1 15 DoNothing
->     ;f = ramp o l}
-> in audition (out 0 (sinOsc AR f 0 * 0.3))
-
-mouse control
-
-> let {x = mouseX KR 220 440 Exponential 0
->     ;x' = ramp x (300 / 1000)}
-> in audition (out 0 (sinOsc AR (mce2 x x') 0 * 0.1))
diff --git a/Help/UGen/Filter/resonz.help.lhs b/Help/UGen/Filter/resonz.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/resonz.help.lhs
+++ /dev/null
@@ -1,35 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Resonz"
-> Sound.SC3.UGen.DB.ugenSummary "Resonz"
-
-> import Sound.SC3.ID
-
-> let n = whiteNoise 'α' AR
-> in audition (out 0 (resonz (n * 0.5) 2000 0.1))
-
-Modulate frequency
-
-> let {n = whiteNoise 'α' AR
->     ;f = xLine KR 1000 8000 10 RemoveSynth}
-> in audition (out 0 (resonz (n * 0.5) f 0.05))
-
-Modulate bandwidth
-
-> let {n = whiteNoise 'α' AR
->     ;bw = xLine KR 1 0.001 8 RemoveSynth}
-> in audition (out 0 (resonz (n * 0.5) 2000 bw))
-
-Modulate bandwidth opposite direction
-
-> let {n = whiteNoise 'α' AR
->     ;bw = xLine KR 0.001 1 8 RemoveSynth}
-> in audition (out 0 (resonz (n * 0.5) 2000 bw))
-
-Mouse exam (1/Q = bandwidth / center-frequency)
-
-> let {n = pinkNoise 'α' AR
->     ;m = mouseX KR 36 85 Linear 0.2 {- midi note -}
->     ;w = mouseY KR 0.1 5 Linear 0.2 {- bandwidth -}
->     ;f = midiCPS (floorE m) {- centre frequency -}
->     ;rq = w / f {- 1/Q (reciprocal of Q) -}
->     ;o = resonz (n * 0.5) f rq}
-> in audition (out 0 o)
diff --git a/Help/UGen/Filter/rhpf.help.lhs b/Help/UGen/Filter/rhpf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/rhpf.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RHPF"
-> Sound.SC3.UGen.DB.ugenSummary "RHPF"
-
-> import Sound.SC3
-
-> let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
-> 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
deleted file mode 100644
--- a/Help/UGen/Filter/ringz.help.lhs
+++ /dev/null
@@ -1,26 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Ringz"
-> Sound.SC3.UGen.DB.ugenSummary "Ringz"
-
-> import Sound.SC3.ID
-
-> let n = dust 'a' AR 3
-> in audition (out 0 (ringz (n * 0.3) 2000 2))
-
-> let n = whiteNoise 'a' AR
-> in audition (out 0 (ringz (n * 0.005) 2000 0.5))
-
-Modulate frequency
-> let {n = whiteNoise 'a' AR
->     ;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
-> 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
-> 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
-> 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
deleted file mode 100644
--- a/Help/UGen/Filter/rlpf.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RLPF"
-> Sound.SC3.UGen.DB.ugenSummary "RLPF"
-
-> import Sound.SC3.ID
-
-> let {n = whiteNoise 'a' AR
->     ;f = sinOsc AR 0.5 0 * 40 + 220
->     ;r = rlpf n f 0.1}
-> in audition (out 0 r)
-
-> let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
-> 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
deleted file mode 100644
--- a/Help/UGen/Filter/select.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Select"
-> Sound.SC3.UGen.DB.ugenSummary "Select"
-
-> import Sound.SC3
-
-> 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))
-
-Here used as a sequencer:
-> 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/selectX.help.lhs b/Help/UGen/Filter/selectX.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/selectX.help.lhs
+++ /dev/null
@@ -1,21 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SelectX"
-> :t selectX
-
-# composite ugen graph
-
-> import Sound.SC3
-> import Sound.SC3.UGen.Dot
-
-> let { n = 3/2
->     ; f = mce2 440 441
->     ; a = mce [sinOsc AR f 0, saw AR f, pulse AR f 0.1]
->     ; s = mceSum (selectX (lfSaw KR 1 0 * n + n) a * 0.2) }
-> in audition (out 0 s) >> draw s
-
-Here used as a sequencer:
-> let { n = 10
->     ; a = mce [517, 403, 89, 562, 816, 107, 241, 145, 90, 224]
->     ; c = n / 2
->     ; f = mceSum (selectX (lfSaw KR 0.5 0 * c + c) a)
->     ; s = saw AR f * 0.2 }
-> in audition (out 0 s) >> draw s
diff --git a/Help/UGen/Filter/shaper.help.lhs b/Help/UGen/Filter/shaper.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/shaper.help.lhs
+++ /dev/null
@@ -1,26 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Shaper"
-> Sound.SC3.UGen.DB.ugenSummary "Shaper"
-
-> import Sound.SC3
-
-> let mk_b a = do {_ <- async (b_alloc 10 512 1)
->                 ;let f = [Normalise,Wavetable,Clear]
->                  in async (b_gen_cheby 10 f a)}
-
-> let z = sinOsc AR 300 0 * line KR 0 1 6 RemoveSynth
-> in withSC3 (do {_ <- mk_b [1,0,1,1,0,1]
->                ;play (out 0 (shaper 10 z * 0.1))})
-
-> let z = sinOsc AR 400 (pi / 2) * line KR 0 1 6 RemoveSynth
-> in withSC3 (do {_ <- mk_b [0.25,0.5,0.25]
->                ;play (out 0 (shaper 10 z * 0.1))})
-
-> let {z = soundIn 4
->     ;x = sinOsc KR (1/4) 0}
-> in withSC3 (do {_ <- mk_b [1,0,1,1,0,1]
->                ;play (out 0 (xFade2 z (shaper 10 z) x 0.5))})
-
-> let {z = soundIn 4
->     ;x = mouseX KR (-1) 1 Linear 0.2}
-> in withSC3 (do {_ <- mk_b [1,0,1,1,0,1,0.5,0,0.25,0,0.75,1]
->                ;play (out 0 (xFade2 z (shaper 10 z) x 0.5))})
diff --git a/Help/UGen/Filter/slew.help.lhs b/Help/UGen/Filter/slew.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/slew.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Slew"
-> Sound.SC3.UGen.DB.ugenSummary "Slew"
-
-> import Sound.SC3
-
-> let z = lfPulse AR 800 0 0.5 * 0.1
-> in audition (out 0 (mce2 z (slew z 4000 4000)))
-
-> let z = saw AR 800 * 0.1
-> in audition (out 0 (mce2 z (slew z 400 400)))
diff --git a/Help/UGen/Filter/sos.help.lhs b/Help/UGen/Filter/sos.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/sos.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SOS"
-> Sound.SC3.UGen.DB.ugenSummary "SOS"
-
-> import Sound.SC3
-
-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) }
-> 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
deleted file mode 100644
--- a/Help/UGen/Filter/twoPole.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TwoPole"
-> Sound.SC3.UGen.DB.ugenSummary "TwoPole"
-
-> import Sound.SC3.ID
-
-> let n = whiteNoise 'a' AR
-> in audition (out 0 (twoPole (n * 0.005) 2000 0.95))
-
-> let {n = whiteNoise 'a' AR
->     ;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
deleted file mode 100644
--- a/Help/UGen/Filter/twoZero.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TwoZero"
-> Sound.SC3.UGen.DB.ugenSummary "TwoZero"
-
-> import Sound.SC3.ID
-
-> let {n = whiteNoise 'a' AR
->     ;f = xLine KR 20 20000 8 RemoveSynth}
-> in audition (out 0 (twoZero (n * 0.125) f 1))
diff --git a/Help/UGen/Filter/varLag.help.lhs b/Help/UGen/Filter/varLag.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/varLag.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "VarLag"
-> Sound.SC3.UGen.DB.ugenSummary "VarLag"
-
-#VarLag at sclang is a composite UGen, at hsc3 it's a direct binding to the underlying UGen.
-
-> import Sound.SC3
-
-used to lag pitch
-
-> let x = mouseX KR 220 440 Linear 0.2
-> in audition (out 0 (sinOsc AR (mce [x, varLag x 1 x]) 0 * 0.1))
-
-compare to lag UGen
-
-> let x = mouseX KR 220 440 Linear 0.2
-> in audition (out 0 (sinOsc AR (mce [x, lag x 1]) 0 * 0.1))
diff --git a/Help/UGen/Filter/wrapIndex.help.lhs b/Help/UGen/Filter/wrapIndex.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/wrapIndex.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "WrapIndex"
-> Sound.SC3.UGen.DB.ugenSummary "WrapIndex"
-
-> import Sound.SC3
-
-> withSC3 (async (b_alloc_setn1 0 0 [200,300,400,500,600,800]))
-
-> let {x = mouseX KR 0 18 Linear 0.1
->     ;f = wrapIndex 0 x}
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
-
-> let {b = asLocalBuf 'α' [200,300,400,500,600,800]
->     ;x = mouseX KR 0 18 Linear 0.1
->     ;f = wrapIndex b x}
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Filter/xFade2.help.lhs b/Help/UGen/Filter/xFade2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Filter/xFade2.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "XFade2"
-> Sound.SC3.UGen.DB.ugenSummary "XFade2"
-
-> import Sound.SC3.ID
-
-> let o = xFade2 (saw AR 440) (sinOsc AR 440 0) (lfTri KR 0.1 0) 0.1
-> in audition (out 0 o)
-
-> let o = linXFade2 (fSinOsc AR 800 0 * 0.2)
->                   (pinkNoise 'α' AR * 0.2)
->                   (fSinOsc KR 1 0)
-> in audition (out 0 o)
diff --git a/Help/UGen/Granular/grainBuf.help.lhs b/Help/UGen/Granular/grainBuf.help.lhs
deleted file mode 100644
--- a/Help/UGen/Granular/grainBuf.help.lhs
+++ /dev/null
@@ -1,30 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "GrainBuf"
-> Sound.SC3.UGen.DB.ugenSummary "GrainBuf"
-
-> import Sound.SC3.ID
-
-> let fn = "/home/rohan/data/audio/pf-c5.snd"
-> in withSC3 (send (b_allocRead 10 fn 0 0))
-
-> let {buf = 10
->     ;dur = 15
->     ;lin a b = line KR a b dur RemoveSynth
->     ;tr = impulse KR (lin 7.5 15) 0
->     ;gd = lin 0.05 0.1
->     ;r = lin 1 0.5 {- rate -}
->     ;i = lin 0 1 {- read-location -}
->     ;l = lin (-0.5) 0.5 {- stereo-location -}
->     ;g = grainBuf 2 tr gd buf r i 2 l (-1) 512}
-> in audition (out 0 g)
-
-> 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
->     ;n1 = lfNoise1 'α' KR 500
->     ;n2 = lfNoise2 'β' KR 0.1
->     ;r = linLin n1 (-1) 1 0.5 2
->     ;p = linLin n2 (-1) 1 0 1
->     ;g = grainBuf 2 i 0.1 b r p 2 x e 512}
-> in audition (out 0 g)
diff --git a/Help/UGen/Granular/grainFM.help.lhs b/Help/UGen/Granular/grainFM.help.lhs
deleted file mode 100644
--- a/Help/UGen/Granular/grainFM.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "GrainFM"
-> Sound.SC3.UGen.DB.ugenSummary "GrainFM"
-
-> import Sound.SC3.ID
-
-> let {d = 15
->     ;lin a b = line KR a b d RemoveSynth
->     ;l = lin (-0.5) 0.5
->     ;f = lin 200 800
->     ;t = impulse KR (lin 7.5 15) 0
->     ;i = lin (-1) 1}
-> in audition (out 0 (grainFM 2 t 0.1 f 200 i l (-1) 512 * 0.1))
-
-> let {n1 = whiteNoise 'α' KR
->     ;n2 = lfNoise1 'β' KR 500
->     ;d = 5
->     ;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 12.5 0
->     ;i = linLin n2 (-1) 1 1 10}
-> in audition (out 0 (grainFM 2 t 0.1 f 200 i x (-1) 512 * 0.1))
diff --git a/Help/UGen/Granular/grainIn.help.lhs b/Help/UGen/Granular/grainIn.help.lhs
deleted file mode 100644
--- a/Help/UGen/Granular/grainIn.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "GrainIn"
-> Sound.SC3.UGen.DB.ugenSummary "GrainIn"
-
-> import Sound.SC3.ID
-
-> let {n = pinkNoise 'α' AR
->     ;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) 512 * 0.1}
-> in audition (out 0 g)
diff --git a/Help/UGen/Granular/grainSin.help.lhs b/Help/UGen/Granular/grainSin.help.lhs
deleted file mode 100644
--- a/Help/UGen/Granular/grainSin.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "GrainSin"
-> Sound.SC3.UGen.DB.ugenSummary "GrainSin"
-
-> import Sound.SC3.ID
-
-> let {n = whiteNoise 'α' KR
->     ;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) 512 * 0.1))
diff --git a/Help/UGen/Granular/warp1.help.lhs b/Help/UGen/Granular/warp1.help.lhs
deleted file mode 100644
--- a/Help/UGen/Granular/warp1.help.lhs
+++ /dev/null
@@ -1,23 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Warp1"
-> Sound.SC3.UGen.DB.ugenSummary "Warp1"
-
-> import Sound.SC3
-
-> let {fn = "/home/rohan/data/audio/pf-c5.aif"
->     ;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 withSC3 (do {send (b_allocRead 10 fn 0 0)
->                ;play (out 0 w)})
-
-real-time (delayed) input
-
-> let {i = soundIn 4
->     ;r = recordBuf AR 10 0 1 0 1 Loop 1 DoNothing i
->     ;ph = (8192 / sampleRate) * 2 * pi
->     ;p = lfSaw KR (1 / bufDur KR 10) ph * 0.5 + 0.5
->     ;x = mouseX KR 0.5 2 Linear 0.2
->     ;y = mouseY KR 0.01 0.2 Linear 0.2
->     ;w = warp1 1 10 p x 0.1 (-1) 8 y 4}
-> in withSC3 (do {send (b_alloc 10 8192 1)
->                ;play (out 0 (mrg2 (i + w) r))})
diff --git a/Help/UGen/IO/in.help.lhs b/Help/UGen/IO/in.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/in.help.lhs
+++ /dev/null
@@ -1,53 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "In"
-> Sound.SC3.UGen.DB.ugenSummary "In"
-
-# hsc3 renames UGen to in' since in is a reserved keyword
-
-> import Sound.SC3.ID
-
-Patching input to output (see also soundIn).
-
-> audition (out 0 (in' 2 AR numOutputBuses))
-
-Patching input to output, with delay.
-
-> let {i = in' 2 AR numOutputBuses
->     ;d = delayN i 0.5 0.5}
-> in audition (out 0 (i + d))
-
-Write noise to first private bus, then read it out.
-The multiple root graph is ordered.
-
-> let {n = pinkNoise 'α' AR
->     ;b = numOutputBuses + numInputBuses
->     ;wr = out b (n * 0.3)
->     ;rd = out 0 (in' 1 AR b)}
-> in audition (mrg [rd,wr])
-
-There are functions to encapsulate the offset calculation.
-(There is also a firstPrivateBus value.)
-
-> let {n = pinkNoise 'α' AR
->     ;wr = privateOut 0 (n * 0.3)
->     ;rd = out 0 (privateIn 1 AR 0)}
-> in audition (mrg [rd,wr])
-
-Set value on a control bus
-
-> withSC3 (send (c_set1 0 300))
-
-Read a control bus
-
-> audition (out 0 (sinOsc AR (in' 1 KR 0) 0 * 0.1))
-
-Re-set value on bus
-
-> withSC3 (send (c_set1 0 600))
-
-Control rate graph writing buses 0 & 1.
-
-> audition (out 0 (mce2 (tRand 'α' 220 2200 (dust 'β' KR 1)) (dust 'γ' KR 3)))
-
-Audio rate graph reading control buses 0 & 1.
-
-> audition (out 0 (sinOsc AR (in' 1 KR 0) 0 * decay (in' 1 KR 1) 0.2 * 0.1))
diff --git a/Help/UGen/IO/inFeedback.help.lhs b/Help/UGen/IO/inFeedback.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/inFeedback.help.lhs
+++ /dev/null
@@ -1,39 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "InFeedback"
-> Sound.SC3.UGen.DB.ugenSummary "InFeedback"
-
-> import Sound.SC3
-
-Audio feedback modulation
-
-> 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 = firstPrivateBus
->     ;s = inFeedback 1 b}
-> in audition (out 0 s)
-
-> let {b  = firstPrivateBus
->     ;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 = firstPrivateBus
->     ;s = in' 1 AR b}
-> in audition (out 0 s)
-
-Resonator, see localOut for variant.
-
-> let {b = firstPrivateBus
->     ;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.
-
-> audition (out 1 (sinOsc AR 440 0 * 0.2))
diff --git a/Help/UGen/IO/inTrig.help.lhs b/Help/UGen/IO/inTrig.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/inTrig.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "InTrig"
-> Sound.SC3.UGen.DB.ugenSummary "InTrig"
-
-> import Sound.SC3
-
-Run an oscillator with the trigger at bus 10.
-
-> 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.
-
-> withSC3 (send (c_set1 10 0.1))
diff --git a/Help/UGen/IO/keyState.help.lhs b/Help/UGen/IO/keyState.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/keyState.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "KeyState"
-> Sound.SC3.UGen.DB.ugenSummary "KeyState"
-
-> import Sound.SC3
-
-The keycode 38 is the A key on my keyboard.  Under X the xev(1)
-command is useful in determining your keyboard layout.
-
-> audition (out 0 (sinOsc AR 800 0 * keyState KR 38 0 0.1 0.5))
diff --git a/Help/UGen/IO/lagIn.help.lhs b/Help/UGen/IO/lagIn.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/lagIn.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LagIn"
-> Sound.SC3.UGen.DB.ugenSummary "LagIn"
-
-> import Sound.SC3
-
-Set frequency at control bus
-
-> withSC3 (send (c_set1 10 200))
-
-Oscillator reading frequency at control bus
-
-> audition (out 0 (sinOsc AR (lagIn 1 10 1) 0 * 0.1))
-
-Re-set frequency at control bus
-
-> withSC3 (send (c_set1 10 2000))
diff --git a/Help/UGen/IO/localBuf.help.lhs b/Help/UGen/IO/localBuf.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/localBuf.help.lhs
+++ /dev/null
@@ -1,75 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LocalBuf"
-> Sound.SC3.UGen.DB.ugenSummary "LocalBuf"
-
-> import Sound.SC3.ID
-
-Allocate a buffer local to the synthesis graph.
-
-> let {n = whiteNoise 'α' AR
->     ;b = localBuf 'β' 2048 1
->     ;f = fft' b n
->     ;c = pv_BrickWall f (sinOsc KR 0.1 0 * 0.75)}
-> in audition (out 0 (ifft' c * 0.1))
-
-> import Sound.SC3.UGen.Protect
-
-Variant with two local buffers
-
-> let {n = uclone 'α' 2 (whiteNoise 'β' AR)
->     ;b = uclone 'γ' 2 (localBuf 'δ' 2048 1)
->     ;f = fft' b n
->     ;c = pv_BrickWall f (sinOsc KR (mce2 0.1 0.11) 0 * 0.75)}
-> in audition (out 0 (ifft' c * 0.1))
-
-Not clearing the buffer accesses old data, slowly overwrite data with noise
-
-> let {b = localBuf 'α' 2048 2
->     ;nf = bufFrames KR b
->     ;x = mouseX KR 1 2 Linear 0.2
->     ;r = playBuf 2 AR b x 1 0 Loop DoNothing * 0.1
->     ;wr p i = bufWr b (linLin p (-1) 1 0 nf) Loop i
->     ;n = uclone 'β' 2 (whiteNoise 'γ' AR)
->     ;ph = lfNoise0 'δ' AR 530}
-> in audition (mrg2 (out 0 r) (wr ph n))
-
-bufCombC needs no clearing, because the delay line is filled by the ugen
-
-> let {d = uclone 'α' 2 (dust 'β' AR 1)
->     ;n = whiteNoise 'γ' AR
->     ;z = decay d 0.3 * n
->     ;l = xLine KR 0.0001 0.01 20 DoNothing
->     ;sr = sampleRate
->     ;b = uclone 'δ' 2 (localBuf 'ε' sr 2)}
-> in audition (out 0 (bufCombC b z l 0.2))
-
-asLocalBuf combines localBuf and setBuf
-
-> let {b = asLocalBuf 'α' [2,1,5,3,4,0]
->     ;x = mouseX KR 0 (bufFrames KR b) Linear 0.2
->     ;f = indexL b x * 100 + 40
->     ;o = saw AR (f * mce2 1 1.1) * 0.1}
-> in audition (out 0 o)
-
-detectIndex example using local buffer
-
-> let {b = asLocalBuf 'α' [2,3,4,0,1,5]
->     ;n = bufFrames KR b
->     ;x = floorE (mouseX KR 0 n Linear 0.1)
->     ;i = detectIndex b x}
-> in audition (out 0 (sinOsc AR (linExp i 0 n 200 700) 0 * 0.1))
-
-degreeToKey example ('modal space') using local buffer
-
-> let {n = lfNoise1 'α' KR (mce [3,3.05])
->     ;x = mouseX KR 0 15 Linear 0.1
->     ;b = asLocalBuf 'β' [0,2,3.2,5,7,9,10]
->     ;k = degreeToKey b x 12
->     ;mk_c bf = let {f0 = midiCPS (bf + k + n * 0.04)
->                    ;o = sinOsc AR f0 0 * 0.1
->                    ;f1 = midiCPS (mce [48,55])
->                    ;t = lfPulse AR f1 0.15 0.5
->                    ;f2 = midiCPS (sinOsc KR 0.1 0 * 10 + bf)
->                    ;d = rlpf t f2 0.1 * 0.1
->                    ;m = o + d}
->                 in combN m 0.31 0.31 2 + m}
-> in audition (out 0 ((mk_c 48 + mk_c 72) * 0.25))
diff --git a/Help/UGen/IO/localOut.help.lhs b/Help/UGen/IO/localOut.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/localOut.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LocalOut"
-> Sound.SC3.UGen.DB.ugenSummary "LocalOut"
-
-> import Sound.SC3.ID
-
-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)}
-> in audition (mrg [offsetOut 0 p,localOut d])
-
-Compare with oscillator.
-
-> audition (out 1 (sinOsc AR 440 0 * 0.2))
diff --git a/Help/UGen/IO/mouseButton.help.lhs b/Help/UGen/IO/mouseButton.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/mouseButton.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MouseButton"
-> Sound.SC3.UGen.DB.ugenSummary "MouseButton"
-
-> import Sound.SC3
-
-As amplitude envelope
-
-> audition (out 0 (sinOsc AR 800 0 * mouseButton KR 0 0.1 0.1))
-
-There is a variant that randomly presses the button.
-
-> audition (out 0 (sinOsc AR 800 0 * mouseButton' KR 0 0.1 0.1))
diff --git a/Help/UGen/IO/mouseX.help.lhs b/Help/UGen/IO/mouseX.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/mouseX.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MouseX"
-> Sound.SC3.UGen.DB.ugenSummary "MouseX"
-
-> import Sound.SC3
-
-Frequency control
-
-> let x = mouseX KR 40 10000 Exponential 0.2
-> in audition (out 0 (sinOsc AR x 0 * 0.1))
-
-There is a variant with equal arguments but random traversal.
-
-> 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
deleted file mode 100644
--- a/Help/UGen/IO/mouseY.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MouseY"
-> Sound.SC3.UGen.DB.ugenSummary "MouseY"
-
-> import Sound.SC3
-
-Frequency at X axis and amplitude at Y axis.
-
-> 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))
-
-There is a variant with equal arguments but a random traversal.
-
-> 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
deleted file mode 100644
--- a/Help/UGen/IO/offsetOut.help.lhs
+++ /dev/null
@@ -1,31 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "OffsetOut"
-> Sound.SC3.UGen.DB.ugenSummary "OffsetOut"
-
-> import Sound.SC3
-
-> 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) }
-> in audition (mrg [a,b])
-
-> import Sound.OSC
-
-Phase cancellation, the 'offsetOut' at bus 0 cancels, the 'out'
-at bus 1 doesn't (or at least is exceedingly unlikely to).
-
-> let a = do
->       {t <- time
->       ;sr <- serverSampleRateActual
->       ;let {f = sr / 100
->            ;c = 1 / f
->            ;g = let o = sinOsc AR (constant f) 0 * 0.2
->                 in synthdef "g" (mrg [offsetOut 0 o,out 1 o])
->            ;m = s_new "g" (-1) AddToTail 1 []
->            ;p = bundle (t + 0.1) [m]
->            ;q = bundle (t + 0.1 + c/2) [m]}
->       ;_ <- async (d_recv g)
->       ;mapM_ sendBundle [p,q]}
-> in withSC3 a
diff --git a/Help/UGen/IO/out.help.lhs b/Help/UGen/IO/out.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/out.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Out"
-> Sound.SC3.UGen.DB.ugenSummary "Out"
-
-> import Sound.SC3
-
-Oscillators at outputs zero (330) and one (331)
-
-> audition (out 0 (sinOsc AR (mce2 330 331) 0 * 0.1))
-
-out is summing, as opposed to replaceOut
-
-> audition (mrg [out 0 (sinOsc AR (mce2 330 990) 0 * 0.1)
->               ,out 0 (sinOsc AR (mce2 331 991) 0 * 0.1)])
diff --git a/Help/UGen/IO/replaceOut.help.lhs b/Help/UGen/IO/replaceOut.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/replaceOut.help.lhs
+++ /dev/null
@@ -1,29 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "ReplaceOut"
-> Sound.SC3.UGen.DB.ugenSummary "ReplaceOut"
-
-> import Sound.SC3.ID
-
-> audition (replaceOut 0 (sinOsc AR 440 0 * 0.1))
-
-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)}
-> 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)}
-> in audition (mrg [a, b, c])
-
-a writes noise to 24
-b reads 24 and replaces with filtered variant
-c reads 24 and writes to 0
-
-> let {a = out 24 (pinkNoise 'a' AR * 0.1)
->     ;b = replaceOut 24 (bpf (in' 1 AR 24) 440 1)
->     ;c = out 0 (in' 1 AR 24)}
-> in mapM_ audition [a,b,c]
diff --git a/Help/UGen/IO/soundIn.help.lhs b/Help/UGen/IO/soundIn.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/soundIn.help.lhs
+++ /dev/null
@@ -1,21 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SoundIn"
-
-# composite of in' and numOutputBuses
-
-> import Sound.SC3
-
-Copy 5th input channel (index 4) to 1st output channel (index 0).
-
-> audition (out 0 (soundIn 4))
-
-Copy input from 4 & 5 to 0 & 1.
-
-> audition (out 0 (soundIn (mce2 4 5)))
-
-IO matrix:    0 1 2 3
-            0 *
-            1     *
-            2   *
-            3       *
-
-> audition (out 0 (soundIn (mce [0, 2, 1, 3])))
diff --git a/Help/UGen/IO/xOut.help.lhs b/Help/UGen/IO/xOut.help.lhs
deleted file mode 100644
--- a/Help/UGen/IO/xOut.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "XOut"
-> Sound.SC3.UGen.DB.ugenSummary "XOut"
-
-> import Sound.SC3
-
-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}
-> 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/controlDur.help.lhs b/Help/UGen/Information/controlDur.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/controlDur.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "ControlDur"
-> Sound.SC3.UGen.DB.ugenSummary "ControlDur"
-
-> import Sound.SC3
-
-controlRate and controlDur are reciprocals
-
-> let f = mce2 controlRate (recip controlDur)
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Information/controlRate.help.lhs b/Help/UGen/Information/controlRate.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/controlRate.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "ControlRate"
-> Sound.SC3.UGen.DB.ugenSummary "ControlRate"
-
-> import Sound.SC3
-
-play a sine tone at control rate, the reciprocal of controlDur
-
-> let f = mce2 controlRate (recip controlDur)
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Information/numAudioBuses.help.lhs b/Help/UGen/Information/numAudioBuses.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/numAudioBuses.help.lhs
+++ /dev/null
@@ -1,3 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "NumAudioBuses"
-> Sound.SC3.UGen.DB.ugenSummary "NumAudioBuses"
-
diff --git a/Help/UGen/Information/numBuffers.help.lhs b/Help/UGen/Information/numBuffers.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/numBuffers.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "NumBuffers"
-> Sound.SC3.UGen.DB.ugenSummary "NumBuffers"
-
-> import Sound.SC3
-
-the number of audio buffers available at the server (by default 1024)
-> audition (poll (impulse KR 1 0) numBuffers (label "numBuffers") 0)
-
-> let f = 110 + numBuffers
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Information/numControlBuses.help.lhs b/Help/UGen/Information/numControlBuses.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/numControlBuses.help.lhs
+++ /dev/null
@@ -1,2 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "NumControlBuses"
-> Sound.SC3.UGen.DB.ugenSummary "NumControlBuses"
diff --git a/Help/UGen/Information/numInputBuses.help.lhs b/Help/UGen/Information/numInputBuses.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/numInputBuses.help.lhs
+++ /dev/null
@@ -1,2 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "NumInputBuses"
-> Sound.SC3.UGen.DB.ugenSummary "NumInputBuses"
diff --git a/Help/UGen/Information/numOutputBuses.help.lhs b/Help/UGen/Information/numOutputBuses.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/numOutputBuses.help.lhs
+++ /dev/null
@@ -1,2 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "NumOutputBuses"
-> Sound.SC3.UGen.DB.ugenSummary "NumOutputBuses"
diff --git a/Help/UGen/Information/numRunningSynths.help.lhs b/Help/UGen/Information/numRunningSynths.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/numRunningSynths.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "NumRunningSynths"
-> Sound.SC3.UGen.DB.ugenSummary "NumRunningSynths"
-
-> import Sound.SC3
-
-each concurrent audition increases oscillator frequency
-> audition (out 0 (sinOsc AR (numRunningSynths * 200 + 400) 0 * 0.1))
diff --git a/Help/UGen/Information/poll.help.lhs b/Help/UGen/Information/poll.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/poll.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Poll"
-> Sound.SC3.UGen.DB.ugenSummary "Poll"
-
-> import Sound.SC3.ID {- hsc3 -}
-
-> let {t = impulse KR 10 0
->     ;l = line KR 0 1 1 RemoveSynth}
-> in audition (poll t l (label "polling...") 0)
-
-multichannel expansion (requires labels be equal length...)
-
-> let {t = impulse KR (mce2 10 5) 0
->     ;l = line KR 0 (mce2 1 5) (mce2 1 2) DoNothing}
-> in audition (poll t l (mce2 (label "t1") (label "t2")) 0)
diff --git a/Help/UGen/Information/radiansPerSample.help.lhs b/Help/UGen/Information/radiansPerSample.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/radiansPerSample.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RadiansPerSample"
-> Sound.SC3.UGen.DB.ugenSummary "RadiansPerSample"
-
-> import Sound.SC3
-
-two pi divided by the nominal sample rate (ie. a very small number)
-> let f = mce2 radiansPerSample ((2 * pi) / sampleRate) * 5e6
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Information/sampleDur.help.lhs b/Help/UGen/Information/sampleDur.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/sampleDur.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SampleDur"
-> Sound.SC3.UGen.DB.ugenSummary "SampleDur"
-
-> import Sound.SC3
-
-the reciprocal of the nominal sample rate of the server
-
-> let f = mce2 sampleRate (recip sampleDur) * 0.01
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/Information/sampleRate.help.lhs b/Help/UGen/Information/sampleRate.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/sampleRate.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SampleRate"
-> Sound.SC3.UGen.DB.ugenSummary "SampleRate"
-
-> import Sound.SC3
-
-the current nominal sample rate of the server
-
-> let {sr = 48000 {- 44100 -}
->     ;f = mce2 sampleRate sr * 0.01}
-> in audition (out 0 (sinOsc AR f 0 * 0.1))
-
-The server status command can extract nominal and actual sample rates
-from a running server.
-
-> import Control.Monad
-
-> withSC3 (liftM2 (,) serverSampleRateNominal serverSampleRateActual)
diff --git a/Help/UGen/Information/subsampleOffset.help.lhs b/Help/UGen/Information/subsampleOffset.help.lhs
deleted file mode 100644
--- a/Help/UGen/Information/subsampleOffset.help.lhs
+++ /dev/null
@@ -1,30 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SubsampleOffset"
-> Sound.SC3.UGen.DB.ugenSummary "SubsampleOffset"
-
-> import Sound.OSC
-> import Sound.SC3
-
-Impulse train that can be moved between samples
-> let g = 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))}
->         in (synthdef "s" (offsetOut 0 r))
-
-Create two pulse trains one sample apart, move one relative to the
-other.  When cursor is at the left, the impulses are adjacent, on the
-right, they are exactly 1 sample apart.  View this with an
-oscilloscope.
-> let run s = do
->       {_ <- async (d_recv s)
->       ;t <- time
->       ;sr <- serverSampleRateActual
->       ;let {t' = t + 0.2
->            ;dt = 1 / sr
->            ;m n = s_new "s" (-1) AddToTail 1 [("a", n)]}
->        in do {sendBundle (bundle t' [m 3])
->              ;sendBundle (bundle (t' + dt) [m 0]) }}
-
-> withSC3 (run g)
diff --git a/Help/UGen/MachineListening/beatTrack.help.lhs b/Help/UGen/MachineListening/beatTrack.help.lhs
deleted file mode 100644
--- a/Help/UGen/MachineListening/beatTrack.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BeatTrack"
-> Sound.SC3.UGen.DB.ugenSummary "BeatTrack"
-
-> import Sound.SC3
-
-> let { i = soundIn 0
->     ; x = mouseX KR (-1) 1 Linear 0.2
->     ; MCE [b, h, q, t] = beatTrack (fft' 10 i) x
->     ; f = mce [440, 660, 880]
->     ; a = mce [0.4, 0.2, 0.1]
->     ; s = mix (sinOsc AR f 0 * a * decay (mce [b, h, q]) 0.05) }
-> in withSC3 (do {_ <- async (b_alloc 10 1024 1)
->                ;play (out 0 (i + s))})
-
-
diff --git a/Help/UGen/MachineListening/loudness.help.lhs b/Help/UGen/MachineListening/loudness.help.lhs
deleted file mode 100644
--- a/Help/UGen/MachineListening/loudness.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Loudness"
-> Sound.SC3.UGen.DB.ugenSummary "Loudness"
-
-> import Sound.SC3
-
-Assume hop of half fftsize
-> withSC3 (async (b_alloc 10 1024 1))
-
-> let { x = mouseX KR 0.001 0.1 Exponential 0.2
->     ; i = sinOsc AR 1000 0 * x
->     ; f = fft' 10 i
->     ; l = loudness f 0.25 6
->     ; o = sinOsc AR (mce2 900 (l * 300 + 600)) 0 * 0.1 }
-> in audition (out 0 o)
diff --git a/Help/UGen/MachineListening/onsets.help.lhs b/Help/UGen/MachineListening/onsets.help.lhs
deleted file mode 100644
--- a/Help/UGen/MachineListening/onsets.help.lhs
+++ /dev/null
@@ -1,34 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Onsets"
-> Sound.SC3.UGen.DB.ugenSummary "Onsets"
-
-> import Sound.SC3.ID
-
-allocate buffer 10
-> withSC3 (async (b_alloc 10 512 1))
-
-> let { x = mouseX KR 0 1 Linear 0.2
->     ; i = soundIn 4
->     ; c = fft' 10 i
->     ; o = onsets' c x (onsetType "rcomplex")
->     ; s = sinOsc AR 440 0 * 0.2
->     ; e = envGen KR o 1 0 1 DoNothing (envPerc 0.001 0.1) }
-> in audition (out 0 (s * e))
-
-> audition (out 0 (soundIn 0 * 0.1))
-
-a generative signal with distinct onsets!
-> let z = let {e = linLin (saw AR 2) (-1) 1 0 1
->             ;p = let f = midiCPS (tIRand 'a' 63 75 (impulse KR 2 0))
->                  in pulse AR f 0.5
->             ;f = linExp (lfNoise2 'a' KR 0.5) (-1) 1 100 10000}
->         in lpf p f * e
-
-> audition (out 0 z)
-
-x varies threshold, whitenoise bursts indicate detected onsets
-> let {c = fft' 10 z
->     ;x = mouseX KR 0 1 Linear 0.2
->     ;o = onsets' c x (onsetType "rcomplex")
->     ;p = let d = envPerc 0.001 0.1
->          in whiteNoise 'a' AR * envGen KR o 0.2 0 1 DoNothing d}
-> in audition (out 0 (pan2 z (-0.75) 0.2 + pan2 p 0.75 1))
diff --git a/Help/UGen/MachineListening/specCentroid.help.lhs b/Help/UGen/MachineListening/specCentroid.help.lhs
deleted file mode 100644
--- a/Help/UGen/MachineListening/specCentroid.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SpecCentroid"
-> Sound.SC3.UGen.DB.ugenSummary "SpecCentroid"
-
-> import Sound.SC3
-
-as the number of harmonics increases, the centroid is pushed higher
-> let {f0 = mouseY KR 1000 100 Exponential 0.2
->     ;nh = mouseX KR 1 100 Exponential 0.2
->     ;z = blip AR f0 nh
->     ;f = fft' (localBuf 'α' 2048 1) z
->     ;c = specCentroid f
->     ;p = poll' (impulse KR 1 0) c (label "c") 0
->     ;o = sinOsc AR p 0 * 0.1}
-> in audition (out 0 o)
diff --git a/Help/UGen/MachineListening/specFlatness.help.lhs b/Help/UGen/MachineListening/specFlatness.help.lhs
deleted file mode 100644
--- a/Help/UGen/MachineListening/specFlatness.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SpecFlatness"
-> Sound.SC3.UGen.DB.ugenSummary "SpecFlatness"
-
-> import Sound.SC3.ID
-
-> let {z = soundIn 4
->     ;g = 1 {- gain, set as required -}
->     ;a = wAmp KR z 0.05
->     ;f = fft' (localBuf 'α' 2048 1) z
->     ;c = poll' 1 (specCentroid f) (label "c") 0
->     ;w = poll' 1 (specFlatness f) (label "w") 0
->     ;o = bpf (pinkNoise 'a' AR) c w * a * g}
-> in audition (out 0 o)
diff --git a/Help/UGen/Math/abs.help.lhs b/Help/UGen/Math/abs.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/abs.help.lhs
+++ /dev/null
@@ -1,6 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.abs"
-> :t abs
-
-> import Sound.SC3
-
-> audition (out 0 (abs (syncSaw AR 100 440 * 0.1)))
diff --git a/Help/UGen/Math/absDif.help.lhs b/Help/UGen/Math/absDif.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/absDif.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.absdif"
-> :t absDif
-
-> import Sound.SC3
-
-Finding the magnitude of the difference of two values is a common operation.
-> let {p = fSinOsc AR 440 0
->     ;q = fSinOsc AR 2 0 * 0.5}
-> in audition (out 0 (p * 0.2 `absDif` q))
diff --git a/Help/UGen/Math/add.help.lhs b/Help/UGen/Math/add.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/add.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.+"
-> :t (+)
-
-> import Sound.SC3.ID
-
-> let { o = fSinOsc AR 800 0
->     ; n = pinkNoise 'a' AR }
-> in audition (out 0 ((o + n) * 0.1))
-
-DC offset.
-> audition (out 0 ((fSinOsc AR 440 0 * 0.1) + 0.5))
diff --git a/Help/UGen/Math/amClip.help.lhs b/Help/UGen/Math/amClip.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/amClip.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.amclip"
-> :t amClip
-
-> import Sound.SC3.ID
-
-> let n = whiteNoise 'a' AR
-> in 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
deleted file mode 100644
--- a/Help/UGen/Math/atan2.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.atan2"
-> :t atan2
-
-> import Sound.SC3
-
-Add a pan to the hypot doppler examples by using atan2 to find the
-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 = 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/clip2.help.lhs b/Help/UGen/Math/clip2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/clip2.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.clip2"
-> :t clip2
-
-> import Sound.SC3
-
-clipping distortion
-> audition (out 0 (clip2 (fSinOsc AR 400 0) 0.2))
-
-> let l = line KR 0 1 8 RemoveSynth
-> in audition (out 0 (clip2 (fSinOsc AR 400 0) l))
diff --git a/Help/UGen/Math/dbAmp.help.lhs b/Help/UGen/Math/dbAmp.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/dbAmp.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.dbamp"
-> :t dbAmp
-
-> import Sound.SC3
-
-Linear db motion is exponential amplitude decay
-> let {a = dbAmp (line KR (-6) (-40) 10 RemoveSynth)
->     ;o = fSinOsc AR 800 0 * a}
-> in audition (out 0 o)
-
-There is a non-UGen variant.
-> dbAmp (-26::Double)
diff --git a/Help/UGen/Math/difSqr.help.lhs b/Help/UGen/Math/difSqr.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/difSqr.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.difsqr"
-> :t difSqr
-
-> import Sound.SC3
-
-> 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 }
-> 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
deleted file mode 100644
--- a/Help/UGen/Math/distort.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.distort"
-> :t distort
-
-> import Sound.SC3
-
-> 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/eq.help.lhs b/Help/UGen/Math/eq.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/eq.help.lhs
+++ /dev/null
@@ -1,2 +0,0 @@
-See gt (>)
-
diff --git a/Help/UGen/Math/excess.help.lhs b/Help/UGen/Math/excess.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/excess.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.excess"
-> :t excess
-
-> import Sound.SC3
-
-> let { o = fSinOsc AR 1000 0
->     ; l = line KR 0 1 8 DoNothing }
-> in audition (out 0 (excess o l))
-
-or written out in terms of clip2
-> let { o = fSinOsc AR 1000 0
->     ; l = line KR 0 1 8 DoNothing }
-> in audition (out 0 (o - (clip2 o l)))
diff --git a/Help/UGen/Math/fdiv.help.lhs b/Help/UGen/Math/fdiv.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/fdiv.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator./"
-> :t (/)
-
-> import Sound.SC3.ID
-
-> let { o = fSinOsc KR 10 0.5
->     ; n = pinkNoise 'a' AR }
-> in audition (out 0 ((n * 0.1) / (o * 0.75)))
diff --git a/Help/UGen/Math/fold2.help.lhs b/Help/UGen/Math/fold2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/fold2.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.fold2"
-> :t fold2
-
-> import Sound.SC3
-
-> let { o = fSinOsc AR 1000 0
->     ; l = line KR 0 1 8 DoNothing }
-> in audition (out 0 (fold2 o l))
diff --git a/Help/UGen/Math/gt.help.lhs b/Help/UGen/Math/gt.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/gt.help.lhs
+++ /dev/null
@@ -1,20 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.=="
-> :t (==*)
-
-The star suffixes (<*,<=*,>*,>=*) are because the result of the
-operators is not of type Bool, as is required by the signature for the
-class Ord.
-
-> import Sound.SC3
-
-> let { o = sinOsc KR 1 0
->     ; t = [o >* 0
->           ,o >=* 0
->           ,o <* 0
->           ,o <=* 0
->           ,o ==* 0
->           ,(o <* 0.001) * (o >* (-0.001))]
->     ; f = [220, 330, 440, 550, 660, 770]
->     ; p = envPerc 0.01 1
->     ; e = envGen KR (mce t) 0.1 0 1 DoNothing p }
-> in audition (out 0 (mix (sinOsc AR (mce f) 0 * e)))
diff --git a/Help/UGen/Math/hypot.help.lhs b/Help/UGen/Math/hypot.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/hypot.help.lhs
+++ /dev/null
@@ -1,25 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.hypot"
-> :t hypot
-
-> import Sound.SC3
-
-> 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) }
-> 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 }
-> in audition (out 0 (delayL s (110 / 344) (d / 344) * a))
diff --git a/Help/UGen/Math/max.help.lhs b/Help/UGen/Math/max.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/max.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.max"
-> :t max
-
-> import Sound.SC3
-
-q modulates and envelopes p
-> let { p = fSinOsc AR 500 0 * 0.25
->     ; q = fSinOsc AR 0.5 0 }
-> in audition (out 0 (p `max` q))
diff --git a/Help/UGen/Math/mod.help.lhs b/Help/UGen/Math/mod.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/mod.help.lhs
+++ /dev/null
@@ -1,6 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.%"
-> :t modE
-
-> import Sound.SC3
-
-> audition (out 0 (fSinOsc AR 100 4 `modE` 1))
diff --git a/Help/UGen/Math/mul.help.lhs b/Help/UGen/Math/mul.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/mul.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.*"
-> :t (*)
-
-> import Sound.SC3.ID
-
-> audition (out 0 (sinOsc AR 440 0 * 0.5))
-
-Creates a beating effect (subaudio rate).
-> let n = pinkNoise 'a' AR
-> in audition (out 0 (fSinOsc kr 10 0 * n * 0.5))
-
-Ring modulation.
-> let { p = sinOsc AR (xLine KR 100 1001 10 DoNothing) 0
->     ; q = syncSaw AR 100 200 }
-> in audition (out 0 (p * q * 0.25))
diff --git a/Help/UGen/Math/pow.help.lhs b/Help/UGen/Math/pow.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/pow.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.**"
-> :t (**)
-
-> import Sound.SC3.Monadic
-
-> let a = fSinOsc AR 100 0 * 0.1
-> in audition (out 0 (mce2 a (a ** 10)))
-
-http://create.ucsb.edu/pipermail/sc-users/2006-December/029998.html
-> 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.5) Exponential 0.1
->          ; y = mouseY KR 1 24 Exponential 0.1
->          ; d = latch s (impulse AR x 0)
->          ; b = roundUp d (0.5 ** y) }
->      in audition (out 0 (mce2 d b)) }
diff --git a/Help/UGen/Math/ring1.help.lhs b/Help/UGen/Math/ring1.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/ring1.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.ring1"
-> :t ring1
-
-> import Sound.SC3
-
-> 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))
-
-is equivalent to:
-> let { a = fSinOsc AR 800 0
->     ; b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0 }
-> in audition (out 0 (((a * b) + a) * 0.125))
diff --git a/Help/UGen/Math/roundUp.help.lhs b/Help/UGen/Math/roundUp.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/roundUp.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.round"
-> :t roundUp
-
-> import Sound.SC3
-
-> let { x = mouseX KR 60 4000 Linear 0.1
->     ; f = roundUp x 100 }
-> in audition (out 0 (sinOsc ar f 0 * 0.1))
-
-> let n = line KR 24 108 6 RemoveSynth
-> in audition (out 0 (saw AR (midiCPS (roundUp n 1)) * 0.2))
diff --git a/Help/UGen/Math/scaleNeg.help.lhs b/Help/UGen/Math/scaleNeg.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/scaleNeg.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.scaleneg"
-> :t scaleNeg
-
-> import Sound.SC3
-
-> let {o = fSinOsc AR 1000 0
->     ;l = line AR 1 (-1) 4 RemoveSynth}
-> in audition (out 0 (scaleNeg o l))
-
-written out:
-> let {o = fSinOsc AR 1000 0
->     ;l = line AR 1 (-1) 4 RemoveSynth
->     ;c = o <* 0}
-> in audition (out 0 (c * (o * l) + (1 - c) * o))
diff --git a/Help/UGen/Math/softClip.help.lhs b/Help/UGen/Math/softClip.help.lhs
deleted file mode 100644
--- a/Help/UGen/Math/softClip.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.softclip"
-> :t softClip
-
-> import Sound.SC3
-
-> let {e = xLine KR 0.1 10 10 RemoveSynth
->     ;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
deleted file mode 100644
--- a/Help/UGen/Math/sumSqr.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.sumsqr"
-> :t sumSqr
-
-> import Sound.SC3
-
-> 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 }
-> 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
deleted file mode 100644
--- a/Help/UGen/Math/thresh.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Operator.thresh"
-> :t thresh
-
-> import Sound.SC3.ID
-
-low-rent gate
-> let n = lfNoise0 'a' AR 50 * 0.5
-> in audition (out 0 (thresh n 0.45))
diff --git a/Help/UGen/Noise/brownNoise.help.lhs b/Help/UGen/Noise/brownNoise.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/brownNoise.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BrownNoise"
-> Sound.SC3.UGen.DB.ugenSummary "BrownNoise"
-
-> import Sound.SC3.ID
-
-> let n = brownNoise 'α' AR
-> in audition (out 0 (n * 0.1))
-
-> let {n = brownNoise 'α' KR
->     ;o = sinOsc AR (linExp n (-1) 1 64 9600) 0 * 0.1}
-> in audition (out 0 o)
-
diff --git a/Help/UGen/Noise/choose.help.lhs b/Help/UGen/Noise/choose.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/choose.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> :t choose
-
-# choose is a composite of iRand and select.
-
-> import Sound.SC3.ID
-
-> let f = uclone 'a' 2 (choose 'a' (mce [440,460 .. 880]))
-> in audition (out 0 (sinOsc AR f  0 * 0.1))
diff --git a/Help/UGen/Noise/clipNoise.help.lhs b/Help/UGen/Noise/clipNoise.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/clipNoise.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "ClipNoise"
-> Sound.SC3.UGen.DB.ugenSummary "ClipNoise"
-
-> import Sound.SC3
-> import qualified Sound.SC3.Monadic as M
-
-> audition . (out 0) . (* 0.1) =<< M.clipNoise AR
-> audition . (out 0) . (* 0.1) =<< M.whiteNoise AR
diff --git a/Help/UGen/Noise/coinGate.help.lhs b/Help/UGen/Noise/coinGate.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/coinGate.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "CoinGate"
-> Sound.SC3.UGen.DB.ugenSummary "CoinGate"
-
-> import Sound.SC3.ID
-
-> let {g = coinGate 'a' 0.2 (impulse KR 10 0)
->     ;f = tRand 'b' 300.0 400.0 g}
-> in 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
deleted file mode 100644
--- a/Help/UGen/Noise/dust.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dust"
-> Sound.SC3.UGen.DB.ugenSummary "Dust"
-
-> import Sound.SC3.ID
-
-> audition (out 0 (dust 'a' AR 200 * 0.25))
-
-> let d = xLine KR 20000 2 10 RemoveSynth
-> in audition (out 0 (dust 'a' AR d * 0.15))
-
-Illustrate monadic constructor
-> import qualified Sound.SC3.Monadic as M
-
-> audition . (out 0) . (* 0.25) =<< M.dust AR 200
-
-> let d = xLine KR 20000 2 10 RemoveSynth
-> in audition . (out 0) . (* 0.15) =<< M.dust AR d
diff --git a/Help/UGen/Noise/dust2.help.lhs b/Help/UGen/Noise/dust2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/dust2.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dust2"
-> Sound.SC3.UGen.DB.ugenSummary "Dust2"
-
-> import Sound.SC3.ID
-
-> let n = dust2 'a' AR 200
-> in audition (out 0 (n * 0.5))
-
-> let d = xLine KR 20000 2 10 RemoveSynth
-> in audition (out 0 (dust2 'b' AR d * 0.15))
diff --git a/Help/UGen/Noise/expRand.help.lhs b/Help/UGen/Noise/expRand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/expRand.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "ExpRand"
-> Sound.SC3.UGen.DB.ugenSummary "ExpRand"
-
-> import Sound.SC3.ID
-
-> let {a = line KR 0.5 0 0.01 RemoveSynth
->     ;f = expRand 'a' 100.0 8000.0}
-> in audition (out 0 (fSinOsc AR f 0 * a))
diff --git a/Help/UGen/Noise/grayNoise.help.lhs b/Help/UGen/Noise/grayNoise.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/grayNoise.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "GrayNoise"
-> Sound.SC3.UGen.DB.ugenSummary "GrayNoise"
-
-> import Sound.SC3
-> import qualified Sound.SC3.Monadic as M
-
-> audition . (out 0) . (* 0.1) =<< M.grayNoise AR
diff --git a/Help/UGen/Noise/iRand.help.lhs b/Help/UGen/Noise/iRand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/iRand.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "IRand"
-> Sound.SC3.UGen.DB.ugenSummary "IRand"
-
-> import Sound.SC3.ID
-
-> let {f = iRand 'a' 200 1200
->     ;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
deleted file mode 100644
--- a/Help/UGen/Noise/lfClipNoise.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFClipNoise"
-> Sound.SC3.UGen.DB.ugenSummary "LFClipNoise"
-
-> import Sound.SC3.ID
-> import qualified Sound.SC3.Monadic as M
-
-> audition . (out 0) . (* 0.05) =<< M.lfClipNoise AR 1000
-
-Modulate frequency
-> let f = xLine KR 1000 10000 10 RemoveSynth
-> in audition . (out 0) . (* 0.05) =<< M.lfClipNoise AR f
-
-Use as frequency control
-> let n = lfClipNoise 'a' KR 4
-> in 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
deleted file mode 100644
--- a/Help/UGen/Noise/lfNoise0.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFNoise0"
-> Sound.SC3.UGen.DB.ugenSummary "LFNoise0"
-
-> import Sound.SC3.ID
-> import qualified Sound.SC3.Monadic as M
-
-> audition . (out 0) . (* 0.05) =<< M.lfNoise0 AR 1000
-
-Modulate frequency.
-> let {f = xLine KR 1000 10000 10 RemoveSynth
->     ;n = lfNoise0 'a' AR f}
-> in audition (out 0 (n * 0.05))
-
-Use as frequency control.
-> let f = lfNoise0 'a' KR 4
-> in audition (out 0 (sinOsc AR (f * 400 + 450) 0 * 0.1))
diff --git a/Help/UGen/Noise/lfNoise1.help.lhs b/Help/UGen/Noise/lfNoise1.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/lfNoise1.help.lhs
+++ /dev/null
@@ -1,18 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFNoise1"
-> Sound.SC3.UGen.DB.ugenSummary "LFNoise1"
-
-> import Sound.SC3.ID
-
-> audition (out 0 (lfNoise1 'α' AR 1000 * 0.05))
-
-Modulate frequency.
-
-> let {f = xLine KR 1000 10000 10 RemoveSynth
->     ;n = lfNoise1 'α' AR f}
-> in audition (out 0 (n * 0.05))
-
-Use as frequency control.
-
-> let {n = lfNoise1 'α' KR 4
->     ;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
deleted file mode 100644
--- a/Help/UGen/Noise/lfNoise2.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFNoise2"
-> Sound.SC3.UGen.DB.ugenSummary "LFNoise2"
-
-> import Sound.SC3.ID
-> import qualified Sound.SC3.Monadic as M
-
-> audition . (out 0) . (* 0.05) =<< M.lfNoise2 AR 1000
-
-Modulate frequency.
-> let {f = xLine KR 1000 10000 10 RemoveSynth
->     ;n = lfNoise2 'a' AR f}
-> in audition (out 0 (n * 0.05))
-
-Use as frequency control.
-> let f = lfNoise2 'a' KR 4
-> in 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
deleted file mode 100644
--- a/Help/UGen/Noise/lfdClipNoise.help.lhs
+++ /dev/null
@@ -1,21 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFDClipNoise"
-> Sound.SC3.UGen.DB.ugenSummary "LFDClipNoise"
-
-> import Sound.SC3.ID
-> import qualified Sound.SC3.Monadic as M
-
-for fast x lfClipNoise frequently seems stuck, lfdClipNoise changes smoothly
-> let {x = mouseX KR 0.1 1000 Exponential 0.2
->     ;n = lfdClipNoise 'a' AR x}
-> in audition (out 0 (sinOsc AR (n * 200 + 500) 0 * 0.05))
-
-> let {x = mouseX KR 0.1 1000 Exponential 0.2
->     ;n = lfClipNoise 'a' AR x}
-> in 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
-> in audition . (out 0) . (* 0.05) =<< M.lfdClipNoise AR f
-
-> let f = xLine KR 1000 20000 10 RemoveSynth
-> in audition . (out 0) . (* 0.05) =<< M.lfClipNoise AR f
diff --git a/Help/UGen/Noise/lfdNoise0.help.lhs b/Help/UGen/Noise/lfdNoise0.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/lfdNoise0.help.lhs
+++ /dev/null
@@ -1,26 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFDNoise0"
-> Sound.SC3.UGen.DB.ugenSummary "LFDNoise0"
-
-> import Sound.SC3
-> import qualified Sound.SC3.Monadic as M
-
-for fast x LFNoise frequently seems stuck, LFDNoise changes smoothly
-> let x = mouseX KR 0.1 1000 Exponential 0.2
-> in audition . (out 0) . (* 0.1) =<< M.lfdNoise0 AR x
-
-> let x = mouseX KR 0.1 1000 Exponential 0.2
-> in audition . (out 0) . (* 0.1) =<< M.lfNoise0 AR x
-
-silent for 2 secs before going up in freq
-> let f = xLine KR 0.5 10000 3 RemoveSynth
-> in audition . (out 0) . (* 0.1) =<< M.lfdNoise0 AR f
-
-> let f = xLine KR 0.5 10000 3 RemoveSynth
-> in audition . (out 0) . (* 0.1) =<< M.lfNoise0 AR f
-
-LFNoise quantizes time steps at high freqs, LFDNoise does not:
-> let f = xLine KR 1000 20000 10 RemoveSynth
-> in audition . (out 0) . (* 0.1) =<< M.lfdNoise0 AR f
-
-> let f = xLine KR 1000 20000 10 RemoveSynth
-> in audition . (out 0) . (* 0.1) =<< M.lfNoise0 AR f
diff --git a/Help/UGen/Noise/lfdNoise1.help.lhs b/Help/UGen/Noise/lfdNoise1.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/lfdNoise1.help.lhs
+++ /dev/null
@@ -1,4 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFDNoise1"
-> Sound.SC3.UGen.DB.ugenSummary "LFDNoise1"
-
-See lfdNoise0
diff --git a/Help/UGen/Noise/lfdNoise3.help.lhs b/Help/UGen/Noise/lfdNoise3.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/lfdNoise3.help.lhs
+++ /dev/null
@@ -1,4 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFDNoise3"
-> Sound.SC3.UGen.DB.ugenSummary "LFDNoise3"
-
-See lfdNoise0
diff --git a/Help/UGen/Noise/linRand.help.lhs b/Help/UGen/Noise/linRand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/linRand.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LinRand"
-> Sound.SC3.UGen.DB.ugenSummary "LinRand"
-
-> import Sound.SC3.ID
-
-> let {f = linRand 'a' 200.0 10000.0 (mce [-1, 1])
->     ;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
deleted file mode 100644
--- a/Help/UGen/Noise/nRand.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "NRand"
-> Sound.SC3.UGen.DB.ugenSummary "NRand"
-
-> import Sound.SC3.ID
-
-> let {n = nRand 'a' 1200.0 4000.0 (mce [2,5])
->     ;e = line KR 0.2 0 0.1 RemoveSynth}
-> in audition (out 0 (fSinOsc AR n 0 * e))
diff --git a/Help/UGen/Noise/pinkNoise.help.lhs b/Help/UGen/Noise/pinkNoise.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/pinkNoise.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PinkNoise"
-> Sound.SC3.UGen.DB.ugenSummary "PinkNoise"
-
-> import Sound.SC3.Monadic
-
-> audition . (out 0) . (* 0.05) =<< pinkNoise AR
-> audition . (out 0) . (* 0.05) =<< whiteNoise AR
-> audition . (out 0) . (* 0.05) =<< brownNoise AR
diff --git a/Help/UGen/Noise/rand.help.lhs b/Help/UGen/Noise/rand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/rand.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Rand"
-> Sound.SC3.UGen.DB.ugenSummary "Rand"
-
-> import Sound.SC3.ID
-
-> let {f = rand 'a' 200 1200
->     ;l = rand 'b' (-1) 1
->     ;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/randID.help.lhs b/Help/UGen/Noise/randID.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/randID.help.lhs
+++ /dev/null
@@ -1,2 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RandID"
-> Sound.SC3.UGen.DB.ugenSummary "RandID"
diff --git a/Help/UGen/Noise/randSeed.help.lhs b/Help/UGen/Noise/randSeed.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/randSeed.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RandSeed"
-> Sound.SC3.UGen.DB.ugenSummary "RandSeed"
-
-> import Sound.SC3.ID
-
-start a noise patch
-> let {n = uclone 'a' 2 (whiteNoise 'a' AR * 0.05 + dust2 'a' AR 70)
->     ;f = lfNoise1 'a' KR 3 * 5500 + 6000
->     ;r = resonz (n * 5) f 0.5 + n * 0.5}
-> in audition (out 0 r)
-
-reset the seed at a variable rate
-> let {s = control KR "seed" 1956
->     ;r = randSeed KR (impulse KR (mouseX KR 0.1 100 Linear 0.2) 0) s}
-> in audition r
-
-always the same (for a given seed)...
-> let {sd = 1957
->     ;n = tIRand 'a' 4 12 (dust 'a' KR 1)
->     ;f = n * 150 + (mce [0,1])
->     ;r = randSeed IR 1 sd}
-> in audition (out 0 (mrg2 (sinOsc AR f 0 * 0.1) r))
diff --git a/Help/UGen/Noise/tExpRand.help.lhs b/Help/UGen/Noise/tExpRand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/tExpRand.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TExpRand"
-> Sound.SC3.UGen.DB.ugenSummary "TExpRand"
-
-> import Sound.SC3.Monad
-
-> 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/tIRand.help.lhs b/Help/UGen/Noise/tIRand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/tIRand.help.lhs
+++ /dev/null
@@ -1,13 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TIRand"
-> Sound.SC3.UGen.DB.ugenSummary "TIRand"
-
-> import Sound.SC3
-> import qualified Sound.SC3.Monadic as M
-
-> do {l <- M.tIRand (-1) 1 =<< M.dust KR 10
->    ;n <- M.pinkNoise AR
->    ;audition (out 0 (pan2 (n * 0.1) l 1))}
-
-> do {n <- M.tIRand 4 12 =<< M.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/tRand.help.lhs b/Help/UGen/Noise/tRand.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/tRand.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TRand"
-> Sound.SC3.UGen.DB.ugenSummary "TRand"
-
-> import Sound.SC3.ID
-
-> let {t = dust 'α' KR (mce2 5 12)
->     ;f = tRand 'β' (mce2 200 1600) (mce2 500 3000) t}
-> in audition (out 0 (sinOsc AR f 0 * 0.2))
diff --git a/Help/UGen/Noise/whiteNoise.help.lhs b/Help/UGen/Noise/whiteNoise.help.lhs
deleted file mode 100644
--- a/Help/UGen/Noise/whiteNoise.help.lhs
+++ /dev/null
@@ -1,35 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "WhiteNoise"
-> Sound.SC3.UGen.DB.ugenSummary "WhiteNoise"
-
-> import Sound.SC3.ID
-
-> audition (out 0 (whiteNoise 'a' AR * 0.05))
-
-Random filtered noise bursts.
-> let {n = whiteNoise 'a' AR
->     ;t = dust 'a' AR (mce [3, 7])
->     ;f = tExpRand 'a' 20 1800 t
->     ;bw = tExpRand 'a' 0.001 1 t
->     ;e = decay2 t 0.01 0.2
->     ;r = resonz (n * e) f bw}
-> in audition (out 0 r)
-
-> import qualified Sound.SC3.Monadic as M
-
-Monadic form of above graph.
-> do {n <- M.whiteNoise AR
->    ;t <- M.dust AR (mce [3, 7])
->    ;f <- M.tExpRand 20 1800 t
->    ;bw <- M.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 again, without using do notation.
-> M.whiteNoise AR >>= \n ->
-> M.dust AR (mce [3, 7]) >>= \t ->
-> M.tExpRand 20 1800 t >>= \f ->
-> M.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/blip.help.lhs b/Help/UGen/Oscillator/blip.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/blip.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Blip"
-> Sound.SC3.UGen.DB.ugenSummary "Blip"
-
-> import Sound.SC3 {- hsc3 -}
-
-> audition (out 0 (blip AR 440 200 * 0.1))
-
-Modulate frequency
-
-> let f = xLine KR 20000 200 6 RemoveSynth
-> in audition (out 0 (blip AR f 100 * 0.1))
-
-Modulate number of harmonics.
-
-> let nh = line KR 1 100 20 RemoveSynth
-> in audition (out 0 (blip AR 200 nh * 0.2))
-
-Self-modulation at control rate.
-
-> let {fr = blip KR 0.25 3 * 300 + 500
->     ;nh = blip KR 0.15 2 * 20 + 21}
-> in audition (out 0 (blip AR fr nh * 0.2))
diff --git a/Help/UGen/Oscillator/cOsc.help.lhs b/Help/UGen/Oscillator/cOsc.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/cOsc.help.lhs
+++ /dev/null
@@ -1,23 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "COsc"
-> Sound.SC3.UGen.DB.ugenSummary "COsc"
-
-> import Sound.SC3
-
-Allocate and fill buffer.
-
-> let {f = [Normalise,Wavetable,Clear]
->     ;d = [1,1/2,1/3,1/4,1/5,1/6,1/7,1/8,1/9,1/10]}
-> in withSC3 ( do {_ <- async (b_alloc 10 512 1)
->                 ;async (b_gen_sine1 10 f d)})
-
-Fixed beat frequency
-
-> audition (out 0 (cOsc AR 10 200 0.7 * 0.1))
-
-Modulate beat frequency with mouseX
-
-> audition (out 0 (cOsc AR 10 200 (mouseX KR 0 4 Linear 0.2) * 0.1))
-
-Compare with plain osc
-
-> audition (out 0 (osc AR 10 200 0.0 * 0.1))
diff --git a/Help/UGen/Oscillator/dc.help.lhs b/Help/UGen/Oscillator/dc.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/dc.help.lhs
+++ /dev/null
@@ -1,24 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DC"
-> Sound.SC3.UGen.DB.ugenSummary "DC"
-
-> import Sound.SC3
-
-nothing
-
-> audition (out 0 0)
-> withSC3 (send (n_trace [-1]))
-
-zero
-
-> audition (out 0 (dc AR 0))
-
-DC offset; will click on start and finish
-
-> audition (out 0 (dc AR 0.5))
-> audition (out 0 (0.5 + sinOsc AR 440 0 * 0.1))
-> audition (out 0 (dc AR 0.5 + sinOsc AR 440 0 * 0.1))
-
-Transient before LeakDC adapts and suppresses the offset?
-
-> audition (out 0 (dc AR 1))
-> audition (out 0 (leakDC (dc AR 1) 0.995))
diff --git a/Help/UGen/Oscillator/dynKlang.help.lhs b/Help/UGen/Oscillator/dynKlang.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/dynKlang.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DynKlang"
-> Sound.SC3.UGen.DB.ugenSummary "DynKlang"
-
-> import Sound.SC3.ID {- hsc3 -}
-
-fixed
-
-> let s = klangSpec [800,1000,1200] [0.3,0.3,0.3] [pi,pi,pi]
-> in audition (out 0 (dynKlang AR 1 0 s * 0.4))
-
-fixed: randomised
-
-> let {f = map (\z -> rand z 600 1000) ['a'..'l']
->     ;s = klangSpec f (replicate 12 1) (replicate 12 0)}
-> in audition (out 0 (dynKlang AR 1 0 s * 0.05))
-
-dynamic: frequency modulation
-
-> let {f = mce3 800 1000 1200 + sinOsc KR (mce3 2 3 4.2) 0 * mce3 13 24 12
->     ;a = mce3 0.3 0.3 0.3
->     ;p = mce3 pi pi pi}
-> in audition (out 0 (dynKlang AR 1 0 (klangSpec_mce f a p) * 0.1))
diff --git a/Help/UGen/Oscillator/fSinOsc.help.lhs b/Help/UGen/Oscillator/fSinOsc.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/fSinOsc.help.lhs
+++ /dev/null
@@ -1,42 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FSinOsc"
-> Sound.SC3.UGen.DB.ugenSummary "FSinOsc"
-
-# SC2 did not have the initial phase argument.
-
-> import Sound.SC3
-
-> audition (out 0 (fSinOsc AR (mce2 440 550) 0 * 0.05))
-
-Modulate frequency
-
-> 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)
-> in audition (out 0 (fSinOsc AR (f 0 * 200 + 800) 0 * 0.1))
-
-sin grain with sine envelope (see also 'sine_grain_ugen_graph')
-
-> let sine = let {b = control IR "out" 0
->                ;f = control IR "freq" 440
->                ;d = control IR "dur" 0.2
->                ;a = control IR "amp" 0.1
->                ;p = control IR "pan" 0
->                ;o = fSinOsc AR f 0
->                ;s = envSine d a
->                ;e = envGen AR 1 1 0 1 RemoveSynth s
->                ;u = offsetOut b (pan2 o p e)}
->            in synthdef "sine" u
-
-> import Sound.SC3.Lang.Pattern {- hsc3-lang -}
-
-granular synthesis
-
-> audition (pbind [(K_instr,psynth sine)
->                 ,(K_midinote,fmap roundE (pbrown 'α' 72 84 1 inf))
->                 ,(K_detune,pwhite 'β' 0 10 inf)
->                 ,(K_dur,pbrown 'γ' 0.005 0.15 0.05 inf)
->                 ,(K_legato,pbrown 'δ' 1 2 0.1 inf)
->                 ,(K_amp,pbrown 'ε' 0.05 0.25 0.05 inf)
->                 ,(K_param "pan",pbrown 'ζ' (-1) 1 0.2 inf)])
diff --git a/Help/UGen/Oscillator/formant.help.lhs b/Help/UGen/Oscillator/formant.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/formant.help.lhs
+++ /dev/null
@@ -1,20 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Formant"
-> Sound.SC3.UGen.DB.ugenSummary "Formant"
-
-> import Sound.SC3
-
-Modulate fundamental frequency, formant frequency stays constant.
-
-> let f = xLine KR 400 1000 8 RemoveSynth
-> in audition (out 0 (formant AR f 2000 800 * 0.125))
-
-Modulate formant frequency, fundamental frequency stays constant.
-
-> let {f = mce [200, 300, 400, 500]
->     ;ff = xLine KR 400 4000 8 RemoveSynth}
-> in audition (out 0 (formant AR f ff 200 * 0.125))
-
-Modulate width frequency, other frequencies stay constant.
-
-> let bw = xLine KR 800 8000 8 RemoveSynth
-> in audition (out 0 (formant AR 400 2000 bw * 0.1))
diff --git a/Help/UGen/Oscillator/gendy1.help.lhs b/Help/UGen/Oscillator/gendy1.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/gendy1.help.lhs
+++ /dev/null
@@ -1,96 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Gendy1"
-> Sound.SC3.UGen.DB.ugenSummary "Gendy1"
-
-> import Sound.SC3.ID
-
-SC3 default parameters
-> let g = gendy1 AR 1 1 1 1 440 660 0.5 0.5 12 12
-> 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
-> 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}
-> 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}
-> 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
-> 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
-> 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}
-> 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
-> 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}
-> 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}
-> 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}
-> 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}
-> 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}
-> in audition (out 0 (pan2 g 0 0.2))
-
-Texture
-> let node e = let {f = rand e 130 160.3
->                  ;r0 = rand e 0 6
->                  ;r1 = rand (Data.Char.toUpper e) 0 6
->                  ;l = rand e (-1) 1
->                  ;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 pan2 o l 0.1
-> in audition (out 0 (mix (mce (map node ['a'..'i']))))
-
-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}
-> 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
deleted file mode 100644
--- a/Help/UGen/Oscillator/impulse.help.lhs
+++ /dev/null
@@ -1,19 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Impulse"
-> Sound.SC3.UGen.DB.ugenSummary "Impulse"
-
-# SC2 had no phase input.
-
-> import Sound.SC3
-
-> audition (out 0 (impulse AR 800 0 * 0.1))
-
-> let f = xLine KR 800 10 5 RemoveSynth
-> in audition (out 0 (impulse AR f 0.0 * 0.1))
-
-> let {f = mouseY KR 4 8 Linear 0.1
->     ;x = mouseX KR 0 1 Linear 0.1}
-> in audition (out 0 (impulse AR f (mce [0,x]) * 0.1))
-
-An impulse with frequency 0 returns a single impulse
-
-> audition (out 0 (decay (impulse AR 0 0) 1 * brownNoise 'a' AR * 0.1))
diff --git a/Help/UGen/Oscillator/klang.help.lhs b/Help/UGen/Oscillator/klang.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/klang.help.lhs
+++ /dev/null
@@ -1,28 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Klang"
-> Sound.SC3.UGen.DB.ugenSummary "Klang"
-
-# SC2 had mul/add inputs.
-
-> import Sound.SC3.ID
-
-> 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)))
-
-play({Klang.ar(`[[800,1000,1200],[0.3,0.3,0.3],[pi,pi,pi]],1,0)*0.4})
-
-> let s = klangSpec [800,1000,1200] [0.3,0.3,0.3] [pi,pi,pi]
-> in audition (out 0 (klang AR 1 0 s * 0.4))
-
-play({Klang.ar(`[[800,1000,1200],nil,nil],1,0)*0.25})
-
-> let s = klangSpec [800,1000,1200] [1,1,1] [0,0,0]
-> in audition (out 0 (klang AR 1 0 s * 0.25))
-
-play({Klang.ar(`[Array.rand(12,600.0,1000.0),nil,nil],1,0)*0.05})
-
-> let {f = map (\z -> rand z 600 1000) ['a'..'l']
->     ;s = klangSpec f (replicate 12 1) (replicate 12 0)}
-> in audition (out 0 (klang AR 1 0 s * 0.05))
-
diff --git a/Help/UGen/Oscillator/lfCub.help.lhs b/Help/UGen/Oscillator/lfCub.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/lfCub.help.lhs
+++ /dev/null
@@ -1,27 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFCub"
-> Sound.SC3.UGen.DB.ugenSummary "LFCub"
-
-> import Sound.SC3
-
-> audition (out 0 (lfCub AR (lfCub KR (lfCub KR 0.2 0 * 8 + 10) 0 * 400 + 800) 0 * 0.1))
-> audition (out 0 (lfCub AR (lfCub KR 0.2 0 * 400 + 800) 0 * 0.1))
-> audition (out 0 (lfCub AR 800 0 * 0.1))
-> audition (out 0 (lfCub AR (xLine KR 100 8000 30 DoNothing) 0 * 0.1))
-
-Compare w/ lfPar
-> audition (out 0 (lfPar AR (lfPar KR (lfPar KR 0.2 0 * 8 + 10) 0 * 400 + 800) 0 * 0.1))
-> audition (out 0 (lfPar AR (lfPar KR 0.2 0 * 400 + 800) 0 * 0.1))
-> audition (out 0 (lfPar AR 800 0 * 0.1))
-> audition (out 0 (lfPar AR (xLine KR 100 8000 30 DoNothing) 0 * 0.1))
-
-Compare w/ sinOsc
-> audition (out 0 (sinOsc AR (sinOsc KR (sinOsc KR 0.2 0 * 8 + 10) 0 * 400 + 800) 0 * 0.1))
-> audition (out 0 (sinOsc AR (sinOsc KR 0.2 0 * 400 + 800) 0 * 0.1))
-> audition (out 0 (sinOsc AR 800 0 * 0.1))
-> audition (out 0 (sinOsc AR (xLine KR 100 8000 30 DoNothing) 0 * 0.1))
-
-Compare w/ lfTri
-> audition (out 0 (lfTri AR (lfTri KR (lfTri KR 0.2 0 * 8 + 10) 0 * 400 + 800) 0 * 0.1))
-> audition (out 0 (lfTri AR (lfTri KR 0.2 0 * 400 + 800) 0 * 0.1))
-> audition (out 0 (lfTri AR 800 0 * 0.1))
-> audition (out 0 (lfTri AR (xLine KR 100 8000 30 DoNothing) 0 * 0.1))
diff --git a/Help/UGen/Oscillator/lfGauss.help.lhs b/Help/UGen/Oscillator/lfGauss.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/lfGauss.help.lhs
+++ /dev/null
@@ -1,82 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFGauss"
-> Sound.SC3.UGen.DB.ugenSummary "LFGauss"
-
-> import Sound.SC3
-
-modulating duration
-> let {d = xLine KR 0.1 0.001 10 DoNothing
->     ;g = lfGauss AR d 0.03 0 Loop DoNothing}
-> in audition (out 0 (g * 0.2))
-
-modulating width, freq 60 Hz
-> let {w = xLine KR 0.1 0.001 10 DoNothing
->     ;g = lfGauss AR (1/60) w 0 Loop DoNothing}
-> in audition (out 0 (g * 0.2))
-
-modulating both: x position is frequency, y is width factor.
-note the artefacts due to alisasing at high frequencies
-> let {d = mouseX KR (1/8000) 0.1 Exponential 0.2
->     ;w = mouseX KR 0.001 0.1 Exponential 0.2
->     ;g = lfGauss AR d w 0 Loop DoNothing}
-> in audition (out 0 (g * 0.1))
-
-LFGauss as amplitude modulator
-> let {d = mouseX KR 1 0.001 Exponential 0.2
->     ;g = lfGauss AR d 0.1 0 Loop DoNothing
->     ;o = sinOsc AR 1000 0}
-> in audition (out 0 (g * o * 0.1))
-
-modulate iphase
-> let {ph = mouseX KR (-1) 1 Linear 0.2
->     ;g = lfGauss AR 0.001 0.2 (mce2 0 ph) Loop DoNothing}
-> in audition (out 0 (mix g * 0.2))
-
-for very small width we are "approaching" a dirac function
-> let {w = sampleDur * mouseX KR 10 3000 Exponential 0.2
->     ;g = lfGauss AR 0.01 w 0 Loop DoNothing}
-> in audition (out 0 (g * 0.2))
-
-dur and width can be modulated at audio rate
-> let {x = mouseX KR 2 1000 Exponential 0.2
->     ;d = range 0.0006 0.01 (sinOsc AR x 0 * mce2 1 1.1)
->     ;w = range 0.01 0.3 (sinOsc AR (0.5 * (mce2 1 1.1)) 0)
->     ;g = lfGauss AR d w 0 Loop DoNothing}
-> in audition (out 0 (g * 0.2))
-
-several frequencies and widths combined
-> let {x = mouseX KR 1 0.07 Exponential 0.2
->     ;y = mouseY KR 1 3 Linear 0.2
->     ;g = lfGauss AR x (y ** mce [-1,-2 .. -6]) 0 Loop DoNothing
->     ;o = sinOsc AR (200 * (1.3 ** mce [0..5])) 0}
-> in audition (out 0 (mix (g * o) * 0.1))
-
-> withSC3 (send (n_trace [-1]))
-
-gabor grain (see also 'gabor_grain_ugen_graph')
-> let gabor = let {b = control IR "out" 0
->                 ;f = control IR "freq" 440
->                 ;s = control IR "sustain" 1
->                 ;p = control IR "pan" 1
->                 ;a = control IR "amp" 0.1
->                 ;w = control IR "width" 0.25
->                 ;e = lfGauss AR s w 0 NoLoop RemoveSynth
->                 ;o = fSinOsc AR f (pi / 2) * e
->                 ;u = offsetOut b (pan2 o p a)}
->             in synthdef "gabor" u
-
-> import Sound.SC3.Lang.Pattern {- hsc3-lang -}
-
-granular synthesis, modulating duration, width and pan
-> audition (pbind [(K_instr,psynth gabor)
->                 ,(K_freq,1000)
->                 ,(K_legato,2)
->                 ,(K_dur,pbrown 'α' 0.005 0.025 0.001 inf)
->                 ,(K_param "width",pbrown 'β' 0.05 0.25 0.005 inf)
->                 ,(K_param "pan",pbrown 'γ' (-1) 1 0.05 inf)])
-
-granular synthesis, modulating width only
-> audition (pbind [(K_instr,psynth gabor)
->                 ,(K_freq,1000)
->                 ,(K_dur,0.01)
->                 ,(K_param "width",pgeom 0.25 0.995 1250)
->                 ,(K_legato,2)])
diff --git a/Help/UGen/Oscillator/lfPar.help.lhs b/Help/UGen/Oscillator/lfPar.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/lfPar.help.lhs
+++ /dev/null
@@ -1,4 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFPar"
-> Sound.SC3.UGen.DB.ugenSummary "LFPar"
-
-See lfCub
diff --git a/Help/UGen/Oscillator/lfPulse.help.lhs b/Help/UGen/Oscillator/lfPulse.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/lfPulse.help.lhs
+++ /dev/null
@@ -1,26 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFPulse"
-> Sound.SC3.UGen.DB.ugenSummary "LFPulse"
-
-# SC2 had no initial phase argument.
-
-> import Sound.SC3
-
-> let f = lfPulse KR 3 0 0.3 * 200 + 200
-> in audition (out 0 (lfPulse AR f 0 0.2 * 0.1))
-
-> let x = mouseX KR 0 1 Linear 0.2
-> in audition (out 0 (lfPulse AR 220 0 x * 0.1))
-
-square wave as sum of sines.
-for odd partials n, amplitude is (1 / n), for even partials amplitude is 0.
-phase is always 0.
-
-> let {mk_freq f0 n = f0 * fromInteger n
->     ;mk_amp n = if even n then 0 else 1 / fromInteger n
->     ;mk_param f0 n = let m = [1,3 .. n] in zip (map (mk_freq f0) m) (map mk_amp m)
->     ;x = midiCPS (mouseX KR 20 72 Linear 0.2)
->     ;y = mouseY KR 0.01 0.1 Exponential 0.2
->     ;e = xLine KR 0.01 1 20 DoNothing
->     ;o1 = sum (map (\(fr,am) -> sinOsc AR fr 0 * am) (mk_param x 50)) * (1 - e)
->     ;o2 = lfPulse AR x 0 0.5 * e}
-> in audition (out 0 (mce2 o1 o2 * y))
diff --git a/Help/UGen/Oscillator/lfSaw.help.lhs b/Help/UGen/Oscillator/lfSaw.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/lfSaw.help.lhs
+++ /dev/null
@@ -1,32 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFSaw"
-> Sound.SC3.UGen.DB.ugenSummary "LFSaw"
-
-# SC2 did not have the initial phase argument.
-
-> import Sound.SC3
-
-> audition (out 0 (lfSaw AR 500 1 * 0.1))
-
-Used as both Oscillator and LFO.
-
-> audition (out 0 (lfSaw AR (lfSaw KR 4 0 * 400 + 400) 0 * 0.1))
-
-Output range is bi-polar.
-
-> let {f = mce [linLin (lfSaw KR 0.5 0) (-1) 1 200 1600, 200, 1600]
->     ;a = mce [0.1,0.05,0.05]}
-> in audition (out 0 (mix (sinOsc AR f 0 * a)))
-
-saw-tooth wave as sum of sines.
-for all partials n, amplitude is (1 / n).
-phase is always 0.
-
-> let {mk_freq f0 n = f0 * fromInteger n
->     ;mk_amp n = 1 / fromInteger n
->     ;mk_param f0 n = let m = [1,2 .. n] in zip (map (mk_freq f0) m) (map mk_amp m)
->     ;x = midiCPS (mouseX KR 20 72 Linear 0.2)
->     ;y = mouseY KR 0.01 0.1 Exponential 0.2
->     ;e = xLine KR 0.01 1 20 DoNothing
->     ;o1 = sum (map (\(fr,am) -> sinOsc AR fr 0 * am) (mk_param x 25)) * (1 - e)
->     ;o2 = lfSaw AR x 0 * e}
-> in audition (out 0 (mce2 o1 o2 * y))
diff --git a/Help/UGen/Oscillator/lfTri.help.lhs b/Help/UGen/Oscillator/lfTri.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/lfTri.help.lhs
+++ /dev/null
@@ -1,32 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFTri"
-> Sound.SC3.UGen.DB.ugenSummary "LFTri"
-
-> import Sound.SC3
-
-> audition (out 0 (lfTri AR 500 1 * 0.1))
-
-Used as both Oscillator and LFO.
-
-> audition (out 0 (lfTri AR (lfTri KR 4 0 * 400 + 400) 0 * 0.1))
-
-Multiple phases
-
-> let f = lfTri KR 0.4 (mce [0..3]) * 200 + 400
-> in audition (out 0 (mix (lfTri AR f 0 * 0.1)))
-
-triangle wave as sum of sines.
-for partial n, amplitude is (1 / square n) and phase is pi at every other odd partial
-
-> import Sound.SC3.UGen.Dot
-
-> let {mk_freq f0 n = f0 * fromInteger n
->     ;mk_amp n = if even n then 0 else 1 / fromInteger (n * n)
->     ;mk_ph n = if n + 1 `mod` 4 == 0 then pi else 0
->     ;mk_param f0 n =
->      let m = [1,3 .. n]
->      in zip3 (map (mk_freq f0) m) (map mk_ph m) (map mk_amp m)
->     ;x = midiCPS (mouseX KR 20 72 Linear 0.2)
->     ;e = xLine KR 0.01 1 20 DoNothing
->     ;o1 = sum (map (\(fr,ph,am) -> sinOsc AR fr ph * am) (mk_param x 25)) * (1 - e)
->     ;o2 = lfTri AR x 0 * e}
-> in audition (out 0 (mce2 o1 o2 * 0.1))
diff --git a/Help/UGen/Oscillator/osc1.help.lhs b/Help/UGen/Oscillator/osc1.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/osc1.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> import Sound.SC3
-
-> withSC3 (let {z = [Normalise,Wavetable,Clear]
->              ;a = [[13,8,55,34,5,21,3,1,2],[55,34,1,3,2,13,5,8,21]]
->              ;f (b,l) = do {_ <- async (b_alloc b 512 1)
->                            ;send (b_gen_sine1 b z (map recip l))}}
->          in mapM_ f (zip [10,11] a))
-
-> audition (out 0 (lfSaw AR (mce2 110 164) 0 * 0.1 * osc1 AR (mce2 10 11) 4 RemoveSynth))
diff --git a/Help/UGen/Oscillator/oscN.help.lhs b/Help/UGen/Oscillator/oscN.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/oscN.help.lhs
+++ /dev/null
@@ -1,4 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "OscN"
-> Sound.SC3.UGen.DB.ugenSummary "OscN"
-
-See osc
diff --git a/Help/UGen/Oscillator/pmOsc.help.lhs b/Help/UGen/Oscillator/pmOsc.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/pmOsc.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PMOsc"
-> :t pmOsc
-
-# pmOsc is a composite of sinOsc, ie. sinOsc r cf (sinOsc r mf mp * pm)
-
-> import Sound.SC3.ID
-
-Random parameters, linear modulation index motion over n seconds
-> let pmi n = let {cf = rand 'α' 0 2000
->                 ;mf = rand 'β' 0 800
->                 ;pme = rand 'γ' 0 12
->                 ;l = rand 'δ' (-1) 1
->                 ;pm = line KR 0 pme n DoNothing}
-> in linPan2 (pmOsc AR cf mf pm 0) l 0.05
-
-> audition (out 0 (pmi 2))
-
-PM textures
-> import qualified Sound.SC3.Lang.Control.OverlapTexture as L
-> L.overlapTextureU (0,1,8,maxBound) (pmi 1)
-> L.overlapTextureU (1,2,7,maxBound) (pmi 2)
-> L.overlapTextureU (6,6,6,maxBound) (pmi 12)
diff --git a/Help/UGen/Oscillator/pulse.help.lhs b/Help/UGen/Oscillator/pulse.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/pulse.help.lhs
+++ /dev/null
@@ -1,20 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Pulse"
-> Sound.SC3.UGen.DB.ugenSummary "Pulse"
-
-> import Sound.SC3
-
-Modulate frequency
-
-> let f = xLine KR 40 4000 6 RemoveSynth
-> in audition (out 0 (pulse AR f 0.1 * 0.1))
-
-Modulate pulse width
-
-> 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 through a resonant low pass filter
-
-> let {p = pulse AR (mce2 100 250) 0.5 * 0.1
->     ;f = xLine KR 8000 400 5 DoNothing}
-> 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
deleted file mode 100644
--- a/Help/UGen/Oscillator/saw.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Saw"
-> Sound.SC3.UGen.DB.ugenSummary "Saw"
-
-> import Sound.SC3
-
-> audition (out 0 (saw AR (xLine KR 40 4000 6 RemoveSynth) * 0.1))
-
-Two band limited sawtooth waves thru a resonant low pass filter
-> let f = xLine KR 8000 400 5 DoNothing
-> in audition (out 0 (rlpf (saw AR (mce2 100 250) * 0.1) f 0.05))
diff --git a/Help/UGen/Oscillator/silent.help.lhs b/Help/UGen/Oscillator/silent.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/silent.help.lhs
+++ /dev/null
@@ -1,6 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Silent"
-> Sound.SC3.UGen.DB.ugenSummary "Silent"
-
-> import Sound.SC3
-
-> audition (out 0 (silent 1))
diff --git a/Help/UGen/Oscillator/sinOsc.help.lhs b/Help/UGen/Oscillator/sinOsc.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/sinOsc.help.lhs
+++ /dev/null
@@ -1,47 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SinOsc"
-> Sound.SC3.UGen.DB.ugenSummary "SinOsc"
-
-> import Sound.SC3
-
-Fixed frequency
-
-> audition (out 0 (sinOsc AR 440 0 * 0.25))
-
-Modulate freq
-
-> audition (out 0 (sinOsc AR (xLine KR 2000 200 9 RemoveSynth) 0 * 0.5))
-
-Modulate freq
-
-> let f = sinOsc AR (xLine KR 1 1000 9 RemoveSynth) 0 * 200 + 800
-> 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
-> in audition (out 0 (sinOsc AR 800 p * 0.1))
-
-Simple bell-like tone.
-
-> let {f = mce [0.5,1,1.19,1.56,2,2.51,2.66,3.01,4.1]
->     ;a = mce [0.25,1,0.8,0.5,0.9,0.4,0.3,0.6,0.1]
->     ;o = sinOsc AR (500 * f) 0 * a
->     ;e = envGen KR 1 0.1 0 1 RemoveSynth (envPerc 0.01 10)}
-> in audition (out 0 (mix o * e))
-
-"When two pure tones of slightly different frequency are superposed,
-our ears perceive audible beats at a rate given by the difference of
-the two frequencies."
-
-> let {f0 = 220;f1 = 221.25;d = abs (f1 - f0)}
-> in audition (out 0 (sinOsc AR (mce2 f0 f1) 0 * 0.1 + impulse AR d 0 * 0.25))
-
-"When two tones are sounded together, a tone of lower frequency is
-frequently heard. Such a tone is called a combination tone.  The most
-commonly heard combination tone occurs at a frequency f2 - f1."
-
-> let {f1 = 300
->     ;f2 = 300 * (3/2)
->     ;f = mce2 (mce2 f1 f2) (abs (f2 - f1))
->     ;a = mce2 0.1 (max (sinOsc KR 0.05 0 * 0.1) 0)}
-> in audition (out 0 (sinOsc AR f 0 * a))
diff --git a/Help/UGen/Oscillator/sinOscFB.help.lhs b/Help/UGen/Oscillator/sinOscFB.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/sinOscFB.help.lhs
+++ /dev/null
@@ -1,28 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SinOscFB"
-> Sound.SC3.UGen.DB.ugenSummary "SinOscFB"
-
-> import Sound.SC3
-
-{SinOscFB.ar([400,301],MouseX.kr(0,4))*0.1}.play
-
-> let {x = mouseX KR 0 4 Linear 0.2
->     ;o = sinOscFB AR (mce2 400 301) x * 0.1}
-> in audition (out 0 o)
-
-{y=MouseY.kr(10,1000,'exponential')
-;x=MouseX.kr(0.5pi,pi)
-;SinOscFB.ar(y,x)*0.1}.play
-
-> let {y = mouseY KR 10 1000 Exponential 0.2
->     ;x = mouseX KR (pi/2) pi Linear 0.2
->     ;o = sinOscFB AR y x * 0.1}
-> in audition (out 0 o)
-
-{y=MouseY.kr(1,1000,'exponential')
-;x=MouseX.kr(0.5pi,pi)
-;SinOscFB.ar(100*SinOscFB.ar(y)+200,x)*0.1}.play
-
-> let {y = mouseY KR 1 1000 Exponential 0.2
->     ;x = mouseX KR (pi/2) pi Linear 0.2
->     ;o = sinOscFB AR (100 * sinOscFB AR y 0 + 200) x * 0.1}
-> in audition (out 0 o)
diff --git a/Help/UGen/Oscillator/syncSaw.help.lhs b/Help/UGen/Oscillator/syncSaw.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/syncSaw.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SyncSaw"
-> Sound.SC3.UGen.DB.ugenSummary "SyncSaw"
-
-> import Sound.SC3
-
-> let f = line KR 100 800 12 RemoveSynth
-> in audition (out 0 (syncSaw AR 100 f * 0.1))
-
-Mouse control
-> let {sy_f = mouseY KR 80 220 Exponential 0.2
->     ;sw_f = sy_f * mouseX KR 1 3 Linear 0.2}
-> in audition (out 0 (syncSaw AR sy_f sw_f * 0.1))
diff --git a/Help/UGen/Oscillator/tChoose.help.lhs b/Help/UGen/Oscillator/tChoose.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/tChoose.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TChoose"
-> :t tChoose
-
-# tChoose is a composite of tIRand and select.
-
-> import Sound.SC3
-
-> let {x = mouseX KR 1 1000 Exponential 0.1
->     ;t = dust 'a' AR x
->     ;f = midiCPS (tIRand 'b' 48 60 t)
->     ;o = let a = mce [sinOsc AR f 0
->                      ,saw AR (f * 2)
->                      ,pulse AR (f * 0.5) 0.1]
->           in tChoose 'c' t a}
-> in audition (out 0 (o * 0.1))
diff --git a/Help/UGen/Oscillator/tGrains.help.lhs b/Help/UGen/Oscillator/tGrains.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/tGrains.help.lhs
+++ /dev/null
@@ -1,52 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TGrains"
-> Sound.SC3.UGen.DB.ugenSummary "TGrains"
-
-> import Sound.SC3
-
-Load audio (#10) data
-
-> let fn = "/home/rohan/data/audio/pf-c5.aif"
-> in withSC3 (async (b_allocRead 10 fn 0 0))
-
-Mouse control
-
-> 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.25 2))
-
-> let {b = 10
->     ;rt = mouseY KR 8 120 Exponential 0.1
->     ;dur = 4 / rt
->     ;clk = dust 'α' AR rt
->     ;r = tRand 'β' 0 0.01 clk
->     ;pan = whiteNoise 'γ' KR * 0.6
->     ;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.25 2))
-
-> let {b = 10
->     ;rt = mouseY KR 2 120 Exponential 0.1
->     ;dur = 1.2 / rt
->     ;clk = impulse AR rt 0
->     ;pos = mouseX KR 0 (bufDur KR b) Linear 0.1
->     ;n0 = whiteNoise 'α' KR
->     ;n1 = whiteNoise 'β' KR
->     ;rate = shiftLeft 1.2 (roundTo (n0 * 3) 1)}
-> in audition (out 0 (tGrains 2 clk b rate pos dur (n1 * 0.6) 0.25 2))
-
-Demand UGens as inputs (may eventually hang scsynth?)
-
-> let {b = 10
->     ;rt = mouseY KR 2 100 Linear 0.2
->     ;d e = dwhite e 1 0.1 0.2
->     ;z e0 e1 = drand e0 1 (mce [dgeom e0 (diwhite e0 1 20 40) 0.1 (1 + d e0)
->                                ,dgeom e1 (diwhite e1 1 20 40) 1 (1 - d e1)])
->     ;clk = impulse AR rt 0
->     ;dsq e xs = dseq e dinf (mce xs)
->     ;rate = dsq 'α' [1,1,z 'β' 'γ',0.5,0.5,0.2,0.1,0.1,0.1,0.1] * 2 + 1
->     ;pos = dsq 'δ' (take 8 (zipWith z ['ε'..] ['ζ'..]))
->     ;dur = dsq 'η' [1,d 'θ',1,z 'ι' 'κ',0.5,0.5,0.1,z 'λ' 'μ'] * 2 / rt
->     ;pan = dsq 'ν' [1,1,1,0.5,0.2,0.1,0,0,0] * 2 - 1
->     ;amp = dsq 'ξ' [1,0,z 'ο' 'π',0,2,1,1,0.1,0.1]}
-> in audition (out 0 (tGrains 2 clk b rate pos dur pan amp 2))
diff --git a/Help/UGen/Oscillator/tWindex.help.lhs b/Help/UGen/Oscillator/tWindex.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/tWindex.help.lhs
+++ /dev/null
@@ -1,18 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TWindex"
-> Sound.SC3.UGen.DB.ugenSummary "TWindex"
-
-> import Sound.SC3.ID
-
-> let {p = mce [1/5, 2/5, 2/5]
->     ;a = mce [400, 500, 600]
->     ;t = impulse KR 6 0
->     ;i = tWindex 'α' t 0 p}
-> in audition (out 0 (sinOsc AR (select i  a) 0 * 0.1))
-
-Modulating probability values
-
-> let {p = mce [1/4, 1/2, sinOsc KR 0.3 0 * 0.5 + 0.5]
->     ;a = mce [400, 500, 600]
->     ;t = impulse KR 6 0
->     ;i = tWindex 'α' t 1 p}
-> in audition (out 0 (sinOsc AR (select i a) 0 * 0.1))
diff --git a/Help/UGen/Oscillator/twChoose.help.lhs b/Help/UGen/Oscillator/twChoose.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/twChoose.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TWChoose"
-
-# tWChoose is a composite of tWindex and select
-
-> import Sound.SC3.ID
-
-> let {x = mouseX KR 1 1000 Exponential 0.1
->     ;d = dust 'a' AR x
->     ;a = mce [sinOsc AR 220 0
->              ,saw AR 440
->              ,pulse AR 110 0.1]
->     ;w = mce [0.5, 0.35, 0.15]
->     ;o = tWChoose 'b' d a w 0}
-> in audition (out 0 (o * 0.1))
diff --git a/Help/UGen/Oscillator/varSaw.help.lhs b/Help/UGen/Oscillator/varSaw.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/varSaw.help.lhs
+++ /dev/null
@@ -1,27 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "VarSaw"
-> Sound.SC3.UGen.DB.ugenSummary "VarSaw"
-
-> import Sound.SC3
-
-> let {f = lfPulse KR (mce2 3 3.03) 0 0.3 * 200 + 200
->     ;w = linLin (lfTri KR 1 0) (-1) 1 0 1}
-> in audition (out 0 (varSaw AR f 0 w * 0.1))
-
-Compare with lfPulse at AR
-
-> let f = lfPulse KR 3 0 0.3 * 200 + 200
-> in audition (out 0 (mce [varSaw AR f 0 0.2
->                         ,lfPulse AR f 0 0.2] * 0.1))
-
-per-note width modulation
-
-> let {d = linLin (lfNoise2 'α' KR 0.1) (-1) 1 0.15 0.5
->     ;t = impulse AR (1 / d) 0
->     ;w0 = tRand 'β' 0 0.35 t
->     ;w1 = tRand 'γ' 0.65 1 t
->     ;w = phasor AR t ((w1 - w0) * sampleDur) w0 w1 0
->     ;e = decay2 t 0.1 d
->     ;f = midiCPS (tRand 'δ' 36 72 t)
->     ;o = varSaw AR f 0 w * e * 0.1
->     ;l = tRand 'ε' (-1) 1 t}
-> in audition (out 0 (pan2 o l 1))
diff --git a/Help/UGen/Oscillator/vibrato.help.lhs b/Help/UGen/Oscillator/vibrato.help.lhs
deleted file mode 100644
--- a/Help/UGen/Oscillator/vibrato.help.lhs
+++ /dev/null
@@ -1,42 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Vibrato"
-> Sound.SC3.UGen.DB.ugenSummary "Vibrato"
-
-> import Sound.SC3.ID
-
-vibrato at 1 Hz, note the use of DC.ar
-
-{SinOsc.ar(Vibrato.ar(DC.ar(400.0),1,0.02))*0.1}.play
-
-> let v = vibrato AR (dc AR 400) 1 0.02 0 0 0.04 0.1 0
-> in audition (out 0 (sinOsc AR v 0 * 0.1))
-
-compare: k-rate freq input can be a constant
-
-{SinOsc.ar(Vibrato.kr(400.0,1,0.02))}.play
-
-> let v = vibrato KR 400 1 0.02 0 0 0.04 0.1 0
-> in audition (out 0 (sinOsc AR v 0 * 0.1))
-
-control rate and rateVariation
-{x=MouseX.kr(2.0,100.0)
-;y=MouseY.kr(0.0,1.0)
-;v=Vibrato.ar(DC.ar(400.0),x,0.1,1.0,1.0,y,0.1)
-;SinOsc.ar(v)}.play
-> let {x = mouseX KR 2 100 Linear 0.2
->     ;y = mouseY KR 0 1 Linear 0.2
->     ;v = vibrato AR (dc AR 400) x 0.1 1 1 y 0.1 0}
-> in audition (out 0 (sinOsc AR v 0 * 0.1))
-
-control depth and depthVariation
-
-{n=LFNoise1.kr(1,3,7)
-;x=MouseX.kr(0.0,1.0)
-;y=MouseY.kr(0.0,1.0)
-;v=Vibrato.ar(DC.ar(400.0),n,x,1.0,1.0,y,0.1)
-;SinOsc.ar(v)}.play
-
-> let {n = lfNoise1 'a' KR 1 * 3 + 7
->     ;x = mouseX KR 0 1 Linear 0.2
->     ;y = mouseY KR 0 1 Linear 0.2
->     ;v = vibrato AR (dc AR 400) n x 1 1 y 0.1 0}
-> in audition (out 0 (sinOsc AR v 0 * 0.1))
diff --git a/Help/UGen/Panner/balance2.help.lhs b/Help/UGen/Panner/balance2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Panner/balance2.help.lhs
+++ /dev/null
@@ -1,37 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Balance2"
-> Sound.SC3.UGen.DB.ugenSummary "Balance2"
-
-> import Sound.SC3.ID
-
-{Balance2.ar(LFSaw.ar(44),Pulse.ar(33),FSinOsc.kr(0.5),0.1)}.play
-> let {l = lfSaw AR 44 0
->     ;r = pulse AR 33 0.5
->     ;p = fSinOsc KR 0.5 0
->     ;o = balance2 l r p 0.1}
-> in audition (out 0 o)
-
-{var s=SinOsc.ar([440,550]);Balance2.ar(s[0],s[1],LFNoise0.kr(4),0.3)}.play
-> let {[s0,s1] = mceChannels (sinOsc AR (mce2 440 550) 0)
->     ;n = lfNoise0 'a' KR 4
->     ;o = balance2 s0 s1 n 0.3}
-> in audition (out 0 o)
-
-{var s=SinOsc.ar(440);Out.ar(0,0.2*Balance2.ar(s,s,SinOsc.kr(0.2)))}.play
-> let {s = sinOsc AR 440 0
->     ;p = sinOsc KR 0.2 0
->     ;o = balance2 s s p 1 * 0.2}
-> in audition (out 0 o) {- >> Sound.SC3.UGen.Dot.draw (out 0 o) -}
-
-{var s=SinOsc.ar(440);Out.ar(0,Balance2.ar(s,s,SinOsc.kr(0.2),0.2))}.play
-> let {s = sinOsc AR 440 0
->     ;p = sinOsc KR 0.2 0
->     ;o = balance2 s s p 0.2}
-> in audition (out 0 o) {- >> Sound.SC3.UGen.Dot.draw (out 0 o) -}
-
-> withSC3 (send (n_trace [-1]))
-
-{var s=SinOsc.ar(440);Out.ar(0,Balance2.ar(s,s,MouseX.kr(-1,1),0.2))}.play
-> let {s0 = sinOsc AR 440 0
->     ;s1 = sinOsc AR 550 0
->     ;x = mouseX KR (-1) 1 Linear 0.2}
-> in audition (out 0 (balance2 s0 s0 x 0.2))
diff --git a/Help/UGen/Panner/decodeB2.help.lhs b/Help/UGen/Panner/decodeB2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Panner/decodeB2.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DecodeB2"
-> Sound.SC3.UGen.DB.ugenSummary "DecodeB2"
-
-> import Sound.SC3.ID
-
-fails..., but so does sclang...
-> let {p = pinkNoise 'a' AR
->     ;mx = mouseX KR (-1) 1 Linear 0.2
->     ;my = mouseY KR 0 0.1 Linear 0.2
->     ;[w,x,y] = mceChannels (panB2 p mx my)
->     ;o = decodeB2 2 w x y 0.5}
-> in audition (out 0 o)
diff --git a/Help/UGen/Panner/linPan2.help.lhs b/Help/UGen/Panner/linPan2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Panner/linPan2.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LinPan2"
-> Sound.SC3.UGen.DB.ugenSummary "LinPan2"
-
-> import Sound.SC3.ID
-
-> let n = pinkNoise 'a' AR
-> in 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
deleted file mode 100644
--- a/Help/UGen/Panner/pan2.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Pan2"
-> Sound.SC3.UGen.DB.ugenSummary "Pan2"
-
-> import Sound.SC3.ID
-
-> let n = pinkNoise 'a' AR
-> in audition (out 0 (pan2 n (fSinOsc KR 2 0) 0.3))
-
-> let {n = pinkNoise 'a' AR
->     ;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/panAz.help.lhs b/Help/UGen/Panner/panAz.help.lhs
deleted file mode 100644
--- a/Help/UGen/Panner/panAz.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PanAz"
-> Sound.SC3.UGen.DB.ugenSummary "PanAz"
-
-> import Sound.SC3.ID
-
-> let {o = pinkNoise 'a' AR
->     ;nc = 4
->     ;fr = 0.15}
-> in audition (out 0 (panAz nc o (lfSaw KR fr 0) 0.1 2 0.5))
diff --git a/Help/UGen/Panner/rotate2.help.lhs b/Help/UGen/Panner/rotate2.help.lhs
deleted file mode 100644
--- a/Help/UGen/Panner/rotate2.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Rotate2"
-> Sound.SC3.UGen.DB.ugenSummary "Rotate2"
-
-> import Sound.SC3.ID
-
-Rotation of stereo sound, via LFO.
-> let {x = pinkNoise 'a' AR
->     ;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
->     ;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
deleted file mode 100644
--- a/Help/UGen/Panner/splay.help.lhs
+++ /dev/null
@@ -1,50 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Splay"
-splay inArray spread=1 level=1 center=0 levelComp=true
-
-splay is a composite UGen.
-
-> import Sound.SC3
-
-mouse control
-
-> let {i = 6
->     ;r = map (\e -> rand e 10 20) (take i ['a'..])
->     ;n = lfNoise2 'a' KR (mce r)
->     ;x = mouseX KR (-1) 1 Linear 0.1
->     ;y = mouseY KR 1 0 Linear 0.1
->     ;ci = constant . fromIntegral
->     ;f = mce [1 .. ci i] + 3 * 100
->     ;o = sinOsc AR (n * 200 + f) 0}
-> in audition (out 0 (splay o y 0.2 x True))
-
-n_set control
-
-> let {i = 10
->     ;s = control KR "spread" 1
->     ;l = control KR "level" 0.2
->     ;c = control KR "center" 0
->     ;r = map (\e -> rand e 10 20) (take i ['a'..])
->     ;ci = constant . fromIntegral
->     ;f = mce [1 .. ci i] + 3 * 100
->     ;n = lfNoise2 'a' KR (mce r) * 200 + f}
-> in audition (out 0 (splay (sinOsc AR n 0) s l c True))
-
-full stereo
-
-> withSC3 (send (n_set (-1) [("spread",1),("center",0)]))
-
-less wide
-
-> withSC3 (send (n_set (-1) [("spread",0.5),("center",0)]))
-
-mono center
-
-> withSC3 (send (n_set (-1) [("spread",0),("center",0)]))
-
-from center to right
-
-> withSC3 (send (n_set (-1) [("spread",0.5),("center",0.5)]))
-
-all left
-
-> withSC3 (send (n_set (-1) [("spread",0),("center",-1)]))
diff --git a/Help/UGen/Trigger/gate.help.lhs b/Help/UGen/Trigger/gate.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/gate.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Gate"
-> Sound.SC3.UGen.DB.ugenSummary "Gate"
-
-> import Sound.SC3
-
-> let t = lfPulse AR 1 0 0.1
-> 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
deleted file mode 100644
--- a/Help/UGen/Trigger/inRange.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "InRange"
-> Sound.SC3.UGen.DB.ugenSummary "InRange"
-
-> import Sound.SC3.ID
-
-trigger noise burst
-> let {n = brownNoise 'α' AR * 0.1
->     ;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))
diff --git a/Help/UGen/Trigger/lastValue.help.lhs b/Help/UGen/Trigger/lastValue.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/lastValue.help.lhs
+++ /dev/null
@@ -1,12 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LastValue"
-> Sound.SC3.UGen.DB.ugenSummary "LastValue"
-
-> import Sound.SC3
-
-> let x = mouseX KR 100 400 Linear 0.1
-> in audition (out 0 (sinOsc AR (lastValue x 40) 0 * 0.1))
-
-Difference between currrent and the last changed
-> 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
deleted file mode 100644
--- a/Help/UGen/Trigger/mostChange.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MostChange"
-> Sound.SC3.UGen.DB.ugenSummary "MostChange"
-
-> import Sound.SC3.ID
-
-> let {n = lfNoise0 'α' KR 1
->     ;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
deleted file mode 100644
--- a/Help/UGen/Trigger/peak.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Peak"
-> Sound.SC3.UGen.DB.ugenSummary "Peak"
-
-> import Sound.SC3.ID
-
-> let {t = dust 'α' AR 20
->     ;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
deleted file mode 100644
--- a/Help/UGen/Trigger/phasor.help.lhs
+++ /dev/null
@@ -1,51 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Phasor"
-> Sound.SC3.UGen.DB.ugenSummary "Phasor"
-
-> import Sound.SC3
-
-phasor controls sine frequency, end frequency matches second sine.
-
-> 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))
-
-Load sound file to buffer zero
-
-> let fn = "/home/rohan/data/audio/pf-c5.aif"
-> in withSC3 (async (b_allocRead 0 fn 0 0))
-
-Phasor as phase input to bufRd
-
-> let ph = phasor AR 0 (bufRateScale KR 0) 0 (bufFrames KR 0) 0
-> in audition (out 0 (bufRdN 1 AR 0 ph Loop))
-
-Allocate and generate (non-wavetable) buffer at index one
-(see osc for wavetable oscillator)
-
-> withSC3 (do {_ <- async (b_alloc 1 256 1)
->             ;let f = [Normalise,Clear]
->              in send (b_gen_sine1 1 f [1])})
-
-Audio rate phasor oscillator as phase input to bufRd
-
-> let {b = 1
->     ;f = 440
->     ;fr = bufFrames KR b
->     ;rt = f * (fr / sampleRate)
->     ;ph = phasor AR b (rt * bufRateScale KR b) 0 fr 0}
-> in audition (out 0 (bufRdL 1 AR b ph Loop * 0.1))
-
-Phasor as impulse with reset
-
-> let {impulse_reset freq reset =
->      let ph = phasor AR reset (freq / sampleRate) 0 1 0
->      in hpz1 ph <* 0
->     ;x = mouseX KR 0 1 Linear 0.2 >* 0.5
->     ;ck = impulse AR 3 0
->     ;im = impulse_reset 3 x
->     ;x' = sinOsc AR 440 0 * x * 0.05
->     ;im' = sinOsc AR 220 0 * decay2 (ck + im) 0.01 0.5 * 0.1}
-> in audition (out 0 (mce2 x' im'))
diff --git a/Help/UGen/Trigger/pulseCount.help.lhs b/Help/UGen/Trigger/pulseCount.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/pulseCount.help.lhs
+++ /dev/null
@@ -1,15 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PulseCount"
-> Sound.SC3.UGen.DB.ugenSummary "PulseCount"
-
-> import Sound.SC3.ID {- hsc3 -}
-
-> let c = pulseCount (impulse AR 10 0) (impulse AR 0.4 0)
-> in audition (out 0 (sinOsc AR (c * 200) 0 * 0.05))
-
-printer
-
-> let {b = localBuf 'α' 11 1
->     ;t = impulse AR 10 0
->     ;p = pulseCount t 0
->     ;d = demand t 0 (dbufwr 'α' (-666) b p NoLoop)}
-> in audition (mrg [out 0 (dc AR 0),poll t p (label "p") 0])
diff --git a/Help/UGen/Trigger/pulseDivider.help.lhs b/Help/UGen/Trigger/pulseDivider.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/pulseDivider.help.lhs
+++ /dev/null
@@ -1,10 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PulseDivider"
-> Sound.SC3.UGen.DB.ugenSummary "PulseDivider"
-
-> import Sound.SC3
-
-> 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
deleted file mode 100644
--- a/Help/UGen/Trigger/runningMax.help.lhs
+++ /dev/null
@@ -1,14 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RunningMax"
-> Sound.SC3.UGen.DB.ugenSummary "RunningMax"
-
-> import Sound.SC3.ID
-
-> let {n = dust 'α' AR 20
->     ;t = impulse AR 0.4 0
->     ;f = runningMax n t * 500 + 200}
-> in audition (out 0 (sinOsc AR f 0 * 0.2))
-
-follow a sine lfo, reset rate controlled by mouse x
-> let {t = impulse KR (mouseX KR 0.01 2 Linear 0.1) 0
->     ;f = runningMax (sinOsc KR 0.2 0) 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
deleted file mode 100644
--- a/Help/UGen/Trigger/runningMin.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RunningMin"
-> Sound.SC3.UGen.DB.ugenSummary "RunningMin"
-
-> import Sound.SC3.ID
-
-Follow a sine lfo, reset rate controlled by mouseX
-> 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))
-
-> let {n = dust 'α' AR 20
->     ;t = impulse AR 0.4 0
->     ;f = runningMin n t * 500 + 200}
-> in audition (out 0 (sinOsc AR f 0 * 0.2))
diff --git a/Help/UGen/Trigger/sendReply.help.lhs b/Help/UGen/Trigger/sendReply.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/sendReply.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SendReply"
-> Sound.SC3.UGen.DB.ugenSummary "SendReply"
-
-> import Sound.SC3.ID
-
-> let {s0 = lfNoise0 'a' KR 5
->     ;s1 = lfNoise0 'b' KR 5
->     ;o = sinOsc AR (s0 * 200 + 500) 0 * s1 * 0.1}
-> in audition (mrg [sendReply s0 0 "/send-reply" [s0,s1],out 0 o])
-
-> withSC3 (withNotifications (waitReply "/send-reply"))
diff --git a/Help/UGen/Trigger/sendTrig.help.lhs b/Help/UGen/Trigger/sendTrig.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/sendTrig.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SendTrig"
-> Sound.SC3.UGen.DB.ugenSummary "SendTrig"
-
-> import Sound.SC3.ID
-
-> let {s = lfNoise0 'α' KR 5
->     ;o = sinOsc AR (s * 200 + 500) 0 * 0.1}
-> in audition (mrg [sendTrig s 0 s,out 0 o])
-
-Retrieve a single message
-> withSC3 (withNotifications (waitReply "/tr"))
diff --git a/Help/UGen/Trigger/setResetFF.help.lhs b/Help/UGen/Trigger/setResetFF.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/setResetFF.help.lhs
+++ /dev/null
@@ -1,21 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SetResetFF"
-> Sound.SC3.UGen.DB.ugenSummary "SetResetFF"
-
-> import Sound.SC3.ID
-
-d0 is the set trigger, d1 the reset trigger
-
-> let {n = brownNoise 'α' AR
->     ;d0 = dust 'β' AR 5
->     ;d1 = dust 'γ' AR 5}
-> in audition (out 0 (setResetFF d0 d1 * n * 0.2))
-
-silence
-
-> let tr = setResetFF (impulse KR 5 0) (impulse KR 10 0)
-> in audition (out 0 (brownNoise 'α' AR * 0.1 * decay2 tr 0.01 0.05))
-
-duty cycle
-
-> let tr = 1 - setResetFF (impulse KR 10 0) (impulse KR 5 0)
-> in audition (out 0 (brownNoise 'α' AR * 0.1 * decay2 tr 0.01 0.05))
diff --git a/Help/UGen/Trigger/stepper.help.lhs b/Help/UGen/Trigger/stepper.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/stepper.help.lhs
+++ /dev/null
@@ -1,41 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Stepper"
-> Sound.SC3.UGen.DB.ugenSummary "Stepper"
-
-> import Sound.SC3.ID
-
-> 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))
-
-Using Stepper and BufRd for sequencing
-> let {compose = foldl (flip (.)) id
->     ;rvb z s =
->         let f i = let dly = mce [rand (z `joinID` i `joinID` 'a') 0 0.5
->                                 ,rand (z `joinID` i `joinID` 'b') 0 0.5]
->                     in allpassN i 0.05 dly (rand i 1.5 2)
->         in compose (replicate 5 f) s
->     ;stpr = let {rate = mouseX KR 1.75 2.25 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 'a' 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 =
->      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 (b_alloc 10 128 1)
->            ;send (b_setn 10 [(0,n)])}}
-> in withSC3 (stprInit >> play (out 0 stpr))
diff --git a/Help/UGen/Trigger/sweep.help.lhs b/Help/UGen/Trigger/sweep.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/sweep.help.lhs
+++ /dev/null
@@ -1,64 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Sweep"
-> Sound.SC3.UGen.DB.ugenSummary "Sweep"
-
-> import Sound.SC3.ID
-
-Using sweep to modulate sine frequency
-
-> 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))
-
-Load audio to buffer
-
-> let fn = "/home/rohan/data/audio/pf-c5.aif"
-> in withSC3 (send (b_allocRead 0 fn 0 0))
-
-Using sweep to index into a buffer
-
-> 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
-
-> let {n = lfNoise0 'α' KR 15
->     ;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
->     ;p = sweep t (bufSampleRate KR 0 * r)}
-> in audition (out 0 (bufRdL 1 AR 0 p NoLoop))
-
-f0 (sc-users, 2012-02-09)
-
-> let {lf = range 0.01 1.25 (lfNoise2 'α' KR 1)
->     ;du = duty AR lf 0 DoNothing lf
->     ;tr = abs (hpz1 du) >* 0
->     ;ph = sweep tr (1/du)
->     ;fr = linExp ph 0 1 400 800
->     ;os = sinOsc AR fr 0 * 0.2}
-> in audition (out 0 os)
-
-line segments, set start & end values, transition time and trigger.
-continues past end point if not re-triggered.
-
-> let {tr = tr_control "tr" 0
->     ;st = control KR "st" 440
->     ;en = control KR "en" 880
->     ;tm = control KR "tm" 2
->     ;rt = ((en - st) / tm)
->     ;sw = sweep tr rt + st}
-> in audition (out 0 (sinOsc AR sw 0 * 0.2))
-
-> withSC3 (send (n_set (-1) [("st",660),("en",550),("tm",4),("tr",1)]))
-> withSC3 (send (n_set (-1) [("st",110),("en",990),("tm",1),("tr",1)]))
diff --git a/Help/UGen/Trigger/tDelay.help.lhs b/Help/UGen/Trigger/tDelay.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/tDelay.help.lhs
+++ /dev/null
@@ -1,9 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "TDelay"
-> Sound.SC3.UGen.DB.ugenSummary "TDelay"
-
-> import Sound.SC3
-
-> 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
deleted file mode 100644
--- a/Help/UGen/Trigger/timer.help.lhs
+++ /dev/null
@@ -1,7 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Timer"
-> Sound.SC3.UGen.DB.ugenSummary "Timer"
-
-> import Sound.SC3
-
-> let t = impulse KR (mouseX KR 0.5 20 Exponential 0.1) 0
-> 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
deleted file mode 100644
--- a/Help/UGen/Trigger/toggleFF.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "ToggleFF"
-> Sound.SC3.UGen.DB.ugenSummary "ToggleFF"
-
-> import Sound.SC3.ID
-
-> let {t = dust 'a' AR (xLine KR 1 1000 60 DoNothing)
->     ;t' = toggleFF t * 400 + 800}
-> in audition (out 0 (sinOsc AR t' 0 * 0.1))
diff --git a/Help/UGen/Trigger/trig.help.lhs b/Help/UGen/Trigger/trig.help.lhs
deleted file mode 100644
--- a/Help/UGen/Trigger/trig.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Trig"
-> Sound.SC3.UGen.DB.ugenSummary "Trig"
-
-> import Sound.SC3.ID
-
-> let {d = dust 'α' AR 1
->     ;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
deleted file mode 100644
--- a/Help/UGen/Trigger/trig1.help.lhs
+++ /dev/null
@@ -1,8 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Trig1"
-> Sound.SC3.UGen.DB.ugenSummary "Trig1"
-
-> import Sound.SC3.ID
-
-> let {d = dust 'α' AR 1
->     ;o = fSinOsc AR 800 0 * 0.2}
-> in audition (out 0 (trig1 d 0.2 * o))
diff --git a/Help/UGen/Wavelets/dwt.help.lhs b/Help/UGen/Wavelets/dwt.help.lhs
deleted file mode 100644
--- a/Help/UGen/Wavelets/dwt.help.lhs
+++ /dev/null
@@ -1,3 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DWT"
-> Sound.SC3.UGen.DB.ugenSummary "DWT"
-
diff --git a/Help/UGen/Wavelets/idwt.help.lhs b/Help/UGen/Wavelets/idwt.help.lhs
deleted file mode 100644
--- a/Help/UGen/Wavelets/idwt.help.lhs
+++ /dev/null
@@ -1,32 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "IDWT"
-> Sound.SC3.UGen.DB.ugenSummary "IDWT"
-
-> import Sound.SC3.ID
-
-> let {i = whiteNoise 'α' AR * 0.05
->     ;b = localBuf 'β' 1024 1
->     ;c = dwt b i 0.5 0 1 0 0}
-> in audition (out 0 (mce2 (idwt c 0 0 0) i))
-
-direct synthesis via writing values to buffer (try changing wavelet
-type...)
-> withSC3 (async (b_alloc 10 1024 1) >> send (b_zero 10))
-
-> let {c = fftTrigger 10 0.5 0
->     ;i = idwt c (-1) 0 0}
-> in audition (out 0 (i * 0.1))
-
-> import Control.Monad.Random
-> import Sound.SC3.Lang.Random.Monad
-
-> withSC3 (send (b_zero 10))
-
-run this to change sound: WARNING, NOISY!
-> do {a <- evalRandIO (nrrand 1024 (-1) 1)
->    ;withSC3 (send (b_setn 10 [(0,a)]))}
-
-> let a = map (/ 1024) [0..1023]
-> in withSC3 (send (b_setn 10 [(0,a)]))
-
-> let a = map (\i -> 1 - i / 1024) [0..1023]
-> in withSC3 (send (b_setn 10 [(0,a)]))
diff --git a/Help/UGen/Wavelets/wt_FilterScale.help.lhs b/Help/UGen/Wavelets/wt_FilterScale.help.lhs
deleted file mode 100644
--- a/Help/UGen/Wavelets/wt_FilterScale.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "WT_FilterScale"
-> Sound.SC3.UGen.DB.ugenSummary "WT_FilterScale"
-
-> import Sound.SC3.ID
-
-> let {i = whiteNoise 'α' AR * 0.2
->     ;b = localBuf 'β' 2048 1
->     ;c = dwt b i 0.5 0 1 0 0
->     ;x = mouseX KR (-1) 1 Linear 0.1
->     ;c' = wt_FilterScale c x}
-> in audition (out 0 (pan2 (idwt c' 0 0 0) x 1))
diff --git a/Help/UGen/Wavelets/wt_TimeWipe.help.lhs b/Help/UGen/Wavelets/wt_TimeWipe.help.lhs
deleted file mode 100644
--- a/Help/UGen/Wavelets/wt_TimeWipe.help.lhs
+++ /dev/null
@@ -1,11 +0,0 @@
-> Sound.SC3.UGen.Help.viewSC3Help "WT_TimeWipe"
-> Sound.SC3.UGen.DB.ugenSummary "WT_TimeWipe"
-
-> import Sound.SC3.ID
-
-> let {i = whiteNoise 'α' AR * 0.2
->     ;b = localBuf 'β' 2048 1
->     ;c = dwt b i 0.5 0 1 0 0
->     ;x = mouseX KR 0 1 Linear 0.1
->     ;c' = wt_TimeWipe c x}
-> in audition (out 0 (pan2 (idwt c' 0 0 0) (x * 2 - 1) 1))
diff --git a/Help/UGen/abs.help.lhs b/Help/UGen/abs.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/abs.help.lhs
@@ -0,0 +1,6 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.abs"
+    > :t abs
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = abs (syncSaw AR 100 440 * 0.1)
diff --git a/Help/UGen/absDif.help.lhs b/Help/UGen/absDif.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/absDif.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.absdif"
+    > :t absDif
+
+> import Sound.SC3 {- hsc3 -}
+
+Finding the magnitude of the difference of two values is a common operation.
+
+> g_01 =
+>     let p = fSinOsc AR 440 0
+>         q = fSinOsc AR 2 0 * 0.5
+>     in p * 0.2 `absDif` q
diff --git a/Help/UGen/add.help.lhs b/Help/UGen/add.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/add.help.lhs
@@ -0,0 +1,13 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.+"
+    > :t (+)
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let o = fSinOsc AR 800 0
+>         n = pinkNoise 'α' AR
+>     in (o + n) * 0.1
+
+DC offset.
+
+> g_02 = fSinOsc AR 440 0 * 0.1 + 0.5
diff --git a/Help/UGen/allpassC.help.lhs b/Help/UGen/allpassC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/allpassC.help.lhs
@@ -0,0 +1,1 @@
+See allPassN
diff --git a/Help/UGen/allpassL.help.lhs b/Help/UGen/allpassL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/allpassL.help.lhs
@@ -0,0 +1,1 @@
+See allPassN
diff --git a/Help/UGen/allpassN.help.lhs b/Help/UGen/allpassN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/allpassN.help.lhs
@@ -0,0 +1,44 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "AllpassN"
+    > Sound.SC3.UGen.DB.ugenSummary "AllpassN"
+
+> import Sound.SC3 {- hsc3 -}
+
+Since the allpass delay has no audible effect as a resonator on steady
+state sound ...
+
+> g_01 =
+>     let dly = xLine KR 0.0001 0.01 20 RemoveSynth
+>         n = whiteNoise 'α' AR
+>     in 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.
+
+> g_02 =
+>     let n = whiteNoise 'β' AR
+>         dly = xLine KR 0.0001 0.01 20 RemoveSynth
+>     in (n + allpassN (n * 0.1) 0.01 dly 0.2) * 0.1
+
+Linear variant
+
+> g_03 =
+>     let n = whiteNoise 'γ' AR
+>         dly = xLine KR 0.0001 0.01 20 RemoveSynth
+>     in (n + allpassL (n * 0.1) 0.01 dly 0.2) * 0.1
+
+Cubic variant
+
+> g_04 =
+>     let n = whiteNoise 'δ' AR
+>         dly = xLine KR 0.0001 0.01 20 RemoveSynth
+>     in (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.
+
+> g_05 =
+>     let n = whiteNoise 'ε' AR
+>         d = dust 'ζ' AR 1
+>         src = decay (d * 0.5) 0.2 * n
+>     in allpassN src 0.2 0.2 3
diff --git a/Help/UGen/amClip.help.lhs b/Help/UGen/amClip.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/amClip.help.lhs
@@ -0,0 +1,6 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.amclip"
+    > :t amClip
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = amClip (whiteNoise 'α' AR) (fSinOsc KR 1 0 * 0.2)
diff --git a/Help/UGen/ampComp.help.lhs b/Help/UGen/ampComp.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ampComp.help.lhs
@@ -0,0 +1,39 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "AmpComp"
+    > Sound.SC3.UGen.DB.ugenSummary "AmpComp"
+
+> import Sound.SC3 {- hsc3 -}
+
+mouse X axis frequency control
+
+> x_freq = mouseX KR 300 1500 Exponential 0.2
+
+> ampComp' :: Bool -> Rate -> UGen -> UGen -> UGen -> UGen
+> ampComp' use_comp r fr rt ex = if use_comp then ampComp r fr rt ex else 1
+
+> f_01 use_comp = sinOsc AR x_freq 0 * 0.1 * ampComp' use_comp KR x_freq 300 0.3333
+
+without amplitude compensation
+
+> g_01 = f_01 False
+
+with amplitude compensation
+
+> g_02 = f_01 True
+
+modified exponent
+
+> g_03 = pulse AR x_freq 0.5 * 0.1 * ampComp KR x_freq 300 1.3
+
+in frequency modulation
+
+> f_02 use_comp =
+>     let freq = x_freq * sinOsc AR (mouseY KR 3 200 Exponential 0.2) 0 * 0.5 + 1
+>     in sinOsc AR freq 0 * 0.1 * ampComp' use_comp KR freq 300 0.3333
+
+with amplitude compensation
+
+> g_04 = f_02 True
+
+without amplitude compensation
+
+> g_05 = f_02 False
diff --git a/Help/UGen/amplitude.help.lhs b/Help/UGen/amplitude.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/amplitude.help.lhs
@@ -0,0 +1,19 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Amplitude"
+    > Sound.SC3.UGen.DB.ugenSummary "Amplitude"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let s = soundIn 0
+>         a = amplitude KR s 0.01 0.01
+>     in pulse AR 90 0.3 * a
+>
+> g_02 =
+>     let s = soundIn 0
+>         f = amplitude KR s 0.5 0.5 * 1200 + 400
+>     in sinOsc AR f 0 * 0.1
+>
+> g_03 =
+>     let s = soundIn 0
+>         a = amplitude AR s 0.5 0.05
+>     in s * a
diff --git a/Help/UGen/atan2.help.lhs b/Help/UGen/atan2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/atan2.help.lhs
@@ -0,0 +1,18 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.atan2"
+    > :t atan2
+
+> import Sound.SC3 {- hsc3 -}
+
+Add a pan to the hypot doppler examples by using atan2 to find the
+azimuth, or direction angle, of the sound source.  Assume speakers
+at +/- 45 degrees and clip the direction to between those.
+
+> g_01 =
+>     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 pan2 (delayL s (110 / 344) (d / 344)) l a
diff --git a/Help/UGen/atari2600.help.lhs b/Help/UGen/atari2600.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/atari2600.help.lhs
@@ -0,0 +1,79 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Atari2600"
+    > Sound.SC3.UGen.DB.ugenSummary "Atari2600"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Lang.Pattern {- hsc3-lang -}
+
+> gr_00 = atari2600 1 2 3 4 5 5 1
+
+> gr_01 = atari2600 2 3 10 10 5 5 1
+
+> gr_02 =
+>     let x = mouseX KR 0 15 Linear 0.1
+>         y = mouseY KR 0 15 Linear 0.1
+>     in atari2600 x y 10 10 5 5 1
+
+> gr_03 =
+>     let x = mouseX KR 0 31 Linear 0.1
+>         y = mouseY KR 0 31 Linear 0.1
+>     in atari2600 2 3 x y 5 5 1
+
+> gr_04 =
+>     let x = mouseX KR 0 15 Linear 0.1
+>         y = mouseY KR 0 15 Linear 0.1
+>     in atari2600 2 3 10 10 x y 1
+
+> gr_05 =
+>     let x = mouseX KR 0 15 Linear 0.1
+>         o1 = sinOsc KR 0.35 0 * 7.5 + 7.5
+>         y = mouseY KR 0 31 Linear 0.1
+>         o2 = sinOsc KR 0.3 0 * 5.5 + 5.5
+>     in atari2600 x o1 10 y o2 5 1
+
+> ati_syn =
+>     let gate' = control KR "gate" 1
+>         tone0 = control KR "tone0" 5
+>         tone1 = control KR "tone1" 8
+>         freq0 = control KR "freq0" 10
+>         freq1 = control KR "freq1" 20
+>         rate = control KR "rate" 1
+>         amp = control KR "amp" 1
+>         pan = control KR "pan" 0
+>         e = envASR 0.01 amp 0.05 (EnvNum (-4))
+>         eg = envGen KR gate' 1 0 1 RemoveSynth e
+>         z = atari2600 tone0 tone1 freq0 freq1 15 15 rate
+>         o = out 0 (pan2 (z * eg) pan 1)
+>     in synthdef "atari2600" o
+
+> p_01 =
+>     [(K_instr,psynth ati_syn)
+>     ,(K_dur,0.125)
+>     ,(K_amp,0.5)
+>     ,(K_param "tone0",pseq [pn 3 64,pn 2 128,pn 10 8] inf)
+>     ,(K_param "tone1",pseqn [32,12] [8,pwhite 'α' 0 15 inf] inf)
+>     ,(K_param "freq0",pseqn [17,4,3] [10,prand 'β' [1,2,3] inf,10] inf)
+>     ,(K_param "freq1",pseq1 [10,3,pwrand 'γ' [20,1] [0.6,0.4] inf] inf)]
+
+    paudition (pbind p_01)
+
+> p_02 =
+>     [(K_instr,psynth ati_syn)
+>     ,(K_dur,pseq [0.25,0.25,0.25,0.45] inf)
+>     ,(K_amp,0.5)
+>     ,(K_param "tone0",pseq [pseq [2,5] 32,pseq [3,5] 32] inf)
+>     ,(K_param "tone1",14)
+>     ,(K_param "freq0",pseq [pbrown 'α' 28 31 1 32,pbrown 'β' 23 26 3 32] inf)
+>     ,(K_param "freq1",pseq [pn 10 16,pn 11 16] inf)]
+
+    paudition (pbind p_03)
+
+> p_03 =
+>     [(K_instr,psynth ati_syn)
+>     ,(K_dur,pbrown 'α' 0.1 0.15 0.1 inf)
+>     ,(K_amp,0.5)
+>     ,(K_param "tone0",1)
+>     ,(K_param "tone1",2)
+>     ,(K_param "freq0",pseqn [2,1] [24,pwrand 'β' [20,23] [0.6,0.4] inf] inf)
+>     ,(K_param "freq1",pseqn [1,1,1] [1,3,pwrand 'γ' [2,1] [0.6,0.4] inf] inf)]
+
+    paudition (pbind p_03)
diff --git a/Help/UGen/atsNoiSynth.help.lhs b/Help/UGen/atsNoiSynth.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/atsNoiSynth.help.lhs
@@ -0,0 +1,36 @@
+    Sound.SC3.UGen.Help.viewSC3Help "AtsNoiSynth"
+    Sound.SC3.UGen.DB.ugenSummary "AtsNoiSynth"
+
+> import System.IO.Unsafe {- base -}
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Data.ATS {- hsc3-data -}
+>
+> ats_fn_0 = "/home/rohan/data/audio/pf-c5.4.ats"
+> ats_fn_1 = "/home/rohan/cvs/tn/tn-56/ats/metal.ats"
+
+load ATS file at scsynth
+
+    > ats_load_sc3 0 ats_fn_0
+    > withSC3 (b_query1_unpack 0)
+
+read ATS header
+
+> ats_hdr_0 = unsafePerformIO (fmap ats_header (ats_read ats_fn_0))
+> ats_hdr_1 = unsafePerformIO (fmap ats_header (ats_read ats_fn_1))
+
+    > putStrLn $ ats_header_pp ats_hdr_0
+    > putStrLn $ ats_header_pp ats_hdr_1
+
+run re-synthesis
+
+> g_01 =
+>     let np = constant (ats_n_partials ats_hdr_0)
+>         ptr = lfSaw KR (constant (1 / ats_analysis_duration ats_hdr_0)) 1 * 0.5 + 0.5
+>     in atsNoiSynth 0 np 0 1 ptr 1 0.1 1 0 25 0 1
+
+> g_02 =
+>     let x = mouseX KR 0.0 1.0 Linear 0.2
+>         y = mouseY KR 0.0 1.0 Linear 0.2
+>         np = constant (ats_n_partials ats_hdr_0)
+>     in atsNoiSynth 0 np 0 1 x (1 - y) y 1 0 25 0 1
+
diff --git a/Help/UGen/atsSynth.help.lhs b/Help/UGen/atsSynth.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/atsSynth.help.lhs
@@ -0,0 +1,29 @@
+    Sound.SC3.UGen.Help.viewSC3Help "AtsSynth"
+    Sound.SC3.UGen.DB.ugenSummary "AtsSynth"
+
+> import System.IO.Unsafe {- base -}
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Data.ATS {- hsc3-data -}
+
+> ats_fn_0 = "/home/rohan/data/audio/pf-c5.4.ats"
+> ats_fn_1 = "/home/rohan/cvs/tn/tn-56/ats/metal.ats"
+
+    > ats_load_sc3 0 ats_fn
+    > withSC3 (b_query1_unpack 0)
+
+read file
+
+> ats_hdr_0 = unsafePerformIO (fmap ats_header (ats_read ats_fn_0))
+> ats_hdr_1 = unsafePerformIO (fmap ats_header (ats_read ats_fn_1))
+
+show header
+
+    > putStrLn $ ats_header_pp ats_hdr_0
+
+simple re-synthesiser, ATS data is at buffer 0
+
+> g_01 =
+>     let x = mouseX KR 0.0 1.0 Linear 0.2
+>         y = mouseY KR 0.75 1.25 Linear 0.2
+>         np = constant (ats_n_partials ats_hdr_0)
+>     in atsSynth 0 np 0 1 x y 0
diff --git a/Help/UGen/ay.help.lhs b/Help/UGen/ay.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ay.help.lhs
@@ -0,0 +1,34 @@
+    Sound.SC3.UGen.Help.viewSC3Help "AY"
+    Sound.SC3.UGen.DB.ugenSummary "AY"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = ay 1777 1666 1555 1 7 15 15 15 4 1 0
+>
+> g_02 =
+>     let tonea = mouseY KR 10 3900 Exponential 0.2
+>         toneb = mouseX KR 10 3900 Exponential 0.2
+>         ctl = 3
+>         vola = 14
+>         volb = 14
+>         volc = 0
+>         s = ay tonea toneb 1555 1 ctl vola volb volc 4 1 0
+>     in pan2 s 0 0.25
+>
+> g_03 =
+>     let rate = mouseX KR 0.1 10 Linear 0.2
+>         rng l r i = linLin i (-1) 1 l r
+>         mk_ctl e l r = rng l r (lfdNoise3 e KR rate)
+>         mk_ctl_0 e l r = rng l r (lfdNoise0 e KR rate)
+>         tonea = mk_ctl 'α' 10 3900
+>         toneb = mk_ctl 'β' 10 3900
+>         tonec = mk_ctl 'γ' 10 3900
+>         n = mk_ctl 'δ' 0 31
+>         ctl = mk_ctl_0 'ε' 0 31
+>         vola = mk_ctl 'ζ' 0 15
+>         volb = mk_ctl 'η' 0 15
+>         volc = mk_ctl 'θ' 0 15
+>         efreq = mk_ctl 'ι' 0 4095
+>         estyle = mk_ctl 'κ' 0 15
+>         s = ay tonea toneb tonec n ctl vola volb volc efreq estyle 0
+>     in pan2 s 0 0.5
diff --git a/Help/UGen/bBandPass.help.lhs b/Help/UGen/bBandPass.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bBandPass.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BBandPass"
+    Sound.SC3.UGen.DB.ugenSummary "BBandPass"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = soundIn 4
+>         f = mouseX KR 20 20000 Exponential 0.2
+>         bw = mouseY KR 0 10 Linear 0.2
+>     in bBandPass i f bw
diff --git a/Help/UGen/bBandStop.help.lhs b/Help/UGen/bBandStop.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bBandStop.help.lhs
@@ -0,0 +1,16 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BBandStop"
+    Sound.SC3.UGen.DB.ugenSummary "BBandStop"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = soundIn (mce2 0 1)
+>         f = mouseX KR 20 20000 Exponential 0.2
+>         bw = mouseY KR 0 10 Linear 0.2
+>     in bBandStop i f bw
+
+> g_02 =
+>     let i = sinOsc AR 1000 (mce2 0 0)
+>         f = mouseX KR 800 1200 Exponential 0.2
+>         bw = mouseY KR 0 10 Linear 0.2
+>     in bBandStop i f bw
diff --git a/Help/UGen/bHiPass.help.lhs b/Help/UGen/bHiPass.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bHiPass.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BHiPass"
+    Sound.SC3.UGen.DB.ugenSummary "BHiPass"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = whiteNoise 'α' AR {- soundIn (mce2 0 1) -}
+>         f = mouseX KR 10 20000 Exponential 0.2
+>         rq = mouseY KR 0 1 Linear 0.2
+>     in bHiPass i f rq
diff --git a/Help/UGen/bHiShelf.help.lhs b/Help/UGen/bHiShelf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bHiShelf.help.lhs
@@ -0,0 +1,16 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BHiShelf"
+    Sound.SC3.UGen.DB.ugenSummary "BHiShelf"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = soundIn 0
+>         f = mouseX KR 2200 18000 Exponential 0.2
+>         db = mouseY KR 18 (-18) Linear 0.2
+>     in bHiShelf i f 1 db
+
+> g_02 =
+>     let i = soundIn 4
+>         f = mouseX KR 2200 18000 Exponential 0.2
+>         rs = mouseY KR 0.1 1 Linear 0.2
+>     in bHiShelf i f rs 6
diff --git a/Help/UGen/bLowPass.help.lhs b/Help/UGen/bLowPass.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bLowPass.help.lhs
@@ -0,0 +1,27 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BLowPass"
+    > Sound.SC3.UGen.DB.ugenSummary "BLowPass"
+    > :t bLowPassCoef
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let i = soundIn (mce2 0 1)
+>         f = mouseX KR 10 20000 Exponential 0.2
+>         rq = mouseY KR 0 1 Linear 0.2
+>     in bLowPass i f rq
+>
+> g_02 =
+>     let i = mix (saw AR (mce [0.99, 1, 1.01] * 440) * 0.3)
+>         f = mouseX KR 100 20000 Exponential 0.2
+>         rq = mouseY KR 0.1 1 Linear 0.2
+>     in bLowPass i f rq
+
+Calculate coefficients and use sos.
+
+> g_03 =
+>     let i = mix (saw AR (mce [0.99, 1, 1.01] * 440) * 0.3)
+>         f = mouseX KR 100 20000 Exponential 0.2
+>         rq = mouseY KR 0.1 1 Linear 0.2
+>         (a0, a1, a2, b1, b2) = bLowPassCoef sampleRate f rq
+>         flt ip = sos ip a0 a1 a2 b1 b2
+>     in flt (flt i)
diff --git a/Help/UGen/bLowShelf.help.lhs b/Help/UGen/bLowShelf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bLowShelf.help.lhs
@@ -0,0 +1,18 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BLowShelf"
+    Sound.SC3.UGen.DB.ugenSummary "BLowShelf"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = soundIn (mce2 0 1)
+>         freq = mouseX KR 40 6000 Exponential 0.2
+>         rs = 1
+>         db = mouseY KR 24 (-24) Linear 0.2
+>     in bLowShelf i freq rs db
+
+> g_02 =
+>     let i = soundIn (mce2 0 1)
+>         freq = mouseX KR 20 6000 Exponential 0.2
+>         rs = mouseY KR 0.1 1 Linear 0.2
+>         db = 6
+>     in bLowShelf i freq rs db
diff --git a/Help/UGen/bPeakEQ.help.lhs b/Help/UGen/bPeakEQ.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bPeakEQ.help.lhs
@@ -0,0 +1,16 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BPeakEQ"
+    Sound.SC3.UGen.DB.ugenSummary "BPeakEQ"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = soundIn 0
+>         freq = mouseX KR 2200 18000 Exponential 0.2
+>         db = mouseY KR 12 (-12) Linear 0.2
+>     in bPeakEQ i freq 0.8 db
+
+> g_02 =
+>     let i = soundIn 0
+>         freq = mouseX KR 2200 18000 Exponential 0.2
+>         rq = mouseY KR 10 0.4 Linear 0.2
+>     in bPeakEQ i freq rq 6
diff --git a/Help/UGen/balance2.help.lhs b/Help/UGen/balance2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/balance2.help.lhs
@@ -0,0 +1,43 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Balance2"
+    Sound.SC3.UGen.DB.ugenSummary "Balance2"
+
+> import Sound.SC3 {- hsc3 -}
+
+{Balance2.ar(LFSaw.ar(44),Pulse.ar(33),FSinOsc.kr(0.5),0.1)}.play
+
+> g_01 =
+>     let l = lfSaw AR 44 0
+>         r = pulse AR 33 0.5
+>         p = fSinOsc KR 0.5 0
+>     in balance2 l r p 0.1
+
+{var s=SinOsc.ar([440,550]);Balance2.ar(s[0],s[1],LFNoise0.kr(4),0.3)}.play
+
+> g_02 =
+>     let [s0,s1] = mceChannels (sinOsc AR (mce2 440 550) 0)
+>         n = lfNoise0 'α' KR 4
+>     in balance2 s0 s1 n 0.3
+
+{var s=SinOsc.ar(440);Out.ar(0,0.2*Balance2.ar(s,s,SinOsc.kr(0.2)))}.play
+
+> g_03 =
+>     let s = sinOsc AR 440 0
+>         p = sinOsc KR 0.2 0
+>     in balance2 s s p 1 * 0.2
+
+{var s=SinOsc.ar(440);Out.ar(0,Balance2.ar(s,s,SinOsc.kr(0.2),0.2))}.play
+
+> g_04 =
+>     let s = sinOsc AR 440 0
+>         p = sinOsc KR 0.2 0
+>     in balance2 s s p 0.2
+
+    > withSC3 (send (n_trace [-1]))
+
+{var s=SinOsc.ar(440);Out.ar(0,Balance2.ar(s,s,MouseX.kr(-1,1),0.2))}.play
+
+> g_05 =
+>     let s0 = sinOsc AR 440 0
+>         s1 = sinOsc AR 550 0
+>         x = mouseX KR (-1) 1 Linear 0.2
+>     in balance2 s0 s1 x 0.2
diff --git a/Help/UGen/beatTrack.help.lhs b/Help/UGen/beatTrack.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/beatTrack.help.lhs
@@ -0,0 +1,17 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BeatTrack"
+    Sound.SC3.UGen.DB.ugenSummary "BeatTrack"
+
+> import Sound.SC3 {- hsc3 -}
+
+    > withSC3 (async (b_alloc 10 1024 1))
+
+> g_01 =
+>     let i = soundIn 0
+>         x = mouseX KR (-1) 1 Linear 0.2
+>         [b, h, q, t] = mceChannels (beatTrack KR (fft' 10 i) x)
+>         f = mce [440, 660, 880]
+>         a = mce [0.4, 0.2, 0.1]
+>         s = mix (sinOsc AR f 0 * a * decay (mce [b, h, q]) 0.05)
+>     in i + 2
+
+
diff --git a/Help/UGen/blip.help.lhs b/Help/UGen/blip.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/blip.help.lhs
@@ -0,0 +1,32 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Blip"
+    Sound.SC3.UGen.DB.ugenSummary "Blip"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = blip AR 440 200 * 0.1
+
+Modulate frequency
+
+> g_02 = let f = xLine KR 20000 200 6 RemoveSynth in blip AR f 100 * 0.1
+
+Modulate number of harmonics.
+
+> g_03 = let nh = line KR 1 100 20 RemoveSynth in blip AR 200 nh * 0.2
+
+Self-modulation at control rate.
+
+> g_04 =
+>     let fr = blip KR 0.25 3 * 300 + 500
+>         nh = blip KR 0.15 2 * 20 + 21
+>     in blip AR fr nh * 0.2
+
+Drawings
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen1 0.1 (blip AR 1000 20)
+
+    import Sound.SC3.Plot.FFT {- hsc3-plot -}
+    plot_ugen_fft1 0.1 (blip AR 1000 20)
+
+![](sw/hsc3/Help/SVG/blip.0.svg)
+![](sw/hsc3/Help/SVG/blip.1.svg)
diff --git a/Help/UGen/blitB3Saw.help.lhs b/Help/UGen/blitB3Saw.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/blitB3Saw.help.lhs
@@ -0,0 +1,19 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BlitB3Saw"
+    Sound.SC3.UGen.DB.ugenSummary "BlitB3Saw"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let f = xLine KR 1000 20 10 DoNothing
+>     in blitB3Saw AR f 0.99 * 0.1
+
+aliasing suddenly appears for very high frequencies
+
+> g_02 =
+>     let f = mouseX KR 10 10000 Exponential 0.2
+>         c = mouseY KR 0.01 0.99 Linear 0.2
+>     in blitB3Saw AR f c * 0.1
+
+comparison
+
+> g_03 = mce2 (saw AR 20) (blitB3Saw AR 20 0.99) * 0.1
diff --git a/Help/UGen/blitB3Square.help.lhs b/Help/UGen/blitB3Square.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/blitB3Square.help.lhs
@@ -0,0 +1,26 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BlitB3Square"
+    Sound.SC3.UGen.DB.ugenSummary "BlitB3Square"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let f = xLine KR 1000 20 10 DoNothing
+>     in blitB3Square AR f 0.99 * 0.1
+
+aliasing suddenly appears for very high frequencies
+
+> g_02 =
+>     let f = mouseX KR 20 10000 Exponential 0.2
+>         c = mouseY KR 0.001 0.999 Linear 0.2
+>     in blitB3Square AR f c * 0.1
+
+difference in CPU usage (excessive wire use,-w 1024)
+
+> g_03 sqr_osc =
+>     let f z = midiCPS (range 36 72 (lfNoise0 z KR (rand z 2 3)))
+>         l z = rand z (-1) 1
+>         o z = pan2 (sqr_osc AR (f z) * 0.1) (l z) 0.1
+>     in sum (map o [0::Int .. 99])
+
+> g_04 = g_03 (\rt f -> blitB3Square rt f 0.99)
+> g_05 = g_03 (\rt f -> pulse rt f 0.5)
diff --git a/Help/UGen/blitB3Tri.help.lhs b/Help/UGen/blitB3Tri.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/blitB3Tri.help.lhs
@@ -0,0 +1,19 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BlitB3Tri"
+    Sound.SC3.UGen.DB.ugenSummary "BlitB3Tri"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = blitB3Tri AR (xLine KR 1000 20 10 DoNothing) 0.99 0.99 * 0.1
+
+unfortunately, aliasing returns at higher frequencies
+(over 5000Hz or so) with a vengence
+
+> g_02 = let x = mouseX KR 20 8000 Exponential 0.2
+>            y = mouseY KR 0.001 0.99 Linear 0.2
+>        in blitB3Tri AR x 0.99 y
+
+more efficient, some aliasing from 3000, but not so scary over 5000
+Duller sound (less high harmonics included for lower fundamentals)
+
+> g_03 = let x = mouseX KR 20 8000 Exponential 0.2
+>        in lfTri AR x 0
diff --git a/Help/UGen/bpf.help.lhs b/Help/UGen/bpf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bpf.help.lhs
@@ -0,0 +1,27 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BPF"
+    Sound.SC3.UGen.DB.ugenSummary "BPF"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
+>     in bpf (saw AR 200 * 0.5) f 0.3
+
+> g_02 =
+>     let x = mouseX KR 100 10000 Exponential 0.2
+>     in bpf (saw AR 200 * 0.5) x 0.3
+
+> g_03 =
+>     let n = whiteNoise 'α' AR
+>         x = mouseX KR 220 440 Exponential 0.1
+>         y = mouseY KR 0.01 0.2 Linear 0.1
+>     in bpf n (mce [x, 550 - x]) y
+
+    import Sound.SC3.Plot.FFT {- hsc3-plot -}
+    plot_ugen_fft1 0.05 (bpf (whiteNoise 'α' AR) 440 0.01)
+
+BPF on control signals:
+
+> g_04 =
+>     let vib = bpf (pinkNoise 'α' KR) (mouseX KR 1 100 Exponential 0.2) 0.3 * 10
+>     in sinOsc AR (vib * 200 + 600) 0 * 0.1
diff --git a/Help/UGen/bpz2.help.lhs b/Help/UGen/bpz2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bpz2.help.lhs
@@ -0,0 +1,8 @@
+   Sound.SC3.UGen.Help.viewSC3Help "BPZ2"
+   Sound.SC3.UGen.DB.ugenSummary "BPZ2"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let n = whiteNoise 'α' AR
+>     in bpz2 (n * 0.25)
diff --git a/Help/UGen/brf.help.lhs b/Help/UGen/brf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/brf.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BRF"
+    Sound.SC3.UGen.DB.ugenSummary "BRF"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = saw AR 200 * 0.1
+>         freq = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3800 + 4000
+>         rq = 0.3
+>     in brf i freq rq
diff --git a/Help/UGen/brownNoise.help.lhs b/Help/UGen/brownNoise.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/brownNoise.help.lhs
@@ -0,0 +1,21 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BrownNoise"
+    Sound.SC3.UGen.DB.ugenSummary "BrownNoise"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = brownNoise 'α' AR * 0.1
+>
+> g_02 =
+>     let n = brownNoise 'α' KR
+>     in sinOsc AR (linExp n (-1) 1 64 9600) 0 * 0.1
+
+Drawing
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen1 0.1 (brownNoise 'γ' AR)
+
+    import Sound.SC3.Plot.FFT {- hsc3-plot -}
+    plot_ugen_fft1 0.1 (brownNoise 'γ' AR)
+
+![](sw/hsc3/Help/SVG/brownNoise.0.svg)
+![](sw/hsc3/Help/SVG/brownNoise.1.svg)
diff --git a/Help/UGen/bufAllpassC.help.lhs b/Help/UGen/bufAllpassC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufAllpassC.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BufAllpassC"
+    > Sound.SC3.UGen.DB.ugenSummary "BufAllpassC"
+
+> import Sound.SC3 {- hsc3 -}
+
+Allocate buffer
+
+    > withSC3 (async (b_alloc 0 44100 1))
+
+Filtered decaying noise bursts
+
+> g_01 =
+>     let d = dust 'α' AR 1
+>         n = whiteNoise 'β' AR
+>         x = decay d 0.2 * n * 0.25
+>     in bufAllpassC 0 x 0.25 6
diff --git a/Help/UGen/bufAllpassL.help.lhs b/Help/UGen/bufAllpassL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufAllpassL.help.lhs
@@ -0,0 +1,1 @@
+See bufAllpassC
diff --git a/Help/UGen/bufAllpassN.help.lhs b/Help/UGen/bufAllpassN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufAllpassN.help.lhs
@@ -0,0 +1,1 @@
+See bufAllpassC
diff --git a/Help/UGen/bufChannels.help.lhs b/Help/UGen/bufChannels.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufChannels.help.lhs
@@ -0,0 +1,2 @@
+> Sound.SC3.UGen.Help.viewSC3Help "BufChannels"
+> Sound.SC3.UGen.DB.ugenSummary "BufChannels"
diff --git a/Help/UGen/bufCombC.help.lhs b/Help/UGen/bufCombC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufCombC.help.lhs
@@ -0,0 +1,32 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BufCombC"
+    > Sound.SC3.UGen.DB.ugenSummary "BufCombC"
+
+> import Sound.SC3 {- hsc3 -}
+
+Allocate buffer zero (required for examples below)
+
+    > withSC3 (async (b_alloc 0 44100 1))
+
+Comb filter as resonator. The resonant fundamental is equal to
+reciprocal of the delay time.
+
+> g_01 =
+>     let n = whiteNoise 'α' AR
+>         dt = xLine KR 0.0001 0.01 20 RemoveSynth
+>     in bufCombC 0 (n * 0.1) dt 0.2
+
+With negative feedback
+
+> g_02 =
+>     let n = whiteNoise 'α' AR
+>         dt = xLine KR 0.0001 0.01 20 RemoveSynth
+>     in bufCombC 0 (n * 0.1) dt (-0.2)
+
+Used as an echo (filtered decaying noise bursts)
+
+> g_03 =
+>     let d = dust 'α' AR 1
+>         n = whiteNoise 'β' AR
+>         i = decay (d * 0.5) 0.2 * n
+>     in bufCombC 0 i 0.2 3
+
diff --git a/Help/UGen/bufCombL.help.lhs b/Help/UGen/bufCombL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufCombL.help.lhs
@@ -0,0 +1,1 @@
+See bufCombC
diff --git a/Help/UGen/bufCombN.help.lhs b/Help/UGen/bufCombN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufCombN.help.lhs
@@ -0,0 +1,1 @@
+See bufCombC
diff --git a/Help/UGen/bufDelayC.help.lhs b/Help/UGen/bufDelayC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufDelayC.help.lhs
@@ -0,0 +1,26 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BufDelayC"
+    > Sound.SC3.UGen.DB.ugenSummary "BufDelayC"
+
+> import Sound.SC3 {- hsc3 -}
+
+Allocate buffer zero (required for examples below)
+
+    > withSC3 (async (b_alloc 0 44100 1))
+
+Dust randomly triggers Decay to create an exponential decay envelope
+for the WhiteNoise input source.  The input is mixed with the delay.
+
+> g_01 =
+>     let t = dust 'α' AR 1
+>         n = whiteNoise 'β' AR
+>         d = decay t 0.5 * n * 0.3
+>     in bufDelayC 0 d 0.2 + d
+
+Mouse control for delay time
+
+> g_02 =
+>     let t = dust 'α' AR 1
+>         n = whiteNoise 'β' AR
+>         d = decay t 0.3 * n
+>         x = mouseX KR 0.0 0.2 Linear 0.1
+>     in d + bufDelayC 0 d x
diff --git a/Help/UGen/bufDelayL.help.lhs b/Help/UGen/bufDelayL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufDelayL.help.lhs
@@ -0,0 +1,1 @@
+See bufDelayC
diff --git a/Help/UGen/bufDelayN.help.lhs b/Help/UGen/bufDelayN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufDelayN.help.lhs
@@ -0,0 +1,1 @@
+See bufDelayC
diff --git a/Help/UGen/bufDur.help.lhs b/Help/UGen/bufDur.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufDur.help.lhs
@@ -0,0 +1,17 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BufDur"
+    Sound.SC3.UGen.DB.ugenSummary "BufDur"
+
+> import Sound.SC3 {- hsc3 -}
+
+Load sound file to buffer zero (required for examples)
+
+> fn_01 = "/home/rohan/data/audio/pf-c5.aif"
+
+    > withSC3 (async (b_allocRead 0 fn_01 0 0))
+
+Read without loop, trigger reset based on buffer duration
+
+> g_01 =
+>     let t = impulse AR (recip (bufDur KR 0)) 0
+>         p = sweep t (bufSampleRate KR 0)
+>     in bufRdL 1 AR 0 p NoLoop
diff --git a/Help/UGen/bufFrames.help.lhs b/Help/UGen/bufFrames.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufFrames.help.lhs
@@ -0,0 +1,23 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BufFrames"
+    > Sound.SC3.UGen.DB.ugenSummary "BufFrames"
+
+> import Sound.SC3
+
+Load sound file to buffer zero (required for examples)
+
+> fn_01 = "/home/rohan/data/audio/pf-c5.aif"
+
+    > withSC3 (async (b_allocRead 0 fn_01 0 0))
+
+Read without loop, trigger reset based on buffer duration
+
+> g_01 =
+>     let p = phasor AR 0 (bufRateScale KR 0) 0 (bufFrames KR 0) 0
+>     in bufRdL 1 AR 0 p NoLoop
+
+Mouse location drags play head
+
+> g_02 =
+>     let r = mce [0.05,0.075 .. 0.15]
+>         p = k2A (mouseX KR 0 (bufFrames KR 0) Linear r)
+>     in mix (bufRdL 1 AR 0 p NoLoop)
diff --git a/Help/UGen/bufRateScale.help.lhs b/Help/UGen/bufRateScale.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufRateScale.help.lhs
@@ -0,0 +1,17 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BufRateScale"
+    > Sound.SC3.UGen.DB.ugenSummary "BufRateScale"
+
+> import Sound.SC3 {- hsc 3 -}
+
+Load sound file to buffer zero (required for examples)
+
+> fn_01 = "/home/rohan/data/audio/pf-c5.aif"
+
+    > withSC3 (async (b_allocRead 0 fn_01 0 0))
+
+Read buffer at 3/4 reported sample rate.
+
+> g_01 =
+>     let r = 0.75 * bufRateScale KR 0
+>         p = phasor AR 0 r 0 (bufFrames KR 0) 0
+>     in bufRdL 1 AR 0 p NoLoop
diff --git a/Help/UGen/bufRd.help.lhs b/Help/UGen/bufRd.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufRd.help.lhs
@@ -0,0 +1,43 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BufRd"
+    > Sound.SC3.UGen.DB.ugenSummary "BufRd"
+
+> import Sound.SC3 {- hsc3 -}
+
+Load sound file to buffer zero (required for examples)
+
+> fn_01 = "/home/rohan/data/audio/pf-c5.aif"
+
+    > withSC3 (async (b_allocRead 0 fn_01 0 0))
+
+Phasor as phase input
+
+> g_01 =
+>     let sc = bufRateScale KR 0
+>         tr = impulse AR (recip (bufDur KR 0)) 0
+>         ph = phasor AR tr sc 0 (bufFrames KR 0) 0
+>     in bufRdL 1 AR 0 ph NoLoop
+
+Audio rate sine oscillator as phase input
+
+> g_02 =
+>     let phase = sinOsc AR 0.1 0 * bufFrames KR 0 * bufRateScale KR 0
+>     in bufRd 1 AR 0 phase Loop NoInterpolation
+
+There are constructors, bufRd{N|L|C}, for the fixed cases.
+
+> g_03 =
+>     let x = mouseX KR (mce [5, 10]) 100 Linear 0.1
+>         n = lfNoise1 'α' AR x
+>     in bufRdL 1 AR 0 (n * bufFrames KR 0 * bufRateScale KR 0) Loop
+
+Allocate and generate (non-wavetable) buffer
+
+    > withSC3 (do {_ <- async (b_alloc 11 256 1)
+    >             ;let f = [Normalise,Clear]
+    >              in send (b_gen_sine1 11 f [1,1/2,1/3,1/4,1/5])})
+
+Fixed frequency wavetable oscillator
+
+> g_04 =
+>     let phase = linLin (saw AR 440) (-1) 1 0 1 * bufFrames KR 11
+>     in bufRd 1 AR 11 phase Loop NoInterpolation * 0.1
diff --git a/Help/UGen/bufSampleRate.help.lhs b/Help/UGen/bufSampleRate.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufSampleRate.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BufSampleRate"
+    > Sound.SC3.UGen.DB.ugenSummary "BufSampleRate"
+
+> import Sound.SC3 {- hsc3 -}
+
+Load sound file to buffer zero (required for examples)
+
+> fn_01 = "/home/rohan/data/audio/pf-c5.aif"
+
+    > withSC3 (async (b_allocRead 0 fn_01 0 0))
+
+Sine tone derived from sample rate of buffer an 440Hz tone.
+
+> g_01 =
+>     let f = mce [bufSampleRate KR 0 * 0.01, 440]
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/bufWr.help.lhs b/Help/UGen/bufWr.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bufWr.help.lhs
@@ -0,0 +1,30 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BufWr"
+    > Sound.SC3.UGen.DB.ugenSummary "BufWr"
+
+> import Sound.SC3 {- hsc3 -}
+
+allocate a buffer (id = 0) for writing into
+
+    > withSC3 (send (b_alloc 0 (44100 * 2) 1))
+
+write into the buffer (id = 0) with a bufWr
+
+> wr_gr =
+>     let rt = control KR "wr-rate" 1
+>         o = sinOsc AR (lfNoise1 'α' KR 2 * 300 + 400) 0 * 0.1
+>         w = bufWr 0 (phasor AR 0 (bufRateScale KR 0 * rt) 0 (bufFrames KR 0) 0) Loop o
+>     in mrg2 (silent 1) w
+
+read it with a BufRd
+
+> rd_gr =
+>     let rt = control KR "rd-rate" 1
+>     in bufRdL 1 AR 0 (phasor AR 0 (bufRateScale KR 0 * rt) 0 (bufFrames KR 0) 0) Loop
+
+    > audition wr_gr
+    > audition rd_gr
+
+set read & write rates independently
+
+    > withSC3 (send (n_set1 1 "wr-rate" 0.25))
+    > withSC3 (send (n_set1 1 "rd-rate" 13.0))
diff --git a/Help/UGen/cOsc.help.lhs b/Help/UGen/cOsc.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/cOsc.help.lhs
@@ -0,0 +1,38 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "COsc"
+    > Sound.SC3.UGen.DB.ugenSummary "COsc"
+
+> import Sound.SC3 {- hsc3 -}
+
+Allocate and fill buffer.
+
+> gen_tbl b p = let f = [Normalise,Wavetable,Clear] in b_gen_sine1 b f p
+
+> b_01 :: Num n => n {- or {-# Language NoMonomorphismRestriction #-} -}
+> b_01 = 10
+> b_01_setup = [b_alloc b_01 512 1,gen_tbl b_01 [1,1/2,1/3,1/4,1/5,1/6,1/7,1/8,1/9,1/10]]
+
+    > withSC3 (mapM_ async b_01_setup)
+
+Fixed beat frequency
+
+> g_01 = cOsc AR b_01 200 0.7 * 0.1
+
+Modulate beat frequency with mouseX
+
+> g_02 = cOsc AR b_01 200 (mouseX KR 0 4 Linear 0.2) * 0.1
+
+Compare with plain osc
+
+> g_03 = osc AR b_01 200 0.0 * 0.1
+
+Summing behaviour (<http://article.gmane.org/gmane.comp.audio.supercollider.devel/62575>)
+
+> b_02 :: Num n => n
+> b_02 = 11
+> b_02_setup = [b_alloc b_02 512 1,gen_tbl b_02 [1]]
+
+    > withSC3 (mapM_ async b_02_setup)
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.1 (cOsc AR 11 100 5)
+
+![](sw/hsc3/Help/SVG/cOsc.0.svg)
diff --git a/Help/UGen/changed.help.lhs b/Help/UGen/changed.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/changed.help.lhs
@@ -0,0 +1,12 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Changed"
+    > Sound.SC3.UGen.DB.ugenSummary "Changed"
+
+> import Sound.SC3 {- hsc3 -}
+
+simple composition of hpz1 and >*
+
+> g_01 =
+>     let s = lfNoise0 'α' KR 2
+>         c = changed s 0
+>         c' = decay2 c 0.01 0.5
+>     in sinOsc AR (440 + mce2 s c' * 440) 0 * 0.1
diff --git a/Help/UGen/choose.help.lhs b/Help/UGen/choose.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/choose.help.lhs
@@ -0,0 +1,9 @@
+    :t choose
+
+choose is a composite of iRand and select.
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let f = uclone 'α' 2 (choose 'β' (mce [440,460 .. 880]))
+>     in sinOsc AR f  0 * 0.1
diff --git a/Help/UGen/clip.help.lhs b/Help/UGen/clip.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/clip.help.lhs
@@ -0,0 +1,6 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Clip"
+    > Sound.SC3.UGen.DB.ugenSummary "Clip"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = clip (sinOsc AR 440 0 * 0.4) (-0.25) 0.25
diff --git a/Help/UGen/clip2.help.lhs b/Help/UGen/clip2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/clip2.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.clip2"
+    > :t clip2
+
+> import Sound.SC3 {- hsc3 -}
+
+clipping distortion
+
+> g_01 = clip2 (fSinOsc AR 400 0) 0.2
+>
+> g_02 = clip2 (fSinOsc AR 400 0) (line KR 0 1 8 RemoveSynth)
diff --git a/Help/UGen/clipNoise.help.lhs b/Help/UGen/clipNoise.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/clipNoise.help.lhs
@@ -0,0 +1,13 @@
+    Sound.SC3.UGen.Help.viewSC3Help "ClipNoise"
+    Sound.SC3.UGen.DB.ugenSummary "ClipNoise"
+
+> import Sound.SC3
+>
+> g_01 = clipNoise 'α' AR * 0.1 {- hsc3 -}
+
+Drawings
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen1 0.01 (clipNoise 'α' AR)
+
+![](sw/hsc3/Help/SVG/clipNoise.0.svg)
diff --git a/Help/UGen/coinGate.help.lhs b/Help/UGen/coinGate.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/coinGate.help.lhs
@@ -0,0 +1,9 @@
+    Sound.SC3.UGen.Help.viewSC3Help "CoinGate"
+    Sound.SC3.UGen.DB.ugenSummary "CoinGate"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let g = coinGate 'α' 0.2 (impulse KR 10 0)
+>         f = tRand 'β' 300.0 400.0 g
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/combC.help.lhs b/Help/UGen/combC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/combC.help.lhs
@@ -0,0 +1,1 @@
+See combN
diff --git a/Help/UGen/combL.help.lhs b/Help/UGen/combL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/combL.help.lhs
@@ -0,0 +1,1 @@
+See combN
diff --git a/Help/UGen/combN.help.lhs b/Help/UGen/combN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/combN.help.lhs
@@ -0,0 +1,37 @@
+Sound.SC3.UGen.Help.viewSC3Help "CombN"
+Sound.SC3.UGen.DB.ugenSummary "CombN"
+
+> import Sound.SC3 {- hsc3 -}
+
+Comb filter as resonator. The resonant fundamental is equal to
+reciprocal of the delay time.
+
+> g_01 =
+>     let n = whiteNoise 'α' AR
+>         dt = xLine KR 0.0001 0.01 20 RemoveSynth
+>     in combN (n * 0.1) 0.01 dt 0.2
+
+> g_02 =
+>     let n = whiteNoise 'α' AR
+>         dt = xLine KR 0.0001 0.01 20 RemoveSynth
+>     in combL (n * 0.1) 0.01 dt 0.2
+
+> g_03 =
+>     let n = whiteNoise 'α' AR
+>         dt = xLine KR 0.0001 0.01 20 RemoveSynth
+>     in combC (n * 0.1) 0.01 dt 0.2
+
+With negative feedback
+
+> g_04 =
+>     let n = whiteNoise 'α' AR
+>         dt = xLine KR 0.0001 0.01 20 RemoveSynth
+>     in combC (n * 0.1) 0.01 dt (-0.2)
+
+Used as an echo.
+
+> g_05 =
+>     let d = dust 'α' AR 1
+>         n = whiteNoise 'β' AR
+>         i = decay (d * 0.5) 0.2 * n
+>     in combC i 0.2 0.2 3
diff --git a/Help/UGen/compander.help.lhs b/Help/UGen/compander.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/compander.help.lhs
@@ -0,0 +1,45 @@
+Sound.SC3.UGen.Help.viewSC3Help "Compander"
+Sound.SC3.UGen.DB.ugenSummary "Compander"
+
+> import Sound.SC3
+
+Example signal to process.
+
+> z =
+>     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 e * p
+
+> z' = soundIn 2
+
+    audition (out 0 z)
+
+Noise gate (no hold, no hysteresis)
+
+> g_01 =
+>     let x = mouseX KR 0.01 0.15 Linear 0.1
+>     in mce [z, compander z z x 10 1 0.002 0.15]
+
+Compressor
+
+> g_02 =
+>     let x = mouseX KR 0.01 1 Linear 0.1
+>     in mce [z, compander z z x 1 (1/3) 0.01 0.01]
+
+Expander
+
+> g_03 =
+>     let x = mouseX KR 0.01 1 Linear 0.1
+>     in mce [z, compander z z x 1 3 0.01 0.1]
+
+Limiter
+
+> g_04 =
+>     let x = mouseX KR 0.01 1 Linear 0.1
+>     in mce [z, compander z z x 1 (1/10) 0.01 0.01]
+
+Sustainer
+
+> g_05 =
+>     let x = mouseX KR 0.01 0.15 Linear 0.1
+>     in mce [z, compander z z x (1/3) 1.0 0.01 0.05]
diff --git a/Help/UGen/concat.help.lhs b/Help/UGen/concat.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/concat.help.lhs
@@ -0,0 +1,22 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Concat"
+    Sound.SC3.UGen.DB.ugenSummary "Concat"
+
+> import Sound.SC3 {- hsc3 -}
+
+> fn_01 = "/home/rohan/data/audio/pf-c5.snd"
+
+    withSC3 (async (b_allocRead 12 fn_01 0 0))
+
+Granulator
+
+> gr_01 =
+>     let y0 = mouseY KR 0.01 1 Linear 0.2
+>         y1 = mouseY KR 12 100 Linear 0.2
+>         n = lfNoise0 'α' KR y0 * 3 + 4.5
+>         k = saw AR (sinOsc KR n 0 * 10 + y1)
+>         i = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+>         x0 = mouseX KR 0.01 0.1 Linear 0.2
+>         y2 = mouseY KR 0 0.1 Linear 0.2
+>         c :: UGen
+>         c = concat' k i 2 2 2 x0 0 y2 1 0.5 0 0
+>     in pan2 c 0 1
diff --git a/Help/UGen/controlDur.help.lhs b/Help/UGen/controlDur.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/controlDur.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "ControlDur"
+    > Sound.SC3.UGen.DB.ugenSummary "ControlDur"
+
+> import Sound.SC3 {- hsc3 -}
+
+controlRate and controlDur are reciprocals
+
+> g_01 =
+>    let f = mce2 controlRate (recip controlDur)
+>    in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/controlRate.help.lhs b/Help/UGen/controlRate.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/controlRate.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "ControlRate"
+    > Sound.SC3.UGen.DB.ugenSummary "ControlRate"
+
+> import Sound.SC3 {- hsc3 -}
+
+play a sine tone at control rate, the reciprocal of controlDur
+
+> g_01 =
+>     let f = mce2 controlRate (recip controlDur)
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/convolution.help.lhs b/Help/UGen/convolution.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/convolution.help.lhs
@@ -0,0 +1,8 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Convolution"
+> Sound.SC3.UGen.DB.ugenSummary "Convolution"
+
+> import Sound.SC3
+
+> let {k = whiteNoise 'α' AR
+>     ;i = in' 2 AR numOutputBuses}
+> in audition (out 0 (convolution i k 2048 * 0.1))
diff --git a/Help/UGen/coyote.help.lhs b/Help/UGen/coyote.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/coyote.help.lhs
@@ -0,0 +1,9 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Coyote"
+> Sound.SC3.UGen.DB.ugenSummary "Coyote"
+
+> import Sound.SC3
+
+> let {i = soundIn 0
+>     ;c = coyote KR i 0.2 0.2 0.01 0.5 0.05 0.05
+>     ;o = pinkNoise 'a' AR * decay c 1}
+> in audition (out 0 (mce2 i o))
diff --git a/Help/UGen/crackle.help.lhs b/Help/UGen/crackle.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/crackle.help.lhs
@@ -0,0 +1,19 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Crackle"
+    Sound.SC3.UGen.DB.ugenSummary "Crackle"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = crackle AR 1.95 * 0.2
+
+Modulate chaos parameter
+
+> g_02 = crackle AR (line KR 1.0 2.0 3 RemoveSynth) * 0.2
+
+Drawing
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.01 (crackle AR 1.95)
+    > plot_ugen1 0.025 (crackle AR (line KR 1.0 2.0 0.025 DoNothing))
+
+![](sw/hsc3/Help/SVG/crackle.0.svg)
+![](sw/hsc3/Help/SVG/crackle.1.svg)
diff --git a/Help/UGen/cuspL.help.lhs b/Help/UGen/cuspL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/cuspL.help.lhs
@@ -0,0 +1,25 @@
+    Sound.SC3.UGen.Help.viewSC3Help "CuspL"
+    Sound.SC3.UGen.DB.ugenSummary "CuspL"
+
+> import Sound.SC3 {- hsc3 -}
+
+Vary frequency
+
+> g_01 =
+>     let x = mouseX KR 20 sampleRate Linear 0.1
+>     in cuspL AR x 1.0 1.99 0 * 0.3
+
+Mouse-controlled parameters.
+
+> g_02 =
+>     let x = mouseX KR 0.9 1.1 Linear 0.1
+>         y = mouseY KR 1.8 2.0 Linear 0.1
+>     in cuspL AR (sampleRate / 4) x y 0 * 0.3
+
+As frequency control.
+
+> g_03 =
+>     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 sinOsc AR (n * 800 + 900) 0 * 0.4
diff --git a/Help/UGen/cuspN.help.lhs b/Help/UGen/cuspN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/cuspN.help.lhs
@@ -0,0 +1,1 @@
+See cuspL
diff --git a/Help/UGen/dPW3Tri.help.lhs b/Help/UGen/dPW3Tri.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dPW3Tri.help.lhs
@@ -0,0 +1,44 @@
+    Sound.SC3.UGen.Help.viewSC3Help "DPW3Tri"
+    Sound.SC3.UGen.DB.ugenSummary "DPW3Tri"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins as E {- hsc3 -}
+
+> import qualified Sound.SC3.UGen.External.RDU as RDU {- sc3-rdu -}
+
+distortion creeps in under 200Hz
+
+> g_01 = E.dPW3Tri AR (xLine KR 2000 20 10 DoNothing) * 0.1
+
+very fast sweeps can have transient distortion effects
+
+> g_02 = E.dPW3Tri AR (mouseX KR 200 12000 Exponential 0.2) * 0.2
+
+compare
+
+> g_03 = lfTri AR (mouseX KR 200 12000 Exponential 0.2) 0 * 0.1
+
+less efficient than LFTri
+
+> g_04 = let f = RDU.randN 50 'α' 50 5000
+>        in splay (E.dPW3Tri AR f) 1 0.1 0 True
+
+> g_05 = let f = RDU.randN 50 'α' 50 5000
+>        in splay (lfTri AR f 0) 1 0.1 0 True
+
+triangle is integration of square wave
+
+> g_06 = let f = mouseX KR 440 8800 Exponential 0.2
+>            o = pulse AR f 0.5
+>        in integrator o 0.99 * 0.05
+
+differentiation of triangle is square
+
+> g_07 = let f = mouseX KR 440 8800 Exponential 0.2
+>            o = E.dPW3Tri AR f
+>        in hpz1 (o * 2) * 0.25
+
+compare
+
+> g_08 = let f = mouseX KR 440 8800 Exponential 0.2
+>        in pulse AR f 0.5 * 0.1
diff --git a/Help/UGen/dWGPlucked2.help.lhs b/Help/UGen/dWGPlucked2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dWGPlucked2.help.lhs
@@ -0,0 +1,39 @@
+> Sound.SC3.UGen.Help.viewSC3Help "DWGPlucked2"
+> Sound.SC3.UGen.DB.ugenSummary "DWGPlucked2"
+
+> import Sound.SC3
+
+self deleting
+
+> let {amp = 0.5
+>     ;gate = 1
+>     ;freq = 440
+>     ;c3 = 20
+>     ;pan = 0
+>     ;e = Envelope
+>      [0,1,1,0] [0.001,0.006,0.0005]
+>      (map EnvNum [5,-5,-8]) Nothing Nothing
+>     ;i = amp * lfClipNoise 'α' AR 2000 * envGen AR gate 1 0 1 DoNothing e
+>     ;s = dWGPlucked2 AR freq amp gate 0.1 1 c3 i 0.1 1.008 0.55 0.01
+>     ;z = detectSilence s 0.001 0.1 RemoveSynth}
+> in audition (out 0 (mrg2 (pan2 s pan 0.1) z))
+
+re-sounding
+
+> let {sequ e s tr = demand tr 0 (dseq e dinf (mce s))
+>     ;d = dseq 'α' dinf (mce [1,1,2,1,1,1,2,3,1,1,1,1,2,3,4] * 0.175)
+>     ;t = tDuty AR d 0 DoNothing 1 0
+>     ;amp = tRand 'β' 0.01 0.25 t
+>     ;n0 = sequ 'γ' [60,62,63,58,48,55] t
+>     ;n1 = sequ 'δ' [63,60,48,62,55,58] t
+>     ;freq = midiCPS (mce2 n0 n1)
+>     ;c3 = tRand 'ε' 300 1400 t
+>     ;pan = tRand 'ζ' (-1) 1 t
+>     ;e_dt = tRand 'η' 0.05 0.150 t
+>     ;mt = tRand 'θ' 0.992 1.008 t
+>     ;pp = tRand 'ι' 0.05 0.15 t
+>     ;dt = tRand 'κ' 0.25 1.75 t
+>     ;env = decay2 t 0.001 e_dt * lfClipNoise 'λ' AR 2000
+>     ;i = amp * lfClipNoise 'μ' AR 2000 * env
+>     ;ps = dWGPlucked2 AR freq amp 1 pp (1 / dt) c3 i 0.1 mt 0.55 0.01}
+> in audition (out 0 (pan2 ps pan 0.1))
diff --git a/Help/UGen/dbAmp.help.lhs b/Help/UGen/dbAmp.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dbAmp.help.lhs
@@ -0,0 +1,14 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.dbamp"
+    > :t dbAmp
+
+> import Sound.SC3 {- hsc3 -}
+
+Linear db motion is exponential amplitude decay
+
+> g_01 =
+>     let a = dbAmp (line KR (-12) (-40) 10 RemoveSynth)
+>     in fSinOsc AR 800 0 * a
+
+There is a non-UGen variant.
+
+    > dbAmp (-26::Double) == 0.05011872336272722
diff --git a/Help/UGen/dbrown.help.lhs b/Help/UGen/dbrown.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dbrown.help.lhs
@@ -0,0 +1,10 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Dbrown"
+> Sound.SC3.UGen.DB.ugenSummary "Dbrown"
+
+> import Sound.SC3 {- hsc3 -}
+
+> let {n = dbrown 'α' dinf 0 15 1
+>     ;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/dbufrd.help.lhs b/Help/UGen/dbufrd.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dbufrd.help.lhs
@@ -0,0 +1,42 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dbufrd"
+    > Sound.SC3.UGen.DB.ugenSummary "Dbufrd"
+
+> import Sound.SC3 {- hsc3 -}
+> import System.Random {- random -}
+
+setup pattern at buffer 10
+
+    > let n = randomRs (200.0,500.0) (mkStdGen 0)
+    > in withSC3 (async (b_alloc_setn1 10 0 (take 24 n)))
+
+pattern as frequency input
+
+> g_01 =
+>     let 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
+>     in sinOsc AR (demand t 0 r) 0 * 0.1
+
+setup time pattern
+
+    > let {i = randomRs (0,2) (mkStdGen 0)
+    >     ;n = map ([1,0.5,0.25] !!) i}
+    > in withSC3 (async (b_alloc_setn1 11 0 (take 24 n)))
+
+requires buffers 10 and 11 as allocated above
+
+> g_02 =
+>     let 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
+>         f = duty KR (d * 0.5) 0 DoNothing l
+>     in sinOsc AR f 0 * 0.1
+
+free buffers
+
+    > withSC3 (async (b_free 10) >> async (b_free 11))
diff --git a/Help/UGen/dbufwr.help.lhs b/Help/UGen/dbufwr.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dbufwr.help.lhs
@@ -0,0 +1,55 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dbufwr"
+    > Sound.SC3.UGen.DB.ugenSummary "Dbufwr"
+
+> import Sound.SC3 {- hsc3 -}
+
+allocate buffer
+
+    > withSC3 (async (b_alloc_setn1 0 0 (replicate 24 210)))
+
+monadic graph constructor (type `C-cM-a` at g_01 to hear, `C-cM-g` to see)
+
+> g_01 :: UId m => m UGen
+> g_01 = do
+>   s1 <- dseriesM 30 0 3
+>   s2 <- dseriesM 30 0 1
+>   s3 <- dseriesM 16 1 1
+>   s4 <- dwhiteM 8 1 16
+>   s5 <- dseqM dinf (mce2 s3 s4)
+>   wt <- dustM KR 1                  {- write trigger -}
+>   rp <- dseriesM dinf 0 1           {- read pointer -}
+>   wp <- dseqM dinf (mce2 s1 s2)     {- write pointer -}
+>   r <- dbufrdM 0 rp Loop            {- reader -}
+>   w <- dbufwrM 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
+>   return (mrg [d, out 0 o])
+
+variant written using a local buffer and uid ugen forms
+
+> g_02 =
+>     let b = asLocalBuf 'α' (replicate 24 210)
+>         s = dseq 'β' dinf (mce2 (dseries 'γ' 16 1 1) (dwhite 'δ' 8 1 16))
+>         rp = dseries 'ε' dinf 0 1 {- read pointer -}
+>         wp = dseq 'ζ' dinf (mce2 (dseries 'η' 30 0 3) (dseries 'θ' 30 0 1)) {- write pointer -}
+>         r = dbufrd 'ι' b rp Loop {- reader -}
+>         w = dbufwr 'κ' b wp (s * 60) Loop {- writer -}
+>         d = demand (dust 'λ' KR 1) 0 w
+>         f = lag (demand (impulse KR 16 0) 0 r) 0.01
+>         o = sinOsc AR (f * mce2 1 1.01) 0 * 0.1
+>     in mrg2 d (out 0 o)
+
+demand rate single memory recurrence relation.
+
+> rec1 z k t f =
+>   let b = asLocalBuf z [k]
+>       r = dbufrd z b 0 Loop {- reader -}
+>       w = dbufwr z b 0 (f r) Loop {- writer -}
+>   in mrg2 (demand t 0 r) (demand t 0 w)
+
+simple counter, written in terms of rec1.
+
+> g_03 =
+>     let f = rec1 'α' 0 (impulse KR 6 0) (\r -> (r + 1) `modE` 24)
+>     in sinOsc AR (midiCPS (60 + f)) 0 * 0.1
diff --git a/Help/UGen/dc.help.lhs b/Help/UGen/dc.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dc.help.lhs
@@ -0,0 +1,25 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "DC"
+    > Sound.SC3.UGen.DB.ugenSummary "DC"
+
+> import Sound.SC3 {- hsc3 -}
+
+error...
+
+> g_01 = 0 :: UGen
+
+    > withSC3 (send (n_trace [-1]))
+
+zero
+
+> g_02 = dc AR 0
+
+DC offset; will click on start and finish
+
+> g_03 = dc AR 0.5
+> g_04 = 0.5 + sinOsc AR 440 0 * 0.1
+> g_05 = dc AR 0.5 + sinOsc AR 440 0 * 0.1
+
+Transient before LeakDC adapts and suppresses the offset?
+
+> g_06 = dc AR 1
+> g_07 = leakDC (dc AR 1) 0.995
diff --git a/Help/UGen/decay.help.lhs b/Help/UGen/decay.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/decay.help.lhs
@@ -0,0 +1,18 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Decay"
+    Sound.SC3.UGen.DB.ugenSummary "Decay"
+
+> import Sound.SC3 {- hsc3 -}
+
+Used as an envelope.
+
+> g_01 =
+>     let n = pinkNoise 'α' AR -- sinOsc AR 11000 0
+>         s = impulse AR (xLine KR 1 50 20 RemoveSynth) 0.25
+>     in decay s 0.2 * n
+
+Drawing
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.05 (decay (impulse AR 1 0) 0.01)
+
+![](sw/hsc3/Help/SVG/decay.0.svg)
diff --git a/Help/UGen/decay2.help.lhs b/Help/UGen/decay2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/decay2.help.lhs
@@ -0,0 +1,27 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Decay2"
+    Sound.SC3.UGen.DB.ugenSummary "Decay2"
+
+> import Sound.SC3 {- hsc3 -}
+
+Used as an envelope
+
+> g_01 =
+>     let s = fSinOsc AR 600 0 * 0.25 -- sinOsc AR 11000 0 * 0.25
+>         f = xLine KR 1 50 20 RemoveSynth
+>     in decay2 (impulse AR f 0) 0.01 0.2 * s
+
+Compare the above with Decay used as the envelope.
+
+> g_02 =
+>     let s = fSinOsc AR 600 0 * 0.25
+>         f = xLine KR 1 50 20 RemoveSynth
+>     in decay (impulse AR f 0) 0.2 * s
+
+Drawings, attack and decay are a difference of two decays, hence inversion
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.05 (decay2 (impulse AR 1 0) 0.001 0.01)
+    > plot_ugen1 0.05 (decay2 (impulse AR 1 0) 0.01 0.001)
+
+![](sw/hsc3/Help/SVG/decay2.0.svg)
+![](sw/hsc3/Help/SVG/decay2.1.svg)
diff --git a/Help/UGen/decodeB2.help.lhs b/Help/UGen/decodeB2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/decodeB2.help.lhs
@@ -0,0 +1,13 @@
+> Sound.SC3.UGen.Help.viewSC3Help "DecodeB2"
+> Sound.SC3.UGen.DB.ugenSummary "DecodeB2"
+
+> import Sound.SC3
+
+fails..., but so does sclang...
+
+> let {p = pinkNoise 'α' AR
+>     ;mx = mouseX KR (-1) 1 Linear 0.2
+>     ;my = mouseY KR 0 0.1 Linear 0.2
+>     ;[w,x,y] = mceChannels (panB2 p mx my)
+>     ;o = decodeB2 2 w x y 0.5}
+> in audition (out 0 o)
diff --git a/Help/UGen/degreeToKey.help.lhs b/Help/UGen/degreeToKey.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/degreeToKey.help.lhs
@@ -0,0 +1,21 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "DegreeToKey"
+    > Sound.SC3.UGen.DB.ugenSummary "DegreeToKey"
+
+> import Sound.SC3 {- hsc3 -}
+
+allocate & initialise buffer zero
+
+    > withSC3 (async (b_alloc_setn1 0 0 [0,2,3.2,5,7,9,10]))
+
+modal space, mouse x controls discrete pitch in dorian mode
+
+> g_01 =
+>     let n = lfNoise1 'α' KR (mce [3,3.05])
+>         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 (f 48 + f 72) * 0.25
diff --git a/Help/UGen/delay1.help.lhs b/Help/UGen/delay1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/delay1.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Delay1"
+    Sound.SC3.UGen.DB.ugenSummary "Delay1"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = let s = impulse AR 1 0 in s + (delay1 s)
+
+left=original, right=subtract delayed from original
+
+> g_02 = let z = dust 'α' AR 1000 in mce2 z (z - delay1 z)
diff --git a/Help/UGen/delay2.help.lhs b/Help/UGen/delay2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/delay2.help.lhs
@@ -0,0 +1,6 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Delay2"
+    > Sound.SC3.UGen.DB.ugenSummary "Delay2"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = let s = impulse AR 1 0 in s + (delay2 s)
diff --git a/Help/UGen/delayC.help.lhs b/Help/UGen/delayC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/delayC.help.lhs
@@ -0,0 +1,1 @@
+See delayN
diff --git a/Help/UGen/delayL.help.lhs b/Help/UGen/delayL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/delayL.help.lhs
@@ -0,0 +1,1 @@
+See delayN
diff --git a/Help/UGen/delayN.help.lhs b/Help/UGen/delayN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/delayN.help.lhs
@@ -0,0 +1,22 @@
+    Sound.SC3.UGen.Help.viewSC3Help "DelayN"
+    Sound.SC3.UGen.DB.ugenSummary "DelayN"
+
+> import Sound.SC3 {- hsc3 -}
+
+Dust randomly triggers Decay to create an exponential decay envelope
+for the WhiteNoise input source.  The input is mixed with the delay.
+
+> g_01 =
+>     let i = decay (dust 'α' AR 1) 0.3 * whiteNoise 'β' AR
+>         maxdelaytime = 0.2
+>         delaytime = mouseX KR 0.0 maxdelaytime Linear 0.1
+>     in i + delayN i maxdelaytime delaytime
+
+The delay time can be varied at control rate.  An oscillator either
+reinforcing or cancelling with the delayed copy of itself.
+
+> g_02 =
+>     let i = sinOsc AR 320 0 * 0.1
+>         maxdelaytime = 0.005
+>         delaytime = mouseX KR 0.0 maxdelaytime Linear 0.15
+>     in i + delayN i maxdelaytime delaytime
diff --git a/Help/UGen/demand.help.lhs b/Help/UGen/demand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/demand.help.lhs
@@ -0,0 +1,35 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Demand"
+    > Sound.SC3.UGen.DB.ugenSummary "Demand"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 :: UId m => m UGen
+> g_01 = do
+>   r <- dustM KR 1
+>   s <- dgeomM 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
+>   return (max (cubed o) 0 * 0.1)
+>
+> g_02 =
+>     let n = diwhite 'α' dinf 60 72
+>         t = impulse KR 10 0
+>         s = midiCPS n
+>         f = demand t 0 s
+>         o = sinOsc AR (mce [f,f + 0.7]) 0
+>     in cubed (cubed o) * 0.1
+
+audio rate (poll output is equal for x1 and x2)
+
+> g_03 =
+>     let i = lfNoise2 'α' AR 8000
+>         d = dseq 'β' dinf (mce [i])
+>         x = mouseX KR 1 3000 Exponential 0.2
+>         t = impulse AR x 0
+>         x1 = demand t 0 d
+>         x2 = latch i t
+>         s = mce2 x1 x2
+>         p = poll t s (mce2 (label "x1") (label "x2")) 0
+>         o = sinOsc AR (s * 300 + 400) 0 * 0.1
+>     in mrg2 o p
diff --git a/Help/UGen/demandEnvGen.help.lhs b/Help/UGen/demandEnvGen.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/demandEnvGen.help.lhs
@@ -0,0 +1,95 @@
+    Sound.SC3.UGen.Help.viewSC3Help "DemandEnvGen"
+    Sound.SC3.UGen.DB.ugenSummary "DemandEnvGen"
+
+> import Sound.SC3 {- hsc3 -}
+
+Frequency ramp, exponential curve.
+
+> g_01 =
+>     let l = dseq 'α' dinf (mce2 440 9600)
+>         y = mouseY KR 0.01 3 Exponential 0.2
+>         s = env_curve_shape EnvExp
+>         f = demandEnvGen AR l y s 0 1 1 1 0 1 DoNothing
+>     in sinOsc AR f 0 * 0.1
+
+Frequency envelope with random times.
+
+> g_02 =
+>     let l = dseq 'α' dinf (mce [204,400,201,502,300,200])
+>         t = drand 'β' dinf (mce [1.01,0.2,0.1,2.0])
+>         y = mouseY KR 0.01 3 Exponential 0.2
+>         s = env_curve_shape EnvCub
+>         f = demandEnvGen AR l (t * y) s 0 1 1 1 0 1 DoNothing
+>     in sinOsc AR (f * mce2 1 1.01) 0 * 0.1
+
+Frequency modulation
+
+> g_03 =
+>     let n = dwhite 'α' dinf 200 1000
+>         x = mouseX KR (-0.01) (-4) Linear 0.2
+>         y = mouseY KR 1 3000 Exponential 0.2
+>         s = env_curve_shape (EnvNum undefined)
+>         f = demandEnvGen AR n (sampleDur * y) s x 1 1 1 0 1 DoNothing
+>     in sinOsc AR f 0 * 0.1
+
+Short sequence with doneAction, linear
+
+> g_04 =
+>     let l = dseq 'α' 1 (mce [1300,500,800,300,400])
+>         s = env_curve_shape EnvLin
+>         f = demandEnvGen KR l 2 s 0 1 1 1 0 1 RemoveSynth
+>     in sinOsc AR (f * mce2 1 1.01) 0 * 0.1
+
+Gate, mouse x on right side of screen toggles gate
+
+> g_05 =
+>     let n = roundTo (dwhite 'α' dinf 300 1000) 100
+>         x = mouseX KR 0 1 Linear 0.2
+>         g = x >* 0.5
+>         f = demandEnvGen AR n 0.1 5 0.3 g 1 1 0 1 DoNothing
+>     in sinOsc AR (f * mce2 1 1.21) 0 * 0.1
+
+gate
+mouse x on right side of screen toggles sample and hold
+mouse button does hard reset
+
+> g_06 =
+>     let l = dseq 'α' 2 (mce [dseries 'β' 5 400 200,500,800,530,4000,900])
+>         x = mouseX KR 0 1 Linear 0.2
+>         g = (x >* 0.5) - 0.1
+>         b = mouseButton KR 0 1 0.2
+>         r = (b >* 0.5) * 2
+>         s = env_curve_shape EnvSin
+>         f = demandEnvGen KR l 0.1 s 0 g r 1 0 1 DoNothing
+>     in sinOsc AR (f * mce2 1 1.001) 0 * 0.1
+
+initialise coordinate buffer
+layout is (initial-level,duration,level,..,loop-duration)
+
+    > withSC3 (async (b_alloc_setn1 0 0 [0,0.5,0.1,0.5,1,0.01]))
+
+> g_07 =
+>     let b = 0
+>         l_i = dseries 'β' dinf 0 2
+>         d_i = dseries 'γ' dinf 1 2
+>         l = dbufrd 'δ' b l_i Loop
+>         d = dbufrd 'ε' b d_i Loop
+>         s = env_curve_shape EnvLin
+>         e = demandEnvGen KR l d s 0 1 1 1 0 5 RemoveSynth
+>         f = midiCPS (60 + (e * 12))
+>     in sinOsc AR (f * mce2 1 1.01) 0 * 0.1
+
+change envelope by setting values or indeed reallocating buffer
+
+    > withSC3 (send (b_set1 0 1 0.1))
+    > withSC3 (async (b_alloc_setn1 0 0 [0.5,0.9,0.1,0.1,1,0.01]))
+
+read envelope break-points from buffer, here simply duration/level pairs.
+the behavior is odd if the curve is zero (ie. flat segments).
+
+> g_08 =
+>     let b = asLocalBuf 'α' [61,1,60,2,72,1,55,5,67,9,67]
+>         lvl = dbufrd 'β' b (dseries 'γ' 6 0 2) Loop
+>         dur = dbufrd 'δ' b (dseries 'ε' 5 1 2) Loop
+>         e = demandEnvGen KR lvl dur 1 0 1 1 1 0 1 RemoveSynth
+>     in sinOsc AR (midiCPS e) 0 * 0.1
diff --git a/Help/UGen/detectIndex.help.lhs b/Help/UGen/detectIndex.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/detectIndex.help.lhs
@@ -0,0 +1,20 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "DetectIndex"
+    > Sound.SC3.UGen.DB.ugenSummary "DetectIndex"
+
+> import Sound.SC3 {- hsc3 -}
+
+Allocate and set values at buffer ten
+
+    > withSC3 (async (b_alloc_setn1 10 0 [2,3,4,0,1,5]))
+
+Find indexes and map to an audible frequency range.
+
+> g_01 =
+>     let n = 6
+>         x = floorE (mouseX KR 0 n Linear 0.1)
+>         i = detectIndex 10 x
+>     in sinOsc AR (linExp i 0 n 200 700) 0 * 0.1
+
+Free buffer.
+
+    > withSC3 (send (b_free 10))
diff --git a/Help/UGen/detectSilence.help.lhs b/Help/UGen/detectSilence.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/detectSilence.help.lhs
@@ -0,0 +1,9 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "DetectSilence"
+    > Sound.SC3.UGen.DB.ugenSummary "DetectSilence"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let s = sinOsc AR 440 0 * mouseY KR 0 0.2 Linear 0.1
+>         d = detectSilence s 0.1 0.1 RemoveSynth
+>     in mrg [s,d]
diff --git a/Help/UGen/dfm1.help.lhs b/Help/UGen/dfm1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dfm1.help.lhs
@@ -0,0 +1,19 @@
+    Sound.SC3.UGen.Help.viewSC3Help "DFM1"
+    Sound.SC3.UGen.DB.ugenSummary "DFM1"
+
+> import Sound.SC3
+
+Play it with the mouse
+
+> gr_01 =
+>     let n = pinkNoise 'α' AR * 0.5
+>         x = mouseX KR 80 5000 Exponential 0.1
+>         y = mouseX KR 0.1 1.2 Linear 0.1
+>     in dfm1 n x y 1 0 3e-4
+
+Bass...
+
+> gr_02 =
+>     let i = pulse AR 100 0.5 * 0.4 + pulse AR 100.1 0.5 * 0.4
+>         f = range 80 2000 (sinOsc KR (range 0.2 5 (sinOsc KR 0.3 0)) 0)
+>     in dfm1 i f 1.1 2 0 3e-4 * 0.1
diff --git a/Help/UGen/dgeom.help.lhs b/Help/UGen/dgeom.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dgeom.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dgeom"
+    > Sound.SC3.UGen.DB.ugenSummary "Dgeom"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = dgeom 'α' 15 1 1.2
+>         x = mouseX KR 1 40 Exponential 0.1
+>         t = impulse KR x 0
+>         f = demand t 0 n * 30 + 340
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/dibrown.help.lhs b/Help/UGen/dibrown.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dibrown.help.lhs
@@ -0,0 +1,4 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Dibrown"
+> Sound.SC3.UGen.DB.ugenSummary "Dibrown"
+
+See dbrown
diff --git a/Help/UGen/difSqr.help.lhs b/Help/UGen/difSqr.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/difSqr.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.difsqr"
+    > :t difSqr
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let a = fSinOsc AR 800 0
+>         b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
+>     in difSqr a b * 0.125
+
+Written out:
+
+> g_02 =
+>     let a = fSinOsc AR 800 0
+>         b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
+>     in (a * a - b * b) * 0.125
diff --git a/Help/UGen/disintegrator.help.lhs b/Help/UGen/disintegrator.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/disintegrator.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Disintegrator"
+    Sound.SC3.UGen.DB.ugenSummary "Disintegrator"
+
+> import Sound.SC3 {- hsc3 -}
+
+> gr_01 =
+>     let x = mouseX KR 0 1 Linear 0.2
+>         y = mouseY KR 0 1 Linear 0.2
+>         s = sinOsc AR (mce2 400 404) 0 * 0.2
+>     in disintegrator 'α' s x y
diff --git a/Help/UGen/diskIn.help.lhs b/Help/UGen/diskIn.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/diskIn.help.lhs
@@ -0,0 +1,19 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "DiskIn"
+    > Sound.SC3.UGen.DB.ugenSummary "DiskIn"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> fn_01 = "/home/rohan/data/audio/pf-c5.snd"
+> nc_01 = 1
+> msg_01 = [b_alloc 0 65536 nc_01,b_read 0 fn_01 0 (-1) 0 True]
+> msg_02 = [b_close 0,b_free 0]
+
+allocate buffer and open file for reading
+
+    > withSC3 (mapM_ async msg_01)
+
+> g_01 = diskIn nc_01 0 Loop
+
+close file & free buffer
+
+    > withSC3 (mapM_ async msg_02)
diff --git a/Help/UGen/diskOut.help.lhs b/Help/UGen/diskOut.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/diskOut.help.lhs
@@ -0,0 +1,48 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "DiskOut"
+    > Sound.SC3.UGen.DB.ugenSummary "DiskOut"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+
+Example graph
+
+> g_01 =
+>     let d = xLine KR 20000 2 10 RemoveSynth
+>     in dust 'α' AR d * 0.15
+
+> g_02 = soundIn 0
+
+Check incoming signal (either graph above or the outside world, or `C-cC-a`)
+
+    > audition (out 0 g_01)
+
+Record incoming signal (or above...), print some informational traces...
+
+> trace str = liftIO (putStrLn str)
+> sy_01 = synthdef "disk-out" (diskOut 0 g_01)
+> fn_01 = "/tmp/disk-out.aiff"
+> nc_01 = 1
+> msg_01 = [b_alloc 0 65536 nc_01,b_write 0 fn_01 Aiff PcmInt16 (-1) 0 True]
+> msg_02 = [b_close 0,b_free 0]
+
+    > withSC3 (do {trace "b_alloc & b_write"
+    >             ;mapM_ async msg_01
+    >             ;trace "record for 10 seconds"
+    >             ;playSynthdef (2001,AddToTail,1,[]) sy_01
+    >             ;pauseThread 10
+    >             ;trace "stop recording and tidy up"
+    >             ;send (n_free [2001])
+    >             ;mapM_ async msg_02
+    >             ;return ()})
+
+Listen to recording (on loop...)
+
+> msg_03 = [b_alloc 0 65536 nc_01,b_read 0 fn_01 0 (-1) 0 True]
+
+    > withSC3 (mapM_ async msg_03)
+
+> g_03 = diskIn nc_01 0 Loop
+
+Tidy up...
+
+    > withSC3 (mapM_ async msg_02)
diff --git a/Help/UGen/distort.help.lhs b/Help/UGen/distort.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/distort.help.lhs
@@ -0,0 +1,9 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.distort"
+    > :t distort
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let e = xLine KR 0.1 10 10 DoNothing
+>         o = fSinOsc AR 500 0.0
+>     in distort (o * e) * 0.25
diff --git a/Help/UGen/diwhite.help.lhs b/Help/UGen/diwhite.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/diwhite.help.lhs
@@ -0,0 +1,4 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Diwhite"
+> Sound.SC3.UGen.DB.ugenSummary "Diwhite"
+
+See dwhite
diff --git a/Help/UGen/done.help.lhs b/Help/UGen/done.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/done.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Done"
+    > Sound.SC3.UGen.DB.ugenSummary "Done"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     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 mce [done e * o1,o2]
diff --git a/Help/UGen/drand.help.lhs b/Help/UGen/drand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/drand.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Drand"
+    > Sound.SC3.UGen.DB.ugenSummary "Drand"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = drand 'α' dinf (mce [1, 3, 2, 7, 8])
+>         x = mouseX KR 1 400 Exponential 0.1
+>         t = impulse KR x 0
+>         f = demand t 0 n * 30 + 340
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/dseq.help.lhs b/Help/UGen/dseq.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dseq.help.lhs
@@ -0,0 +1,41 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Dseq"
+    Sound.SC3.UGen.DB.ugenSummary "Dseq"
+
+> import Sound.SC3 {- hsc3 -}
+
+At control rate.
+
+> gr_01 =
+>     let n = dseq 'α' 3 (mce [1,3,2,7,8])
+>         x = mouseX KR 1 40 Exponential 0.1
+>         t = impulse KR x 0
+>         f = demand t 0 n * 30 + 340
+>     in sinOsc AR f 0 * 0.1
+
+At audio rate.
+
+> gr_02 =
+>     let n = dseq 'α' dinf (mce [1,3,2,7,8,32,16,18,12,24])
+>         x = mouseX KR 1 10000 Exponential 0.1
+>         t = impulse AR x 0
+>         f = demand t 0 n * 30 + 340
+>     in sinOsc AR f 0 * 0.1
+
+The SC2 Sequencer UGen is somewhat like the sequ function below
+
+> gr_03 =
+>     let sequ e s tr = demand tr 0 (dseq e dinf (mce s))
+>         t = impulse AR 6 0
+>         n0 = sequ 'α' [60,62,63,58,48,55] t
+>         n1 = sequ 'β' [63,60,48,62,55,58] t
+>     in lfSaw AR (midiCPS (mce2 n0 n1)) 0 * 0.1
+
+Rather than MCE expansion at _tr_, it can be clearer to view _tr_ as a
+functor.
+
+> gr_04 =
+>     let tr = impulse KR (mce [2,3,5]) 0
+>         f (z,t) = demand t 0 (dseq z dinf (mce [60,63,67,69]))
+>         m = mce_map_ix f tr
+>         o = sinOsc AR (midiCPS m) 0 * 0.1
+>     in splay o 1 1 0 True
diff --git a/Help/UGen/dser.help.lhs b/Help/UGen/dser.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dser.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dser"
+    > Sound.SC3.UGen.DB.ugenSummary "Dser"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let a = dser 'α' 7 (mce [1, 3, 2, 7, 8])
+>         x = mouseX KR 1 40 Exponential 0.1
+>         t = impulse KR x 0
+>         f = demand t 0 a * 30 + 340
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/dseries.help.lhs b/Help/UGen/dseries.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dseries.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dseries"
+    > Sound.SC3.UGen.DB.ugenSummary "Dseries"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = dseries 'α' 15 0 1
+>         x = mouseX KR 1 40 Exponential 0.1
+>         t = impulse KR x 0
+>         f = demand t 0 n * 30 + 340
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/dshuf.help.lhs b/Help/UGen/dshuf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dshuf.help.lhs
@@ -0,0 +1,19 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dshuf"
+    > Sound.SC3.UGen.DB.ugenSummary "Dshuf"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.External.RDU as RDU {- sc3-rdu -}
+
+> g_01 =
+>     let a = dseq 'α' dinf (dshuf 'β' 3 (mce [1,3,2,7,8.5]))
+>         x = mouseX KR 1 40 Exponential 0.1
+>         t = impulse KR x 0
+>         f = demand t 0 a * 30 + 340
+>     in sinOsc AR f 0 * 0.1
+
+> g_02 =
+>     let a = dseq 'α' dinf (dshuf 'β' 5 (RDU.randN 81 'γ' 0 10))
+>         x = mouseX KR 1 10000 Exponential 0.1
+>         t = impulse AR x 0
+>         f = demand t 0 a * 30 + 340
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/dstutter.help.lhs b/Help/UGen/dstutter.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dstutter.help.lhs
@@ -0,0 +1,26 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dstutter"
+    > Sound.SC3.UGen.DB.ugenSummary "Dstutter"
+
+> import Sound.SC3 {- hsc3-}
+>
+> g_01 =
+>     let inp = dseq 'α' dinf (mce [1,2,3])
+>         nse = diwhite 'β' dinf 2 8
+>         rep = dstutter 'γ' nse inp
+>         trg = impulse KR (mouseX KR 1 40 Exponential 0.2) 0
+>         frq = demand trg 0 rep * 30 + 340
+>     in sinOsc AR frq 0 * 0.1
+
+see also <https://www.listarc.bham.ac.uk/lists/sc-users/msg14775.html>
+
+> g_02 =
+>     let a z = let xr = dxrand z dinf (mce [0.1,0.2,0.3,0.4,0.5])
+>                   lf = dstutter z 2 xr
+>                   du = duty AR lf 0 DoNothing lf
+>                   tr = abs (hpz1 du) >* 0
+>                   ph = sweep tr (1/du)
+>               in linExp ph 0 1 (rand z 50 100) (rand z 500 2000)
+>         f = mce (map a ['a'..'h'])
+>         [s0,s1] = mceChannels (splay (sinOsc AR f 0) 1 1 0 True)
+>         o = limiter (rotate2 s0 s1 (lfSaw KR 0.1 0)) 1 1e-2
+>     in o * 0.25
diff --git a/Help/UGen/dswitch.help.lhs b/Help/UGen/dswitch.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dswitch.help.lhs
@@ -0,0 +1,21 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dswitch"
+    > Sound.SC3.UGen.DB.ugenSummary "Dswitch"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> mk_g :: UId m => (UGen -> UGen -> m UGen) -> m UGen
+> mk_g sw = do
+>   a0 <- dwhiteM 2 3 4
+>   a1 <- dwhiteM 2 0 1
+>   a2 <- dseqM 2 (mce [1,1,1,0])
+>   i <- dseqM 2 (mce [0,1,2,1,0])
+>   d <- sw i (mce [a0,a1,a2])
+>   let t = impulse KR 4 0
+>       f = demand t 0 d * 300 + 400
+>   return (sinOsc AR f 0 * 0.1)
+
+compare with dswitch1
+
+> g_01,g_02 :: UId m => m UGen
+> g_01 = mk_g dswitchM
+> g_02 = mk_g dswitch1M
diff --git a/Help/UGen/dswitch1.help.lhs b/Help/UGen/dswitch1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dswitch1.help.lhs
@@ -0,0 +1,13 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dswitch1"
+    > Sound.SC3.UGen.DB.ugenSummary "Dswitch1"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let x = mouseX KR 0 4 Linear 0.1
+>         y = mouseY KR 1 15 Linear 0.1
+>         t = impulse KR 3 0
+>         w = dwhite 'α' dinf 20 23
+>         n = dswitch1 'β' x (mce [1, 3, y, 2, w])
+>         f = demand t 0 n * 30 + 340
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/dust.help.lhs b/Help/UGen/dust.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dust.help.lhs
@@ -0,0 +1,25 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Dust"
+    Sound.SC3.UGen.DB.ugenSummary "Dust"
+
+> import Sound.SC3
+>
+> g_01 = dust 'α' AR 200 * 0.25
+>
+> g_02 =
+>     let d = xLine KR 20000 2 10 RemoveSynth
+>     in dust 'β' AR d * 0.15
+
+Drawings
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen1 0.1 (dust 'γ' AR 300)
+    plot_ugen1 0.1 (dust 'γ' AR (xLine KR 5000 100 0.1 RemoveSynth))
+
+![](sw/hsc3/Help/SVG/dust.0.svg)
+![](sw/hsc3/Help/SVG/dust.1.svg)
+
+Illustrate monadic constructor
+
+> g_03,g_04 :: UId m => m UGen
+> g_03 = fmap (* 0.25) (dustM AR 200)
+> g_04 = fmap (* 0.15) (dustM AR (xLine KR 20000 2 10 RemoveSynth))
diff --git a/Help/UGen/dust2.help.lhs b/Help/UGen/dust2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dust2.help.lhs
@@ -0,0 +1,19 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Dust2"
+    Sound.SC3.UGen.DB.ugenSummary "Dust2"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = dust2 'α' AR 200 * 0.5
+
+> g_02 =
+>     let d = xLine KR 20000 2 10 RemoveSynth
+>     in dust2 'β' AR d * 0.15
+
+Drawings
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen1 0.1 (dust2 'γ' AR 400)
+    plot_ugen1 0.1 (dust2 'γ' AR (xLine KR 5000 100 0.1 RemoveSynth))
+
+![](sw/hsc3/Help/SVG/dust2.0.svg)
+![](sw/hsc3/Help/SVG/dust2.1.svg)
diff --git a/Help/UGen/duty.help.lhs b/Help/UGen/duty.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/duty.help.lhs
@@ -0,0 +1,19 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Duty"
+    > Sound.SC3.UGen.DB.ugenSummary "Duty"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 :: UId m => m UGen
+> g_01 = do
+>   n0 <- drandM dinf (mce [0.01,0.2,0.4])
+>   n1 <- dseqM dinf (mce [204,400,201,502,300,200])
+>   let f = duty KR n0 0 RemoveSynth n1
+>   return (sinOsc AR (f * mce2 1 1.01) 0 * 0.1)
+
+Using control rate signal, mouseX, to determine duration.
+
+> g_02 =
+>     let n = dseq 'α' dinf (mce [204,400,201,502,300,200])
+>         x = mouseX KR 0.001 2 Linear 0.1
+>         f = duty KR x 0 RemoveSynth n
+>     in sinOsc AR (f * mce2 1 1.01) 0 * 0.1
diff --git a/Help/UGen/dwhite.help.lhs b/Help/UGen/dwhite.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dwhite.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dwhite"
+    > Sound.SC3.UGen.DB.ugenSummary "Dwhite"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = dwhite 'α' 30 0 15
+>         x = mouseX KR 1 40 Exponential 0.1
+>         t = impulse KR x 0
+>         f = demand t 0 n * 30 + 340
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/dwrand.help.lhs b/Help/UGen/dwrand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dwrand.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dwrand"
+    > Sound.SC3.UGen.DB.ugenSummary "Dwrand"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = dwrand 'α' dinf (mce [0.3,0.2,0.1,0.2,0.2]) (mce [1,3,2,7,8])
+>         x = mouseX KR 1 400 Exponential 0.1
+>         t = impulse KR x 0
+>         f = demand t 0 n * 30 + 340
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/dwt.help.lhs b/Help/UGen/dwt.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dwt.help.lhs
@@ -0,0 +1,3 @@
+> Sound.SC3.UGen.Help.viewSC3Help "DWT"
+> Sound.SC3.UGen.DB.ugenSummary "DWT"
+
diff --git a/Help/UGen/dxrand.help.lhs b/Help/UGen/dxrand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dxrand.help.lhs
@@ -0,0 +1,30 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Dxrand"
+    > Sound.SC3.UGen.DB.ugenSummary "Dxrand"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = mce [0.2,0.4,dseq 'α' 2 (mce [0.1,0.1])]
+>         d = dxrand 'β' dinf i
+>     in tDuty AR d 0 DoNothing (dwhite 'γ' dinf 0.5 1) 0
+
+The list inputs to demand rate ugens may operate at different rates.
+The variants i' and i'' below ought to generate the same graph.  A
+simple-minded mce rule sets the rate of the operator primitive to the
+maximum rate of the inputs and then does not revise this after mce
+transformation, where it may be lower.  The hsc3 constructors attempt
+to get this right!
+
+> g_02 =
+>     let i = mce [0.2,0.4,dseq 'α' 2 (mce [0.1,0.1])]
+>         i' = mceMap (* 0.5) i
+>         i'' = i * 0.5
+>         d = dxrand 'β' dinf i''
+>     in tDuty AR d 0 DoNothing (dwhite 'γ' dinf 0.5 1) 0
+
+> g_03 =
+>     let n = dxrand 'α' dinf (mce [1, 3, 2, 7, 8])
+>         x = mouseX KR 1 400 Exponential 0.1
+>         t = impulse KR x 0
+>         f = demand t 0 n * 30 + 340
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/dynKlang.help.lhs b/Help/UGen/dynKlang.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dynKlang.help.lhs
@@ -0,0 +1,25 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "DynKlang"
+    > Sound.SC3.UGen.DB.ugenSummary "DynKlang"
+
+> import Sound.SC3 {- hsc3 -}
+
+fixed
+
+> g_01 =
+>     let s = klangSpec [800,1000,1200] [0.3,0.3,0.3] [pi,pi,pi]
+>     in dynKlang AR 1 0 s * 0.4
+
+fixed: randomised
+
+> g_02 =
+>     let f = map (\z -> rand z 600 1000) ['a'..'l']
+>         s = klangSpec f (replicate 12 1) (replicate 12 0)
+>     in dynKlang AR 1 0 s * 0.05
+
+dynamic: frequency modulation
+
+> g_03 =
+>     let f = mce3 800 1000 1200 + sinOsc KR (mce3 2 3 4.2) 0 * mce3 13 24 12
+>         a = mce3 0.3 0.3 0.3
+>         p = mce3 pi pi pi
+>     in dynKlang AR 1 0 (klangSpec_mce f a p) * 0.1
diff --git a/Help/UGen/dynKlank.help.lhs b/Help/UGen/dynKlank.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dynKlank.help.lhs
@@ -0,0 +1,45 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "DynKlank"
+    > Sound.SC3.UGen.DB.ugenSummary "DynKlank"
+
+> import Sound.SC3 {- hsc3 -}
+
+    {s=`[[800,1071,1153,1723],nil,[1,1,1,1]]
+    ;DynKlank.ar(,Impulse.ar(2,0,0.1))}.play
+
+> g_01 =
+>     let s = klankSpec [800,1071,1153,1723] [1,1,1,1] [1,1,1,1]
+>     in dynKlank (impulse AR 2 0 * 0.1) 1 0 1 s
+
+    {s=`[[800,1071,1353,1723],nil,[1,1,1,1]]
+    ;DynKlank.ar(s,Dust.ar(8,0.1))}.play
+
+> g_02 =
+>     let s = klankSpec [800,1071,1353,1723] [1,1,1,1] [1,1,1,1]
+>     in dynKlank (dust 'α' AR 8 * 0.1) 1 0 1 s
+
+    {s=`[[800,1071,1353,1723],nil,[1,1,1,1]]
+    ;DynKlank.ar(s,PinkNoise.ar(0.007))}.play
+
+> g_03 =
+>     let s = klankSpec [800,1071,1353,1723] [1,1,1,1] [1,1,1,1]
+>     in dynKlank (pinkNoise 'α' AR * 0.007) 1 0 1 s
+
+    {s=`[[200,671,1153,1723],nil,[1,1,1,1]]
+    ;a=[0.007,0.007]
+    ;DynKlank.ar(s,PinkNoise.ar(a))}.play;
+
+> g_04 =
+>     let s = klankSpec [200,671,1153,1723] [1,1,1,1] [1,1,1,1]
+>         a = mce2 0.007 0.007
+>     in dynKlank (pinkNoise 'α' AR * a) 1 0 1 s
+
+Change frequencies (x) and ring-times (y) with mouse.
+
+> g_05 =
+>     let x = mouseX KR 0.5 2 Exponential 0.2
+>         f = map (* x) [800,1071,1153,1723]
+>         y = mouseY KR 0.1 10 Exponential 0.2
+>         d = map (* y) [1,1,1,1]
+>         s = klankSpec f [1,1,1,1] d
+>         i = impulse AR 2 0 * 0.1
+>     in dynKlank i 1 0 1 s
diff --git a/Help/UGen/envADSR.help.lhs b/Help/UGen/envADSR.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envADSR.help.lhs
@@ -0,0 +1,70 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Env.*adsr"
+    :i Sound.SC3.ADSR
+    :t Sound.SC3.envADSR_r
+    :t Sound.SC3.envADSR
+
+> import Sound.SC3 {- hsc3 -}
+
+{SinOsc.ar * EnvGen.kr(Env.adsr(0.75, 2.75, 0.1, 7.25, 1, -4, 0))}.draw;
+
+> g_01 =
+>     let c = control KR "env-gate" 1
+>         p = envADSR 0.75 2.75 0.1 7.25 1 (EnvNum (-4)) 0
+>         e = envGen KR c 1 0 1 DoNothing p
+>     in sinOsc AR 440 0 * e * 0.1
+
+    import Sound.OSC {- hosc -}
+    withSC3 (sendMessage (n_set1 (-1) "env-gate" 0))
+    withSC3 (sendMessage (n_set1 (-1) "env-gate" 1))
+    withSC3 (sendMessage (n_free [-1]))
+
+> e_01 =
+>     [envADSR 0.75 0.75 0.5 0.75 1 (EnvNum (-4)) 0
+>     ,envADSR 0.02 0.2 0.25 1 1 (EnvNum (-4)) 0
+>     ,envADSR 0.001 0.2 0.25 1 1 (EnvNum (-4)) 0
+>     ,envADSR 0 2 1 0.1 0.5 EnvSin 0
+>     ,envADSR 0.001 1.54 1 0.001 0.4 EnvSin 0]
+
+    import Sound.SC3.Plot {- hsc3 -}
+    plotEnvelope e_01
+
+There is a record variant:
+
+> g_02 =
+>     let g = control KR "gate" 1
+>         c = EnvNum (-4)
+>         r = ADSR {adsr_attackTime = 0.75
+>                  ,adsr_decayTime = 0.75
+>                  ,adsr_sustainLevel = 0.5
+>                  ,adsr_releaseTime = 0.75
+>                  ,adsr_peakLevel = 1
+>                  ,adsr_curve = (c,c,c)
+>                  ,adsr_bias = 0}
+>         p = envADSR_r r
+>         e = envGen KR g 0.1 0 1 DoNothing p
+>     in sinOsc AR 440 0 * e
+
+    withSC3 (sendMessage (n_set1 (-1) "gate" 0))
+    withSC3 (sendMessage (n_set1 (-1) "gate" 1))
+    withSC3 (sendMessage (n_free [-1]))
+
+SC3 comparison:
+
+Env.adsr.asArray == [0,3,2,-99,1,0.01,5,-4,0.5,0.3,5,-4,0,1,5,-4];
+
+> r_03 = [0,3,2,-99,1,0.01,5,-4,0.5,0.3,5,-4,0,1,5,-4]
+> e_03 = envADSR 0.01 0.3 0.5 1 1 (EnvNum (-4)) 0
+> a_03 = envelope_sc3_array e_03
+
+    e_03 == envADSR_r adsrDefault
+    a_03 == Just r_03
+
+> r_04 = [0,3,2,-99,1,0.3,5,-4,0.1,0.4,5,-4,0,1.2,5,-4]
+> e_04 = envADSR 0.3 0.4 0.1 1.2 1 (EnvNum (-4)) 0
+> a_04 = envelope_sc3_array e_04
+
+    a_04 == Just r_04
+
+x = {|gate=0, freq=440 | EnvGen.kr(Env.adsr,gate) * SinOsc.ar(freq,0) * 0.1}.play
+x.set(\gate,1);
+x.set(\gate,0);
diff --git a/Help/UGen/envASR.help.lhs b/Help/UGen/envASR.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envASR.help.lhs
@@ -0,0 +1,30 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Env.*asr"
+    :i Sound.SC3.ASR
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let g = control KR "env-gate" 1
+>         p = envASR 0.01 1 1 (EnvNum (-4))
+>         e = envGen KR g 0.1 0 1 RemoveSynth p
+>     in sinOsc AR 440 0 * e
+
+    import Sound.OSC {- hosc -}
+    withSC3 (sendMessage (n_set1 (-1) "env-gate" 0))
+
+> e_01 =
+>     [envASR 0.1 1 1 (EnvNum (-4))
+>     ,envASR 0.3 0.25 1 EnvSin
+>     ,envASR 0.01 0.5 1.25 EnvLin]
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plotEnvelope e_01
+
+An envelope with a long release time that mostly sustains and then decays quickly
+
+> e_02 = envASR_c 0.01 1 0.75 (EnvNum (-4),EnvNum 4)
+> e_03 = envASR_c 0.15 1 1.25 (EnvNum (-4),EnvNum (-4))
+> e_04 = envASR_c 0.15 1 1.25 (EnvNum (-4),EnvNum 64)
+
+    plotEnvelope [e_02,e_03,e_04]
+
diff --git a/Help/UGen/envCoord.help.lhs b/Help/UGen/envCoord.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envCoord.help.lhs
@@ -0,0 +1,53 @@
+    :t envCoord
+
+> import Sound.SC3
+
+co-ordinate (break-point) envelope
+
+> g_01 =
+>     let c = EnvLin
+>         p = envCoord [(0,0),(0.5,0.1),(0.55,1),(1,0)] 9 0.1 c
+>         e = envGen KR 1 1 0 1 RemoveSynth p
+>     in sinOsc AR 440 0 * e
+
+line segments, set target value & transition time and trigger
+
+> g_02 =
+>     let tr = tr_control "tr" 1
+>         st = control KR "st" 440
+>         en = control KR "en" 880
+>         tm = control KR "tm" 2
+>         p = envCoord [(0,st),(tm,en)] 1 1 EnvLin
+>         e = envGen KR tr 1 0 1 DoNothing p
+>     in sinOsc AR e 0 * 0.2
+
+    import Sound.OSC {- hosc3 -}
+    withSC3 (sendMessage (n_set (-1) [("en",550),("tm",4),("tr",1)]))
+    withSC3 (sendMessage (n_set (-1) [("en",990),("tm",1),("tr",1)]))
+    withSC3 (sendMessage (n_set (-1) [("en",110),("tm",2),("tr",1)]))
+
+likewise, but internal graph triggers and randomises line end points
+
+> g_03 =
+>     let tr = dust 'α' KR 2
+>         st = 440
+>         en = tRand 'β' 300 900 tr
+>         tm = tRand 'γ' 0.5 1.5 tr
+>         p = envCoord [(0,st),(tm,en)] 1 1 EnvLin
+>         e = envGen KR tr 1 0 1 DoNothing p
+>     in sinOsc AR e 0 * 0.2
+
+plotting
+
+> e_01 =
+>     let c0 = [(0,0),(0.35,0.1),(0.55,1),(1,0)]
+>         c1 = [(0,0),(0.15,0.6),(0.35,0.2),(1,0)]
+>         c2 = [(0,0),(0.65,0.3),(0.85,0.7),(1,0)]
+>         c3 = [(0,0.1),(0.25,0.6),(0.5,0.4),(1,0.4)]
+>     in [envCoord c0 9 0.1 EnvLin
+>        ,envCoord c1 6 0.1 EnvSin
+>        ,envCoord c2 5 0.1 EnvCub
+>        ,envCoord c3 7 0.1 EnvStep]
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plotEnvelope e_01
diff --git a/Help/UGen/envDetect.help.lhs b/Help/UGen/envDetect.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envDetect.help.lhs
@@ -0,0 +1,14 @@
+    Sound.SC3.UGen.Help.viewSC3Help "EnvDetect"
+    Sound.SC3.UGen.DB.ugenSummary "EnvDetect"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+
+> g_01 =
+>     let i = soundIn 4
+>         c = envDetect AR i 0.01 0.1
+>         p = pitch i 440 60 4000 100 16 1 0.01 0.5 1 0
+>         f = mceChannel 0 p * 3
+>         e = lagUD (mceChannel 1 p) 0 0.1
+>         o = pinkNoise 'α' AR * c + sinOsc AR f 0 * c * e
+>     in mce2 i o
diff --git a/Help/UGen/envFollow.help.lhs b/Help/UGen/envFollow.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envFollow.help.lhs
@@ -0,0 +1,12 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "EnvFollow"
+    > Sound.SC3.UGen.DB.ugenSummary "EnvFollow"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+
+> g_01 =
+>     let z = soundIn 4
+>         d = mouseX KR 0.990 0.999 Linear 0.2
+>         c = envFollow KR z d
+>         o = pinkNoise 'α' AR * c
+>     in mce2 z o
diff --git a/Help/UGen/envGate.help.lhs b/Help/UGen/envGate.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envGate.help.lhs
@@ -0,0 +1,34 @@
+    Sound.SC3.UGen.Help.viewSC3Help "EnvGate"
+
+> import Sound.SC3 {- hsc3 -}
+
+Make envGate, giving the /default/ arguments, as used by envGate'.
+
+> g_01 =
+>     let k = control KR
+>         e = envGate 1 (k "gate" 1) (k "fadeTime" 0.02) RemoveSynth EnvSin
+>     in lpf (saw AR 200) 600 * 0.1 * e
+
+Set fade time, then release gate.
+
+    import Sound.OSC {- hosc -}
+    withSC3 (sendMessage (n_set1 (-1) "fadeTime" 2))
+    withSC3 (sendMessage (n_set1 (-1) "gate" 0))
+
+The same, but built in defaults.
+
+> g_02 =
+>     let e = envGate'
+>     in lpf (saw AR 200) 600 * 0.1 * e
+
+Several envGate nodes can coexist in one synth, but if they are the
+same they're shared (as ever).
+
+> g_03 =
+>     let e = envGate'
+>         s1 = lpf (saw AR 80) 600 * e
+>         s2 = rlpf (saw AR 200 * 0.5) (6000 * e + 60) 0.1 * e
+>     in mce2 s1 s2 * 0.1
+
+    withSC3 (sendMessage (n_set1 (-1) "fadeTime" 5))
+    withSC3 (sendMessage (n_set1 (-1) "gate" 0))
diff --git a/Help/UGen/envGen.help.lhs b/Help/UGen/envGen.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envGen.help.lhs
@@ -0,0 +1,33 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "EnvGen"
+    > Sound.SC3.UGen.DB.ugenSummary "EnvGen"
+
+At least the following envelope constructors are provided:
+envPerc, envSine, envCoord, envTrapezoid, and envLinen.
+
+> import Sound.SC3 {- hsc3 -}
+
+env_circle joins the end of the envelope to the start
+
+> g_01 =
+>     let e = Envelope [6000,700,100] [1,1] [EnvExp,EnvLin] Nothing Nothing
+>         f = envGen KR 1 1 0 1 DoNothing (env_circle e 0 EnvLin)
+>     in sinOsc AR f 0 * 0.1 + impulse AR 1 0
+
+Env([6000,700,100],[1,1],['exp','lin']).circle.asArray == [6000,2,-99,-99,700,1,2,0,100,1,1,0]
+
+    > let {e = Envelope [6000,700,100] [1,1] [EnvExp,EnvLin] Nothing Nothing
+    >     ;r = [0,4,3,0,6000,0,1,0,700,1,2,0,100,1,1,0,0,9e8,1,0]}
+    > in envelope_sc3_array (env_circle e 0 EnvLin) == Just r
+
+Env([0,1],[0.1]).asArray == [0,1,-99,-99,1,0.1,1,0]
+
+    > let e = (Envelope [0,1] [0.1] [EnvLin] Nothing Nothing)
+    > in envelope_sc3_array e == Just [0,1,-99,-99,1,0.1,1,0]
+
+https://www.listarc.bham.ac.uk/lists/sc-users/msg14815.html
+
+> g_02 =
+>     let n = range 0.01 0.1 (lfNoise1 'α' KR 2)
+>         e = Envelope [0,1] [n] [EnvLin] Nothing (Just 0)
+>         a = envGen AR 1 1 0 1 DoNothing (env_circle e 0 EnvLin)
+>     in sinOsc AR (a * 400 + 500) 0 * 0.1
diff --git a/Help/UGen/envLinen.help.lhs b/Help/UGen/envLinen.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envLinen.help.lhs
@@ -0,0 +1,30 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Env.*linen"
+    :i Sound.SC3.LINEN
+    :t envLinen
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let t = envLinen 0.4 2 0.4 0.1
+>         e = envGen KR 1 1 0 1 RemoveSynth t
+>     in sinOsc AR 440 0 * e
+
+> e_01 =
+>     [envLinen 0 1 0 0.4
+>     ,envelope_normalise (envLinen 0 2 0 0.5)
+>     ,envLinen 0.4 2 0.4 0.6
+>     ,envLinen 0.6 1 1.2 0.7]
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plotEnvelope e_01
+
+> e_02 =
+>     let e = envLinen 0 1 0 1
+>     in (envelope_duration e
+>        ,envelope_segment_ix e 0
+>        ,envelope_segment_ix e 1
+>        ,envelope_segment e 0
+>        ,envelope_segment e 1
+>        ,envelope_at e 0
+>        ,envelope_at e 1
+>        ,envelope_render 10 e)
diff --git a/Help/UGen/envPerc.help.lhs b/Help/UGen/envPerc.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envPerc.help.lhs
@@ -0,0 +1,21 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Env.*perc"
+    :t envPerc'
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let a = 0.1
+>         p = envPerc 0.01 1
+>         e = envGen KR 1 a 0 1 RemoveSynth p
+>     in sinOsc AR 440 0 * e
+
+> g_02 =
+>     let a = 0.1
+>         c = EnvNum (-4)
+>         p = envPerc' 0.01 1 a (c,c)
+>         e = envGen KR 1 1 0 1 RemoveSynth p
+>     in sinOsc AR 440 0 * e
+
+
+import Sound.SC3.Plot {- hsc3-plot -}
+plotEnvelope [envPerc 0.05 1,envPerc 0.2 0.75]
diff --git a/Help/UGen/envSine.help.lhs b/Help/UGen/envSine.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envSine.help.lhs
@@ -0,0 +1,14 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Env.*sine"
+    :t Sound.SC3.envSine
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let s = envSine 9 0.1
+>         e = envGen KR 1 1 0 1 RemoveSynth s
+>     in sinOsc AR 440 0 * e
+
+> e_01 = [envSine 9 1,envSine 3 0.25]
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plotEnvelope e_01
diff --git a/Help/UGen/envStep.help.lhs b/Help/UGen/envStep.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envStep.help.lhs
@@ -0,0 +1,23 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Env.*step"
+    :i Sound.SC3.envStep
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let env = envStep [0.0,0.5,0.7,1.0,0.9,0.0] [0.5,0.1,0.2,1.0,1.5,3] Nothing Nothing
+>         envgen = envGen AR 1 1 0 1 RemoveSynth env
+>     in sinOsc AR (envgen * 1000 + 440) 0 * (envgen + 1) * 0.1
+
+major scale, accelerating, with loop & release nodes
+
+> g_02 =
+>     let env = envStep [0,2,4,5,7,9,11,12,0] (take 9 (iterate (* 0.75) 1)) (Just 8) (Just 0)
+>         envgen = envGen AR 1 1 0 1 DoNothing env
+>     in sinOsc AR (midiCPS (envgen + 60)) 0 * 0.1
+
+draw envelope
+
+> e_01 = [envStep [0,2,4,5,7,9,11,12] (take 8 (iterate (* 0.75) 1)) Nothing Nothing]
+
+    import Sound.SC3.Plot
+    plotEnvelope e_01
diff --git a/Help/UGen/envTrapezoid.help.lhs b/Help/UGen/envTrapezoid.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envTrapezoid.help.lhs
@@ -0,0 +1,20 @@
+    :t Sound.SC3.envTrapezoid
+
+> import Sound.SC3
+
+> g_01 =
+>     let t = envTrapezoid 0.05 0.95 3 0.1
+>         e = envGen KR 1 1 0 1 RemoveSynth t
+>     in sinOsc AR 440 0 * e
+
+> e_02 = envTrapezoid 0 0.25 2 0.1 :: Envelope Double
+> r_02 = [0,3,-99,-99,0.1,0.5,1,0,0.1,0,1,0,0,1.5,1,0]
+> a_02 = envelope_sc3_array e_02
+
+     a_02 == Just r_02
+
+> e_03 :: [Envelope Double]
+> e_03 = [envTrapezoid 0.75 0.25 2 1,envTrapezoid 0.25 0.75 3 0.5]
+
+    import Sound.SC3.Plot
+    plotEnvelope e_03
diff --git a/Help/UGen/envTriangle.help.lhs b/Help/UGen/envTriangle.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envTriangle.help.lhs
@@ -0,0 +1,14 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Env.*triangle"
+    :t envTriangle
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let t = envTriangle 1 0.1
+>         e = envGen KR 1 1 0 1 RemoveSynth t
+>     in sinOsc AR 440 0 * e
+
+> e_02 = [envTriangle 1 1,envTriangle 0.25 0.5]
+
+    import Sound.SC3.Plot
+    plotEnvelope e_02
diff --git a/Help/UGen/eq.help.lhs b/Help/UGen/eq.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/eq.help.lhs
@@ -0,0 +1,2 @@
+See gt (>)
+
diff --git a/Help/UGen/excess.help.lhs b/Help/UGen/excess.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/excess.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.excess"
+    > :t excess
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let o = fSinOsc AR 1000 0
+>         l = line KR 0 1 8 DoNothing
+>     in excess o l * 0.1
+
+or written out in terms of clip2
+
+> g_02 =
+>     let o = fSinOsc AR 1000 0
+>         l = line KR 0 1 8 DoNothing
+>     in (o - clip2 o l) * 0.1
diff --git a/Help/UGen/expRand.help.lhs b/Help/UGen/expRand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/expRand.help.lhs
@@ -0,0 +1,9 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "ExpRand"
+    > Sound.SC3.UGen.DB.ugenSummary "ExpRand"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let a = line KR 0.5 0 0.01 RemoveSynth
+>         f = expRand 'α' 100.0 8000.0
+>     in fSinOsc AR f 0 * a
diff --git a/Help/UGen/fSinOsc.help.lhs b/Help/UGen/fSinOsc.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fSinOsc.help.lhs
@@ -0,0 +1,44 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "FSinOsc"
+    > Sound.SC3.UGen.DB.ugenSummary "FSinOsc"
+
+Note: SC2 did not have the initial phase argument.
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = fSinOsc AR (mce2 440 550) 0 * 0.05
+
+Modulate frequency
+
+> g_02 = fSinOsc AR (xLine KR 200 4000 1 RemoveSynth) 0 * 0.1
+
+Loses amplitude towards the end
+
+> g_03 =
+>     let f = fSinOsc AR (xLine KR 4 401 8 RemoveSynth)
+>     in fSinOsc AR (f 0 * 200 + 800) 0 * 0.1
+
+sin grain with sine envelope (see also 'sine_grain_ugen_graph')
+
+> sine =
+>     let b = control IR "out" 0
+>         f = control IR "freq" 440
+>         d = control IR "dur" 0.2
+>         a = control IR "amp" 0.1
+>         p = control IR "pan" 0
+>         o = fSinOsc AR f 0
+>         s = envSine d a
+>         e = envGen AR 1 1 0 1 RemoveSynth s
+>         u = offsetOut b (pan2 o p e)
+>     in synthdef "sine" u
+
+    > import Sound.SC3.Lang.Pattern {- hsc3-lang -}
+
+granular synthesis
+
+    > paudition (pbind [(K_instr,psynth sine)
+    >                  ,(K_midinote,fmap roundE (pbrown 'α' 72 84 1 inf))
+    >                  ,(K_detune,pwhite 'β' 0 10 inf)
+    >                  ,(K_dur,pbrown 'γ' 0.005 0.15 0.05 inf)
+    >                  ,(K_legato,pbrown 'δ' 1 2 0.1 inf)
+    >                  ,(K_amp,pbrown 'ε' 0.05 0.25 0.05 inf)
+    >                  ,(K_param "pan",pbrown 'ζ' (-1) 1 0.2 inf)])
diff --git a/Help/UGen/fbSineC.help.lhs b/Help/UGen/fbSineC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fbSineC.help.lhs
@@ -0,0 +1,33 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "FBSineC"
+    > Sound.SC3.UGen.DB.ugenSummary "FBSineC"
+
+> import Sound.SC3 {- hsc3 -}
+
+SC3 default values.
+
+> g_01 = fbSineC AR (sampleRate / 4) 1 0.1 1.1 0.5 0.1 0.1 * 0.2
+
+Increase feedback
+
+> g_02 =
+>     let fb = line KR 0.01 4 10 DoNothing
+>     in fbSineC AR sampleRate 1 fb 1.1 0.5 0.1 0.1 * 0.2
+
+Increase phase multiplier
+
+> g_03 =
+>     let a = line KR 1 2 10 DoNothing
+>     in fbSineC AR sampleRate 1 0 a 0.5 0.1 0.1 * 0.2
+
+Randomly modulate parameters
+
+> g_04 =
+>     let madd a m = (+ a) . (* m)
+>         x = mouseX KR 1 12 Linear 0.1
+>         n e = lfNoise2 e KR x
+>         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 'ε')
+>     in fbSineC AR n0 n1 n2 n3 n4 0.1 0.1 * 0.2
diff --git a/Help/UGen/fbSineL.help.lhs b/Help/UGen/fbSineL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fbSineL.help.lhs
@@ -0,0 +1,1 @@
+See fbSineC
diff --git a/Help/UGen/fbSineN.help.lhs b/Help/UGen/fbSineN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fbSineN.help.lhs
@@ -0,0 +1,1 @@
+See fbSineC
diff --git a/Help/UGen/fdiv.help.lhs b/Help/UGen/fdiv.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fdiv.help.lhs
@@ -0,0 +1,9 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator./"
+    > :t (/)
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let o = fSinOsc KR 10 0.5
+>         n = pinkNoise 'α' AR
+>     in (n * 0.1) / (o * 0.75)
diff --git a/Help/UGen/fft.help.lhs b/Help/UGen/fft.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fft.help.lhs
@@ -0,0 +1,23 @@
+    Sound.SC3.UGen.Help.viewSC3Help "FFT"
+    Sound.SC3.UGen.DB.ugenSummary "FFT"
+    :t fft'
+
+> import Sound.SC3 {- hsc3 -}
+
+Non-local buffer
+
+    withSC3 (async (b_alloc 10 2048 1))
+
+Variants with default values
+
+> gr_01 =
+>     let n = whiteNoise 'α' AR
+>     in ifft' (fft' 10 (n * 0.05))
+
+Local buffer allocating fft variant
+
+> gr_02 =
+>     let s0 = sinOsc KR 0.08 0 * 6 + 6.2
+>         s1 = sinOsc KR (squared s0) 0 * 100 + 800
+>         s2 = sinOsc AR s1 0
+>     in ifft (ffta 'α' 2048 s2 0.5 0 1 0) 0 0 * 0.25
diff --git a/Help/UGen/fftTrigger.help.lhs b/Help/UGen/fftTrigger.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fftTrigger.help.lhs
@@ -0,0 +1,2 @@
+> Sound.SC3.UGen.Help.viewSC3Help "FFTTrigger"
+> Sound.SC3.UGen.DB.ugenSummary "FFTTrigger"
diff --git a/Help/UGen/fm7.help.lhs b/Help/UGen/fm7.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fm7.help.lhs
@@ -0,0 +1,85 @@
+    Sound.SC3.UGen.Help.viewSC3Help "FM7"
+    Sound.SC3.UGen.DB.ugenSummary "FM7"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+
+> gr_01 =
+>     let c = [[xLine KR 300 310 4 DoNothing,0,1]
+>             ,[xLine KR 300 310 8 DoNothing,0,1]
+>             ,[0,0,1]
+>             ,[0,0,1]
+>             ,[0,0,1]
+>             ,[0,0,1] ]
+>         m = [[line KR 0 0.001 2 DoNothing,line KR 0.1 0 4 DoNothing,0,0,0,0]
+>             ,[line KR 0 6 1 DoNothing,0,0,0,0,0]
+>             ,[0,0,0,0,0,0]
+>             ,[0,0,0,0,0,0]
+>             ,[0,0,0,0,0,0]
+>             ,[0,0,0,0,0,0] ]
+>         [l,r,_,_,_,_] = mceChannels (fm7 c m)
+>     in mce2 l r * 0.1
+
+An algorithmically generated graph courtesy f0.
+
+> gr_02 =
+>     let x = [[[0.0,-1/3,-1.0,0.0]
+>              ,[0.75,0.75,0.0,-0.5]
+>              ,[-0.5,-0.25,0.25,-0.75]
+>              ,[-0.5,1.0,1.0,1.0]
+>              ,[0.0,1/6,-0.75,-1.0]
+>              ,[0.5,0.5,-0.5,1/3]]
+>             ,[[-1/3,0.5,-0.5,-0.5]
+>              ,[0.5,0.75,0.25,0.75]
+>              ,[-15/18,0.25,-1.0,0.5]
+>              ,[1.5,0.25,0.25,-0.25]
+>              ,[-2/3,-2/3,-1.0,-0.5]
+>              ,[-1.0,0.0,-15/18,-1/3]]
+>             ,[[0.25,-0.5,-0.5,-1.0]
+>              ,[-0.5,1.0,-1.5,0.0]
+>              ,[-1.0,-1.5,-0.5,0.0]
+>              ,[0.5,-1.0,7/6,-0.5]
+>              ,[15/18,-0.75,-1.5,0.5]
+>              ,[0.25,-1.0,0.5,1.0]]
+>             ,[[1.0,1/3,0.0,-0.75]
+>              ,[-0.25,0.0,0.0,-0.5]
+>              ,[-0.5,-0.5,0.0,0.5]
+>              ,[1.0,0.75,0.5,0.5]
+>              ,[0.0,1.5,-0.5,0.0]
+>              ,[1.0,0.0,-0.25,-0.5]]
+>             ,[[0.5,-0.25,0.0,1/3]
+>              ,[0.25,-0.75,1/3,-1.0]
+>              ,[-0.25,-0.5,0.25,-7/6]
+>              ,[0.0,0.25,0.5,1/6]
+>              ,[-1.0,-0.5,15/18,-0.5]
+>              ,[15/18,-0.75,-0.5,0.0]]
+>             ,[[0.0,-0.75,-1/6,0.0]
+>              ,[1.0,0.5,0.5,0.0]
+>              ,[-0.5,0.0,-0.5,0.0]
+>              ,[-0.5,-1/6,0.0,0.5]
+>              ,[-0.25,1/6,-0.75,0.25]
+>              ,[-7/6,-4/3,-1/6,1.5]]]
+>         y = [[[0.0,-0.5,1.0,0.0]
+>              ,[-0.5,1.0,0.5,-0.5]
+>              ,[0.0,1/3,1.0,1.0]]
+>             ,[[-0.5,0.5,1.0,1.0]
+>              ,[0.0,1/3,0.0,1.5]
+>              ,[-0.5,15/18,1.0,0.0]]
+>             ,[[0.25,-2/3,0.25,0.0]
+>              ,[0.5,-0.5,-0.5,-0.5]
+>              ,[0.5,-0.5,-0.75,15/18]]
+>             ,[[-0.25,1.0,0.0,1/3]
+>              ,[-1.25,-0.25,0.5,0.0]
+>              ,[0.0,-1.25,-0.25,-0.5]]
+>             ,[[0.75,-0.25,1.5,0.0]
+>              ,[0.25,-1.5,0.5,0.5]
+>              ,[-0.5,-0.5,-0.5,-0.25]]
+>             ,[[0.0,0.5,-0.5,0.25]
+>              ,[0.25,0.5,-1/3,0.0]
+>              ,[1.0,0.5,-1/6,0.5]]]
+>         cs = map (map (\[f,p,m,a] -> sinOsc AR f p * m + a)) x
+>         ms = map (map (\[f,w,m,a] -> pulse AR f w * m + a)) y
+>         [c1,c2,c3,_,c4,c5] = mceChannels (fm7 cs ms)
+>         g3 = linLin (lfSaw KR 0.1 0) (-1) 1 0 (dbAmp (-12))
+>         g5 = dbAmp (-3)
+>     in mce [c1 + c3 * g3 + c5 * g5,c2 + c4 + c5 * g5]
diff --git a/Help/UGen/fmGrain.help.lhs b/Help/UGen/fmGrain.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fmGrain.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "FMGrain"
+    > Sound.SC3.UGen.DB.ugenSummary "FMGrain"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let t = impulse AR 20 0
+>         n = linLin (lfNoise1 'α' KR 1) (-1) 1 1 10
+>         s = envSine 9 0.1
+>         e = envGen KR 1 1 0 1 RemoveSynth s
+>     in fmGrain t 0.2 440 220 n * e
diff --git a/Help/UGen/fmGrainB.help.lhs b/Help/UGen/fmGrainB.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fmGrainB.help.lhs
@@ -0,0 +1,15 @@
+> Sound.SC3.UGen.Help.viewSC3Help "FMGrainB"
+> Sound.SC3.UGen.DB.ugenSummary "FMGrainB"
+
+> import Sound.SC3
+
+> withSC3 (do {_ <- async (b_alloc 10 512 1)
+>             ;let f = [Normalise,Wavetable,Clear]
+>              in send (b_gen_sine2 10 f [(0.5,0.1)])})
+
+> let {t = impulse AR 20 0
+>     ;n = linLin (lfNoise1 'α' KR 1) (-1) 1 1 10
+>     ;s = envSine 9 0.1
+>     ;e = envGen KR 1 1 0 1 RemoveSynth s
+>     ;o = fmGrainB t 0.2 440 220 n 10 * e}
+> in audition (out 0 o)
diff --git a/Help/UGen/fold2.help.lhs b/Help/UGen/fold2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fold2.help.lhs
@@ -0,0 +1,9 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.fold2"
+    > :t fold2
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let o = fSinOsc AR 1000 0
+>         l = line KR 0 1 8 DoNothing
+>     in fold2 o l
diff --git a/Help/UGen/formant.help.lhs b/Help/UGen/formant.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/formant.help.lhs
@@ -0,0 +1,21 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Formant"
+    Sound.SC3.UGen.DB.ugenSummary "Formant"
+
+> import Sound.SC3
+
+Modulate fundamental frequency, formant frequency stays constant.
+
+> g_01 = formant AR (xLine KR 400 1000 8 RemoveSynth) 2000 800 * 0.125
+
+Modulate formant frequency, fundamental frequency stays constant.
+
+> g_02 =
+>     let f = mce [200, 300, 400, 500]
+>         ff = xLine KR 400 4000 8 RemoveSynth
+>     in formant AR f ff 200 * 0.125
+
+Modulate width frequency, other frequencies stay constant.
+
+> g_03 =
+>     let bw = xLine KR 800 8000 8 RemoveSynth
+>     in formant AR 400 2000 bw * 0.1
diff --git a/Help/UGen/formlet.help.lhs b/Help/UGen/formlet.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/formlet.help.lhs
@@ -0,0 +1,34 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Formlet"
+    > Sound.SC3.UGen.DB.ugenSummary "Formlet"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = formlet (impulse AR 20 0.5) 1000 0.01 0.1
+
+> g_02 =
+>     let f = xLine KR 10 400 8 RemoveSynth
+>     in formlet (blip AR f 1000 * 0.1) 1000 0.01 0.1
+
+Modulating formant frequency.
+
+> g_03 =
+>     let s = blip AR (sinOsc KR 5 0 * 20 + 300) 1000 * 0.1
+>         ff = xLine KR 1500 700 8 RemoveSynth
+>     in formlet s ff 0.005 0.04
+
+Mouse control of frequency and decay time.
+
+> g_04 =
+>     let s = blip AR (sinOsc KR 5 0 * 20 + 300) 1000 * 0.1
+>         x = mouseX KR 0.01 0.2 Exponential 0.2
+>         y = mouseY KR 700 2000 Exponential 0.2
+>     in formlet s y 0.005 x
+
+and again...
+
+> g_05 =
+>     let s = dust 'α' KR (mce2 10 11)
+>         x = mouseX KR 0.1 2 Exponential 0.2
+>         y = mouseY KR 7 200 Exponential 0.2
+>         f = formlet s y 0.005 x
+>     in sinOsc AR (f * 200 + mce2 500 600 - 100) 0 * 0.2
diff --git a/Help/UGen/fos.help.lhs b/Help/UGen/fos.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/fos.help.lhs
@@ -0,0 +1,14 @@
+> Sound.SC3.UGen.Help.viewSC3Help "FOS"
+> Sound.SC3.UGen.DB.ugenSummary "FOS"
+
+> import Sound.SC3
+
+Same as OnePole.
+
+> let x = lfTri AR 0.4 0 * 0.99
+> 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
+> in audition (out 0 (fos (lfSaw AR 200 0 * 0.2) (1 - (abs x)) x 0))
diff --git a/Help/UGen/free.help.lhs b/Help/UGen/free.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/free.help.lhs
@@ -0,0 +1,15 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Free"
+    > Sound.SC3.UGen.DB.ugenSummary "Free"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = out 0 (sinOsc AR 880 0 * 0.1)
+>
+> g_02 =
+>     let n0 = pinkNoise 'α' AR
+>         n1 = dust 'β' KR 20
+>     in mrg [out 1 (n0 * 0.1), free n1 1001]
+
+    > audition_at (1001,AddToTail,1,[]) g_01
+    > audition_at (-1,AddToTail,1,[]) g_02
+
diff --git a/Help/UGen/freeSelf.help.lhs b/Help/UGen/freeSelf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/freeSelf.help.lhs
@@ -0,0 +1,8 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "FreeSelf"
+    > Sound.SC3.UGen.DB.ugenSummary "FreeSelf"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = dust 'α' KR 0.5
+>     in mrg [sinOsc AR 440 0 * 0.1,freeSelf n]
diff --git a/Help/UGen/freeSelfWhenDone.help.lhs b/Help/UGen/freeSelfWhenDone.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/freeSelfWhenDone.help.lhs
@@ -0,0 +1,18 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "FreeSelfWhenDone"
+    > Sound.SC3.UGen.DB.ugenSummary "FreeSelfWhenDone"
+
+> import Sound.SC3 {- hsc3 -}
+
+using RemoveSynth doneAction
+
+> g_01 =
+>     let x = mouseX KR (-1) 1 Linear 0.1
+>         e = linen x 1 0.1 1 RemoveSynth
+>     in sinOsc AR 440 0 * e
+
+using FreeSelfWhenDone UGen
+
+> g_02 =
+>     let x = mouseX KR (-1) 1 Linear 0.1
+>         e = linen x 1 0.1 1 DoNothing
+>     in mrg [sinOsc AR 440 0 * e,freeSelfWhenDone e]
diff --git a/Help/UGen/freeVerb.help.lhs b/Help/UGen/freeVerb.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/freeVerb.help.lhs
@@ -0,0 +1,21 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "FreeVerb"
+    > Sound.SC3.UGen.DB.ugenSummary "FreeVerb"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = impulse AR 1 0
+>         c = lfCub AR 1200 0
+>         s = decay i 0.25 * c * 0.1
+>         x = mouseX KR 0 1 Linear 0.1
+>         y = mouseY KR 0 1 Linear 0.1
+>     in freeVerb s y x 0.5
+
+Process input channels
+
+> g_02 =
+>     let i = soundIn (mce2 0 1)
+>         c = mceChannel
+>         x = mouseX KR 0 1 Linear 0.1
+>         y = mouseY KR 0 1 Linear 0.1
+>     in freeVerb2 (c 0 i) (c 1 i) y x 0.5
diff --git a/Help/UGen/freqShift.help.lhs b/Help/UGen/freqShift.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/freqShift.help.lhs
@@ -0,0 +1,50 @@
+    Sound.SC3.UGen.Help.viewSC3Help "FreqShift"
+    Sound.SC3.UGen.DB.ugenSummary "FreqShift"
+
+> import Sound.SC3 {- hcs3 -}
+
+Shifting a 100Hz tone by 1 Hz rising to 500Hz
+
+> g_01 =
+>     let i = sinOsc AR 100 0
+>         s = xLine KR 1 500 5 RemoveSynth
+>     in freqShift i s 0 * 0.1
+
+Shifting a complex tone by 1 Hz rising to 500Hz
+
+> g_02 =
+>     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 freqShift i s 0 * 0.1
+
+Modulating shift and phase
+
+> g_03 =
+>     let s = lfNoise2 'α' AR 0.3
+>         i = sinOsc AR 10 0
+>         p = linLin (sinOsc AR 500 0) (-1) 1 0 (2 * pi)
+>     in freqShift i (s * 1500) p * 0.1
+
+Shifting bandpassed noise
+
+> g_04 =
+>     let n1 = whiteNoise 'α' AR
+>         n2 = lfNoise0 'β' AR 5.5
+>         i = bpf n1 1000 0.001
+>         s = n2 * 1000
+>     in freqShift i s 0 * 32
+
+    {a=Blip.ar(60,4,LFGauss.ar(4,1/8))
+    ;a=a/4+LocalIn.ar(2)
+    ;a=FreqShift.ar(a,LFNoise0.kr(1/4,90))
+    ;LocalOut.ar(DelayC.ar(a,1,0.1,0.9))
+    ;a}.play
+
+> g_05 =
+>     let e = lfGauss AR 4 (1/8) 0 Loop DoNothing
+>         o = blip AR 60 4 * e
+>         a = o / 4 + localIn 2 AR 0
+>         s = freqShift a (lfNoise0 'α' KR (1/4) * 90) 0
+>         z = delayC s 1 0.1 * 0.9
+>     in mrg2 s (localOut z)
diff --git a/Help/UGen/gVerb.help.lhs b/Help/UGen/gVerb.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/gVerb.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "GVerb"
+    > Sound.SC3.UGen.DB.ugenSummary "GVerb"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = impulse AR 1 0
+>         c = lfCub AR 1200 0
+>         s = decay i 0.25 * c * 0.1
+>     in gVerb s 10 3 0.5 0.5 15 1 0.7 0.5 300
diff --git a/Help/UGen/gate.help.lhs b/Help/UGen/gate.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/gate.help.lhs
@@ -0,0 +1,7 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Gate"
+> Sound.SC3.UGen.DB.ugenSummary "Gate"
+
+> import Sound.SC3
+
+> let t = lfPulse AR 1 0 0.1
+> in audition (out 0 (gate (fSinOsc AR 500 0 * 0.25) t))
diff --git a/Help/UGen/gbmanL.help.lhs b/Help/UGen/gbmanL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/gbmanL.help.lhs
@@ -0,0 +1,1 @@
+See GbmanN
diff --git a/Help/UGen/gbmanN.help.lhs b/Help/UGen/gbmanN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/gbmanN.help.lhs
@@ -0,0 +1,28 @@
+    Sound.SC3.UGen.Help.viewSC3Help "GbmanN"
+    Sound.SC3.UGen.DB.ugenSummary "GbmanN"
+
+> import Sound.SC3 {- hsc3 -}
+
+default initial params
+
+> g_01 =
+>     let x = mouseX KR 20 sampleRate Linear 0.2
+>     in gbmanN AR x 1.2 2.1 * 0.1
+
+change initial params
+
+> g_02 =
+>     let x = mouseX KR 20 sampleRate Linear 0.2
+>     in gbmanN AR x (-0.7) (-2.7) * 0.1
+
+wait for it...
+
+> g_03 =
+>     let x = mouseX KR 20 sampleRate Linear 0.2
+>     in gbmanN AR x 1.2 2.0002 * 0.1
+
+as a frequency control
+
+> g_04 =
+>     let f = gbmanN AR 40 1.2 2.1 * 400 + 500
+>     in sinOsc AR f 0 * 0.4
diff --git a/Help/UGen/gendy1.help.lhs b/Help/UGen/gendy1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/gendy1.help.lhs
@@ -0,0 +1,114 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Gendy1"
+    > Sound.SC3.UGen.DB.ugenSummary "Gendy1"
+
+> import Data.Char {- base -}
+> import Sound.SC3 {- base -}
+
+SC3 default parameters
+
+> g_01 = gendy1 'α' AR 1 1 1 1 440 660 0.5 0.5 12 12 * 0.15
+
+Wandering bass
+
+> g_02 = gendy1 'α' AR 1 1 1.0 1.0 30 100 0.3 0.05 5 5 * 0.15
+
+Play me
+
+> g_03 =
+>     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 rlpf g 500 0.3 * 0.1
+
+Scream!
+
+> g_04 =
+>     let x = mouseX KR 220 440 Exponential 0.1
+>         y = mouseY KR 0.0 1.0 Linear 0.1
+>     in gendy1 'α' AR 2 3 1 1 x (8 * x) y y 7 7 *0.3
+
+1 CP = random noise
+
+> g_05 = gendy1 'α' AR 1 1 1 1 440 660 0.5 0.5 1 1 * 0.15
+
+2 CPs = an oscillator
+
+> g_06 = gendy1 'α' AR 1 1 1 1 440 660 0.5 0.5 2 2 * 0.15
+
+Used as an LFO
+
+> g_07 =
+>     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 sinOsc AR (g * 50 + 350) 0 * 0.3
+
+Wasp
+
+> g_08 =
+>     let ad = sinOsc KR 0.1 0 * 0.1 + 0.9
+>     in gendy1 'α' AR 0 0 ad 1.0 50 1000 1 0.005 12 12 * 0.2
+
+Modulate distributions. Change of pitch as distributions change
+the duration structure and spectrum
+
+> g_09 =
+>     let x = mouseX KR 0 7 Linear 0.1
+>         y = mouseY KR 0 7 Linear 0.1
+>     in gendy1 'α' AR x y 1 1 440 660 0.5 0.5 12 12 * 0.2
+
+Modulate number of CPs.
+
+> g_10 =
+>     let x = mouseX KR 1 13 Linear 0.1
+>     in gendy1 'α' AR 1 1 1 1 440 660 0.5 0.5 12 x * 0.2
+
+Self modulation.
+
+> g_11 =
+>     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
+>     in gendy1 'α' AR 1 1 1 1 440 (g0 * 500 + 600) 0.5 0.5 12 x * 0.2
+
+Use SINUS to track any oscillator and take CP positions from it use
+adParam and ddParam as the inputs to sample.
+
+> g_12 =
+>     let p = lfPulse KR 100 0 0.4
+>         s = sinOsc KR 30 0 * 0.5
+>     in gendy1 'α' AR 6 6 p s 440 660 0.5 0.5 12 12 * 0.2
+
+Near the corners are interesting.
+
+> g_13 =
+>     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
+>     in gendy1 'α' AR 6 6 p s 440 660 0.5 0.5 12 12 * 0.2
+
+Texture
+
+> g_14 =
+>     let node e = let f = rand e 130 160.3
+>                      r0 = rand e 0 6
+>                      r1 = rand (toUpper e) 0 6
+>                      l = rand e (-1) 1
+>                      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 pan2 o l 0.1
+>     in mix (mce (map node ['β'..'γ']))
+
+Try durscale 10.0 and 0.0 too.
+
+> g_15 =
+>     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 combN (resonz g y 0.1) 0.1 0.1 5 * 0.6
diff --git a/Help/UGen/grainBuf.help.lhs b/Help/UGen/grainBuf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/grainBuf.help.lhs
@@ -0,0 +1,31 @@
+    Sound.SC3.UGen.Help.viewSC3Help "GrainBuf"
+    Sound.SC3.UGen.DB.ugenSummary "GrainBuf"
+
+> import Sound.SC3 {- hsc3 -}
+
+> fn_01 = "/home/rohan/data/audio/pf-c5.snd"
+
+    > withSC3 (async (b_allocRead 10 fn_01 0 0))
+
+> g_01 =
+>     let buf = 10
+>         dur = 15
+>         lin a b = line KR a b dur RemoveSynth
+>         tr = impulse KR (lin 7.5 15) 0
+>         gd = lin 0.05 0.1
+>         r = lin 1 0.5 {- rate -}
+>         i = lin 0 1 {- read-location -}
+>         l = lin (-0.5) 0.5 {- stereo-location -}
+>     in grainBuf 2 tr gd buf r i 2 l (-1) 512
+
+> g_02 =
+>     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
+>         n1 = lfNoise1 'α' KR 500
+>         n2 = lfNoise2 'β' KR 0.1
+>         r = linLin n1 (-1) 1 0.5 2
+>         p = linLin n2 (-1) 1 0 1
+>     in grainBuf 2 i 0.1 b r p 2 x e 512
diff --git a/Help/UGen/grainFM.help.lhs b/Help/UGen/grainFM.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/grainFM.help.lhs
@@ -0,0 +1,23 @@
+    Sound.SC3.UGen.Help.viewSC3Help "GrainFM"
+    Sound.SC3.UGen.DB.ugenSummary "GrainFM"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let d = 15
+>         lin a b = line KR a b d RemoveSynth
+>         l = lin (-0.5) 0.5
+>         f = lin 200 800
+>         t = impulse KR (lin 7.5 15) 0
+>         i = lin (-1) 1
+>     in grainFM 2 t 0.1 f 200 i l (-1) 512 * 0.1
+
+> g_02 =
+>     let n1 = whiteNoise 'α' KR
+>         n2 = lfNoise1 'β' KR 500
+>         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 12.5 0
+>         i = linLin n2 (-1) 1 1 10
+>     in grainFM 2 t 0.1 f 200 i x (-1) 512 * 0.1
diff --git a/Help/UGen/grainIn.help.lhs b/Help/UGen/grainIn.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/grainIn.help.lhs
@@ -0,0 +1,11 @@
+    Sound.SC3.UGen.Help.viewSC3Help "GrainIn"
+    Sound.SC3.UGen.DB.ugenSummary "GrainIn"
+
+> import Sound.SC3
+
+> g_01 =
+>     let n = pinkNoise 'α' AR
+>         x = mouseX KR (-0.5) 0.5 Linear 0.1
+>         y = mouseY KR 5 25 Linear 0.1
+>         t = impulse KR y 0
+>     in grainIn 2 t 0.1 n x (-1) 512 * 0.1
diff --git a/Help/UGen/grainSin.help.lhs b/Help/UGen/grainSin.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/grainSin.help.lhs
@@ -0,0 +1,12 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "GrainSin"
+    > Sound.SC3.UGen.DB.ugenSummary "GrainSin"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = whiteNoise 'α' KR
+>         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 grainSin 2 t 0.1 f x (-1) 512 * 0.1
diff --git a/Help/UGen/grayNoise.help.lhs b/Help/UGen/grayNoise.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/grayNoise.help.lhs
@@ -0,0 +1,17 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "GrayNoise"
+    > Sound.SC3.UGen.DB.ugenSummary "GrayNoise"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = grayNoise 'α' AR * 0.1
+
+Drawing
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen1 0.025 (grayNoise 'γ' AR)
+
+    import Sound.SC3.Plot.FFT {- hsc3-plot -}
+    plot_ugen_fft1 0.1 (grayNoise 'γ' AR)
+
+![](sw/hsc3/Help/SVG/grayNoise.0.svg)
+![](sw/hsc3/Help/SVG/grayNoise.1.svg)
diff --git a/Help/UGen/gt.help.lhs b/Help/UGen/gt.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/gt.help.lhs
@@ -0,0 +1,22 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.=="
+    > :t (==*)
+
+The star suffixes (<*,<=*,>*,>=*) are because the result of the
+operators is not of type Bool, as is required by the signature for the
+class Ord.  At some point `<*` was written into the standard prelude...
+
+> import Prelude hiding ((<*)) {- base -}
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let o = sinOsc KR 1 0
+>         t = [o >* 0
+>             ,o >=* 0
+>             ,o <* 0
+>             ,o <=* 0
+>             ,o ==* 0
+>             ,(o <* 0.001) * (o >* (-0.001))]
+>         f = [220, 330, 440, 550, 660, 770]
+>         p = envPerc 0.01 1
+>         e = envGen KR (mce t) 0.1 0 1 DoNothing p
+>     in mix (sinOsc AR (mce f) 0 * e)
diff --git a/Help/UGen/hasher.help.lhs b/Help/UGen/hasher.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/hasher.help.lhs
@@ -0,0 +1,14 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Hasher"
+> Sound.SC3.UGen.DB.ugenSummary "Hasher"
+
+> import Sound.SC3
+
+noise
+
+> audition (out 0 (hasher (line AR 0 1 1 RemoveSynth) * 0.2))
+
+remap x
+
+> let {x = mouseX KR 0 10 Linear 0.2
+>     ;f = hasher (roundTo x 1) * 300 + 500}
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/henonC.help.lhs b/Help/UGen/henonC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/henonC.help.lhs
@@ -0,0 +1,1 @@
+See henonN
diff --git a/Help/UGen/henonL.help.lhs b/Help/UGen/henonL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/henonL.help.lhs
@@ -0,0 +1,1 @@
+See henonN
diff --git a/Help/UGen/henonN.help.lhs b/Help/UGen/henonN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/henonN.help.lhs
@@ -0,0 +1,40 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "HenonN"
+    > Sound.SC3.UGen.DB.ugenSummary "HenonN"
+
+> import Sound.SC3 {- hsc3 -}
+
+With SC3 default initial parameters.
+
+> g_01 =
+>     let x = mouseX KR 20 sampleRate Linear 0.1
+>     in henonN AR x 1.4 0.3 0 0 * 0.1
+
+With mouse-control of parameters.
+
+> g_02 =
+>     let x = mouseX KR 1 1.4 Linear 0.1
+>         y = mouseY KR 0 0.3 Linear 0.1
+>     in henonN AR (sampleRate / 4) x y 0 0 * 0.1
+
+With randomly modulated parameters.
+
+> g_03 =
+>     let n0 = lfNoise2 'α' KR 1 * 0.20 + 1.20
+>         n1 = lfNoise2 'β' KR 1 * 0.15 + 0.15
+>     in henonN AR (sampleRate / 8) n0 n1 0 0 * 0.1
+
+As a frequency control.
+
+> g_04 =
+>     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 sinOsc AR f 0 * 0.4
+
+Drawing
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.1 (henonN AR 2500 1.4 0.3 0 0 * 0.1)
+
+![](sw/hsc3/Help/SVG/henonN.0.svg)
diff --git a/Help/UGen/hpf.help.lhs b/Help/UGen/hpf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/hpf.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "HPF"
+    > Sound.SC3.UGen.DB.ugenSummary "HPF"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
+>     in hpf (saw AR 200 * 0.2) f
+
+    import Sound.SC3.Plot.FFT {- hsc3-plot -}
+    plot_ugen_fft1 0.05 (hpf (whiteNoise 'α' AR) 12000)
diff --git a/Help/UGen/hpz1.help.lhs b/Help/UGen/hpz1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/hpz1.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "HPZ1"
+    > Sound.SC3.UGen.DB.ugenSummary "HPZ1"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = let n = whiteNoise 'α' AR in hpz1 (n * 0.25)
+
+    import Sound.SC3.Plot.FFT {- hsc3-plot -}
+    plot_ugen_fft1 0.05 (hpz1 (whiteNoise 'α' AR))
+
diff --git a/Help/UGen/hpz2.help.lhs b/Help/UGen/hpz2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/hpz2.help.lhs
@@ -0,0 +1,7 @@
+> Sound.SC3.UGen.Help.viewSC3Help "HPZ2"
+> Sound.SC3.UGen.DB.ugenSummary "HPZ2"
+
+> import Sound.SC3
+
+> let n = whiteNoise 'α' AR
+> in audition (out 0 (hpz2 (n * 0.25)))
diff --git a/Help/UGen/hypot.help.lhs b/Help/UGen/hypot.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/hypot.help.lhs
@@ -0,0 +1,29 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.hypot"
+    > :t hypot
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let x = mouseX KR 0 0.1 Linear 0.1
+>         y = mouseY KR 0 0.1 Linear 0.1
+>     in 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.
+
+> g_02 =
+>     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 fSinOsc AR (1000 * r) 0 * a
+>
+> g_03 =
+>     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 delayL s (110 / 344) (d / 344) * a
diff --git a/Help/UGen/iEnvGen.help.lhs b/Help/UGen/iEnvGen.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/iEnvGen.help.lhs
@@ -0,0 +1,25 @@
+    Sound.SC3.UGen.Help.viewSC3Help "IEnvGen"
+    Sound.SC3.UGen.DB.ugenSummary "IEnvGen"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let l = [0,0.6,0.3,1.0,0]
+>         t = [0.1,0.02,0.4,1.1]
+>         c = [EnvLin,EnvExp,EnvNum (-6),EnvSin]
+>         e = Envelope l t c Nothing Nothing
+>         x = mouseX KR 0 (sum t) Linear 0.2
+>         g = iEnvGen KR x e
+>     in sinOsc AR (g * 500 + 440) 0 * 0.1
+
+index with an SinOsc ... mouse controls amplitude of SinOsc
+use offset so negative values of SinOsc will map into the Env
+
+> g_02 =
+>     let l = [-1,-0.7,0.7,1]
+>         t = [0.8666,0.2666,0.8668]
+>         c = [EnvLin,EnvLin]
+>         e = Envelope l t c Nothing Nothing
+>         x = mouseX KR 0 1 Linear 0.2
+>         o = (sinOsc AR 440 0 + 1) * x
+>     in iEnvGen AR o e * 0.1
diff --git a/Help/UGen/iRand.help.lhs b/Help/UGen/iRand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/iRand.help.lhs
@@ -0,0 +1,9 @@
+    Sound.SC3.UGen.Help.viewSC3Help "IRand"
+    Sound.SC3.UGen.DB.ugenSummary "IRand"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let f = iRand 'α' 200 1200
+>         e = line KR 0.2 0 0.1 RemoveSynth
+>     in fSinOsc AR f 0 * e
diff --git a/Help/UGen/idwt.help.lhs b/Help/UGen/idwt.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/idwt.help.lhs
@@ -0,0 +1,33 @@
+> Sound.SC3.UGen.Help.viewSC3Help "IDWT"
+> Sound.SC3.UGen.DB.ugenSummary "IDWT"
+
+> import Sound.SC3
+
+> let {i = whiteNoise 'α' AR * 0.05
+>     ;b = localBuf 'β' 1024 1
+>     ;c = dwt b i 0.5 0 1 0 0}
+> in audition (out 0 (mce2 (idwt c 0 0 0) i))
+
+direct synthesis via writing values to buffer (try changing wavelet type...)
+
+> withSC3 (async (b_alloc 10 1024 1) >> send (b_zero 10))
+
+> let {c = fftTrigger 10 0.5 0
+>     ;i = idwt c (-1) 0 0}
+> in audition (out 0 (i * 0.1))
+
+> import Control.Monad.Random
+> import Sound.SC3.Lang.Random.Monad
+
+> withSC3 (send (b_zero 10))
+
+run this to change sound: WARNING, NOISY!
+
+> do {a <- evalRandIO (nrrand 1024 (-1) 1)
+>    ;withSC3 (send (b_setn 10 [(0,a)]))}
+
+> let a = map (/ 1024) [0..1023]
+> in withSC3 (send (b_setn 10 [(0,a)]))
+
+> let a = map (\i -> 1 - i / 1024) [0..1023]
+> in withSC3 (send (b_setn 10 [(0,a)]))
diff --git a/Help/UGen/ifft.help.lhs b/Help/UGen/ifft.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ifft.help.lhs
@@ -0,0 +1,5 @@
+> Sound.SC3.UGen.Help.viewSC3Help "IFFT"
+> Sound.SC3.UGen.DB.ugenSummary "IFFT"
+> :t ifft'
+
+# ifft' is a variant with the default window type and size
diff --git a/Help/UGen/impulse.help.lhs b/Help/UGen/impulse.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/impulse.help.lhs
@@ -0,0 +1,21 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Impulse"
+    > Sound.SC3.UGen.DB.ugenSummary "Impulse"
+
+Note: SC2 had no phase input.
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = impulse AR 800 0 * 0.1
+
+> g_02 =
+>     let f = xLine KR 800 10 5 RemoveSynth
+>     in impulse AR f 0.0 * 0.1
+
+> g_03 =
+>     let f = mouseY KR 4 8 Linear 0.1
+>         x = mouseX KR 0 1 Linear 0.1
+>     in impulse AR f (mce [0,x]) * 0.1
+
+An impulse with frequency 0 returns a single impulse
+
+> g_04 = decay (impulse AR 0 0) 1 * brownNoise 'α' AR * 0.1
diff --git a/Help/UGen/in.help.lhs b/Help/UGen/in.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/in.help.lhs
@@ -0,0 +1,56 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "In"
+    > Sound.SC3.UGen.DB.ugenSummary "In"
+
+Note: `hsc3` renames UGen to `in'` since `in` is a reserved keyword
+
+> import Sound.SC3 {- hsc3 -}
+
+Patching input to output (see also soundIn).
+
+> g_01 = in' 2 AR numOutputBuses
+
+Patching input to output, with delay.
+
+> g_02 =
+>     let i = in' 2 AR numOutputBuses
+>         d = delayN i 0.5 0.5
+>     in i + d
+
+Write noise to first private bus, then read it out.
+The multiple root graph is ordered.
+
+> g_03 =
+>     let n = pinkNoise 'α' AR
+>         b = numOutputBuses + numInputBuses
+>         wr = out b (n * 0.3)
+>         rd = out 0 (in' 1 AR b)
+>     in mrg [rd,wr]
+
+There are functions to encapsulate the offset calculation.
+(There is also a firstPrivateBus value.)
+
+> g_04 =
+>     let n = pinkNoise 'α' AR
+>         wr = privateOut 0 (n * 0.3)
+>         rd = out 0 (privateIn 1 AR 0)
+>     in mrg [rd,wr]
+
+Set value on a control bus
+
+    > withSC3 (send (c_set1 0 300))
+
+Read a control bus
+
+> g_05 = sinOsc AR (in' 1 KR 0) 0 * 0.1
+
+Re-set value on bus
+
+    > withSC3 (send (c_set1 0 600))
+
+Control rate graph writing buses 0 & 1.
+
+> g_06 = mce2 (tRand 'α' 220 2200 (dust 'β' KR 1)) (dust 'γ' KR 3)
+
+Audio rate graph reading control buses 0 & 1.
+
+> g_07 = sinOsc AR (in' 1 KR 0) 0 * decay (in' 1 KR 1) 0.2 * 0.1
diff --git a/Help/UGen/inFeedback.help.lhs b/Help/UGen/inFeedback.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/inFeedback.help.lhs
@@ -0,0 +1,37 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "InFeedback"
+    > Sound.SC3.UGen.DB.ugenSummary "InFeedback"
+
+> import Sound.SC3 {- hsc3 -}
+
+Audio feedback modulation
+
+> g_01 =
+>     let f = inFeedback 1 0 * 1300 + 300
+>     in sinOsc AR f 0 * 0.4
+
+Audition these in either order and hear both tones.
+
+> g_02 = inFeedback 1 firstPrivateBus
+>
+> g_03 =
+>     let b  = firstPrivateBus
+>         s0 = out b (sinOsc AR 220 0 * 0.1)
+>         s1 = out 0 (sinOsc AR 660 0 * 0.1)
+>     in mrg [s0, s1]
+
+Doubters consult this
+
+> g_04 = let b = firstPrivateBus in in' 1 AR b
+
+Resonator, see localOut for variant.
+
+> g_05 =
+>     let b = firstPrivateBus
+>         p = inFeedback 1 b
+>         i = impulse AR 1 0
+>         d = delayC (i + (p * 0.995)) 1 (recip 440 - recip controlRate)
+>     in mrg [offsetOut b d, offsetOut 0 p]
+
+Compare with oscillator (at right).
+
+> g_06 = out 1 (sinOsc AR 440 0 * 0.2)
diff --git a/Help/UGen/inRange.help.lhs b/Help/UGen/inRange.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/inRange.help.lhs
@@ -0,0 +1,12 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "InRange"
+    > Sound.SC3.UGen.DB.ugenSummary "InRange"
+
+> import Sound.SC3 {- hsc3 -}
+
+trigger noise burst
+
+> g_01 =
+>     let n = brownNoise 'α' AR * 0.1
+>         x = mouseX KR 1 2 Linear 0.1
+>         o = sinOsc KR x 0 * 0.2
+>     in inRange o (-0.15) 0.15 * n
diff --git a/Help/UGen/inTrig.help.lhs b/Help/UGen/inTrig.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/inTrig.help.lhs
@@ -0,0 +1,15 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "InTrig"
+    > Sound.SC3.UGen.DB.ugenSummary "InTrig"
+
+> import Sound.SC3 {- hsc3 -}
+
+Run an oscillator with the trigger at bus 10.
+
+> g_01 =
+>     let t = inTrig 1 10
+>         e = envGen KR t t 0 1 DoNothing (envPerc 0.01 1)
+>     in sinOsc AR 440 0 * e
+
+Set bus 10, each set will trigger a ping.
+
+    > withSC3 (send (c_set1 10 0.1))
diff --git a/Help/UGen/index.help.lhs b/Help/UGen/index.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/index.help.lhs
@@ -0,0 +1,18 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Index"
+    > Sound.SC3.UGen.DB.ugenSummary "Index"
+
+> import Sound.SC3 {- hsc3 -}
+
+Allocate and set values at buffer ten
+
+    > withSC3 (async (b_alloc_setn1 10 0 [50,100,200,400,800,1600]))
+
+Index buffer for frequency values
+
+> g_01 =
+>     let f = index 10 (lfSaw KR 2 3 * 4)
+>     in sinOsc AR (mce [f,f * 9]) 0 * 0.1
+
+Free buffer
+
+    > withSC3 (send (b_free 10))
diff --git a/Help/UGen/indexInBetween.help.lhs b/Help/UGen/indexInBetween.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/indexInBetween.help.lhs
@@ -0,0 +1,29 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "IndexInBetween"
+    > Sound.SC3.UGen.DB.ugenSummary "IndexInBetween"
+
+> import Sound.SC3 {- hsc3 -}
+
+Allocate and set values at buffer ten
+
+    > withSC3 (async (b_alloc_setn1 10 0 [200,210,400,430,600,800]))
+
+Index into buffer for frequency values
+
+> g_01 =
+>     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 sinOsc AR (mce [f0,f1]) 0 * 0.1
+
+Free buffer
+
+    > withSC3 (send (b_free 10))
+
+> g_02 =
+>     let from = asLocalBuf 'α' [1, 2, 4, 8, 16]
+>         to = asLocalBuf 'β' [0, 1, 0, -1, 0]
+>         x = mouseX KR 1 16 Linear 0.1
+>         i = indexL KR to (indexInBetween from x)
+>     in sinOsc AR (linLin i (-1) 1 440 880) 0 * 0.1
diff --git a/Help/UGen/integrator.help.lhs b/Help/UGen/integrator.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/integrator.help.lhs
@@ -0,0 +1,32 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Integrator"
+    > Sound.SC3.UGen.DB.ugenSummary "Integrator"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let x = mouseX KR 0.001 0.999 Exponential 0.2
+>         o = lfPulse AR 300 0.2 0.1 * 0.1
+>     in integrator o x
+
+used as an envelope
+
+> g_02 =
+>     let i = lfPulse AR 3 0.2 0.0004
+>         o = sinOsc AR 700 0
+>     in integrator i 0.999 * o
+
+
+scope
+
+> g_03 =
+>     let x = mouseX KR 0.01 0.999 Exponential 0.2
+>         o = lfPulse AR (1500 / 4) 0.2 0.1
+>     in integrator o x * 0.1
+
+Drawing
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > let s = lfPulse AR (1500 / 4) 0.2 0.1
+    > plot_ugen 0.006 (integrator s (mce [0.1,0.4,0.7]))
+
+![](sw/hsc3/Help/SVG/integrator.0.svg)
diff --git a/Help/UGen/ix.md b/Help/UGen/ix.md
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ix.md
@@ -0,0 +1,717 @@
+## Algebraic
+
+[sum3](?t=hsc3&e=Help/UGen/sum3.help.lhs),
+[sum4](?t=hsc3&e=Help/UGen/sum4.help.lhs)
+
+
+## Analysis
+
+[beatTrack](?t=hsc3&e=Help/UGen/beatTrack.help.lhs),
+[beatTrack2](?t=hsc3&e=Help/UGen/beatTrack2.help.lhs),
+[mFCC](?t=hsc3&e=Help/UGen/mFCC.help.lhs),
+[onsets](?t=hsc3&e=Help/UGen/onsets.help.lhs),
+[runningSum](?t=hsc3&e=Help/UGen/runningSum.help.lhs),
+[slope](?t=hsc3&e=Help/UGen/slope.help.lhs)
+
+
+## Analysis>Amplitude
+
+[ampComp](?t=hsc3&e=Help/UGen/ampComp.help.lhs),
+[ampCompA](?t=hsc3&e=Help/UGen/ampCompA.help.lhs),
+[amplitude](?t=hsc3&e=Help/UGen/amplitude.help.lhs),
+[detectSilence](?t=hsc3&e=Help/UGen/detectSilence.help.lhs),
+[loudness](?t=hsc3&e=Help/UGen/loudness.help.lhs),
+[peak](?t=hsc3&e=Help/UGen/peak.help.lhs),
+[peakFollower](?t=hsc3&e=Help/UGen/peakFollower.help.lhs),
+[sendPeakRMS](?t=hsc3&e=Help/UGen/sendPeakRMS.help.lhs)
+
+
+## Analysis>Pitch
+
+[keyTrack](?t=hsc3&e=Help/UGen/keyTrack.help.lhs),
+[pitch](?t=hsc3&e=Help/UGen/pitch.help.lhs),
+[zeroCrossing](?t=hsc3&e=Help/UGen/zeroCrossing.help.lhs)
+
+
+## Buffer
+
+[bufRd](?t=hsc3&e=Help/UGen/bufRd.help.lhs),
+[bufWr](?t=hsc3&e=Help/UGen/bufWr.help.lhs),
+[dbufrd](?t=hsc3&e=Help/UGen/dbufrd.help.lhs),
+[dbufwr](?t=hsc3&e=Help/UGen/dbufwr.help.lhs),
+[delTapRd](?t=hsc3&e=Help/UGen/delTapRd.help.lhs),
+[delTapWr](?t=hsc3&e=Help/UGen/delTapWr.help.lhs),
+[detectIndex](?t=hsc3&e=Help/UGen/detectIndex.help.lhs),
+[diskIn](?t=hsc3&e=Help/UGen/diskIn.help.lhs),
+[diskOut](?t=hsc3&e=Help/UGen/diskOut.help.lhs),
+[grainBuf](?t=hsc3&e=Help/UGen/grainBuf.help.lhs),
+[index](?t=hsc3&e=Help/UGen/index.help.lhs),
+[indexInBetween](?t=hsc3&e=Help/UGen/indexInBetween.help.lhs),
+[indexL](?t=hsc3&e=Help/UGen/indexL.help.lhs),
+[localBuf](?t=hsc3&e=Help/UGen/localBuf.help.lhs),
+[phasor](?t=hsc3&e=Help/UGen/phasor.help.lhs),
+[playBuf](?t=hsc3&e=Help/UGen/playBuf.help.lhs),
+[recordBuf](?t=hsc3&e=Help/UGen/recordBuf.help.lhs),
+[scopeOut](?t=hsc3&e=Help/UGen/scopeOut.help.lhs),
+[shaper](?t=hsc3&e=Help/UGen/shaper.help.lhs),
+[tGrains](?t=hsc3&e=Help/UGen/tGrains.help.lhs),
+[tap](?t=hsc3&e=Help/UGen/tap.help.lhs),
+[vDiskIn](?t=hsc3&e=Help/UGen/vDiskIn.help.lhs),
+[warp1](?t=hsc3&e=Help/UGen/warp1.help.lhs),
+[wrapIndex](?t=hsc3&e=Help/UGen/wrapIndex.help.lhs)
+
+
+## Buffer>Info
+
+[bufChannels](?t=hsc3&e=Help/UGen/bufChannels.help.lhs),
+[bufDur](?t=hsc3&e=Help/UGen/bufDur.help.lhs),
+[bufFrames](?t=hsc3&e=Help/UGen/bufFrames.help.lhs),
+[bufRateScale](?t=hsc3&e=Help/UGen/bufRateScale.help.lhs),
+[bufSampleRate](?t=hsc3&e=Help/UGen/bufSampleRate.help.lhs),
+[bufSamples](?t=hsc3&e=Help/UGen/bufSamples.help.lhs)
+
+
+## Conversion
+
+[a2K](?t=hsc3&e=Help/UGen/a2K.help.lhs),
+[degreeToKey](?t=hsc3&e=Help/UGen/degreeToKey.help.lhs),
+[k2A](?t=hsc3&e=Help/UGen/k2A.help.lhs),
+[t2A](?t=hsc3&e=Help/UGen/t2A.help.lhs),
+[t2K](?t=hsc3&e=Help/UGen/t2K.help.lhs)
+
+
+## Convolution
+
+[convolution](?t=hsc3&e=Help/UGen/convolution.help.lhs),
+[convolution2](?t=hsc3&e=Help/UGen/convolution2.help.lhs),
+[convolution2L](?t=hsc3&e=Help/UGen/convolution2L.help.lhs),
+[convolution3](?t=hsc3&e=Help/UGen/convolution3.help.lhs),
+[partConv](?t=hsc3&e=Help/UGen/partConv.help.lhs),
+[stereoConvolution2L](?t=hsc3&e=Help/UGen/stereoConvolution2L.help.lhs)
+
+
+## Delays
+
+[allpassC](?t=hsc3&e=Help/UGen/allpassC.help.lhs),
+[allpassL](?t=hsc3&e=Help/UGen/allpassL.help.lhs),
+[allpassN](?t=hsc3&e=Help/UGen/allpassN.help.lhs),
+[combC](?t=hsc3&e=Help/UGen/combC.help.lhs),
+[combL](?t=hsc3&e=Help/UGen/combL.help.lhs),
+[combN](?t=hsc3&e=Help/UGen/combN.help.lhs),
+[delTapRd](?t=hsc3&e=Help/UGen/delTapRd.help.lhs),
+[delTapWr](?t=hsc3&e=Help/UGen/delTapWr.help.lhs),
+[delay1](?t=hsc3&e=Help/UGen/delay1.help.lhs),
+[delay2](?t=hsc3&e=Help/UGen/delay2.help.lhs),
+[delayC](?t=hsc3&e=Help/UGen/delayC.help.lhs),
+[delayL](?t=hsc3&e=Help/UGen/delayL.help.lhs),
+[delayN](?t=hsc3&e=Help/UGen/delayN.help.lhs),
+[pluck](?t=hsc3&e=Help/UGen/pluck.help.lhs),
+[tDelay](?t=hsc3&e=Help/UGen/tDelay.help.lhs)
+
+
+## Delays>Buffer
+
+[bufAllpassC](?t=hsc3&e=Help/UGen/bufAllpassC.help.lhs),
+[bufAllpassL](?t=hsc3&e=Help/UGen/bufAllpassL.help.lhs),
+[bufAllpassN](?t=hsc3&e=Help/UGen/bufAllpassN.help.lhs),
+[bufCombC](?t=hsc3&e=Help/UGen/bufCombC.help.lhs),
+[bufCombL](?t=hsc3&e=Help/UGen/bufCombL.help.lhs),
+[bufCombN](?t=hsc3&e=Help/UGen/bufCombN.help.lhs),
+[bufDelayC](?t=hsc3&e=Help/UGen/bufDelayC.help.lhs),
+[bufDelayL](?t=hsc3&e=Help/UGen/bufDelayL.help.lhs),
+[bufDelayN](?t=hsc3&e=Help/UGen/bufDelayN.help.lhs),
+[tap](?t=hsc3&e=Help/UGen/tap.help.lhs)
+
+
+## Demand
+
+[dbrown](?t=hsc3&e=Help/UGen/dbrown.help.lhs),
+[dbufrd](?t=hsc3&e=Help/UGen/dbufrd.help.lhs),
+[dbufwr](?t=hsc3&e=Help/UGen/dbufwr.help.lhs),
+[dconst](?t=hsc3&e=Help/UGen/dconst.help.lhs),
+[demand](?t=hsc3&e=Help/UGen/demand.help.lhs),
+[demandEnvGen](?t=hsc3&e=Help/UGen/demandEnvGen.help.lhs),
+[dgeom](?t=hsc3&e=Help/UGen/dgeom.help.lhs),
+[dibrown](?t=hsc3&e=Help/UGen/dibrown.help.lhs),
+[diwhite](?t=hsc3&e=Help/UGen/diwhite.help.lhs),
+[dpoll](?t=hsc3&e=Help/UGen/dpoll.help.lhs),
+[drand](?t=hsc3&e=Help/UGen/drand.help.lhs),
+[dreset](?t=hsc3&e=Help/UGen/dreset.help.lhs),
+[dseq](?t=hsc3&e=Help/UGen/dseq.help.lhs),
+[dser](?t=hsc3&e=Help/UGen/dser.help.lhs),
+[dseries](?t=hsc3&e=Help/UGen/dseries.help.lhs),
+[dshuf](?t=hsc3&e=Help/UGen/dshuf.help.lhs),
+[dstutter](?t=hsc3&e=Help/UGen/dstutter.help.lhs),
+[dswitch](?t=hsc3&e=Help/UGen/dswitch.help.lhs),
+[dswitch1](?t=hsc3&e=Help/UGen/dswitch1.help.lhs),
+[dunique](?t=hsc3&e=Help/UGen/dunique.help.lhs),
+[duty](?t=hsc3&e=Help/UGen/duty.help.lhs),
+[dwhite](?t=hsc3&e=Help/UGen/dwhite.help.lhs),
+[dwrand](?t=hsc3&e=Help/UGen/dwrand.help.lhs),
+[dxrand](?t=hsc3&e=Help/UGen/dxrand.help.lhs),
+[tDuty](?t=hsc3&e=Help/UGen/tDuty.help.lhs)
+
+
+## Dynamics
+
+[compander](?t=hsc3&e=Help/UGen/compander.help.lhs),
+[companderD](?t=hsc3&e=Help/UGen/companderD.help.lhs),
+[limiter](?t=hsc3&e=Help/UGen/limiter.help.lhs),
+[normalizer](?t=hsc3&e=Help/UGen/normalizer.help.lhs)
+
+
+## Envelopes
+
+[decay](?t=hsc3&e=Help/UGen/decay.help.lhs),
+[decay2](?t=hsc3&e=Help/UGen/decay2.help.lhs),
+[demandEnvGen](?t=hsc3&e=Help/UGen/demandEnvGen.help.lhs),
+[envGen](?t=hsc3&e=Help/UGen/envGen.help.lhs),
+[iEnvGen](?t=hsc3&e=Help/UGen/iEnvGen.help.lhs),
+[line](?t=hsc3&e=Help/UGen/line.help.lhs),
+[linen](?t=hsc3&e=Help/UGen/linen.help.lhs),
+[xLine](?t=hsc3&e=Help/UGen/xLine.help.lhs)
+
+
+## FFT
+
+[beatTrack](?t=hsc3&e=Help/UGen/beatTrack.help.lhs),
+[beatTrack2](?t=hsc3&e=Help/UGen/beatTrack2.help.lhs),
+[convolution](?t=hsc3&e=Help/UGen/convolution.help.lhs),
+[convolution2](?t=hsc3&e=Help/UGen/convolution2.help.lhs),
+[convolution2L](?t=hsc3&e=Help/UGen/convolution2L.help.lhs),
+[fft](?t=hsc3&e=Help/UGen/fft.help.lhs),
+[fFTTrigger](?t=hsc3&e=Help/UGen/fFTTrigger.help.lhs),
+[ifft](?t=hsc3&e=Help/UGen/ifft.help.lhs),
+[pv_Add](?t=hsc3&e=Help/UGen/pv_Add.help.lhs),
+[pv_BinScramble](?t=hsc3&e=Help/UGen/pv_BinScramble.help.lhs),
+[pv_BinShift](?t=hsc3&e=Help/UGen/pv_BinShift.help.lhs),
+[pv_BinWipe](?t=hsc3&e=Help/UGen/pv_BinWipe.help.lhs),
+[pv_BrickWall](?t=hsc3&e=Help/UGen/pv_BrickWall.help.lhs),
+[pv_ChainUGen](?t=hsc3&e=Help/UGen/pv_ChainUGen.help.lhs),
+[pv_ConformalMap](?t=hsc3&e=Help/UGen/pv_ConformalMap.help.lhs),
+[pv_Conj](?t=hsc3&e=Help/UGen/pv_Conj.help.lhs),
+[pv_Copy](?t=hsc3&e=Help/UGen/pv_Copy.help.lhs),
+[pv_CopyPhase](?t=hsc3&e=Help/UGen/pv_CopyPhase.help.lhs),
+[pv_Diffuser](?t=hsc3&e=Help/UGen/pv_Diffuser.help.lhs),
+[pv_Div](?t=hsc3&e=Help/UGen/pv_Div.help.lhs),
+[pv_HainsworthFoote](?t=hsc3&e=Help/UGen/pv_HainsworthFoote.help.lhs),
+[pv_JensenAndersen](?t=hsc3&e=Help/UGen/pv_JensenAndersen.help.lhs),
+[pv_LocalMax](?t=hsc3&e=Help/UGen/pv_LocalMax.help.lhs),
+[pv_MagAbove](?t=hsc3&e=Help/UGen/pv_MagAbove.help.lhs),
+[pv_MagBelow](?t=hsc3&e=Help/UGen/pv_MagBelow.help.lhs),
+[pv_MagClip](?t=hsc3&e=Help/UGen/pv_MagClip.help.lhs),
+[pv_MagDiv](?t=hsc3&e=Help/UGen/pv_MagDiv.help.lhs),
+[pv_MagFreeze](?t=hsc3&e=Help/UGen/pv_MagFreeze.help.lhs),
+[pv_MagMul](?t=hsc3&e=Help/UGen/pv_MagMul.help.lhs),
+[pv_MagNoise](?t=hsc3&e=Help/UGen/pv_MagNoise.help.lhs),
+[pv_MagShift](?t=hsc3&e=Help/UGen/pv_MagShift.help.lhs),
+[pv_MagSmear](?t=hsc3&e=Help/UGen/pv_MagSmear.help.lhs),
+[pv_MagSquared](?t=hsc3&e=Help/UGen/pv_MagSquared.help.lhs),
+[pv_Max](?t=hsc3&e=Help/UGen/pv_Max.help.lhs),
+[pv_Min](?t=hsc3&e=Help/UGen/pv_Min.help.lhs),
+[pv_Mul](?t=hsc3&e=Help/UGen/pv_Mul.help.lhs),
+[pv_PhaseShift](?t=hsc3&e=Help/UGen/pv_PhaseShift.help.lhs),
+[pv_PhaseShift270](?t=hsc3&e=Help/UGen/pv_PhaseShift270.help.lhs),
+[pv_PhaseShift90](?t=hsc3&e=Help/UGen/pv_PhaseShift90.help.lhs),
+[pv_RandComb](?t=hsc3&e=Help/UGen/pv_RandComb.help.lhs),
+[pv_RandWipe](?t=hsc3&e=Help/UGen/pv_RandWipe.help.lhs),
+[pv_RectComb](?t=hsc3&e=Help/UGen/pv_RectComb.help.lhs),
+[pv_RectComb2](?t=hsc3&e=Help/UGen/pv_RectComb2.help.lhs),
+[packFFT](?t=hsc3&e=Help/UGen/packFFT.help.lhs),
+[partConv](?t=hsc3&e=Help/UGen/partConv.help.lhs),
+[specCentroid](?t=hsc3&e=Help/UGen/specCentroid.help.lhs),
+[specFlatness](?t=hsc3&e=Help/UGen/specFlatness.help.lhs),
+[specPcile](?t=hsc3&e=Help/UGen/specPcile.help.lhs),
+[stereoConvolution2L](?t=hsc3&e=Help/UGen/stereoConvolution2L.help.lhs),
+[unpack1FFT](?t=hsc3&e=Help/UGen/unpack1FFT.help.lhs),
+[unpackFFT](?t=hsc3&e=Help/UGen/unpackFFT.help.lhs)
+
+
+## Filters
+
+[lag2UD](?t=hsc3&e=Help/UGen/lag2UD.help.lhs),
+[lag3UD](?t=hsc3&e=Help/UGen/lag3UD.help.lhs),
+[lagUD](?t=hsc3&e=Help/UGen/lagUD.help.lhs),
+[moogFF](?t=hsc3&e=Help/UGen/moogFF.help.lhs)
+
+
+## Filters>BEQSuite
+
+[bAllPass](?t=hsc3&e=Help/UGen/bAllPass.help.lhs),
+[bBandPass](?t=hsc3&e=Help/UGen/bBandPass.help.lhs),
+[bBandStop](?t=hsc3&e=Help/UGen/bBandStop.help.lhs),
+[bEQSuite](?t=hsc3&e=Help/UGen/bEQSuite.help.lhs),
+[bHiPass](?t=hsc3&e=Help/UGen/bHiPass.help.lhs),
+[bHiShelf](?t=hsc3&e=Help/UGen/bHiShelf.help.lhs),
+[bLowPass](?t=hsc3&e=Help/UGen/bLowPass.help.lhs),
+[bLowShelf](?t=hsc3&e=Help/UGen/bLowShelf.help.lhs),
+[bPeakEQ](?t=hsc3&e=Help/UGen/bPeakEQ.help.lhs)
+
+
+## Filters>Linear
+
+[apf](?t=hsc3&e=Help/UGen/apf.help.lhs),
+[bpf](?t=hsc3&e=Help/UGen/bpf.help.lhs),
+[bpz2](?t=hsc3&e=Help/UGen/bpz2.help.lhs),
+[brf](?t=hsc3&e=Help/UGen/brf.help.lhs),
+[brz2](?t=hsc3&e=Help/UGen/brz2.help.lhs),
+[changed](?t=hsc3&e=Help/UGen/changed.help.lhs),
+[decay](?t=hsc3&e=Help/UGen/decay.help.lhs),
+[decay2](?t=hsc3&e=Help/UGen/decay2.help.lhs),
+[dynKlank](?t=hsc3&e=Help/UGen/dynKlank.help.lhs),
+[fos](?t=hsc3&e=Help/UGen/fos.help.lhs),
+[formlet](?t=hsc3&e=Help/UGen/formlet.help.lhs),
+[hpf](?t=hsc3&e=Help/UGen/hpf.help.lhs),
+[hpz1](?t=hsc3&e=Help/UGen/hpz1.help.lhs),
+[hpz2](?t=hsc3&e=Help/UGen/hpz2.help.lhs),
+[integrator](?t=hsc3&e=Help/UGen/integrator.help.lhs),
+[klank](?t=hsc3&e=Help/UGen/klank.help.lhs),
+[lpf](?t=hsc3&e=Help/UGen/lpf.help.lhs),
+[lpz1](?t=hsc3&e=Help/UGen/lpz1.help.lhs),
+[lpz2](?t=hsc3&e=Help/UGen/lpz2.help.lhs),
+[lag](?t=hsc3&e=Help/UGen/lag.help.lhs),
+[lag2](?t=hsc3&e=Help/UGen/lag2.help.lhs),
+[lag3](?t=hsc3&e=Help/UGen/lag3.help.lhs),
+[leakDC](?t=hsc3&e=Help/UGen/leakDC.help.lhs),
+[midEQ](?t=hsc3&e=Help/UGen/midEQ.help.lhs),
+[onePole](?t=hsc3&e=Help/UGen/onePole.help.lhs),
+[oneZero](?t=hsc3&e=Help/UGen/oneZero.help.lhs),
+[rhpf](?t=hsc3&e=Help/UGen/rhpf.help.lhs),
+[rlpf](?t=hsc3&e=Help/UGen/rlpf.help.lhs),
+[ramp](?t=hsc3&e=Help/UGen/ramp.help.lhs),
+[resonz](?t=hsc3&e=Help/UGen/resonz.help.lhs),
+[ringz](?t=hsc3&e=Help/UGen/ringz.help.lhs),
+[sos](?t=hsc3&e=Help/UGen/sos.help.lhs),
+[slope](?t=hsc3&e=Help/UGen/slope.help.lhs),
+[twoPole](?t=hsc3&e=Help/UGen/twoPole.help.lhs),
+[twoZero](?t=hsc3&e=Help/UGen/twoZero.help.lhs),
+[varLag](?t=hsc3&e=Help/UGen/varLag.help.lhs)
+
+
+## Filters>Nonlinear
+
+[ball](?t=hsc3&e=Help/UGen/ball.help.lhs),
+[freqShift](?t=hsc3&e=Help/UGen/freqShift.help.lhs),
+[hasher](?t=hsc3&e=Help/UGen/hasher.help.lhs),
+[hilbert](?t=hsc3&e=Help/UGen/hilbert.help.lhs),
+[hilbertFIR](?t=hsc3&e=Help/UGen/hilbertFIR.help.lhs),
+[mantissaMask](?t=hsc3&e=Help/UGen/mantissaMask.help.lhs),
+[median](?t=hsc3&e=Help/UGen/median.help.lhs),
+[slew](?t=hsc3&e=Help/UGen/slew.help.lhs),
+[spring](?t=hsc3&e=Help/UGen/spring.help.lhs),
+[tBall](?t=hsc3&e=Help/UGen/tBall.help.lhs)
+
+
+## Filters>Pitch
+
+[freqShift](?t=hsc3&e=Help/UGen/freqShift.help.lhs),
+[pitchShift](?t=hsc3&e=Help/UGen/pitchShift.help.lhs),
+[vibrato](?t=hsc3&e=Help/UGen/vibrato.help.lhs)
+
+
+## Generators>Chaotic
+
+[chaosGen](?t=hsc3&e=Help/UGen/chaosGen.help.lhs),
+[cuspL](?t=hsc3&e=Help/UGen/cuspL.help.lhs),
+[cuspN](?t=hsc3&e=Help/UGen/cuspN.help.lhs),
+[fBSineC](?t=hsc3&e=Help/UGen/fBSineC.help.lhs),
+[fBSineL](?t=hsc3&e=Help/UGen/fBSineL.help.lhs),
+[fBSineN](?t=hsc3&e=Help/UGen/fBSineN.help.lhs),
+[gbmanL](?t=hsc3&e=Help/UGen/gbmanL.help.lhs),
+[gbmanN](?t=hsc3&e=Help/UGen/gbmanN.help.lhs),
+[henonC](?t=hsc3&e=Help/UGen/henonC.help.lhs),
+[henonL](?t=hsc3&e=Help/UGen/henonL.help.lhs),
+[henonN](?t=hsc3&e=Help/UGen/henonN.help.lhs),
+[latoocarfianC](?t=hsc3&e=Help/UGen/latoocarfianC.help.lhs),
+[latoocarfianL](?t=hsc3&e=Help/UGen/latoocarfianL.help.lhs),
+[latoocarfianN](?t=hsc3&e=Help/UGen/latoocarfianN.help.lhs),
+[linCongC](?t=hsc3&e=Help/UGen/linCongC.help.lhs),
+[linCongL](?t=hsc3&e=Help/UGen/linCongL.help.lhs),
+[linCongN](?t=hsc3&e=Help/UGen/linCongN.help.lhs),
+[logistic](?t=hsc3&e=Help/UGen/logistic.help.lhs),
+[lorenzL](?t=hsc3&e=Help/UGen/lorenzL.help.lhs),
+[quadC](?t=hsc3&e=Help/UGen/quadC.help.lhs),
+[quadL](?t=hsc3&e=Help/UGen/quadL.help.lhs),
+[quadN](?t=hsc3&e=Help/UGen/quadN.help.lhs),
+[sinOscFB](?t=hsc3&e=Help/UGen/sinOscFB.help.lhs),
+[standardL](?t=hsc3&e=Help/UGen/standardL.help.lhs),
+[standardN](?t=hsc3&e=Help/UGen/standardN.help.lhs)
+
+
+## Generators>Deterministic
+
+[blip](?t=hsc3&e=Help/UGen/blip.help.lhs),
+[cOsc](?t=hsc3&e=Help/UGen/cOsc.help.lhs),
+[dynKlang](?t=hsc3&e=Help/UGen/dynKlang.help.lhs),
+[dynKlank](?t=hsc3&e=Help/UGen/dynKlank.help.lhs),
+[fSinOsc](?t=hsc3&e=Help/UGen/fSinOsc.help.lhs),
+[formant](?t=hsc3&e=Help/UGen/formant.help.lhs),
+[impulse](?t=hsc3&e=Help/UGen/impulse.help.lhs),
+[klang](?t=hsc3&e=Help/UGen/klang.help.lhs),
+[klank](?t=hsc3&e=Help/UGen/klank.help.lhs),
+[lfCub](?t=hsc3&e=Help/UGen/lfCub.help.lhs),
+[lfGauss](?t=hsc3&e=Help/UGen/lfGauss.help.lhs),
+[lfPar](?t=hsc3&e=Help/UGen/lfPar.help.lhs),
+[lfPulse](?t=hsc3&e=Help/UGen/lfPulse.help.lhs),
+[lfSaw](?t=hsc3&e=Help/UGen/lfSaw.help.lhs),
+[lfTri](?t=hsc3&e=Help/UGen/lfTri.help.lhs),
+[osc](?t=hsc3&e=Help/UGen/osc.help.lhs),
+[oscN](?t=hsc3&e=Help/UGen/oscN.help.lhs),
+[pSinGrain](?t=hsc3&e=Help/UGen/pSinGrain.help.lhs),
+[pulse](?t=hsc3&e=Help/UGen/pulse.help.lhs),
+[saw](?t=hsc3&e=Help/UGen/saw.help.lhs),
+[sinOsc](?t=hsc3&e=Help/UGen/sinOsc.help.lhs),
+[sinOscFB](?t=hsc3&e=Help/UGen/sinOscFB.help.lhs),
+[syncSaw](?t=hsc3&e=Help/UGen/syncSaw.help.lhs),
+[vOsc](?t=hsc3&e=Help/UGen/vOsc.help.lhs),
+[vOsc3](?t=hsc3&e=Help/UGen/vOsc3.help.lhs),
+[varSaw](?t=hsc3&e=Help/UGen/varSaw.help.lhs),
+[vibrato](?t=hsc3&e=Help/UGen/vibrato.help.lhs)
+
+
+## Generators>Granular
+
+[grainBuf](?t=hsc3&e=Help/UGen/grainBuf.help.lhs),
+[grainFM](?t=hsc3&e=Help/UGen/grainFM.help.lhs),
+[grainIn](?t=hsc3&e=Help/UGen/grainIn.help.lhs),
+[grainSin](?t=hsc3&e=Help/UGen/grainSin.help.lhs),
+[tGrains](?t=hsc3&e=Help/UGen/tGrains.help.lhs),
+[warp1](?t=hsc3&e=Help/UGen/warp1.help.lhs)
+
+
+## Generators>PhysicalModels
+
+[ball](?t=hsc3&e=Help/UGen/ball.help.lhs),
+[spring](?t=hsc3&e=Help/UGen/spring.help.lhs),
+[tBall](?t=hsc3&e=Help/UGen/tBall.help.lhs)
+
+
+## Generators>Single-value
+
+[dc](?t=hsc3&e=Help/UGen/dc.help.lhs)
+
+
+## Generators>Stochastic
+
+[brownNoise](?t=hsc3&e=Help/UGen/brownNoise.help.lhs),
+[clipNoise](?t=hsc3&e=Help/UGen/clipNoise.help.lhs),
+[coinGate](?t=hsc3&e=Help/UGen/coinGate.help.lhs),
+[crackle](?t=hsc3&e=Help/UGen/crackle.help.lhs),
+[dust](?t=hsc3&e=Help/UGen/dust.help.lhs),
+[dust2](?t=hsc3&e=Help/UGen/dust2.help.lhs),
+[gendy1](?t=hsc3&e=Help/UGen/gendy1.help.lhs),
+[gendy2](?t=hsc3&e=Help/UGen/gendy2.help.lhs),
+[gendy3](?t=hsc3&e=Help/UGen/gendy3.help.lhs),
+[grayNoise](?t=hsc3&e=Help/UGen/grayNoise.help.lhs),
+[lfClipNoise](?t=hsc3&e=Help/UGen/lfClipNoise.help.lhs),
+[lfdClipNoise](?t=hsc3&e=Help/UGen/lfdClipNoise.help.lhs),
+[lfdNoise0](?t=hsc3&e=Help/UGen/lfdNoise0.help.lhs),
+[lfdNoise1](?t=hsc3&e=Help/UGen/lfdNoise1.help.lhs),
+[lfdNoise3](?t=hsc3&e=Help/UGen/lfdNoise3.help.lhs),
+[lfNoise0](?t=hsc3&e=Help/UGen/lfNoise0.help.lhs),
+[lfNoise1](?t=hsc3&e=Help/UGen/lfNoise1.help.lhs),
+[lfNoise2](?t=hsc3&e=Help/UGen/lfNoise2.help.lhs),
+[pinkNoise](?t=hsc3&e=Help/UGen/pinkNoise.help.lhs),
+[randID](?t=hsc3&e=Help/UGen/randID.help.lhs),
+[randSeed](?t=hsc3&e=Help/UGen/randSeed.help.lhs),
+[vibrato](?t=hsc3&e=Help/UGen/vibrato.help.lhs),
+[whiteNoise](?t=hsc3&e=Help/UGen/whiteNoise.help.lhs)
+
+
+## InOut
+
+[diskIn](?t=hsc3&e=Help/UGen/diskIn.help.lhs),
+[diskOut](?t=hsc3&e=Help/UGen/diskOut.help.lhs),
+[in](?t=hsc3&e=Help/UGen/in.help.lhs),
+[inFeedback](?t=hsc3&e=Help/UGen/inFeedback.help.lhs),
+[inTrig](?t=hsc3&e=Help/UGen/inTrig.help.lhs),
+[lagIn](?t=hsc3&e=Help/UGen/lagIn.help.lhs),
+[localIn](?t=hsc3&e=Help/UGen/localIn.help.lhs),
+[localOut](?t=hsc3&e=Help/UGen/localOut.help.lhs),
+[maxLocalBufs](?t=hsc3&e=Help/UGen/maxLocalBufs.help.lhs),
+[offsetOut](?t=hsc3&e=Help/UGen/offsetOut.help.lhs),
+[out](?t=hsc3&e=Help/UGen/out.help.lhs),
+[replaceOut](?t=hsc3&e=Help/UGen/replaceOut.help.lhs),
+[vDiskIn](?t=hsc3&e=Help/UGen/vDiskIn.help.lhs),
+[xOut](?t=hsc3&e=Help/UGen/xOut.help.lhs)
+
+
+## Info
+
+[checkBadValues](?t=hsc3&e=Help/UGen/checkBadValues.help.lhs),
+[controlDur](?t=hsc3&e=Help/UGen/controlDur.help.lhs),
+[controlRate](?t=hsc3&e=Help/UGen/controlRate.help.lhs),
+[dpoll](?t=hsc3&e=Help/UGen/dpoll.help.lhs),
+[numAudioBuses](?t=hsc3&e=Help/UGen/numAudioBuses.help.lhs),
+[numBuffers](?t=hsc3&e=Help/UGen/numBuffers.help.lhs),
+[numControlBuses](?t=hsc3&e=Help/UGen/numControlBuses.help.lhs),
+[numInputBuses](?t=hsc3&e=Help/UGen/numInputBuses.help.lhs),
+[numOutputBuses](?t=hsc3&e=Help/UGen/numOutputBuses.help.lhs),
+[numRunningSynths](?t=hsc3&e=Help/UGen/numRunningSynths.help.lhs),
+[poll](?t=hsc3&e=Help/UGen/poll.help.lhs),
+[radiansPerSample](?t=hsc3&e=Help/UGen/radiansPerSample.help.lhs),
+[sampleDur](?t=hsc3&e=Help/UGen/sampleDur.help.lhs),
+[sampleRate](?t=hsc3&e=Help/UGen/sampleRate.help.lhs),
+[subsampleOffset](?t=hsc3&e=Help/UGen/subsampleOffset.help.lhs)
+
+
+## Maths
+
+[clip](?t=hsc3&e=Help/UGen/clip.help.lhs),
+[fold](?t=hsc3&e=Help/UGen/fold.help.lhs),
+[inRange](?t=hsc3&e=Help/UGen/inRange.help.lhs),
+[inRect](?t=hsc3&e=Help/UGen/inRect.help.lhs),
+[integrator](?t=hsc3&e=Help/UGen/integrator.help.lhs),
+[leastChange](?t=hsc3&e=Help/UGen/leastChange.help.lhs),
+[linExp](?t=hsc3&e=Help/UGen/linExp.help.lhs),
+[modDif](?t=hsc3&e=Help/UGen/modDif.help.lhs),
+[mostChange](?t=hsc3&e=Help/UGen/mostChange.help.lhs),
+[mulAdd](?t=hsc3&e=Help/UGen/mulAdd.help.lhs),
+[runningMax](?t=hsc3&e=Help/UGen/runningMax.help.lhs),
+[runningMin](?t=hsc3&e=Help/UGen/runningMin.help.lhs),
+[runningSum](?t=hsc3&e=Help/UGen/runningSum.help.lhs),
+[schmidt](?t=hsc3&e=Help/UGen/schmidt.help.lhs),
+[slope](?t=hsc3&e=Help/UGen/slope.help.lhs),
+[wrap](?t=hsc3&e=Help/UGen/wrap.help.lhs)
+
+
+## Multichannel>Ambisonics
+
+[biPanB2](?t=hsc3&e=Help/UGen/biPanB2.help.lhs),
+[decodeB2](?t=hsc3&e=Help/UGen/decodeB2.help.lhs),
+[panB](?t=hsc3&e=Help/UGen/panB.help.lhs),
+[panB2](?t=hsc3&e=Help/UGen/panB2.help.lhs),
+[rotate2](?t=hsc3&e=Help/UGen/rotate2.help.lhs)
+
+
+## Multichannel>Panners
+
+[balance2](?t=hsc3&e=Help/UGen/balance2.help.lhs),
+[linPan2](?t=hsc3&e=Help/UGen/linPan2.help.lhs),
+[pan2](?t=hsc3&e=Help/UGen/pan2.help.lhs),
+[pan4](?t=hsc3&e=Help/UGen/pan4.help.lhs),
+[panAz](?t=hsc3&e=Help/UGen/panAz.help.lhs),
+[rotate2](?t=hsc3&e=Help/UGen/rotate2.help.lhs),
+[splay](?t=hsc3&e=Help/UGen/splay.help.lhs),
+[splayAz](?t=hsc3&e=Help/UGen/splayAz.help.lhs)
+
+
+## Multichannel>Select
+
+[linXFade2](?t=hsc3&e=Help/UGen/linXFade2.help.lhs),
+[select](?t=hsc3&e=Help/UGen/select.help.lhs),
+[xFade2](?t=hsc3&e=Help/UGen/xFade2.help.lhs)
+
+
+## Random
+
+[dshuf](?t=hsc3&e=Help/UGen/dshuf.help.lhs),
+[dwrand](?t=hsc3&e=Help/UGen/dwrand.help.lhs),
+[expRand](?t=hsc3&e=Help/UGen/expRand.help.lhs),
+[hasher](?t=hsc3&e=Help/UGen/hasher.help.lhs),
+[iRand](?t=hsc3&e=Help/UGen/iRand.help.lhs),
+[linRand](?t=hsc3&e=Help/UGen/linRand.help.lhs),
+[nRand](?t=hsc3&e=Help/UGen/nRand.help.lhs),
+[rand](?t=hsc3&e=Help/UGen/rand.help.lhs),
+[randID](?t=hsc3&e=Help/UGen/randID.help.lhs),
+[randSeed](?t=hsc3&e=Help/UGen/randSeed.help.lhs),
+[tExpRand](?t=hsc3&e=Help/UGen/tExpRand.help.lhs),
+[tIRand](?t=hsc3&e=Help/UGen/tIRand.help.lhs),
+[tRand](?t=hsc3&e=Help/UGen/tRand.help.lhs),
+[tWindex](?t=hsc3&e=Help/UGen/tWindex.help.lhs)
+
+
+## Reverbs
+
+[freeVerb](?t=hsc3&e=Help/UGen/freeVerb.help.lhs),
+[freeVerb2](?t=hsc3&e=Help/UGen/freeVerb2.help.lhs),
+[gVerb](?t=hsc3&e=Help/UGen/gVerb.help.lhs)
+
+
+## Synth control
+
+[control](?t=hsc3&e=Help/UGen/control.help.lhs),
+[detectSilence](?t=hsc3&e=Help/UGen/detectSilence.help.lhs),
+[done](?t=hsc3&e=Help/UGen/done.help.lhs),
+[free](?t=hsc3&e=Help/UGen/free.help.lhs),
+[freeSelf](?t=hsc3&e=Help/UGen/freeSelf.help.lhs),
+[freeSelfWhenDone](?t=hsc3&e=Help/UGen/freeSelfWhenDone.help.lhs),
+[lagControl](?t=hsc3&e=Help/UGen/lagControl.help.lhs),
+[pause](?t=hsc3&e=Help/UGen/pause.help.lhs),
+[pauseSelf](?t=hsc3&e=Help/UGen/pauseSelf.help.lhs),
+[pauseSelfWhenDone](?t=hsc3&e=Help/UGen/pauseSelfWhenDone.help.lhs),
+[trigControl](?t=hsc3&e=Help/UGen/trigControl.help.lhs)
+
+
+## Triggers
+
+[changed](?t=hsc3&e=Help/UGen/changed.help.lhs),
+[gate](?t=hsc3&e=Help/UGen/gate.help.lhs),
+[inTrig](?t=hsc3&e=Help/UGen/inTrig.help.lhs),
+[lastValue](?t=hsc3&e=Help/UGen/lastValue.help.lhs),
+[latch](?t=hsc3&e=Help/UGen/latch.help.lhs),
+[phasor](?t=hsc3&e=Help/UGen/phasor.help.lhs),
+[pulseCount](?t=hsc3&e=Help/UGen/pulseCount.help.lhs),
+[pulseDivider](?t=hsc3&e=Help/UGen/pulseDivider.help.lhs),
+[sendReply](?t=hsc3&e=Help/UGen/sendReply.help.lhs),
+[sendTrig](?t=hsc3&e=Help/UGen/sendTrig.help.lhs),
+[setResetFF](?t=hsc3&e=Help/UGen/setResetFF.help.lhs),
+[stepper](?t=hsc3&e=Help/UGen/stepper.help.lhs),
+[sweep](?t=hsc3&e=Help/UGen/sweep.help.lhs),
+[t2A](?t=hsc3&e=Help/UGen/t2A.help.lhs),
+[t2K](?t=hsc3&e=Help/UGen/t2K.help.lhs),
+[tDelay](?t=hsc3&e=Help/UGen/tDelay.help.lhs),
+[tExpRand](?t=hsc3&e=Help/UGen/tExpRand.help.lhs),
+[tIRand](?t=hsc3&e=Help/UGen/tIRand.help.lhs),
+[tRand](?t=hsc3&e=Help/UGen/tRand.help.lhs),
+[tWindex](?t=hsc3&e=Help/UGen/tWindex.help.lhs),
+[timer](?t=hsc3&e=Help/UGen/timer.help.lhs),
+[toggleFF](?t=hsc3&e=Help/UGen/toggleFF.help.lhs),
+[trig](?t=hsc3&e=Help/UGen/trig.help.lhs),
+[trig1](?t=hsc3&e=Help/UGen/trig1.help.lhs)
+
+
+## Undocumented
+
+[apf](?t=hsc3&e=Help/UGen/apf.help.lhs),
+[audioControl](?t=hsc3&e=Help/UGen/audioControl.help.lhs),
+[blockSize](?t=hsc3&e=Help/UGen/blockSize.help.lhs),
+[dustR](?t=hsc3&e=Help/UGen/dustR.help.lhs),
+[nodeID](?t=hsc3&e=Help/UGen/nodeID.help.lhs),
+[pauseSelfWhenDone](?t=hsc3&e=Help/UGen/pauseSelfWhenDone.help.lhs),
+[rDelayMap](?t=hsc3&e=Help/UGen/rDelayMap.help.lhs),
+[rDelaySet](?t=hsc3&e=Help/UGen/rDelaySet.help.lhs),
+[rDelaySetB](?t=hsc3&e=Help/UGen/rDelaySetB.help.lhs),
+[rFreezer](?t=hsc3&e=Help/UGen/rFreezer.help.lhs),
+[rLoopSet](?t=hsc3&e=Help/UGen/rLoopSet.help.lhs),
+[rPlayTrace](?t=hsc3&e=Help/UGen/rPlayTrace.help.lhs),
+[rShufflerB](?t=hsc3&e=Help/UGen/rShufflerB.help.lhs),
+[rShufflerL](?t=hsc3&e=Help/UGen/rShufflerL.help.lhs),
+[rTraceRd](?t=hsc3&e=Help/UGen/rTraceRd.help.lhs),
+[rTraceRdX](?t=hsc3&e=Help/UGen/rTraceRdX.help.lhs),
+[rTraceRdY](?t=hsc3&e=Help/UGen/rTraceRdY.help.lhs),
+[rTraceRdZ](?t=hsc3&e=Help/UGen/rTraceRdZ.help.lhs),
+[scopeOut](?t=hsc3&e=Help/UGen/scopeOut.help.lhs),
+[scopeOut2](?t=hsc3&e=Help/UGen/scopeOut2.help.lhs),
+[trigControl](?t=hsc3&e=Help/UGen/trigControl.help.lhs)
+
+
+## User interaction
+
+[keyState](?t=hsc3&e=Help/UGen/keyState.help.lhs),
+[mouseButton](?t=hsc3&e=Help/UGen/mouseButton.help.lhs),
+[mouseX](?t=hsc3&e=Help/UGen/mouseX.help.lhs),
+[mouseY](?t=hsc3&e=Help/UGen/mouseY.help.lhs)
+
+
+## Operator>Binary
+
+[add](?t=hsc3&e=Help/UGen/add.help.lhs),
+[sub](?t=hsc3&e=Help/UGen/sub.help.lhs),
+[mul](?t=hsc3&e=Help/UGen/mul.help.lhs),
+[iDiv](?t=hsc3&e=Help/UGen/iDiv.help.lhs),
+[fDiv](?t=hsc3&e=Help/UGen/fDiv.help.lhs),
+[mod](?t=hsc3&e=Help/UGen/mod.help.lhs),
+[eq](?t=hsc3&e=Help/UGen/eq.help.lhs),
+[ne](?t=hsc3&e=Help/UGen/ne.help.lhs),
+[lt](?t=hsc3&e=Help/UGen/lt.help.lhs),
+[gt](?t=hsc3&e=Help/UGen/gt.help.lhs),
+[le](?t=hsc3&e=Help/UGen/le.help.lhs),
+[ge](?t=hsc3&e=Help/UGen/ge.help.lhs),
+[min](?t=hsc3&e=Help/UGen/min.help.lhs),
+[max](?t=hsc3&e=Help/UGen/max.help.lhs),
+[bitAnd](?t=hsc3&e=Help/UGen/bitAnd.help.lhs),
+[bitOr](?t=hsc3&e=Help/UGen/bitOr.help.lhs),
+[bitXor](?t=hsc3&e=Help/UGen/bitXor.help.lhs),
+[lcm](?t=hsc3&e=Help/UGen/lcm.help.lhs),
+[gcd](?t=hsc3&e=Help/UGen/gcd.help.lhs),
+[round](?t=hsc3&e=Help/UGen/round.help.lhs),
+[roundUp](?t=hsc3&e=Help/UGen/roundUp.help.lhs),
+[trunc](?t=hsc3&e=Help/UGen/trunc.help.lhs),
+[atan2](?t=hsc3&e=Help/UGen/atan2.help.lhs),
+[hypot](?t=hsc3&e=Help/UGen/hypot.help.lhs),
+[hypotx](?t=hsc3&e=Help/UGen/hypotx.help.lhs),
+[pow](?t=hsc3&e=Help/UGen/pow.help.lhs),
+[shiftLeft](?t=hsc3&e=Help/UGen/shiftLeft.help.lhs),
+[shiftRight](?t=hsc3&e=Help/UGen/shiftRight.help.lhs),
+[unsignedShift](?t=hsc3&e=Help/UGen/unsignedShift.help.lhs),
+[fill](?t=hsc3&e=Help/UGen/fill.help.lhs),
+[ring1](?t=hsc3&e=Help/UGen/ring1.help.lhs),
+[ring2](?t=hsc3&e=Help/UGen/ring2.help.lhs),
+[ring3](?t=hsc3&e=Help/UGen/ring3.help.lhs),
+[ring4](?t=hsc3&e=Help/UGen/ring4.help.lhs),
+[difSqr](?t=hsc3&e=Help/UGen/difSqr.help.lhs),
+[sumSqr](?t=hsc3&e=Help/UGen/sumSqr.help.lhs),
+[sqrSum](?t=hsc3&e=Help/UGen/sqrSum.help.lhs),
+[sqrDif](?t=hsc3&e=Help/UGen/sqrDif.help.lhs),
+[absDif](?t=hsc3&e=Help/UGen/absDif.help.lhs),
+[thresh](?t=hsc3&e=Help/UGen/thresh.help.lhs),
+[aMClip](?t=hsc3&e=Help/UGen/aMClip.help.lhs),
+[scaleNeg](?t=hsc3&e=Help/UGen/scaleNeg.help.lhs),
+[clip2](?t=hsc3&e=Help/UGen/clip2.help.lhs),
+[excess](?t=hsc3&e=Help/UGen/excess.help.lhs),
+[fold2](?t=hsc3&e=Help/UGen/fold2.help.lhs),
+[wrap2](?t=hsc3&e=Help/UGen/wrap2.help.lhs),
+[firstArg](?t=hsc3&e=Help/UGen/firstArg.help.lhs),
+[randRange](?t=hsc3&e=Help/UGen/randRange.help.lhs),
+[expRandRange](?t=hsc3&e=Help/UGen/expRandRange.help.lhs)
+
+
+## Operator>Unary
+
+[neg](?t=hsc3&e=Help/UGen/neg.help.lhs),
+[not](?t=hsc3&e=Help/UGen/not.help.lhs),
+[isNil](?t=hsc3&e=Help/UGen/isNil.help.lhs),
+[notNil](?t=hsc3&e=Help/UGen/notNil.help.lhs),
+[bitNot](?t=hsc3&e=Help/UGen/bitNot.help.lhs),
+[abs](?t=hsc3&e=Help/UGen/abs.help.lhs),
+[asFloat](?t=hsc3&e=Help/UGen/asFloat.help.lhs),
+[asInt](?t=hsc3&e=Help/UGen/asInt.help.lhs),
+[ceil](?t=hsc3&e=Help/UGen/ceil.help.lhs),
+[floor](?t=hsc3&e=Help/UGen/floor.help.lhs),
+[frac](?t=hsc3&e=Help/UGen/frac.help.lhs),
+[sign](?t=hsc3&e=Help/UGen/sign.help.lhs),
+[squared](?t=hsc3&e=Help/UGen/squared.help.lhs),
+[cubed](?t=hsc3&e=Help/UGen/cubed.help.lhs),
+[sqrt](?t=hsc3&e=Help/UGen/sqrt.help.lhs),
+[exp](?t=hsc3&e=Help/UGen/exp.help.lhs),
+[recip](?t=hsc3&e=Help/UGen/recip.help.lhs),
+[mIDICPS](?t=hsc3&e=Help/UGen/mIDICPS.help.lhs),
+[cPSMIDI](?t=hsc3&e=Help/UGen/cPSMIDI.help.lhs),
+[mIDIRatio](?t=hsc3&e=Help/UGen/mIDIRatio.help.lhs),
+[ratioMIDI](?t=hsc3&e=Help/UGen/ratioMIDI.help.lhs),
+[dbAmp](?t=hsc3&e=Help/UGen/dbAmp.help.lhs),
+[ampDb](?t=hsc3&e=Help/UGen/ampDb.help.lhs),
+[octCPS](?t=hsc3&e=Help/UGen/octCPS.help.lhs),
+[cPSOct](?t=hsc3&e=Help/UGen/cPSOct.help.lhs),
+[log](?t=hsc3&e=Help/UGen/log.help.lhs),
+[log2](?t=hsc3&e=Help/UGen/log2.help.lhs),
+[log10](?t=hsc3&e=Help/UGen/log10.help.lhs),
+[sin](?t=hsc3&e=Help/UGen/sin.help.lhs),
+[cos](?t=hsc3&e=Help/UGen/cos.help.lhs),
+[tan](?t=hsc3&e=Help/UGen/tan.help.lhs),
+[arcSin](?t=hsc3&e=Help/UGen/arcSin.help.lhs),
+[arcCos](?t=hsc3&e=Help/UGen/arcCos.help.lhs),
+[arcTan](?t=hsc3&e=Help/UGen/arcTan.help.lhs),
+[sinH](?t=hsc3&e=Help/UGen/sinH.help.lhs),
+[cosH](?t=hsc3&e=Help/UGen/cosH.help.lhs),
+[tanH](?t=hsc3&e=Help/UGen/tanH.help.lhs),
+[rand_](?t=hsc3&e=Help/UGen/rand_.help.lhs),
+[rand2](?t=hsc3&e=Help/UGen/rand2.help.lhs),
+[linRand_](?t=hsc3&e=Help/UGen/linRand_.help.lhs),
+[biLinRand](?t=hsc3&e=Help/UGen/biLinRand.help.lhs),
+[sum3Rand](?t=hsc3&e=Help/UGen/sum3Rand.help.lhs),
+[distort](?t=hsc3&e=Help/UGen/distort.help.lhs),
+[softClip](?t=hsc3&e=Help/UGen/softClip.help.lhs),
+[coin](?t=hsc3&e=Help/UGen/coin.help.lhs),
+[digitValue](?t=hsc3&e=Help/UGen/digitValue.help.lhs),
+[silence](?t=hsc3&e=Help/UGen/silence.help.lhs),
+[thru](?t=hsc3&e=Help/UGen/thru.help.lhs),
+[rectWindow](?t=hsc3&e=Help/UGen/rectWindow.help.lhs),
+[hanWindow](?t=hsc3&e=Help/UGen/hanWindow.help.lhs),
+[welchWindow](?t=hsc3&e=Help/UGen/welchWindow.help.lhs),
+[triWindow](?t=hsc3&e=Help/UGen/triWindow.help.lhs),
+[ramp_](?t=hsc3&e=Help/UGen/ramp_.help.lhs),
+[sCurve](?t=hsc3&e=Help/UGen/sCurve.help.lhs)
+
+
diff --git a/Help/UGen/k2A.help.lhs b/Help/UGen/k2A.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/k2A.help.lhs
@@ -0,0 +1,17 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "K2A"
+    > Sound.SC3.UGen.DB.ugenSummary "K2A"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = k2A (whiteNoise 'α' KR * 0.3)
+
+compare
+
+> g_02 = mce2 (k2A (whiteNoise 'α' KR * 0.3)) (whiteNoise 'β' AR * 0.1)
+
+> g_03 =
+>     let blockSize = controlDur * sampleRate
+>         freq = (mouseX KR 0.1 40 Exponential 0.2) / blockSize * sampleRate;
+>         o1 = k2A (lfNoise0 'α' KR freq)
+>         o2 = lfNoise0 'β' AR freq
+>     in mce2 o1 o2 * 0.1
diff --git a/Help/UGen/keyState.help.lhs b/Help/UGen/keyState.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/keyState.help.lhs
@@ -0,0 +1,9 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "KeyState"
+    > Sound.SC3.UGen.DB.ugenSummary "KeyState"
+
+> import Sound.SC3 {- hsc3 -}
+
+The keycode 38 is the A key on my keyboard.  Under X the xev(1)
+command is useful in determining your keyboard layout.
+
+> g_01 = sinOsc AR 800 0 * keyState KR 38 0 0.1 0.5
diff --git a/Help/UGen/klang.help.lhs b/Help/UGen/klang.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/klang.help.lhs
@@ -0,0 +1,31 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Klang"
+    > Sound.SC3.UGen.DB.ugenSummary "Klang"
+
+Note: SC2 had mul/add inputs.
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let f = [440,550..1100]
+>         a = take 7 (cycle [0.05, 0.02])
+>         p = replicate 7 0
+>     in klang AR 1 0 (klangSpec f a p)
+
+    play({Klang.ar(`[[800,1000,1200],[0.3,0.3,0.3],[pi,pi,pi]],1,0)*0.4})
+
+> g_02 =
+>     let s = klangSpec [800,1000,1200] [0.3,0.3,0.3] [pi,pi,pi]
+>     in klang AR 1 0 s * 0.4
+
+    play({Klang.ar(`[[800,1000,1200],nil,nil],1,0)*0.25})
+
+> g_03 =
+>     let s = klangSpec [800,1000,1200] [1,1,1] [0,0,0]
+>     in klang AR 1 0 s * 0.25
+
+    play({Klang.ar(`[Array.rand(12,600.0,1000.0),nil,nil],1,0)*0.05})
+
+> g_04 =
+>     let f = map (\z -> rand z 600 1000) ['a'..'l']
+>         s = klangSpec f (replicate 12 1) (replicate 12 0)
+>     in klang AR 1 0 s * 0.05
diff --git a/Help/UGen/klank.help.lhs b/Help/UGen/klank.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/klank.help.lhs
@@ -0,0 +1,34 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Klank"
+    > Sound.SC3.UGen.DB.ugenSummary "Klank"
+
+> import Sound.SC3 {- hsc3 -}
+
+The function klankSpec can help create the 'spec' entry.
+
+> g_01 =
+>     let s = klankSpec' [800,1071,1153,1723] [1,1,1,1] [1,1,1,1]
+>     in klank (impulse AR 2 0 * 0.1) 1 0 1 s
+
+A variant spec function takes non-UGen inputs
+
+> g_02 =
+>     let f = [800::Double,1071,1153,1723]
+>         u = [1,1,1,1]
+>         s = klankSpec' f u u
+>     in 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 transposed and force expansion in a sensible manner.
+
+> g_03 =
+>     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
+>         l = mce [-1,0,1]
+>     in mix (pan2 (klank t 1 0 1 s) l 1)
diff --git a/Help/UGen/lag.help.lhs b/Help/UGen/lag.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lag.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Lag"
+    > Sound.SC3.UGen.DB.ugenSummary "Lag"
+
+> import Sound.SC3 {- hsc3 -}
+
+used to lag pitch
+
+> g_01 =
+>     let x = mouseX KR 220 440 Linear 0.2
+>     in sinOsc AR (mce [x, lag x 1]) 0 * 0.1
+
+used to smooth amplitude changes
+
+> g_02 =
+>     let n = lfNoise0 'a' KR 0.5
+>     in sinOsc AR (220 + (lag n 1 * 220)) 0 * (lag n 2 * 0.1)
diff --git a/Help/UGen/lag2.help.lhs b/Help/UGen/lag2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lag2.help.lhs
@@ -0,0 +1,8 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Lag2"
+    Sound.SC3.UGen.DB.ugenSummary "Lag2"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let x = mouseX KR 220 440 Exponential 0.1
+>     in sinOsc AR (mce [x, lag2 x 1]) 0 * 0.1
diff --git a/Help/UGen/lag3.help.lhs b/Help/UGen/lag3.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lag3.help.lhs
@@ -0,0 +1,8 @@
+     Sound.SC3.UGen.Help.viewSC3Help "Lag3"
+    Sound.SC3.UGen.DB.ugenSummary "Lag3"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let x = mouseX KR 220 440 Exponential 0.1
+>     in sinOsc AR (mce [x, lag3 x 1]) 0 * 0.1
diff --git a/Help/UGen/lagIn.help.lhs b/Help/UGen/lagIn.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lagIn.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LagIn"
+    > Sound.SC3.UGen.DB.ugenSummary "LagIn"
+
+> import Sound.SC3 {- hsc3 -}
+
+Set frequency at control bus
+
+    > withSC3 (send (c_set1 10 200))
+
+Oscillator reading frequency at control bus
+
+> g_01 = sinOsc AR (lagIn 1 10 1) 0 * 0.1
+
+Re-set frequency at control bus
+
+    > withSC3 (send (c_set1 10 2000))
diff --git a/Help/UGen/lagUD.help.lhs b/Help/UGen/lagUD.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lagUD.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LagUD"
+    Sound.SC3.UGen.DB.ugenSummary "LagUD"
+
+> import Sound.SC3 {- hsc3 -}
+
+lag pitch, slower down (5 seconds) than up (1 second)
+
+> g_01 =
+>     let x = mouseX KR 220 440 Linear 0.2
+>     in sinOsc AR (mce2 x (lagUD x 1 5)) 0 * 0.1
diff --git a/Help/UGen/lastValue.help.lhs b/Help/UGen/lastValue.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lastValue.help.lhs
@@ -0,0 +1,12 @@
+> Sound.SC3.UGen.Help.viewSC3Help "LastValue"
+> Sound.SC3.UGen.DB.ugenSummary "LastValue"
+
+> import Sound.SC3
+
+> let x = mouseX KR 100 400 Linear 0.1
+> in audition (out 0 (sinOsc AR (lastValue x 40) 0 * 0.1))
+
+Difference between currrent and the last changed
+> 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/latch.help.lhs b/Help/UGen/latch.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/latch.help.lhs
@@ -0,0 +1,26 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Latch"
+    Sound.SC3.UGen.DB.ugenSummary "Latch"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>   let n = whiteNoise 'α' AR
+>       i = impulse AR 9 0
+>       l = latch n i
+>   in blip AR (l * 400 + 500) 4 * 0.2
+
+The above is just meant as example. LFNoise0 is a faster way to
+generate random steps :
+
+> g_02 =
+>   let n = lfNoise0 'α' KR 9
+>   in blip AR (n * 400 + 500) 4 * 0.2
+
+http://create.ucsb.edu/pipermail/sc-users/2006-December/029991.html
+
+> g_03 =
+>   let n0 = lfNoise2 'α' KR 8
+>       n1 = lfNoise2 'β' KR 3
+>       s = blip AR (n0 * 200 + 300) (n1 * 10 + 20)
+>       x = mouseX KR 1000 (sampleRate * 0.1) Exponential 0.1
+>   in latch s (impulse AR x 0)
diff --git a/Help/UGen/latoocarfianC.help.lhs b/Help/UGen/latoocarfianC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/latoocarfianC.help.lhs
@@ -0,0 +1,20 @@
+> Sound.SC3.UGen.Help.viewSC3Help "LatoocarfianC"
+> Sound.SC3.UGen.DB.ugenSummary "LatoocarfianC"
+
+> import Sound.SC3
+
+SC3 default initial parameters.
+
+> let x = mouseX KR 20 sampleRate Linear 0.1
+> in audition (out 0 (latoocarfianC AR x 1 3 0.5 0.5 0.5 0.5 * 0.2))
+
+Randomly modulate all parameters.
+
+> let {[n0,n1,n2,n3] = map (\e -> lfNoise2 e KR 5) "abcd"
+>     ;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
+>     ;o = latoocarfianC AR f a b c d 0.5 0.5 * 0.2}
+> in audition (out 0 o)
diff --git a/Help/UGen/leakDC.help.lhs b/Help/UGen/leakDC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/leakDC.help.lhs
@@ -0,0 +1,8 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LeakDC"
+    > Sound.SC3.UGen.DB.ugenSummary "LeakDC"
+
+> import Sound.SC3
+
+> g_01 =
+>     let a = lfPulse AR 800 0 0.5 * 0.1 + 0.5
+>     in mce [a,leakDC a 0.995]
diff --git a/Help/UGen/lfBrownNoise2.help.lhs b/Help/UGen/lfBrownNoise2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfBrownNoise2.help.lhs
@@ -0,0 +1,17 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LFBrownNoise2"
+    > Sound.SC3.UGen.DB.ugenSummary "LFBrownNoise2"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins as E {- hsc3 -}
+
+Modulate frequency.
+
+> g_01 =
+>     let x = mouseX KR 0 5 Linear 0.2
+>     in E.lfBrownNoise2 'α' AR 1000 1 x * 0.25
+
+Use as frequency control.
+
+> g_02 =
+>     let f = E.lfBrownNoise2 'α' KR 8 0.2 0 * 400 + 450
+>     in sinOsc AR f 0 * 0.2
diff --git a/Help/UGen/lfClipNoise.help.lhs b/Help/UGen/lfClipNoise.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfClipNoise.help.lhs
@@ -0,0 +1,25 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LFClipNoise"
+    Sound.SC3.UGen.DB.ugenSummary "LFClipNoise"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = lfClipNoise 'α' AR 1000 * 0.05
+
+Modulate frequency
+
+> g_02 =
+>     let f = xLine KR 1000 10000 10 RemoveSynth
+>     in lfClipNoise 'α' AR f * 0.05
+
+Use as frequency control
+
+> g_03 =
+>     let n = lfClipNoise 'α' KR 4
+>     in sinOsc AR (n * 200 + 600) 0 * 0.1
+
+Drawings
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen1 0.1 (lfClipNoise 'α' AR 1000)
+
+![](sw/hsc3/Help/SVG/lfClipNoise.0.svg)
diff --git a/Help/UGen/lfCub.help.lhs b/Help/UGen/lfCub.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfCub.help.lhs
@@ -0,0 +1,39 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LFCub"
+    > Sound.SC3.UGen.DB.ugenSummary "LFCub"
+
+> import Sound.SC3
+
+> g_01 = lfCub AR (lfCub KR (lfCub KR 0.2 0 * 8 + 10) 0 * 400 + 800) 0 * 0.1
+> g_02 = lfCub AR (lfCub KR 0.2 0 * 400 + 800) 0 * 0.1
+> g_03 = lfCub AR 800 0 * 0.1
+> g_04 = lfCub AR (xLine KR 100 8000 30 DoNothing) 0 * 0.1
+
+Compare w/ lfPar
+
+> g_05 = lfPar AR (lfPar KR (lfPar KR 0.2 0 * 8 + 10) 0 * 400 + 800) 0 * 0.1
+> g_06 = lfPar AR (lfPar KR 0.2 0 * 400 + 800) 0 * 0.1
+> g_07 = lfPar AR 800 0 * 0.1
+> g_08 = lfPar AR (xLine KR 100 8000 30 DoNothing) 0 * 0.1
+
+Compare w/ sinOsc
+
+> g_09 = sinOsc AR (sinOsc KR (sinOsc KR 0.2 0 * 8 + 10) 0 * 400 + 800) 0 * 0.1
+> g_11 = sinOsc AR (sinOsc KR 0.2 0 * 400 + 800) 0 * 0.1
+> g_12 = sinOsc AR 800 0 * 0.1
+> g_13 = sinOsc AR (xLine KR 100 8000 30 DoNothing) 0 * 0.1
+
+Compare w/ lfTri
+
+> g_14 = lfTri AR (lfTri KR (lfTri KR 0.2 0 * 8 + 10) 0 * 400 + 800) 0 * 0.1
+> g_15 = lfTri AR (lfTri KR 0.2 0 * 400 + 800) 0 * 0.1
+> g_16 = lfTri AR 800 0 * 0.1
+> g_17 = lfTri AR (xLine KR 100 8000 30 DoNothing) 0 * 0.1
+
+Drawings
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen 0.1 (mce2 (sinOsc AR 20 0) (lfCub AR 20 0))
+    > plot_ugen 0.1 (mce2 (sinOsc AR 20 0) (lfPar AR 20 pi))
+
+![](sw/hsc3/Help/SVG/lfCub.0.svg)
+![](sw/hsc3/Help/SVG/lfCub.1.svg)
diff --git a/Help/UGen/lfGauss.help.lhs b/Help/UGen/lfGauss.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfGauss.help.lhs
@@ -0,0 +1,111 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LFGauss"
+    Sound.SC3.UGen.DB.ugenSummary "LFGauss"
+
+> import Sound.SC3 {- hsc3 -}
+
+modulating duration
+
+> g_01 =
+>     let d = xLine KR 0.1 0.001 10 DoNothing
+>     in lfGauss AR d 0.03 0 Loop DoNothing * 0.2
+
+modulating width, freq 60 Hz
+
+> g_02 =
+>     let w = xLine KR 0.1 0.001 10 DoNothing
+>     in lfGauss AR (1/60) w 0 Loop DoNothing * 0.2
+
+modulating both: x position is frequency, y is width factor.
+note the artefacts due to alisasing at high frequencies
+
+> g_03 =
+>     let d = mouseX KR (1/8000) 0.1 Exponential 0.2
+>         w = mouseY KR 0.001 0.1 Exponential 0.2
+>     in lfGauss AR d w 0 Loop DoNothing * 0.1
+
+LFGauss as amplitude modulator
+
+> g_04 =
+>     let d = mouseX KR 1 0.001 Exponential 0.2
+>         g = lfGauss AR d 0.1 0 Loop DoNothing
+>         o = sinOsc AR 1000 0
+>     in g * o * 0.1
+
+modulate iphase
+
+> g_05 =
+>     let ph = mouseX KR (-1) 1 Linear 0.2
+>         g = lfGauss AR 0.001 0.2 (mce2 0 ph) Loop DoNothing
+>     in mix g * 0.2
+
+for very small width we are "approaching" a dirac function
+
+> g_06 =
+>     let w = sampleDur * mouseX KR 10 3000 Exponential 0.2
+>     in lfGauss AR 0.01 w 0 Loop DoNothing * 0.2
+
+dur and width can be modulated at audio rate
+
+> g_07 =
+>     let x = mouseX KR 2 1000 Exponential 0.2
+>         d = range 0.0006 0.01 (sinOsc AR x 0 * mce2 1 1.1)
+>         w = range 0.01 0.3 (sinOsc AR (0.5 * (mce2 1 1.1)) 0)
+>     in lfGauss AR d w 0 Loop DoNothing * 0.2
+
+several frequencies and widths combined
+
+> g_08 =
+>     let x = mouseX KR 1 0.07 Exponential 0.2
+>         y = mouseY KR 1 3 Linear 0.2
+>         g = lfGauss AR x (y ** mce [-1,-2 .. -6]) 0 Loop DoNothing
+>         o = sinOsc AR (200 * (1.3 ** mce [0..5])) 0
+>     in mix (g * o) * 0.1
+
+    > withSC3 (send (n_trace [-1]))
+
+Drawing
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > let plot_f tm du ph = plot_ugen1 tm (lfGauss AR du 0.12 ph Loop DoNothing)
+    > plot_f 0.1 0.1 0
+    > plot_f 0.1 0.1 (-1) -- shifting left
+    > plot_f 0.1 0.1 2 -- moving further away from the center
+    > plot_f 0.3 0.065 0 -- several grains
+
+![](sw/hsc3/Help/SVG/lfGauss.0.svg)
+![](sw/hsc3/Help/SVG/lfGauss.1.svg)
+![](sw/hsc3/Help/SVG/lfGauss.2.svg)
+![](sw/hsc3/Help/SVG/lfGauss.3.svg)
+
+gabor grain (see also 'gabor_grain_ugen_graph')
+
+> gabor =
+>     let b = control IR "out" 0
+>         f = control IR "freq" 440
+>         s = control IR "sustain" 1
+>         p = control IR "pan" 0
+>         a = control IR "amp" 0.1
+>         w = control IR "width" 0.25
+>         e = lfGauss AR s w 0 NoLoop RemoveSynth
+>         o = fSinOsc AR f (pi / 2) * e
+>         u = offsetOut b (pan2 o p a)
+>     in synthdef "gabor" u
+
+    > import Sound.SC3.Lang.Pattern {- hsc3-lang -}
+
+granular synthesis, modulating duration, width and pan
+
+    > paudition (pbind [(K_instr,psynth gabor)
+    >                  ,(K_freq,1000)
+    >                  ,(K_legato,2)
+    >                  ,(K_dur,pbrown 'α' 0.005 0.025 0.001 inf)
+    >                  ,(K_param "width",pbrown 'β' 0.05 0.25 0.005 inf)
+    >                  ,(K_param "pan",pbrown 'γ' (-1) 1 0.05 inf)])
+
+granular synthesis, modulating width only
+
+    > paudition (pbind [(K_instr,psynth gabor)
+    >                  ,(K_freq,1000)
+    >                  ,(K_dur,0.01)
+    >                  ,(K_param "width",pgeom 0.25 0.995 1250)
+    >                  ,(K_legato,2)])
diff --git a/Help/UGen/lfNoise0.help.lhs b/Help/UGen/lfNoise0.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfNoise0.help.lhs
@@ -0,0 +1,29 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LFNoise0"
+    Sound.SC3.UGen.DB.ugenSummary "LFNoise0"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = lfNoise0 'α' AR 1000 * 0.05
+
+Modulate frequency.
+
+> g_02 =
+>     let f = xLine KR 1000 10000 10 RemoveSynth
+>     in lfNoise0 'α' AR f * 0.05
+
+Use as frequency control.
+
+> g_03 =
+>     let f = lfNoise0 'α' KR 4
+>     in sinOsc AR (f * 400 + 450) 0 * 0.1
+
+Drawing
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.1 (lfNoise0 'γ' AR 1000)
+    > plot_ugen1 0.1 (lfNoise1 'γ' AR 1000)
+    > plot_ugen1 0.1 (lfNoise2 'γ' AR 1000)
+
+![](sw/hsc3/Help/SVG/lfNoise0.0.svg)
+![](sw/hsc3/Help/SVG/lfNoise0.1.svg)
+![](sw/hsc3/Help/SVG/lfNoise0.2.svg)
diff --git a/Help/UGen/lfNoise1.help.lhs b/Help/UGen/lfNoise1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfNoise1.help.lhs
@@ -0,0 +1,18 @@
+> Sound.SC3.UGen.Help.viewSC3Help "LFNoise1"
+> Sound.SC3.UGen.DB.ugenSummary "LFNoise1"
+
+> import Sound.SC3
+
+> audition (out 0 (lfNoise1 'α' AR 1000 * 0.05))
+
+Modulate frequency.
+
+> let {f = xLine KR 1000 10000 10 RemoveSynth
+>     ;n = lfNoise1 'α' AR f}
+> in audition (out 0 (n * 0.05))
+
+Use as frequency control.
+
+> let {n = lfNoise1 'α' KR 4
+>     ;f = n * 400 + 450}
+> in audition (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/lfNoise2.help.lhs b/Help/UGen/lfNoise2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfNoise2.help.lhs
@@ -0,0 +1,25 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LFNoise2"
+    Sound.SC3.UGen.DB.ugenSummary "LFNoise2"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = lfNoise2 'α' AR 1000 * 0.05
+
+Modulate frequency.
+
+> g_02 =
+>     let f = xLine KR 1000 10000 10 RemoveSynth
+>     in lfNoise2 'α' AR f * 0.05
+
+Use as frequency control.
+
+> g_03 =
+>     let f = lfNoise2 'α' KR 4
+>     in sinOsc AR (f * 400 + 450) 0 * 0.1
+
+Drawings
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.1 (lfNoise2 'α' AR 1000)
+
+![](sw/hsc3/Help/SVG/lfNoise2.0.svg)
diff --git a/Help/UGen/lfPar.help.lhs b/Help/UGen/lfPar.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfPar.help.lhs
@@ -0,0 +1,4 @@
+> Sound.SC3.UGen.Help.viewSC3Help "LFPar"
+> Sound.SC3.UGen.DB.ugenSummary "LFPar"
+
+See lfCub
diff --git a/Help/UGen/lfPulse.help.lhs b/Help/UGen/lfPulse.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfPulse.help.lhs
@@ -0,0 +1,32 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LFPulse"
+    Sound.SC3.UGen.DB.ugenSummary "LFPulse"
+
+Note: SC2 had no initial phase argument.
+
+> import Sound.SC3
+>
+> g_01 = let f = lfPulse KR 3 0 0.3 * 200 + 200 in lfPulse AR f 0 0.2 * 0.1
+>
+> g_02 = let x = mouseX KR 0 1 Linear 0.2 in lfPulse AR 220 0 x * 0.1
+
+square wave as sum of sines.
+for odd partials n, amplitude is (1 / n), for even partials amplitude is 0.
+phase is always 0.
+
+> g_03 =
+>     let mk_freq f0 n = f0 * fromInteger n
+>         mk_amp n = if even n then 0 else 1 / fromInteger n
+>         mk_param f0 n = let m = [1,3 .. n] in zip (map (mk_freq f0) m) (map mk_amp m)
+>         x = midiCPS (mouseX KR 20 72 Linear 0.2)
+>         y = mouseY KR 0.01 0.1 Exponential 0.2
+>         e = xLine KR 0.01 1 20 DoNothing
+>         o1 = sum (map (\(fr,am) -> sinOsc AR fr 0 * am) (mk_param x 50)) * (1 - e)
+>         o2 = lfPulse AR x 0 0.5 * e
+>     in mce2 o1 o2 * y
+
+Drawings
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.1 (lfPulse AR (line KR 100 800 0.1 DoNothing) 0 0.5)
+
+![](sw/hsc3/Help/SVG/lfPulse.0.svg)
diff --git a/Help/UGen/lfSaw.help.lhs b/Help/UGen/lfSaw.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfSaw.help.lhs
@@ -0,0 +1,44 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LFSaw"
+    > Sound.SC3.UGen.DB.ugenSummary "LFSaw"
+
+Note: SC2 did not have the initial phase argument.
+
+> import Sound.SC3
+
+> g_01 = lfSaw AR 500 1 * 0.1
+
+Used as both Oscillator and LFO.
+
+> g_02 = lfSaw AR (lfSaw KR 4 0 * 400 + 400) 0 * 0.1
+
+Output range is bi-polar.
+
+> g_03 =
+>     let f = mce [linLin (lfSaw KR 0.5 0) (-1) 1 200 1600, 200, 1600]
+>         a = mce [0.1,0.05,0.05]
+>     in mix (sinOsc AR f 0 * a)
+
+saw-tooth wave as sum of sines.
+for all partials n, amplitude is (1 / n).
+phase is always 0.
+cross-fade from sum to lfSaw.
+
+> g_04 =
+>     let mk_freq f0 n = f0 * fromInteger n
+>         mk_amp n = 1 / fromInteger n
+>         mk_param f0 n = let m = [1,2 .. n] in zip (map (mk_freq f0) m) (map mk_amp m)
+>         x = midiCPS (mouseX KR 20 72 Linear 0.2)
+>         y = mouseY KR 0.01 0.1 Exponential 0.2
+>         e = xLine KR 0.01 1 20 DoNothing
+>         o1 = sum (map (\(fr,am) -> sinOsc AR fr 0 * am) (mk_param x 25)) * (1 - e)
+>         o2 = lfSaw AR x 0 * e
+>     in mce2 o1 o2 * y
+
+Drawings
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.1 (lfSaw AR 50 0) -- ascending
+    > plot_ugen1 0.002 (lfSaw AR 5000 0)
+
+![](sw/hsc3/Help/SVG/lfSaw.0.svg)
+![](sw/hsc3/Help/SVG/lfSaw.1.svg)
diff --git a/Help/UGen/lfTri.help.lhs b/Help/UGen/lfTri.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfTri.help.lhs
@@ -0,0 +1,32 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LFTri"
+    Sound.SC3.UGen.DB.ugenSummary "LFTri"
+
+see <http://thread.gmane.org/gmane.comp.audio.supercollider.user/84719>
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = lfTri AR 500 1 * 0.1
+
+Used as both Oscillator and LFO.
+
+> g_02 = lfTri AR (lfTri KR 4 0 * 400 + 400) 0 * 0.1
+
+Multiple phases
+
+> g_03 = let f = lfTri KR 0.4 (mce [0..3]) * 200 + 400
+>        in mix (lfTri AR f 0 * 0.1)
+>
+> g_04 = let x = midiCPS (mouseX KR 20 72 Linear 0.2)
+>            e = xLine KR 0.01 1 20 DoNothing
+>            o1 = triAS 25 x * (1 - e)
+>            o2 = lfTri AR x 0 * e
+>        in mce2 o1 o2 * 0.1
+
+Drawings
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.1 (lfTri AR 40 0)
+    > plot_ugen1 0.1 (lfTri AR (xLine KR 1 800 0.1 DoNothing) 0)
+
+![](sw/hsc3/Help/SVG/lfTri.0.svg)
+![](sw/hsc3/Help/SVG/lfTri.1.svg)
diff --git a/Help/UGen/lfdClipNoise.help.lhs b/Help/UGen/lfdClipNoise.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfdClipNoise.help.lhs
@@ -0,0 +1,22 @@
+> Sound.SC3.UGen.Help.viewSC3Help "LFDClipNoise"
+> Sound.SC3.UGen.DB.ugenSummary "LFDClipNoise"
+
+> import Sound.SC3
+
+for fast x lfClipNoise frequently seems stuck, lfdClipNoise changes smoothly
+
+> let {x = mouseX KR 0.1 1000 Exponential 0.2
+>     ;n = lfdClipNoise 'α' AR x}
+> in 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}
+> in 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
+> in audition . (out 0) . (* 0.05) =<< lfdClipNoiseM AR f
+
+> let f = xLine KR 1000 20000 10 RemoveSynth
+> in audition . (out 0) . (* 0.05) =<< lfClipNoiseM AR f
diff --git a/Help/UGen/lfdNoise0.help.lhs b/Help/UGen/lfdNoise0.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfdNoise0.help.lhs
@@ -0,0 +1,33 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LFDNoise0"
+    Sound.SC3.UGen.DB.ugenSummary "LFDNoise0"
+
+> import Sound.SC3 {- hsc3 -}
+
+for fast x LFNoise frequently seems stuck, LFDNoise changes smoothly
+
+> g_01 = lfdNoise0 'a' AR (mouseX KR 0.1 1000 Exponential 0.2) * 0.1
+>
+> g_02 = lfNoise0 'a' AR (mouseX KR 0.1 1000 Exponential 0.2) * 0.1
+
+silent for 2 secs before going up in freq
+
+> g_03 = lfdNoise0 'a' AR (xLine KR 0.5 10000 3 RemoveSynth)
+>
+> g_04 = lfNoise0 'a' AR (xLine KR 0.5 10000 3 RemoveSynth)
+
+LFNoise quantizes time steps at high freqs, LFDNoise does not:
+
+> g_05 = lfdNoise0 'a' AR (xLine KR 1000 20000 10 RemoveSynth)
+>
+> g_06 = lfNoise0 'a' AR (xLine KR 1000 20000 10 RemoveSynth)
+
+Drawings
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen1 0.1 (lfdNoise0 'γ' AR 1000)
+    plot_ugen1 0.1 (lfdNoise1 'γ' AR 1000)
+    plot_ugen1 0.1 (lfdNoise3 'γ' AR 1000)
+
+![](sw/hsc3/Help/SVG/lfdNoise0.0.svg)
+![](sw/hsc3/Help/SVG/lfdNoise0.1.svg)
+![](sw/hsc3/Help/SVG/lfdNoise0.2.svg)
diff --git a/Help/UGen/lfdNoise1.help.lhs b/Help/UGen/lfdNoise1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfdNoise1.help.lhs
@@ -0,0 +1,4 @@
+> Sound.SC3.UGen.Help.viewSC3Help "LFDNoise1"
+> Sound.SC3.UGen.DB.ugenSummary "LFDNoise1"
+
+See lfdNoise0
diff --git a/Help/UGen/lfdNoise3.help.lhs b/Help/UGen/lfdNoise3.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfdNoise3.help.lhs
@@ -0,0 +1,13 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LFDNoise3"
+    > Sound.SC3.UGen.DB.ugenSummary "LFDNoise3"
+
+See lfdNoise0
+
+Drawings
+
+    > import Sound.SC3 {- hsc3 -}
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.1 (lfdNoise3 'α' AR (xLine AR 1000 100 0.1 DoNothing))
+
+![](sw/hsc3/Help/SVG/lfdNoise3.0.svg)
+
diff --git a/Help/UGen/limiter.help.lhs b/Help/UGen/limiter.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/limiter.help.lhs
@@ -0,0 +1,14 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Limiter"
+> Sound.SC3.UGen.DB.ugenSummary "Limiter"
+
+> import Sound.SC3
+
+example signal
+> let z = let i = impulse AR 8 0 * lfSaw KR 0.25 0 * (-0.6) + 0.7
+>         in decay2 i 0.001 0.3 * fSinOsc AR 500 0
+
+unprocessed
+> audition (out 0 z)
+
+limited
+> audition (out 0 (limiter z 0.4 0.01))
diff --git a/Help/UGen/linCongC.help.lhs b/Help/UGen/linCongC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/linCongC.help.lhs
@@ -0,0 +1,18 @@
+> Sound.SC3.UGen.Help.viewSC3Help "LinCongC"
+> Sound.SC3.UGen.DB.ugenSummary "LinCongC"
+
+> import Sound.SC3
+
+Default SC3 initial parameters.
+
+> let x = mouseX KR 20 sampleRate Linear 0.1
+> in audition (out 0 (linCongC AR x 1.1 0.13 1 0 * 0.2))
+
+Randomly modulate parameters.
+
+> let {fr = [1,0.1,0.1,0.1]
+>     ;[n0,n1,n2,m] = map (\(i,j) -> lfNoise2 i KR j) (zip "abde" fr)
+>     ;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/linCongL.help.lhs b/Help/UGen/linCongL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/linCongL.help.lhs
@@ -0,0 +1,1 @@
+See linCongC
diff --git a/Help/UGen/linCongN.help.lhs b/Help/UGen/linCongN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/linCongN.help.lhs
@@ -0,0 +1,1 @@
+See linCongC
diff --git a/Help/UGen/linExp.help.lhs b/Help/UGen/linExp.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/linExp.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LinExp"
+    > Sound.SC3.UGen.DB.ugenSummary "LinExp"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let f = linExp (mouseX KR 0 1 Linear 0.2) 0 1 440 660
+>     in sinOsc AR f 0 * 0.1
+
+The destination range may be k-rate.
+
+> g_02 =
+>     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 sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/linLin.help.lhs b/Help/UGen/linLin.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/linLin.help.lhs
@@ -0,0 +1,27 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LinLin"
+    Sound.SC3.UGen.DB.ugenSummary "LinLin"
+
+> import Sound.SC3 {- hsc3 -}
+
+linLin is a function for writing a MulAdd UGen.
+
+> g_01 =
+>     let f = linLin (mouseX KR 0 1 Linear 0.2) 0 1 440 660
+>     in sinOsc AR f 0 * 0.1
+
+The destination range may be k-rate.
+
+> g_02 =
+>     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 sinOsc AR f 0 * 0.1
+
+Modulating source and destination values.
+
+> g_03 =
+>     let n = lfNoise2 'α' AR 80
+>         x = mouseX KR 200 8000 Linear 0.2
+>         y = mouseY KR 200 8000 Linear 0.2
+>         f = linLin n (sinOsc KR 0.2 0) (sinOsc KR 0.2543 0) x y
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/linPan2.help.lhs b/Help/UGen/linPan2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/linPan2.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LinPan2"
+    > Sound.SC3.UGen.DB.ugenSummary "LinPan2"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = pinkNoise 'α' AR
+>     in linPan2 n (fSinOsc KR 2 0) 0.1
+>
+> g_02 = linPan2 (fSinOsc AR 800 0) (fSinOsc KR 3 0) 0.1
diff --git a/Help/UGen/linRand.help.lhs b/Help/UGen/linRand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/linRand.help.lhs
@@ -0,0 +1,8 @@
+> Sound.SC3.UGen.Help.viewSC3Help "LinRand"
+> Sound.SC3.UGen.DB.ugenSummary "LinRand"
+
+> import Sound.SC3
+
+> let {f = linRand 'α' 200.0 10000.0 (mce [-1, 1])
+>     ;e = line KR 0.4 0 0.01 RemoveSynth}
+> in audition (out 0 (fSinOsc AR f 0 * e))
diff --git a/Help/UGen/linXFade2.help.lhs b/Help/UGen/linXFade2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/linXFade2.help.lhs
@@ -0,0 +1,15 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LinXFade2"
+    > Sound.SC3.UGen.DB.ugenSummary "LinXFade2"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = linXFade2 (saw AR 440) (sinOsc AR 440 0) (lfTri KR 0.1 0) 0.1
+>
+> gen_cmp ty = ty (fSinOsc AR 800 0 * 0.2)
+>                 (pinkNoise 'α' AR * 0.2)
+>                 (fSinOsc KR 0.5 0)
+>                 1.0
+>
+> g_03 = gen_cmp linXFade2
+>
+> g_04 = gen_cmp xFade2
diff --git a/Help/UGen/line.help.lhs b/Help/UGen/line.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/line.help.lhs
@@ -0,0 +1,16 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Line"
+    Sound.SC3.UGen.DB.ugenSummary "Line"
+
+Note: SC3 reorders the mul and add inputs to precede the doneAction input.
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = let f = line KR 200 17000 5 RemoveSynth in sinOsc AR f 0 * 0.1
+
+Demonstrate RemoveGroup done-action.
+
+    > withSC3 (send (g_new [(10,AddToTail,1)]))
+
+> g_02 =
+>    let f = line KR 200 (mce2 209 211) 5 RemoveGroup
+>    in audition_at (-1,AddToTail,10,[]) (out 0 (sinOsc AR f 0 * 0.1))
diff --git a/Help/UGen/linen.help.lhs b/Help/UGen/linen.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/linen.help.lhs
@@ -0,0 +1,14 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Linen"
+    Sound.SC3.UGen.DB.ugenSummary "Linen"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let e = linen (impulse KR 2 0) 0.01 0.6 0.4 DoNothing
+>     in e * sinOsc AR 440 0 * 0.1
+>
+> g_02 =
+>     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 sinOsc AR 440 0 * e
diff --git a/Help/UGen/localBuf.help.lhs b/Help/UGen/localBuf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/localBuf.help.lhs
@@ -0,0 +1,79 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LocalBuf"
+    Sound.SC3.UGen.DB.ugenSummary "LocalBuf"
+
+> import Sound.SC3
+
+Allocate a buffer local to the synthesis graph.
+
+> g_01 =
+>     let n = whiteNoise 'α' AR
+>         b = localBuf 'β' 2048 1
+>         f = fft' b n
+>         c = pv_BrickWall f (sinOsc KR 0.1 0 * 0.75)
+>     in ifft' c * 0.1
+
+Variant with two local buffers
+
+> g_02 =
+>     let n = uclone 'α' 2 (whiteNoise 'β' AR)
+>         b = uclone 'γ' 2 (localBuf 'δ' 2048 1)
+>         f = fft' b n
+>         c = pv_BrickWall f (sinOsc KR (mce2 0.1 0.11) 0 * 0.75)
+>     in ifft' c * 0.1
+
+Not clearing the buffer accesses old data, slowly overwrite data with noise
+
+> g_03 =
+>     let b = localBuf 'α' 2048 2
+>         nf = bufFrames KR b
+>         x = mouseX KR 1 2 Linear 0.2
+>         r = playBuf 2 AR b x 1 0 Loop DoNothing * 0.1
+>         wr p i = bufWr b (linLin p (-1) 1 0 nf) Loop i
+>         n = uclone 'β' 2 (whiteNoise 'γ' AR)
+>         ph = lfNoise0 'δ' AR 530
+>     in mrg2 r (wr ph n)
+
+bufCombC needs no clearing, because the delay line is filled by the ugen
+
+> g_04 =
+>     let d = uclone 'α' 2 (dust 'β' AR 1)
+>         n = whiteNoise 'γ' AR
+>         z = decay d 0.3 * n
+>         l = xLine KR 0.0001 0.01 20 DoNothing
+>         sr = sampleRate
+>         b = uclone 'δ' 2 (localBuf 'ε' sr 2)
+>     in bufCombC b z l 0.2
+
+asLocalBuf combines localBuf and setBuf
+
+> g_05 =
+>     let b = asLocalBuf 'α' [2,1,5,3,4,0]
+>         x = mouseX KR 0 (bufFrames KR b) Linear 0.2
+>         f = indexL KR b x * 100 + 40
+>     in saw AR (f * mce2 1 1.1) * 0.1
+
+detectIndex example using local buffer
+
+> g_06 =
+>     let b = asLocalBuf 'α' [2,3,4,0,1,5]
+>         n = bufFrames KR b
+>         x = floorE (mouseX KR 0 n Linear 0.1)
+>         i = detectIndex b x
+>     in sinOsc AR (linExp i 0 n 200 700) 0 * 0.1
+
+degreeToKey example ('modal space') using local buffer
+
+> g_07 =
+>     let n = lfNoise1 'α' KR (mce [3,3.05])
+>         x = mouseX KR 0 15 Linear 0.1
+>         b = asLocalBuf 'β' [0,2,3.2,5,7,9,10]
+>         k = degreeToKey b x 12
+>         mk_c bf = let f0 = midiCPS (bf + k + n * 0.04)
+>                       o = sinOsc AR f0 0 * 0.1
+>                       f1 = midiCPS (mce [48,55])
+>                       t = lfPulse AR f1 0.15 0.5
+>                       f2 = midiCPS (sinOsc KR 0.1 0 * 10 + bf)
+>                       d = rlpf t f2 0.1 * 0.1
+>                       m = o + d
+>                   in combN m 0.31 0.31 2 + m
+>     in (mk_c 48 + mk_c 72) * 0.25
diff --git a/Help/UGen/localIn.help.lhs b/Help/UGen/localIn.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/localIn.help.lhs
@@ -0,0 +1,39 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LocalIn"
+    > Sound.SC3.UGen.DB.ugenSummary "LocalIn"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> noise_signal =
+>     let e = decay (impulse AR 0.3 0) 0.1
+>     in whiteNoise 'α' AR * e * 0.2
+>
+> outside_world = soundIn 4
+>
+> ping_pong z =
+>     let a1 = localIn 2 AR 0 + mce [z,0]
+>         a2 = delayN a1 0.2 0.2
+>         a3 = mceEdit reverse a2 * 0.8
+>     in mrg [z + a2,localOut a3]
+>
+> g_01 = ping_pong noise_signal
+> g_02 = ping_pong outside_world
+>
+> rotate2_mce z p =
+>     case mceChannels z of
+>       [l,r] -> rotate2 l r p
+>       _ -> error "rotate2_mce"
+>
+> tape_delay dt fb z =
+>     let a = amplitude KR (mix z) 0.01 0.01
+>         z' = z * (a >* 0.02)
+>         l0 = localIn 2 AR 0
+>         l1 = onePole l0 0.4
+>         l2 = onePole l1 (-0.08)
+>         l3 = rotate2_mce l2 0.2
+>         l4 = delayN l3 dt dt
+>         l5 = leakDC l4 0.995
+>         l6 = softClip ((l5 + z') * fb)
+>     in mrg2 (l6 * 0.1) (localOut l6)
+>
+> g_03 = tape_delay 0.35 1.20 noise_signal
+> g_04 = tape_delay 0.25 1.25 outside_world
diff --git a/Help/UGen/localOut.help.lhs b/Help/UGen/localOut.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/localOut.help.lhs
@@ -0,0 +1,25 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LocalOut"
+    > Sound.SC3.UGen.DB.ugenSummary "LocalOut"
+
+> import Sound.SC3 {- hsc3 -}
+
+Resonator, must subtract blockSize for correct tuning
+
+> g_01 =
+>     let p = localIn 1 AR 0
+>         i = impulse AR 1 0
+>         d = delayC (i + (p * 0.995)) 1 (recip 440 - recip controlRate)
+>     in mrg [offsetOut 0 p,localOut d]
+
+Compare with oscillator.
+
+> g_02 = sinOsc AR 440 0 * 0.2
+
+ping pong
+
+> g_03 =
+>     let n = decay (impulse AR 0.3 0) 0.1 * whiteNoise 'α' AR * 0.2
+>         l = localIn 2 AR 0 + mce2 n 0
+>         d = delayN l 0.2 0.2
+>         o = localOut (mceReverse d * 0.8)
+>     in mrg2 d o
diff --git a/Help/UGen/logistic.help.lhs b/Help/UGen/logistic.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/logistic.help.lhs
@@ -0,0 +1,15 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Logistic"
+> Sound.SC3.UGen.DB.ugenSummary "Logistic"
+
+> import Sound.SC3
+
+SC3 default parameters
+> audition (out 0 (logistic AR 3 1000 0.5))
+
+Onset of chaos
+> audition (out 0 (logistic AR (line KR 3.55 3.6 5 DoNothing) 1000 0.01))
+
+Mouse control
+> let {x = mouseX KR 3 3.99 Linear 0.1
+>     ;y = mouseY KR 10 10000 Exponential 0.1}
+> in audition (out 0 (logistic AR x y 0.25 * 0.5))
diff --git a/Help/UGen/loopBuf.help.lhs b/Help/UGen/loopBuf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/loopBuf.help.lhs
@@ -0,0 +1,55 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LoopBuf"
+    Sound.SC3.UGen.DB.ugenSummary "LoopBuf"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins as E {- hsc3 -}
+
+Read audio file into memory
+
+> ld b = do
+>   let fn = "/home/rohan/opt/src/supercollider/sounds/a11wlk01.wav"
+>   withSC3 (async (b_allocRead b fn 0 0))
+
+Simple sampler instrument
+
+> lb0 =
+>     let ou = control KR "out" 0
+>         bf = control KR "bufnum" 0
+>         rt = control KR "rate" 1
+>         gl = control KR "glide" 0
+>         gt = control KR "gate" 1
+>         lr = control KR "loopRel" 0
+>         sp = control KR "startPos" 0
+>         sl = control KR "startLoop" 0
+>         el = control KR "endLoop" 0
+>         ip = control KR "ipol" 2
+>         rt' = lag rt gl * bufRateScale KR bf
+>         e = let d = envADSR 0.1 0.2 1 2 1 (EnvNum (-4)) 0
+>             in envGen AR gt 1 0 1 RemoveSynth d
+>         s = E.loopBuf 1 AR bf rt' (gt + lr) sp sl el ip
+>     in out ou (s * e)
+
+> lb0s :: Synthdef
+> lb0s = synthdef "lb0" lb0
+
+    ld 0
+    withSC3 (async (d_recv lb0s))
+
+    import Sound.OSC {- hosc -}
+    let send = sendMessage
+    withSC3 (send (s_new "lb0" 3000 AddToTail 1 [("bufnum",0),("startLoop",5000),("endLoop",15000)]))
+
+    withSC3 (send (n_set1 3000 "rate" (-1))) -- backwards
+    withSC3 (send (n_set1 3000 "rate" 1)) -- forwards
+    withSC3 (send (n_set 3000 [("startLoop",11000),("endLoop",13000)])) -- change loop points
+    withSC3 (send (n_set1 3000 "glide" 5)) -- 5 second glide
+    withSC3 (send (n_set1 3000 "rate" 2)) -- up an octave
+    withSC3 (send (n_set1 3000 "rate" (-1))) -- backwards
+    withSC3 (send (n_set1 3000 "rate" 1)) -- back to normal
+    withSC3 (send (n_set1 3000 "ipol" 1)) -- no interpolation
+    withSC3 (send (n_set1 3000 "ipol" 2)) -- linear interpolation
+    withSC3 (send (n_set1 3000 "ipol" 4)) -- cubic interpolation
+    withSC3 (send (n_set1 3000 "gate" 0)) -- release gate to hear post-loop
+
+    withSC3 (send (s_new "lb0" 3000 AddToTail 1 [("bufnum",0),("startLoop",5000),("endLoop",15000)]))
+    withSC3 (send (n_set 3000 [("loopRel",1),("gate",0)])) -- release instrument without post-loop
diff --git a/Help/UGen/lorenzL.help.lhs b/Help/UGen/lorenzL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lorenzL.help.lhs
@@ -0,0 +1,31 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LorenzL"
+    Sound.SC3.UGen.DB.ugenSummary "LorenzL"
+
+> import Sound.SC3 {- hsc3 -}
+
+Vary frequency
+
+> g_01 =
+>     let x = mouseX KR 20 sampleRate Linear 0.1
+>     in lorenzL AR x 10 27 2.667 0.05 0.1 0 0 * 0.3
+
+Randomly modulate params
+
+> g_02 =
+>     let n e = lfNoise0 e KR 0.5
+>         n0 = mul_add (n 'α') 2 10
+>         n1 = mul_add (n 'β') 20 38
+>         n2 = mul_add (n 'γ') 1.5 2
+>     in lorenzL AR sampleRate n0 n1 n2 0.05 0.1 0 0 * 0.2
+
+As frequency control
+
+> g_03 =
+>     let x = mouseX KR 1 200 Linear 0.1
+>         n = lorenzL AR x 10 28 2.667 0.05 0.1 0 0
+>     in sinOsc AR (lag n 0.003 * 800 + 900) 0 * 0.4
+
+> g_04 =
+>     let x = mouseX KR 1 200 Linear 0.1
+>         n = lorenzL AR x 10 28 2.667 0.05 0.1 0 0
+>     in impulse AR (n * 4 + 8) 0 * 0.4
diff --git a/Help/UGen/loudness.help.lhs b/Help/UGen/loudness.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/loudness.help.lhs
@@ -0,0 +1,15 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Loudness"
+    Sound.SC3.UGen.DB.ugenSummary "Loudness"
+
+> import Sound.SC3 {- hsc3 -}
+
+Assume hop of half fftsize
+
+    > withSC3 (async (b_alloc 10 1024 1))
+
+> g_01 =
+>     let x = mouseX KR 0.001 0.1 Exponential 0.2
+>         i = sinOsc AR 1000 0 * x
+>         f = fft' 10 i
+>         l = loudness f 0.25 6
+>     in sinOsc AR (mce2 900 (l * 300 + 600)) 0 * 0.1
diff --git a/Help/UGen/lpcSynth.help.lhs b/Help/UGen/lpcSynth.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lpcSynth.help.lhs
@@ -0,0 +1,29 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LPCSynth"
+    Sound.SC3.UGen.DB.ugenSummary "LPCSynth"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Data.LPC {- hsc3-data -}
+
+> lpc_instr b n lpc =
+>     let x = mouseX KR 0.05 1.5 Linear 0.2
+>         y = mouseY KR 0.25 2.0 Linear 0.2
+>         f = x / constant (lpcAnalysisDuration (lpcHeader lpc))
+>         ptr = lfSaw AR f 1 * 0.5 + 0.5
+>         [cps, rms, err] = mceChannels (lpcVals AR b ptr)
+>         nh = floorE (22000 / cps)
+>         voc = blip AR (cps * y) nh * (1 - err)
+>         s = lpcSynth b (voc + (n * err * 20)) ptr
+>     in s * 1e-5 * rms
+
+> fn_01 = "/home/rohan/cvs/tn/tn-56/lpc/fate.lpc"
+
+> au_01 lpc = do
+>   let d = map realToFrac (lpcSC3 lpc)
+>   _ <- async (b_alloc 10 (length d) 1)
+>   mapM_ send (b_setn1_segmented 512 10 0 d)
+>   let s = lpc_instr 10 (pinkNoise 'α' AR) lpc
+>   play (out 0 s)
+
+    lpc <- lpcRead fn_01
+    withSC3 (au_01 lpc)
diff --git a/Help/UGen/lpcVals.help.lhs b/Help/UGen/lpcVals.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lpcVals.help.lhs
@@ -0,0 +1,1 @@
+See lpcSynth
diff --git a/Help/UGen/lpf.help.lhs b/Help/UGen/lpf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lpf.help.lhs
@@ -0,0 +1,15 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LPF"
+    > Sound.SC3.UGen.DB.ugenSummary "LPF"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let f = xLine KR 0.7 300 20 RemoveSynth
+>         ff = fSinOsc KR f 0 * 3600 + 4000
+>     in lpf (saw AR 200 * 0.1) ff
+
+Control rate filtering.
+
+> g_02 =
+>     let ctl = lpf (lfPulse KR 8 0 0.5) (mouseX KR 2 50 Exponential 0.1)
+>     in sinOsc AR (ctl * 200 + 400) 0 * 0.1
diff --git a/Help/UGen/lpz1.help.lhs b/Help/UGen/lpz1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lpz1.help.lhs
@@ -0,0 +1,7 @@
+> Sound.SC3.UGen.Help.viewSC3Help "LPZ1"
+> Sound.SC3.UGen.DB.ugenSummary "LPZ1"
+
+> import Sound.SC3
+
+> let n = whiteNoise 'α' AR * 0.1
+> in audition (out 0 (mce2 n (lpz1 n)))
diff --git a/Help/UGen/lpz2.help.lhs b/Help/UGen/lpz2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lpz2.help.lhs
@@ -0,0 +1,7 @@
+> Sound.SC3.UGen.Help.viewSC3Help "LPZ2"
+> Sound.SC3.UGen.DB.ugenSummary "LPZ2"
+
+> import Sound.SC3
+
+> let n = whiteNoise 'α' AR
+> in audition (out 0 (lpz2 (n * 0.25)))
diff --git a/Help/UGen/lti.help.lhs b/Help/UGen/lti.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lti.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LTI"
+    Sound.SC3.UGen.DB.ugenSummary "LTI"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> gr_01 =
+>     let a = [0.02,-0.01]
+>         b = [1,0.7,0,0,0,0,-0.8,0,0,0,0,0.9,0,0,0,-0.5,0,0,0,0,0,0,0.25,0.1,0.25]
+>         z = pinkNoise 'α' AR * 0.1 {- soundIn 4 -}
+>     in lti AR z (asLocalBuf 'β' a) (asLocalBuf 'γ' b)
diff --git a/Help/UGen/mantissaMask.help.lhs b/Help/UGen/mantissaMask.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mantissaMask.help.lhs
@@ -0,0 +1,7 @@
+> Sound.SC3.UGen.Help.viewSC3Help "MantissaMask"
+> Sound.SC3.UGen.DB.ugenSummary "MantissaMask"
+
+> import Sound.SC3
+
+> let s = sinOsc AR (sinOsc KR 0.2 0 * 400 + 500) 0 * 0.4
+> in audition (out 0 (mantissaMask s 3))
diff --git a/Help/UGen/max.help.lhs b/Help/UGen/max.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/max.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.max"
+    > :t max
+
+> import Sound.SC3 {- hsc3 -}
+
+q modulates and envelopes p
+
+> g_01 =
+>     let p = fSinOsc AR 500 0 * 0.25
+>         q = fSinOsc AR 0.5 0
+>     in p `max` q
diff --git a/Help/UGen/median.help.lhs b/Help/UGen/median.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/median.help.lhs
@@ -0,0 +1,26 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Median"
+> Sound.SC3.UGen.DB.ugenSummary "Median"
+
+> import Sound.SC3
+
+Signal with impulse noise.
+
+> let n = dust2 'α' AR 100
+> in audition (out 0 (median 3 (saw AR 500 * 0.1 + n * 0.9)))
+
+The median length can be increased for longer duration noise.
+
+> let n = dust2 'α' AR 100
+> in 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
+> 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.
+
+> let {n = whiteNoise 'α' AR
+>     ;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/membraneCircle.help.lhs b/Help/UGen/membraneCircle.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/membraneCircle.help.lhs
@@ -0,0 +1,20 @@
+> Sound.SC3.UGen.Help.viewSC3Help "MembraneCircle"
+> Sound.SC3.UGen.DB.ugenSummary "MembraneCircle"
+
+> import Sound.SC3
+
+Excite the mesh with some pink noise, triggered by an
+impulse generator.  mouseX is tension and impulse frequency,
+mouseY is duration of excitation, release-time and amplitude.
+
+> let {x = mouseX KR 0 1 Linear 0.2
+>     ;y = mouseY KR 1e-9 1 Exponential 0.2
+>     ;loss = linLin y 0 1 0.999999 0.999
+>     ;wobble = sinOsc KR 2 0
+>     ;tension = linLin x 0 1 0.01 0.1 + (wobble * 0.0001)
+>     ;p = envPerc 0.0001 y
+>     ;tr = impulse KR (linLin x 0 1 3 9) 0
+>     ;e = envGen KR tr (linLin y 0 1 0.05 0.25) 0 0.1 DoNothing p
+>     ;m = membraneCircle
+>     ;n = pinkNoise 'α' AR}
+> in audition (out (mce2 0 1) (m (n * e) tension loss))
diff --git a/Help/UGen/membraneHexagon.help.lhs b/Help/UGen/membraneHexagon.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/membraneHexagon.help.lhs
@@ -0,0 +1,1 @@
+See membraneCircle
diff --git a/Help/UGen/metro.help.lhs b/Help/UGen/metro.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/metro.help.lhs
@@ -0,0 +1,16 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Metro"
+> Sound.SC3.UGen.DB.ugenSummary "Metro"
+
+> import Sound.SC3
+
+> audition (out 0 (metro AR 60 1))
+
+> let {b = xLine KR 60 120 5 DoNothing
+>     ;m = metro KR b 1
+>     ;o = sinOsc AR 440 0 * 0.1}
+> in audition (out 0 (decay m 0.2 * o))
+
+> let {b = range 30 240 (lfNoise2 'α' KR 0.2)
+>     ;n = dseq 'β' dinf (mce [1,0.25,0.5,0.25])
+>     ;a = decay (metro KR b n) 0.2 * sinOsc AR 440 0 * 0.1}
+> in audition (out 0 a)
diff --git a/Help/UGen/midEQ.help.lhs b/Help/UGen/midEQ.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/midEQ.help.lhs
@@ -0,0 +1,13 @@
+    Sound.SC3.UGen.Help.viewSC3Help "MidEQ"
+    Sound.SC3.UGen.DB.ugenSummary "MidEQ"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let f = midiCPS (fSinOsc KR 1 0 * 24 + 84)
+>     in midEQ (saw AR 200 * 0.2) f 0.3 12
+
+> g_02 =
+>     let i = pinkNoise 'α' AR * 0.2 + sinOsc AR 600 0 * 0.1
+>         f = sinOsc KR 0.2 (0.5 * pi) * 2 + 600
+>     in midEQ i f 0.01 (-24)
diff --git a/Help/UGen/mod.help.lhs b/Help/UGen/mod.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mod.help.lhs
@@ -0,0 +1,6 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.%"
+    > :t modE
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = fSinOsc AR 100 4 `modE` 1 * 0.1
diff --git a/Help/UGen/moogFF.help.lhs b/Help/UGen/moogFF.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/moogFF.help.lhs
@@ -0,0 +1,26 @@
+    Sound.SC3.UGen.Help.viewSC3Help "MoogFF"
+    Sound.SC3.UGen.DB.ugenSummary "MoogFF"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let n = whiteNoise 'α' AR
+>         y = mouseY KR 100 10000 Exponential 0.1
+>         x = mouseX KR 0 4 Linear 0.1
+>     in moogFF (n * 0.1) y x 0
+
+Note distortion at high gain.
+
+> g_02 =
+>     let x = mouseX KR 100 20000 Exponential 0.1
+>         y = mouseY KR 0.1 4.0 Linear 0.1
+>         i = mix (saw AR (mce [0.99, 1, 1.01] * 440)) * 0.3
+>     in moogFF i x y 0
+
+> g_03 =
+>     let n = lfNoise0 'α' KR 0.43
+>         p = pulse AR (mce [40, 121]) (mce [0.3, 0.7])
+>         f0 = linLin n 0 1 0.001 2.2
+>         f = linLin (sinOsc KR f0 0) (-1) 1 30 4200
+>         y = mouseY KR 1 4 Linear 0.1
+>     in moogFF p f (0.83 * y) 0
diff --git a/Help/UGen/mostChange.help.lhs b/Help/UGen/mostChange.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mostChange.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "MostChange"
+    > Sound.SC3.UGen.DB.ugenSummary "MostChange"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = lfNoise0 'α' KR 1
+>         x = mouseX KR 200 300 Linear 0.1
+>         f = mostChange (n * 400 + 900) x
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/mouseButton.help.lhs b/Help/UGen/mouseButton.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mouseButton.help.lhs
@@ -0,0 +1,12 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "MouseButton"
+    > Sound.SC3.UGen.DB.ugenSummary "MouseButton"
+
+> import Sound.SC3 {- hsc3 -}
+
+As amplitude envelope
+
+> g_01 = sinOsc AR 800 0 * mouseButton KR 0 0.1 0.1
+
+There is a variant that randomly presses the button.
+
+> g_02 = sinOsc AR 800 0 * mouseButton' KR 0 0.1 0.1
diff --git a/Help/UGen/mouseX.help.lhs b/Help/UGen/mouseX.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mouseX.help.lhs
@@ -0,0 +1,20 @@
+    Sound.SC3.UGen.Help.viewSC3Help "MouseX"
+    Sound.SC3.UGen.DB.ugenSummary "MouseX"
+
+> import Sound.SC3
+
+> e_01 = map from_warp [Linear,Exponential]
+
+    e_01 == [0,1]
+
+Frequency control
+
+> g_01 =
+>     let x = mouseX KR 40 10000 Exponential 0.2
+>     in sinOsc AR x 0 * 0.1
+
+There is a variant with equal arguments but random traversal.
+
+> g_02 =
+>     let x = mouseX' KR 40 10000 Exponential 0.2
+>     in sinOsc AR x 0 * 0.1
diff --git a/Help/UGen/mouseY.help.lhs b/Help/UGen/mouseY.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mouseY.help.lhs
@@ -0,0 +1,18 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "MouseY"
+    > Sound.SC3.UGen.DB.ugenSummary "MouseY"
+
+> import Sound.SC3 {- hsc3 -}
+
+Frequency at X axis and amplitude at Y axis.
+
+> g_01 =
+>     let freq = mouseX KR 20 2000 Exponential 0.1
+>         ampl = mouseY KR 0.01 0.1 Linear 0.1
+>     in sinOsc AR freq 0 * ampl
+
+There is a variant with equal arguments but a random traversal.
+
+> g_02 =
+>     let freq = mouseX' KR 20 2000 Exponential 0.1
+>         ampl = mouseY' KR 0.01 0.1 Linear 0.1
+>     in sinOsc AR freq 0 * ampl
diff --git a/Help/UGen/mrg2.help.lhs b/Help/UGen/mrg2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mrg2.help.lhs
@@ -0,0 +1,24 @@
+> :t mrg2
+
+> import Sound.SC3
+
+mrg2 defines a node indicating a multiple root graph.
+> let {l = out 0 (sinOsc AR 300 0 * 0.1)
+>     ;r = out 1 (sinOsc AR 900 0 * 0.1)}
+> in audition (mrg2 l r)
+
+there is a leftmost rule, so that mrg nodes need not
+be terminal.
+> let {l = sinOsc AR 300 0 * 0.1
+>     ;r = out 1 (sinOsc AR 900 0 * 0.1)}
+> in audition (out 0 (mrg2 l r))
+
+the leftmost node may be an mce node
+> let {l = sinOsc AR (mce2 300 400) 0 * 0.1
+>     ;r = out 1 (sinOsc AR 900 0 * 0.1)}
+> in audition (out 0 (mrg2 l r))
+
+the implementation is not thorough
+> let {l = sinOsc AR (mce2 300 400) 0 * 0.1
+>     ;r = out 1 (sinOsc AR 900 0 * 0.1)}
+> in audition (out 0 (mrg2 l r + mrg2 l r))
diff --git a/Help/UGen/mul.help.lhs b/Help/UGen/mul.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mul.help.lhs
@@ -0,0 +1,17 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.*"
+    > :t (*)
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = sinOsc AR 440 0 * 0.15
+
+Creates a beating effect (subaudio rate).
+
+> g_02 = fSinOsc KR 10 0 * pinkNoise 'α' AR * 0.5
+
+Ring modulation.
+
+> g_03 =
+>     let p = sinOsc AR (xLine KR 100 1001 10 DoNothing) 0
+>         q = syncSaw AR 100 200
+>     in p * q * 0.25
diff --git a/Help/UGen/mzPokey.help.lhs b/Help/UGen/mzPokey.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mzPokey.help.lhs
@@ -0,0 +1,31 @@
+> Sound.SC3.UGen.Help.viewSC3Help "MZPokey"
+> Sound.SC3.UGen.DB.ugenSummary "MZPokey"
+
+> import Sound.SC3
+> import qualified Sound.SC3.Lang.Math as M
+
+> let b = fromIntegral . M.parseBits :: (String -> UGen)
+> let bln = line KR 0 255 5 RemoveSynth
+> let mz1 i j = mzPokey i j 0 0 0 0 0 0 0
+> let mz1c i j c = mzPokey i j 0 0 0 0 0 0 c
+
+> audition (out 0 (mz1 bln (b "00001111")))
+> audition (out 0 (mz1 bln (b "00101111")))
+> audition (out 0 (mz1 bln (b "10101111")))
+> audition (out 0 (mz1c bln (b "10101111") (b "00000001")))
+> audition (out 0 (mz1c bln (b "10101111") (b "01000001")))
+
+> let mz2c i j p q c = mzPokey i j p q 0 0 0 0 c
+> let bX = mouseX KR 0 255 Linear 0.1
+> let bY = mouseY KR 0 255 Linear 0.1
+
+> audition (out 0 (mz2c bX (b "10101010") bY (b "10101010") (b "00000001")))
+
+> let mz4pc (f1,c1) (f2,c2) (f3,c3) (f4,c4) c = mzPokey f1 c1 f2 c2 f3 c3 f4 c4 c
+
+> let { v1 = (bX,b "11000111")
+>     ; v2 = (bY,b "11100111")
+>     ; v3 = (sinOsc KR 0.4 0 * 127.5 + 127.5,b "11000111")
+>     ; v4 = (sinOsc KR 0.5 0 * 127.5 + 127.5,b "01000111")
+>     ; m = mz4pc v1 v2 v3 v4 (b "00000000") }
+> in audition (out 0 (mce2 m m))
diff --git a/Help/UGen/nRand.help.lhs b/Help/UGen/nRand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/nRand.help.lhs
@@ -0,0 +1,8 @@
+> Sound.SC3.UGen.Help.viewSC3Help "NRand"
+> Sound.SC3.UGen.DB.ugenSummary "NRand"
+
+> import Sound.SC3
+
+> let {n = nRand 'α' 1200.0 4000.0 (mce [2,5])
+>     ;e = line KR 0.2 0 0.1 RemoveSynth}
+> in audition (out 0 (fSinOsc AR n 0 * e))
diff --git a/Help/UGen/normalizer.help.lhs b/Help/UGen/normalizer.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/normalizer.help.lhs
@@ -0,0 +1,9 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Normalizer"
+> Sound.SC3.UGen.DB.ugenSummary "Normalizer"
+
+> import Sound.SC3
+
+> let {s = fSinOsc AR 500 0
+>     ;t = impulse AR 8 (lfSaw KR 0.25 (-0.6) * 0.7)
+>     ;z = decay2 t 0.001 0.3 * s}
+> in audition (out 0 (mce [z, normalizer z 0.4 0.01]))
diff --git a/Help/UGen/numAudioBuses.help.lhs b/Help/UGen/numAudioBuses.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/numAudioBuses.help.lhs
@@ -0,0 +1,3 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "NumAudioBuses"
+    > Sound.SC3.UGen.DB.ugenSummary "NumAudioBuses"
+
diff --git a/Help/UGen/numBuffers.help.lhs b/Help/UGen/numBuffers.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/numBuffers.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "NumBuffers"
+    > Sound.SC3.UGen.DB.ugenSummary "NumBuffers"
+
+> import Sound.SC3 {- hsc3 -}
+
+the number of audio buffers available at the server (by default 1024)
+
+> g_01 = poll (impulse KR 1 0) numBuffers (label "numBuffers") 0
+>
+> g_02 = let f = 110 + numBuffers in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/numControlBuses.help.lhs b/Help/UGen/numControlBuses.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/numControlBuses.help.lhs
@@ -0,0 +1,2 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "NumControlBuses"
+    > Sound.SC3.UGen.DB.ugenSummary "NumControlBuses"
diff --git a/Help/UGen/numInputBuses.help.lhs b/Help/UGen/numInputBuses.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/numInputBuses.help.lhs
@@ -0,0 +1,2 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "NumInputBuses"
+    > Sound.SC3.UGen.DB.ugenSummary "NumInputBuses"
diff --git a/Help/UGen/numOutputBuses.help.lhs b/Help/UGen/numOutputBuses.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/numOutputBuses.help.lhs
@@ -0,0 +1,2 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "NumOutputBuses"
+    > Sound.SC3.UGen.DB.ugenSummary "NumOutputBuses"
diff --git a/Help/UGen/numRunningSynths.help.lhs b/Help/UGen/numRunningSynths.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/numRunningSynths.help.lhs
@@ -0,0 +1,8 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "NumRunningSynths"
+    > Sound.SC3.UGen.DB.ugenSummary "NumRunningSynths"
+
+> import Sound.SC3 {- hsc3 -}
+
+each concurrent audition increases oscillator frequency
+
+> g_01 = sinOsc AR (numRunningSynths * 200 + 400) 0 * 0.1
diff --git a/Help/UGen/offsetOut.help.lhs b/Help/UGen/offsetOut.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/offsetOut.help.lhs
@@ -0,0 +1,69 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "OffsetOut"
+    > Sound.SC3.UGen.DB.ugenSummary "OffsetOut"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let a = offsetOut 0 (impulse AR 5 0)
+>         b = out 0 (sinOsc AR 60 0 * 0.1)
+>     in mrg [a,b]
+>
+> g_02 =
+>     let a = out 0 (impulse AR 5 0)
+>         b = out 0 (sinOsc AR 60 0 * 0.1)
+>     in mrg [a,b]
+
+Phase cancellation, the `offsetOut` at bus 0 should cancel, the `out` at
+bus 1 doesn't (or at least is exceedingly unlikely to).
+
+> sy_01 sr =
+>     let f = sr / 100
+>         o = sinOsc AR (constant f) 0 * 0.2
+>     in synthdef "sy_01" (mrg [offsetOut 0 o,out 1 o])
+>
+> bnd_01 sr t =
+>     let latency = 0.2
+>         c = 100 / sr {- recip f -}
+>         m = s_new "sy_01" (-1) AddToHead 1 []
+>         p = bundle (t + latency) [m]
+>         q = bundle (t + latency + c/2) [m]
+>     in [p,q]
+>
+> proc_01 :: Transport m => m ()
+> proc_01 = do
+>   sr <- serverSampleRateActual
+>   _ <- async (d_recv (sy_01 sr))
+>   t <- time
+>   mapM_ sendBundle (bnd_01 sr t)
+
+    > withSC3 proc_01
+
+The cancellation isn't completely reliable though.  In supercollider language it seems
+to be better, though these _should_ be equivalent...
+
+    Routine(
+    {var sr = s.actualSampleRate
+    ;var f = sr / 100
+    ;var c = 1 / f
+    ;var g = {var o = SinOsc.ar(f,0) * 0.2; OffsetOut.ar(0,o); Out.ar(1,o)}
+    ;var sy = SynthDef("g",g)
+    ;var m = ["/s_new", "g", -1, 0, 1]
+    ;var latency = 0.2
+    ;sy.send(s)
+    ;s.sync
+    ;s.sendBundle(latency,m)
+    ;s.sendBundle(latency + (c/2),m)}).play
+
+To see/hear scheduler clock and sample clock drift:
+
+    Routine(
+    {var g = {OffsetOut.ar(0,Saw.ar(400) * EnvGen.kr(Env.perc, doneAction: 2) * 0.2)}
+    ;var h = {OffsetOut.ar(1,Saw.ar(800) * Decay2.ar(Impulse.ar(1)) * 0.2)}
+    ;var t_delay = 0.25
+    ;SynthDef("g",g).send(s)
+    ;SynthDef("h",h).send(s)
+    ;s.sync
+    ;s.sendBundle(t_delay,["/s_new", "h", -1, 0, 1])
+    ;inf.do({s.sendBundle(t_delay,["/s_new", "g", -1, 0, 1]); 1.0.wait})}).play
+
diff --git a/Help/UGen/onePole.help.lhs b/Help/UGen/onePole.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/onePole.help.lhs
@@ -0,0 +1,14 @@
+> Sound.SC3.UGen.Help.viewSC3Help "OnePole"
+> Sound.SC3.UGen.DB.ugenSummary "OnePole"
+
+> import Sound.SC3
+
+> let n = whiteNoise 'α' AR
+> in audition (out 0 (onePole (n * 0.5) 0.95))
+
+> let n = whiteNoise 'α' AR
+> in audition (out 0 (onePole (n * 0.5) (-0.95)))
+
+> let {n = whiteNoise 'α' AR
+>     ;c = line KR (-0.99) 0.99 10 RemoveSynth}
+> in audition (out 0 (onePole (n * 0.5) c))
diff --git a/Help/UGen/oneZero.help.lhs b/Help/UGen/oneZero.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/oneZero.help.lhs
@@ -0,0 +1,14 @@
+> Sound.SC3.UGen.Help.viewSC3Help "OneZero"
+> Sound.SC3.UGen.DB.ugenSummary "OneZero"
+
+> import Sound.SC3
+
+> let n = whiteNoise 'α' AR
+> in audition (out 0 (oneZero (n * 0.5) 0.5))
+
+> let n = whiteNoise 'α' AR
+> in audition (out 0 (oneZero (n * 0.5) (-0.5)))
+
+> let {n = whiteNoise 'α' AR
+>     ;c = line KR (-0.5) 0.5 10 RemoveSynth}
+> in audition (out 0 (oneZero (n * 0.5) c))
diff --git a/Help/UGen/onsets.help.lhs b/Help/UGen/onsets.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/onsets.help.lhs
@@ -0,0 +1,43 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Onsets"
+    > Sound.SC3.UGen.DB.ugenSummary "Onsets"
+
+> import Sound.SC3 {- hsc3 -}
+
+    > withSC3 (async (b_alloc 10 512 1))
+
+> f_01 t = t2A t 0
+
+> f_02 t =
+>     let s = sinOsc AR 440 0 * 0.2
+>         e = envGen KR t 1 0 1 DoNothing (envPerc 0.001 0.1)
+>     in s * e
+
+> f_03 f =
+>     let x = mouseX KR 0 1 Linear 0.2
+>         i = mix (soundIn (mce2 0 1))
+>         c = fft' 10 i
+>         o = onsets' c x (onsetType "rcomplex")
+>     in f o
+
+> g_01 = f_03 f_01
+
+> g_02 = mce2 (dc AR 0) (mix (soundIn (mce2 0 1) * 0.75))
+
+a generative signal with distinct onsets!
+
+> g_03 =
+>     let e = linLin (saw AR 2) (-1) 1 0 1
+>         p = let f = midiCPS (tIRand 'α' 63 75 (impulse KR 2 0))
+>             in pulse AR f 0.5
+>         f = linExp (lfNoise2 'β' KR 0.5) (-1) 1 100 10000
+>     in lpf p f * e
+
+x varies threshold, whitenoise bursts indicate detected onsets
+
+> g_04 =
+>     let c = fft' 10 g_03
+>         x = mouseX KR 0 1 Linear 0.2
+>         o = onsets' c x (onsetType "rcomplex")
+>         p = let d = envPerc 0.001 0.1
+>             in whiteNoise 'α' AR * envGen KR o 0.2 0 1 DoNothing d
+>     in pan2 g_03 (-0.75) 0.2 + pan2 p 0.75 1
diff --git a/Help/UGen/osc.help.lhs b/Help/UGen/osc.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/osc.help.lhs
@@ -0,0 +1,48 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Osc"
+    > Sound.SC3.UGen.DB.ugenSummary "Osc"
+
+> import Sound.SC3 {- hsc3 -}
+
+Allocate and generate wavetable buffer
+
+    > withSC3 (do {_ <- async (b_alloc 10 512 1)
+    >             ;let f = [Normalise,Wavetable,Clear]
+    >              in send (b_gen_sine1 10 f [1,1/2,1/3,1/4,1/5])})
+
+Fixed frequency wavetable oscillator
+
+> g_01 = osc AR 10 220 0 * 0.1
+
+Modulate frequency
+
+> g_02 =
+>     let f = xLine KR 2000 200 1 DoNothing
+>     in osc AR 10 f 0 * 0.1
+
+As frequency modulator
+
+> g_03 =
+>     let f = osc AR 10 (xLine KR 1 1000 9 RemoveSynth) 0 * 200 + 800
+>     in osc AR 10 f 0 * 0.1
+
+As phase modulatulator
+
+> g_04 =
+>     let p = osc AR 10 (xLine KR 20 8000 10 RemoveSynth) 0 * 2 * pi
+>     in osc AR 10 800 p * 0.1
+
+Fixed frequency wavetable oscillator
+
+> g_05 = osc AR 10 220 0 * 0.1
+
+Change the wavetable while its playing
+
+    > let f = [Normalise,Wavetable,Clear]
+    > in withSC3 (send (b_gen_sine1 10 f [1,0.6,1/4]))
+
+Send directly calculated wavetable
+
+    > import Sound.SC3.Common.Buffer {- hsc3 -}
+    > import Sound.SC3.Common.Math.Window {- hsc3 -}
+    > let t = to_wavetable (triangular_table 512)
+    > withSC3 (send (b_setn1 10 0 t))
diff --git a/Help/UGen/osc1.help.lhs b/Help/UGen/osc1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/osc1.help.lhs
@@ -0,0 +1,9 @@
+> import Sound.SC3
+
+> withSC3 (let {z = [Normalise,Wavetable,Clear]
+>              ;a = [[13,8,55,34,5,21,3,1,2],[55,34,1,3,2,13,5,8,21]]
+>              ;f (b,l) = do {_ <- async (b_alloc b 512 1)
+>                            ;send (b_gen_sine1 b z (map recip l))}}
+>          in mapM_ f (zip [10,11] a))
+
+> audition (out 0 (lfSaw AR (mce2 110 164) 0 * 0.1 * osc1 AR (mce2 10 11) 4 RemoveSynth))
diff --git a/Help/UGen/oscN.help.lhs b/Help/UGen/oscN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/oscN.help.lhs
@@ -0,0 +1,4 @@
+> Sound.SC3.UGen.Help.viewSC3Help "OscN"
+> Sound.SC3.UGen.DB.ugenSummary "OscN"
+
+See osc
diff --git a/Help/UGen/out.help.lhs b/Help/UGen/out.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/out.help.lhs
@@ -0,0 +1,13 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Out"
+    > Sound.SC3.UGen.DB.ugenSummary "Out"
+
+> import Sound.SC3 {- hsc3 -}
+
+Oscillators at outputs zero (330) and one (331)
+
+> g_01 = out 0 (sinOsc AR (mce2 330 331) 0 * 0.1)
+
+`out` is summing, as opposed to `replaceOut`
+
+> g_02 = mrg [out 0 (sinOsc AR (mce2 330 990) 0 * 0.1)
+>            ,out 0 (sinOsc AR (mce2 331 991) 0 * 0.1)]
diff --git a/Help/UGen/packFFT.help.lhs b/Help/UGen/packFFT.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/packFFT.help.lhs
@@ -0,0 +1,22 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PackFFT"
+> Sound.SC3.UGen.DB.ugenSummary "PackFFT"
+
+> import Sound.SC3
+
+> withSC3 (async (b_alloc 10 512 1))
+
+> let {n = 100
+>     ;square a = a * a
+>     ;r1 = let f = expRand 'α' 0.1 1
+>           in linLin (fSinOsc KR f 0) (-1) 1 0 1
+>     ;m1 = uclone' 'β' n r1
+>     ;m2 = zipWith (*) m1 (map square [1.0, 0.99 ..])
+>     ;r2 = let r = iRand 'γ' (-3) 5
+>           in lfPulse KR (2 ** r) 0 0.3
+>     ;i = uclone' 'δ' n r2
+>     ;m3 = zipWith (*) m2 i
+>     ;p = replicate n 0.0
+>     ;c1 = fft' 10 (fSinOsc AR 440 0)
+>     ;c2 = packFFT c1 512 0 (constant n - 1) 1 (packFFTSpec m3 p)
+>     ;s = ifft' c2}
+> in audition (out 0 (mce [s,s]))
diff --git a/Help/UGen/pan2.help.lhs b/Help/UGen/pan2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pan2.help.lhs
@@ -0,0 +1,14 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Pan2"
+    > Sound.SC3.UGen.DB.ugenSummary "Pan2"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = pinkNoise 'α' AR
+>     in pan2 n (fSinOsc KR 2 0) 0.3
+>
+> g_02 =
+>     let n = pinkNoise 'α' AR
+>         x = mouseX KR (-1) 1 Linear 0.2
+>         y = mouseY KR 0 1 Linear 0.2
+>     in pan2 n x y
diff --git a/Help/UGen/panAz.help.lhs b/Help/UGen/panAz.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/panAz.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PanAz"
+    > Sound.SC3.UGen.DB.ugenSummary "PanAz"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let o = pinkNoise 'α' AR
+>         nc = 4
+>         fr = 0.15
+>     in panAz nc o (lfSaw KR fr 0) 0.1 2 0.5
diff --git a/Help/UGen/partConv.help.lhs b/Help/UGen/partConv.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/partConv.help.lhs
@@ -0,0 +1,23 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PartConv"
+> Sound.SC3.UGen.DB.ugenSummary "PartConv"
+
+> import Sound.SC3
+
+> let { fft_size = 2048
+>     ; ir_file = "/home/rohan/data/audio/reverbs/chapel.wav"
+>     ; ir_length = 62494 {- frame count of ir_file -}
+>     ; accum_size = pc_calcAccumSize fft_size ir_length
+>     ; ir_td_b = 10 {- time domain -}
+>     ; ir_fd_b = 11 {- frequency domain -}
+>     ; target_b = 12 {- source signal -}
+>     ; target_file = "/home/rohan/data/audio/pf-c5.snd"
+>     ; c = constant
+>     ; g = let { i = playBuf 1 AR (c target_b) 1 0 0 Loop DoNothing
+>               ; pc = partConv i (c fft_size) (c ir_fd_b) }
+>           in out 0 (pc * 0.1) }
+> in withSC3 (do
+>     {_ <- async (b_allocRead ir_td_b ir_file 0 ir_length)
+>     ;_ <- async (b_alloc ir_fd_b accum_size 1)
+>     ;send (pc_preparePartConv ir_fd_b ir_td_b fft_size)
+>     ;_ <- async (b_allocRead target_b target_file 0 0)
+>     ;play g })
diff --git a/Help/UGen/pause.help.lhs b/Help/UGen/pause.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pause.help.lhs
@@ -0,0 +1,20 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Pause"
+    > Sound.SC3.UGen.DB.ugenSummary "Pause"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let f = control KR "f" 440
+>         g = control KR "g" 1
+>     in mrg [sinOsc AR f 0 * 0.1,pause g 1001]
+
+    > audition_at (1001,AddToTail,1,[]) g_01
+    > audition_at (1002,AddToTail,1,[("f",880)]) g_01
+
+Request that node 1002 pause node 1001.
+
+    > withSC3 (send (n_set 1002 [("g",0)]))
+
+Restart node 1001.
+
+    > withSC3 (send (n_set 1002 [("g",1)]))
diff --git a/Help/UGen/pauseSelf.help.lhs b/Help/UGen/pauseSelf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pauseSelf.help.lhs
@@ -0,0 +1,13 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PauseSelf"
+    > Sound.SC3.UGen.DB.ugenSummary "PauseSelf"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let x = mouseX KR (-1) 1 Linear 0.1
+>         o = sinOsc AR 440 0 * 0.1
+>     in mrg [o,pauseSelf x]
+
+Run paused node (assuming no intermediate node is created).
+
+    > withSC3 (send (n_run [(-1, True)]))
diff --git a/Help/UGen/pauseSelfWhenDone.help.lhs b/Help/UGen/pauseSelfWhenDone.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pauseSelfWhenDone.help.lhs
@@ -0,0 +1,23 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PauseSelfWhenDone"
+    > Sound.SC3.UGen.DB.ugenSummary "PauseSelfWhenDone"
+
+> import Sound.SC3 {- hsc3 -}
+
+using PauseSynth done action
+
+> g_01 =
+>     let x = mouseX KR (-1) 1 Linear 0.1
+>         e = linen x 1 0.1 1 PauseSynth
+>     in sinOsc AR 440 0 * e
+
+Run paused node (assuming no intermediate node is created).
+
+    > withSC3 (send (n_run [(-1, True)]))
+
+> g_02 =
+>     let x = mouseX KR (-1) 1 Linear 0.1
+>         e = linen x 1 0.1 1 DoNothing
+>         o = sinOsc AR 440 0 * e
+>     in mrg [o,pauseSelfWhenDone e]
+
+    > withSC3 (send (n_run [(-1, True)]))
diff --git a/Help/UGen/peak.help.lhs b/Help/UGen/peak.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/peak.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Peak"
+    > Sound.SC3.UGen.DB.ugenSummary "Peak"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let t = dust 'α' AR 20
+>         r = impulse AR 0.4 0
+>         f = peak t r * 500 + 200
+>     in sinOsc AR f 0 * 0.2
diff --git a/Help/UGen/phasor.help.lhs b/Help/UGen/phasor.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/phasor.help.lhs
@@ -0,0 +1,54 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Phasor"
+    Sound.SC3.UGen.DB.ugenSummary "Phasor"
+
+> import Prelude hiding ((<*))
+> import Sound.SC3
+
+phasor controls sine frequency, end frequency matches second sine.
+
+> g_01 =
+>     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 sinOsc AR f 0 * 0.2
+
+Load sound file to buffer zero
+
+    let fn = "/home/rohan/data/audio/pf-c5.aif"
+    withSC3 (async (b_allocRead 0 fn 0 0))
+
+Phasor as phase input to bufRd
+
+> g_02 =
+>      let ph = phasor AR 0 (bufRateScale KR 0) 0 (bufFrames KR 0) 0
+>      in bufRdN 1 AR 0 ph Loop
+
+Allocate and generate (non-wavetable) buffer at index one
+(see osc for wavetable oscillator)
+
+    withSC3 (async (b_alloc 1 256 1) >> send (b_gen_sine1 1 [Normalise,Clear] [1]))
+
+Audio rate phasor oscillator as phase input to bufRd
+
+> g_03 =
+>     let b = 1
+>         f = 440
+>         fr = bufFrames KR b
+>         rt = f * (fr / sampleRate)
+>         ph = phasor AR b (rt * bufRateScale KR b) 0 fr 0
+>     in bufRdL 1 AR b ph Loop * 0.1
+
+Phasor as impulse with reset
+
+> g_04 =
+>     let impulse_reset freq reset =
+>             let ph = phasor AR reset (freq / sampleRate) 0 1 0
+>             in hpz1 ph <* 0
+>         x = mouseX KR 0 1 Linear 0.2 >* 0.5
+>         ck = impulse AR 3 0
+>         im = impulse_reset 3 x
+>         x' = sinOsc AR 440 0 * x * 0.05
+>         im' = sinOsc AR 220 0 * decay2 (ck + im) 0.01 0.5 * 0.1
+>     in mce2 x' im'
diff --git a/Help/UGen/pinkNoise.help.lhs b/Help/UGen/pinkNoise.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pinkNoise.help.lhs
@@ -0,0 +1,29 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PinkNoise"
+    > Sound.SC3.UGen.DB.ugenSummary "PinkNoise"
+
+> import Sound.SC3 {- hsc3 -}
+
+    audition . (out 0) . (* 0.05) =<< pinkNoiseM AR
+    audition . (out 0) . (* 0.05) =<< whiteNoiseM AR
+    audition . (out 0) . (* 0.05) =<< brownNoiseM AR
+
+speaker balance
+
+> g_01 = let n = pinkNoise 'α' AR * 0.05 in mce2 n n
+>
+> g_02 =
+>     let x = mouseX KR 0 1 Linear 0.2
+>         x' = 1 - x
+>         n = pinkNoise 'α' AR * 0.05
+>     in mce2 (n * x') (n * x)
+
+Drawing
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen1 0.1 (pinkNoise 'α' AR)
+
+    import Sound.SC3.Plot.FFT {- hsc3-plot -}
+    plot_ugen_fft1 0.1 (pinkNoise 'α' AR)
+
+![](sw/hsc3/Help/SVG/pinkNoise.0.svg)
+![](sw/hsc3/Help/SVG/pinkNoise.1.svg)
diff --git a/Help/UGen/pitch.help.lhs b/Help/UGen/pitch.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pitch.help.lhs
@@ -0,0 +1,31 @@
+     Sound.SC3.UGen.Help.viewSC3Help "Pitch"
+     Sound.SC3.UGen.DB.ugenSummary "Pitch"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     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 0
+>     in mce [s, sinOsc AR (mceChannel 0 f / 2) 0 * a]
+
+> g_02 =
+>     let s = soundIn 4
+>         a = amplitude KR s 0.1 0.1
+>         f = pitch s 440 60 4000 100 16 7 0.02 0.5 1 0
+>     in mce [s, sinOsc AR (mceChannel 0 f) 0 * a]
+
+Comparison of input frequency (x) and tracked oscillator frequency (f).
+Output is printed to the console by scsynth.
+
+> g_03 =
+>     let x = mouseX KR 440 880 Exponential 0.1
+>         o = sinOsc AR x 0 * 0.1
+>         [f,_] = mceChannels (pitch o 440 60 4000 100 16 7 0.02 0.5 1 0)
+>         r = sinOsc AR f 0 * 0.1
+>         t = impulse KR 4 0
+>         pf = poll t f (label "f") 0
+>         px = poll t x (label "x") 0
+>     in mce [out 0 (mce2 o r),pf,px]
diff --git a/Help/UGen/pitchShift.help.lhs b/Help/UGen/pitchShift.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pitchShift.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PitchShift"
+    > Sound.SC3.UGen.DB.ugenSummary "PitchShift"
+
+> import Sound.SC3 {- hsc3 -}
+
+> gr_01 =
+>     let s = sinOsc AR 440 0 * 0.1
+>         r = mouseX KR 0.5 2.0 Linear 0.1
+>         d = mouseY KR 0.0 0.1 Linear 0.1
+>     in pitchShift s 0.2 r d 0
+
+> gr_02 =
+>     let s = soundIn 0
+>         pd = mouseX KR 0.0 0.1 Linear 0.1
+>         td = mouseY KR 0.0 0.1 Linear 0.1
+>     in pitchShift s 0.2 (mce2 1.0 1.5) pd td
diff --git a/Help/UGen/playBuf.help.lhs b/Help/UGen/playBuf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/playBuf.help.lhs
@@ -0,0 +1,86 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PlayBuf"
+    > Sound.SC3.UGen.DB.ugenSummary "PlayBuf"
+
+> import Sound.SC3 {- hsc3 -}
+
+Load sound file to buffer zero (single channel file required for examples)
+
+> fn = "/home/rohan/data/audio/pf-c5.aif"
+
+    withSC3 (async (b_allocRead 0 fn 0 0))
+
+Play once only.
+
+> gr_01 = playBuf 1 AR 0 (bufRateScale KR 0) 1 0 NoLoop RemoveSynth
+
+Play in infinite loop.
+
+> gr_02 = playBuf 1 AR 0 (bufRateScale KR 0) 1 0 Loop DoNothing
+
+Trigger playback at each pulse.
+
+> gr_03 =
+>     let t = impulse KR 2 0
+>         s = bufRateScale KR 0
+>     in playBuf 1 AR 0 s t 0 NoLoop DoNothing
+
+Trigger playback at each pulse (diminishing intervals).
+
+> gr_04 =
+>     let f = xLine KR 0.1 100 10 RemoveSynth
+>         t = impulse KR f 0
+>         s = bufRateScale KR 0
+>     in playBuf 1 AR 0 s t 0 NoLoop DoNothing
+
+Loop playback, accelerating pitch.
+
+> gr_05 =
+>     let r = xLine KR 0.1 100 60 RemoveSynth
+>     in playBuf 1 AR 0 r 1 0 Loop DoNothing
+
+Sine wave control of playback rate, negative rate plays backwards.
+
+> gr_06 =
+>     let f = xLine KR 0.2 8 30 RemoveSynth
+>         r = fSinOsc KR f 0 * 3 + 0.6
+>         s = bufRateScale KR 0 * r
+>     in playBuf 1 AR 0 s 1 0 Loop DoNothing
+
+Channel mismatch, single channel buffer, two channel playBuf, result
+is single channel playback and channel mismatch message in server log.
+
+> gr_07 = playBuf 2 AR 0 (bufRateScale KR 0) 1 0 Loop DoNothing
+
+Graph will play both channels after loading a two channel signal to
+buffer.
+
+> fn' = "/home/rohan/data/audio/sp/tinguely.aif"
+
+    withSC3 (async (b_allocRead 0 fn' 0 0))
+
+Release buffer.
+
+    withSC3 (send (b_free 0))
+
+Scan sequence of buffers:
+
+> gr_08 =
+>     let n = 29 * 6
+>         b = mouseX KR 0 n Linear 0.2
+>         r = bufRateScale KR b
+>     in playBuf 1 AR b r 1 0 Loop DoNothing
+
+In sclanguage:
+
+{var fn = "/home/rohan/data/audio/pf-c5.aif"
+;s.sendMsg("/b_allocRead",0,fn,0,0)}.value
+
+{var sc = BufRateScale.kr(0)
+;Out.ar(0,PlayBuf.ar(2,0,sc,1,0,1,0))}.play
+
+{var fn = "/home/rohan/data/audio/sp/tinguely.aif"
+;s.sendMsg("/b_allocRead",0,fn,0,0)}.value
+
+{var b = MouseX.kr(32,64,0,0.2)
+;var r = BufRateScale.kr(b)
+;Out.ar(0,PlayBuf.ar(1,b,r,1,0,1,0))}.play
diff --git a/Help/UGen/playBufCF.help.lhs b/Help/UGen/playBufCF.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/playBufCF.help.lhs
@@ -0,0 +1,31 @@
+wslib: external/composite
+
+> import Sound.SC3 {- hsc3 -}
+
+Load sound file to buffer zero (single channel file required for examples)
+
+> fn_01 = "/home/rohan/data/audio/pf-c5.aif"
+> fn_02 = "/home/rohan/opt/src/supercollider/sounds/a11wlk01.wav"
+
+    > withSC3 (async (b_allocRead 0 fn_02 0 0))
+
+control-rate trigger and start-position inputs
+
+> g_01 =
+>     let b = 0
+>         r = bufRateScale KR b
+>         tr = impulse KR 2 0
+>         wn = whiteNoise 'α' KR
+>         sp = linLin wn (-1) 1 0 (bufFrames KR b - (0.5 * 44100))
+>         o = playBufCF 1 b r tr sp NoLoop 0.1 2
+>         o' = playBuf 1 AR b r tr sp NoLoop DoNothing
+>     in mce2 o o'
+
+demand ugens inputs
+
+> g_02 =
+>     let b = 0
+>         r = drand 'α' dinf (mce [0.95,1,1.05])
+>         tr = dwhite 'β' dinf 0.1 0.3
+>         sp = dbrown 'γ' dinf 0 0.95 0.1 * bufFrames KR b
+>     in playBufCF 1 b r tr sp NoLoop 2 5
diff --git a/Help/UGen/pluck.help.lhs b/Help/UGen/pluck.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pluck.help.lhs
@@ -0,0 +1,29 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Pluck"
+    Sound.SC3.UGen.DB.ugenSummary "Pluck"
+
+> import Sound.SC3 {- hsc3 -}
+
+Excitation signal is white noise, triggered twice a second with varying OnePole coef.
+
+> g_01 =
+>     let n = whiteNoise 'α' AR
+>         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 pluck (n * 0.25) t dl (dl * y) 10 x
+
+> g_02 =
+>     let n = 50
+>         udup = uclone 'α'
+>         f = udup n (rand 'β' 0.05 0.2)
+>         p = udup n (rand 'γ' 0 1)
+>         w = udup n (whiteNoise 'δ' AR)
+>         fi = udup n (rand 'ε' 10 12)
+>         coef = rand 'ζ' 0.01 0.2
+>         l = udup n (rand 'η' (-1) 1)
+>         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 leakDC (mix (pan2 ks l 1)) 0.995
diff --git a/Help/UGen/pmOsc.help.lhs b/Help/UGen/pmOsc.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pmOsc.help.lhs
@@ -0,0 +1,25 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PMOsc"
+    :t pmOsc
+
+pmOsc is a composite of sinOsc, ie. sinOsc r cf (sinOsc r mf mp * pm)
+
+> import Sound.SC3
+
+Random parameters, linear modulation index motion over n seconds
+
+> pmi n =
+>     let cf = rand 'α' 0 2000
+>         mf = rand 'β' 0 800
+>         pme = rand 'γ' 0 12
+>         l = rand 'δ' (-1) 1
+>         pm = line KR 0 pme n DoNothing
+>     in linPan2 (pmOsc AR cf mf pm 0) l 0.05
+
+> g_01 = pmi 2
+
+PM textures
+
+    > import qualified Sound.SC3.Lang.Control.OverlapTexture as L
+    > L.overlapTextureU (0,1,8,maxBound) (pmi 1)
+    > L.overlapTextureU (1,2,7,maxBound) (pmi 2)
+    > L.overlapTextureU (6,6,6,maxBound) (pmi 12)
diff --git a/Help/UGen/poll.help.lhs b/Help/UGen/poll.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/poll.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Poll"
+    > Sound.SC3.UGen.DB.ugenSummary "Poll"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let t = impulse KR 10 0
+>         l = line KR 0 1 1 RemoveSynth
+>     in poll t l (label "polling...") 0
+
+multichannel expansion (requires labels be equal length...)
+
+> g_02 =
+>     let t = impulse KR (mce2 10 5) 0
+>         l = line KR 0 (mce2 1 5) (mce2 1 2) DoNothing
+>     in poll t l (mce2 (label "t1") (label "t2")) 0
diff --git a/Help/UGen/pow.help.lhs b/Help/UGen/pow.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pow.help.lhs
@@ -0,0 +1,20 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.**"
+    > :t (**)
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let a = fSinOsc AR 100 0 * 0.1
+>     in mce2 a (a ** 10)
+
+see also <http://create.ucsb.edu/pipermail/sc-users/2006-December/029998.html>
+
+> g_02 =
+>     let n0 = lfNoise2 'α' KR 8
+>         n1 = lfNoise2 'β' KR 3
+>         s = blip AR (n0 * 200 + 300) (n1 * 10 + 20)
+>         x = mouseX KR 1000 (sampleRate * 0.5) Exponential 0.1
+>         y = mouseY KR 1 24 Exponential 0.1
+>         d = latch s (impulse AR x 0)
+>         b = roundUp d (0.5 ** y)
+>     in mce2 d b
diff --git a/Help/UGen/pulse.help.lhs b/Help/UGen/pulse.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pulse.help.lhs
@@ -0,0 +1,23 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Pulse"
+    > Sound.SC3.UGen.DB.ugenSummary "Pulse"
+
+> import Sound.SC3 {- hsc3 -}
+
+Modulate frequency
+
+> g_01 =
+>     let f = xLine KR 40 4000 6 RemoveSynth
+>     in pulse AR f 0.1 * 0.1
+
+Modulate pulse width
+
+> g_02 =
+>     let w = line KR 0.01 0.99 8 RemoveSynth
+>     in pulse AR 200 w * 0.1
+
+Two band limited square waves through a resonant low pass filter
+
+> g_03 =
+>     let p = pulse AR (mce2 100 250) 0.5 * 0.1
+>         f = xLine KR 8000 400 5 DoNothing
+>     in rlpf p f 0.05
diff --git a/Help/UGen/pulseCount.help.lhs b/Help/UGen/pulseCount.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pulseCount.help.lhs
@@ -0,0 +1,15 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PulseCount"
+> Sound.SC3.UGen.DB.ugenSummary "PulseCount"
+
+> import Sound.SC3 {- hsc3 -}
+
+> let c = pulseCount (impulse AR 10 0) (impulse AR 0.4 0)
+> in audition (out 0 (sinOsc AR (c * 200) 0 * 0.05))
+
+printer
+
+> let {b = localBuf 'α' 11 1
+>     ;t = impulse AR 10 0
+>     ;p = pulseCount t 0
+>     ;d = demand t 0 (dbufwr 'α' (-666) b p NoLoop)}
+> in audition (mrg [out 0 (dc AR 0),poll t p (label "p") 0])
diff --git a/Help/UGen/pulseDivider.help.lhs b/Help/UGen/pulseDivider.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pulseDivider.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PulseDivider"
+    > Sound.SC3.UGen.DB.ugenSummary "PulseDivider"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     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 a + b * 0.4
diff --git a/Help/UGen/pv_BinDelay.help.lhs b/Help/UGen/pv_BinDelay.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_BinDelay.help.lhs
@@ -0,0 +1,61 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PV_BinDelay"
+    > Sound.SC3.UGen.DB.ugenSummary "PV_BinDelay"
+
+> import Sound.SC3 {- hsc3 -}
+
+function to allocate buffers (fft,delay,feedback)
+
+> mk_buf sz = do
+>   _ <- async (b_alloc 10 (sz * 2) 1)
+>   _ <- async (b_alloc 11 sz 1)
+>   async (b_alloc 12 sz 1)
+
+allocate buffers (number of bins)
+
+    withSC3 (mk_buf 128)
+
+function to generate bindelay filter
+
+> mk_del z =
+>     let maxdel = 0.5
+>         c1 = fft 10 z 0.25 0 1 0
+>         c2 = pv_BinDelay c1 maxdel 11 12 0.25
+>     in z + ifft c2 0 0
+
+start filter
+
+> gr_01 = mk_del (soundIn 0)
+
+set delay times (unary)
+
+    withSC3 (send (b_fill 11 [(0,128,0.25)]))
+
+set feedback gain
+
+    withSC3 (send (b_fill 12 [(0,128,0.75)]))
+
+function to generate sin table of n places in range (l,r)
+
+> gen_sin l r n ph =
+>     let f x = range l r (sin ((x / n) * 2 * pi + ph))
+>     in map f [0..n]
+
+set delay times (sin)
+
+    withSC3 (send (b_setn1 11 0 (gen_sin 0 0.35 128 0)))
+
+set feedback gain (sin)
+
+    withSC3 (send (b_setn1 12 0 (gen_sin 0.75 0.95 128 pi)))
+
+modulate delay times (lfo)
+
+> gr_02 =
+>     let o = range 0.15 0.35 (blip KR (1/23) 3)
+>     in recordBuf KR 11 0 1 0 1 Loop 1 DoNothing o
+
+modulate feedback gains (lfo)
+
+> gr_03 =
+>     let o = range 0.75 0.95 (blip KR (1/25) 5)
+>     in recordBuf KR 12 0 1 0 1 Loop 1 DoNothing o
diff --git a/Help/UGen/pv_BinScramble.help.lhs b/Help/UGen/pv_BinScramble.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_BinScramble.help.lhs
@@ -0,0 +1,26 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_BinScramble"
+> Sound.SC3.UGen.DB.ugenSummary "PV_BinScramble"
+
+> import Sound.SC3
+
+> let fileName = "/home/rohan/data/audio/pf-c5.snd"
+> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
+>                ;async (b_allocRead 12 fileName 0 0)})
+
+> let {a = playBuf 1 AR 12 (bufRateScale KR 12) 1 0 Loop DoNothing
+>     ;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)}
+> in audition (out 0 (pan2 (ifft' g) 0 0.5))
+
+careful - feedback loop!
+
+> let {a = soundIn (mce2 4 5) * 4
+>     ;f = fft' 10 a
+>     ;x = mouseX KR 0.15 1 Linear 0.1
+>     ;y = mouseY KR 0.15 1 Linear 0.1
+>     ;i = impulse KR (lfNoise0 'α' KR 2 * 8 + 10) 0
+>     ;g = pv_BinScramble 'β' f x y i
+>     ;h = ifft' g}
+> in audition (out 0 (pan2 h 0 0.5))
diff --git a/Help/UGen/pv_BinShift.help.lhs b/Help/UGen/pv_BinShift.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_BinShift.help.lhs
@@ -0,0 +1,30 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_BinShift"
+> Sound.SC3.UGen.DB.ugenSummary "PV_BinShift"
+
+> import Sound.SC3
+
+allocate buffer
+
+> withSC3 (async (b_alloc 10 2048 1))
+
+source signal (oscillators)
+
+> let z = let {s0 = sinOsc KR 0.08 0 * 6 + 6.2
+>             ;s1 = sinOsc KR (squared s0) 0 * 100 + 800}
+>         in sinOsc AR s1 0 * 0.2
+
+source signal (the world)
+
+> let z = soundIn 4
+
+default values
+
+> audition (out 0 (ifft' (pv_BinShift (fft' 10 z) 1 0 0)))
+
+mouse control
+
+> let {x = mouseX KR (-10) 100 Linear 0.1
+>     ;y = mouseY KR 1 4 Linear 0.1
+>     ;b = mouseButton KR 0 1 0.2
+>     ;pv = pv_BinShift (fft' 10 z) y x b}
+> in audition (out 0 (ifft' pv))
diff --git a/Help/UGen/pv_BinWipe.help.lhs b/Help/UGen/pv_BinWipe.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_BinWipe.help.lhs
@@ -0,0 +1,17 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_BinWipe"
+> Sound.SC3.UGen.DB.ugenSummary "PV_BinWipe"
+
+> import Sound.SC3
+
+> let fileName = "/home/rohan/data/audio/pf-c5.snd"
+> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
+>                ;_ <- async (b_alloc 11 2048 1)
+>                ;async (b_allocRead 12 fileName 0 0)})
+
+> let {n = whiteNoise 'α' AR
+>     ;b = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+>     ;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/pv_BrickWall.help.lhs b/Help/UGen/pv_BrickWall.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_BrickWall.help.lhs
@@ -0,0 +1,10 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_BrickWall"
+> Sound.SC3.UGen.DB.ugenSummary "PV_BrickWall"
+
+> import Sound.SC3
+
+> withSC3 (async (b_alloc 10 2048 1))
+
+> let {n = whiteNoise 'α' AR
+>     ;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/pv_BufRd.help.lhs b/Help/UGen/pv_BufRd.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_BufRd.help.lhs
@@ -0,0 +1,32 @@
+> import Sound.SC3
+
+allocate anazlysis buffer and load soundfile
+
+> let {p = "/home/rohan/opt/share/SuperCollider/sounds/a11wlk01.wav"
+>     ;f = 1024 {- frame size -}
+>     ;h = 0.25 {- hop size -}
+>     ;p_dur = 4.2832879818594 {- duration (in seconds) of p -}
+>     ;b_size = pv_calcPVRecSize p_dur f h 48000}
+> in withSC3 (do {_ <- async (b_alloc 0 b_size 1)
+>                ;async (b_allocRead 1 p 0 0)})
+
+do the analysis and store to buffer.  the window type and overlaps are
+important for resynthesis parameters
+
+> let {rec_buf = 0
+>     ;au_buf = 1
+>     ;l_buf = localBuf 'α' 1024 1;
+>     ;rt = bufRateScale KR au_buf
+>     ;i = playBuf 1 AR au_buf rt 1 0 NoLoop RemoveSynth
+>     ;c0 = fft l_buf i 0.25 1 1 0
+>     ;c1 = pv_RecordBuf c0 rec_buf 0 1 0 0.25 1}
+> in audition (mrg2 (out 0 (dc AR 0)) c1)
+
+play analysis back
+
+> let {rec_buf = 0
+>     ;l_buf = localBuf 'α' 1024 1
+>     ;x = mouseX KR 0 1 Linear 0.2
+>     ;c0 = pv_BufRd l_buf rec_buf x
+>     ;s = ifft c0 1 0}
+> in audition (out 0 s)
diff --git a/Help/UGen/pv_ConformalMap.help.lhs b/Help/UGen/pv_ConformalMap.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_ConformalMap.help.lhs
@@ -0,0 +1,27 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_ConformalMap"
+> Sound.SC3.UGen.DB.ugenSummary "PV_ConformalMap"
+
+> import Sound.SC3
+
+> withSC3 (async (b_alloc 10 1024 1))
+
+> let { i = soundIn 4
+>     ; 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 (async (b_alloc 0 2048 1))
+
+> let z = 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}
+>         in mix (lfSaw AR f 0) * 0.3
+
+> let z = soundIn 4
+
+> let {x = mouseX KR 0.01  2.0 Linear 0.1
+>     ;y = mouseY KR 0.01 10.0 Linear 0.1
+>     ;c = fft' 0 z
+>     ;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/pv_Copy.help.lhs b/Help/UGen/pv_Copy.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_Copy.help.lhs
@@ -0,0 +1,30 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PV_Copy"
+    > Sound.SC3.UGen.DB.ugenSummary "PV_Copy"
+
+> import Sound.SC3 {- hsc3 -}
+
+Proof of concept, silence.  This graph is disallowed.  pv_Copy is
+required to run before the ifft of c0, which mutates c0, however that
+is not apparent from the edge structure of the graph.  See instead
+PV_Split.
+
+> cpy0 =
+>     let z = lfClipNoise 'α' AR 100 * 0.1
+>         c0 = fft' (localBuf 'β' 2048 1) z
+>         c1 = pv_Copy c0 (localBuf 'γ' 2048 1)
+>     in ifft' c1 - ifft' c0
+
+The equivalent situation in sclang.
+
+{var z = LFClipNoise.ar(100) * 0.1
+;var g = FFT(LocalBuf(2048),z)
+;IFFT(g) - IFFT(PV_Copy(g,LocalBuf(2048)))}.play
+
+{var z = LFClipNoise.ar(100) * 0.1
+;var g = FFT(LocalBuf(2048),z)
+;IFFT(PV_Copy(g,LocalBuf(2048))) - IFFT(g)}.play
+
+{var z = LFClipNoise.ar(100) * 0.1
+;var g = FFT(LocalBuf(2048),z)
+;var h = PV_Copy(g,LocalBuf(2048))
+;IFFT(g) - IFFT(h)}.play
diff --git a/Help/UGen/pv_Diffuser.help.lhs b/Help/UGen/pv_Diffuser.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_Diffuser.help.lhs
@@ -0,0 +1,20 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_Diffuser"
+    Sound.SC3.UGen.DB.ugenSummary "PV_Diffuser"
+
+> import Sound.SC3 {- hsc3 -}
+
+> diff_01 = do
+>   let fn = "/home/rohan/data/audio/pf-c5.snd"
+>   withSC3 (async (b_alloc 10 2048 1) >> async (b_allocRead 12 fn 0 0))
+
+> diff_02 = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+
+> diff_02' = soundIn 0
+
+Trigger revised phase shifts with MouseX crossing center of screen
+
+> diff_03 =
+>     let f = fft' 10 diff_02
+>         x = mouseX KR 0 1 Linear 0.1
+>         h = pv_Diffuser f (x >* 0.5)
+>     in ifft' h * 0.5
diff --git a/Help/UGen/pv_HainsworthFoote.help.lhs b/Help/UGen/pv_HainsworthFoote.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_HainsworthFoote.help.lhs
@@ -0,0 +1,23 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_HainsworthFoote"
+    Sound.SC3.UGen.DB.ugenSummary "PV_HainsworthFoote"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = soundIn 4
+>         b = localBuf 'α' 2048 1
+>         f = fft' b i
+>         x = mouseX KR 0.5 1.25 Linear 0.2
+>         h = pv_HainsworthFoote f 1 0 x 0.04
+>         o = sinOsc AR (mrg2 440 445) 0 * decay (h * 0.1) 0.1
+>     in o + i
+
+spot note transitions
+
+> g_02 =
+>     let s = lfSaw AR (lfNoise0 'a' KR 1 * 90 + 400) 0 * 0.5
+>         b = localBuf 'α' 2048 1
+>         f = fft' b s
+>         d = pv_HainsworthFoote f 1.0 0.0 0.9 0.5
+>         t = sinOsc AR 440 0 * decay (d * 0.1) 0.1
+>     in mce2 (s * 0.2) t
diff --git a/Help/UGen/pv_Invert.help.lhs b/Help/UGen/pv_Invert.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_Invert.help.lhs
@@ -0,0 +1,13 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_Invert"
+> Sound.SC3.UGen.DB.ugenSummary "PV_Invert"
+
+> import Sound.SC3
+
+> let {s = sinOsc AR 440 0 * 0.4
+>     ;n = pinkNoise 'α' AR * 0.1
+>     ;i = s + n
+>     ;c0 = fft' 10 i
+>     ;c1 = pv_Invert c0
+>     ;run = do {_ <- async (b_alloc 10 2048 1)
+>               ;play (out 0 (mce2 i (ifft' c1) * 0.5))}}
+> in withSC3 run
diff --git a/Help/UGen/pv_LocalMax.help.lhs b/Help/UGen/pv_LocalMax.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_LocalMax.help.lhs
@@ -0,0 +1,14 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_LocalMax"
+> Sound.SC3.UGen.DB.ugenSummary "PV_LocalMax"
+
+> import Sound.SC3
+
+> let fileName = "/home/rohan/data/audio/pf-c5.snd"
+> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
+>                ;async (b_allocRead 12 fileName 0 0)})
+
+> let { a = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+>     ; 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/pv_MagAbove.help.lhs b/Help/UGen/pv_MagAbove.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_MagAbove.help.lhs
@@ -0,0 +1,22 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_MagAbove"
+> Sound.SC3.UGen.DB.ugenSummary "PV_MagAbove"
+
+> import Sound.SC3
+
+> let fileName = "/home/rohan/data/audio/pf-c5.snd"
+> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
+>                ;async (b_allocRead 12 fileName 0 0) })
+
+> let {a = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+>     ;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.
+> 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/pv_MagBelow.help.lhs b/Help/UGen/pv_MagBelow.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_MagBelow.help.lhs
@@ -0,0 +1,22 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_MagBelow"
+> Sound.SC3.UGen.DB.ugenSummary "PV_MagBelow"
+
+> import Sound.SC3
+
+> let fileName = "/home/rohan/data/audio/pf-c5.snd"
+> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
+>                ;async (b_allocRead 12 fileName 0 0)})
+
+> let { a = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+>     ; 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.
+> 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/pv_MagClip.help.lhs b/Help/UGen/pv_MagClip.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_MagClip.help.lhs
@@ -0,0 +1,28 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_MagClip"
+> Sound.SC3.UGen.DB.ugenSummary "PV_MagClip"
+
+> import Sound.SC3
+
+> let fileName = "/home/rohan/data/audio/pf-c5.snd"
+> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
+>                ;async (b_allocRead 12 fileName 0 0)})
+
+File input
+
+> let z = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+
+Synthesised input.
+
+> let z = let {f0 = squared (sinOsc KR 0.08 0 * 6 + 6.2)
+>             ;f1 = sinOsc KR f0 0 * 100 + 800}
+>         in sinOsc AR f1 0
+
+Outside world
+
+> let z = soundIn 4
+
+> let {f = fft' 10 z
+>     ;c = 128
+>     ;x = mouseX KR 0 c Linear 0.1
+>     ;h = pv_MagClip f x}
+> in audition (out 0 (ifft' h * 0.5))
diff --git a/Help/UGen/pv_MagFreeze.help.lhs b/Help/UGen/pv_MagFreeze.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_MagFreeze.help.lhs
@@ -0,0 +1,31 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_MagFreeze"
+> Sound.SC3.UGen.DB.ugenSummary "PV_MagFreeze"
+
+> import Sound.SC3 {- hsc3 -}
+
+Load audio file.
+
+> let fileName = "/home/rohan/data/audio/pf-c5.snd"
+> in withSC3 (do {_ <- async (b_alloc 10 2048 1)
+>                ;async (b_allocRead 12 fileName 0 0)})
+
+File as signal...
+
+> let z = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+
+Synthesised signal...
+
+> let z = let {o1 = sinOsc KR 0.08 0
+>             ;o2 = sinOsc KR (squared (o1 * 6 + 6.2)) 0 * 100 + 800}
+>         in sinOsc AR o2 0
+
+Outside world signal...
+
+> let z = soundIn 4
+
+Process (freeze) 'z'...
+
+> let {f = fft' 10 z
+>     ;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/pv_MagMul.help.lhs b/Help/UGen/pv_MagMul.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_MagMul.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PV_MagMul"
+    > Sound.SC3.UGen.DB.ugenSummary "PV_MagMul"
+
+> import Sound.SC3 {- hsc3 -}
+
+    > withSC3 (async (b_alloc 0 2048 1) >> async (b_alloc 1 2048 1))
+
+> mm0 z =
+>     let y = lfSaw AR (midiCPS 43) 0 * 0.2
+>         c0 = fft' (localBuf 'α' 2048 1) y
+>         c1 = fft' (localBuf 'β' 2048 1) z
+>         c2 = pv_MagMul c0 c1
+>     in ifft' c2 * 0.1
+
+> g_01 = mm0 (whiteNoise 'γ' AR * 0.2)
+> g_02 = mm0 (soundIn 4 * 0.5)
diff --git a/Help/UGen/pv_RandComb.help.lhs b/Help/UGen/pv_RandComb.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_RandComb.help.lhs
@@ -0,0 +1,23 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_RandComb"
+> Sound.SC3.UGen.DB.ugenSummary "PV_RandComb"
+
+> import Sound.SC3
+
+allocate buffer
+
+> withSC3 (async (b_alloc 10 2048 1))
+
+noise signal
+
+> let z = whiteNoise 'α' AR * 0.5
+
+outside world
+
+> let z = soundIn 4
+
+processor
+
+> let {t = impulse KR 0.1 0
+>     ;x = mouseX KR 0.6 0.95 Linear 0.1
+>     ;c = pv_RandComb 'α' (fft' 10 z) x t}
+> in audition (out 0 (pan2 (ifft' c) 0 1))
diff --git a/Help/UGen/pv_RandWipe.help.lhs b/Help/UGen/pv_RandWipe.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_RandWipe.help.lhs
@@ -0,0 +1,23 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_RandWipe"
+> Sound.SC3.UGen.DB.ugenSummary "PV_RandWipe"
+
+> import Sound.SC3
+> import qualified System.Random as R
+
+> withSC3 (do {_ <- async (b_alloc 10 2048 1)
+>             ;async (b_alloc 11 2048 1)})
+
+> let { n0 = R.randomRs (400.0, 1000.0) (R.mkStdGen 0)
+>     ; n1 = R.randomRs (80.0, 400.0) (R.mkStdGen 1)
+>     ; n2 = R.randomRs (0.0, 8.0) (R.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 'a' f g x (y >* 0.5) }
+> in audition (out 0 (pan2 (ifft' h) 0 0.5))
diff --git a/Help/UGen/pv_RectComb.help.lhs b/Help/UGen/pv_RectComb.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_RectComb.help.lhs
@@ -0,0 +1,24 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_RectComb"
+> Sound.SC3.UGen.DB.ugenSummary "PV_RectComb"
+
+> import Sound.SC3
+
+> withSC3 (async (b_alloc 10 2048 1))
+
+noise source
+
+> let z = whiteNoise 'α' AR * 0.3
+
+outside world
+
+> let z = soundIn 4
+
+> let {x = mouseX KR 0 0.5 Linear 0.1
+>     ;y = mouseY KR 0 0.5 Linear 0.1
+>     ;c = pv_RectComb (fft' 10 z) 8 x y}
+> in audition (out 0 (pan2 (ifft' c) 0 1))
+
+> 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 z) 8 p w}
+> in audition (out 0 (pan2 (ifft' c) 0 1))
diff --git a/Help/UGen/pvcollect.help.lhs b/Help/UGen/pvcollect.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pvcollect.help.lhs
@@ -0,0 +1,53 @@
+> Sound.SC3.UGen.Help.viewSC3Help "PV_ChainUGen.pvcollect"
+> :t pvcollect
+
+> import Prelude hiding ((<*))
+> import Data.List {- base -}
+> import Sound.SC3 {- hsc3 -}
+
+> let fileName = "/home/rohan/data/audio/pf-c5.snd"
+> in withSC3 (do {_ <- async (b_alloc 10 1024 1)
+>                ;async (b_allocRead 11 fileName 0 0)})
+
+> let 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)
+
+> let bpf_sweep nf 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)
+
+> let pv_g nf cf =
+>   let {no_op m p _ = (m,p)
+>       ;combf m p i = ((modE i 7.0 ==* 0) * m,p)
+>       ;sf = playBuf 1 AR 11 (bufRateScale KR 11) 1 0 Loop DoNothing
+>       ;c1 = fft' 10 sf
+>       ;c2 = pvcollect c1 nf cf 0 250 0}
+>   in out 0 (0.1 * ifft' c2)
+
+> let pv_au nf cf =
+>   let {no_op m p _ = (m,p)
+>       ;combf m p i = ((modE i 7.0 ==* 0) * m,p)
+>       ;c1 = fft' 10 (soundIn 0)
+>       ;c2 = pvcollect c1 nf cf 0 250 0}
+>   in out 0 (0.1 * ifft' c2)
+
+> let r = unlines ["number of constants       : 257"
+>                 ,"number of controls        : 0"
+>                 ,"control rates             : []"
+>                 ,"number of unit generators : 1013"
+>                 ,"unit generator rates      : [(KR,5),(AR,4),(DR,1004)]"]
+> in r `isPrefixOf` synthstat (pv_g 1024 spectral_delay)
+
+> synthstat (pv_g 1024 (bpf_sweep 1024))
+> audition (pv_g 1024 spectral_delay)
+> audition (pv_g 1024 (bpf_sweep 1024))
+
+> audition (pv_au 1024 spectral_delay)
+> audition (pv_au 1024 (bpf_sweep 1024))
+
+> import Sound.SC3.UGen.Dot {- hsc3-dot -}
+
+> draw_svg (pv_g 1024 (bpf_sweep 1024))
diff --git a/Help/UGen/qitch.help.lhs b/Help/UGen/qitch.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/qitch.help.lhs
@@ -0,0 +1,23 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Qitch"
+> Sound.SC3.UGen.DB.ugenSummary "Qitch"
+
+> import Sound.SC3
+> import System.FilePath
+
+Load required data file (edit path as required)
+
+> let {d = "/home/rohan/opt/share/SuperCollider/Extensions/SC3plugins"
+>     ;qf = d </> "PitchDetection/extraqitchfiles/QspeckernN2048SR48000.wav"}
+> in withSC3 (async (b_allocRead 10 qf 0 0))
+
+Comparison of input frequency (x) and tracked oscillator frequency (f).
+Output is printed to the console by scsynth.
+
+> let {x = mouseX KR 440 880 Exponential 0.1
+>     ;o = sinOsc AR x 0 * 0.1
+>     ;[f,e] = mceChannels (qitch KR o 10 1e-2 1 0 0 2500)
+>     ;r = sinOsc AR f 0 * 0.1
+>     ;t = impulse KR 4 0
+>     ;pf = poll t f (label "f") 0
+>     ;px = poll t x (label "x") 0}
+> in audition (mrg [out 0 (mce2 o r),pf,px])
diff --git a/Help/UGen/quadC.help.lhs b/Help/UGen/quadC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/quadC.help.lhs
@@ -0,0 +1,1 @@
+See quadN
diff --git a/Help/UGen/quadL.help.lhs b/Help/UGen/quadL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/quadL.help.lhs
@@ -0,0 +1,1 @@
+See quadN
diff --git a/Help/UGen/quadN.help.lhs b/Help/UGen/quadN.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/quadN.help.lhs
@@ -0,0 +1,13 @@
+> Sound.SC3.UGen.Help.viewSC3Help "QuadN"
+> Sound.SC3.UGen.DB.ugenSummary "QuadN"
+
+> import Sound.SC3
+
+> audition (out 0 (quadC AR 4000 1 (-1) (-0.75) 0 * 0.2))
+
+> let x = mouseX KR 3.5441 4 Linear 0.1
+> 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}
+> in audition (out 0 (sinOsc AR f 0 * 0.4))
diff --git a/Help/UGen/radiansPerSample.help.lhs b/Help/UGen/radiansPerSample.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/radiansPerSample.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "RadiansPerSample"
+    > Sound.SC3.UGen.DB.ugenSummary "RadiansPerSample"
+
+> import Sound.SC3 {- hsc3 -}
+
+two pi divided by the nominal sample rate (ie. a very small number)
+
+> g_01 =
+>     let f = mce2 radiansPerSample ((2 * pi) / sampleRate) * 5e6
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/ramp.help.lhs b/Help/UGen/ramp.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ramp.help.lhs
@@ -0,0 +1,19 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Ramp"
+    > Sound.SC3.UGen.DB.ugenSummary "Ramp"
+
+> import Sound.SC3 {- hsc3 -}
+
+Used to lag pitch
+
+> g_01 =
+>     let o = lfPulse KR 4 0 0.5 * 50 + 400
+>         l = line KR 0 1 15 DoNothing
+>         f = ramp o l
+>     in sinOsc AR f 0 * 0.3
+
+mouse control
+
+> g_02 =
+>     let x = mouseX KR 220 440 Exponential 0
+>         x' = ramp x (300 / 1000)
+>     in sinOsc AR (mce2 x x') 0 * 0.1
diff --git a/Help/UGen/rand.help.lhs b/Help/UGen/rand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/rand.help.lhs
@@ -0,0 +1,10 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Rand"
+> Sound.SC3.UGen.DB.ugenSummary "Rand"
+
+> import Sound.SC3
+
+> let {f = rand 'α' 200 1200
+>     ;l = rand 'β' (-1) 1
+>     ;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/randID.help.lhs b/Help/UGen/randID.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/randID.help.lhs
@@ -0,0 +1,2 @@
+> Sound.SC3.UGen.Help.viewSC3Help "RandID"
+> Sound.SC3.UGen.DB.ugenSummary "RandID"
diff --git a/Help/UGen/randSeed.help.lhs b/Help/UGen/randSeed.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/randSeed.help.lhs
@@ -0,0 +1,27 @@
+Sound.SC3.UGen.Help.viewSC3Help "RandSeed"
+Sound.SC3.UGen.DB.ugenSummary "RandSeed"
+
+> import Sound.SC3
+
+start a noise patch
+
+> u0 =
+>     let n = uclone 'α' 2 (whiteNoise 'β' AR * 0.05 + dust2 'γ' AR 70)
+>         f = lfNoise1 'δ' KR 3 * 5500 + 6000
+>     in resonz (n * 5) f 0.5 + n * 0.5
+
+reset the seed at a variable rate (crash?)
+
+> u1 =
+>      let s = 1956 -- control KR "seed" 1956
+>          i = impulse KR (mouseX KR 0.1 100 Linear 0.2) 0
+>      in randSeed KR i s
+
+always the same (for a given seed)...
+
+> u2 =
+>     let sd = 1957
+>         n = tIRand 'α' 4 12 (dust 'β' KR 1)
+>         f = n * 150 + (mce [0,1])
+>         r = randSeed IR 1 sd
+>     in mrg2 (sinOsc AR f 0 * 0.1) r
diff --git a/Help/UGen/recordBuf.help.lhs b/Help/UGen/recordBuf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/recordBuf.help.lhs
@@ -0,0 +1,24 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "RecordBuf"
+    > Sound.SC3.UGen.DB.ugenSummary "RecordBuf"
+
+> import Sound.SC3 {- hsc3 -}
+
+Allocate a buffer (assume SR of 48k)
+
+    > withSC3 (async (b_alloc 0 (48000 * 4) 1))
+
+Record for four seconds (until end of buffer)
+
+> g_01 =
+>     let o = formant AR (xLine KR 400 1000 4 DoNothing) 2000 800 * 0.125
+>     in mrg2 o (recordBuf AR 0 0 1 0 1 NoLoop 1 RemoveSynth o)
+
+Play it back
+
+> g_02 = playBuf 1 AR 0 1 1 0 NoLoop RemoveSynth
+
+Mix second signal equally with existing signal, replay to hear
+
+> g_03 =
+>     let o = formant AR (xLine KR 200 1000 4 DoNothing) 2000 800 * 0.125
+>     in mrg2 o (recordBuf AR 0 0 0.5 0.5 1 NoLoop 1 RemoveSynth o)
diff --git a/Help/UGen/replaceOut.help.lhs b/Help/UGen/replaceOut.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/replaceOut.help.lhs
@@ -0,0 +1,72 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "ReplaceOut"
+    > Sound.SC3.UGen.DB.ugenSummary "ReplaceOut"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = replaceOut 0 (sinOsc AR 440 0 * 0.1)
+
+Send signal to a bus, overwrite existing signal.
+
+> g_02 =
+>     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 mrg [a, b, c]
+
+Compare to
+
+> g_03 =
+>     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 mrg [a,b,c]
+
+- a writes noise to 24
+- b reads 24 and replaces with filtered variant
+- c reads 24 and writes to 0
+
+> g_04 =
+>     let a = out 24 (pinkNoise 'α' AR * 0.1)
+>         b = replaceOut 24 (bpf (in' 1 AR 24) 440 1)
+>         c = out 0 (in' 1 AR 24)
+>     in mrg [c,b,a]
+
+    > putStrLn$ synthstat g_04
+
+~~~~
+number of constants       : 5
+number of controls        : 0
+control rates             : []
+number of unit generators : 7
+unit generator rates      : [(AR,7)]
+unit generator set        : *,BPF,In,Out,PinkNoise,ReplaceOut
+unit generator sequence   : PinkNoise,*,Out,In,BPF,ReplaceOut,Out
+~~~~
+
+Signal/effect model using separate groups operating at the same bus.
+
+> n_01 =
+>     let d = dust 'α' AR 1
+>         n = whiteNoise 'β' AR
+>         i = decay (d * 0.5) 0.2 * n
+>     in synthdef "n_01" (out 0 i)
+
+> n_02 =
+>     let i = in' 1 AR 0
+>     in synthdef "n_02" (replaceOut 0 (combC i 0.2 0.2 3))
+
+> m_01 =
+>     [g_new [(1,AddToTail,0)]
+>     ,g_new [(2,AddToTail,0)]
+>     ,d_recv n_01
+>     ,d_recv n_02
+>     ,s_new "n_01" (-1) AddToTail 1 []
+>     ,s_new "n_02" (-1) AddToTail 2 []]
+
+> f_01 m =
+>     if isAsync m
+>     then async m >> return ()
+>     else send m
+
+   > withSC3 (mapM_ f_01 m_01)
diff --git a/Help/UGen/resonz.help.lhs b/Help/UGen/resonz.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/resonz.help.lhs
@@ -0,0 +1,35 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Resonz"
+> Sound.SC3.UGen.DB.ugenSummary "Resonz"
+
+> import Sound.SC3
+
+> let n = whiteNoise 'α' AR
+> in audition (out 0 (resonz (n * 0.5) 2000 0.1))
+
+Modulate frequency
+
+> let {n = whiteNoise 'α' AR
+>     ;f = xLine KR 1000 8000 10 RemoveSynth}
+> in audition (out 0 (resonz (n * 0.5) f 0.05))
+
+Modulate bandwidth
+
+> let {n = whiteNoise 'α' AR
+>     ;bw = xLine KR 1 0.001 8 RemoveSynth}
+> in audition (out 0 (resonz (n * 0.5) 2000 bw))
+
+Modulate bandwidth opposite direction
+
+> let {n = whiteNoise 'α' AR
+>     ;bw = xLine KR 0.001 1 8 RemoveSynth}
+> in audition (out 0 (resonz (n * 0.5) 2000 bw))
+
+Mouse exam (1/Q = bandwidth / center-frequency)
+
+> let {n = pinkNoise 'α' AR
+>     ;m = mouseX KR 36 85 Linear 0.2 {- midi note -}
+>     ;w = mouseY KR 0.1 5 Linear 0.2 {- bandwidth -}
+>     ;f = midiCPS (floorE m) {- centre frequency -}
+>     ;rq = w / f {- 1/Q (reciprocal of Q) -}
+>     ;o = resonz (n * 0.5) f rq}
+> in audition (out 0 o)
diff --git a/Help/UGen/rhpf.help.lhs b/Help/UGen/rhpf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/rhpf.help.lhs
@@ -0,0 +1,7 @@
+> Sound.SC3.UGen.Help.viewSC3Help "RHPF"
+> Sound.SC3.UGen.DB.ugenSummary "RHPF"
+
+> import Sound.SC3
+
+> let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
+> in audition (out 0 (rhpf (saw AR 200 * 0.1) f 0.2))
diff --git a/Help/UGen/ring1.help.lhs b/Help/UGen/ring1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ring1.help.lhs
@@ -0,0 +1,12 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.ring1"
+    > :t ring1
+
+> import Sound.SC3 {- hsc3 -}
+>
+> o_01 = fSinOsc AR 800 0
+> o_02 = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
+> g_01 = ring1 o_01 o_02 * 0.125
+
+is equivalent to:
+
+> g_02 = ((o_01 * o_02) + o_01) * 0.125
diff --git a/Help/UGen/ringz.help.lhs b/Help/UGen/ringz.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ringz.help.lhs
@@ -0,0 +1,29 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Ringz"
+> Sound.SC3.UGen.DB.ugenSummary "Ringz"
+
+> import Sound.SC3
+
+> let n = dust 'α' AR 3
+> in audition (out 0 (ringz (n * 0.3) 2000 2))
+
+> let n = whiteNoise 'α' AR
+> in audition (out 0 (ringz (n * 0.005) 2000 0.5))
+
+Modulate frequency
+
+> let {n = whiteNoise 'α' AR
+>     ;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
+> 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
+> 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
+> in audition (out 0 (ringz (impulse AR 6 0.3) 2000 rt))
diff --git a/Help/UGen/rlpf.help.lhs b/Help/UGen/rlpf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/rlpf.help.lhs
@@ -0,0 +1,12 @@
+> Sound.SC3.UGen.Help.viewSC3Help "RLPF"
+> Sound.SC3.UGen.DB.ugenSummary "RLPF"
+
+> import Sound.SC3
+
+> let {n = whiteNoise 'α' AR
+>     ;f = sinOsc AR 0.5 0 * 40 + 220
+>     ;r = rlpf n f 0.1}
+> in audition (out 0 r)
+
+> let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
+> in audition (out 0 (rlpf (saw AR 200 * 0.1) f 0.2))
diff --git a/Help/UGen/rossler.help.lhs b/Help/UGen/rossler.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/rossler.help.lhs
diff --git a/Help/UGen/rotate2.help.lhs b/Help/UGen/rotate2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/rotate2.help.lhs
@@ -0,0 +1,19 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Rotate2"
+    > Sound.SC3.UGen.DB.ugenSummary "Rotate2"
+
+> import Sound.SC3 {- hsc3 -}
+
+Rotation of stereo sound, via LFO.
+
+> g_01 =
+>     let x = pinkNoise 'α' AR
+>         y = lfTri AR 800 0 * lfPulse KR 3 0 0.3 * 0.2
+>     in rotate2 x y (lfSaw KR 0.1 0)
+
+Rotation of stereo sound, via mouse.
+
+> g_02 =
+>     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 rotate2 x y p
diff --git a/Help/UGen/roundUp.help.lhs b/Help/UGen/roundUp.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/roundUp.help.lhs
@@ -0,0 +1,13 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.round"
+    > :t roundUp
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let x = mouseX KR 60 4000 Linear 0.1
+>         f = roundUp x 100
+>     in sinOsc AR f 0 * 0.1
+>
+> g_02 =
+>     let n = line KR 24 108 6 RemoveSynth
+>     in saw AR (midiCPS (roundUp n 1)) * 0.2
diff --git a/Help/UGen/runningMax.help.lhs b/Help/UGen/runningMax.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/runningMax.help.lhs
@@ -0,0 +1,17 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "RunningMax"
+    > Sound.SC3.UGen.DB.ugenSummary "RunningMax"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let n = dust 'α' AR 20
+>         t = impulse AR 0.4 0
+>         f = runningMax n t * 500 + 200
+>     in t + sinOsc AR f 0 * 0.2
+
+follow a sine lfo, reset rate controlled by mouse x
+
+> g_02 =
+>     let t = impulse KR (mouseX KR 0.01 2 Linear 0.1) 0
+>         f = runningMax (sinOsc KR 0.2 0) t * 500 + 200
+>     in t + sinOsc AR f 0 * 0.2
diff --git a/Help/UGen/runningMin.help.lhs b/Help/UGen/runningMin.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/runningMin.help.lhs
@@ -0,0 +1,19 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "RunningMin"
+    > Sound.SC3.UGen.DB.ugenSummary "RunningMin"
+
+> import Sound.SC3 {- hsc3 -}
+
+Follow a sine lfo, reset rate controlled by mouseX
+
+> g_01 =
+>     let o = sinOsc KR 2 pi
+>         x = mouseX KR 0.01 10 Exponential 0.1
+>         t = impulse AR x 0
+>         f = runningMin o t * 500 + 200
+>     in t + sinOsc AR f 0 * 0.1
+>
+> g_02 =
+>     let n = dust 'α' AR 20
+>         t = impulse AR 0.4 0
+>         f = runningMin n t * 500 + 200
+>     in sinOsc AR f 0 * 0.2
diff --git a/Help/UGen/runningSum.help.lhs b/Help/UGen/runningSum.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/runningSum.help.lhs
@@ -0,0 +1,28 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "RunningSum"
+    > Sound.SC3.UGen.DB.ugenSummary "RunningSum"
+
+> import Sound.SC3 {- hsc3 -}
+
+distorts of course - would need scaling
+
+> g_01 = runningSum (soundIn 4) 40
+
+Running Average over x samples
+
+> g_02 = let x = 100 in runningSum (lfSaw AR 440 0) x * recip x
+
+RMS Power
+
+> g_03 =
+>     let input = lfSaw AR 440 0
+>         numsamp = 30
+>     in runningSum (input * input) numsamp / (sqrt numsamp)
+
+composite UGen
+
+> g_04 = runningSumRMS (soundIn 4) 40
+
+> g_05 =
+>     let z = soundIn 4
+>         a = runningSum z 40
+>     in sinOsc AR 440 0 * a * 0.1
diff --git a/Help/UGen/sampleDur.help.lhs b/Help/UGen/sampleDur.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sampleDur.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "SampleDur"
+    > Sound.SC3.UGen.DB.ugenSummary "SampleDur"
+
+> import Sound.SC3 {- hsc3 -}
+
+`sampleDur` is the reciprocal of the nominal sample rate of the server
+
+> g_01 =
+>     let f = mce2 sampleRate (recip sampleDur) * 0.01
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/sampleRate.help.lhs b/Help/UGen/sampleRate.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sampleRate.help.lhs
@@ -0,0 +1,17 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "SampleRate"
+    > Sound.SC3.UGen.DB.ugenSummary "SampleRate"
+
+> import Sound.SC3 {- hsc3 -}
+
+the current nominal sample rate of the server
+
+> g_01 =
+>     let sr = 48000 {- 44100 -}
+>         f = mce2 sampleRate sr * 0.01
+>     in sinOsc AR f 0 * 0.1
+
+The server status command can extract nominal and actual sample rates
+from a running server.
+
+    > import Control.Monad
+    > withSC3 (liftM2 (,) serverSampleRateNominal serverSampleRateActual)
diff --git a/Help/UGen/saw.help.lhs b/Help/UGen/saw.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/saw.help.lhs
@@ -0,0 +1,25 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Saw"
+    > Sound.SC3.UGen.DB.ugenSummary "Saw"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = saw AR (xLine KR 40 4000 6 RemoveSynth) * 0.1
+
+compare to the non-bandlimited lfSaw
+
+> g_02 = lfSaw AR (xLine KR 40 4000 6 RemoveSynth) 0 * 0.1
+
+Two band limited sawtooth waves thru a resonant low pass filter
+
+> g_03 =
+>     let f = xLine KR 8000 400 5 DoNothing
+>     in rlpf (saw AR (mce2 100 250) * 0.1) f 0.05
+
+Drawings
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen1 0.1 (saw AR 50) -- descending
+    > plot_ugen1 0.002 (saw AR 5000) -- ragged
+
+![](sw/hsc3/Help/SVG/saw.0.svg)
+![](sw/hsc3/Help/SVG/saw.1.svg)
diff --git a/Help/UGen/scaleNeg.help.lhs b/Help/UGen/scaleNeg.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/scaleNeg.help.lhs
@@ -0,0 +1,18 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.scaleneg"
+    > :t scaleNeg
+
+> import Prelude hiding ((<*)) {- base -}
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let o = fSinOsc AR 1000 0
+>         l = line AR 1 (-1) 4 RemoveSynth
+>     in scaleNeg o l * 0.1
+
+written out:
+
+> g_02 =
+>     let o = fSinOsc AR 1000 0
+>         l = line AR 1 (-1) 4 RemoveSynth
+>         c = o <* 0
+>     in (c * (o * l) + (1 - c) * o) * 0.1
diff --git a/Help/UGen/schmidt.help.lhs b/Help/UGen/schmidt.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/schmidt.help.lhs
@@ -0,0 +1,11 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Schmidt"
+    > Sound.SC3.UGen.DB.ugenSummary "Schmidt"
+
+> import Sound.SC3 {- hsc3 -}
+
+threshold octave jumps
+
+> g_01 =
+>     let n = lfNoise1 'α' KR 3
+>         o = schmidt n (-0.15) 0.15 + 1
+>     in sinOsc AR (n * 200 + 500 * o) 0 * 0.1
diff --git a/Help/UGen/select.help.lhs b/Help/UGen/select.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/select.help.lhs
@@ -0,0 +1,19 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Select"
+    > Sound.SC3.UGen.DB.ugenSummary "Select"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let n = 3/2
+>         a = mce [sinOsc AR 440 0, saw AR 440, pulse AR 440 0.1]
+>     in select (lfSaw KR 1 0 * n + n) a * 0.2
+
+Here used as a sequencer:
+
+> g_02 =
+>     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 saw AR f * 0.2
+
diff --git a/Help/UGen/selectX.help.lhs b/Help/UGen/selectX.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/selectX.help.lhs
@@ -0,0 +1,22 @@
+> Sound.SC3.UGen.Help.viewSC3Help "SelectX"
+> :t selectX
+
+# composite ugen graph
+
+> import Sound.SC3
+> import Sound.SC3.UGen.Dot
+
+> let { n = 3/2
+>     ; f = mce2 440 441
+>     ; a = mce [sinOsc AR f 0, saw AR f, pulse AR f 0.1]
+>     ; s = mceSum (selectX (lfSaw KR 1 0 * n + n) a * 0.2) }
+> in audition (out 0 s) >> draw s
+
+Here used as a sequencer:
+
+> let { n = 10
+>     ; a = mce [517, 403, 89, 562, 816, 107, 241, 145, 90, 224]
+>     ; c = n / 2
+>     ; f = mceSum (selectX (lfSaw KR 0.5 0 * c + c) a)
+>     ; s = saw AR f * 0.2 }
+> in audition (out 0 s) >> draw s
diff --git a/Help/UGen/sendReply.help.lhs b/Help/UGen/sendReply.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sendReply.help.lhs
@@ -0,0 +1,16 @@
+    Sound.SC3.UGen.Help.viewSC3Help "SendReply"
+    Sound.SC3.UGen.DB.ugenSummary "SendReply"
+
+> import Sound.OSC {- hosc3 -}
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>   let s0 = lfNoise0 'α' KR 5
+>       s1 = lfNoise0 'β' KR 5
+>       o = sinOsc AR (s0 * 200 + 500) 0 * s1 * 0.1
+>   in mrg [o,sendReply s0 0 "/send-reply" [s0,s1]]
+
+> f_01 :: (DuplexOSC m) => m Message
+> f_01 = withNotifications (waitReply "/send-reply")
+
+    withSC3 f_01
diff --git a/Help/UGen/sendTrig.help.lhs b/Help/UGen/sendTrig.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sendTrig.help.lhs
@@ -0,0 +1,48 @@
+    Sound.SC3.UGen.Help.viewSC3Help "SendTrig"
+    Sound.SC3.UGen.DB.ugenSummary "SendTrig"
+
+> import Control.Monad {- base -}
+> import Data.Maybe {- base -}
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+
+Retrieve a single message
+
+> g_01 =
+>     let s = lfNoise0 'α' KR 5
+>         o = sinOsc AR (s * 200 + 500) 0 * 0.1
+>     in mrg [o,sendTrig s 0 s]
+
+> f_01 :: Transport m => m Message
+> f_01 = withNotifications (waitReply "/tr")
+
+    withSC3 f_01
+
+Send random triggers, request notifications, then for each trigger start a synth (s_03).
+
+> g_02 =
+>     let t = dust 'α' KR 1.0
+>     in sendTrig t 0 t
+
+> g_03 =
+>     let freq = control KR "freq" 440
+>         env = envGen KR 1 0.1 0 1 RemoveSynth (envPerc 0.01 1)
+>     in sinOsc AR freq 0 * env
+
+> s_03 = synthdef "s_03" (out 0 g_03)
+
+> f_02 :: Transport m => m ()
+> f_02 = do
+>   r <- waitReply "/tr"
+>   let (_,_,n) = unpack_tr_err r
+>   sendMessage (s_new "s_03" (-1) AddToTail 1 [("freq",110 + (n * 110))])
+
+> f_03 :: Transport m => m ()
+> f_03 = do
+>   play g_02
+>   async_ (notify True)
+>   async_ (d_recv s_03)
+>   repeatM_ f_02
+
+     withSC3 f_03
diff --git a/Help/UGen/setResetFF.help.lhs b/Help/UGen/setResetFF.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/setResetFF.help.lhs
@@ -0,0 +1,21 @@
+> Sound.SC3.UGen.Help.viewSC3Help "SetResetFF"
+> Sound.SC3.UGen.DB.ugenSummary "SetResetFF"
+
+> import Sound.SC3
+
+d0 is the set trigger, d1 the reset trigger
+
+> let {n = brownNoise 'α' AR
+>     ;d0 = dust 'β' AR 5
+>     ;d1 = dust 'γ' AR 5}
+> in audition (out 0 (setResetFF d0 d1 * n * 0.2))
+
+silence
+
+> let tr = setResetFF (impulse KR 5 0) (impulse KR 10 0)
+> in audition (out 0 (brownNoise 'α' AR * 0.1 * decay2 tr 0.01 0.05))
+
+duty cycle
+
+> let tr = 1 - setResetFF (impulse KR 10 0) (impulse KR 5 0)
+> in audition (out 0 (brownNoise 'α' AR * 0.1 * decay2 tr 0.01 0.05))
diff --git a/Help/UGen/shaper.help.lhs b/Help/UGen/shaper.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/shaper.help.lhs
@@ -0,0 +1,52 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Shaper"
+    > Sound.SC3.UGen.DB.ugenSummary "Shaper"
+
+> import Sound.SC3 {- hsc3 -}
+
+function to generate wavetable buffer using b_gen_cheby
+
+> mk_b a =
+>     let tbl_f = [Normalise,Wavetable,Clear]
+>         msg = [b_alloc 10 512 1,b_gen_cheby 10 tbl_f a]
+>     in withSC3 (mapM_ async msg)
+
+hear waveshaper at pure (sin) tone
+
+    > mk_b [1,0,1,1,0,1]
+
+> g_01 =
+>     let z = sinOsc AR 300 0 * line KR 0 1 6 RemoveSynth
+>     in shaper 10 z * 0.1
+
+plot wavetable (as in-buffer layout, as plain wavetable)
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > withSC3 (plot_buffer1 10)
+    > withSC3 (plot_wavetable1 10)
+
+![](sw/hsc3/Help/SVG/shaper.0.svg)
+![](sw/hsc3/Help/SVG/shaper.1.svg)
+
+variations
+
+    > mk_b [0.25,0.5,0.25]
+
+> g_02 =
+>     let z = sinOsc AR 400 (pi / 2) * line KR 0 1 6 RemoveSynth
+>     in shaper 10 z * 0.1
+
+wave shape external signal
+
+    > mk_b [1,0,1,1,0,1]
+
+> g_03 =
+>     let z = soundIn 0
+>         x = sinOsc KR (1/4) 0
+>     in xFade2 z (shaper 10 z) x 0.5
+
+    > mk_b [1,0,1,1,0,1,0.5,0,0.25,0,0.75,1]
+
+> g_04 =
+>     let z = soundIn 4
+>         x = mouseX KR (-1) 1 Linear 0.2
+>     in xFade2 z (shaper 10 z) x 0.5
diff --git a/Help/UGen/silent.help.lhs b/Help/UGen/silent.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/silent.help.lhs
@@ -0,0 +1,7 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Silent"
+> Sound.SC3.UGen.DB.ugenSummary "Silent"
+
+> import Sound.SC3
+
+> let g = out 0 (silent 2)
+> in audition g
diff --git a/Help/UGen/sinOsc.help.lhs b/Help/UGen/sinOsc.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sinOsc.help.lhs
@@ -0,0 +1,61 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "SinOsc"
+    > Sound.SC3.UGen.DB.ugenSummary "SinOsc"
+
+> import Sound.SC3 {- hsc3 -}
+
+Fixed frequency
+
+> g_01 = sinOsc AR (midiCPS 69) 0 * 0.25
+
+Modulate freq
+
+> g_02 = sinOsc AR (xLine KR 2000 200 9 RemoveSynth) 0 * 0.5
+
+Modulate freq
+
+> g_03 =
+>     let f = sinOsc AR (xLine KR 1 1000 9 RemoveSynth) 0 * 200 + 800
+>     in sinOsc AR f 0 * 0.1
+
+Modulate phase
+
+> g_04 =
+>     let ph = sinOsc AR (xLine KR 20 8000 10 RemoveSynth) 0 * 2 * pi
+>     in sinOsc AR 800 ph * 0.1
+
+Mouse control
+
+> g_05 =
+>     let x = mouseX KR 40 10000 Exponential 0.2
+>         y = mouseY KR 0.01 0.25 Exponential 0.2
+>     in sinOsc AR x 0 * y
+
+Simple bell-like tone.
+
+> g_06 =
+>     let f = mce [0.5,1,1.19,1.56,2,2.51,2.66,3.01,4.1]
+>         a = mce [0.25,1,0.8,0.5,0.9,0.4,0.3,0.6,0.1]
+>         o = sinOsc AR (500 * f) 0 * a
+>         e = envGen KR 1 0.1 0 1 RemoveSynth (envPerc 0.01 10)
+>     in mix o * e
+
+"When two pure tones of slightly different frequency are superposed,
+our ears perceive audible beats at a rate given by the difference of
+the two frequencies."
+
+> g_07 =
+>     let f0 = 220
+>         f1 = 221.25
+>         d = abs (f1 - f0)
+>     in sinOsc AR (mce2 f0 f1) 0 * 0.1 + impulse AR d 0 * 0.25
+
+"When two tones are sounded together, a tone of lower frequency is
+frequently heard. Such a tone is called a combination tone.  The most
+commonly heard combination tone occurs at a frequency f2 - f1."
+
+> g_08 =
+>     let f1 = 300
+>         f2 = 300 * (3/2)
+>         f = mce2 (mce2 f1 f2) (abs (f2 - f1))
+>         a = mce2 0.1 (max (sinOsc KR 0.05 0 * 0.1) 0)
+>     in sinOsc AR f 0 * a
diff --git a/Help/UGen/sinOscFB.help.lhs b/Help/UGen/sinOscFB.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sinOscFB.help.lhs
@@ -0,0 +1,28 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "SinOscFB"
+    > Sound.SC3.UGen.DB.ugenSummary "SinOscFB"
+
+> import Sound.SC3 {- hsc3 -}
+
+    {SinOscFB.ar([400,301],MouseX.kr(0,4))*0.1}.play
+
+> g_01 =
+>     let x = mouseX KR 0 4 Linear 0.2
+>     in sinOscFB AR (mce2 400 301) x * 0.1
+
+    {var y = MouseY.kr(10,1000,'exponential')
+    ;var x = MouseX.kr(0.5pi,pi)
+    ;SinOscFB.ar(y,x) * 0.1}.play
+
+> g_02 =
+>     let y = mouseY KR 10 1000 Exponential 0.2
+>         x = mouseX KR (pi/2) pi Linear 0.2
+>     in sinOscFB AR y x * 0.1
+
+    {var y = MouseY.kr(1,1000,'exponential')
+    ;var x = MouseX.kr(0.5pi,pi)
+    ;SinOscFB.ar(100 * SinOscFB.ar(y)+200,x) * 0.1}.play
+
+> g_03 =
+>     let y = mouseY KR 1 1000 Exponential 0.2
+>         x = mouseX KR (pi/2) pi Linear 0.2
+>     in sinOscFB AR (100 * sinOscFB AR y 0 + 200) x * 0.1
diff --git a/Help/UGen/slew.help.lhs b/Help/UGen/slew.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/slew.help.lhs
@@ -0,0 +1,20 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Slew"
+    > Sound.SC3.UGen.DB.ugenSummary "Slew"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = let z = lfPulse AR 800 0 0.5 * 0.1 in mce2 z (slew z 4000 4000)
+>
+> g_02 = let z = saw AR 800 * 0.1 in mce2 z (slew z 400 400)
+
+Drawings
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > let z = lfPulse AR 800 0 0.5
+    > plot_ugen1 0.05 z
+    > plot_ugen1 0.05 (slew z 4000 4000)
+    > plot_ugen1 0.05 (slew z 500 500)
+
+![](sw/hsc3/Help/SVG/slew.0.svg)
+![](sw/hsc3/Help/SVG/slew.1.svg)
+![](sw/hsc3/Help/SVG/slew.2.svg)
diff --git a/Help/UGen/slope.help.lhs b/Help/UGen/slope.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/slope.help.lhs
@@ -0,0 +1,22 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Slope"
+    > Sound.SC3.UGen.DB.ugenSummary "Slope"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> sig f0 =
+>     let a = lfNoise2 'α' AR f0 {- quadratic noise -}
+>         b = slope a {- first derivative, line segments -}
+>         c = slope b {- second derivative, constant segments -}
+>         s = 0.0002
+>     in [a, b * s, c * s * s]
+>
+> g_01 =
+>     let f = mce (sig 2) * 220 + 220
+>     in mix (sinOsc AR f 0 * 0.1)
+
+Drawing
+
+    > import Sound.SC3.Plot {- hsc3-plot -}
+    > plot_ugen 0.05 (mce (sig 2000))
+
+![](sw/hsc3/Help/SVG/slope.0.svg)
diff --git a/Help/UGen/sms.help.lhs b/Help/UGen/sms.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sms.help.lhs
@@ -0,0 +1,12 @@
+> Sound.SC3.UGen.Help.viewSC3Help "SMS"
+> Sound.SC3.UGen.DB.ugenSummary "SMS"
+
+> import Sound.SC3
+
+sine reconstruction left channel, noises on right
+
+> let {z= soundIn 0
+>     ;y = mouseY KR 1 50 Linear 0.2
+>     ;x = mouseX KR 0.5 4 Linear 0.2
+>     ;o = sms z 50 y 8 0.3 x 0 0 0 1 (-1)}
+> in audition (out 0 o)
diff --git a/Help/UGen/softClip.help.lhs b/Help/UGen/softClip.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/softClip.help.lhs
@@ -0,0 +1,9 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.softclip"
+    > :t softClip
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let e = xLine KR 0.1 10 10 RemoveSynth
+>         o = fSinOsc AR 500 0.0
+>     in softClip (o * e) * 0.25
diff --git a/Help/UGen/sos.help.lhs b/Help/UGen/sos.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sos.help.lhs
@@ -0,0 +1,13 @@
+    Sound.SC3.UGen.Help.viewSC3Help "SOS"
+    Sound.SC3.UGen.DB.ugenSummary "SOS"
+
+> import Sound.SC3 {- hsc3 -}
+
+Same as TwoPole
+
+> g_01 =
+>     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 sos (lfSaw AR 200 0 * 0.1) 1 0 0 b1 b2)
diff --git a/Help/UGen/soundIn.help.lhs b/Help/UGen/soundIn.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/soundIn.help.lhs
@@ -0,0 +1,23 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "SoundIn"
+
+soundIn is a composite of the UGens in' and numOutputBuses
+
+> import Sound.SC3 {- hsc3 -}
+
+copy fifth second channel (index 4) to first output channel (index 0)
+
+> gr_01 = out 0 (soundIn 0)
+
+Copy input from 1 & 0 to outputs 0 & 1.
+
+> gr_02 = out 0 (soundIn (mce2 1 0))
+
+io matrix:
+
+  0 1 2 3
+0 *
+1     *
+2   *
+3       *
+
+> gr_03 = out 0 (soundIn (mce [0, 2, 1, 3]))
diff --git a/Help/UGen/specCentroid.help.lhs b/Help/UGen/specCentroid.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/specCentroid.help.lhs
@@ -0,0 +1,14 @@
+> Sound.SC3.UGen.Help.viewSC3Help "SpecCentroid"
+> Sound.SC3.UGen.DB.ugenSummary "SpecCentroid"
+
+> import Sound.SC3
+
+as the number of harmonics increases, the centroid is pushed higher
+> let {f0 = mouseY KR 1000 100 Exponential 0.2
+>     ;nh = mouseX KR 1 100 Exponential 0.2
+>     ;z = blip AR f0 nh
+>     ;f = fft' (localBuf 'α' 2048 1) z
+>     ;c = specCentroid f
+>     ;p = poll' (impulse KR 1 0) c (label "c") 0
+>     ;o = sinOsc AR p 0 * 0.1}
+> in audition (out 0 o)
diff --git a/Help/UGen/specFlatness.help.lhs b/Help/UGen/specFlatness.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/specFlatness.help.lhs
@@ -0,0 +1,13 @@
+> Sound.SC3.UGen.Help.viewSC3Help "SpecFlatness"
+> Sound.SC3.UGen.DB.ugenSummary "SpecFlatness"
+
+> import Sound.SC3
+
+> let {z = soundIn 4
+>     ;g = 1 {- gain, set as required -}
+>     ;a = wAmp KR z 0.05
+>     ;f = fft' (localBuf 'α' 2048 1) z
+>     ;c = poll' 1 (specCentroid f) (label "c") 0
+>     ;w = poll' 1 (specFlatness f) (label "w") 0
+>     ;o = bpf (pinkNoise 'a' AR) c w * a * g}
+> in audition (out 0 o)
diff --git a/Help/UGen/splay.help.lhs b/Help/UGen/splay.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/splay.help.lhs
@@ -0,0 +1,60 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Splay"
+
+splay is a composite UGen, arguments are:
+inArray spread=1 level=1 center=0 levelComp=true
+
+> import Sound.SC3 {- hsc3 -}
+
+mouse control
+
+> g_01 =
+>     let i = 6
+>         r = map (\e -> rand e 10 20) (take i ['α'..])
+>         n = lfNoise2 'β' KR (mce r)
+>         x = mouseX KR (-1) 1 Linear 0.1
+>         y = mouseY KR 1 0 Linear 0.1
+>         ci = constant . fromIntegral
+>         f = mce [1 .. ci i] + 3 * 100
+>         o = sinOsc AR (n * 200 + f) 0
+>     in splay o y 0.2 x True
+
+n_set control
+
+> g_02 =
+>     let i = 10
+>         s = control KR "spread" 1
+>         l = control KR "level" 0.2
+>         c = control KR "center" 0
+>         r = map (\e -> rand e 10 20) (take i ['α'..])
+>         ci = constant . fromIntegral
+>         f = mce [1 .. ci i] + 3 * 100
+>         n = lfNoise2 'β' KR (mce r) * 200 + f
+>     in splay (sinOsc AR n 0) s l c True
+
+full stereo
+
+    > withSC3 (send (n_set (-1) [("spread",1),("center",0)]))
+
+less wide
+
+    > withSC3 (send (n_set (-1) [("spread",0.5),("center",0)]))
+
+mono center
+
+    > withSC3 (send (n_set (-1) [("spread",0),("center",0)]))
+
+from center to right
+
+    > withSC3 (send (n_set (-1) [("spread",0.5),("center",0.5)]))
+
+all left
+
+    > withSC3 (send (n_set (-1) [("spread",0),("center",-1)]))
+
+single channel input
+
+> g_03 =
+>     let x = mouseX KR (-1) 1 Linear 0.1
+>         y = mouseY KR 1 0 Linear 0.1
+>         o = sinOsc AR (lfNoise2 'α' KR 6 * 9 + 440) 0 * 0.1
+>     in splay o y 0.2 x True
diff --git a/Help/UGen/squiz.help.lhs b/Help/UGen/squiz.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/squiz.help.lhs
@@ -0,0 +1,27 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Squiz"
+> Sound.SC3.UGen.DB.ugenSummary "Squiz"
+
+> import Sound.SC3
+
+Squiz of sin oscillator
+
+> let {o = sinOsc AR 440 0
+>     ;x = mouseX KR 1 10 Exponential 0.2
+>     ;y = mouseY KR 1 10 Linear 0.2
+>     ;s = squiz o x y 0.1 * 0.1}
+> in audition (out 0 s)
+
+Load sound file to buffer zero
+
+> let {fn' = "/home/rohan/data/audio/pf-c5.aif"
+>     ;fn = "/home/rohan/opt/share/SuperCollider/sounds/a11wlk01.wav"}
+> in withSC3 (async (b_allocRead 0 fn 0 0))
+
+Squiz of audio file.
+
+> let {r = bufRateScale KR 0
+>     ;p = playBuf 1 AR 0 (r * 0.5) 1 0 Loop DoNothing
+>     ;x = mouseX KR 1 100 Exponential 0.2
+>     ;y = mouseY KR 1 10 Linear 0.2
+>     ;o = squiz p x y 0.1 * 0.5}
+> in audition (out 0 o)
diff --git a/Help/UGen/stepper.help.lhs b/Help/UGen/stepper.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/stepper.help.lhs
@@ -0,0 +1,42 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Stepper"
+> Sound.SC3.UGen.DB.ugenSummary "Stepper"
+
+> import Sound.SC3
+
+> 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))
+
+Using Stepper and BufRd for sequencing
+
+> let {compose = foldl (flip (.)) id
+>     ;rvb z s =
+>         let f i = let dly = mce [rand (z `joinID` i `joinID` 'α') 0 0.5
+>                                 ,rand (z `joinID` i `joinID` 'β') 0 0.5]
+>                     in allpassN i 0.05 dly (rand i 1.5 2)
+>         in compose (replicate 5 f) s
+>     ;stpr = let {rate = mouseX KR 1.75 2.25 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 =
+>      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 (b_alloc 10 128 1)
+>            ;send (b_setn 10 [(0,n)])}}
+> in withSC3 (stprInit >> play (out 0 stpr))
diff --git a/Help/UGen/stkBowed.help.lhs b/Help/UGen/stkBowed.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/stkBowed.help.lhs
@@ -0,0 +1,8 @@
+> Sound.SC3.UGen.Help.viewSC3Help "StkBowed"
+> Sound.SC3.UGen.DB.ugenSummary "StkBowed"
+
+> import Sound.SC3
+
+no longer working...
+> let g = toggleFF (impulse KR 1 0)
+> in audition (out 0 (stkBowed AR 220 64 64 64 64 64 g 1 1))
diff --git a/Help/UGen/stkFlute.help.lhs b/Help/UGen/stkFlute.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/stkFlute.help.lhs
@@ -0,0 +1,8 @@
+> Sound.SC3.UGen.Help.viewSC3Help "StkFlute"
+> Sound.SC3.UGen.DB.ugenSummary "StkFlute"
+
+> import Sound.SC3
+
+> let { bp = line KR 76 32 3 RemoveSynth
+>     ; ng = line KR 16 64 3 DoNothing }
+> in audition (out 0 (stkFlute AR 400 64 ng 16 16 bp 1))
diff --git a/Help/UGen/stkMandolin.help.lhs b/Help/UGen/stkMandolin.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/stkMandolin.help.lhs
@@ -0,0 +1,24 @@
+> Sound.SC3.UGen.Help.viewSC3Help "StkMandolin"
+> Sound.SC3.UGen.DB.ugenSummary "StkMandolin"
+
+> import Control.Monad
+> import Sound.SC3
+
+requires "../../rawwaves/mand1.raw"
+
+> let {x = mouseX KR 0.25 4 Linear 0.2
+>     ;tr = impulse KR x 0 - 0.5 }
+> in do {mn <- tRandM 54 66 tr
+>       ;[bs, pp, dm, dt, at] <- replicateM 5 (tRandM 0 127 tr)
+>       ;audition (out 0 (stkMandolin AR (midiCPS mn) bs pp dm dt at tr))}
+
+> let {x = mouseX KR 3 16 Linear 0.2
+>     ;t = impulse KR x 0 - 0.5
+>     ;tr = pulseDivider t 6 0 }
+> in do {mn <- tIRandM 54 66 t
+>       ;bs <- tRandM 72 94 tr
+>       ;pp <- tRandM 32 42 tr
+>       ;dm <- tRandM 64 72 tr
+>       ;dt <- tRandM 0 4 tr
+>       ;at <- tRandM 2 8 tr
+>       ;audition (out 0 (stkMandolin AR (midiCPS mn) bs pp dm dt at t))}
diff --git a/Help/UGen/stkModalBar.help.lhs b/Help/UGen/stkModalBar.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/stkModalBar.help.lhs
@@ -0,0 +1,29 @@
+> Sound.SC3.UGen.Help.viewSC3Help "StkModalBar"
+> Sound.SC3.UGen.DB.ugenSummary "StkModalBar"
+
+> import Control.Monad
+> import Sound.SC3
+
+requires "../../rawwaves/marmstk1.raw"
+
+> let {x = mouseX KR 0.25 4 Linear 0.2
+>     ;tr = impulse KR x 0 - 0.5
+>     ;tR = tRand 0 127 tr}
+> in do {i <- tRandM 0 9 tr
+>       ;mn <- tIRandM 25 96 tr
+>       ;[sh,sp,vg,vf,mx,v] <- replicateM 6 tR
+>       ;let s = stkModalBar AR (midiCPS mn) i sh sp vg vf mx v tr
+>        in audition (out 0 s)}
+
+> let {x = mouseX KR 1 6 Linear 0.2
+>     ;t = impulse KR x 0 - 0.5
+>     ;tr = pulseDivider t 6 0}
+> in do {mn <- tIRandM 52 64 t
+>       ;sh <- tRandM 4 8 tr
+>       ;sp <- tRandM 54 68 tr
+>       ;vg <- tRandM 66 98 tr
+>       ;vf <- tRandM 4 12 tr
+>       ;mx <- tRandM 0 1 tr
+>       ;v <- tRand 16 48 tr
+>       ;let s = stkModalBar AR (midiCPS mn) 1 sh sp vg vf mx v t
+>        in audition (out 0 s)}
diff --git a/Help/UGen/stkShakers.help.lhs b/Help/UGen/stkShakers.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/stkShakers.help.lhs
@@ -0,0 +1,17 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "StkShakers"
+    > Sound.SC3.UGen.DB.ugenSummary "StkShakers"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+> import Sound.SC3.UGen.External.RDU {- hsc3 -}
+
+> gr_01 =
+>     let x = mouseX KR 0.25 4 Linear 0.2
+>         tr = impulse KR x 0 - 0.5
+>         i = tRand 'α' 0 23 tr
+>         [e,sd,no,rf] = mceChannels (tRandN 4 'β' 0 127 tr)
+>     in stkShakers AR i e sd no rf tr
+
+> gr_02 =
+>     let tr = impulse KR 1 0 - 0.5
+>     in stkShakers AR 4 64 64 64 64 tr
diff --git a/Help/UGen/streson.help.lhs b/Help/UGen/streson.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/streson.help.lhs
@@ -0,0 +1,8 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Streson"
+> Sound.SC3.UGen.DB.ugenSummary "Streson"
+
+> import Sound.SC3
+
+> let {dt = recip (linExp (lfCub KR 0.1 (0.5 * pi)) (-1) 1 280 377)
+>     ;s = streson (lfSaw AR (mce2 220 180) 0 * 0.2) dt 0.9 * 0.3}
+> in audition (out 0 s)
diff --git a/Help/UGen/subsampleOffset.help.lhs b/Help/UGen/subsampleOffset.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/subsampleOffset.help.lhs
@@ -0,0 +1,33 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "SubsampleOffset"
+    > Sound.SC3.UGen.DB.ugenSummary "SubsampleOffset"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+
+Impulse train that can be moved between samples
+
+> sy_01 =
+>     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))
+>     in synthdef "s" (offsetOut 0 r)
+
+Create two pulse trains one sample apart, move one relative to the
+other.  When cursor is at the left, the impulses are adjacent, on the
+right, they are exactly 1 sample apart.  View this with an
+oscilloscope.
+
+> run s = do
+>       {_ <- async (d_recv s)
+>       ;t <- time
+>       ;sr <- serverSampleRateActual
+>       ;let {t' = t + 0.2
+>            ;dt = 1 / sr
+>            ;m n = s_new "s" (-1) AddToTail 1 [("a", n)]}
+>        in do {sendBundle (bundle t' [m 3])
+>              ;sendBundle (bundle (t' + dt) [m 0]) }}
+
+   > withSC3 (run sy_01)
diff --git a/Help/UGen/sum3.help.lhs b/Help/UGen/sum3.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sum3.help.lhs
@@ -0,0 +1,6 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Sum3"
+    > Sound.SC3.UGen.DB.ugenSummary "Sum3"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = sum3 (sinOsc AR 440 0) (sinOsc AR 441 0) (sinOsc AR 442 0) * 0.1
diff --git a/Help/UGen/sum4.help.lhs b/Help/UGen/sum4.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sum4.help.lhs
@@ -0,0 +1,6 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Sum4"
+    > Sound.SC3.UGen.DB.ugenSummary "Sum4"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 = sum4 (sinOsc AR 440 0) (sinOsc AR 441 0) (sinOsc AR 442 0) (sinOsc AR 443 0) * 0.1
diff --git a/Help/UGen/sumSqr.help.lhs b/Help/UGen/sumSqr.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sumSqr.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.sumsqr"
+    > :t sumSqr
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let a = fSinOsc AR 800 0
+>         b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
+>     in sumSqr a b * 0.125
+
+Written out:
+
+> g_02 =
+>     let a = fSinOsc AR 800 0
+>         b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
+>     in (a * a + b * b) * 0.125
diff --git a/Help/UGen/sweep.help.lhs b/Help/UGen/sweep.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sweep.help.lhs
@@ -0,0 +1,64 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Sweep"
+> Sound.SC3.UGen.DB.ugenSummary "Sweep"
+
+> import Sound.SC3
+
+Using sweep to modulate sine frequency
+
+> 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))
+
+Load audio to buffer
+
+> let fn = "/home/rohan/data/audio/pf-c5.aif"
+> in withSC3 (send (b_allocRead 0 fn 0 0))
+
+Using sweep to index into a buffer
+
+> 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
+
+> let {n = lfNoise0 'α' KR 15
+>     ;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
+>     ;p = sweep t (bufSampleRate KR 0 * r)}
+> in audition (out 0 (bufRdL 1 AR 0 p NoLoop))
+
+f0 (sc-users, 2012-02-09)
+
+> let {lf = range 0.01 1.25 (lfNoise2 'α' KR 1)
+>     ;du = duty AR lf 0 DoNothing lf
+>     ;tr = abs (hpz1 du) >* 0
+>     ;ph = sweep tr (1/du)
+>     ;fr = linExp ph 0 1 400 800
+>     ;os = sinOsc AR fr 0 * 0.2}
+> in audition (out 0 os)
+
+line segments, set start & end values, transition time and trigger.
+continues past end point if not re-triggered.
+
+> let {tr = tr_control "tr" 0
+>     ;st = control KR "st" 440
+>     ;en = control KR "en" 880
+>     ;tm = control KR "tm" 2
+>     ;rt = ((en - st) / tm)
+>     ;sw = sweep tr rt + st}
+> in audition (out 0 (sinOsc AR sw 0 * 0.2))
+
+> withSC3 (send (n_set (-1) [("st",660),("en",550),("tm",4),("tr",1)]))
+> withSC3 (send (n_set (-1) [("st",110),("en",990),("tm",1),("tr",1)]))
diff --git a/Help/UGen/switchDelay.help.lhs b/Help/UGen/switchDelay.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/switchDelay.help.lhs
@@ -0,0 +1,13 @@
+> Sound.SC3.UGen.Help.viewSC3Help "SwitchDelay"
+> Sound.SC3.UGen.DB.ugenSummary "SwitchDelay"
+
+> import Sound.SC3
+
+simple feedback delay
+> audition (out 0 (switchDelay (soundIn 4) 1 1 1 0.99 20))
+
+change the buffer read pointer periodically.
+> let {ix = stepper (impulse KR 0.5 0) 0 0 3 1 0
+>     ;dt = select ix (mce [0.02,0.1,0.725,0.25])
+>     ;sd = switchDelay (soundIn 4) 1 1 dt 0.99 20}
+> in audition (out 0 sd)
diff --git a/Help/UGen/syncSaw.help.lhs b/Help/UGen/syncSaw.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/syncSaw.help.lhs
@@ -0,0 +1,15 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "SyncSaw"
+    > Sound.SC3.UGen.DB.ugenSummary "SyncSaw"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let f = line KR 100 800 12 RemoveSynth
+>     in syncSaw AR 100 f * 0.1
+
+Mouse control
+
+> g_02 =
+>     let sy_f = mouseY KR 80 220 Exponential 0.2
+>         sw_f = sy_f * mouseX KR 1 3 Linear 0.2
+>     in syncSaw AR sy_f sw_f * 0.1
diff --git a/Help/UGen/t2K.help.lhs b/Help/UGen/t2K.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/t2K.help.lhs
@@ -0,0 +1,22 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "T2K"
+    > Sound.SC3.UGen.DB.ugenSummary "T2K"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let tr = impulse KR (mouseX KR 1 100 Exponential 0.2) 0
+>     in ringz (t2A tr 0) 800 0.01 * 0.4
+
+compare with K2A (oscilloscope)
+
+> g_02 =
+>     let tr = impulse KR 200 0
+>     in lag (mce2 (t2A tr 0) (k2A tr)) 0.001
+
+removing jitter by randomising offset (C-cC-a at g_03)
+
+> g_03 =
+>     let tr = impulse KR (mouseX KR 1 100 Exponential 0.2) 0
+>         o = range 0 (blockSize - 1) (whiteNoise 'α' KR)
+>     in ringz (t2A tr o) 880 0.1 * 0.4
+
diff --git a/Help/UGen/tBetaRand.help.lhs b/Help/UGen/tBetaRand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tBetaRand.help.lhs
@@ -0,0 +1,19 @@
+    Sound.SC3.UGen.Help.viewSC3Help "TBetaRand"
+    Sound.SC3.UGen.DB.ugenSummary "TBetaRand"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+
+> g_01 =
+>     let t = dust 'α' KR 10
+>         f = tBetaRand 'β' 300 3000 0.1 0.1 t
+>     in sinOsc AR f 0 * 0.1
+
+mouse control of parameters
+
+> g_02 =
+>     let t = dust 'α' KR 10
+>         p1 = mouseX KR 1 5 Linear 0.2
+>         p2 = mouseY KR 1 5 Linear 0.2
+>         f = tBetaRand 'β' 300 3000 p1 p2 t
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/tBrownRand.help.lhs b/Help/UGen/tBrownRand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tBrownRand.help.lhs
@@ -0,0 +1,19 @@
+    Sound.SC3.UGen.Help.viewSC3Help "TBrownRand"
+    Sound.SC3.UGen.DB.ugenSummary "TBrownRand"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+
+> g_01 =
+>     let t = dust 'α' KR 10
+>         dist = mouseX KR 0 5 Linear 0.2
+>         f = tBrownRand 'β' 300 3000 1 dist t
+>     in sinOsc AR f 0 * 0.1
+
+> g_02 =
+>     let t = dust 'α' KR 10
+>         n = tBrownRand 'β' 0 1 0.2 0 t
+>         f = linExp n 0 1 300 3000
+>         o = sinOsc AR f 0
+>         l = tBrownRand 'γ' (-1) 1 1 4 t
+>     in pan2 o l 0.1
diff --git a/Help/UGen/tChoose.help.lhs b/Help/UGen/tChoose.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tChoose.help.lhs
@@ -0,0 +1,16 @@
+    Sound.SC3.UGen.Help.viewSC3Help "TChoose"
+    :t tChoose
+
+tChoose is a composite of tIRand and select.
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let x = mouseX KR 1 1000 Exponential 0.1
+>         t = dust 'a' AR x
+>         f = midiCPS (tIRand 'b' 48 60 t)
+>         o = let a = mce [sinOsc AR f 0
+>                         ,saw AR (f * 2)
+>                         ,pulse AR (f * 0.5) 0.1]
+>             in tChoose 'c' t a
+>     in o * 0.1
diff --git a/Help/UGen/tDelay.help.lhs b/Help/UGen/tDelay.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tDelay.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "TDelay"
+    Sound.SC3.UGen.DB.ugenSummary "TDelay"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let z = impulse AR 2 0
+>         z' = tDelay z 0.5
+>         o = sinOsc AR 440 0 * 0.1
+>     in mce [z * 0.1,toggleFF z' * o]
diff --git a/Help/UGen/tDuty.help.lhs b/Help/UGen/tDuty.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tDuty.help.lhs
@@ -0,0 +1,46 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "TDuty"
+    > Sound.SC3.UGen.DB.ugenSummary "TDuty"
+
+> import Data.List {- base -}
+> import Sound.SC3 {- hsc3 -}
+
+Play a little rhythm
+
+> g_01 =
+>     let d = dseq 'α' dinf (mce [0.1, 0.2, 0.4, 0.3])
+>     in tDuty AR d 0 DoNothing 1 0
+
+Amplitude changes
+
+> g_02 =
+>     let 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])
+>     in ringz (tDuty AR d0 0 DoNothing d1 1) 1000 0.1
+
+Mouse control.
+
+> g_03 =
+>     let d = dseq 'α' dinf (mce [0.1, 0.4, 0.01, 0.5, 1.0])
+>         x = mouseX KR 0.003 1 Exponential 0.1
+>     in ringz (tDuty AR x 0 DoNothing d 1) 1000 0.1 * 0.5
+
+Note that the 440 is the shorter pitch, since gap is set to false
+
+> g_04 =
+>     let d0 = dser 'α' 12 (mce [0.1, 0.3])
+>         d1 = dser 'β' 12 (mce [440, 880])
+>         t = tDuty AR d0 0 RemoveSynth d1 0
+>     in sinOsc AR (latch t t) 0 * 0.1
+
+Abstraction
+
+> g_05 =
+>     let bp n d act = let (e,t) = unzip d
+>                          mk z l = dser z n (mce l)
+>                          sq = tDuty AR (mk 'α' t) 0 act (mk 'β' e) 0
+>                      in latch sq sq
+>         bp' d = bp (genericLength d) d
+>         tm m = let f (e,t) = (e,t * m) in map f
+>         f1 = midiCPS (bp 35 (tm 0.125 [(60,1),(63,1),(67,2),(68,1),(62,1)]) RemoveSynth)
+>         f2 = midiCPS (bp' [(60,1),(63,0.5),(67,0.5),(68,1),(62,1)] DoNothing)
+>     in sinOsc AR (mce2 f1 f2) 0 * 0.1
diff --git a/Help/UGen/tExpRand.help.lhs b/Help/UGen/tExpRand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tExpRand.help.lhs
@@ -0,0 +1,9 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "TExpRand"
+    > Sound.SC3.UGen.DB.ugenSummary "TExpRand"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 :: UId m => m UGen
+> g_01 = do
+>  f <- tExpRandM 300.0 3000.0 =<< dustM KR 10
+>  return (sinOsc AR f 0 * 0.1)
diff --git a/Help/UGen/tGaussRand.help.lhs b/Help/UGen/tGaussRand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tGaussRand.help.lhs
@@ -0,0 +1,21 @@
+    Sound.SC3.UGen.Help.viewSC3Help "TGaussRand"
+    Sound.SC3.UGen.DB.ugenSummary "TGaussRand"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+
+> g_01 =
+>     let t = dust 'α' KR 10
+>         f = tGaussRand 'β' 300 3000 t
+>         o = sinOsc AR f 0
+>         l = tGaussRand 'γ' (-1) 1 t
+>     in  pan2 o l 0.1
+
+compare to tRand
+
+> g_02 =
+>     let t = dust 'α' KR 10
+>         f = tRand 'β' 300 3000 t
+>         o = sinOsc AR f 0
+>         l = tRand 'γ' (-1) 1 t
+>     in pan2 o l 0.1
diff --git a/Help/UGen/tGrains.help.lhs b/Help/UGen/tGrains.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tGrains.help.lhs
@@ -0,0 +1,56 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "TGrains"
+    > Sound.SC3.UGen.DB.ugenSummary "TGrains"
+
+> import Sound.SC3 {- hsc3 -}
+
+Load audio (#10) data
+
+    > let fn = "/home/rohan/data/audio/pf-c5.aif"
+    > withSC3 (async (b_allocRead 10 fn 0 0))
+
+Mouse control
+
+> g_01 =
+>     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 tGrains 2 tr 10 1 ctr (4 / tRate) 0 0.25 2
+
+> g_02 =
+>     let b = 10
+>         rt = mouseY KR 8 120 Exponential 0.1
+>         dur = 4 / rt
+>         clk = dust 'α' AR rt
+>         r = tRand 'β' 0 0.01 clk
+>         pan = whiteNoise 'γ' KR * 0.6
+>         x = mouseX KR 0 (bufDur KR b) Linear 0.1
+>         pos = x + r
+>     in tGrains 2 clk b 1 pos dur pan 0.25 2
+
+> g_03 =
+>     let b = 10
+>         rt = mouseY KR 2 120 Exponential 0.1
+>         dur = 1.2 / rt
+>         clk = impulse AR rt 0
+>         pos = mouseX KR 0 (bufDur KR b) Linear 0.1
+>         n0 = whiteNoise 'α' KR
+>         n1 = whiteNoise 'β' KR
+>         rate = shiftLeft 1.2 (roundTo (n0 * 3) 1)
+>     in tGrains 2 clk b rate pos dur (n1 * 0.6) 0.25 2
+
+Demand UGens as inputs (may eventually hang scsynth?)
+
+> g_04 =
+>     let b = 10
+>         rt = mouseY KR 2 100 Linear 0.2
+>         d e = dwhite e 1 0.1 0.2
+>         z e0 e1 = drand e0 1 (mce [dgeom e0 (diwhite e0 1 20 40) 0.1 (1 + d e0)
+>                                   ,dgeom e1 (diwhite e1 1 20 40) 1 (1 - d e1)])
+>         clk = impulse AR rt 0
+>         dsq e xs = dseq e dinf (mce xs)
+>         rate = dsq 'α' [1,1,z 'β' 'γ',0.5,0.5,0.2,0.1,0.1,0.1,0.1] * 2 + 1
+>         pos = dsq 'δ' (take 8 (zipWith z ['ε'..] ['ζ'..]))
+>         dur = dsq 'η' [1,d 'θ',1,z 'ι' 'κ',0.5,0.5,0.1,z 'λ' 'μ'] * 2 / rt
+>         pan = dsq 'ν' [1,1,1,0.5,0.2,0.1,0,0,0] * 2 - 1
+>         amp = dsq 'ξ' [1,0,z 'ο' 'π',0,2,1,1,0.1,0.1]
+>     in tGrains 2 clk b rate pos dur pan amp 2
diff --git a/Help/UGen/tIRand.help.lhs b/Help/UGen/tIRand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tIRand.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "TIRand"
+    > Sound.SC3.UGen.DB.ugenSummary "TIRand"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 :: UId m => m UGen
+> g_01 = do
+>   l <- tIRandM (-1) 1 =<< dustM KR 10
+>   n <- pinkNoiseM AR
+>   return (pan2 (n * 0.1) l 1)
+
+> g_02 :: UId m => m UGen
+> g_02 = do
+>   n <- tIRandM 4 12 =<< dustM KR 10
+>   let f = n * 150 + (mce [0,1])
+>   return (sinOsc AR f 0 * 0.1)
diff --git a/Help/UGen/tRand.help.lhs b/Help/UGen/tRand.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tRand.help.lhs
@@ -0,0 +1,16 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "TRand"
+    > Sound.SC3.UGen.DB.ugenSummary "TRand"
+
+> import Sound.SC3 {- hsc3 -}
+
+> gr_01 =
+>     let t = dust 'α' KR (mce2 5 12)
+>         f = tRand 'β' (mce2 200 1600) (mce2 500 3000) t
+>     in sinOsc AR f 0 * 0.2
+
+> gr_02_m = do
+>   t <- dustM KR (mce2 5 12)
+>   f <- tRandM (mce2 200 1600) (mce2 500 3000) t
+>   return (sinOsc AR f 0 * 0.2)
+
+> gr_02 = uid_st_eval gr_02_m
diff --git a/Help/UGen/tWindex.help.lhs b/Help/UGen/tWindex.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tWindex.help.lhs
@@ -0,0 +1,20 @@
+    Sound.SC3.UGen.Help.viewSC3Help "TWindex"
+    Sound.SC3.UGen.DB.ugenSummary "TWindex"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let p = mce [1/5, 2/5, 2/5]
+>         a = mce [400, 500, 600]
+>         t = impulse KR 6 0
+>         i = tWindex 'α' t 0 p
+>     in sinOsc AR (select i  a) 0 * 0.1
+
+Modulating probability values
+
+> g_02 =
+>     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
+>         i = tWindex 'α' t 1 p
+>     in sinOsc AR (select i a) 0 * 0.1
diff --git a/Help/UGen/tartini.help.lhs b/Help/UGen/tartini.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tartini.help.lhs
@@ -0,0 +1,21 @@
+> Sound.SC3.UGen.Help.viewSC3Help "Tartini"
+> Sound.SC3.UGen.DB.ugenSummary "Tartini"
+
+> import Sound.SC3
+
+Comparison of input frequency (x) and tracked oscillator frequency (f).
+
+> let {x = mouseX KR 440 880 Exponential 0.1
+>     ;o = lfSaw AR x 0 * 0.05 {- sinOsc AR x 0 * 0.1 -}
+>     ;[f,e] = mceChannels (tartini KR o 0.2 2048 0 1024 0.5)
+>     ;r = sinOsc AR f 0 * 0.1
+>     ;t = impulse KR 4 0
+>     ;pf = poll t f (label "f") 0
+>     ;px = poll t x (label "x") 0}
+> in audition (mrg [out 0 (mce2 o r),pf,px])
+
+Fast test of live pitch tracking, not careful with amplitude of input
+
+> let {z = soundIn 4
+>     ;[f,e] = mceChannels (tartini KR z 0.2 2048 0 1024 0.5)}
+> in audition (out 0 (saw AR f * 0.05 * e))
diff --git a/Help/UGen/thresh.help.lhs b/Help/UGen/thresh.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/thresh.help.lhs
@@ -0,0 +1,8 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.thresh"
+    > :t thresh
+
+> import Sound.SC3 {- hsc3 -}
+
+low-rent gate
+
+> g_01 = let n = lfNoise0 'α' AR 50 * 0.5 in thresh n 0.45
diff --git a/Help/UGen/timer.help.lhs b/Help/UGen/timer.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/timer.help.lhs
@@ -0,0 +1,8 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Timer"
+    Sound.SC3.UGen.DB.ugenSummary "Timer"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let t = impulse KR (mouseX KR 0.5 20 Exponential 0.1) 0
+>     in sinOsc AR (timer t * 500 + 500) 0 * 0.2
diff --git a/Help/UGen/toggleFF.help.lhs b/Help/UGen/toggleFF.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/toggleFF.help.lhs
@@ -0,0 +1,9 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "ToggleFF"
+    > Sound.SC3.UGen.DB.ugenSummary "ToggleFF"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let tr = dust 'α' AR (xLine KR 1 1000 60 DoNothing)
+>         fr = toggleFF tr * 400 + 800
+>     in sinOsc AR fr 0 * 0.1
diff --git a/Help/UGen/tpv.help.lhs b/Help/UGen/tpv.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tpv.help.lhs
@@ -0,0 +1,28 @@
+    Sound.SC3.UGen.Help.viewSC3Help "TPV"
+    Sound.SC3.UGen.DB.ugenSummary "TPV"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+
+> fft_sz = 2048::Int
+> hop_sz = fft_sz `div` 2
+> fn_0 = "/home/rohan/data/audio/pf-c5.snd"
+> fn_1 = "/home/rohan/data/audio/material/tyndall/var/talking-fragments/0001.WAV"
+> tpv' b i = tpv (fft b i 0.5 1 1 0) (constant fft_sz) (constant hop_sz)
+
+    > withSC3 (do {_ <- async (b_alloc 0 fft_sz 1)
+    >             ;async (b_allocRead 1 fn_1 0 0)})
+
+> g_01 =
+>     let i = playBuf 1 AR 1 (bufRateScale KR 1) 1 0 Loop DoNothing
+>         x = mouseX KR 1 70 Linear 0.1
+>         y = mouseY KR 0.25 3 Linear 0.1
+>         o = tpv' 0 i 70 x y 4 0.2
+>     in mce2 (i * 0.1) o
+
+> g_02 =
+>     let i = playBuf 1 AR 1 (bufRateScale KR 1) 1 0 Loop DoNothing
+>         x = mouseX KR 0.1 100 Linear 0.1
+>         y = mouseY KR (-20) 40 Linear 0.1
+>         o = tpv' 0 i 50 50 1 x (dbAmp y)
+>     in pan2 o 0 1
diff --git a/Help/UGen/trig.help.lhs b/Help/UGen/trig.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/trig.help.lhs
@@ -0,0 +1,9 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Trig"
+    Sound.SC3.UGen.DB.ugenSummary "Trig"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let d = dust 'α' AR 1
+>         o = fSinOsc AR 800 0 * 0.5
+>     in o * trig d 0.2
diff --git a/Help/UGen/trig1.help.lhs b/Help/UGen/trig1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/trig1.help.lhs
@@ -0,0 +1,9 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Trig1"
+    Sound.SC3.UGen.DB.ugenSummary "Trig1"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let d = dust 'α' AR 1
+>         o = fSinOsc AR 800 0 * 0.2
+>     in o * trig1 d 0.2
diff --git a/Help/UGen/trigControl.help.lhs b/Help/UGen/trigControl.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/trigControl.help.lhs
@@ -0,0 +1,37 @@
+> import Sound.SC3 {- hsc3 -}
+
+Graph with the three types of non-audio controls.
+
+> g_01 =
+>     let freq = control KR "freq" 440
+>         phase = control IR "phase" 0
+>         gate' = tr_control "gate" 1
+>         amp = control KR "amp" 0.1
+>         e = envGen KR gate' amp 0 1 DoNothing (envASR 0.01 0.1 1 EnvLin)
+>     in sinOsc AR freq phase * e
+
+Make a graph drawing
+
+    > import Sound.SC3.UGen.Dot {- hsc3-ugen -}
+    > draw (out 0 g_01)
+
+Listen
+
+    > audition_at (10,AddToHead,1,[]) (out 0 g_01)
+
+Set frequency and the trigger gate.
+
+    > withSC3 (send (n_set1 10 "freq" 2200))
+    > withSC3 (send (n_set1 10 "gate" 1))
+
+Make a control rate graph to write freq and gate values.
+
+> g_02 = mce2 (tRand 'α' 220 2200 (dust 'β' KR 1)) (dust 'γ' KR 3)
+
+Add it _before_ the node it will map to, the trigger is only on the bus for the current cycle.
+
+    > audition_at (-1,AddBefore,10,[]) (out 0 g_02)
+
+Map the control values at the audio graph.
+
+    > withSC3 (send (n_map 10 [("freq",0),("gate",1)]))
diff --git a/Help/UGen/twChoose.help.lhs b/Help/UGen/twChoose.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/twChoose.help.lhs
@@ -0,0 +1,15 @@
+    Sound.SC3.UGen.Help.viewSC3Help "TWChoose"
+
+tWChoose is a composite of tWindex and select
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let x = mouseX KR 1 1000 Exponential 0.1
+>         d = dust 'α' AR x
+>         a = mce [sinOsc AR 220 0
+>                 ,saw AR 440
+>                 ,pulse AR 110 0.1]
+>         w = mce [0.5, 0.35, 0.15]
+>         o = tWChoose 'β' d a w 0
+>     in o * 0.1
diff --git a/Help/UGen/twoPole.help.lhs b/Help/UGen/twoPole.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/twoPole.help.lhs
@@ -0,0 +1,13 @@
+    Sound.SC3.UGen.Help.viewSC3Help "TwoPole"
+    Sound.SC3.UGen.DB.ugenSummary "TwoPole"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let n = whiteNoise 'α' AR
+>     in twoPole (n * 0.005) 2000 0.95
+
+> g_02 =
+>     let n = whiteNoise 'α' AR
+>         f = xLine KR 800 8000 8 RemoveSynth
+>     in twoPole (n * 0.005) f 0.95
diff --git a/Help/UGen/twoZero.help.lhs b/Help/UGen/twoZero.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/twoZero.help.lhs
@@ -0,0 +1,9 @@
+    Sound.SC3.UGen.Help.viewSC3Help "TwoZero"
+    Sound.SC3.UGen.DB.ugenSummary "TwoZero"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let n = whiteNoise 'α' AR
+>         f = xLine KR 20 20000 8 RemoveSynth
+>     in twoZero (n * 0.125) f 1
diff --git a/Help/UGen/vDiskIn.help.lhs b/Help/UGen/vDiskIn.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/vDiskIn.help.lhs
@@ -0,0 +1,15 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "VDiskIn"
+    > Sound.SC3.UGen.DB.ugenSummary "VDiskIn"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> fn_01 = "/home/rohan/data/audio/pf-c5.snd"
+> nc_01 = 1
+> msg_01 = [b_alloc 0 8192 nc_01,b_read 0 fn_01 0 (-1) 0 True]
+> msg_02 = [b_close 0,b_free 0]
+
+    > withSC3 (mapM_ async msg_01)
+
+> g_01 = vDiskIn nc_01 0 (sinOsc KR 0.25 0 * 0.25 + 1) Loop 0
+
+    > withSC3 (mapM_ async msg_02)
diff --git a/Help/UGen/vOsc.help.lhs b/Help/UGen/vOsc.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/vOsc.help.lhs
@@ -0,0 +1,35 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "VOsc"
+    > Sound.SC3.UGen.DB.ugenSummary "VOsc"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+
+Allocate and fill tables 0 to 7.
+
+> square a = a * a
+> bf = [Normalise,Wavetable,Clear]
+> gen_harm i =
+>     let n = square (i + 1)
+>         f j = square ((n - j) / n)
+>     in map f [0 .. n - 1]
+> gen_setup i =
+>     let i' = fromIntegral i
+>     in (b_alloc i 1024 1,b_gen_sine1 i bf (gen_harm i'))
+> run_setup (p,q) = (async p >> sendMessage q)
+
+    > withSC3 (mapM_ (run_setup . gen_setup) [0 .. 7])
+
+Oscillator at buffers 0 through 7, mouse selects buffer.
+
+> g_01 =
+>     let x = mouseX KR 0 7 Linear 0.1
+>         y = mouseY KR 0.01 0.2 Exponential 0.2
+>     in vOsc AR x (mce [120, 121]) 0 * y
+
+Reallocate buffers while oscillator is running.
+
+    > import Sound.SC3.Lang.Random.IO {- hsc3-lang -}
+    >
+    > let resetTable i = do {h <- nrrand 12 0 1
+    >                        ;sendMessage (b_gen_sine1 i bf h)}
+    > in withSC3 (mapM_ resetTable [0 .. 7])
diff --git a/Help/UGen/vOsc3.help.lhs b/Help/UGen/vOsc3.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/vOsc3.help.lhs
@@ -0,0 +1,15 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "VOsc3"
+    > Sound.SC3.UGen.DB.ugenSummary "VOsc3"
+
+> import Sound.SC3 {- hsc3 -}
+
+see vOsc help for code to allocate and fill tables 0 to 7...
+
+oscillator at buffers 0 through 7, mouse selects buffer.
+
+> g_01 =
+>     let x = mouseX KR 0 7 Linear 0.1
+>         y = mouseY KR 0.01 0.2 Exponential 0.2
+>         o1 = vOsc3 AR x 120 121 129
+>         o2 = vOsc3 AR x 119 123 127
+>     in mce2 o1 o2 * y
diff --git a/Help/UGen/varLag.help.lhs b/Help/UGen/varLag.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/varLag.help.lhs
@@ -0,0 +1,19 @@
+    Sound.SC3.UGen.Help.viewSC3Help "VarLag"
+    Sound.SC3.UGen.DB.ugenSummary "VarLag"
+
+Note: VarLag at sclang is a composite UGen, at hsc3 it's a direct
+binding to the underlying UGen.
+
+> import Sound.SC3 {- hsc3 -}
+
+used to lag pitch
+
+> g_01 =
+>     let x = mouseX KR 220 440 Linear 0.2
+>     in sinOsc AR (mce [x, varLag x 1 0 5 x]) 0 * 0.1
+
+compare to lag UGen
+
+> g_02 =
+>     let x = mouseX KR 220 440 Linear 0.2
+>     in sinOsc AR (mce [x, lag x 1]) 0 * 0.1
diff --git a/Help/UGen/varSaw.help.lhs b/Help/UGen/varSaw.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/varSaw.help.lhs
@@ -0,0 +1,30 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "VarSaw"
+    > Sound.SC3.UGen.DB.ugenSummary "VarSaw"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let f = lfPulse KR (mce2 3 3.03) 0 0.3 * 200 + 200
+>         w = linLin (lfTri KR 1 0) (-1) 1 0 1
+>     in varSaw AR f 0 w * 0.1
+
+Compare with lfPulse at AR
+
+> g_02 =
+>     let f = lfPulse KR 3 0 0.3 * 200 + 200
+>     in mce [varSaw AR f 0 0.2
+>            ,lfPulse AR f 0 0.2] * 0.1
+
+per-note width modulation
+
+> g_03 =
+>     let d = linLin (lfNoise2 'α' KR 0.1) (-1) 1 0.15 0.5
+>         t = impulse AR (1 / d) 0
+>         w0 = tRand 'β' 0 0.35 t
+>         w1 = tRand 'γ' 0.65 1 t
+>         w = phasor AR t ((w1 - w0) * sampleDur) w0 w1 0
+>         e = decay2 t 0.1 d
+>         f = midiCPS (tRand 'δ' 36 72 t)
+>         o = varSaw AR f 0 w * e * 0.1
+>         l = tRand 'ε' (-1) 1 t
+>     in pan2 o l 1
diff --git a/Help/UGen/vibrato.help.lhs b/Help/UGen/vibrato.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/vibrato.help.lhs
@@ -0,0 +1,48 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Vibrato"
+    > Sound.SC3.UGen.DB.ugenSummary "Vibrato"
+
+> import Sound.SC3 {- hsc3 -}
+
+vibrato at 1 Hz, note the use of DC.ar
+
+    {SinOsc.ar(Vibrato.ar(DC.ar(400.0),1,0.02))*0.1}.play
+
+> g_01 =
+>     let v = vibrato 'α' AR (dc AR 400) 1 0.02 0 0 0.04 0.1 0
+>     in sinOsc AR v 0 * 0.1
+
+compare: k-rate freq input can be a constant
+
+    {SinOsc.ar(Vibrato.kr(400.0,1,0.02))}.play
+
+> g_02 =
+>     let v = vibrato 'α' KR 400 1 0.02 0 0 0.04 0.1 0
+>     in sinOsc AR v 0 * 0.1
+
+control rate and rateVariation
+
+    {x=MouseX.kr(2.0,100.0)
+    ;y=MouseY.kr(0.0,1.0)
+    ;v=Vibrato.ar(DC.ar(400.0),x,0.1,1.0,1.0,y,0.1)
+    ;SinOsc.ar(v)}.play
+
+> g_03 =
+>     let x = mouseX KR 2 100 Linear 0.2
+>         y = mouseY KR 0 1 Linear 0.2
+>         v = vibrato 'α' AR (dc AR 400) x 0.1 1 1 y 0.1 0
+>     in sinOsc AR v 0 * 0.1
+
+control depth and depthVariation
+
+    {n=LFNoise1.kr(1,3,7)
+    ;x=MouseX.kr(0.0,1.0)
+    ;y=MouseY.kr(0.0,1.0)
+    ;v=Vibrato.ar(DC.ar(400.0),n,x,1.0,1.0,y,0.1)
+    ;SinOsc.ar(v)}.play
+
+> g_04 =
+>     let n = lfNoise1 'α' KR 1 * 3 + 7
+>         x = mouseX KR 0 1 Linear 0.2
+>         y = mouseY KR 0 1 Linear 0.2
+>         v = vibrato 'β' AR (dc AR 400) n x 1 1 y 0.1 0
+>     in sinOsc AR v 0 * 0.1
diff --git a/Help/UGen/vosim.help.lhs b/Help/UGen/vosim.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/vosim.help.lhs
@@ -0,0 +1,31 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "VOSIM"
+    > Sound.SC3.UGen.DB.ugenSummary "VOSIM"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins as E {- hsc3 -}
+
+> gr_00 =
+>     let trg = impulse AR 100 0
+>         frq = mouseX KR 440 880 Exponential 0.2
+>         n_cycles = 3
+>         dcy = 0.1
+>     in E.vosim trg frq n_cycles dcy * 0.25
+
+> gr_01 =
+>     let p = tRand 'α' 0 1 (impulse AR 6 0)
+>         t = impulse AR (9 * ( 1 + ( p >* 0.95))) 0
+>         x = mouseX KR 0.25 2 Linear 0.2
+>         y = mouseY KR 0.25 0.75 Linear 0.2
+>         z = 9
+>         rng i = linLin i (-1) 1
+>         mk_n e = rng (lfNoise2 e KR z) 0.25 2
+>         tR e ll rl = tRand e (mce ll) (mce rl)
+>         f = tR 'β' [40,120,220] [440,990,880] t
+>         n = tR 'γ' [4] [8,16,32] t
+>         d = tR 'δ' [0.2,0.4,0.6] [0.6,0.8,1] t
+>         a = tR 'ε' [0] [0.05,0.15,0.25] t
+>         l = tR 'ζ' [-1] [1] t
+>         xn = mk_n 'η'
+>         yn = mk_n 'θ'
+>         v = E.vosim t (f * x * xn) n (d * y * yn) * a
+>     in pan2 (mix v) l 1
diff --git a/Help/UGen/warp1.help.lhs b/Help/UGen/warp1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/warp1.help.lhs
@@ -0,0 +1,26 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Warp1"
+    > Sound.SC3.UGen.DB.ugenSummary "Warp1"
+
+> import Sound.SC3 {- hsc3 -}
+
+    > let fn = "/home/rohan/data/audio/pf-c5.aif"
+    > withSC3 (async (b_allocRead 10 fn 0 0))
+
+> g_01 =
+>     let p = linLin (lfSaw KR 0.05 0) (-1) 1 0 1
+>         x = mouseX KR 0.5 2 Linear 0.1
+>     in warp1 1 10 p x 0.1 (-1) 8 0.1 2
+
+real-time (delayed) input
+
+    > withSC3 (async (b_alloc 10 8192 1))
+
+> g_02 =
+>     let i = soundIn 4
+>         r = recordBuf AR 10 0 1 0 1 Loop 1 DoNothing i
+>         ph = (8192 / sampleRate) * 2 * pi
+>         p = lfSaw KR (1 / bufDur KR 10) ph * 0.5 + 0.5
+>         x = mouseX KR 0.5 2 Linear 0.2
+>         y = mouseY KR 0.01 0.2 Linear 0.2
+>         w = warp1 1 10 p x 0.1 (-1) 8 y 4
+>     in mrg2 (i + w) r
diff --git a/Help/UGen/waveTerrain.help.lhs b/Help/UGen/waveTerrain.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/waveTerrain.help.lhs
@@ -0,0 +1,78 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "WaveTerrain"
+    > Sound.SC3.UGen.DB.ugenSummary "WaveTerrain"
+
+> import Sound.SC3 {- hsc3 -}
+
+Terrain function
+
+> ter_f (x,y) =
+>     let a = x ** 2
+>         b = abs (sin (10 * y)) ** (1/3)
+>     in 2 * (a + b) - 1
+
+Create terrain given function.
+
+> gen_t z =
+>     let w = 100 {- width -}
+>         h = 50 {- height -}
+>         tk n = take (round n)
+>         xs = tk w [0,1/w ..]
+>         ys = tk h [0,1/h ..]
+>         ix = map (\y -> map (\x -> (x,y)) xs) ys
+>         add_z = map (\(x,y) -> (x,y,z (x,y)))
+>     in concatMap add_z ix
+
+Confirm terrain
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_p3_pt [gen_t ter_f]
+
+Create table.
+
+> tbl' = map (\(_,_,z) -> z) (gen_t ter_f)
+
+Confirm table
+
+    plotTable [tbl']
+
+Send table to scsynth
+
+    withSC3 (async (b_alloc_setn1 0 0 tbl'))
+
+Hear terrain
+
+> gr_01 =
+>     let x' = mouseX KR 1 200 Exponential 0.2
+>         y' = mouseY KR 1 300 Exponential 0.2
+>         x = abs (sinOsc AR x' 0) + lfNoise2 'α' AR 2
+>         y = abs (sinOsc AR y' (pi / 2))
+>         b = 0
+>     in waveTerrain AR b x y 100 50
+
+Alternate terrain function.
+
+> ter_f' (x,y) =
+>     let a = (cos(5 * x + 1.7)) ** 3
+>         b = abs (sin (23 * y)) ** (1/3)
+>     in (a - b)
+
+Free buffer
+
+    withSC3 (async (b_free 0))
+
+Gerate mesh given terrain given function.
+
+> gen_mesh z =
+>     let w = 100 {- width -}
+>         h = 50 {- height -}
+>         tk n = take (round n)
+>         xs = tk w [0,1/w ..]
+>         ys = tk h [0,1/h ..]
+>         ix0 = map (\y -> map (\x -> (x,y)) xs) ys
+>         ix1 = map (\x -> map (\y -> (x,y)) ys) xs
+>         add_z = map (\(x,y) -> (x,y,z (x,y)))
+>     in (map add_z ix0,map add_z ix1)
+
+Confirm terrain mesh
+
+    plot_p3_ln ((\(p,q) -> p ++ q) (gen_mesh ter_f))
diff --git a/Help/UGen/whiteNoise.help.lhs b/Help/UGen/whiteNoise.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/whiteNoise.help.lhs
@@ -0,0 +1,64 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "WhiteNoise"
+    > Sound.SC3.UGen.DB.ugenSummary "WhiteNoise"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = whiteNoise 'α' AR * 0.05
+
+Random filtered noise bursts.
+
+> g_02 =
+>     let n = whiteNoise 'α' AR
+>         t = dust 'β' AR (mce [3, 7])
+>         f = tExpRand 'γ' 20 1800 t
+>         bw = tExpRand 'δ' 0.001 1 t
+>         e = decay2 t 0.01 0.2
+>     in resonz (n * e) f bw
+
+Monadic form of above graph.
+
+> g_03 :: UId m => m UGen
+> g_03 = do
+>   n <- whiteNoiseM AR
+>   t <- dustM AR (mce [3, 7])
+>   f <- tExpRandM 20 1800 t
+>   bw <- tExpRandM 0.001 1 t
+>   let e = decay2 t 0.01 0.2
+>   return (resonz (n * e) f bw)
+
+The same graph again, without using do notation.
+
+> g_04 :: UId m => m UGen
+> g_04 =
+>     whiteNoiseM AR >>= \n ->
+>     dustM AR (mce [3, 7]) >>= \t ->
+>     tExpRandM 20 1800 t >>= \f ->
+>     tExpRandM 0.001 1 t >>= \bw ->
+>     let e = decay2 t 0.01 0.2
+>     in return (resonz (n * e) f bw)
+
+Drawing
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen1 0.01 (whiteNoise 'γ' AR)
+    plot_ugen1 0.05 (lpf (whiteNoise 'γ' AR) 500)
+
+    import Sound.SC3.Plot.FFT {- hsc3-plot -}
+    plot_ugen_fft1 0.1 (whiteNoise 'α' AR)
+
+![](sw/hsc3/Help/SVG/whiteNoise.0.svg)
+![](sw/hsc3/Help/SVG/whiteNoise.1.svg)
+![](sw/hsc3/Help/SVG/whiteNoise.2.svg)
+
+Speaker balance
+
+> g_05 = let n = whiteNoise 'α' AR * 0.1 in mce2 n n
+
+> g_06 =
+>     let x = mouseX KR 0.1 2 Linear 0.2
+>         l = sinOsc KR x 0
+>         n = whiteNoise 'α' AR
+>     in pan2 n l 0.1
+
+> g_07 = hpz1 (whiteNoise 'α' AR * 0.01)
+
diff --git a/Help/UGen/wrapIndex.help.lhs b/Help/UGen/wrapIndex.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/wrapIndex.help.lhs
@@ -0,0 +1,17 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "WrapIndex"
+    > Sound.SC3.UGen.DB.ugenSummary "WrapIndex"
+
+> import Sound.SC3 {- hsc3 -}
+
+    > withSC3 (async (b_alloc_setn1 0 0 [200,300,400,500,600,800]))
+
+> g_01 =
+>     let x = mouseX KR 0 18 Linear 0.1
+>         f = wrapIndex 0 x
+>     in sinOsc AR f 0 * 0.1
+
+> g_02 =
+>     let b = asLocalBuf 'α' [200,300,400,500,600,800]
+>         x = mouseX KR 0 18 Linear 0.1
+>         f = wrapIndex b x
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/wt_FilterScale.help.lhs b/Help/UGen/wt_FilterScale.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/wt_FilterScale.help.lhs
@@ -0,0 +1,13 @@
+    Sound.SC3.UGen.Help.viewSC3Help "WT_FilterScale"
+    Sound.SC3.UGen.DB.ugenSummary "WT_FilterScale"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.Wavelets {- hsc3 -}
+
+> g_01 =
+>     let i = whiteNoise 'α' AR * 0.2
+>         b = localBuf 'β' 2048 1
+>         c = dwt b i 0.5 0 1 0 0
+>         x = mouseX KR (-1) 1 Linear 0.1
+>         c' = wt_FilterScale c x
+>     in pan2 (idwt c' 0 0 0) x 1
diff --git a/Help/UGen/wt_TimeWipe.help.lhs b/Help/UGen/wt_TimeWipe.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/wt_TimeWipe.help.lhs
@@ -0,0 +1,13 @@
+    Sound.SC3.UGen.Help.viewSC3Help "WT_TimeWipe"
+    Sound.SC3.UGen.DB.ugenSummary "WT_TimeWipe"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.Wavelets {- hsc3 -}
+
+> g_01 =
+>     let i = whiteNoise 'α' AR * 0.2
+>         b = localBuf 'β' 2048 1
+>         c = dwt b i 0.5 0 1 0 0
+>         x = mouseX KR 0 1 Linear 0.1
+>         c' = wt_TimeWipe c x
+>     in pan2 (idwt c' 0 0 0) (x * 2 - 1) 1
diff --git a/Help/UGen/xFade2.help.lhs b/Help/UGen/xFade2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/xFade2.help.lhs
@@ -0,0 +1,6 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "XFade2"
+    > Sound.SC3.UGen.DB.ugenSummary "XFade2"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = xFade2 (saw AR 440) (sinOsc AR 440 0) (lfTri KR 0.1 0) 0.1
diff --git a/Help/UGen/xLine.help.lhs b/Help/UGen/xLine.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/xLine.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "XLine"
+    > Sound.SC3.UGen.DB.ugenSummary "XLine"
+
+Note: SC3 reorders mul and add inputs to precede the doneAction input.
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let f = xLine KR 200 17000 10 RemoveSynth
+>     in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/xOut.help.lhs b/Help/UGen/xOut.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/xOut.help.lhs
@@ -0,0 +1,15 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "XOut"
+    > Sound.SC3.UGen.DB.ugenSummary "XOut"
+
+> import Sound.SC3 {- hsc3 -}
+
+Send signal to a bus, crossfading with existing contents.
+
+> g_01 =
+>     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 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/zeroCrossing.help.lhs b/Help/UGen/zeroCrossing.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/zeroCrossing.help.lhs
@@ -0,0 +1,8 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "ZeroCrossing"
+    > Sound.SC3.UGen.DB.ugenSummary "ZeroCrossing"
+
+> import Sound.SC3 {- hsc3 -}
+>
+> g_01 =
+>     let a = sinOsc AR (sinOsc KR 1 0 * 600 + 700) 0 * 0.1
+>     in mce [a, impulse AR (zeroCrossing a) 0 * 0.25]
diff --git a/Help/UGen/zitaRev1.help.lhs b/Help/UGen/zitaRev1.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/zitaRev1.help.lhs
@@ -0,0 +1,35 @@
+faust2supercollider zita_rev1.dsp
+http://kokkinizita.linuxaudio.org/linuxaudio/zita-rev1-doc/quickguide.html
+
+delay, lin,   0.02,    0.1,     0.04
+xover, log,  50.0,  1000.0,   200.0
+rtlow, log,   1.0,     8.0,     3.0
+rtmid, log,   1.0,     8.0,     2.0
+fdamp, log,   1.5e3,  24.0e3,   6.0e3
+eq1fr, log,  40.0,     2.5e3, 160.0
+eq1gn, lin, -15.0,    15.0,     0.0
+eq2fr, log, 160.0,    10.0e3,   2.5e3
+eq2gn, lin, -15.0,    15.0,     0.0
+opmix, lin,   0.0,     1.0,     0.5
+level, lin,  -9.0,     9.0,   -20.0
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.Zita {- hsc3 -}
+
+default settings
+
+> g_01 =
+>     let i = soundIn 0
+>     in zitaRev1 i i 0.04 200 3 2 6000 160 0 2500 0 0.5 (-6)
+
+longer
+
+> g_02 =
+>     let i = soundIn 0
+>     in zitaRev1 i i 0.08 200 6 4 6000 190 (-6) 3500 6 0.5 0
+
+longer still
+
+> g_03 =
+>     let i = soundIn 0
+>     in zitaRev1 i i 0.1 200 6 8 6000 190 (-6) 3500 6 0.5 0
diff --git a/README b/README
--- a/README
+++ b/README
@@ -20,10 +20,17 @@
 - [hsc3-forth](?t=hsc3-forth): FORTH SuperCollider
 - [hsc3-lisp](?t=hsc3-lisp): LISP SuperCollider
 
-The hsc3 interaction environment is written for [GNU][gnu]
-[Emacs][emacs].
+The hsc3 interaction environment ([hsc3.el](?t=hsc3&e=emacs/hsc3.el))
+is written for [GNU][gnu] [Emacs][emacs].
 
-© [rohan drape][rd] and others, 2005-2014, [gpl][gpl].
+## cli
+
+[scsyndef-stat](?t=hsc3&e=md/scsyndef-stat.md),
+[scsyndef-to-hs](?t=hsc3&e=md/scsyndef-to-hs.md),
+[scsynth](?t=hsc3&e=md/scsynth.md),
+[setup](?t=hsc3&e=md/setup.md)
+
+© [rohan drape][rd] and others, 2005-2017, [gpl][gpl].
 with contributions by:
 
 - henning thielemann
@@ -35,7 +42,8 @@
 see the [darcs][darcs] [history](?t=hsc3&q=history) for details
 
 initial announcement:
-[[haskell.org](http://www.haskell.org/pipermail/haskell-cafe/2005-November/012483.html)]
+[[2005-11-29/haskell-cafe](?t=hsc3&e=md/announce.text),
+ [haskell.org](http://www.haskell.org/pipermail/haskell-cafe/2005-November/012483.html)]
 
 [rd]: http://rd.slavepianos.org/
 [hsc3]: http://rd.slavepianos.org/?t=hsc3
diff --git a/Sound/SC3.hs b/Sound/SC3.hs
--- a/Sound/SC3.hs
+++ b/Sound/SC3.hs
@@ -1,8 +1,8 @@
--- | Composite of "Sound.SC3.Server.Monad", "Sound.SC3.UGen" and "Sound.SC3.UGen.Bindings".
+-- | Composite of "Sound.SC3.Common", "Sound.SC3.Server.Monad",
+-- "Sound.SC3.UGen" and "Sound.SC3.UGen.Bindings".
 module Sound.SC3 (module M) where
 
+import Sound.SC3.Common as M
 import Sound.SC3.Server.Monad as M
 import Sound.SC3.UGen as M
-
 import Sound.SC3.UGen.Bindings as M
-
diff --git a/Sound/SC3/Common.hs b/Sound/SC3/Common.hs
--- a/Sound/SC3/Common.hs
+++ b/Sound/SC3/Common.hs
@@ -1,79 +1,6 @@
-module Sound.SC3.Common where
-
-import Data.Char {- base -}
-import Data.List {- base -}
-
--- | Variant of 'reads' requiring exact match.
-reads_exact :: Read a => String -> Maybe a
-reads_exact s =
-    case reads s of
-      [(r,"")] -> Just r
-      _ -> Nothing
-
--- * STRING / CASE
-
--- | CI = Case insensitive, CS = case sensitive.
-data Case_Rule = CI | CS deriving (Eq)
-
--- | Predicates for 'Case_Rule'.
-is_ci,is_cs :: Case_Rule -> Bool
-is_ci = (==) CI
-is_cs = (==) CS
-
--- | String equality with 'Case_Rule'.
---
--- > string_eq CI "lower" "LOWER" == True
-string_eq :: Case_Rule -> String -> String -> Bool
-string_eq cr x y = if is_ci cr then map toLower x == map toLower y else x == y
-
--- | 'rlookup_by' of 'string_eq'.
-rlookup_str :: Case_Rule -> String -> [(a,String)] -> Maybe a
-rlookup_str = rlookup_by . string_eq
-
--- | 'Enum' parser with 'Case_Rule'.
---
--- > parse_enum CI "FALSE" == Just False
-parse_enum :: (Show t,Enum t,Bounded t) => Case_Rule -> String -> Maybe t
-parse_enum cr nm =
-    let u = [minBound .. maxBound]
-        t = zip (map show u) u
-    in lookup_by (string_eq cr) nm t
-
--- * LIST
-
--- | 'lookup' with equality function.
-lookup_by :: (a -> a -> Bool) -> a -> [(a,b)] -> Maybe b
-lookup_by f x = fmap snd . find (f x . fst)
-
--- | Reverse 'lookup' with equality function.
-rlookup_by :: (b -> b -> Bool) -> b -> [(a,b)] -> Maybe a
-rlookup_by f x = fmap fst . find (f x . snd)
-
--- | (prev,cur,next) triples.
---
--- > pcn_triples [1..3] == [(Nothing,1,Just 2),(Just 1,2,Just 3),(Just 2,3,Nothing)]
-pcn_triples :: [a] -> [(Maybe a,a,Maybe a)]
-pcn_triples =
-    let f e l = case l of
-                  e1 : e2 : l' -> (e,e1,Just e2) : f (Just e1) (e2 : l')
-                  [e'] -> [(e,e',Nothing)]
-                  [] -> undefined
-    in f Nothing
-
--- * TUPLES
-
-type T2 a = (a,a)
-type T3 a = (a,a,a)
-type T4 a = (a,a,a,a)
-
--- | 'concatMap' of /f/ at /x/ and /g/ at /y/.
-mk_duples :: (a -> c) -> (b -> c) -> [(a, b)] -> [c]
-mk_duples a b = concatMap (\(x,y) -> [a x, b y])
-
--- | Length prefixed list variant of 'mk_duples'.
-mk_duples_l :: (Int -> c) -> (a -> c) -> (b -> c) -> [(a,[b])] -> [c]
-mk_duples_l i a b = concatMap (\(x,y) -> a x : i (length y) : map b y)
+module Sound.SC3.Common (module M) where
 
--- | 'concatMap' of /f/ at /x/ and /g/ at /y/ and /h/ at /z/.
-mk_triples :: (a -> d) -> (b -> d) -> (c -> d) -> [(a, b, c)] -> [d]
-mk_triples a b c = concatMap (\(x,y,z) -> [a x, b y, c z])
+import Sound.SC3.Common.Buffer as M
+import Sound.SC3.Common.Envelope as M
+import Sound.SC3.Common.Math as M
+import Sound.SC3.Common.Monad as M
diff --git a/Sound/SC3/Common/Buffer.hs b/Sound/SC3/Common/Buffer.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Buffer.hs
@@ -0,0 +1,184 @@
+-- | Signals & wavetables
+module Sound.SC3.Common.Buffer where
+
+import Data.List {- base -}
+
+import qualified Sound.SC3.Common.Math as S {- hsc3 -}
+
+{- | /z/ ranges from 0 (for /i/) to 1 (for /j/).
+
+> > 1.5.blend(2.0,0.50) == 1.75
+> > 1.5.blend(2.0,0.75) == 1.875
+
+> blend 0.50 1.5 2 == 1.75
+> blend 0.75 1.5 2 == 1.875
+-}
+blend :: Num a => a -> a -> a -> a
+blend z i j = i + (z * (j - i))
+
+-- | Variant of '(!!)' but values for index greater than the size of
+-- the collection will be clipped to the last index.
+clipAt :: Int -> [a] -> a
+clipAt ix c =
+    if ix > length c - 1
+    then last c
+    else c !! ix
+
+-- | 'abs' of '(-)'.
+absdif :: Num a => a -> a -> a
+absdif i j = abs (j - i)
+
+-- | 'blendAt' with @clip@ function as argument.
+blendAtBy :: (Integral i,RealFrac n) => (i -> t -> n) -> n -> t -> n
+blendAtBy f ix c =
+    let m = floor ix
+        m' = fromIntegral m
+    in blend (absdif ix m') (f m c) (f (m + 1) c)
+
+-- | @SequenceableCollection.blendAt@ returns a linearly interpolated
+-- value between the two closest indices.  Inverse operation is
+-- 'indexInBetween'.
+--
+-- > > [2,5,6].blendAt(0.4) == 3.2
+--
+-- > blendAt 0 [2,5,6] == 2
+-- > blendAt 0.4 [2,5,6] == 3.2
+blendAt :: RealFrac a => a -> [a] -> a
+blendAt = blendAtBy clipAt
+
+-- | Resampling function, /n/ is destination length, /r/ is source
+-- length, /f/ is the indexing function, /c/ is the collection.
+resamp1_gen :: (Integral i,RealFrac n) => i -> i -> (i -> t -> n) -> t -> i -> n
+resamp1_gen n r f c =
+    let n' = fromIntegral n
+        fwd = (fromIntegral r - 1) / (n' - 1)
+        gen i = blendAtBy f (fromIntegral i * fwd) c
+    in gen
+
+-- | @SequenceableCollection.resamp1@ returns a new collection of the
+-- desired length, with values resampled evenly-spaced from the
+-- receiver with linear interpolation.
+--
+-- > > [1].resamp1(3) == [1,1,1]
+-- > > [1,2,3,4].resamp1(12)
+-- > > [1,2,3,4].resamp1(3) == [1,2.5,4]
+--
+-- > resamp1 3 [1] == [1,1,1]
+-- > resamp1 12 [1,2,3,4]
+-- > resamp1 3 [1,2,3,4] == [1,2.5,4]
+resamp1 :: RealFrac n => Int -> [n] -> [n]
+resamp1 n c =
+    let gen = resamp1_gen n (length c) clipAt c
+    in map gen [0 .. n - 1]
+
+-- | @ArrayedCollection.normalizeSum@ ensures sum of elements is one.
+--
+-- > > [1,2,3].normalizeSum == [1/6,1/3,0.5]
+-- > normalizeSum [1,2,3] == [1/6,2/6,3/6]
+normalizeSum :: (Fractional a) => [a] -> [a]
+normalizeSum l =
+    let n = sum l
+    in map (/ n) l
+
+-- | Variant that specifies range of input sequence separately.
+normalise_rng :: Fractional n => (n,n) -> (n,n) -> [n] -> [n]
+normalise_rng (il,ir) (l,r) = map (\e -> S.linlin e il ir l r)
+
+-- | @ArrayedCollection.normalize@ returns a new Array with the receiver
+-- items normalized between min and max.
+--
+-- > > [1,2,3].normalize == [0,0.5,1]
+-- > > [1,2,3].normalize(-20,10) == [-20,-5,10]
+--
+-- > normalize 0 1 [1,2,3] == [0,0.5,1]
+-- > normalize (-20) 10 [1,2,3] == [-20,-5,10]
+normalize :: (Fractional n, Ord n) => n -> n -> [n] -> [n]
+normalize l r c = normalise_rng (minimum c,maximum c) (l,r) c
+
+-- | List of 2-tuples of elements at distance (stride) /n/.
+--
+-- > t2_window 3 [1..9] == [(1,2),(4,5),(7,8)]
+t2_window :: Integral i => i -> [t] -> [(t,t)]
+t2_window n x =
+    case x of
+      i:j:_ -> (i,j) : t2_window n (genericDrop n x)
+      _ -> []
+
+-- | List of 2-tuples of adjacent elements.
+--
+-- > t2_adjacent [1..6] == [(1,2),(3,4),(5,6)]
+-- > t2_adjacent [1..5] == [(1,2),(3,4)]
+t2_adjacent :: [t] -> [(t,t)]
+t2_adjacent = t2_window (2::Int)
+
+-- | List of 2-tuples of overlapping elements.
+--
+-- > t2_overlap [1..4] == [(1,2),(2,3),(3,4)]
+t2_overlap :: [b] -> [(b,b)]
+t2_overlap x = zip x (tail x)
+
+-- | Concat of 2-tuples.
+--
+-- > t2_concat (t2_adjacent [1..6]) == [1..6]
+-- > t2_concat (t2_overlap [1..4]) == [1,2,2,3,3,4]
+t2_concat :: [(a,a)] -> [a]
+t2_concat x =
+    case x of
+      [] -> []
+      (i,j):x' -> i : j : t2_concat x'
+
+{- | A Signal is half the size of a Wavetable, each element is the sum
+of two adjacent elements of the Wavetable.
+
+> from_wavetable [-0.5,0.5,0,0.5,1.5,-0.5,1,-0.5] == [0.0,0.5,1.0,0.5]
+> let s = [0,0.5,1,0.5] in from_wavetable (to_wavetable s) == s
+-}
+from_wavetable :: Num n => [n] -> [n]
+from_wavetable = map (uncurry (+)) . t2_adjacent
+
+{- | A Wavetable has /n * 2 + 2/ elements, where /n/ is the number
+of elements of the Signal.  Each signal element /e0/ expands to the
+two elements /(2 * e0 - e1, e1 - e0)/ where /e1/ is the next
+element, or zero at the final element.  Properly wavetables are
+only of power of two element signals.
+
+> > Signal[0,0.5,1,0.5].asWavetable == Wavetable[-0.5,0.5,0,0.5,1.5,-0.5,1,-0.5]
+
+> to_wavetable [0,0.5,1,0.5] == [-0.5,0.5,0,0.5,1.5,-0.5,1,-0.5]
+-}
+to_wavetable :: Num a => [a] -> [a]
+to_wavetable =
+    let f (e0,e1) = (2 * e0 - e1,e1 - e0)
+    in t2_concat . map f . t2_overlap . (++ [0])
+
+{- | Variant of 'sineFill' that gives each component table.
+
+> let t = sineGen 1024 (map recip [1,2,3,5,8,13,21,34,55]) (replicate 9 0)
+> map length t == replicate 9 1024
+
+> import Sound.SC3.Plot
+> plotTable t
+-}
+sineGen :: (Floating n,Enum n) => Int -> [n] -> [n] -> [[n]]
+sineGen n =
+    let incr = (2 * pi) / fromIntegral n
+        ph partial = take n [0,incr * partial ..]
+        f h amp iph = map (\z -> sin (z + iph) * amp) (ph h)
+    in zipWith3 f [1..]
+
+{- | @Signal.*sineFill@ is a table generator.  Frequencies are
+partials, amplitudes and initial phases are as given.  Result is
+normalised.
+
+> let t = let a = [[21,5,34,3,2,13,1,8,55]
+>                 ,[13,8,55,34,5,21,3,1,2]
+>                 ,[55,34,1,3,2,13,5,8,21]]
+>         in map (\amp -> sineFill 1024 (map recip amp) (replicate 9 0)) a
+
+> import Sound.SC3.Plot
+> plotTable t
+-}
+sineFill :: (Ord n,Floating n,Enum n) => Int -> [n] -> [n] -> [n]
+sineFill n amp iph =
+    let t = sineGen n amp iph
+    in normalize (-1) 1 (map sum (transpose t))
diff --git a/Sound/SC3/Common/Buffer/Array.hs b/Sound/SC3/Common/Buffer/Array.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Buffer/Array.hs
@@ -0,0 +1,31 @@
+-- | 'A.Array' variants of "Sound.SC3.Common.Buffer".
+module Sound.SC3.Common.Buffer.Array where
+
+import qualified Data.Array as A {- array -}
+
+import qualified Sound.SC3.Common.Buffer as SC3
+
+-- | 'SC3.clipAt'.
+clipAt :: Int -> A.Array Int a -> a
+clipAt ix c =
+    let (l,r) = A.bounds c
+        f = (A.!) c
+    in if ix < l then f l else if ix > r then f r else f ix
+
+-- | 'C.blendAtBy' of 'clipAt'.
+--
+-- > blendAt 0 (A.listArray (0,2) [2,5,6]) == 2
+-- > blendAt 0.4 (A.listArray (0,2) [2,5,6]) == 3.2
+blendAt :: RealFrac a => a -> A.Array Int a -> a
+blendAt = SC3.blendAtBy clipAt
+
+-- | 'C.resamp1'.
+--
+-- > resamp1 12 (A.listArray (0,3) [1,2,3,4])
+-- > resamp1 3 (A.listArray (0,3) [1,2,3,4]) == A.listArray (0,2) [1,2.5,4]
+resamp1 :: RealFrac n => Int -> A.Array Int n -> A.Array Int n
+resamp1 n c =
+    let (_,r) = A.bounds c
+        gen = SC3.resamp1_gen n (r + 1) clipAt c
+        rs = map gen [0 .. n - 1]
+    in A.listArray (0,n - 1) rs
diff --git a/Sound/SC3/Common/Buffer/Gen.hs b/Sound/SC3/Common/Buffer/Gen.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Buffer/Gen.hs
@@ -0,0 +1,82 @@
+-- | Implementaion of server b_gen routines.
+--
+-- The naming scheme is: _p generates one partial, _l generates a list
+-- of partials, _nrm is the unit normalised form.
+module Sound.SC3.Common.Buffer.Gen where
+
+import Data.List {- base -}
+
+import Sound.SC3.Common.Buffer {- hsc3 -}
+import Sound.SC3.Common.Math {- hsc3 -}
+
+-- | Sum (mix) multiple tables into one.
+sum_l :: Num n => [[n]] -> [n]
+sum_l = map sum . transpose
+
+-- | Unit normalisation.
+nrm_u :: (Fractional n,Ord n) => [n] -> [n]
+nrm_u = normalize (-1) 1
+
+-- * sine1
+
+sine1_p :: (Enum n,Floating n) => Int -> (n,n) -> [n]
+sine1_p n (pfreq,ampl) = sine3_p n (pfreq,ampl,0)
+
+sine1_l :: (Enum n,Floating n) => Int -> [n] -> [[n]]
+sine1_l n ampl = map (sine1_p n) (zip [1..] ampl)
+
+-- > import Sound.SC3.Plot
+-- > plotTable1 (sine1 256 [1,0.95 .. 0.5])
+sine1 :: (Enum n,Floating n) => Int -> [n] -> [n]
+sine1 n = sum_l . sine1_l n
+
+-- > plotTable1 (sine1_nrm 256 [1,0.95 .. 0.5])
+sine1_nrm :: (Enum n,Floating n,Ord n) => Int -> [n] -> [n]
+sine1_nrm n = nrm_u . sine1 n
+
+-- * sine2
+
+sine2_l :: (Enum n,Floating n) => Int -> [(n,n)] -> [[n]]
+sine2_l n = map (sine1_p n)
+
+-- > plotTable1 (sine2 256 (zip [1,2..] [1,0.95 .. 0.5]))
+-- > plotTable1 (sine2 256 (zip [1,1.5 ..] [1,0.95 .. 0.5]))
+sine2 :: (Enum n,Floating n) => Int -> [(n,n)] -> [n]
+sine2 n = sum_l . sine2_l n
+
+sine2_nrm :: (Enum n,Floating n,Ord n) => Int -> [n] -> [n]
+sine2_nrm n = nrm_u . sine1 n
+
+-- * sine3
+
+sine3_p :: (Enum n,Floating n) => Int -> (n,n,n) -> [n]
+sine3_p n (pfreq,ampl,phase) =
+    let incr = (two_pi / (fromIntegral n - 1)) * pfreq
+    in map ((*) ampl . sin) (take n [phase,phase + incr ..])
+
+sine3_l :: (Enum n,Floating n) => Int -> [(n,n,n)] -> [[n]]
+sine3_l n = map (sine3_p n)
+
+-- > plotTable1 (sine3 256 (zip3 [1,1.5 ..] [1,0.95 .. 0.5] [0,pi/7..]))
+sine3 :: (Enum n,Floating n) => Int -> [(n,n,n)] -> [n]
+sine3 n = sum_l . sine3_l n
+
+-- * cheby
+
+{- | Generate Chebyshev waveshaping table, see b_gen_cheby.
+
+> import Sound.SC3.Plot
+> plotTable1 (gen_cheby 256 [1,0,1,1,0,1])
+
+-}
+gen_cheby :: (Enum n, Floating n, Ord n, Integral i) => i -> [n] -> [n]
+gen_cheby n =
+    let acos' x = if x > 1 then 0 else if x < -1 then pi else acos x
+        c k x = cos (k * acos' x)
+        ix = [-1,-1 + (2 / (fromIntegral n - 1)) .. 1]
+        mix = map sum . transpose
+        c_normalize x = let m = maximum (map abs x) in map (* (recip m)) x
+    in c_normalize . mix . map (\(k,a) -> map ((* a) . (c k)) ix) . zip [1..]
+
+cheby :: (Enum n, Floating n, Ord n) => Int -> [n] -> [n]
+cheby = gen_cheby
diff --git a/Sound/SC3/Common/Buffer/Vector.hs b/Sound/SC3/Common/Buffer/Vector.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Buffer/Vector.hs
@@ -0,0 +1,30 @@
+-- | 'V.Vector' variants of "Sound.SC3.Common.Buffer".
+module Sound.SC3.Common.Buffer.Vector where
+
+import qualified Data.Vector as V {- vector -}
+
+import qualified Sound.SC3.Common.Buffer as C {- hsc3 -}
+
+-- | 'C.clipAt'.
+clipAt :: Int -> V.Vector a -> a
+clipAt ix c =
+    let r = V.length c
+        f = (V.!) c
+    in if ix > r - 1 then f (r - 1) else f ix
+
+-- | 'C.blendAtBy' of 'clipAt'.
+--
+-- > blendAt 0 (V.fromList [2,5,6]) == 2
+-- > blendAt 0.4 (V.fromList [2,5,6]) == 3.2
+-- > blendAt 2.1 (V.fromList [2,5,6]) == 6
+blendAt :: RealFrac a => a -> V.Vector a -> a
+blendAt = C.blendAtBy clipAt
+
+-- | 'C.resamp1'.
+--
+-- > resamp1 12 (V.fromList [1,2,3,4])
+-- > resamp1 3 (V.fromList [1,2,3,4]) == V.fromList [1,2.5,4]
+resamp1 :: RealFrac n => Int -> V.Vector n -> V.Vector n
+resamp1 n c =
+    let gen = C.resamp1_gen n (V.length c) clipAt c
+    in V.generate n gen
diff --git a/Sound/SC3/Common/Envelope.hs b/Sound/SC3/Common/Envelope.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Envelope.hs
@@ -0,0 +1,466 @@
+-- | Envelope generators.
+module Sound.SC3.Common.Envelope where
+
+import Data.List {- base -}
+import Data.Maybe {- base -}
+
+import qualified Sound.SC3.Common.Prelude as P
+import qualified Sound.SC3.Common.Math.Interpolate as I
+
+-- * Curve
+
+-- | Envelope curve indicator input.
+data Envelope_Curve a = EnvStep
+                      | EnvLin
+                      | EnvExp
+                      | EnvSin
+                      | EnvWelch -- ^ Note: not implemented at SC3
+                      | EnvNum a
+                      | EnvSqr
+                      | EnvCub
+                      | EnvHold
+                        deriving (Eq, Show)
+
+-- | Envelope curve pair.
+type Envelope_Curve2 a = P.T2 (Envelope_Curve a)
+
+-- | Envelope curve triple.
+type Envelope_Curve3 a = P.T3 (Envelope_Curve a)
+
+-- | Envelope curve quadruple.
+type Envelope_Curve4 a = P.T4 (Envelope_Curve a)
+
+-- | Convert 'Envelope_Curve' to shape value.
+--
+-- > map env_curve_shape [EnvSin,EnvSqr] == [3,6]
+env_curve_shape :: Num a => Envelope_Curve a -> a
+env_curve_shape e =
+    case e of
+      EnvStep -> 0
+      EnvLin -> 1
+      EnvExp -> 2
+      EnvSin -> 3
+      EnvWelch -> 4
+      EnvNum _ -> 5
+      EnvSqr -> 6
+      EnvCub -> 7
+      EnvHold -> 8
+
+-- | The /value/ of 'EnvCurve' is non-zero for 'EnvNum'.
+--
+-- > map env_curve_value [EnvWelch,EnvNum 2] == [0,2]
+env_curve_value :: Num a => Envelope_Curve a -> a
+env_curve_value e =
+    case e of
+      EnvNum u -> u
+      _ -> 0
+
+-- | 'Interpolation_F' of 'Envelope_Curve'.
+env_curve_interpolation_f :: (Ord t, Floating t) => Envelope_Curve t -> I.Interpolation_F t
+env_curve_interpolation_f c =
+    case c of
+      EnvStep -> I.step
+      EnvLin -> I.linear
+      EnvExp -> I.exponential
+      EnvSin -> I.sine
+      EnvWelch -> I.welch
+      EnvNum n -> I.curve n
+      EnvSqr -> I.squared
+      EnvCub -> I.cubed
+      EnvHold -> undefined
+
+-- | Apply /f/ to 'EnvNum' value.
+env_curve_coerce :: (a -> b) -> Envelope_Curve a -> Envelope_Curve b
+env_curve_coerce f e =
+    case e of
+      EnvStep -> EnvStep
+      EnvLin -> EnvLin
+      EnvExp -> EnvExp
+      EnvSin -> EnvSin
+      EnvWelch -> EnvWelch
+      EnvNum x -> EnvNum (f x)
+      EnvSqr -> EnvSqr
+      EnvCub -> EnvCub
+      EnvHold -> EnvHold
+
+-- * Envelope
+
+-- | SC3 envelope segment model
+data Envelope a =
+    Envelope {env_levels :: [a] -- ^ Set of /n/ levels, n is >= 1
+             ,env_times :: [a] -- ^ Set of /n-1/ time intervals
+             ,env_curves :: [Envelope_Curve a] -- ^ Possibly empty curve set
+             ,env_release_node :: Maybe Int -- ^ Maybe index to release node
+             ,env_loop_node :: Maybe Int -- ^ Maybe index to loop node
+             }
+    deriving (Eq,Show)
+
+-- | Apply /f/ to all /a/ at 'Envelope'.
+envelope_coerce :: (a -> b) -> Envelope a -> Envelope b
+envelope_coerce f e =
+    let Envelope l t c rn ln = e
+    in Envelope (map f l) (map f t) (map (env_curve_coerce f) c) rn ln
+
+-- | Variant without release and loop node inputs (defaulting to nil).
+envelope :: [a] -> [a] -> [Envelope_Curve a] -> Envelope a
+envelope l t c = Envelope l t c Nothing Nothing
+
+-- | Duration of 'Envelope', ie. 'sum' '.' 'env_times'.
+envelope_duration :: Num n => Envelope n -> n
+envelope_duration = sum . env_times
+
+-- | Number of segments at 'Envelope', ie. 'length' '.' 'env_times'.
+envelope_n_segments :: Integral i => Envelope n -> i
+envelope_n_segments = genericLength . env_times
+
+-- | Determine which envelope segment a given time /t/ falls in.
+envelope_segment_ix :: (Ord a, Num a) => Envelope a -> a -> Maybe Int
+envelope_segment_ix e t =
+    let d = P.dx_d (env_times e)
+    in findIndex (>= t) d
+
+-- | A set of start time, start level, end time, end level and curve.
+type Envelope_Segment t = (t,t,t,t,Envelope_Curve t)
+
+-- | Extract envelope segment given at index /i/.
+envelope_segment :: Num t => Envelope t -> Int -> Envelope_Segment t
+envelope_segment e i =
+    let l = env_levels e
+        t = env_times e
+        x0 = l !! i
+        x1 = l !! (i + 1)
+        t0 = (0 : P.dx_d t) !! i
+        t1 = t0 + t !! i
+        c = envelope_curves e !! i
+    in (t0,x0,t1,x1,c)
+
+-- | Extract all segments.
+envelope_segments :: Num t => Envelope t -> [Envelope_Segment t]
+envelope_segments e =
+    let n = envelope_n_segments e
+    in map (envelope_segment e) [0 .. n - 1]
+
+-- | Transform list of 'Envelope_Segment's into lists ('env_levels','env_times','env_curves').
+pack_envelope_segments :: Num t => [Envelope_Segment t] -> ([t],[t],[Envelope_Curve t])
+pack_envelope_segments s =
+    case s of
+      [] -> error ""
+      [(t0,l0,t1,l1,c)] -> ([l0,l1],[t1 - t0],[c])
+      (_,l0,_,_,_) : _ ->
+          let t (t0,_,t1,_,_) = t1 - t0
+              c (_,_,_,_,x) = x
+              l (_,_,_,x,_) = x
+          in (l0 : map l s,map t s,map c s)
+
+-- | An envelope is /normal/ if it has no segments with zero duration.
+envelope_is_normal :: (Eq n,Num n) => Envelope n -> Bool
+envelope_is_normal = not . any (== 0) . env_times
+
+-- | Normalise envelope by deleting segments of zero duration.
+envelope_normalise :: (Num a, Ord a) => Envelope a -> Envelope a
+envelope_normalise e =
+    let s = envelope_segments e
+        f (t0,_,t1,_,_) = t1 <= t0
+        s' = filter (not . f) s
+        (l,t,c) = pack_envelope_segments s'
+    in case e of
+         Envelope _ _ _ Nothing Nothing -> Envelope l t c Nothing Nothing
+         _ -> error "envelope_normalise: has release or loop node..."
+
+-- | Get value for 'Envelope' at time /t/, or zero if /t/ is out of
+-- range.  By convention if the envelope has a segment of zero
+-- duration we give the rightmost value.
+envelope_at :: (Ord t, Floating t) => Envelope t -> t -> t
+envelope_at e t =
+    case envelope_segment_ix e t of
+      Just n -> let (t0,x0,t1,x1,c) = envelope_segment e n
+                    d = t1 - t0
+                    t' = (t - t0) / d
+                    f = env_curve_interpolation_f c
+                in if d <= 0
+                   then x1
+                   else f x0 x1 t'
+      Nothing -> 0
+
+-- | Render 'Envelope' to breakpoint set of /n/ equi-distant places.
+envelope_render :: (Ord t, Floating t, Enum t) => t -> Envelope t -> [(t,t)]
+envelope_render n e =
+    let d = envelope_duration e
+        k = d / (n - 1)
+        t = [0,k .. d]
+    in zip t (map (envelope_at e) t)
+
+-- | Contruct a lookup table of /n/ places from 'Envelope'.
+envelope_table :: (Ord t, Floating t, Enum t) => t -> Envelope t -> [t]
+envelope_table n = map snd . envelope_render n
+
+-- | Variant on 'env_curves' that expands the, possibly empty, user
+-- list by cycling (if not empty) or by filling with 'EnvLin'.
+envelope_curves :: Envelope a -> [Envelope_Curve a]
+envelope_curves e =
+    let c = env_curves e
+        n = envelope_n_segments e
+    in if null c
+       then replicate n EnvLin
+       else take n (cycle c)
+
+-- | Linear SC3 form of 'Envelope' data.
+--
+-- Form is: l0 #t reset loop l1 t0 c0 c0' ...
+--
+-- > let {l = [0,0.6,0.3,1.0,0]
+-- >     ;t = [0.1,0.02,0.4,1.1]
+-- >     ;c = [EnvLin,EnvExp,EnvNum (-6),EnvSin]
+-- >     ;e = Envelope l t c Nothing Nothing
+-- >     ;r = [0,4,-99,-99,0.6,0.1,1,0,0.3,0.02,2,0,1,0.4,5,-6,0,1.1,3,0]}
+-- > in envelope_sc3_array e == Just r
+envelope_sc3_array :: Num a => Envelope a -> Maybe [a]
+envelope_sc3_array e =
+    let Envelope l t _ rn ln = e
+        n = length t
+        n' = fromIntegral n
+        rn' = fromIntegral (fromMaybe (-99) rn)
+        ln' = fromIntegral (fromMaybe (-99) ln)
+        c = envelope_curves e
+        f i j k = [i,j,env_curve_shape k,env_curve_value k]
+    in case l of
+         l0:l' -> Just (l0 : n' : rn' : ln' : concat (zipWith3 f l' t c))
+         _ -> Nothing
+
+-- | @IEnvGen@ SC3 form of 'Envelope' data.  Offset not supported (zero).
+--
+-- > let {l = [0,0.6,0.3,1.0,0]
+-- >     ;t = [0.1,0.02,0.4,1.1]
+-- >     ;c = [EnvLin,EnvExp,EnvNum (-6),EnvSin]
+-- >     ;e = Envelope l t c Nothing Nothing
+-- >     ;r = [0,0,4,1.62,0.1,1,0,0.6,0.02,2,0,0.3,0.4,5,-6,1,1.1,3,0,0]}
+-- > in envelope_sc3_ienvgen_array e == Just r
+envelope_sc3_ienvgen_array :: Num a => Envelope a -> Maybe [a]
+envelope_sc3_ienvgen_array e =
+    let Envelope l t _ _ _ = e
+        n = length t
+        n' = fromIntegral n
+        c = envelope_curves e
+        f i j k = [j,env_curve_shape k,env_curve_value k,i]
+    in case l of
+         l0:l' -> Just (0 : l0 : n' : sum t : concat (zipWith3 f l' t c))
+         _ -> Nothing
+
+-- | 'True' if 'env_release_node' is not 'Nothing'.
+env_is_sustained :: Envelope a -> Bool
+env_is_sustained = isJust . env_release_node
+
+-- | Delay the onset of the envelope.
+env_delay :: Envelope a -> a -> Envelope a
+env_delay (Envelope l t c rn ln) d =
+    let (l0:_) = l
+        l' = l0 : l
+        t' = d : t
+        c' = EnvLin : c
+        rn' = fmap (+ 1) rn
+        ln' = fmap (+ 1) ln
+    in Envelope l' t' c' rn' ln'
+
+-- | Connect releaseNode (or end) to first node of envelope.
+env_circle :: Fractional a => Envelope a -> a -> Envelope_Curve a -> Envelope a
+env_circle (Envelope l t c rn _) tc cc =
+    let z = 1 {- 1 - impulse KR 0 0 -}
+        n = length t
+    in case rn of
+         Nothing -> let l' = 0 : l ++ [0]
+                        t' = z * tc : t ++ [9e8]
+                        c' = cc : take n (cycle c) ++ [EnvLin]
+                        rn' = Just (n + 1)
+                    in Envelope l' t' c' rn' (Just 0)
+         Just i -> let l' = 0 : l
+                       t' = z * tc : t
+                       c' = cc : take n (cycle c)
+                       rn' = Just (i + 1)
+                   in  Envelope l' t' c' rn' (Just 0)
+
+-- * Construct
+
+{- | Trapezoidal envelope generator.
+
+Requires (<=) and (>=) functions returning @1@ for true and @0@ for false.
+
+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_f :: Num t => (t -> t -> t,t -> t -> t) -> t -> t -> t -> t -> Envelope t
+envTrapezoid_f (lte_f,gte_f) shape skew dur amp =
+    let x1 = skew * (1 - shape)
+        bp = [(0,lte_f skew 0)
+             ,(x1,1)
+             ,(shape + x1,1)
+             ,(1,gte_f skew 1)]
+    in envCoord bp dur amp EnvLin
+
+{- | Co-ordinate based static envelope generator.  Points are (time,value) pairs.
+
+> let e = envCoord [(0,0),(1/4,1),(1,0)] 1 1 EnvLin
+> in envelope_sc3_array e == Just [0,2,-99,-99,1,1/4,1,0,0,3/4,1,0]
+
+> import Sound.SC3.Plot {- hsc3-plot -}
+
+> plotEnvelope [envCoord [(0,0),(1/4,1),(1,0)] 1 1 EnvLin]
+
+-}
+envCoord :: Num a => [(a,a)] -> a -> a -> Envelope_Curve a -> Envelope a
+envCoord bp dur amp c =
+    let l = map ((* amp) . snd) bp
+        t = map (* dur) (tail (P.d_dx (map fst bp)))
+    in Envelope l t [c] Nothing Nothing
+
+-- | Variant 'envPerc' with user specified 'Envelope_Curve a'.
+envPerc' :: Num a => a -> a -> a -> Envelope_Curve2 a -> Envelope a
+envPerc' atk rls lvl (c0,c1) =
+    let c = [c0,c1]
+    in Envelope [0,lvl,0] [atk,rls] c Nothing Nothing
+
+-- | Percussive envelope, with attack, release, level and curve
+--   inputs.
+envPerc :: Num a => a -> a -> Envelope a
+envPerc atk rls =
+    let cn = EnvNum (-4)
+    in envPerc' atk rls 1 (cn,cn)
+
+-- | Triangular envelope, with duration and level inputs.
+--
+-- > let e = envTriangle 1 0.1
+-- > in envelope_sc3_array e = Just [0,2,-99,-99,0.1,0.5,1,0,0,0.5,1,0]
+envTriangle :: Fractional a => a -> a -> Envelope a
+envTriangle dur lvl =
+    let c = replicate 2 EnvLin
+        d = replicate 2 (dur / 2)
+    in Envelope [0,lvl,0] d c Nothing Nothing
+
+-- | Sine envelope, with duration and level inputs.
+--
+-- > let e = envSine 0 0.1
+-- > in envelope_sc3_array e == Just [0,2,-99,-99,0.1,0,3.0,0,0,0,3,0]
+envSine :: Fractional a => a -> a -> Envelope a
+envSine dur lvl =
+    let c = replicate 2 EnvSin
+        d = replicate 2 (dur / 2)
+    in Envelope [0,lvl,0] d c Nothing Nothing
+
+-- | Parameters for LINEN envelopes.
+data LINEN a = LINEN {linen_attackTime :: a
+                     ,linen_sustainTime :: a
+                     ,linen_releaseTime :: a
+                     ,linen_level :: a
+                     ,linen_curve :: Envelope_Curve3 a}
+
+-- | Record ('LINEN') variant of 'envLinen'.
+envLinen_r :: Num a => LINEN a -> Envelope a
+envLinen_r (LINEN aT sT rT lv (c0,c1,c2)) =
+    let l = [0,lv,lv,0]
+        t = [aT,sT,rT]
+        c = [c0,c1,c2]
+    in Envelope l t c Nothing Nothing
+
+-- | Variant of 'envLinen' with user specified 'Envelope_Curve a'.
+envLinen' :: Num a => a -> a -> a -> a -> Envelope_Curve3 a -> Envelope a
+envLinen' aT sT rT lv c = envLinen_r (LINEN aT sT rT lv c)
+
+-- | Linear envelope parameter constructor.
+--
+-- > let {e = envLinen 0 1 0 1
+-- >     ;s = envelope_segments e
+-- >     ;p = pack_envelope_segments s}
+-- > in p == (env_levels e,env_times e,env_curves e)
+envLinen :: Num a => a -> a -> a -> a -> Envelope a
+envLinen aT sT rT l =
+    let c = (EnvLin,EnvLin,EnvLin)
+    in envLinen' aT sT rT l c
+
+-- | Parameters for ADSR envelopes.
+--   The sustain level is given as a proportion of the peak level.
+data ADSR a = ADSR {adsr_attackTime :: a
+                   ,adsr_decayTime :: a
+                   ,adsr_sustainLevel :: a
+                   ,adsr_releaseTime :: a
+                   ,adsr_peakLevel :: a
+                   ,adsr_curve :: Envelope_Curve3 a
+                   ,adsr_bias :: a}
+
+adsrDefault :: Fractional n => ADSR n
+adsrDefault = let c = EnvNum (-4) in ADSR 0.01 0.3 0.5 1 1 (c,c,c) 0
+
+-- | Attack, decay, sustain, release envelope parameter constructor.
+envADSR :: Num a => a -> a -> a -> a -> a -> Envelope_Curve a -> a -> Envelope a
+envADSR aT dT sL rT pL c b = envADSR_r (ADSR aT dT sL rT pL (c,c,c) b)
+
+-- | Vairant with defaults for pL, c and b.
+envADSR' :: Num a => a -> a -> a -> a -> Envelope a
+envADSR' aT dT sL rT = envADSR aT dT sL rT 1 (EnvNum (-4)) 0
+
+-- | Record ('ADSR') variant of 'envADSR'.
+envADSR_r :: Num a => ADSR a -> Envelope a
+envADSR_r (ADSR aT dT sL rT pL (c0,c1,c2) b) =
+    let l = map (+ b) [0,pL,pL*sL,0]
+        t = [aT,dT,rT]
+        c = [c0,c1,c2]
+    in Envelope l t c (Just 2) Nothing
+
+-- | Parameters for Roland type ADSSR envelopes.
+data ADSSR a = ADSSR {adssr_attackTime :: a
+                     ,adssr_attackLevel :: a
+                     ,adssr_decayTime :: a
+                     ,adssr_decayLevel :: a
+                     ,adssr_slopeTime :: a
+                     ,adssr_sustainLevel :: a
+                     ,adssr_releaseTime :: a
+                     ,adssr_curve :: Envelope_Curve4 a
+                     ,adssr_bias :: a}
+
+-- | Attack, decay, slope, sustain, release envelope parameter constructor.
+envADSSR :: Num a => a -> a -> a -> a -> a -> a -> a -> Envelope_Curve a -> a -> Envelope a
+envADSSR t1 l1 t2 l2 t3 l3 t4 c b = envADSSR_r (ADSSR t1 l1 t2 l2 t3 l3 t4 (c,c,c,c) b)
+
+-- | Record ('ADSSR') variant of 'envADSSR'.
+envADSSR_r :: Num a => ADSSR a -> Envelope a
+envADSSR_r (ADSSR t1 l1 t2 l2 t3 l3 t4 (c1,c2,c3,c4) b) =
+    let l = map (+ b) [0,l1,l2,l3,0]
+        t = [t1,t2,t3,t4]
+        c = [c1,c2,c3,c4]
+    in Envelope l t c (Just 3) Nothing
+
+-- | Parameters for ASR envelopes.
+data ASR a = ASR {asr_attackTime :: a
+                 ,asr_sustainLevel :: a
+                 ,asr_releaseTime :: a
+                 ,asr_curve :: Envelope_Curve2 a}
+
+-- | SC3 .asr has singular curve argument, hence _c suffix.
+envASR_c :: Num a => a -> a -> a -> Envelope_Curve2 a -> Envelope a
+envASR_c aT sL rT c = envASR_r (ASR aT sL rT c)
+
+-- | Attack, sustain, release envelope parameter constructor.
+--
+-- > let {c = 3
+-- >     ;r = Just [0,2,1,-99,0.1,3,c,0,0,2,c,0]}
+-- > in envelope_sc3_array (envASR 3 0.1 2 EnvSin) == r
+envASR :: Num a => a -> a -> a -> Envelope_Curve a -> Envelope a
+envASR aT sL rT c = envASR_c aT sL rT (c,c)
+
+-- | Record ('ASR') variant of 'envASR'.
+envASR_r :: Num a => ASR a -> Envelope a
+envASR_r (ASR aT sL rT (c0,c1)) =
+    let l = [0,sL,0]
+        t = [aT,rT]
+        c' = [c0,c1]
+    in Envelope l t c' (Just 1) Nothing
+
+-- | All segments are horizontal lines.
+envStep :: [a] -> [a] -> Maybe Int -> Maybe Int -> Envelope a
+envStep levels times releaseNode loopNode =
+    if length levels /= length times
+    then error "envStep: levels and times must have same size"
+    else let levels' = head levels : levels
+         in Envelope levels' times [EnvStep] releaseNode loopNode
diff --git a/Sound/SC3/Common/Math.hs b/Sound/SC3/Common/Math.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Math.hs
@@ -0,0 +1,435 @@
+module Sound.SC3.Common.Math where
+
+import qualified Data.Fixed as F {- base -}
+import Data.Maybe {- base -}
+
+-- | Half pi.
+--
+-- > half_pi == 1.5707963267948966
+half_pi :: Floating a => a
+half_pi = pi / 2
+
+-- | Two pi.
+--
+-- > two_pi == 6.283185307179586
+two_pi :: Floating n => n
+two_pi = 2 * pi
+
+-- | Multiply and add, ordinary haskell argument order.
+-- 'mul_add' is a method of the 'MulAdd' class.
+--
+-- > map (mul_add_hs 2 3) [1,2] == [5,7] && map (mul_add_hs 3 4) [1,2] == [7,10]
+mul_add_hs :: Num a => a -> a -> a -> a
+mul_add_hs m a = (+ a) . (* m)
+
+sc_truncate :: RealFrac a => a -> a
+sc_truncate = fromInteger . truncate
+
+sc_round :: RealFrac a => a -> a
+sc_round = fromInteger . round
+
+sc_ceiling :: RealFrac a => a -> a
+sc_ceiling = fromInteger . ceiling
+
+sc_floor :: RealFrac a => a -> a
+sc_floor = fromInteger . floor
+
+-- | Variant of @SC3@ @roundTo@ function.
+--
+-- > let r = [0,0,0.25,0.25,0.5,0.5,0.5,0.75,0.75,1,1]
+-- > in map (`sc3_round_to` 0.25) [0,0.1 .. 1] == r
+sc3_round_to :: RealFrac n => n -> n -> n
+sc3_round_to a b = if b == 0 then a else sc_floor ((a / b) + 0.5) * b
+
+sc3_idiv :: RealFrac n => n -> n -> n
+sc3_idiv a b = fromInteger (floor a `div` floor b)
+
+{- | The SC3 @%@ UGen operator is the 'F.mod'' function.
+
+> > 1.5 % 1.2 // ~= 0.3
+> > -1.5 % 1.2 // ~= 0.9
+> > 1.5 % -1.2 // ~= -0.9
+> > -1.5 % -1.2 // ~= -0.3
+
+> let (%) = sc3_mod
+> 1.5 % 1.2 ~= 0.3
+> (-1.5) % 1.2 ~= 0.9
+> 1.5 % (-1.2) ~= -0.9
+> (-1.5) % (-1.2) ~= -0.3
+
+> > 1.2 % 1.5 // ~= 1.2
+> > -1.2 % 1.5 // ~= 0.3
+> > 1.2 % -1.5 // ~= -0.3
+> > -1.2 % -1.5 // ~= -1.2
+
+> 1.2 % 1.5 ~= 1.2
+> (-1.2) % 1.5 ~= 0.3
+> 1.2 % (-1.5) ~= -0.3
+> (-1.2) % (-1.5) ~= -1.2
+
+> map (\n -> sc3_mod n 12.0) [-1.0,12.25,15.0] == [11.0,0.25,3.0]
+-}
+sc3_mod :: RealFrac n => n -> n -> n
+sc3_mod = F.mod'
+
+-- | Type specialised 'sc3_mod'.
+fmod_f32 :: Float -> Float -> Float
+fmod_f32 = sc3_mod
+
+-- | Type specialised 'sc3_mod'.
+fmod_f64 :: Double -> Double -> Double
+fmod_f64 = sc3_mod
+
+-- | @SC3@ clip function.  Clip /n/ to within range /(i,j)/.  'clip' is a 'UGen'.
+--
+-- > map (\n -> sc_clip n 5 10) [3..12] == [5,5,5,6,7,8,9,10,10,10]
+sc_clip :: Ord a => a -> a -> a -> a
+sc_clip n i j = if n < i then i else if n > j then j else n
+
+-- | Variant of 'sc_clip' with haskell argument structure.
+--
+-- > map (clip_hs (5,10)) [3..12] == [5,5,5,6,7,8,9,10,10,10]
+clip_hs :: (Ord a) => (a,a) -> a -> a
+clip_hs (i,j) n = sc_clip n i j
+
+-- | Fractional modulo.
+--
+-- > map (\n -> sc_mod n 12.0) [-1.0,12.25,15.0] == [11.0,0.25,3.0]
+sc_mod :: RealFrac a => a -> a -> a
+sc_mod n hi =
+    let lo = 0.0
+    in if n >= lo && n < hi
+       then n
+       else if hi == lo
+            then lo
+            else n - hi * sc_floor (n / hi)
+
+{- | Wrap function that is /non-inclusive/ at right edge, ie. the Wrap UGen rule.
+
+> map (sc_wrap_ni 0 5) [4,5,6] == [4,0,1]
+> map (sc_wrap_ni 5 10) [3..12] == [8,9,5,6,7,8,9,5,6,7]
+-}
+sc_wrap_ni :: RealFrac a => a -> a -> a -> a
+sc_wrap_ni lo hi n = sc_mod (n - lo) (hi - lo) + lo
+
+{- | Wrap /n/ to within range /(i,j)/, ie. @AbstractFunction.wrap@,
+ie. /inclusive/ at right edge.  'wrap' is a 'UGen', hence prime.
+
+> > [5,6].wrap(0,5) == [5,0]
+> map (wrap_hs (0,5)) [5,6] == [5,0]
+
+> > [9,10,5,6,7,8,9,10,5,6].wrap(5,10) == [9,10,5,6,7,8,9,10,5,6]
+> map (wrap_hs (5,10)) [3..12] == [9,10,5,6,7,8,9,10,5,6]
+
+-}
+wrap_hs :: RealFrac n => (n,n) -> n -> n
+wrap_hs (i,j) n =
+    let r = j - i + 1
+    in if n >= i && n <= j
+       then n
+       else n - r * sc_floor ((n - i) / r)
+
+-- | Variant of 'wrap'' with @SC3@ argument ordering.
+--
+-- > map (\n -> sc_wrap n 5 10) [3..12] == map (wrap_hs (5,10)) [3..12]
+sc_wrap :: RealFrac n => n -> n -> n -> n
+sc_wrap a b c = wrap_hs (b,c) a
+
+{- | Generic variant of 'wrap''.
+
+> > [5,6].wrap(0,5) == [5,0]
+> map (generic_wrap (0,5)) [5,6] == [5,0]
+
+> > [9,10,5,6,7,8,9,10,5,6].wrap(5,10) == [9,10,5,6,7,8,9,10,5,6]
+> map (generic_wrap (5::Integer,10)) [3..12] == [9,10,5,6,7,8,9,10,5,6]
+-}
+generic_wrap :: (Ord a, Num a) => (a,a) -> a -> a
+generic_wrap (l,r) n =
+    let d = r - l + 1
+        f = generic_wrap (l,r)
+    in if n < l
+       then f (n + d)
+       else if n > r then f (n - d) else n
+
+-- > bin_to_freq 44100 2048 32 == 689.0625
+bin_to_freq :: (Fractional n, Integral i) => n -> i -> i -> n
+bin_to_freq sr n i = fromIntegral i * sr / fromIntegral n
+
+-- | Midi note number to cycles per second.
+--
+-- > map (floor . midi_to_cps) [0,24,69,120,127] == [8,32,440,8372,12543]
+-- > map (floor . midi_to_cps) [-36,138] == [1,23679]
+midi_to_cps :: Floating a => a -> a
+midi_to_cps i = 440.0 * (2.0 ** ((i - 69.0) * (1.0 / 12.0)))
+
+-- | Cycles per second to midi note number.
+--
+-- > map (round . cps_to_midi) [8,32,440,8372,12543] == [0,24,69,120,127]
+-- > map (round . cps_to_midi) [1,24000] == [-36,138]
+cps_to_midi :: Floating a => a -> a
+cps_to_midi a = (logBase 2 (a * (1.0 / 440.0)) * 12.0) + 69.0
+
+cps_to_oct :: Floating a => a -> a
+cps_to_oct a = logBase 2 (a * (1.0 / 440.0)) + 4.75
+
+oct_to_cps :: Floating a => a -> a
+oct_to_cps a = 440.0 * (2.0 ** (a - 4.75))
+
+-- | Linear amplitude to decibels.
+--
+-- > map (round . amp_to_db) [0.01,0.05,0.0625,0.125,0.25,0.5] == [-40,-26,-24,-18,-12,-6]
+amp_to_db :: Floating a => a -> a
+amp_to_db a = logBase 10 a * 20
+
+-- | Decibels to linear amplitude.
+--
+-- > map (floor . (* 100). db_to_amp) [-40,-26,-24,-18,-12,-6] == [01,05,06,12,25,50]
+db_to_amp :: Floating a => a -> a
+db_to_amp a = 10 ** (a * 0.05)
+
+-- | Fractional midi note interval to frequency multiplier.
+--
+-- > map midi_to_ratio [0,7,12] == [1,1.4983070768766815,2]
+midi_to_ratio :: Floating a => a -> a
+midi_to_ratio a = 2.0 ** (a * (1.0 / 12.0))
+
+-- | Inverse of 'midi_to_ratio'.
+--
+-- > map ratio_to_midi [3/2,2] == [7.019550008653875,12]
+ratio_to_midi :: Floating a => a -> a
+ratio_to_midi a = 12.0 * logBase 2 a
+
+-- | Scale uni-polar (0,1) input to linear (l,r) range
+--
+-- > map (urange 3 4) [0,0.5,1] == [3,3.5,4]
+urange :: Fractional a => a -> a -> a -> a
+urange l r i = let m = r - l in i * m + l
+
+-- | Calculate multiplier and add values for 'range' transform.
+--
+-- > range_muladd 3 4 == (0.5,3.5)
+range_muladd :: Fractional t => t -> t -> (t,t)
+range_muladd = linlin_muladd (-1) 1
+
+-- | Scale bi-polar (-1,1) input to linear (l,r) range.  Note that the
+-- argument order is not the same as 'linlin'.
+--
+-- > map (range 3 4) [-1,0,1] == [3,3.5,4]
+-- > map (\x -> let (m,a) = linlin_muladd (-1) 1 3 4 in x * m + a) [-1,0,1] == [3,3.5,4]
+range :: Fractional a => a -> a -> a -> a
+range l r i = let (m,a) = range_muladd l r in i * m + a
+
+range_hs :: Fractional a => (a,a) -> a -> a
+range_hs (l,r) = range l r
+
+data Clip_Rule = Clip_None | Clip_Left | Clip_Right | Clip_Both
+                 deriving (Enum,Bounded)
+
+-- > let f r = map (\x -> apply_clip_rule r 0 1 (-1) 1 x) [-1,0,0.5,1,2]
+-- > in map f [minBound .. maxBound]
+apply_clip_rule :: Ord n => Clip_Rule -> n -> n -> n -> n -> n -> Maybe n
+apply_clip_rule clip_rule sl sr dl dr x =
+    case clip_rule of
+      Clip_None -> Nothing
+      Clip_Left -> if x <= sl then Just dl else Nothing
+      Clip_Right -> if x >= sr then Just dr else Nothing
+      Clip_Both -> if x <= sl then Just dl else if x >= sr then Just dr else Nothing
+
+-- | Calculate multiplier and add values for 'linlin' transform.
+--
+-- > range_muladd 3 4 == (0.5,3.5)
+-- > linlin_muladd (-1) 1 3 4 == (0.5,3.5)
+-- > linlin_muladd 0 1 3 4 == (1,3)
+-- > linlin_muladd (-1) 1 0 1 == (0.5,0.5)
+-- > linlin_muladd (-0.3) 1 (-1) 1
+linlin_muladd :: Fractional t => t -> t -> t -> t -> (t,t)
+linlin_muladd sl sr dl dr =
+    let m = (dr - dl) / (sr - sl)
+        a = dl - (m * sl)
+    in (m,a)
+
+-- | Map from one linear range to another linear range.
+--
+-- > map (\i -> linlin i (-1) 1 0 1) [-1,-0.9 .. 1.0]
+linlin :: Fractional a => a -> a -> a -> a -> a -> a
+linlin i sl sr dl dr = let (m,a) = linlin_muladd sl sr dl dr in i * m + a
+
+-- | Variant with a more typical argument structure, ranges as pairs and input last.
+--
+-- > map (linlin_hs (0,127) (-0.5,0.5)) [0,63.5,127]
+linlin_hs :: Fractional a => (a, a) -> (a, a) -> a -> a
+linlin_hs (sl,sr) (dl,dr) i = linlin i sl sr dl dr
+
+-- | Given enumeration from /dst/ that is in the same relation as /n/ is from /src/.
+--
+-- > linlin _enum' 'a' 'A' 'e' == 'E'
+-- > linlin_enum' 0 (-50) 16 == -34
+-- > linlin_enum' 0 (-50) (-1) == -51
+linlin_enum' :: (Enum t,Enum u) => t -> u -> t -> u
+linlin_enum' src dst n = toEnum (fromEnum dst + (fromEnum n - fromEnum src))
+
+-- | Variant of 'linlin_enum'' that requires /src/ and /dst/ ranges to be of equal size,
+-- and for /n/ to lie in /src/.
+--
+-- > linlin_enum (0,100) (-50,50) 0x10 == Just (-34)
+-- > linlin_enum (-50,50) (0,100) (-34) == Just 0x10
+-- > linlin_enum (0,100) (-50,50) (-1) == Nothing
+linlin_enum :: (Enum t,Enum u) => (t,t) -> (u,u) -> t -> Maybe u
+linlin_enum (l,r) (l',r') n =
+    if fromEnum n >= fromEnum l && fromEnum r - fromEnum l == fromEnum r' - fromEnum l'
+    then Just (linlin_enum' l l' n)
+    else Nothing
+
+-- | Erroring variant.
+linlin_enum_err :: (Enum t,Enum u) => (t,t) -> (u,u) -> t -> u
+linlin_enum_err src dst = fromMaybe (error "linlin_enum") . linlin_enum src dst
+
+-- | Variant of 'linlin' that requires /src/ and /dst/ ranges to be of
+-- equal size, thus with constraint of 'Num' and 'Eq' instead of
+-- 'Fractional'.
+--
+-- > linlin_eq (0,100) (-50,50) 0x10 == Just (-34)
+-- > linlin_eq (-50,50) (0,100) (-34) == Just 0x10
+linlin_eq :: (Eq a, Num a) => (a,a) -> (a,a) -> a -> Maybe a
+linlin_eq (l,r) (l',r') n =
+    let d = r - l
+        d' = r' - l'
+    in if d == d' then Just (l' + (n - l)) else Nothing
+
+-- | Erroring variant.
+linlin_eq_err :: (Eq a,Num a) => (a,a) -> (a,a) -> a -> a
+linlin_eq_err src dst = fromMaybe (error "linlin_eq") . linlin_eq src dst
+
+-- | @SimpleNumber.linexp@ shifts from linear to exponential ranges.
+--
+-- > > [1,1.5,2].collect({|i| i.linexp(1,2,10,100).floor}) == [10,31,100]
+-- > map (floor . sc_linexp 1 2 10 100) [0,1,1.5,2,3] == [10,10,31,100,100]
+sc_linexp :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a
+sc_linexp src_l src_r dst_l dst_r x =
+    case apply_clip_rule Clip_Both src_l src_r dst_l dst_r x of
+      Just r -> r
+      Nothing -> ((dst_r / dst_l) ** ((x - src_l) / (src_r - src_l))) * dst_l
+
+-- | @SimpleNumber.explin@ is the inverse of linexp.
+--
+-- > map (sc_explin 10 100 1 2) [10,10,31,100,100]
+sc_explin :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a
+sc_explin src_l src_r dst_l dst_r x =
+    case apply_clip_rule Clip_Both src_l src_r dst_l dst_r x of
+      Just r -> r
+      Nothing -> (log (x / src_l)) / (log (src_r / src_l)) * (dst_r - dst_l) + dst_l
+
+-- > map (sc_expexp 0.1 10 4.3 100) [1.. 10]
+sc_expexp :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a
+sc_expexp src_l src_r dst_l dst_r x =
+    case apply_clip_rule Clip_Both src_l src_r dst_l dst_r x of
+      Just r -> r
+      Nothing -> ((dst_r / dst_l) ** (log (x / src_l) / log (src_r / src_l))) * dst_l
+
+{- | Map /x/ from an assumed linear input range (src_l,src_r) to an
+exponential curve output range (dst_l,dst_r). 'curve' is like the
+parameter in Env.  Unlike with linexp, the output range may include
+zero.
+
+> > (0..10).lincurve(0,10,-4.3,100,-3).round == [-4,24,45,61,72,81,87,92,96,98,100]
+
+> let f = round . sc_lincurve (-3) 0 10 (-4.3) 100
+> in map f [0 .. 10] == [-4,24,45,61,72,81,87,92,96,98,100]
+
+> import Sound.SC3.Plot {- hsc3-plot -}
+> plotTable (map (\c-> map (sc_lincurve c 0 1 (-1) 1) [0,0.01 .. 1]) [-6,-4 .. 6])
+
+-}
+sc_lincurve :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a -> a
+sc_lincurve curve src_l src_r dst_l dst_r x =
+    case apply_clip_rule Clip_Both src_l src_r dst_l dst_r x of
+      Just r -> r
+      Nothing ->
+          if abs curve < 0.001
+          then linlin_hs (src_l,src_r) (dst_l,dst_r) x
+          else let grow = exp curve
+                   a = (dst_r - dst_l) / (1.0 - grow)
+                   b = dst_l + a
+                   scaled = (x - src_l) / (src_r - src_l)
+               in b - (a * (grow ** scaled))
+
+-- | Inverse of 'sc_lincurve'.
+--
+-- > let f = round . sc_curvelin (-3) (-4.3) 100 0 10
+-- > in map f [-4,24,45,61,72,81,87,92,96,98,100] == [0..10]
+sc_curvelin :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a -> a
+sc_curvelin curve src_l src_r dst_l dst_r x =
+    case apply_clip_rule Clip_Both src_l src_r dst_l dst_r x of
+      Just r -> r
+      Nothing ->
+          if abs curve < 0.001
+          then linlin_hs (src_l,src_r) (dst_l,dst_r) x
+          else let grow = exp curve
+                   a = (src_r - src_l) / (1.0 - grow)
+                   b = src_l + a
+               in log ((b - x) / a) * (dst_r - dst_l) / curve + dst_l
+
+-- > map (floor . linexp_hs (1,2) (10,100)) [0,1,1.5,2,3] == [1,10,31,100,1000]
+linexp_hs :: Floating a => (a,a) -> (a,a) -> a -> a
+linexp_hs (in_l,in_r) (out_l,out_r) x =
+    let rt = out_r / out_l
+        rn = 1.0 / (in_r - in_l)
+        rr = rn * negate in_l
+    in out_l * (rt ** (x * rn + rr))
+
+-- | Exponential range conversion.
+--
+-- > map (\i -> lin_exp i 1 2 1 3) [1,1.1 .. 2]
+lin_exp :: Floating a => a -> a -> a -> a -> a -> a
+lin_exp x in_l in_r out_l out_r = linexp_hs (in_l,in_r) (out_l,out_r) x
+
+-- | /sr/ = sample rate, /r/ = cycle (two-pi), /cps/ = frequency
+--
+-- > cps_to_incr 48000 128 375 == 1
+-- > cps_to_incr 48000 two_pi 458.3662361046586 == 6e-2
+cps_to_incr :: Fractional a => a -> a -> a -> a
+cps_to_incr sr r cps = (r / sr) * cps
+
+-- | Inverse of 'cps_to_incr'.
+--
+-- > incr_to_cps 48000 128 1 == 375
+incr_to_cps :: Fractional a => a -> a -> a -> a
+incr_to_cps sr r ic = ic / (r / sr)
+
+-- | Linear pan.
+--
+-- > map (lin_pan2 1) [-1,0,1] == [(1,0),(0.5,0.5),(0,1)]
+lin_pan2 :: Fractional t => t -> t -> (t, t)
+lin_pan2 p q =
+    let q' = (q / 2) + 0.5
+    in (p * (1 - q'),p * q')
+
+sc3_properFraction :: RealFrac t => t -> (t,t)
+sc3_properFraction a =
+    let (p,q) = properFraction a
+    in (fromInteger p,q)
+
+sc_dif_sqr :: Num a => a -> a -> a
+sc_dif_sqr a b = (a * a) - (b * b)
+
+sc_hypot :: Floating a => a -> a -> a
+sc_hypot x y = sqrt (x * x + y * y)
+
+sc_hypotx :: (Ord a, Floating a) => a -> a -> a
+sc_hypotx x y = abs x + abs y - ((sqrt 2 - 1) * min (abs x) (abs y))
+
+-- | Fold /k/ to within range /(i,j)/, ie. @AbstractFunction.fold@
+--
+-- > map (foldToRange 5 10) [3..12] == [7,6,5,6,7,8,9,10,9,8]
+foldToRange :: (Ord a,Num a) => a -> a -> a -> a
+foldToRange i j =
+    let f n = if n > j
+              then f (j - (n - j))
+              else if n < i
+                   then f (i - (n - i))
+                   else n
+    in f
+
+-- | Variant of 'foldToRange' with @SC3@ argument ordering.
+fold_ :: (Ord a,Num a) => a -> a -> a -> a
+fold_ n i j = foldToRange i j n
diff --git a/Sound/SC3/Common/Math/Interpolate.hs b/Sound/SC3/Common/Math/Interpolate.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Math/Interpolate.hs
@@ -0,0 +1,108 @@
+-- | Interpolation functions, ie. for envelope segments.
+module Sound.SC3.Common.Math.Interpolate where
+
+import Sound.SC3.Common.Math {- hsc3 -}
+
+-- | An interpolation function takes three arguments. /x0/ is the left
+-- or begin value, /x1/ is the right or end value, and /t/ is a (0,1)
+-- index.
+type Interpolation_F t = t -> t -> t -> t
+
+-- | Clip /x/ to (0,1) and run /f/.
+--
+-- > interpolate linear (-1,1) 0.5 == 0
+interpolate :: (Num t,Ord t) => Interpolation_F t -> (t,t) -> t -> t
+interpolate f (l,r) x = if x < 0 then l else if x > 1 then r else f l r x
+
+-- | Step function, ignores /t/ and returns /x1/.
+step :: Interpolation_F t
+step _ x1 _ = x1
+
+-- | Linear interpolation.
+--
+-- > import Sound.SC3.Plot {- hsc3-plot -}
+-- > plotTable1 (map (linear (-1) 1) [0,0.01 .. 1])
+linear :: Num t => Interpolation_F t
+linear x0 x1 t = t * (x1 - x0) + x0
+
+-- | Exponential interpolation, /x0/ must not be @0@, (/x0/,/x1/) must
+-- not span @0@.
+--
+-- > plotTable1 (map (exponential 0.001 1) [0,0.01 .. 1])
+exponential :: Floating t => Interpolation_F t
+exponential x0 x1 t = x0 * ((x1 / x0) ** t)
+
+-- | Variant that allows /x0/ to be @0@, though (/x0/,/x1/) must not
+-- span @0@.
+--
+-- > plotTable1 (map (exponential' 0 1) [0,0.01 .. 1])
+-- > plotTable1 (map (exponential' 0 (-1)) [0,0.01 .. 1])
+exponential' :: (Eq t,Floating t) => Interpolation_F t
+exponential' x0 x1 =
+    let epsilon = 1e-6
+        x0' = if x0 == 0 then epsilon * signum x1 else x0
+    in exponential x0' x1
+
+-- | 'linear' of 'exponential'', ie. allows (/x0/,/x1/) to span @0@.
+--
+-- > plotTable1 (map (exponential'' (-1) 1) [0,0.01 .. 1])
+exponential'' :: (Eq t,Floating t) => Interpolation_F t
+exponential'' x0 x1 t = linear x0 x1 (exponential' 0 1 t)
+
+-- | 'linear' with /t/ transformed by sine function over (-pi/2,pi/2).
+--
+-- > plotTable1 (map (sine (-1) 1) [0,0.01 .. 1])
+sine :: Floating t => Interpolation_F t
+sine x0 x1 t =
+    let t' = - cos (pi * t) * 0.5 + 0.5
+    in linear x0 x1 t'
+
+-- | If /x0/ '<' /x1/ rising sine segment (0,pi/2), else falling
+-- segment (pi/2,pi).
+--
+-- > plotTable1 (map (welch (-1) 1) [0,0.01 .. 1])
+-- > plotTable1 (map (welch 1 (-1)) [0,0.01 .. 1])
+welch :: (Ord t, Floating t) => Interpolation_F t
+welch x0 x1 t =
+    if x0 < x1
+    then x0 + (x1 - x0) * sin (half_pi * t)
+    else x1 - (x1 - x0) * sin (half_pi - (half_pi * t))
+
+-- | Curvature controlled by single parameter /c/.  @0@ is 'linear',
+-- increasing /c/ approaches 'exponential'.
+--
+-- > plotTable (map (\c-> map (curve c (-1) 1) [0,0.01 .. 1]) [-6,-4 .. 6])
+curve :: (Ord t, Floating t) => t -> Interpolation_F t
+curve c x0 x1 t =
+    if abs c < 0.0001
+    then t * (x1 - x0) + x0
+    else let d = 1 - exp c
+             n = 1 - exp (t * c)
+         in x0 + (x1 - x0) * (n/d)
+
+-- | Square of 'linear' of 'sqrt' of /x0/ and /x1/, therefore neither
+-- may be negative.
+--
+-- > plotTable1 (map (squared 0 1) [0,0.01 .. 1])
+squared :: Floating t => Interpolation_F t
+squared x0 x1 t =
+    let x0' = sqrt x0
+        x1' = sqrt x1
+        l = linear x0' x1' t
+    in l * l
+
+-- | Cubic variant of 'squared'.
+--
+-- > plotTable1 (map (cubed 0 1) [0,0.01 .. 1])
+cubed :: Floating t => Interpolation_F t
+cubed x0 x1 t =
+    let x0' = x0 ** (1/3)
+        x1' = x1 ** (1/3)
+        l = linear x0' x1' t
+    in l * l * l
+
+-- | x0 until end, then immediately x1.
+--
+-- > plotTable1 (map (hold 0 1) [0,0.01 .. 1])
+hold :: (Num t,Ord t) => Interpolation_F t
+hold x0 x1 t = if t >= 1 then x1 else x0
diff --git a/Sound/SC3/Common/Math/Window.hs b/Sound/SC3/Common/Math/Window.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Math/Window.hs
@@ -0,0 +1,82 @@
+-- | Windowing functions.
+module Sound.SC3.Common.Math.Window where
+
+-- * Type and conversion
+
+-- | A function from a \(0,1)\ normalised input to an output.
+type Window x = x -> x
+
+-- | A discrete /n/ element rendering of a 'Window'.
+type Table x = [x]
+
+-- | Generate an /n/ element table from a \(0,1)\ normalised window
+-- function.
+window_table :: (Integral n,Fractional a,Enum a) => n -> Window a -> Table a
+window_table n f =
+    let k = 1 / (fromIntegral n - 1)
+    in map f [0,k..1]
+
+-- * Math
+
+-- | /n/ ^ 2.
+square :: Num a => a -> a
+square x = x * x
+
+-- * Window functions
+
+-- | Gaussian window, θ <= 0.5.
+gaussian :: Floating a => a -> Window a
+gaussian theta i = exp (- (0.5 * square ((i - 0.5) / (theta * 0.5))))
+
+-- | Hann raised cosine window.
+hann :: Floating a => Window a
+hann i = 0.5 * (1 - cos (2 * pi * i))
+
+-- | Hamming raised cosine window.
+hamming :: Floating a => Window a
+hamming i = 0.54 - 0.46 * cos (2 * pi * i)
+
+-- | Unit ('id') window, also known as a Dirichlet window.
+rectangular :: Window a
+rectangular = id
+
+-- | 'sin' window.
+sine :: Floating a => Window a
+sine i = sin (i * pi)
+
+-- | Triangular window, ie. Bartlett window with zero end-points.
+triangular :: Fractional a => Window a
+triangular i = 2 * (0.5 - abs (i - 0.5))
+
+-- * Tables
+
+-- | 'window_table' . 'gaussian'.
+--
+-- > import Sound.SC3.Plot
+-- > plotTable [gaussian_table 1024 0.25,gaussian_table 1024 0.5]
+gaussian_table :: (Integral n, Floating b, Enum b) => n -> b -> [b]
+gaussian_table n = window_table n . gaussian
+
+-- | 'window_table' . 'hamming'.
+--
+-- > plotTable [hann_table 128,hamming_table 128]
+hamming_table :: Int -> [Double]
+hamming_table n = window_table n hamming
+
+-- | 'window_table' . 'hann'.
+--
+-- > plotTable [hann_table 128]
+hann_table :: Int -> [Double]
+hann_table n = window_table n hann
+
+-- | 'window_table' . 'sine'.
+--
+-- plotTable [sine_table 128]
+sine_table :: (Integral n, Floating b, Enum b) => n -> [b]
+sine_table n = window_table n sine
+
+-- | 'window_table' . 'triangular'.
+--
+-- plotTable [triangular_table (2^9)]
+triangular_table :: (Integral n, Fractional b, Enum b) => n -> [b]
+triangular_table n = window_table n triangular
diff --git a/Sound/SC3/Common/Monad.hs b/Sound/SC3/Common/Monad.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Monad.hs
@@ -0,0 +1,24 @@
+module Sound.SC3.Common.Monad where
+
+import Control.Monad {- base -}
+
+-- | 'sequence' of 'repeat'
+repeatM :: Monad m => m t -> m [t]
+repeatM = sequence . repeat
+
+-- | 'void' of 'repeatM'.
+repeatM_ :: Monad m => m t -> m ()
+repeatM_ = void . repeatM
+
+-- | Right to left compositon of 'Monad' functions.
+--
+-- > fmap (== 7) (composeM [return . (+ 1),return . (/ 2)] 3)
+-- > fmap (== 8) (composeM [return . (* 2),return . (+ 1)] 3)
+composeM :: Monad m => [a -> m a] -> a -> m a
+composeM = foldr (<=<) return
+
+-- | Feed forward composition of /n/ applications of /f/.
+--
+-- > fmap (== 3) (chainM 3 (return . (+ 1)) 0)
+chainM :: Monad m => Int -> (b -> m b) -> b -> m b
+chainM n f = foldr (<=<) return (replicate n f)
diff --git a/Sound/SC3/Common/Monad/Operators.hs b/Sound/SC3/Common/Monad/Operators.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Monad/Operators.hs
@@ -0,0 +1,92 @@
+-- | Functions to make writing 'Applicative' and 'Monad' UGen graphs
+-- less clumsy.
+module Sound.SC3.Common.Monad.Operators where
+
+import Control.Applicative {- base -}
+
+infixl 7  .*,*.,.*.
+infixl 6  .+,+.,.+.
+
+infixl 7  ./,/.,./.
+infixl 6  .-,-.,.-.
+
+-- | '+' variant with 'Functor' at left.
+--
+-- > fmap (== 5) (return 3 .+ 2)
+-- > [3,4] .+ 2 == [5,6]
+(.+) :: (Functor f, Num a) => f a -> a -> f a
+m .+ n = fmap (+ n) m
+
+-- | '+' variant with 'Functor' at right.
+--
+-- > fmap (== 5) (3 +. return 2)
+-- > 3 +. [2,3] == [5,6]
+(+.) :: (Functor f, Num a) => a -> f a -> f a
+m +. n = fmap (+ m) n
+
+-- | '+' variant with 'Applicative' at left and right.
+--
+-- > fmap (== 5) (return 3 .+. return 2)
+-- > [3,4] .+. [2,3] == [5,6,6,7]
+-- > getZipList (ZipList [3,4] .+. ZipList [2,3]) == [5,7]
+(.+.) :: (Applicative m, Num a) => m a -> m a -> m a
+(.+.) = liftA2 (+)
+
+-- | '*' variant with 'Functor' at left.
+--
+-- > fmap (== 6) (return 3 .* 2)
+(.*) :: (Functor f, Num a) => f a -> a -> f a
+m .* n = fmap (* n) m
+
+-- | '*' variant with 'Functor' at right.
+--
+-- > fmap (== 6) (3 *. return 2)
+(*.) :: (Functor f, Num a) => a -> f a -> f a
+m *. n = fmap (* m) n
+
+-- | '*' variant with 'Applicative' at left and right.
+--
+-- > fmap (== 6) (return 3 .*. return 2)
+(.*.) :: (Applicative m, Num a) => m a -> m a -> m a
+(.*.) = liftA2 (*)
+
+-- | '-' variant with 'Functor' at left.
+--
+-- > fmap (== 1) (return 3 .- 2)
+-- > [3,4] .- 2 == [1,2]
+(.-) :: (Functor f, Num a) => f a -> a -> f a
+m .- n = fmap (subtract n) m
+
+-- | '-' variant with 'Functor' at right.
+--
+-- > fmap (== 1) (3 -. return 2)
+-- > 3 -. [2,3] == [1,0]
+(-.) :: (Functor f, Num a) => a -> f a -> f a
+m -. n = fmap (m -) n
+
+-- | '-' variant with 'Applicative' at left and right.
+--
+-- > fmap (== 1) (return 3 .-. return 2)
+-- > [3,4] .-. [2,3] == [1,0,2,1]
+-- > getZipList (ZipList [3,4] .-. ZipList [2,3]) == [1,1]
+(.-.) :: (Applicative m, Num a) => m a -> m a -> m a
+(.-.) = liftA2 (-)
+
+-- | '/' variant with 'Functor' at left.
+--
+-- > fmap (== 3) (return 6 ./ 2)
+(./) :: (Functor f,Fractional a) => f a -> a -> f a
+m ./ n = fmap (/ n) m
+
+-- | '/' variant with 'Functor' at right.
+--
+-- > fmap (== 3) (6 /. return 2)
+(/.) :: (Functor f,Fractional a) => a -> f a -> f a
+m /. n = fmap (m /) n
+
+-- | '/' variant with 'Applicative' at left and right.
+--
+-- > fmap (== 3) (return 6 ./. return 2)
+-- > [5,6] ./. [2,3] == [5/2,5/3,3,2]
+(./.) :: (Applicative m,Fractional a) => m a -> m a -> m a
+(./.) = liftA2 (/)
diff --git a/Sound/SC3/Common/Monad/Syntax.hs b/Sound/SC3/Common/Monad/Syntax.hs
deleted file mode 100644
--- a/Sound/SC3/Common/Monad/Syntax.hs
+++ /dev/null
@@ -1,106 +0,0 @@
--- | Functions to make writing 'Applicative' and 'Monad' UGen graphs
--- less clumsy.
-module Sound.SC3.Common.Monad.Syntax where
-
-import Control.Applicative {- base -}
-import Control.Monad {- base -}
-
-infixl 7  .*,*.,.*.
-infixl 6  .+,+.,.+.
-
-infixl 7  ./,/.,./.
-infixl 6  .-,-.,.-.
-
--- | '+' variant with 'Functor' at left.
---
--- > fmap (== 5) (return 3 .+ 2)
--- > [3,4] .+ 2 == [5,6]
-(.+) :: (Functor f, Num a) => f a -> a -> f a
-m .+ n = fmap (+ n) m
-
--- | '+' variant with 'Functor' at right.
---
--- > fmap (== 5) (3 +. return 2)
--- > 3 +. [2,3] == [5,6]
-(+.) :: (Functor f, Num a) => a -> f a -> f a
-m +. n = fmap (+ m) n
-
--- | '+' variant with 'Applicative' at left and right.
---
--- > fmap (== 5) (return 3 .+. return 2)
--- > [3,4] .+. [2,3] == [5,6,6,7]
--- > getZipList (ZipList [3,4] .+. ZipList [2,3]) == [5,7]
-(.+.) :: (Applicative m, Num a) => m a -> m a -> m a
-(.+.) = liftA2 (+)
-
--- | '*' variant with 'Functor' at left.
---
--- > fmap (== 6) (return 3 .* 2)
-(.*) :: (Functor f, Num a) => f a -> a -> f a
-m .* n = fmap (* n) m
-
--- | '*' variant with 'Functor' at right.
---
--- > fmap (== 6) (3 *. return 2)
-(*.) :: (Functor f, Num a) => a -> f a -> f a
-m *. n = fmap (* m) n
-
--- | '*' variant with 'Applicative' at left and right.
---
--- > fmap (== 6) (return 3 .*. return 2)
-(.*.) :: (Applicative m, Num a) => m a -> m a -> m a
-(.*.) = liftA2 (*)
-
--- | '-' variant with 'Functor' at left.
---
--- > fmap (== 1) (return 3 .- 2)
--- > [3,4] .- 2 == [1,2]
-(.-) :: (Functor f, Num a) => f a -> a -> f a
-m .- n = fmap (subtract n) m
-
--- | '-' variant with 'Functor' at right.
---
--- > fmap (== 1) (3 -. return 2)
--- > 3 -. [2,3] == [1,0]
-(-.) :: (Functor f, Num a) => a -> f a -> f a
-m -. n = fmap (m -) n
-
--- | '-' variant with 'Applicative' at left and right.
---
--- > fmap (== 1) (return 3 .-. return 2)
--- > [3,4] .-. [2,3] == [1,0,2,1]
--- > getZipList (ZipList [3,4] .-. ZipList [2,3]) == [1,1]
-(.-.) :: (Applicative m, Num a) => m a -> m a -> m a
-(.-.) = liftA2 (-)
-
--- | '/' variant with 'Functor' at left.
---
--- > fmap (== 3) (return 6 ./ 2)
-(./) :: (Functor f,Fractional a) => f a -> a -> f a
-m ./ n = fmap (/ n) m
-
--- | '/' variant with 'Functor' at right.
---
--- > fmap (== 3) (6 /. return 2)
-(/.) :: (Functor f,Fractional a) => a -> f a -> f a
-m /. n = fmap (m /) n
-
--- | '/' variant with 'Applicative' at left and right.
---
--- > fmap (== 3) (return 6 ./. return 2)
--- > [5,6] ./. [2,3] == [5/2,5/3,3,2]
-(./.) :: (Applicative m,Fractional a) => m a -> m a -> m a
-(./.) = liftA2 (/)
-
--- | Right to left compositon of 'Monad' functions.
---
--- > fmap (== 7) (composeM [return . (+ 1),return . (/ 2)] 3)
--- > fmap (== 8) (composeM [return . (* 2),return . (+ 1)] 3)
-composeM :: Monad m => [a -> m a] -> a -> m a
-composeM f = foldr (<=<) return f
-
--- | Feed forward composition of /n/ applications of /f/.
---
--- > fmap (== 3) (chainM 3 (return . (+ 1)) 0)
-chainM :: Monad m => Int -> (b -> m b) -> b -> m b
-chainM n f = foldr (<=<) return (replicate n f)
diff --git a/Sound/SC3/Common/Prelude.hs b/Sound/SC3/Common/Prelude.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Prelude.hs
@@ -0,0 +1,139 @@
+module Sound.SC3.Common.Prelude where
+
+import Data.Char {- base -}
+import Data.List {- base -}
+
+-- | Variant of 'reads' requiring exact match.
+reads_exact :: Read a => String -> Maybe a
+reads_exact s =
+    case reads s of
+      [(r,"")] -> Just r
+      _ -> Nothing
+
+-- * STRING / CASE
+
+-- | CI = Case insensitive, CS = case sensitive.
+data Case_Rule = CI | CS deriving (Eq)
+
+-- | Predicates for 'Case_Rule'.
+is_ci :: Case_Rule -> Bool
+is_ci = (==) CI
+
+-- | Predicates for 'Case_Rule'.
+is_cs :: Case_Rule -> Bool
+is_cs = (==) CS
+
+-- | String equality with 'Case_Rule'.
+--
+-- > string_eq CI "lower" "LOWER" == True
+string_eq :: Case_Rule -> String -> String -> Bool
+string_eq cr x y = if is_ci cr then map toLower x == map toLower y else x == y
+
+-- | 'rlookup_by' of 'string_eq'.
+rlookup_str :: Case_Rule -> String -> [(a,String)] -> Maybe a
+rlookup_str = rlookup_by . string_eq
+
+-- | 'Enum' parser with 'Case_Rule'.
+--
+-- > parse_enum CI "FALSE" == Just False
+parse_enum :: (Show t,Enum t,Bounded t) => Case_Rule -> String -> Maybe t
+parse_enum cr nm =
+    let u = [minBound .. maxBound]
+        t = zip (map show u) u
+    in lookup_by (string_eq cr) nm t
+
+-- * LIST
+
+-- > d_dx [0,1,3,6] == [0,1,2,3]
+d_dx :: (Num a) => [a] -> [a]
+d_dx l = zipWith (-) l (0:l)
+
+-- > dx_d (d_dx [0,1,3,6]) == [0,1,3,6]
+-- > dx_d [0.5,0.5] == [0.5,1]
+dx_d :: Num n => [n] -> [n]
+dx_d = scanl1 (+)
+
+-- > d_dx' [0,1,3,6] == [1,2,3]
+d_dx' :: Num n => [n] -> [n]
+d_dx' l = zipWith (-) (tail l) l
+
+-- > dx_d' (d_dx' [0,1,3,6]) == [0,1,3,6]
+-- > dx_d' [0.5,0.5] == [0,0.5,1]
+dx_d' :: Num n => [n] -> [n]
+dx_d' = (0 :) . scanl1 (+)
+
+-- | 'lookup' with equality function.
+lookup_by :: (a -> a -> Bool) -> a -> [(a,b)] -> Maybe b
+lookup_by f x = fmap snd . find (f x . fst)
+
+-- | Reverse 'lookup' with equality function.
+rlookup_by :: (b -> b -> Bool) -> b -> [(a,b)] -> Maybe a
+rlookup_by f x = fmap fst . find (f x . snd)
+
+-- | (prev,cur,next) triples.
+--
+-- > pcn_triples [1..3] == [(Nothing,1,Just 2),(Just 1,2,Just 3),(Just 2,3,Nothing)]
+pcn_triples :: [a] -> [(Maybe a,a,Maybe a)]
+pcn_triples =
+    let f e l = case l of
+                  e1 : e2 : l' -> (e,e1,Just e2) : f (Just e1) (e2 : l')
+                  [e'] -> [(e,e',Nothing)]
+                  [] -> undefined
+    in f Nothing
+
+-- | Separate first list element.
+--
+-- > sep_first "astring" == Just ('a',"string")
+sep_first :: [t] -> Maybe (t,[t])
+sep_first l =
+    case l of
+      e:l' -> Just (e,l')
+      _ -> Nothing
+
+-- | Separate last list element.
+--
+-- > sep_last "stringb" == Just ("string",'b')
+sep_last :: [t] -> Maybe ([t], t)
+sep_last =
+    let f (e,l) = (reverse l,e)
+    in fmap f . sep_first . reverse
+
+-- | Are lists of equal length?
+--
+-- > equal_length_p ["t1","t2"] == True
+-- > equal_length_p ["t","t1","t2"] == False
+equal_length_p :: [[a]] -> Bool
+equal_length_p = (== 1) . length . nub . map length
+
+-- | Histogram
+histogram :: Ord a => [a] -> [(a,Int)]
+histogram x =
+    let g = group (sort x)
+    in zip (map head g) (map length g)
+
+-- * TUPLES
+
+type T2 a = (a,a)
+type T3 a = (a,a,a)
+type T4 a = (a,a,a,a)
+
+dup2 :: t -> T2 t
+dup2 t = (t,t)
+
+dup3 :: t -> T3 t
+dup3 t = (t,t,t)
+
+dup4 :: t -> T4 t
+dup4 t = (t,t,t,t)
+
+-- | 'concatMap' of /f/ at /x/ and /g/ at /y/.
+mk_duples :: (a -> c) -> (b -> c) -> [(a, b)] -> [c]
+mk_duples a b = concatMap (\(x,y) -> [a x, b y])
+
+-- | Length prefixed list variant of 'mk_duples'.
+mk_duples_l :: (Int -> c) -> (a -> c) -> (b -> c) -> [(a,[b])] -> [c]
+mk_duples_l i a b = concatMap (\(x,y) -> a x : i (length y) : map b y)
+
+-- | 'concatMap' of /f/ at /x/ and /g/ at /y/ and /h/ at /z/.
+mk_triples :: (a -> d) -> (b -> d) -> (c -> d) -> [(a, b, c)] -> [d]
+mk_triples a b c = concatMap (\(x,y,z) -> [a x, b y, c z])
diff --git a/Sound/SC3/FD.hs b/Sound/SC3/FD.hs
--- a/Sound/SC3/FD.hs
+++ b/Sound/SC3/FD.hs
@@ -1,7 +1,8 @@
--- | Composite of "Sound.SC3.Server.FD" and "Sound.SC3.UGen" and "Sound.SC3.UGen.Bindings".
+-- | Composite of "Sound.SC3.Common", "Sound.SC3.Server.FD",
+--   "Sound.SC3.UGen" and "Sound.SC3.UGen.Bindings".
 module Sound.SC3.FD (module M) where
 
+import Sound.SC3.Common as M
 import Sound.SC3.Server.FD as M
 import Sound.SC3.UGen as M
-
 import Sound.SC3.UGen.Bindings as M
diff --git a/Sound/SC3/Server/Command/Completion.hs b/Sound/SC3/Server/Command/Completion.hs
--- a/Sound/SC3/Server/Command/Completion.hs
+++ b/Sound/SC3/Server/Command/Completion.hs
@@ -4,81 +4,64 @@
 -- that this mechanism is for synchronizing server side processes only, for
 -- client side synchronization use @\/done@ message notification or the
 -- @\/sync@ barrier.
-module Sound.SC3.Server.Command.Completion
-  ( -- *Synthdef handling
-   d_recv'
-  ,d_load'
-  ,d_loadDir'
-  -- *Buffer allocation
-  ,b_alloc'
-  ,b_allocRead'
-  ,b_allocReadChannel'
-  ,b_free'
-  ,b_close'
-  -- *Buffer reading
-  ,b_read'
-  ,b_readChannel'
-  -- *Buffer writing
-  ,b_write'
-  -- *Buffer operations
-  ,b_zero'
-  ) where
+module Sound.SC3.Server.Command.Completion where
 
 import Sound.OSC {- hosc -}
+
 import Sound.SC3.Server.Enum
 import Sound.SC3.Server.Synthdef
 
--- Encode an OSC packet as an OSC blob.
-encode_blob :: OSC o => o -> Datum
-encode_blob = Blob . encodeOSC
+-- | Encode an OSC packet as an OSC blob.
+encode_blob :: Packet -> Datum
+encode_blob = Blob . encodePacket
 
 -- | Install a bytecode instrument definition. (Asynchronous)
-d_recv' :: OSC o => o -> Synthdef -> Message
-d_recv' osc d = message "/d_recv" [Blob (synthdefData d),encode_blob osc]
+d_recv :: Packet -> Synthdef -> Message
+d_recv osc d = Message "/d_recv" [Blob (synthdefData d),encode_blob osc]
 
 -- | Load an instrument definition from a named file. (Asynchronous)
-d_load' :: OSC o => o -> String -> Message
-d_load' osc p = message "/d_load" [string p,encode_blob osc]
+d_load :: Packet -> String -> Message
+d_load osc p = Message "/d_load" [string p,encode_blob osc]
 
 -- | Load a directory of instrument definitions files. (Asynchronous)
-d_loadDir' :: OSC o => o -> String -> Message
-d_loadDir' osc p = message "/d_loadDir" [string p,encode_blob osc]
+d_loadDir :: Packet -> String -> Message
+d_loadDir osc p = Message "/d_loadDir" [string p,encode_blob osc]
 
 -- | Allocates zero filled buffer to number of channels and samples. (Asynchronous)
-b_alloc' :: OSC o => o -> Int -> Int -> Int -> Message
-b_alloc' osc nid frames channels = message "/b_alloc" [int32 nid,int32 frames,int32 channels,encode_blob osc]
+b_alloc :: Packet -> Int -> Int -> Int -> Message
+b_alloc osc nid frames channels = Message "/b_alloc" [int32 nid,int32 frames,int32 channels,encode_blob osc]
 
 -- | Allocate buffer space and read a sound file. (Asynchronous)
-b_allocRead' :: OSC o => o -> Int -> String -> Int -> Int -> Message
-b_allocRead' osc nid p f n = message "/b_allocRead" [int32 nid,string p,int32 f,int32 n,encode_blob osc]
+b_allocRead :: Packet -> Int -> String -> Int -> Int -> Message
+b_allocRead osc nid p f n = Message "/b_allocRead" [int32 nid,string p,int32 f,int32 n,encode_blob osc]
 
 -- | Allocate buffer space and read a sound file, picking specific channels. (Asynchronous)
-b_allocReadChannel' :: OSC o => o -> Int -> String -> Int -> Int -> [Int] -> Message
-b_allocReadChannel' osc nid p f n cs = message "/b_allocReadChannel" ([int32 nid,string p,int32 f,int32 n] ++ map int32 cs ++ [encode_blob osc])
+b_allocReadChannel :: Packet -> Int -> String -> Int -> Int -> [Int] -> Message
+b_allocReadChannel osc nid p f n cs = Message "/b_allocReadChannel" ([int32 nid,string p,int32 f,int32 n] ++ map int32 cs ++ [encode_blob osc])
 
 -- | Free buffer data. (Asynchronous)
-b_free' :: OSC o => o -> Int -> Message
-b_free' osc nid = message "/b_free" [int32 nid,encode_blob osc]
+b_free :: Packet -> Int -> Message
+b_free osc nid = Message "/b_free" [int32 nid,encode_blob osc]
 
 -- | Close attached soundfile and write header information. (Asynchronous)
-b_close' :: OSC o => o -> Int -> Message
-b_close' osc nid = message "/b_close" [int32 nid,encode_blob osc]
+b_close :: Packet -> Int -> Message
+b_close osc nid = Message "/b_close" [int32 nid,encode_blob osc]
 
 -- | Read sound file data into an existing buffer. (Asynchronous)
-b_read' :: OSC o => o -> Int -> String -> Int -> Int -> Int -> Bool -> Message
-b_read' osc nid p f n f' z = message "/b_read" [int32 nid,string p,int32 f,int32 n,int32 f',int32 (fromEnum z),encode_blob osc]
+b_read :: Packet -> Int -> String -> Int -> Int -> Int -> Bool -> Message
+b_read osc nid p f n f' z = Message "/b_read" [int32 nid,string p,int32 f,int32 n,int32 f',int32 (fromEnum z),encode_blob osc]
 
 -- | Read sound file data into an existing buffer. (Asynchronous)
-b_readChannel' :: OSC o => o -> Int -> String -> Int -> Int -> Int -> Bool -> [Int] -> Message
-b_readChannel' osc nid p f n f' z cs = message "/b_readChannel" ([int32 nid,string p,int32 f,int32 n,int32 f',int32 (fromEnum z)] ++ map int32 cs ++ [encode_blob osc])
+b_readChannel :: Packet -> Int -> String -> Int -> Int -> Int -> Bool -> [Int] -> Message
+b_readChannel osc nid p f n f' z cs = Message "/b_readChannel" ([int32 nid,string p,int32 f,int32 n,int32 f',int32 (fromEnum z)] ++ map int32 cs ++ [encode_blob osc])
 
 -- | Write sound file data. (Asynchronous)
-b_write' :: OSC o => o -> Int -> String -> SoundFileFormat -> SampleFormat -> Int -> Int -> Bool -> Message
-b_write' osc nid p h t f s z = message "/b_write" [int32 nid,string p,string (soundFileFormatString h),string (sampleFormatString t),int32 f,int32 s,int32 (fromEnum z),encode_blob osc]
+b_write :: Packet -> Int -> String -> SoundFileFormat -> SampleFormat -> Int -> Int -> Bool -> Message
+b_write osc nid p h t f s z = Message "/b_write" [int32 nid,string p,string (soundFileFormatString h),string (sampleFormatString t),int32 f,int32 s,int32 (fromEnum z),encode_blob osc]
 
 -- | Zero sample data. (Asynchronous)
-b_zero' :: OSC o => o -> Int -> Message
-b_zero' osc nid = message "/b_zero" [int32 nid,encode_blob osc]
+b_zero :: Packet -> Int -> Message
+b_zero osc nid = Message "/b_zero" [int32 nid,encode_blob osc]
 
 -- Local Variables:
 -- truncate-lines:t
diff --git a/Sound/SC3/Server/Command/Enum.hs b/Sound/SC3/Server/Command/Enum.hs
--- a/Sound/SC3/Server/Command/Enum.hs
+++ b/Sound/SC3/Server/Command/Enum.hs
@@ -3,8 +3,9 @@
 
 import Data.List {- base -}
 import Data.Maybe {- base -}
-import Sound.OSC.Type {- hosc -}
 
+import Sound.OSC.Packet {- hosc -}
+
 -- | SC3 server commands are strings.
 type SC3_Command = String
 
@@ -104,7 +105,7 @@
 known_sc3_cmd :: SC3_Command -> Bool
 known_sc3_cmd = isJust . sc3_cmd_number
 
--- | List of asynchronous server commands.
+-- | List of asynchronous server commands, ie. commands that reply with @/done@.
 async_cmds :: [SC3_Command]
 async_cmds =
     ["/b_alloc"
@@ -125,7 +126,8 @@
 
 -- | 'True' if 'Message' is an asynchronous 'Message'.
 --
--- > map isAsync [b_close 0,n_set1 0 "0" 0] == [True,False]
+-- > import Sound.SC3
+-- > map isAsync [b_close 0,n_set1 0 "0" 0,status] == [True,False,False]
 isAsync :: Message -> Bool
 isAsync (Message a _) = a `elem` async_cmds
 
@@ -135,3 +137,23 @@
 -- > partition_async [b_close 0,n_set1 0 "0" 0]
 partition_async :: [Message] -> ([Message],[Message])
 partition_async = partition isAsync
+
+-- | Types & names for @b_info@ message fields.
+b_info_fields :: [(String,String)]
+b_info_fields =
+    [("int","buffer-id")
+    ,("int","frame-count")
+    ,("int","channels-count")
+    ,("float","sample-rate")]
+
+-- | Type, name and value descriptors for fields of @n_info@ message.
+n_info_fields :: [(String,String,String)]
+n_info_fields =
+    [("int","node-id","")
+    ,("int","parent group-id","-1 = nil")
+    ,("int","previous node-id","-1 = nil")
+    ,("int","next node-id","-1 = nil")
+    ,("int","node-type","0 = synth,1 = group")
+    ,("int","head node-id","-1 = nil")
+    ,("int","tail node-id","-1 = nil")]
+
diff --git a/Sound/SC3/Server/Command/Generic.hs b/Sound/SC3/Server/Command/Generic.hs
--- a/Sound/SC3/Server/Command/Generic.hs
+++ b/Sound/SC3/Server/Command/Generic.hs
@@ -3,89 +3,90 @@
 
 import Data.List {- base -}
 import Data.Maybe {- base -}
+
 import Sound.OSC.Core {- hosc -}
 
-import Sound.SC3.Common
-import Sound.SC3.Server.Command.Enum
-import Sound.SC3.Server.Enum
+import qualified Sound.SC3.Common.Prelude as P
+import qualified Sound.SC3.Server.Command.Enum as C
+import qualified Sound.SC3.Server.Enum as E
 import qualified Sound.SC3.Server.Graphdef as G
-import Sound.SC3.Server.Synthdef
+import qualified Sound.SC3.Server.Synthdef as S
 
 -- * Buffer commands (b_)
 
 -- | Allocates zero filled buffer to number of channels and samples. (Asynchronous)
-b_alloc :: (Integral i) => i -> i -> i -> Message
+b_alloc :: Integral i => i -> i -> i -> Message
 b_alloc nid frames channels = message "/b_alloc" [int32 nid,int32 frames,int32 channels]
 
 -- | Allocate buffer space and read a sound file. (Asynchronous)
-b_allocRead :: (Integral i) => i -> String -> i -> i -> Message
+b_allocRead :: Integral i => i -> String -> i -> i -> Message
 b_allocRead nid p f n = message "/b_allocRead" [int32 nid,string p,int32 f,int32 n]
 
 -- | Allocate buffer space and read a sound file, picking specific channels. (Asynchronous)
-b_allocReadChannel :: (Integral i) => i -> String -> i -> i -> [i] -> Message
+b_allocReadChannel :: Integral i => i -> String -> i -> i -> [i] -> Message
 b_allocReadChannel nid p f n cs = message "/b_allocReadChannel" ([int32 nid,string p,int32 f,int32 n] ++ map int32 cs)
 
 -- | Close attached soundfile and write header information. (Asynchronous)
-b_close :: (Integral i) => i -> Message
+b_close :: Integral i => i -> Message
 b_close nid = message "/b_close" [int32 nid]
 
 -- | Fill ranges of sample values.
 b_fill :: (Integral i,Real n) => i -> [(i,i,n)] -> Message
-b_fill nid l = message "/b_fill" (int32 nid : mk_triples int32 int32 float l)
+b_fill nid l = message "/b_fill" (int32 nid : P.mk_triples int32 int32 float l)
 
 -- | Free buffer data. (Asynchronous)
-b_free :: (Integral i) => i -> Message
+b_free :: Integral i => i -> Message
 b_free nid = message "/b_free" [int32 nid]
 
 -- | Call a command to fill a buffer.  (Asynchronous)
-b_gen :: (Integral i) => i -> String -> [Datum] -> Message
+b_gen :: Integral i => i -> String -> [Datum] -> Message
 b_gen bid name arg = message "/b_gen" (int32 bid : string name : arg)
 
 -- | Call @sine1@ 'b_gen' command.
-b_gen_sine1 :: (Integral i,Real n) => i -> [B_Gen] -> [n] -> Message
-b_gen_sine1 z f n = b_gen z "sine1" (int32 (b_gen_flag f) : map float n)
+b_gen_sine1 :: (Integral i,Real n) => i -> [E.B_Gen] -> [n] -> Message
+b_gen_sine1 z f n = b_gen z "sine1" (int32 (E.b_gen_flag f) : map float n)
 
 -- | Call @sine2@ 'b_gen' command.
-b_gen_sine2 :: (Integral i,Real n) => i -> [B_Gen] -> [(n,n)] -> Message
-b_gen_sine2 z f n = b_gen z "sine2" (int32 (b_gen_flag f) : mk_duples float float n)
+b_gen_sine2 :: (Integral i,Real n) => i -> [E.B_Gen] -> [(n,n)] -> Message
+b_gen_sine2 z f n = b_gen z "sine2" (int32 (E.b_gen_flag f) : P.mk_duples float float n)
 
 -- | Call @sine3@ 'b_gen' command.
-b_gen_sine3 :: (Integral i,Real n) => i -> [B_Gen] -> [(n,n,n)] -> Message
-b_gen_sine3 z f n = b_gen z "sine3" (int32 (b_gen_flag f) : mk_triples float float float n)
+b_gen_sine3 :: (Integral i,Real n) => i -> [E.B_Gen] -> [(n,n,n)] -> Message
+b_gen_sine3 z f n = b_gen z "sine3" (int32 (E.b_gen_flag f) : P.mk_triples float float float n)
 
 -- | Call @cheby@ 'b_gen' command.
-b_gen_cheby :: (Integral i,Real n) => i -> [B_Gen] -> [n] -> Message
-b_gen_cheby z f n = b_gen z "cheby" (int32 (b_gen_flag f) : map float n)
+b_gen_cheby :: (Integral i,Real n) => i -> [E.B_Gen] -> [n] -> Message
+b_gen_cheby z f n = b_gen z "cheby" (int32 (E.b_gen_flag f) : map float n)
 
 -- | Call @copy@ 'b_gen' command.
-b_gen_copy :: (Integral i) => i -> i -> i -> i -> Maybe i -> Message
-b_gen_copy z dst_ix src_b src_ix nf =
+b_gen_copy :: Integral i => i -> i -> i -> i -> Maybe i -> Message
+b_gen_copy dst_b dst_ix src_b src_ix nf =
     let nf' = fromMaybe (-1) nf
-    in b_gen z "copy" (map int32 [dst_ix,src_b,src_ix,nf'])
+    in b_gen dst_b "copy" (map int32 [dst_ix,src_b,src_ix,nf'])
 
 -- | Get sample values.
-b_get :: (Integral i) => i -> [i] -> Message
+b_get :: Integral i => i -> [i] -> Message
 b_get nid i = message "/b_get" (int32 nid : map int32 i)
 
 -- | Get ranges of sample values.
-b_getn :: (Integral i) => i -> [(i,i)] -> Message
-b_getn nid l = message "/b_getn" (int32 nid : mk_duples int32 int32 l)
+b_getn :: Integral i => i -> [(i,i)] -> Message
+b_getn nid l = message "/b_getn" (int32 nid : P.mk_duples int32 int32 l)
 
 -- | Request \/b_info messages.
-b_query :: (Integral i) => [i] -> Message
+b_query :: Integral i => [i] -> Message
 b_query = message "/b_query" . map int32
 
 -- | Read sound file data into an existing buffer. (Asynchronous)
-b_read :: (Integral i) => i -> String -> i -> i -> i -> Bool -> Message
+b_read :: Integral i => i -> String -> i -> i -> i -> Bool -> Message
 b_read nid p f n f' z = message "/b_read" [int32 nid,string p,int32 f,int32 n,int32 f',int32 (fromEnum z)]
 
 -- | Read sound file data into an existing buffer, picking specific channels. (Asynchronous)
-b_readChannel :: (Integral i) => i -> String -> i -> i -> i -> Bool -> [i] -> Message
+b_readChannel :: Integral i => i -> String -> i -> i -> i -> Bool -> [i] -> Message
 b_readChannel nid p f n f' z cs = message "/b_readChannel" ([int32 nid,string p,int32 f,int32 n,int32 f',int32 (fromEnum z)] ++ map int32 cs)
 
 -- | Set sample values.
 b_set :: (Integral i,Real n) => i -> [(i,n)] -> Message
-b_set nid l = message "/b_set" (int32 nid : mk_duples int32 float l)
+b_set nid l = message "/b_set" (int32 nid : P.mk_duples int32 float l)
 
 -- | Set ranges of sample values.
 b_setn :: (Integral i,Real n) => i -> [(i,[n])] -> Message
@@ -94,30 +95,33 @@
     in message "/b_setn" (int32 nid : concatMap f l)
 
 -- | Write sound file data. (Asynchronous)
-b_write :: (Integral i) => i -> String -> SoundFileFormat -> SampleFormat -> i -> i -> Bool -> Message
-b_write nid p h t f s z = message "/b_write" [int32 nid,string p,string (soundFileFormatString h),string (sampleFormatString t),int32 f,int32 s,int32 (fromEnum z)]
+b_write :: Integral i => i -> String -> E.SoundFileFormat -> E.SampleFormat -> i -> i -> Bool -> Message
+b_write nid p h t f s z =
+    let h' = string (E.soundFileFormatString h)
+        t' = string (E.sampleFormatString t)
+    in message "/b_write" [int32 nid,string p,h',t',int32 f,int32 s,int32 (fromEnum z)]
 
 -- | Zero sample data. (Asynchronous)
-b_zero :: (Integral i) => i -> Message
+b_zero :: Integral i => i -> Message
 b_zero nid = message "/b_zero" [int32 nid]
 
 -- * Control bus commands (c_)
 
 -- |  Fill ranges of bus values.
 c_fill :: (Integral i,Real n) => [(i,i,n)] -> Message
-c_fill = message "/c_fill" . mk_triples int32 int32 float
+c_fill = message "/c_fill" . P.mk_triples int32 int32 float
 
 -- | Get bus values.
-c_get :: (Integral i) => [i] -> Message
+c_get :: Integral i => [i] -> Message
 c_get = message "/c_get" . map int32
 
 -- | Get ranges of bus values.
-c_getn :: (Integral i) => [(i,i)] -> Message
-c_getn = message "/c_getn" . mk_duples int32 int32
+c_getn :: Integral i => [(i,i)] -> Message
+c_getn = message "/c_getn" . P.mk_duples int32 int32
 
 -- | Set bus values.
 c_set :: (Integral i,Real n) => [(i,n)] -> Message
-c_set = message "/c_set" . mk_duples int32 float
+c_set = message "/c_set" . P.mk_duples int32 float
 
 -- | Set ranges of bus values.
 c_setn :: (Integral i,Real n) => [(i,[n])] -> Message
@@ -132,8 +136,8 @@
 d_recv' g = message "/d_recv" [Blob (G.encode_graphdef g)]
 
 -- | Install a bytecode instrument definition. (Asynchronous)
-d_recv :: Synthdef -> Message
-d_recv d = message "/d_recv" [Blob (synthdefData d)]
+d_recv :: S.Synthdef -> Message
+d_recv d = message "/d_recv" [Blob (S.synthdefData d)]
 
 -- | Load an instrument definition from a named file. (Asynchronous)
 d_load :: String -> Message
@@ -150,28 +154,28 @@
 -- * Group node commands (g_)
 
 -- | Free all synths in this group and all its sub-groups.
-g_deepFree :: (Integral i) => [i] -> Message
+g_deepFree :: Integral i => [i] -> Message
 g_deepFree = message "/g_deepFree" . map int32
 
 -- | Delete all nodes in a group.
-g_freeAll :: (Integral i) => [i] -> Message
+g_freeAll :: Integral i => [i] -> Message
 g_freeAll = message "/g_freeAll" . map int32
 
 -- | Add node to head of group.
-g_head :: (Integral i) => [(i,i)] -> Message
-g_head = message "/g_head" . mk_duples int32 int32
+g_head :: Integral i => [(i,i)] -> Message
+g_head = message "/g_head" . P.mk_duples int32 int32
 
 -- | Create a new group.
-g_new :: (Integral i) => [(i,AddAction,i)] -> Message
-g_new = message "/g_new" . mk_triples int32 (int32 . fromEnum) int32
+g_new :: Integral i => [(i,E.AddAction,i)] -> Message
+g_new = message "/g_new" . P.mk_triples int32 (int32 . fromEnum) int32
 
 -- | Add node to tail of group.
-g_tail :: (Integral i) => [(i,i)] -> Message
-g_tail = message "/g_tail" . mk_duples int32 int32
+g_tail :: Integral i => [(i,i)] -> Message
+g_tail = message "/g_tail" . P.mk_duples int32 int32
 
 -- | Post a representation of a group's node subtree, optionally including the current control values for synths.
-g_dumpTree :: (Integral i) => [(i,Bool)] -> Message
-g_dumpTree = message "/g_dumpTree" . mk_duples int32 (int32 . fromEnum)
+g_dumpTree :: Integral i => [(i,Bool)] -> Message
+g_dumpTree = message "/g_dumpTree" . P.mk_duples int32 (int32 . fromEnum)
 
 -- | Request a representation of a group's node subtree, optionally including the current control values for synths.
 --
@@ -198,53 +202,53 @@
 -- > ] * the number of nodes in the subtree
 --
 -- N.B. The order of nodes corresponds to their execution order on the server. Thus child nodes (those contained within a group) are listed immediately following their parent.
-g_queryTree :: (Integral i) => [(i,Bool)] -> Message
-g_queryTree = message "/g_queryTree" . mk_duples int32 (int32 . fromEnum)
+g_queryTree :: Integral i => [(i,Bool)] -> Message
+g_queryTree = message "/g_queryTree" . P.mk_duples int32 (int32 . fromEnum)
 
 -- * Node commands (n_)
 
 -- | Place a node after another.
-n_after :: (Integral i) => [(i,i)] -> Message
-n_after = message "/n_after" . mk_duples int32 int32
+n_after :: Integral i => [(i,i)] -> Message
+n_after = message "/n_after" . P.mk_duples int32 int32
 
 -- | Place a node before another.
-n_before :: (Integral i) => [(i,i)] -> Message
-n_before = message "/n_before" . mk_duples int32 int32
+n_before :: Integral i => [(i,i)] -> Message
+n_before = message "/n_before" . P.mk_duples int32 int32
 
 -- | Fill ranges of a node's control values.
 n_fill :: (Integral i,Real f) => i -> [(String,i,f)] -> Message
-n_fill nid l = message "/n_fill" (int32 nid : mk_triples string int32 float l)
+n_fill nid l = message "/n_fill" (int32 nid : P.mk_triples string int32 float l)
 
 -- | Delete a node.
-n_free :: (Integral i) => [i] -> Message
+n_free :: Integral i => [i] -> Message
 n_free = message "/n_free" . map int32
 
-n_map :: (Integral i) => i -> [(String,i)] -> Message
-n_map nid l = message "/n_map" (int32 nid : mk_duples string int32 l)
+n_map :: Integral i => i -> [(String,i)] -> Message
+n_map nid l = message "/n_map" (int32 nid : P.mk_duples string int32 l)
 
 -- | Map a node's controls to read from buses.
-n_mapn :: (Integral i) => i -> [(String,i,i)] -> Message
-n_mapn nid l = message "/n_mapn" (int32 nid : mk_triples string int32 int32 l)
+n_mapn :: Integral i => i -> [(String,i,i)] -> Message
+n_mapn nid l = message "/n_mapn" (int32 nid : P.mk_triples string int32 int32 l)
 
 -- | Map a node's controls to read from an audio bus.
-n_mapa :: (Integral i) => i -> [(String,i)] -> Message
-n_mapa nid l = message "/n_mapa" (int32 nid : mk_duples string int32 l)
+n_mapa :: Integral i => i -> [(String,i)] -> Message
+n_mapa nid l = message "/n_mapa" (int32 nid : P.mk_duples string int32 l)
 
 -- | Map a node's controls to read from audio buses.
-n_mapan :: (Integral i) => i -> [(String,i,i)] -> Message
-n_mapan nid l = message "/n_mapan" (int32 nid : mk_triples string int32 int32 l)
+n_mapan :: Integral i => i -> [(String,i,i)] -> Message
+n_mapan nid l = message "/n_mapan" (int32 nid : P.mk_triples string int32 int32 l)
 
 -- | Get info about a node.
-n_query :: (Integral i) => [i] -> Message
+n_query :: Integral i => [i] -> Message
 n_query = message "/n_query" . map int32
 
 -- | Turn node on or off.
-n_run :: (Integral i) => [(i,Bool)] -> Message
-n_run = message "/n_run" . mk_duples int32 (int32 . fromEnum)
+n_run :: Integral i => [(i,Bool)] -> Message
+n_run = message "/n_run" . P.mk_duples int32 (int32 . fromEnum)
 
 -- | Set a node's control values.
 n_set :: (Integral i,Real n) => i -> [(String,n)] -> Message
-n_set nid c = message "/n_set" (int32 nid : mk_duples string float c)
+n_set nid c = message "/n_set" (int32 nid : P.mk_duples string float c)
 
 -- | Set ranges of a node's control values.
 n_setn :: (Integral i,Real n) => i -> [(String,[n])] -> Message
@@ -253,41 +257,41 @@
     in message "/n_setn" (int32 nid : concatMap f l)
 
 -- | Trace a node.
-n_trace :: (Integral i) => [i] -> Message
+n_trace :: Integral i => [i] -> Message
 n_trace = message "/n_trace" . map int32
 
 -- | Move an ordered sequence of nodes.
-n_order :: (Integral i) => AddAction -> i -> [i] -> Message
+n_order :: Integral i => E.AddAction -> i -> [i] -> Message
 n_order a n ns = message "/n_order" (int32 (fromEnum a) : int32 n : map int32 ns)
 
 -- * Par commands (p_)
 
 -- | Create a new parallel group (supernova specific).
-p_new :: (Integral i) => [(i,AddAction,i)] -> Message
-p_new = message "/p_new" . mk_triples int32 (int32 . fromEnum) int32
+p_new :: Integral i => [(i,E.AddAction,i)] -> Message
+p_new = message "/p_new" . P.mk_triples int32 (int32 . fromEnum) int32
 
 -- * Synthesis node commands (s_)
 
 -- | Get control values.
-s_get :: (Integral i) => i -> [String] -> Message
+s_get :: Integral i => i -> [String] -> Message
 s_get nid i = message "/s_get" (int32 nid : map string i)
 
 -- | Get ranges of control values.
-s_getn :: (Integral i) => i -> [(String,i)] -> Message
-s_getn nid l = message "/s_getn" (int32 nid : mk_duples string int32 l)
+s_getn :: Integral i => i -> [(String,i)] -> Message
+s_getn nid l = message "/s_getn" (int32 nid : P.mk_duples string int32 l)
 
 -- | Create a new synth.
-s_new :: (Integral i,Real n) => String -> i -> AddAction -> i -> [(String,n)] -> Message
-s_new n i a t c = message "/s_new" (string n : int32 i : int32 (fromEnum a) : int32 t : mk_duples string float c)
+s_new :: (Integral i,Real n) => String -> i -> E.AddAction -> i -> [(String,n)] -> Message
+s_new n i a t c = message "/s_new" (string n : int32 i : int32 (fromEnum a) : int32 t : P.mk_duples string float c)
 
 -- | Auto-reassign synth's ID to a reserved value.
-s_noid :: (Integral i) => [i] -> Message
+s_noid :: Integral i => [i] -> Message
 s_noid = message "/s_noid" . map int32
 
 -- * UGen commands (u_)
 
 -- | Send a command to a unit generator.
-u_cmd :: (Integral i) => i -> i -> String -> [Datum] -> Message
+u_cmd :: Integral i => i -> i -> String -> [Datum] -> Message
 u_cmd nid uid name arg = message "/u_cmd" ([int32 nid,int32 uid,string name] ++ arg)
 
 -- * Server operation commands
@@ -301,15 +305,15 @@
 clearSched = message "/clearSched" []
 
 -- | Select printing of incoming Open Sound Control messages.
-dumpOSC :: PrintLevel -> Message
+dumpOSC :: E.PrintLevel -> Message
 dumpOSC c = message "/dumpOSC" [int32 (fromEnum c)]
 
 -- | Set error posting scope and mode.
-errorMode :: ErrorScope -> ErrorMode -> Message
+errorMode :: E.ErrorScope -> E.ErrorMode -> Message
 errorMode scope mode =
     let e = case scope of
-              Globally -> fromEnum mode
-              Locally  -> -1 - fromEnum mode
+              E.Globally -> fromEnum mode
+              E.Locally  -> -1 - fromEnum mode
     in message "/error" [int32 e]
 
 -- | Select reception of notification messages. (Asynchronous)
@@ -329,24 +333,27 @@
 status = message "/status" []
 
 -- | Request \/synced message when all current asynchronous commands complete.
-sync :: (Integral i) => i -> Message
+sync :: Integral i => i -> Message
 sync sid = message "/sync" [int32 sid]
 
 -- * Modify existing message to include completion message
 
--- | Add a completion message (or bundle, the name is misleading) to
--- an existing asynchronous command.
---
--- > let {m = n_set1 0 "0" 0
--- >     ;m' = encodeMessage m}
--- > in withCM (b_close 0) m == Message "/b_close" [Int 0,Blob m']
-withCM :: OSC o => Message -> o -> Message
-withCM (Message c xs) cm =
-    if c `elem` async_cmds
-    then let xs' = xs ++ [Blob (encodeOSC cm)]
+-- | Add a completion packet to an existing asynchronous command.
+with_completion_packet :: Message -> Packet -> Message
+with_completion_packet (Message c xs) cm =
+    if c `elem` C.async_cmds
+    then let xs' = xs ++ [Blob (encodePacket cm)]
          in Message c xs'
-    else error ("withCM: not async: " ++ c)
+    else error ("with_completion_packet: not async: " ++ c)
 
+-- | Add a completion message to an existing asynchronous command.
+--
+-- > let m = n_set1 0 "0" 0
+-- > let e = encodeMessage m
+-- > withCM (b_close 0) m == Message "/b_close" [Int32 0,Blob e]
+withCM :: Message -> Message -> Message
+withCM m cm = with_completion_packet m (Packet_Message cm)
+
 -- * Variants to simplify common cases
 
 -- | Pre-allocate for b_setn1, values preceding offset are zeroed.
@@ -357,11 +364,11 @@
     in withCM (b_alloc nid k 1) (b_setn1 nid 0 xs')
 
 -- | Get ranges of sample values.
-b_getn1 :: (Integral i) => i -> (i,i) -> Message
+b_getn1 :: Integral i => i -> (i,i) -> Message
 b_getn1 nid = b_getn nid . return
 
 -- | Variant on 'b_query'.
-b_query1 :: (Integral i) => i -> Message
+b_query1 :: Integral i => i -> Message
 b_query1 = b_query . return
 
 -- | Set single sample value.
@@ -372,8 +379,15 @@
 b_setn1 :: (Integral i,Real n) => i -> i -> [n] -> Message
 b_setn1 nid i xs = b_setn nid [(i,xs)]
 
+-- | Segmented variant of 'b_setn1'.
+b_setn1_segmented :: (Integral i,Real n) => i -> i -> i -> [n] -> [Message]
+b_setn1_segmented k b i d =
+    if genericLength d < k
+    then [b_setn1 b i d]
+    else b_setn1 b i (genericTake k d) : b_setn1_segmented k b (i + k) (genericDrop k d)
+
 -- | Get ranges of sample values.
-c_getn1 :: (Integral i) => (i,i) -> Message
+c_getn1 :: Integral i => (i,i) -> Message
 c_getn1 = c_getn . return
 
 -- | Set single bus values.
@@ -384,12 +398,16 @@
 c_setn1 :: (Integral i,Real n) => (i,[n]) -> Message
 c_setn1 = c_setn . return
 
+-- | Turn a single node on or off.
+n_run1 :: Integral i => i -> Bool -> Message
+n_run1 nid k = n_run [(nid,k)]
+
 -- | Set a single node control value.
 n_set1 :: (Integral i,Real n) => i -> String -> n -> Message
 n_set1 nid k n = n_set nid [(k,n)]
 
 -- | @s_new@ with no parameters.
-s_new0 :: (Integral i) => String -> i -> AddAction -> i -> Message
+s_new0 :: Integral i => String -> i -> E.AddAction -> i -> Message
 s_new0 n i a t = s_new n i a t ([]::[(String,Double)])
 
 -- * Buffer segmentation and indices
@@ -398,7 +416,7 @@
 --
 -- > b_segment 1024 2056 == [8,1024,1024]
 -- > b_segment 1 5 == replicate 5 1
-b_segment :: (Integral i) => i -> i -> [i]
+b_segment :: Integral i => i -> i -> [i]
 b_segment n m =
     let (q,r) = m `quotRem` n
         s = genericReplicate q n
@@ -409,19 +427,84 @@
 --
 -- > b_indices 1 5 0 == zip [0..4] (replicate 5 1)
 -- > b_indices 1024 2056 16 == [(16,8),(24,1024),(1048,1024)]
-b_indices :: (Integral i) => i -> i -> i -> [(i,i)]
+b_indices :: Integral i => i -> i -> i -> [(i,i)]
 b_indices n m k =
-    let dx_d = scanl1 (+)
-        s = b_segment n m
-        i = 0 : dx_d s
+    let s = b_segment n m
+        i = 0 : P.dx_d s
     in zip (map (+ k) i) s
 
 -- * UGen commands.
 
 -- | Generate accumulation buffer given time-domain IR buffer and FFT size.
-pc_preparePartConv :: (Integral i) => i -> i -> i -> Message
+pc_preparePartConv :: Integral i => i -> i -> i -> Message
 pc_preparePartConv b irb fft_size =
     b_gen b "PreparePartConv" (map int32 [irb, fft_size])
+
+-- * Unpack
+
+-- | Result is null for non-conforming data, or has five or sevel elements.
+unpack_n_info_datum_plain :: Num i => [Datum] -> [i]
+unpack_n_info_datum_plain m =
+    let to_i = fromIntegral
+    in case m of
+         [Int32 i1,Int32 i2,Int32 i3,Int32 i4,Int32 i5] -> [to_i i1,to_i i2,to_i i3,to_i i4,to_i i5]
+         [Int32 i1,Int32 i2,Int32 i3,Int32 i4,Int32 i5,Int32 i6,Int32 i7] -> [to_i i1,to_i i2,to_i i3,to_i i4,to_i i5,to_i i6,to_i i7]
+         _ -> []
+
+unpack_n_info_plain :: Num i => Message -> [i]
+unpack_n_info_plain m =
+    case m of
+      Message "/n_info" dat -> unpack_n_info_datum_plain dat
+      _ -> []
+
+-- | Unpack @n_info@ message.
+unpack_n_info :: Num i => Message -> Maybe (i,i,i,i,i,Maybe (i,i))
+unpack_n_info m =
+    case unpack_n_info_plain m of
+      [i1,i2,i3,i4,i5] -> Just (i1,i2,i3,i4,i5,Nothing)
+      [i1,i2,i3,i4,i5,i6,i7] -> Just (i1,i2,i3,i4,i5,Just (i6,i7))
+      _ -> Nothing
+
+unpack_n_info_err :: Num i => Message -> (i,i,i,i,i,Maybe (i,i))
+unpack_n_info_err = fromMaybe (error "unpack_n_info") . unpack_n_info
+
+-- | Unpack the '/tr' messages sent by 'sendTrig'.
+unpack_tr :: (Num i,Fractional f) => Message -> Maybe (i,i,f)
+unpack_tr m =
+    let to_i = fromIntegral
+        to_f = realToFrac
+    in case m of
+         Message "/tr" [Int32 p,Int32 q,Float r] -> Just (to_i p,to_i q,to_f r)
+         _ -> Nothing
+
+unpack_tr_err :: (Num i,Fractional f) => Message -> (i,i,f)
+unpack_tr_err = fromMaybe (error "unpack_tr") . unpack_tr
+
+unpack_b_setn :: (Num i,Fractional f) => Message -> Maybe (i,i,i,[f])
+unpack_b_setn m =
+    let to_i = fromIntegral
+        to_f d = case d of
+                    Float n -> realToFrac n
+                    _ -> error "unpack_b_setn: non-float data"
+    in case m of
+         Message "/b_setn" (Int32 p:Int32 q:Int32 r:z) -> Just (to_i p,to_i q,to_i r,map to_f z)
+         _ -> Nothing
+
+unpack_b_setn_err :: (Num i,Fractional f) => Message -> (i,i,i,[f])
+unpack_b_setn_err = fromMaybe (error "unpack_b_setn") . unpack_b_setn
+
+-- | Unpack @b_info@ message, fields are (id,frames,channels,sample-rate).
+unpack_b_info :: (Num i,Fractional f) => Message -> Maybe (i,i,i,f)
+unpack_b_info m =
+    let to_i = fromIntegral
+        to_f = realToFrac
+    in case m of
+         Message "/b_info" [Int32 p,Int32 q,Int32 r,Float s] -> Just (to_i p,to_i q,to_i r,to_f s)
+         _ -> Nothing
+
+-- | Variant generating 'error'.
+unpack_b_info_err :: (Num i,Fractional f) => Message -> (i,i,i,f)
+unpack_b_info_err = fromMaybe (error "unpack_b_info") . unpack_b_info
 
 -- Local Variables:
 -- truncate-lines:t
diff --git a/Sound/SC3/Server/Command/Plain.hs b/Sound/SC3/Server/Command/Plain.hs
--- a/Sound/SC3/Server/Command/Plain.hs
+++ b/Sound/SC3/Server/Command/Plain.hs
@@ -1,97 +1,128 @@
 -- | Functions from "Sound.SC3.Server.Command.Generic" specialised to 'Int' and 'Double'.
 module Sound.SC3.Server.Command.Plain where
 
-import Sound.OSC.Core {- hosc -}
+import Sound.OSC.Core (Datum,Message) {- hosc -}
 
 import qualified Sound.SC3.Server.Command.Generic as G
-import Sound.SC3.Server.Enum
-import qualified Sound.SC3.Server.Graphdef as G
-import Sound.SC3.Server.Synthdef
+import qualified Sound.SC3.Server.Enum as E
+import Sound.SC3.Server.Graphdef (Graphdef)
+import Sound.SC3.Server.Synthdef (Synthdef)
 
+-- * Types
+
+-- | Buffer identifier (buffer number).
+type Buffer_Id = Int
+
+-- | Buffer index (frame index).
+type Buffer_Ix = Int
+
+-- | File connection flag.
+type Buffer_Leave_File_Open = Bool
+
+-- | Control bus identifier (number).
+type Bus_Id = Int
+
+-- | Node identifier (number).
+type Node_Id = Int
+
+-- | Group-node identifier (number).
+type Group_Id = Int
+
+-- | Synth-node identifier (number).
+type Synth_Id = Int
+
 -- * Buffer commands (b_)
 
 -- | Allocates zero filled buffer to number of channels and samples. (Asynchronous)
-b_alloc :: Int -> Int -> Int -> Message
+b_alloc :: Buffer_Id -> Int -> Int -> Message
 b_alloc = G.b_alloc
 
 -- | Allocate buffer space and read a sound file. (Asynchronous)
-b_allocRead :: Int -> String -> Int -> Int -> Message
+b_allocRead :: Buffer_Id -> String -> Int -> Int -> Message
 b_allocRead = G.b_allocRead
 
 -- | Allocate buffer space and read a sound file, picking specific channels. (Asynchronous)
-b_allocReadChannel :: Int -> String -> Int -> Int -> [Int] -> Message
+b_allocReadChannel :: Buffer_Id -> String -> Int -> Int -> [Int] -> Message
 b_allocReadChannel = G.b_allocReadChannel
 
 -- | Close attached soundfile and write header information. (Asynchronous)
-b_close :: Int -> Message
+b_close :: Buffer_Id -> Message
 b_close = G.b_close
 
+-- | Fill ranges of sample values.
+b_fill :: Buffer_Id -> [(Buffer_Ix,Int,Double)] -> Message
+b_fill = G.b_fill
+
 -- | Free buffer data. (Asynchronous)
-b_free :: Int -> Message
+b_free :: Buffer_Id -> Message
 b_free = G.b_free
 
 -- | Call a command to fill a buffer.  (Asynchronous)
-b_gen :: Int -> String -> [Datum] -> Message
+b_gen :: Buffer_Id -> String -> [Datum] -> Message
 b_gen = G.b_gen
 
--- | Call @copy@ 'b_gen' command.
-b_gen_copy :: Int -> Int -> Int -> Int -> Maybe Int -> Message
-b_gen_copy = G.b_gen_copy
-
 -- | Get sample values.
-b_get :: Int -> [Int] -> Message
+b_get :: Buffer_Id -> [Buffer_Ix] -> Message
 b_get = G.b_get
 
 -- | Get ranges of sample values.
-b_getn :: Int -> [(Int,Int)] -> Message
+b_getn :: Buffer_Id -> [(Buffer_Ix,Int)] -> Message
 b_getn = G.b_getn
 
 -- | Request \/b_info messages.
-b_query :: [Int] -> Message
+b_query :: [Buffer_Id] -> Message
 b_query = G.b_query
 
 -- | Read sound file data into an existing buffer. (Asynchronous)
-b_read :: Int -> String -> Int -> Int -> Int -> Bool -> Message
+b_read :: Buffer_Id -> String -> Int -> Int -> Buffer_Ix -> Buffer_Leave_File_Open -> Message
 b_read = G.b_read
 
 -- | Read sound file data into an existing buffer, picking specific channels. (Asynchronous)
-b_readChannel :: Int -> String -> Int -> Int -> Int -> Bool -> [Int] -> Message
+b_readChannel :: Buffer_Id -> String -> Int -> Int -> Buffer_Ix -> Buffer_Leave_File_Open -> [Int] -> Message
 b_readChannel = G.b_readChannel
 
+-- | Set sample values.
+b_set :: Buffer_Id -> [(Buffer_Ix,Double)] -> Message
+b_set = G.b_set
+
+-- | Set ranges of sample values.
+b_setn :: Buffer_Id -> [(Buffer_Ix,[Double])] -> Message
+b_setn = G.b_setn
+
 -- | Write sound file data. (Asynchronous)
-b_write :: Int -> String -> SoundFileFormat -> SampleFormat -> Int -> Int -> Bool -> Message
+b_write :: Buffer_Id -> String -> E.SoundFileFormat -> E.SampleFormat -> Int -> Buffer_Ix -> Buffer_Leave_File_Open -> Message
 b_write = G.b_write
 
 -- | Zero sample data. (Asynchronous)
-b_zero :: Int -> Message
+b_zero :: Buffer_Id -> Message
 b_zero = G.b_zero
 
 -- * Control bus commands
 
 -- |  Fill ranges of bus values.
-c_fill :: [(Int,Int,Double)] -> Message
+c_fill :: [(Bus_Id,Int,Double)] -> Message
 c_fill = G.c_fill
 
 -- | Get bus values.
-c_get :: [Int] -> Message
+c_get :: [Bus_Id] -> Message
 c_get = G.c_get
 
 -- | Get ranges of bus values.
-c_getn :: [(Int,Int)] -> Message
+c_getn :: [(Bus_Id,Int)] -> Message
 c_getn = G.c_getn
 
 -- | Set bus values.
-c_set :: [(Int,Double)] -> Message
+c_set :: [(Bus_Id,Double)] -> Message
 c_set = G.c_set
 
 -- | Set ranges of bus values.
-c_setn :: [(Int,[Double])] -> Message
+c_setn :: [(Bus_Id,[Double])] -> Message
 c_setn = G.c_setn
 
 -- * Instrument definition commands (d_)
 
 -- | Install a bytecode instrument definition. (Asynchronous)
-d_recv' :: G.Graphdef -> Message
+d_recv' :: Graphdef -> Message
 d_recv' = G.d_recv'
 
 -- | Install a bytecode instrument definition. (Asynchronous)
@@ -113,108 +144,112 @@
 -- * Group node commands (g_)
 
 -- | Free all synths in this group and all its sub-groups.
-g_deepFree :: [Int] -> Message
+g_deepFree :: [Group_Id] -> Message
 g_deepFree = G.g_deepFree
 
--- | Delete all nodes in a group.
-g_freeAll :: [Int] -> Message
+-- | Delete all nodes in a set of groups.
+g_freeAll :: [Group_Id] -> Message
 g_freeAll = G.g_freeAll
 
 -- | Add node to head of group.
-g_head :: [(Int,Int)] -> Message
+g_head :: [(Group_Id,Node_Id)] -> Message
 g_head = G.g_head
 
 -- | Create a new group.
-g_new :: [(Int,AddAction,Int)] -> Message
+g_new :: [(Group_Id,E.AddAction,Node_Id)] -> Message
 g_new = G.g_new
 
 -- | Add node to tail of group.
-g_tail :: [(Int,Int)] -> Message
+g_tail :: [(Group_Id,Node_Id)] -> Message
 g_tail = G.g_tail
 
 -- | Post a representation of a group's node subtree, optionally including the current control values for synths.
-g_dumpTree :: [(Int,Bool)] -> Message
+g_dumpTree :: [(Group_Id,Bool)] -> Message
 g_dumpTree = G.g_dumpTree
 
 -- | Request a representation of a group's node subtree, optionally including the current control values for synths.
-g_queryTree :: [(Int,Bool)] -> Message
+g_queryTree :: [(Group_Id,Bool)] -> Message
 g_queryTree = G.g_queryTree
 
 -- * Node commands (n_)
 
 -- | Place a node after another.
-n_after :: [(Int,Int)] -> Message
+n_after :: [(Node_Id,Node_Id)] -> Message
 n_after = G.n_after
 
 -- | Place a node before another.
-n_before :: [(Int,Int)] -> Message
+n_before :: [(Node_Id,Node_Id)] -> Message
 n_before = G.n_before
 
 -- | Fill ranges of a node's control values.
-n_fill :: Int -> [(String,Int,Double)] -> Message
+n_fill :: Node_Id -> [(String,Int,Double)] -> Message
 n_fill = G.n_fill
 
 -- | Delete a node.
-n_free :: [Int] -> Message
+n_free :: [Node_Id] -> Message
 n_free = G.n_free
 
-n_map :: Int -> [(String,Int)] -> Message
+n_map :: Node_Id -> [(String,Bus_Id)] -> Message
 n_map = G.n_map
 
 -- | Map a node's controls to read from buses.
-n_mapn :: Int -> [(String,Int,Int)] -> Message
+n_mapn :: Node_Id -> [(String,Bus_Id,Int)] -> Message
 n_mapn = G.n_mapn
 
 -- | Map a node's controls to read from an audio bus.
-n_mapa :: Int -> [(String,Int)] -> Message
+n_mapa :: Node_Id -> [(String,Bus_Id)] -> Message
 n_mapa = G.n_mapa
 
 -- | Map a node's controls to read from audio buses.
-n_mapan :: Int -> [(String,Int,Int)] -> Message
+n_mapan :: Node_Id -> [(String,Bus_Id,Int)] -> Message
 n_mapan = G.n_mapan
 
 -- | Get info about a node.
-n_query :: [Int] -> Message
+n_query :: [Node_Id] -> Message
 n_query = G.n_query
 
 -- | Turn node on or off.
-n_run :: [(Int,Bool)] -> Message
+n_run :: [(Node_Id,Bool)] -> Message
 n_run = G.n_run
 
 -- | Set a node's control values.
-n_set :: Int -> [(String,Double)] -> Message
+n_set :: Node_Id -> [(String,Double)] -> Message
 n_set = G.n_set
 
 -- | Set ranges of a node's control values.
-n_setn :: Int -> [(String,[Double])] -> Message
+n_setn :: Node_Id -> [(String,[Double])] -> Message
 n_setn = G.n_setn
 
 -- | Trace a node.
-n_trace :: [Int] -> Message
+n_trace :: [Node_Id] -> Message
 n_trace = G.n_trace
 
--- | Move an ordered sequence of nodes.
-n_order :: AddAction -> Int -> [Int] -> Message
+-- | Move and order a sequence of nodes.
+n_order :: E.AddAction -> Node_Id -> [Node_Id] -> Message
 n_order = G.n_order
 
 -- * Par commands (p_)
 
 -- | Create a new parallel group (supernova specific).
-p_new :: [(Int,AddAction,Int)] -> Message
+p_new :: [(Group_Id,E.AddAction,Node_Id)] -> Message
 p_new = G.p_new
 
 -- * Synthesis node commands (s_)
 
 -- | Get control values.
-s_get :: Int -> [String] -> Message
+s_get :: Synth_Id -> [String] -> Message
 s_get = G.s_get
 
 -- | Get ranges of control values.
-s_getn :: Int -> [(String,Int)] -> Message
+s_getn :: Synth_Id -> [(String,Int)] -> Message
 s_getn = G.s_getn
 
+-- | Create a new synth.
+s_new :: String -> Synth_Id -> E.AddAction -> Node_Id -> [(String,Double)] -> Message
+s_new = G.s_new
+
 -- | Auto-reassign synth's ID to a reserved value.
-s_noid :: [Int] -> Message
+s_noid :: [Synth_Id] -> Message
 s_noid = G.s_noid
 
 -- * Unit Generator commands (u_)
@@ -234,11 +269,11 @@
 clearSched = G.clearSched
 
 -- | Select printing of incoming Open Sound Control messages.
-dumpOSC :: PrintLevel -> Message
+dumpOSC :: E.PrintLevel -> Message
 dumpOSC = G.dumpOSC
 
 -- | Set error posting scope and mode.
-errorMode :: ErrorScope -> ErrorMode -> Message
+errorMode :: E.ErrorScope -> E.ErrorMode -> Message
 errorMode = G.errorMode
 
 -- | Select reception of notification messages. (Asynchronous)
@@ -264,31 +299,35 @@
 -- * Variants to simplify common cases
 
 -- | Get ranges of sample values.
-b_getn1 :: Int -> (Int,Int) -> Message
+b_getn1 :: Buffer_Id -> (Buffer_Ix,Int) -> Message
 b_getn1 = G.b_getn1
 
 -- | Variant on 'b_query'.
-b_query1 :: Int -> Message
+b_query1 :: Buffer_Id -> Message
 b_query1 = b_query . return
 
 -- | Get ranges of sample values.
-c_getn1 :: (Int,Int) -> Message
+c_getn1 :: (Bus_Id,Int) -> Message
 c_getn1 = G.c_getn1
 
 -- | Set single bus values.
-c_set1 :: Int -> Double -> Message
+c_set1 :: Bus_Id -> Double -> Message
 c_set1 = G.c_set1
 
 -- | Set single range of bus values.
-c_setn1 :: (Int,[Double]) -> Message
+c_setn1 :: (Bus_Id,[Double]) -> Message
 c_setn1 = G.c_setn1
 
+-- | Turn a single node on or off.
+n_run1 :: Node_Id -> Bool -> Message
+n_run1 = G.n_run1
+
 -- | Set a single node control value.
-n_set1 :: Int -> String -> Double -> Message
+n_set1 :: Node_Id -> String -> Double -> Message
 n_set1 = G.n_set1
 
 -- | @s_new@ with no parameters.
-s_new0 :: String -> Int -> AddAction -> Int -> Message
+s_new0 :: String -> Synth_Id -> E.AddAction -> Node_Id -> Message
 s_new0 = G.s_new0
 
 -- * Buffer segmentation and indices
@@ -307,55 +346,76 @@
 b_indices :: Int -> Int -> Int -> [(Int,Int)]
 b_indices = G.b_indices
 
--- | Create a new synth.
-s_new :: String -> Int -> AddAction -> Int -> [(String,Double)] -> Message
-s_new = G.s_new
-
--- | Fill ranges of sample values.
-b_fill :: Int -> [(Int,Int,Double)] -> Message
-b_fill = G.b_fill
+-- | Call @copy@ 'b_gen' command.
+b_gen_copy :: Buffer_Id -> Int -> Buffer_Id -> Int -> Maybe Int -> Message
+b_gen_copy = G.b_gen_copy
 
 -- | Call @sine1@ 'b_gen' command.
-b_gen_sine1 :: Int -> [B_Gen] -> [Double] -> Message
+b_gen_sine1 :: Buffer_Id -> [E.B_Gen] -> [Double] -> Message
 b_gen_sine1 = G.b_gen_sine1
 
 -- | Call @sine2@ 'b_gen' command.
-b_gen_sine2 :: Int -> [B_Gen] -> [(Double,Double)] -> Message
+b_gen_sine2 :: Buffer_Id -> [E.B_Gen] -> [(Double,Double)] -> Message
 b_gen_sine2 = G.b_gen_sine2
 
 -- | Call @sine3@ 'b_gen' command.
-b_gen_sine3 :: Int -> [B_Gen] -> [(Double,Double,Double)] -> Message
+b_gen_sine3 :: Buffer_Id -> [E.B_Gen] -> [(Double,Double,Double)] -> Message
 b_gen_sine3 = G.b_gen_sine3
 
 -- | Call @cheby@ 'b_gen' command.
-b_gen_cheby :: Int -> [B_Gen] -> [Double] -> Message
+b_gen_cheby :: Buffer_Id -> [E.B_Gen] -> [Double] -> Message
 b_gen_cheby = G.b_gen_cheby
 
--- | Set sample values.
-b_set :: Int -> [(Int,Double)] -> Message
-b_set = G.b_set
-
--- | Set ranges of sample values.
-b_setn :: Int -> [(Int,[Double])] -> Message
-b_setn = G.b_setn
-
 -- | Pre-allocate for b_setn1, values preceding offset are zeroed.
-b_alloc_setn1 :: Int -> Int -> [Double] -> Message
+b_alloc_setn1 :: Buffer_Id -> Buffer_Ix -> [Double] -> Message
 b_alloc_setn1 = G.b_alloc_setn1
 
 -- | Set single sample value.
-b_set1 :: Int -> Int -> Double -> Message
+b_set1 :: Buffer_Id -> Buffer_Ix -> Double -> Message
 b_set1 = G.b_set1
 
 -- | Set a range of sample values.
-b_setn1 :: Int -> Int -> [Double] -> Message
+b_setn1 :: Buffer_Id -> Buffer_Ix -> [Double] -> Message
 b_setn1 = G.b_setn1
 
+-- | Segmented variant of 'b_setn1'.
+b_setn1_segmented :: Int -> Buffer_Id -> Buffer_Ix -> [Double] -> [Message]
+b_setn1_segmented = G.b_setn1_segmented
+
 -- * UGen commands.
 
 -- | Generate accumulation buffer given time-domain IR buffer and FFT size.
 pc_preparePartConv :: Int -> Int -> Int -> Message
 pc_preparePartConv = G.pc_preparePartConv
+
+-- * Unpack
+
+unpack_n_info_plain :: Message -> [Int]
+unpack_n_info_plain = G.unpack_n_info_plain
+
+unpack_n_info :: Message -> Maybe (Int,Int,Int,Int,Int,Maybe (Int,Int))
+unpack_n_info = G.unpack_n_info
+
+unpack_n_info_err :: Message -> (Int,Int,Int,Int,Int,Maybe (Int,Int))
+unpack_n_info_err = G.unpack_n_info_err
+
+unpack_tr :: Message -> Maybe (Int,Int,Double)
+unpack_tr = G.unpack_tr
+
+unpack_tr_err :: Message -> (Int,Int,Double)
+unpack_tr_err = G.unpack_tr_err
+
+unpack_b_setn :: Message -> Maybe (Int,Int,Int,[Double])
+unpack_b_setn = G.unpack_b_setn
+
+unpack_b_setn_err :: Message -> (Int,Int,Int,[Double])
+unpack_b_setn_err = G.unpack_b_setn_err
+
+unpack_b_info :: Message -> Maybe (Int,Int,Int,Double)
+unpack_b_info = G.unpack_b_info
+
+unpack_b_info_err :: Message -> (Int,Int,Int,Double)
+unpack_b_info_err = G.unpack_b_info_err
 
 -- Local Variables:
 -- truncate-lines:t
diff --git a/Sound/SC3/Server/Graphdef.hs b/Sound/SC3/Server/Graphdef.hs
--- a/Sound/SC3/Server/Graphdef.hs
+++ b/Sound/SC3/Server/Graphdef.hs
@@ -3,13 +3,12 @@
 
 import Control.Monad {- base -}
 import qualified Data.ByteString.Lazy as L {- bytestring -}
-import qualified Data.ByteString.Char8 as C {- bytestring -}
 import Data.List
 import System.IO {- base -}
 
-import Sound.OSC.Coding.Byte {- hosc -}
-import Sound.OSC.Coding.Cast {- hosc -}
-import Sound.OSC.Type {- hosc -}
+import qualified Sound.OSC.Coding.Byte as B {- hosc -}
+import qualified Sound.OSC.Coding.Cast as C {- hosc -}
+import Sound.OSC.Datum {- hosc -}
 
 -- * Type
 
@@ -74,45 +73,45 @@
 -- * Read
 
 read_i8 :: Handle -> IO Int
-read_i8 h = fmap decode_i8 (L.hGet h 1)
+read_i8 h = fmap B.decode_i8 (L.hGet h 1)
 
 read_i16 :: Handle -> IO Int
-read_i16 h = fmap decode_i16 (L.hGet h 2)
+read_i16 h = fmap B.decode_i16 (L.hGet h 2)
 
 read_i32 :: Handle -> IO Int
-read_i32 h = fmap decode_i32 (L.hGet h 4)
+read_i32 h = fmap B.decode_i32 (L.hGet h 4)
 
 read_sample :: Handle -> IO Sample
-read_sample h = fmap (realToFrac . decode_f32) (L.hGet h 4)
+read_sample h = fmap (realToFrac . B.decode_f32) (L.hGet h 4)
 
 read_pstr :: Handle -> IO ASCII
 read_pstr h = do
-  n <- fmap decode_u8 (L.hGet h 1)
-  fmap decode_str (L.hGet h n)
+  n <- fmap B.decode_u8 (L.hGet h 1)
+  fmap B.decode_str (L.hGet h n)
 
-read_control :: Handle -> IO Control
-read_control h = do
+read_control :: (Handle -> IO Int) -> Handle -> IO Control
+read_control read_i h = do
   nm <- read_pstr h
-  ix <- read_i16 h
+  ix <- read_i h
   return (nm,ix)
 
-read_input :: Handle -> IO Input
-read_input h = do
-  u <- read_i16 h
-  p <- read_i16 h
+read_input :: (Handle -> IO Int) -> Handle -> IO Input
+read_input read_i h = do
+  u <- read_i h
+  p <- read_i h
   return (Input u p)
 
 read_output :: Handle -> IO Int
 read_output = read_i8
 
-read_ugen :: Handle -> IO UGen
-read_ugen h = do
+read_ugen :: (Handle -> IO Int) -> Handle -> IO UGen
+read_ugen read_i h = do
   name <- read_pstr h
   rate <- read_i8 h
-  number_of_inputs <- read_i16 h
-  number_of_outputs <- read_i16 h
+  number_of_inputs <- read_i h
+  number_of_outputs <- read_i h
   special <- read_i16 h
-  inputs <- replicateM number_of_inputs (read_input h)
+  inputs <- replicateM number_of_inputs (read_input read_i h)
   outputs <- replicateM number_of_outputs (read_output h)
   return (name
          ,rate
@@ -122,24 +121,28 @@
 
 read_graphdef :: Handle -> IO Graphdef
 read_graphdef h = do
-  magic <- L.hGet h 4
+  magic <- fmap B.decode_str (L.hGet h 4)
   version <- read_i32 h
+  let read_i =
+          case version of
+            0 -> read_i16
+            2 -> read_i32
+            _ -> error ("read_graphdef: version not at {zero | two}: " ++ show version)
   number_of_definitions <- read_i16 h
-  when (magic /= L.pack (map (fromIntegral . fromEnum) "SCgf"))
+  when (magic /= ascii "SCgf")
        (error "read_graphdef: illegal magic string")
-  when (version /= 0)
-       (error "read_graphdef: version not at zero")
   when (number_of_definitions /= 1)
        (error "read_graphdef: non unary graphdef file")
   name <- read_pstr h
-  number_of_constants <- read_i16 h
+  number_of_constants <- read_i h
   constants <- replicateM number_of_constants (read_sample h)
-  number_of_control_defaults <- read_i16 h
+  number_of_control_defaults <- read_i h
   control_defaults <- replicateM number_of_control_defaults (read_sample h)
-  number_of_controls <- read_i16 h
-  controls <- replicateM number_of_controls (read_control h)
-  number_of_ugens <- read_i16 h
-  ugens <- replicateM number_of_ugens (read_ugen h)
+  number_of_controls <- read_i h
+  controls <- replicateM number_of_controls (read_control read_i h)
+  number_of_ugens <- read_i h
+  ugens <- replicateM number_of_ugens (read_ugen read_i h)
+  -- ignore variants...
   return (Graphdef name
                    constants
                    (zip controls control_defaults)
@@ -149,6 +152,7 @@
 -- > g <- read_graphdef_file "/home/rohan/sw/rsc3-disassembler/scsyndef/with-ctl.scsyndef"
 -- > g <- read_graphdef_file "/home/rohan/sw/rsc3-disassembler/scsyndef/mce.scsyndef"
 -- > g <- read_graphdef_file "/home/rohan/sw/rsc3-disassembler/scsyndef/mrg.scsyndef"
+-- > putStrLn$ graphdef_stat g
 read_graphdef_file :: FilePath -> IO Graphdef
 read_graphdef_file nm = do
   h <- openFile nm ReadMode
@@ -156,60 +160,62 @@
   hClose h
   return g
 
--- * Encode
+-- * Encode, we write version zero files
 
 -- | Pascal (length prefixed) encoding of string.
 encode_pstr :: ASCII -> L.ByteString
-encode_pstr = L.pack . str_pstr . ascii_to_string
+encode_pstr = L.pack . C.str_pstr . ascii_to_string
 
 -- | Byte-encode 'Input' value.
 encode_input :: Input -> L.ByteString
-encode_input (Input u p) = L.append (encode_i16 u) (encode_i16 p)
+encode_input (Input u p) = L.append (B.encode_i16 u) (B.encode_i16 p)
 
 encode_control :: Control -> L.ByteString
-encode_control (nm,k) = L.concat [encode_pstr nm,encode_i16 k]
+encode_control (nm,k) = L.concat [encode_pstr nm,B.encode_i16 k]
 
 -- | Byte-encode 'UGen'.
 encode_ugen :: UGen -> L.ByteString
 encode_ugen (nm,r,i,o,s) =
     L.concat [encode_pstr nm
-             ,encode_i8 r
-             ,encode_i16 (length i)
-             ,encode_i16 (length o)
-             ,encode_i16 s
+             ,B.encode_i8 r
+             ,B.encode_i16 (length i)
+             ,B.encode_i16 (length o)
+             ,B.encode_i16 s
              ,L.concat (map encode_input i)
-             ,L.concat (map encode_i8 o)]
+             ,L.concat (map B.encode_i8 o)]
 
 encode_sample :: Sample -> L.ByteString
-encode_sample = encode_f32 . realToFrac
+encode_sample = B.encode_f32 . realToFrac
 
 encode_graphdef :: Graphdef -> L.ByteString
 encode_graphdef (Graphdef nm cs ks us) =
     let (ks_ctl,ks_def) = unzip ks
-    in L.concat [encode_str (C.pack "SCgf")
-                ,encode_i32 0 -- version
-                ,encode_i16 1 -- number of graphs
+    in L.concat [B.encode_str (ascii "SCgf")
+                ,B.encode_i32 0 -- version
+                ,B.encode_i16 1 -- number of graphs
                 ,encode_pstr nm
-                ,encode_i16 (length cs)
+                ,B.encode_i16 (length cs)
                 ,L.concat (map encode_sample cs)
-                ,encode_i16 (length ks_def)
+                ,B.encode_i16 (length ks_def)
                 ,L.concat (map encode_sample ks_def)
-                ,encode_i16 (length ks_ctl)
+                ,B.encode_i16 (length ks_ctl)
                 ,L.concat (map encode_control ks_ctl)
-                ,encode_i16 (length us)
+                ,B.encode_i16 (length us)
                 ,L.concat (map encode_ugen us)]
 
 -- * Stat
 
 graphdef_stat :: Graphdef -> String
-graphdef_stat (Graphdef _ cs ks us) =
+graphdef_stat (Graphdef nm cs ks us) =
     let u_nm (sc3_nm,_,_,_,_) = ascii_to_string sc3_nm
         f g = let h (x:xs) = (x,length (x:xs))
                   h [] = error "graphdef_stat"
               in show . map h . group . sort . map g
-        sq = intercalate "," (map u_nm us)
-    in unlines ["number of constants       : " ++ show (length cs)
+        sq pp_f = intercalate "," (pp_f (map u_nm us))
+    in unlines ["name                      : " ++ show nm
+               ,"number of constants       : " ++ show (length cs)
                ,"number of controls        : " ++ show (length ks)
                ,"number of unit generators : " ++ show (length us)
                ,"unit generator rates      : " ++ f ugen_rate us
-               ,"unit generator sequence   : " ++ sq]
+               ,"unit generator set        : " ++ sq (nub . sort)
+               ,"unit generator sequence   : " ++ sq id]
diff --git a/Sound/SC3/Server/Graphdef/Graph.hs b/Sound/SC3/Server/Graphdef/Graph.hs
--- a/Sound/SC3/Server/Graphdef/Graph.hs
+++ b/Sound/SC3/Server/Graphdef/Graph.hs
@@ -3,7 +3,7 @@
 
 import Data.Maybe{- base -}
 
-import Sound.OSC.Type {- hosc -}
+import Sound.OSC.Datum {- hosc -}
 
 import qualified Sound.SC3.Server.Graphdef as G
 import Sound.SC3.UGen.Graph
diff --git a/Sound/SC3/Server/Graphdef/Read.hs b/Sound/SC3/Server/Graphdef/Read.hs
--- a/Sound/SC3/Server/Graphdef/Read.hs
+++ b/Sound/SC3/Server/Graphdef/Read.hs
@@ -1,7 +1,8 @@
 -- | Transform (read) a 'Graphdef' into a 'Graph'.
 module Sound.SC3.Server.Graphdef.Read where
 
-import Sound.OSC.Type
+import Sound.OSC.Datum {- hosc -}
+
 import Sound.SC3.Server.Graphdef
 import qualified Sound.SC3.UGen.Graph as G
 import qualified Sound.SC3.UGen.Rate as R
diff --git a/Sound/SC3/Server/Help.hs b/Sound/SC3/Server/Help.hs
--- a/Sound/SC3/Server/Help.hs
+++ b/Sound/SC3/Server/Help.hs
@@ -7,10 +7,13 @@
 
 import Sound.SC3.UGen.Help
 
--- | Generate path to indicated SC3 instance method help.
---
--- > let r = "./Reference/Server-Command-Reference.html#/b_alloc"
--- > in sc3HelpServerCommand "." "b_alloc" == r
+{- | Generate path to indicated SC3 instance method help.  Adds initial
+forward slash if not present.
+
+> let r = "./Reference/Server-Command-Reference.html#/b_alloc"
+> in sc3_server_command_ref "." "b_alloc" == r
+
+-}
 sc3_server_command_ref :: FilePath -> String -> FilePath
 sc3_server_command_ref d c =
     let f = d </> "Reference/Server-Command-Reference.html"
@@ -19,10 +22,11 @@
                _ -> '/':c
     in f ++ '#':c'
 
--- | Lookup @SC3@ help file for server command `c'.
---
--- > Sound.SC3.Server.Help.viewServerHelp "/b_allocRead"
--- > viewServerHelp "done"
+{- | Lookup @SC3@ help file for server command `c'.
+
+> Sound.SC3.Server.Help.viewServerHelp "/b_allocRead"
+> viewServerHelp "done"
+-}
 viewServerHelp :: String -> IO ()
 viewServerHelp c = do
   d <- sc3HelpDirectory
diff --git a/Sound/SC3/Server/NRT.hs b/Sound/SC3/Server/NRT.hs
--- a/Sound/SC3/Server/NRT.hs
+++ b/Sound/SC3/Server/NRT.hs
@@ -8,20 +8,36 @@
 import System.Process {- process -}
 
 import Sound.OSC.Core {- hosc -}
-import Sound.OSC.Coding.Byte {- hosc -}
+import qualified Sound.OSC.Coding.Byte as Byte {- hosc -}
 
+import Sound.SC3.Common.Prelude
 import Sound.SC3.Server.Enum
 
 -- | Encode and prefix with encoded length.
 oscWithSize :: Bundle -> B.ByteString
 oscWithSize o =
     let b = encodeBundle o
-        l = encode_i32 (fromIntegral (B.length b))
+        l = Byte.encode_i32 (fromIntegral (B.length b))
     in B.append l b
 
 -- | An 'NRT' score is a sequence of 'Bundle's.
 data NRT = NRT {nrt_bundles :: [Bundle]} deriving (Show)
 
+type NRT_STAT =
+    ((String, Time)
+    ,(String, Int)
+    ,(String, Int)
+    ,(String, [(String,Int)]))
+
+-- | Trivial NRT statistics.
+nrt_stat :: NRT -> NRT_STAT
+nrt_stat (NRT b_seq) =
+    let b_msg = map bundleMessages b_seq
+    in (("duration",bundleTime (last b_seq))
+       ,("# bundles",length b_seq)
+       ,("# messages",sum (map length b_msg))
+       ,("command set",histogram (concatMap (map messageAddress) b_msg)))
+
 -- | 'span' of 'f' of 'bundleTime'.  Can be used to separate the
 -- /initialisation/ and /remainder/ parts of a score.
 nrt_span :: (Time -> Bool) -> NRT -> ([Bundle],[Bundle])
@@ -43,7 +59,7 @@
 decode_nrt_bundles :: B.ByteString -> [Bundle]
 decode_nrt_bundles s =
     let (p,q) = B.splitAt 4 s
-        n = fromIntegral (decode_i32 p)
+        n = fromIntegral (Byte.decode_i32 p)
         (r,s') = B.splitAt n q
         r' = decodeBundle r
     in if B.null s'
@@ -63,14 +79,15 @@
 -- | Minimal NRT rendering options.  The sound file type is inferred
 -- from the file name extension.  Structure is: OSC file name, output
 -- audio file name, output number of channels, sample rate, sample
--- format.
-type NRT_Render_Plain = (FilePath,FilePath,Int,Int,SampleFormat)
+-- format, further parameters (ie. ["-m","32768"]) to be inserted before
+-- the NRT -N option.
+type NRT_Render_Plain = (FilePath,FilePath,Int,Int,SampleFormat,[String])
 
 -- | Minimal NRT rendering, for more control see Stefan Kersten's
 -- /hsc3-process/ package at:
 -- <https://github.com/kaoskorobase/hsc3-process>.
 nrt_render_plain :: NRT_Render_Plain -> NRT -> IO ()
-nrt_render_plain (osc_nm,sf_nm,nc,sr,sf) sc = do
+nrt_render_plain (osc_nm,sf_nm,nc,sr,sf,param) sc = do
   let sf_ty = case takeExtension sf_nm of
                 '.':ext -> let fmt = soundFileFormat_from_extension ext
                            in fromMaybe (error "nrt_render_plain: unknown sf extension") fmt
@@ -78,6 +95,7 @@
       sys = unwords ["scsynth"
                     ,"-i","0"
                     ,"-o",show nc
+                    ,unwords param
                     ,"-N"
                     ,osc_nm,"_"
                     ,sf_nm,show sr,soundFileFormatString sf_ty,sampleFormatString sf]
diff --git a/Sound/SC3/Server/NRT/Edit.hs b/Sound/SC3/Server/NRT/Edit.hs
--- a/Sound/SC3/Server/NRT/Edit.hs
+++ b/Sound/SC3/Server/NRT/Edit.hs
@@ -79,3 +79,7 @@
                                 else m ++ [nrt_end]
                       in bundle_map id f
     in NRT (at_last rem_end_msg req_end_msg l)
+
+-- | Append /q/ to /p/, assumes last timestamp at /p/ precedes first at /q/.
+nrt_append :: NRT -> NRT -> NRT
+nrt_append (NRT p) (NRT q) = NRT (p ++ q)
diff --git a/Sound/SC3/Server/Recorder.hs b/Sound/SC3/Server/Recorder.hs
--- a/Sound/SC3/Server/Recorder.hs
+++ b/Sound/SC3/Server/Recorder.hs
@@ -33,21 +33,26 @@
                  ,rec_fname = "/tmp/sc3-recorder.wav"
                  ,rec_nc = 2
                  ,rec_bus = 0
-                 ,rec_buf_id = 2001
-                 ,rec_buf_frames = 48000
+                 ,rec_buf_id = 10
+                 ,rec_buf_frames = 65536
                  ,rec_node_id = 2001
                  ,rec_group_id = 0
                  ,rec_dur = Just 60}
 
 instance Default SC3_Recorder where def = default_SC3_Recorder
 
+-- | The name indicates the number of channels.
+rec_synthdef_nm :: Int -> String
+rec_synthdef_nm nc = "sc3-recorder-" ++ show nc
+
 -- | Generate 'Synthdef' with required number of channels.
-rec_synthdef :: SC3_Recorder -> Synthdef
-rec_synthdef r =
+--
+-- > Sound.SC3.UGen.Dot.draw (rec_synthdef 2)
+rec_synthdef :: Int -> Synthdef
+rec_synthdef nc =
     let bufnum = control KR "bufnum" 0
         bus = control KR "bus" 0
-        nm = "sc3-recorder-" ++ show (rec_nc r)
-    in synthdef nm (diskOut bufnum (in' (rec_nc r) AR bus))
+    in synthdef (rec_synthdef_nm nc) (diskOut bufnum (in' nc AR bus))
 
 -- | Asyncronous initialisation 'Message's ('d_recv', 'b_alloc' and
 -- 'b_write').
@@ -56,7 +61,7 @@
 rec_init_m :: SC3_Recorder -> [Message]
 rec_init_m r =
     let buf = rec_buf_id r
-    in [d_recv (rec_synthdef r)
+    in [d_recv (rec_synthdef (rec_nc r))
        ,b_alloc buf (rec_buf_frames r) (rec_nc r)
        ,b_write buf (rec_fname r) (rec_sftype r) (rec_coding r) (-1) 0 True]
 
@@ -65,7 +70,7 @@
 -- > withSC3 (sendMessage (rec_begin_m def))
 rec_begin_m :: SC3_Recorder -> Message
 rec_begin_m r =
-    s_new (synthdefName (rec_synthdef r))
+    s_new (rec_synthdef_nm (rec_nc r))
           (rec_node_id r)
           AddToTail
           (rec_group_id r)
@@ -81,8 +86,15 @@
     ,b_close (rec_buf_id r)
     ,b_free (rec_buf_id r)]
 
--- | 'NRT' score for recorder, if 'rec_dur' is given schedule
--- 'rec_end_m'.
+{- | 'NRT' score for recorder, if 'rec_dur' is given schedule 'rec_end_m'.
+
+> import Sound.SC3
+> withSC3 (Sound.OSC.sendMessage (dumpOSC TextPrinter))
+> audition (out 0 (sinOsc AR (mce2 440 441) 0 * 0.1))
+> let rc = default_SC3_Recorder {rec_dur = Just 5.0}
+> nrt_audition (sc3_recorder rc)
+
+-}
 sc3_recorder :: SC3_Recorder -> NRT
 sc3_recorder r =
     let b0 = bundle 0 (rec_init_m r ++ [rec_begin_m r])
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
@@ -5,8 +5,9 @@
 import Data.List {- base -}
 import Data.Maybe {- base -}
 import qualified Data.Tree as T {- containers -}
-import Sound.OSC.Type {- hosc -}
 
+import Sound.OSC.Datum {- hosc -}
+
 -- | Get /n/th field of status as 'Floating'.
 extractStatusField :: Floating n => Int -> [Datum] -> n
 extractStatusField n =
@@ -31,8 +32,7 @@
 statusFormat :: [Datum] -> [String]
 statusFormat d =
     let s = "***** SuperCollider Server Status *****"
-    in s : zipWith (++) (tail statusFields) (map show (tail d))
-
+    in s : zipWith (++) (tail statusFields) (map (datum_pp_typed (Just 5)) (tail d))
 
 -- * Query Group
 
@@ -75,8 +75,13 @@
                 _ -> err "float/string" d
     in (f p,g q)
 
--- > let d = [int32 1,string "freq",float 440]
--- > in queryTree_synth True 1000 "saw" d
+{- | If /rc/ is 'True' then 'Query_Ctl' data is expected (ie. flag was set at @/g_queryTree@).
+/k/ is the synth-id, and /nm/ the name.
+
+> let d = [int32 1,string "freq",float 440]
+> in queryTree_synth True 1000 "saw" d
+
+-}
 queryTree_synth :: Bool -> Int -> String -> [Datum] -> (Query_Node,[Datum])
 queryTree_synth rc k nm d =
     let pairs l = case l of
@@ -93,11 +98,12 @@
 
 queryTree_group :: Bool -> Int -> Int -> [Datum] -> (Query_Node,[Datum])
 queryTree_group rc gid nc =
-    let rec n r d = if n == 0
-                    then (Query_Group gid (reverse r),d)
-                    else let (c,d') = queryTree_child rc d
-                         in rec (n - 1) (c : r) d'
-    in rec nc []
+    let recur n r d =
+            if n == 0
+            then (Query_Group gid (reverse r),d)
+            else let (c,d') = queryTree_child rc d
+                 in recur (n - 1) (c : r) d'
+    in recur nc []
 
 queryTree_child :: Bool -> [Datum] -> (Query_Node,[Datum])
 queryTree_child rc d =
@@ -120,13 +126,20 @@
 queryTree d =
     case d of
       Int32 rc : Int32 gid : Int32 nc : d' ->
-          let rc' = not (rc == 0)
+          let rc' = rc /= 0
               gid' = fromIntegral gid
               nc' = fromIntegral nc
           in case queryTree_group rc' gid' nc' d' of
                (r,[]) -> r
                _ -> error "queryTree"
       _ -> error "queryTree"
+
+-- | Extact sequence of group-ids from 'Query_Node'.
+queryNode_to_group_seq :: Query_Node -> [Int]
+queryNode_to_group_seq nd =
+    case nd of
+      Query_Group k ch -> k : concatMap queryNode_to_group_seq ch
+      Query_Synth _ _ _ -> []
 
 -- | Transform 'Query_Node' to 'T.Tree'.
 --
diff --git a/Sound/SC3/Server/Synthdef.hs b/Sound/SC3/Server/Synthdef.hs
--- a/Sound/SC3/Server/Synthdef.hs
+++ b/Sound/SC3/Server/Synthdef.hs
@@ -29,7 +29,9 @@
 -- | The SC3 /default/ instrument 'Synthdef', see
 -- 'default_ugen_graph'.
 --
--- > withSC3 (send (d_recv defaultSynthdef))
+-- > import Sound.OSC {- hosc -}
+-- > import Sound.SC3 {- hsc3 -}
+-- > withSC3 (sendMessage (d_recv defaultSynthdef))
 -- > audition defaultSynthdef
 defaultSynthdef :: Synthdef
 defaultSynthdef = synthdef "default" default_ugen_graph
@@ -37,7 +39,7 @@
 -- | The SC3 /default/ sample (buffer) playback instrument 'Synthdef',
 -- see 'default_sampler_ugen_graph'.
 --
--- > withSC3 (send (d_recv (defaultSampler False)))
+-- > withSC3 (sendMessage (d_recv (defaultSampler False)))
 -- > audition (defaultSampler False)
 defaultSampler :: Bool -> Synthdef
 defaultSampler use_gate =
@@ -50,7 +52,7 @@
 
 -- | Parameter names at 'Synthdef'.
 --
--- > synthdefParam def == ["amp","pan","gate","freq"]
+-- > synthdefParam defaultSynthdef == ["amp","pan","gate","freq","out"]
 synthdefParam :: Synthdef -> [String]
 synthdefParam = map node_k_name . controls . synthdefGraph
 
@@ -80,7 +82,7 @@
     in L.writeFile nm (synthdefData s)
 
 -- | Simple statistical analysis of a unit generator graph.
-graph_stat :: Graph -> String
+graph_stat :: Graph -> [String]
 graph_stat s =
     let cs = constants s
         ks = controls s
@@ -89,15 +91,20 @@
         f g = let h (x:xs) = (x,length (x:xs))
                   h [] = error "graph_stat"
               in show . map h . group . sort . map g
-        sq = intercalate "," (map u_nm us)
-    in unlines ["number of constants       : " ++ show (length cs)
-               ,"number of controls        : " ++ show (length ks)
-               ,"control rates             : " ++ f node_k_rate ks
-               ,"number of unit generators : " ++ show (length us)
-               ,"unit generator rates      : " ++ f node_u_rate us
-               ,"unit generator sequence   : " ++ sq]
+        sq pp_f = intercalate "," (pp_f (map u_nm us))
+    in ["number of constants       : " ++ show (length cs)
+       ,"number of controls        : " ++ show (length ks)
+       ,"control rates             : " ++ f node_k_rate ks
+       ,"number of unit generators : " ++ show (length us)
+       ,"unit generator rates      : " ++ f node_u_rate us
+       ,"unit generator set        : " ++ sq (sort . nub)
+       ,"unit generator sequence   : " ++ sq id]
 
+synthstat' :: UGen -> [String]
+synthstat' = graph_stat . ugen_to_graph
+
 -- | 'graph_stat' of 'synth'.
 synthstat :: UGen -> String
-synthstat = graph_stat . ugen_to_graph
+synthstat = unlines . synthstat'
+
 
diff --git a/Sound/SC3/Server/Transport/FD.hs b/Sound/SC3/Server/Transport/FD.hs
--- a/Sound/SC3/Server/Transport/FD.hs
+++ b/Sound/SC3/Server/Transport/FD.hs
@@ -4,6 +4,8 @@
 -- at some point at least part of the duplication will be removed.
 module Sound.SC3.Server.Transport.FD where
 
+import Data.List {- base -}
+import Data.List.Split {- split -}
 import Data.Maybe {- base -}
 import Control.Monad {- base -}
 import Sound.OSC.FD {- hosc -}
@@ -18,14 +20,21 @@
 
 -- * hosc variants
 
--- | Synonym for 'sendMessage'.
-send :: (Transport t) => t -> Message -> IO ()
-send = sendMessage
-
 -- | Send a 'Message' and 'waitReply' for a @\/done@ reply.
 async :: Transport t => t -> Message -> IO Message
 async fd m = sendMessage fd m >> waitReply fd "/done"
 
+-- | If 'isAsync' then 'void' 'async' else 'sendMessage'.
+maybe_async :: (Transport t) => t -> Message -> IO ()
+maybe_async fd m = if isAsync m then void (async fd m) else sendMessage fd m
+
+-- | Variant that timestamps synchronous messages.
+maybe_async_at :: (Transport t) => t -> Time -> Message -> IO ()
+maybe_async_at fd t m =
+    if isAsync m
+    then void (async fd m)
+    else sendBundle fd (bundle t [m])
+
 -- | Bracket @SC3@ communication.
 withSC3 :: (UDP -> IO a) -> IO a
 withSC3 = withTransport (openUDP "127.0.0.1" 57110)
@@ -62,31 +71,30 @@
 -- to initial 'Time', then send each message, asynchronously if
 -- required.
 run_bundle :: Transport t => t -> Time -> Bundle -> IO ()
-run_bundle fd st b = do
-  let t = bundleTime b
+run_bundle fd t0 b = do
+  let t = t0 + bundleTime b
       latency = 0.1
-      wr m = if isAsync m
-             then async fd m >> return ()
-             else sendBundle fd (bundle (st + t) [m])
-  pauseThreadUntil (st + t - latency)
-  mapM_ wr (bundleMessages b)
+  pauseThreadUntil (t - latency)
+  mapM_ (maybe_async_at fd t) (bundleMessages b)
 
 -- | Perform an 'NRT' score (as would be rendered by 'writeNRT').  In
 -- particular note that all timestamps /must/ be in 'NTPr' form.
-performNRT :: Transport t => t -> NRT -> IO ()
-performNRT fd s = time >>= \i -> mapM_ (run_bundle fd i) (nrt_bundles s)
+nrt_play :: Transport t => t -> NRT -> IO ()
+nrt_play fd sc = time >>= \t0 -> mapM_ (run_bundle fd t0) (nrt_bundles sc)
 
+nrt_audition :: NRT -> IO ()
+nrt_audition sc = withSC3 (\fd -> nrt_play fd sc)
+
 -- * Audible
 
--- | Class for values that can be encoded and sent to @scsynth@ for
--- audition.
+-- | Class for values that can be encoded and sent to @scsynth@ for audition.
 class Audible e where
     play_id :: Transport t => Int -> t -> e -> IO ()
     play :: Transport t => t -> e -> IO ()
     play = play_id (-1)
 
 instance Audible G.Graphdef where
-    play_id k fd = playGraphdef k fd
+    play_id = playGraphdef
 
 instance Audible Synthdef where
     play_id = playSynthdef
@@ -94,9 +102,6 @@
 instance Audible UGen where
     play_id = playUGen
 
-instance Audible NRT where
-    play_id _ = performNRT
-
 audition_id :: Audible e => Int -> e -> IO ()
 audition_id k e = withSC3 (\fd -> play_id k fd e)
 
@@ -138,15 +143,19 @@
   return (concat d)
 
 -- | Variant of 'b_getn1_data_segment' that gets the entire buffer.
-b_fetch :: Transport t => t -> Int -> Int -> IO [Double]
+b_fetch :: Transport t => t -> Int -> Int -> IO [[Double]]
 b_fetch fd n b = do
   let f d = case d of
               [Int32 _,Int32 nf,Int32 nc,Float _] ->
                   let ix = (0,fromIntegral (nf * nc))
-                  in b_getn1_data_segment fd n b ix
+                      deinterleave = transpose . chunksOf (fromIntegral nc)
+                  in liftM deinterleave (b_getn1_data_segment fd n b ix)
               _ -> error "b_fetch"
   sendMessage fd (b_query1 b)
   waitDatum fd "/b_info" >>= f
+
+b_fetch1 :: Transport t => t -> Int -> Int -> IO [Double]
+b_fetch1 fd n b = liftM head (b_fetch fd n b)
 
 -- * Status
 
diff --git a/Sound/SC3/Server/Transport/Monad.hs b/Sound/SC3/Server/Transport/Monad.hs
--- a/Sound/SC3/Server/Transport/Monad.hs
+++ b/Sound/SC3/Server/Transport/Monad.hs
@@ -2,10 +2,15 @@
 module Sound.SC3.Server.Transport.Monad where
 
 import Control.Monad {- base -}
+import Data.List {- base -}
+import Data.List.Split {- split -}
 import Data.Maybe {- base -}
+import Safe {- safe -}
+
 import Sound.OSC {- hosc -}
 
 import Sound.SC3.Server.Command
+import qualified Sound.SC3.Server.Command.Generic as Generic
 import Sound.SC3.Server.Enum
 import qualified Sound.SC3.Server.Graphdef as G
 import Sound.SC3.Server.NRT
@@ -17,52 +22,78 @@
 
 -- * hosc variants
 
--- | Synonym for 'sendMessage'.
-send :: SendOSC m => Message -> m ()
-send = sendMessage
-
--- | Send a 'Message' and 'waitReply' for a @\/done@ reply.
+-- | 'sendMessage' and 'waitReply' for a @\/done@ reply.
 async :: DuplexOSC m => Message -> m Message
-async m = send m >> waitReply "/done"
+async m = sendMessage m >> waitReply "/done"
 
--- | Bracket @SC3@ communication. 'withTransport' at standard SC3 UDP
--- port.
+-- | 'void' of 'async'.
+async_ :: DuplexOSC m => Message -> m ()
+async_ = void . async
+
+-- | If 'isAsync' then 'async_' else 'sendMessage'.
+maybe_async :: DuplexOSC m => Message -> m ()
+maybe_async m = if isAsync m then async_ m else sendMessage m
+
+-- | Variant that timestamps synchronous messages.
+maybe_async_at :: DuplexOSC m => Time -> Message -> m ()
+maybe_async_at t m =
+    if isAsync m
+    then async_ m
+    else sendBundle (bundle t [m])
+
+-- | Local host (ie. @127.0.0.1@) at port @57110@.
+sc3_default_udp :: IO UDP
+sc3_default_udp = openUDP "127.0.0.1" 57110
+
+-- | Bracket @SC3@ communication, ie. 'withTransport' 'sc3_default_udp'.
 --
 -- > import Sound.SC3.Server.Command
 --
--- > withSC3 (send status >> waitReply "/status.reply")
+-- > withSC3 (sendMessage status >> waitReply "/status.reply")
 withSC3 :: Connection UDP a -> IO a
-withSC3 = withTransport (openUDP "127.0.0.1" 57110)
+withSC3 = withTransport sc3_default_udp
 
+-- | 'void' of 'withSC3'.
+withSC3_ :: Connection UDP a -> IO ()
+withSC3_ = void . withSC3
+
 -- * Server control
 
 -- | Free all nodes ('g_freeAll') at group @1@.
 stop :: SendOSC m => m ()
-stop = send (g_freeAll [1])
+stop = sendMessage (g_freeAll [1])
 
 -- * Composite
 
--- | 'clearSched', free all nodes ('g_freeAll') at, and then
--- re-create, groups @1@ and @2@.
+-- | Runs 'clearSched' and then frees and re-creates groups @1@ and @2@.
 reset :: SendOSC m => m ()
 reset =
     let m = [clearSched
-            ,g_freeAll [1,2]
+            ,n_free [1,2]
             ,g_new [(1,AddToHead,0),(2,AddToTail,0)]]
     in sendBundle (bundle immediately m)
 
+-- | (node-id,add-action,group-id,parameters)
+type Play_Opt = (Node_Id,AddAction,Group_Id,[(String,Double)])
+
+play_graphdef_msg :: Play_Opt -> G.Graphdef -> Message
+play_graphdef_msg (nid,act,gid,param) g =
+    let nm = ascii_to_string (G.graphdef_name g)
+    in s_new nm nid act gid param
+
 -- | Send 'd_recv' and 's_new' messages to scsynth.
-playGraphdef :: DuplexOSC m => (Int,AddAction,Int) -> G.Graphdef -> m ()
-playGraphdef (nid,act,gid) g = do
-  _ <- async (d_recv' g)
-  send (s_new0 (ascii_to_string (G.graphdef_name g)) nid act gid)
+playGraphdef :: DuplexOSC m => Play_Opt -> G.Graphdef -> m ()
+playGraphdef opt g = async_ (d_recv' g) >> sendMessage (play_graphdef_msg opt g)
 
+play_synthdef_msg :: Play_Opt -> Synthdef -> Message
+play_synthdef_msg (nid,act,gid,param) syn = s_new (synthdefName syn) nid act gid param
+
 -- | Send 'd_recv' and 's_new' messages to scsynth.
-playSynthdef :: DuplexOSC m => (Int,AddAction,Int) -> Synthdef -> m ()
-playSynthdef opt = playGraphdef opt . synthdef_to_graphdef
+playSynthdef :: DuplexOSC m => Play_Opt -> Synthdef -> m ()
+playSynthdef opt syn = async_ (d_recv syn) >> sendMessage (play_synthdef_msg opt syn)
 
 -- | Send an /anonymous/ instrument definition using 'playSynthdef'.
-playUGen :: DuplexOSC m => (Int,AddAction,Int) -> UGen -> m ()
+playUGen :: DuplexOSC m => Play_Opt -> UGen -> m ()
 playUGen loc =
     playSynthdef loc .
     synthdef "Anonymous" .
@@ -74,25 +105,29 @@
 -- to the initial 'Time', then send each message, asynchronously if
 -- required.
 run_bundle :: Transport m => Time -> Bundle -> m ()
-run_bundle st b = do
-  let t = bundleTime b
+run_bundle t0 b = do
+  let t = t0 + bundleTime b
       latency = 0.1
-      wr m = if isAsync m
-             then async m >> return ()
-             else sendBundle (bundle (st + t) [m])
-  liftIO (pauseThreadUntil (st + t - latency))
-  mapM_ wr (bundleMessages b)
+  liftIO (pauseThreadUntil (t - latency))
+  mapM_ (maybe_async_at t) (bundleMessages b)
 
--- | Perform an 'NRT' score (as would be rendered by 'writeNRT').
--- Asynchronous commands at time @0@ are separated out and run before
+{- | Play an 'NRT' score (as would be rendered by 'writeNRT').
+
+> let sc = NRT [bundle 1 [s_new0 "default" (-1) AddToHead 1]
+>              ,bundle 2 [n_set1 (-1) "gate" 0]]
+> in withSC3 (nrt_play sc)
+
+-}
+nrt_play :: Transport m => NRT -> m ()
+nrt_play sc = do
+  t0 <- liftIO time
+  mapM_ (run_bundle t0) (nrt_bundles sc)
+
+-- | Variant where asynchronous commands at time @0@ are separated out and run before
 -- the initial time-stamp is taken.  This re-orders synchronous
 -- commands in relation to asynchronous at time @0@.
---
--- > let sc = NRT [bundle 1 [s_new0 "default" (-1) AddToHead 1]
--- >              ,bundle 2 [n_set1 (-1) "gate" 0]]
--- > in withSC3 (performNRT sc)
-performNRT :: Transport m => NRT -> m ()
-performNRT s = do
+nrt_play_reorder :: Transport m => NRT -> m ()
+nrt_play_reorder s = do
   let (i,r) = nrt_span (<= 0) s
       i' = concatMap bundleMessages i
       (a,b) = partition_async i'
@@ -100,18 +135,20 @@
   t <- liftIO time
   mapM_ (run_bundle t) (Bundle 0 b : r)
 
+nrt_audition :: NRT -> IO ()
+nrt_audition = withSC3 . nrt_play
+
 -- * Audible
 
--- | Class for values that can be encoded and send to @scsynth@ for
--- audition.
+-- | Class for values that can be encoded and send to @scsynth@ for audition.
 class Audible e where
-    play_at :: Transport m => (Int,AddAction,Int) -> e -> m ()
+    play_at :: Transport m => Play_Opt -> e -> m ()
     -- | Variant where /id/ is @-1@.
     play :: Transport m => e -> m ()
-    play = play_at (-1,AddToHead,1)
+    play = play_at (-1,AddToHead,1,[])
 
 instance Audible G.Graphdef where
-    play_at k = playGraphdef k
+    play_at = playGraphdef
 
 instance Audible Synthdef where
     play_at = playSynthdef
@@ -119,40 +156,34 @@
 instance Audible UGen where
     play_at = playUGen
 
-instance Audible NRT where
-    play_at _ = performNRT
-
 -- | 'withSC3' of 'play_at'.
-audition_at :: Audible e => (Int,AddAction,Int) -> e -> IO ()
+audition_at :: Audible e => Play_Opt -> e -> IO ()
 audition_at k = withSC3 . play_at k
 
 -- | Variant where /id/ is @-1@.
 audition :: Audible e => e -> IO ()
-audition = audition_at (-1,AddToHead,1)
+audition = audition_at (-1,AddToHead,1,[])
 
 -- * Notifications
 
--- | Turn on notifications, run /f/, turn off notifications, return
--- result.
+-- | Turn on notifications, run /f/, turn off notifications, return result.
 withNotifications :: DuplexOSC m => m a -> m a
 withNotifications f = do
-  _ <- async (notify True)
+  async_ (notify True)
   r <- f
-  _ <- async (notify False)
+  async_ (notify False)
   return r
 
--- * Buffer
+-- * Buffer & control & node variants.
 
 -- | Variant of 'b_getn1' that waits for return message and unpacks it.
 --
 -- > withSC3 (b_getn1_data 0 (0,5))
 b_getn1_data :: DuplexOSC m => Int -> (Int,Int) -> m [Double]
 b_getn1_data b s = do
-  let f d = case d of
-              Int32 _:Int32 _:Int32 _:x -> mapMaybe datum_floating x
-              _ -> error "b_getn1_data"
+  let f m = let (_,_,_,r) = unpack_b_setn_err m in r
   sendMessage (b_getn1 b s)
-  liftM f (waitDatum "/b_setn")
+  liftM f (waitReply "/b_setn")
 
 -- | Variant of 'b_getn1_data' that segments individual 'b_getn'
 -- messages to /n/ elements.
@@ -166,16 +197,43 @@
   return (concat d)
 
 -- | Variant of 'b_getn1_data_segment' that gets the entire buffer.
-b_fetch :: DuplexOSC m => Int -> Int -> m [Double]
+--
+b_fetch :: DuplexOSC m => Int -> Int -> m [[Double]]
 b_fetch n b = do
-  let f d = case d of
-              [Int32 _,Int32 nf,Int32 nc,Float _] ->
-                  let ix = (0,fromIntegral (nf * nc))
-                  in b_getn1_data_segment n b ix
-              _ -> error "b_fetch"
+  let f m = let (_,nf,nc,_) = unpack_b_info_err m
+                ix = (0,nf * nc)
+                deinterleave = transpose . chunksOf nc
+            in liftM deinterleave (b_getn1_data_segment n b ix)
   sendMessage (b_query1 b)
-  waitDatum "/b_info" >>= f
+  waitReply "/b_info" >>= f
 
+-- | First channel of 'b_fetch', errors if there is no data.
+--
+-- > withSC3 (b_fetch1 512 123456789)
+b_fetch1 :: DuplexOSC m => Int -> Int -> m [Double]
+b_fetch1 n b = liftM (headNote "b_fetch1: no data") (b_fetch n b)
+
+-- | Combination of 'b_query1_unpack' and 'b_fetch'.
+b_fetch_hdr :: Transport m => Int -> Int -> m ((Int,Int,Int,Double),[[Double]])
+b_fetch_hdr k b = do
+  q <- b_query1_unpack b
+  d <- b_fetch k b
+  return (q,d)
+
+-- | 'b_info_unpack_err' of 'b_query1'.
+b_query1_unpack_generic :: (DuplexOSC m,Num n,Fractional r) => Int -> m (n,n,n,r)
+b_query1_unpack_generic n = do
+  sendMessage (b_query1 n)
+  q <- waitReply "/b_info"
+  return (Generic.unpack_b_info_err q)
+
+-- | Type specialised 'b_query1_unpack_generic'.
+--
+-- > withSC3 (b_query1_unpack 0)
+b_query1_unpack :: DuplexOSC m => Buffer_Id -> m (Int,Int,Int,Double)
+b_query1_unpack = b_query1_unpack_generic
+
+-- | Variant of 'c_getn1' that waits for the reply and unpacks the data.
 c_getn1_data :: DuplexOSC m => (Int,Int) -> m [Double]
 c_getn1_data s = do
   let f d = case d of
@@ -183,6 +241,26 @@
               _ -> error "c_getn1_data"
   sendMessage (c_getn1 s)
   liftM f (waitDatum "/c_setn")
+
+n_query1_unpack_f :: Transport m => (Message -> t) -> Node_Id -> m t
+n_query1_unpack_f f n = do
+  sendMessage (n_query [n])
+  r <- waitReply "/n_info"
+  return (f r)
+
+-- | Variant of 'n_query' that waits for and unpacks the reply.
+n_query1_unpack :: Transport m => Node_Id -> m (Maybe (Int,Int,Int,Int,Int,Maybe (Int,Int)))
+n_query1_unpack = n_query1_unpack_f unpack_n_info
+
+n_query1_unpack_plain :: Transport m => Node_Id -> m [Int]
+n_query1_unpack_plain = n_query1_unpack_f unpack_n_info_plain
+
+-- | Variant of 'g_queryTree' that waits for and unpacks the reply.
+g_queryTree1_unpack :: Transport m => Group_Id -> m Query_Node
+g_queryTree1_unpack n = do
+  sendMessage (g_queryTree [(n,True)])
+  r <- waitReply "/g_queryTree.reply"
+  return (queryTree (messageDatum r))
 
 -- * Status
 
diff --git a/Sound/SC3/UGen.hs b/Sound/SC3/UGen.hs
--- a/Sound/SC3/UGen.hs
+++ b/Sound/SC3/UGen.hs
@@ -1,10 +1,11 @@
 -- | Collection of modules for writing unit-generator graphs.
 module Sound.SC3.UGen (module U) where
 
+import Sound.SC3.UGen.Analysis as U
 import Sound.SC3.UGen.Envelope as U
-import Sound.SC3.UGen.Envelope.Construct as U
 import Sound.SC3.UGen.Enum as U
 import Sound.SC3.UGen.Help as U
+import Sound.SC3.UGen.Help.Graph as U
 import Sound.SC3.UGen.Identifier as U
 import Sound.SC3.UGen.Math as U
 import Sound.SC3.UGen.Name as U
diff --git a/Sound/SC3/UGen/Analysis.hs b/Sound/SC3/UGen/Analysis.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/Analysis.hs
@@ -0,0 +1,67 @@
+-- | UGen analysis
+module Sound.SC3.UGen.Analysis where
+
+import Data.List {- base -}
+
+import qualified Sound.SC3.UGen.Bindings.DB as DB
+import qualified Sound.SC3.UGen.MCE as MCE
+import Sound.SC3.UGen.Type
+
+-- | UGen primitive.  Sees through Proxy and MRG, possible multiple
+-- primitives for MCE.
+ugen_primitive :: UGen -> [Primitive]
+ugen_primitive u =
+    case u of
+      Constant_U _ -> []
+      Control_U _ -> []
+      Label_U _ -> []
+      Primitive_U p -> [p]
+      Proxy_U p -> [proxySource p]
+      MCE_U m -> concatMap ugen_primitive (MCE.mce_elem m)
+      MRG_U m -> ugen_primitive (mrgLeft m)
+
+-- | Heuristic based on primitive name (@FFT@, @PV_@).  Note that
+-- @IFFT@ is at /control/ rate, not @PV@ rate.
+primitive_is_pv_rate :: String -> Bool
+primitive_is_pv_rate nm = nm == "FFT" || "PV_" `isPrefixOf` nm
+
+-- | Variant on primitive_is_pv_rate.
+ugen_is_pv_rate :: UGen -> Bool
+ugen_is_pv_rate = any (primitive_is_pv_rate . ugenName) . ugen_primitive
+
+-- | Traverse input graph until an @FFT@ or @PV_Split@ node is
+-- encountered, and then locate the buffer input.  Biases left at MCE
+-- nodes.
+--
+-- > import Sound.SC3
+-- > let z = soundIn 4
+-- > let f1 = fft 10 z 0.5 0 1 0
+-- > let f2 = ffta 'a' 1024 z 0.5 0 1 0
+-- > pv_track_buffer (pv_BrickWall f1 0.5) == Right 10
+-- > pv_track_buffer (pv_BrickWall f2 0.5) == Right (localBuf 'a' 1024 1)
+pv_track_buffer :: UGen -> Either String UGen
+pv_track_buffer u =
+    case ugen_primitive u of
+      [] -> Left "pv_track_buffer: not located"
+      p:_ -> case ugenName p of
+               "FFT" -> Right (ugenInputs p !! 0)
+               "PV_Split" -> Right (ugenInputs p !! 1)
+               _ -> pv_track_buffer (ugenInputs p !! 0)
+
+-- | Buffer node number of frames. Biases left at MCE nodes.  Sees
+-- through @LocalBuf@, otherwise uses 'bufFrames'.
+--
+-- > buffer_nframes 10 == bufFrames IR 10
+-- > buffer_nframes (control KR "b" 0) == bufFrames KR (control KR "b" 0)
+-- > buffer_nframes (localBuf 'α' 2048 1) == 2048
+buffer_nframes :: UGen -> UGen
+buffer_nframes u =
+    case ugen_primitive u of
+      [] -> DB.bufFrames (rateOf u) u
+      p:_ -> case ugenName p of
+               "LocalBuf" -> ugenInputs p !! 1
+               _ -> DB.bufFrames (rateOf u) u
+
+-- | 'pv_track_buffer' then 'buffer_nframes'.
+pv_track_nframes :: UGen -> Either String UGen
+pv_track_nframes u = pv_track_buffer u >>= Right . buffer_nframes
diff --git a/Sound/SC3/UGen/Bindings.hs b/Sound/SC3/UGen/Bindings.hs
--- a/Sound/SC3/UGen/Bindings.hs
+++ b/Sound/SC3/UGen/Bindings.hs
@@ -3,5 +3,5 @@
 import Sound.SC3.UGen.Bindings.Composite as B
 import Sound.SC3.UGen.Bindings.DB as B
 import Sound.SC3.UGen.Bindings.HW as B
-import Sound.SC3.UGen.Bindings.HW.External as B
+--import Sound.SC3.UGen.Bindings.HW.External as B
 import Sound.SC3.UGen.Bindings.Monad as B
diff --git a/Sound/SC3/UGen/Bindings/Composite.hs b/Sound/SC3/UGen/Bindings/Composite.hs
--- a/Sound/SC3/UGen/Bindings/Composite.hs
+++ b/Sound/SC3/UGen/Bindings/Composite.hs
@@ -6,11 +6,12 @@
 import Data.List.Split {- split -}
 import Data.Maybe {- base -}
 
+import Sound.SC3.Common.Envelope
+
 import Sound.SC3.UGen.Bindings.DB
 import Sound.SC3.UGen.Bindings.HW
 import Sound.SC3.UGen.Bindings.Monad
 import Sound.SC3.UGen.Enum
-import Sound.SC3.UGen.Envelope
 import Sound.SC3.UGen.Identifier
 import Sound.SC3.UGen.Math
 import Sound.SC3.UGen.Rate
@@ -133,39 +134,38 @@
     in linLin (frac i) 0 1 x y
 -}
 
--- | Format frequency, amplitude and phase data as required for klang.
+-- | Generalised Klan(k/g) specification rule.  /f/ unwraps inputs, /g/ wraps output.
+--
+-- > let r = [220,0.2,0,219,0.1,1,221,0.1,2]
+-- > in klanx_spec_f id id [220,219,221] [0.2,0.1,0.1] [0,1,2] == r
+klanx_spec_f :: (a -> [b]) -> ([b] -> c) -> a -> a -> a -> c
+klanx_spec_f f g fr am z = g ((concat . transpose) [f fr,f am,f z])
+
+-- | Format frequency, amplitude and decay time data as required for klank.
 klangSpec :: [UGen] -> [UGen] -> [UGen] -> UGen
-klangSpec f a p = mce ((concat . transpose) [f, a, p])
+klangSpec = klanx_spec_f id mce
 
 -- | Variant of 'klangSpec' for non-UGen inputs.
 klangSpec' :: Real n => [n] -> [n] -> [n] -> UGen
-klangSpec' f a p =
-    let u = map constant
-    in klangSpec (u f) (u a) (u p)
+klangSpec' = klanx_spec_f (map constant) mce
 
 -- | Variant of 'klangSpec' for 'MCE' inputs.
 klangSpec_mce :: UGen -> UGen -> UGen -> UGen
-klangSpec_mce f a p =
-    let m = mceChannels
-    in klangSpec (m f) (m a) (m p)
+klangSpec_mce = klanx_spec_f mceChannels mce
 
 -- | Format frequency, amplitude and decay time data as required for klank.
 klankSpec :: [UGen] -> [UGen] -> [UGen] -> UGen
-klankSpec f a dt = mce ((concat . transpose) [f,a,dt])
+klankSpec = klanx_spec_f id mce
 
 -- | Variant for non-UGen inputs.
 klankSpec' :: Real n => [n] -> [n] -> [n] -> UGen
-klankSpec' f a dt =
-    let u = map constant
-    in klankSpec (u f) (u a) (u dt)
+klankSpec' = klanx_spec_f (map constant) mce
 
 -- | Variant of 'klankSpec' for 'MCE' inputs.
 klankSpec_mce :: UGen -> UGen -> UGen -> UGen
-klankSpec_mce f a dt =
-    let m = mceChannels
-    in klankSpec (m f) (m a) (m dt)
+klankSpec_mce = klanx_spec_f mceChannels mce
 
--- | Randomly select one of a list of UGens (initialiastion rate).
+-- | Randomly select one of a list of UGens (initialisation rate).
 lchoose :: ID m => m -> [UGen] -> UGen
 lchoose e a = select (iRand e 0 (fromIntegral (length a))) (mce a)
 
@@ -183,9 +183,7 @@
 
 -- | Map from one linear range to another linear range.
 linLin :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-linLin i sl sr dl dr =
-    let (m,a) = linLin_muladd sl sr dl dr
-    in mulAdd i m a
+linLin = linlin_ma
 
 -- | 'linLin' where source is (0,1).
 linLin_u :: UGen -> UGen -> UGen -> UGen
@@ -303,16 +301,33 @@
 -- | Apply function /f/ to each bin of an @FFT@ chain, /f/ receives
 -- magnitude, phase and index and returns a (magnitude,phase).
 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
+pvcollect c nf f from to z =
+    let m = unpackFFT c nf from to 0
         p = unpackFFT c nf from to 1
         i = [from .. to]
         e = zipWith3 f m p i
         mp = uncurry packFFTSpec (unzip e)
+    in packFFT c nf from to z mp
 
+-- | 'rand' with left edge set to zero.
+rand0 :: ID a => a -> UGen -> UGen
+rand0 z = rand z 0
+
+-- | 'UId' form of 'rand0'.
+rand0M :: UId m => UGen -> m UGen
+rand0M = randM 0
+
+-- | 'rand' with left edge set to negative /n/.
+rand2 :: ID a => a -> UGen -> UGen
+rand2 z n = rand z (negate n) n
+
+-- | 'UId' form of 'rand2'.
+rand2M :: UId m => UGen -> m UGen
+rand2M n = randM (negate n) n
+
 -- | RMS variant of 'runningSum'.
 runningSumRMS :: UGen -> UGen -> UGen
-runningSumRMS z n = sqrt (runningSum (z * z) n * (recip n))
+runningSumRMS z n = sqrt (runningSum (z * z) n * recip n)
 
 -- | Mix one output from many sources
 selectX :: UGen -> UGen -> UGen
@@ -342,9 +357,11 @@
          _ -> r
 
 -- | Pan a set of channels across the stereo field.
+--
+-- > input, spread:1, level:1, center:0, levelComp:true
 splay :: UGen -> UGen -> UGen -> UGen -> Bool -> UGen
 splay i s l c lc =
-    let n = fromIntegral (mceDegree i)
+    let n = max 2 (fromIntegral (fromMaybe 1 (mceDegree i)))
         m = n - 1
         p = map ( (+ (-1.0)) . (* (2 / m)) ) [0 .. m]
         a = if lc then sqrt (1 / n) else 1
@@ -374,6 +391,17 @@
   r <- tIRandM 0 (constant (length (mceChannels a))) t
   return (select r a)
 
+-- | Triangle wave as sum of /n/ sines.
+-- For partial n, amplitude is (1 / square n) and phase is pi at every other odd partial.
+triAS :: Int -> UGen -> UGen
+triAS n f0 =
+    let mk_freq i = f0 * fromIntegral i
+        mk_amp i = if even i then 0 else 1 / fromIntegral (i * i)
+        mk_ph i = if i + 1 `mod` 4 == 0 then pi else 0
+        m = [1,3 .. n]
+        param = zip3 (map mk_freq m) (map mk_ph m) (map mk_amp m)
+    in sum (map (\(fr,ph,am) -> sinOsc AR fr ph * am) param)
+
 -- | Randomly select one of several inputs on trigger (weighted).
 tWChoose :: ID m => m -> UGen -> UGen -> UGen -> UGen -> UGen
 tWChoose z t a w n =
@@ -416,8 +444,8 @@
              [0 .. constant n - 1]
         rate' = case rateOf rate of
                   DR -> map (\on' -> demand on' 0 rate) on
-                  KR -> map (\on' -> gate rate on') on
-                  AR -> map (\on' -> gate rate on') on
+                  KR -> map (gate rate) on
+                  AR -> map (gate rate) on
                   IR -> map (const rate) on
         startPos' = if rateOf startPos == DR
                     then demand trigger' 0 startPos
diff --git a/Sound/SC3/UGen/Bindings/DB.hs b/Sound/SC3/UGen/Bindings/DB.hs
--- a/Sound/SC3/UGen/Bindings/DB.hs
+++ b/Sound/SC3/UGen/Bindings/DB.hs
@@ -1,6 +1,7 @@
 module Sound.SC3.UGen.Bindings.DB where
 
-import Sound.SC3.UGen.Envelope
+import Sound.SC3.Common.Envelope
+
 import Sound.SC3.UGen.Enum
 import Sound.SC3.UGen.Identifier
 import Sound.SC3.UGen.Rate
@@ -8,1509 +9,2261 @@
 import Sound.SC3.UGen.UGen
 
 -- | Audio to control rate converter.
+--
+--  A2K [KR] in=0.0
 a2K :: UGen -> UGen
 a2K in_ = mkUGen Nothing [KR] (Left KR) "A2K" [in_] Nothing 1 (Special 0) NoId
 
 -- | FIXME: APF purpose.
+--
+--  APF [KR,AR] in=0.0 freq=440.0 radius=0.8;    FILTER: TRUE
 apf :: UGen -> UGen -> UGen -> UGen
 apf in_ freq radius = mkUGen Nothing [KR,AR] (Right [0]) "APF" [in_,freq,radius] Nothing 1 (Special 0) NoId
 
 -- | All pass delay line with cubic interpolation.
+--
+--  AllpassC [KR,AR] in=0.0 maxdelaytime=0.2 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
 allpassC :: UGen -> UGen -> UGen -> UGen -> UGen
 allpassC in_ maxdelaytime delaytime decaytime = mkUGen Nothing [KR,AR] (Right [0]) "AllpassC" [in_,maxdelaytime,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | All pass delay line with linear interpolation.
+--
+--  AllpassL [KR,AR] in=0.0 maxdelaytime=0.2 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
 allpassL :: UGen -> UGen -> UGen -> UGen -> UGen
 allpassL in_ maxdelaytime delaytime decaytime = mkUGen Nothing [KR,AR] (Right [0]) "AllpassL" [in_,maxdelaytime,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | All pass delay line with no interpolation.
+--
+--  AllpassN [KR,AR] in=0.0 maxdelaytime=0.2 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
 allpassN :: UGen -> UGen -> UGen -> UGen -> UGen
 allpassN in_ maxdelaytime delaytime decaytime = mkUGen Nothing [KR,AR] (Right [0]) "AllpassN" [in_,maxdelaytime,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Basic psychoacoustic amplitude compensation.
+--
+--  AmpComp [IR,KR,AR] freq=0.0 root=0.0 exp=0.3333
 ampComp :: Rate -> UGen -> UGen -> UGen -> UGen
 ampComp rate freq root exp_ = mkUGen Nothing [IR,KR,AR] (Left rate) "AmpComp" [freq,root,exp_] Nothing 1 (Special 0) NoId
 
 -- | Basic psychoacoustic amplitude compensation (ANSI A-weighting curve).
+--
+--  AmpCompA [IR,KR,AR] freq=1000.0 root=0.0 minAmp=0.32 rootAmp=1.0
 ampCompA :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 ampCompA rate freq root minAmp rootAmp = mkUGen Nothing [IR,KR,AR] (Left rate) "AmpCompA" [freq,root,minAmp,rootAmp] Nothing 1 (Special 0) NoId
 
 -- | Amplitude follower
+--
+--  Amplitude [KR,AR] in=0.0 attackTime=1.0e-2 releaseTime=1.0e-2
 amplitude :: Rate -> UGen -> UGen -> UGen -> UGen
 amplitude rate in_ attackTime releaseTime = mkUGen Nothing [KR,AR] (Left rate) "Amplitude" [in_,attackTime,releaseTime] Nothing 1 (Special 0) NoId
 
 -- | (Undocumented class)
+--
+--  AudioControl [AR] values=0.0
 audioControl :: Rate -> UGen -> UGen
 audioControl rate values = mkUGen Nothing [AR] (Left rate) "AudioControl" [values] Nothing 0 (Special 0) NoId
 
 -- | All Pass Filter
+--
+--  BAllPass [AR] in=0.0 freq=1200.0 rq=1.0;    FILTER: TRUE
 bAllPass :: UGen -> UGen -> UGen -> UGen
 bAllPass in_ freq rq = mkUGen Nothing [AR] (Right [0]) "BAllPass" [in_,freq,rq] Nothing 1 (Special 0) NoId
 
 -- | Band Pass Filter
+--
+--  BBandPass [AR] in=0.0 freq=1200.0 bw=1.0;    FILTER: TRUE
 bBandPass :: UGen -> UGen -> UGen -> UGen
 bBandPass in_ freq bw = mkUGen Nothing [AR] (Right [0]) "BBandPass" [in_,freq,bw] Nothing 1 (Special 0) NoId
 
 -- | Band reject filter
+--
+--  BBandStop [AR] in=0.0 freq=1200.0 bw=1.0;    FILTER: TRUE
 bBandStop :: UGen -> UGen -> UGen -> UGen
 bBandStop in_ freq bw = mkUGen Nothing [AR] (Right [0]) "BBandStop" [in_,freq,bw] Nothing 1 (Special 0) NoId
 
 -- | 12db/oct rolloff - 2nd order resonant  Hi Pass Filter
+--
+--  BHiPass [AR] in=0.0 freq=1200.0 rq=1.0;    FILTER: TRUE
 bHiPass :: UGen -> UGen -> UGen -> UGen
 bHiPass in_ freq rq = mkUGen Nothing [AR] (Right [0]) "BHiPass" [in_,freq,rq] Nothing 1 (Special 0) NoId
 
 -- | Hi Shelf
+--
+--  BHiShelf [AR] in=0.0 freq=1200.0 rs=1.0 db=0.0;    FILTER: TRUE
 bHiShelf :: UGen -> UGen -> UGen -> UGen -> UGen
 bHiShelf in_ freq rs db = mkUGen Nothing [AR] (Right [0]) "BHiShelf" [in_,freq,rs,db] Nothing 1 (Special 0) NoId
 
 -- | 12db/oct rolloff - 2nd order resonant Low Pass Filter
+--
+--  BLowPass [AR] in=0.0 freq=1200.0 rq=1.0;    FILTER: TRUE
 bLowPass :: UGen -> UGen -> UGen -> UGen
 bLowPass in_ freq rq = mkUGen Nothing [AR] (Right [0]) "BLowPass" [in_,freq,rq] Nothing 1 (Special 0) NoId
 
 -- | Low Shelf
+--
+--  BLowShelf [AR] in=0.0 freq=1200.0 rs=1.0 db=0.0;    FILTER: TRUE
 bLowShelf :: UGen -> UGen -> UGen -> UGen -> UGen
 bLowShelf in_ freq rs db = mkUGen Nothing [AR] (Right [0]) "BLowShelf" [in_,freq,rs,db] Nothing 1 (Special 0) NoId
 
 -- | 2nd order Butterworth bandpass filter.
+--
+--  BPF [KR,AR] in=0.0 freq=440.0 rq=1.0;    FILTER: TRUE
 bpf :: UGen -> UGen -> UGen -> UGen
 bpf in_ freq rq = mkUGen Nothing [KR,AR] (Right [0]) "BPF" [in_,freq,rq] Nothing 1 (Special 0) NoId
 
 -- | Two zero fixed midpass.
+--
+--  BPZ2 [KR,AR] in=0.0;    FILTER: TRUE
 bpz2 :: UGen -> UGen
 bpz2 in_ = mkUGen Nothing [KR,AR] (Right [0]) "BPZ2" [in_] Nothing 1 (Special 0) NoId
 
 -- | Parametric equalizer
+--
+--  BPeakEQ [AR] in=0.0 freq=1200.0 rq=1.0 db=0.0;    FILTER: TRUE
 bPeakEQ :: UGen -> UGen -> UGen -> UGen -> UGen
 bPeakEQ in_ freq rq db = mkUGen Nothing [AR] (Right [0]) "BPeakEQ" [in_,freq,rq,db] Nothing 1 (Special 0) NoId
 
 -- | 2nd order Butterworth band reject filter.
+--
+--  BRF [KR,AR] in=0.0 freq=440.0 rq=1.0;    FILTER: TRUE
 brf :: UGen -> UGen -> UGen -> UGen
 brf in_ freq rq = mkUGen Nothing [KR,AR] (Right [0]) "BRF" [in_,freq,rq] Nothing 1 (Special 0) NoId
 
 -- | Two zero fixed midcut.
+--
+--  BRZ2 [KR,AR] in=0.0;    FILTER: TRUE
 brz2 :: UGen -> UGen
 brz2 in_ = mkUGen Nothing [KR,AR] (Right [0]) "BRZ2" [in_] Nothing 1 (Special 0) NoId
 
 -- | Stereo signal balancer
-balance2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
-balance2 rate left right pos level = mkUGen Nothing [KR,AR] (Left rate) "Balance2" [left,right,pos,level] Nothing 2 (Special 0) NoId
+--
+--  Balance2 [KR,AR] left=0.0 right=0.0 pos=0.0 level=1.0;    FILTER: TRUE
+balance2 :: UGen -> UGen -> UGen -> UGen -> UGen
+balance2 left right pos level = mkUGen Nothing [KR,AR] (Right [0,1]) "Balance2" [left,right,pos,level] Nothing 2 (Special 0) NoId
 
 -- | physical model of bouncing object
+--
+--  Ball [KR,AR] in=0.0 g=1.0 damp=0.0 friction=1.0e-2
 ball :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 ball rate in_ g damp friction = mkUGen Nothing [KR,AR] (Left rate) "Ball" [in_,g,damp,friction] Nothing 1 (Special 0) NoId
 
 -- | Autocorrelation beat tracker
+--
+--  BeatTrack [KR] chain=0.0 lock=0.0
 beatTrack :: Rate -> UGen -> UGen -> UGen
-beatTrack rate chain lock = mkUGen Nothing [KR] (Left rate) "BeatTrack" [chain,lock] Nothing 1 (Special 0) NoId
+beatTrack rate chain lock = mkUGen Nothing [KR] (Left rate) "BeatTrack" [chain,lock] Nothing 4 (Special 0) NoId
 
 -- | Template matching beat tracker
+--
+--  BeatTrack2 [KR] busindex=0.0 numfeatures=0.0 windowsize=2.0 phaseaccuracy=2.0e-2 lock=0.0 weightingscheme=0.0
 beatTrack2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 beatTrack2 rate busindex numfeatures windowsize phaseaccuracy lock weightingscheme = mkUGen Nothing [KR] (Left rate) "BeatTrack2" [busindex,numfeatures,windowsize,phaseaccuracy,lock,weightingscheme] Nothing 6 (Special 0) NoId
 
 -- | 2D Ambisonic B-format panner.
+--
+--  BiPanB2 [KR,AR] inA=0.0 inB=0.0 azimuth=0.0 gain=1.0
 biPanB2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 biPanB2 rate inA inB azimuth gain = mkUGen Nothing [KR,AR] (Left rate) "BiPanB2" [inA,inB,azimuth,gain] Nothing 3 (Special 0) NoId
 
 -- | Apply a binary operation to the values of an input UGen
+--
+--  BinaryOpUGen [] a=0.0 b=0.0;    FILTER: TRUE
 binaryOpUGen :: UGen -> UGen -> UGen
 binaryOpUGen a b = mkUGen Nothing [IR,KR,AR,DR] (Right [0,1]) "BinaryOpUGen" [a,b] Nothing 1 (Special 0) NoId
 
 -- | Band limited impulse oscillator.
+--
+--  Blip [KR,AR] freq=440.0 numharm=200.0
 blip :: Rate -> UGen -> UGen -> UGen
 blip rate freq numharm = mkUGen Nothing [KR,AR] (Left rate) "Blip" [freq,numharm] Nothing 1 (Special 0) NoId
 
 -- | (Undocumented class)
+--
+--  BlockSize [IR]
 blockSize :: UGen
 blockSize = mkUGen Nothing [IR] (Left IR) "BlockSize" [] Nothing 1 (Special 0) NoId
 
 -- | Brown Noise.
+--
+--  BrownNoise [KR,AR] ;    NONDET
 brownNoise :: ID a => a -> Rate -> UGen
 brownNoise z rate = mkUGen Nothing [KR,AR] (Left rate) "BrownNoise" [] Nothing 1 (Special 0) (toUId z)
 
 -- | Buffer based all pass delay line with cubic interpolation.
-bufAllpassC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
-bufAllpassC rate buf in_ delaytime decaytime = mkUGen Nothing [AR] (Left rate) "BufAllpassC" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
+--
+--  BufAllpassC [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0
+bufAllpassC :: UGen -> UGen -> UGen -> UGen -> UGen
+bufAllpassC buf in_ delaytime decaytime = mkUGen Nothing [AR] (Right [1]) "BufAllpassC" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Buffer based all pass delay line with linear interpolation.
-bufAllpassL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
-bufAllpassL rate buf in_ delaytime decaytime = mkUGen Nothing [AR] (Left rate) "BufAllpassL" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
+--
+--  BufAllpassL [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0
+bufAllpassL :: UGen -> UGen -> UGen -> UGen -> UGen
+bufAllpassL buf in_ delaytime decaytime = mkUGen Nothing [AR] (Right [1]) "BufAllpassL" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Buffer based all pass delay line with no interpolation.
-bufAllpassN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
-bufAllpassN rate buf in_ delaytime decaytime = mkUGen Nothing [AR] (Left rate) "BufAllpassN" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
+--
+--  BufAllpassN [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0
+bufAllpassN :: UGen -> UGen -> UGen -> UGen -> UGen
+bufAllpassN buf in_ delaytime decaytime = mkUGen Nothing [AR] (Right [1]) "BufAllpassN" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Current number of channels of soundfile in buffer.
+--
+--  BufChannels [IR,KR] bufnum=0.0
 bufChannels :: Rate -> UGen -> UGen
 bufChannels rate bufnum = mkUGen Nothing [IR,KR] (Left rate) "BufChannels" [bufnum] Nothing 1 (Special 0) NoId
 
 -- | Buffer based comb delay line with cubic interpolation.
-bufCombC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
-bufCombC rate buf in_ delaytime decaytime = mkUGen Nothing [AR] (Left rate) "BufCombC" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
+--
+--  BufCombC [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
+bufCombC :: UGen -> UGen -> UGen -> UGen -> UGen
+bufCombC buf in_ delaytime decaytime = mkUGen Nothing [AR] (Right [1]) "BufCombC" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Buffer based comb delay line with linear interpolation.
-bufCombL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
-bufCombL rate buf in_ delaytime decaytime = mkUGen Nothing [AR] (Left rate) "BufCombL" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
+--
+--  BufCombL [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
+bufCombL :: UGen -> UGen -> UGen -> UGen -> UGen
+bufCombL buf in_ delaytime decaytime = mkUGen Nothing [AR] (Right [1]) "BufCombL" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Buffer based comb delay line with no interpolation.
-bufCombN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
-bufCombN rate buf in_ delaytime decaytime = mkUGen Nothing [AR] (Left rate) "BufCombN" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
+--
+--  BufCombN [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
+bufCombN :: UGen -> UGen -> UGen -> UGen -> UGen
+bufCombN buf in_ delaytime decaytime = mkUGen Nothing [AR] (Right [1]) "BufCombN" [buf,in_,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Buffer based simple delay line with cubic interpolation.
-bufDelayC :: Rate -> UGen -> UGen -> UGen -> UGen
-bufDelayC rate buf in_ delaytime = mkUGen Nothing [KR,AR] (Left rate) "BufDelayC" [buf,in_,delaytime] Nothing 1 (Special 0) NoId
+--
+--  BufDelayC [KR,AR] buf=0.0 in=0.0 delaytime=0.2
+bufDelayC :: UGen -> UGen -> UGen -> UGen
+bufDelayC buf in_ delaytime = mkUGen Nothing [KR,AR] (Right [1]) "BufDelayC" [buf,in_,delaytime] Nothing 1 (Special 0) NoId
 
 -- | Buffer based simple delay line with linear interpolation.
-bufDelayL :: Rate -> UGen -> UGen -> UGen -> UGen
-bufDelayL rate buf in_ delaytime = mkUGen Nothing [KR,AR] (Left rate) "BufDelayL" [buf,in_,delaytime] Nothing 1 (Special 0) NoId
+--
+--  BufDelayL [KR,AR] buf=0.0 in=0.0 delaytime=0.2
+bufDelayL :: UGen -> UGen -> UGen -> UGen
+bufDelayL buf in_ delaytime = mkUGen Nothing [KR,AR] (Right [1]) "BufDelayL" [buf,in_,delaytime] Nothing 1 (Special 0) NoId
 
 -- | Buffer based simple delay line with no interpolation.
-bufDelayN :: Rate -> UGen -> UGen -> UGen -> UGen
-bufDelayN rate buf in_ delaytime = mkUGen Nothing [KR,AR] (Left rate) "BufDelayN" [buf,in_,delaytime] Nothing 1 (Special 0) NoId
+--
+--  BufDelayN [KR,AR] buf=0.0 in=0.0 delaytime=0.2
+bufDelayN :: UGen -> UGen -> UGen -> UGen
+bufDelayN buf in_ delaytime = mkUGen Nothing [KR,AR] (Right [1]) "BufDelayN" [buf,in_,delaytime] Nothing 1 (Special 0) NoId
 
 -- | Current duration of soundfile in buffer.
+--
+--  BufDur [IR,KR] bufnum=0.0
 bufDur :: Rate -> UGen -> UGen
 bufDur rate bufnum = mkUGen Nothing [IR,KR] (Left rate) "BufDur" [bufnum] Nothing 1 (Special 0) NoId
 
 -- | Current number of frames allocated in the buffer.
+--
+--  BufFrames [IR,KR] bufnum=0.0
 bufFrames :: Rate -> UGen -> UGen
 bufFrames rate bufnum = mkUGen Nothing [IR,KR] (Left rate) "BufFrames" [bufnum] Nothing 1 (Special 0) NoId
 
 -- | Buffer rate scaling in respect to server samplerate.
+--
+--  BufRateScale [IR,KR] bufnum=0.0
 bufRateScale :: Rate -> UGen -> UGen
 bufRateScale rate bufnum = mkUGen Nothing [IR,KR] (Left rate) "BufRateScale" [bufnum] Nothing 1 (Special 0) NoId
 
 -- | Buffer reading oscillator.
+--
+--  BufRd [KR,AR] bufnum=0.0 phase=0.0 loop=1.0 interpolation=2.0;    NC INPUT: True, ENUMERATION INPUTS: 2=Loop, 3=Interpolation
 bufRd :: Int -> Rate -> UGen -> UGen -> Loop -> Interpolation -> UGen
 bufRd numChannels rate bufnum phase loop interpolation = mkUGen Nothing [KR,AR] (Left rate) "BufRd" [bufnum,phase,(from_loop loop),(from_interpolation interpolation)] Nothing numChannels (Special 0) NoId
 
 -- | Buffer sample rate.
+--
+--  BufSampleRate [IR,KR] bufnum=0.0
 bufSampleRate :: Rate -> UGen -> UGen
 bufSampleRate rate bufnum = mkUGen Nothing [IR,KR] (Left rate) "BufSampleRate" [bufnum] Nothing 1 (Special 0) NoId
 
 -- | Current number of samples in buffer.
+--
+--  BufSamples [IR,KR] bufnum=0.0
 bufSamples :: Rate -> UGen -> UGen
 bufSamples rate bufnum = mkUGen Nothing [IR,KR] (Left rate) "BufSamples" [bufnum] Nothing 1 (Special 0) NoId
 
 -- | Buffer writing oscillator.
+--
+--  BufWr [KR,AR] bufnum=0.0 phase=0.0 loop=1.0 *inputArray=0.0;    MCE, FILTER: TRUE, REORDERS INPUTS: [3,0,1,2], ENUMERATION INPUTS: 2=Loop
 bufWr :: UGen -> UGen -> Loop -> UGen -> UGen
 bufWr bufnum phase loop inputArray = mkUGen Nothing [KR,AR] (Right [3]) "BufWr" [bufnum,phase,(from_loop loop)] (Just inputArray) 1 (Special 0) NoId
 
 -- | Chorusing wavetable oscillator.
+--
+--  COsc [KR,AR] bufnum=0.0 freq=440.0 beats=0.5
 cOsc :: Rate -> UGen -> UGen -> UGen -> UGen
 cOsc rate bufnum freq beats = mkUGen Nothing [KR,AR] (Left rate) "COsc" [bufnum,freq,beats] Nothing 1 (Special 0) NoId
 
 -- | Test for infinity, not-a-number, and denormals
+--
+--  CheckBadValues [KR,AR] in=0.0 id=0.0 post=2.0;    FILTER: TRUE
 checkBadValues :: UGen -> UGen -> UGen -> UGen
 checkBadValues in_ id_ post = mkUGen Nothing [KR,AR] (Right [0]) "CheckBadValues" [in_,id_,post] Nothing 1 (Special 0) NoId
 
 -- | Clip a signal outside given thresholds.
+--
+--  Clip [IR,KR,AR] in=0.0 lo=0.0 hi=1.0;    FILTER: TRUE
 clip :: UGen -> UGen -> UGen -> UGen
 clip in_ lo hi = mkUGen Nothing [IR,KR,AR] (Right [0]) "Clip" [in_,lo,hi] Nothing 1 (Special 0) NoId
 
 -- | Clip Noise.
+--
+--  ClipNoise [KR,AR] ;    NONDET
 clipNoise :: ID a => a -> Rate -> UGen
 clipNoise z rate = mkUGen Nothing [KR,AR] (Left rate) "ClipNoise" [] Nothing 1 (Special 0) (toUId z)
 
 -- | Statistical gate.
+--
+--  CoinGate [KR,AR] prob=0.0 in=0.0;    FILTER: TRUE, NONDET
 coinGate :: ID a => a -> UGen -> UGen -> UGen
 coinGate z prob in_ = mkUGen Nothing [KR,AR] (Right [1]) "CoinGate" [prob,in_] Nothing 1 (Special 0) (toUId z)
 
 -- | Comb delay line with cubic interpolation.
+--
+--  CombC [KR,AR] in=0.0 maxdelaytime=0.2 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
 combC :: UGen -> UGen -> UGen -> UGen -> UGen
 combC in_ maxdelaytime delaytime decaytime = mkUGen Nothing [KR,AR] (Right [0]) "CombC" [in_,maxdelaytime,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Comb delay line with linear interpolation.
+--
+--  CombL [KR,AR] in=0.0 maxdelaytime=0.2 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
 combL :: UGen -> UGen -> UGen -> UGen -> UGen
 combL in_ maxdelaytime delaytime decaytime = mkUGen Nothing [KR,AR] (Right [0]) "CombL" [in_,maxdelaytime,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Comb delay line with no interpolation.
+--
+--  CombN [KR,AR] in=0.0 maxdelaytime=0.2 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
 combN :: UGen -> UGen -> UGen -> UGen -> UGen
 combN in_ maxdelaytime delaytime decaytime = mkUGen Nothing [KR,AR] (Right [0]) "CombN" [in_,maxdelaytime,delaytime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Compressor, expander, limiter, gate, ducker
+--
+--  Compander [AR] in=0.0 control=0.0 thresh=0.5 slopeBelow=1.0 slopeAbove=1.0 clampTime=1.0e-2 relaxTime=0.1;    FILTER: TRUE
 compander :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 compander in_ control_ thresh slopeBelow slopeAbove clampTime relaxTime = mkUGen Nothing [AR] (Right [0]) "Compander" [in_,control_,thresh,slopeBelow,slopeAbove,clampTime,relaxTime] Nothing 1 (Special 0) NoId
 
 -- | Compressor, expander, limiter, gate, ducker.
+--
+--  CompanderD [AR] in=0.0 thresh=0.5 slopeBelow=1.0 slopeAbove=1.0 clampTime=1.0e-2 relaxTime=1.0e-2
 companderD :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 companderD rate in_ thresh slopeBelow slopeAbove clampTime relaxTime = mkUGen Nothing [AR] (Left rate) "CompanderD" [in_,thresh,slopeBelow,slopeAbove,clampTime,relaxTime] Nothing 1 (Special 0) NoId
 
 -- | Duration of one block
+--
+--  ControlDur [IR]
 controlDur :: UGen
 controlDur = mkUGen Nothing [IR] (Left IR) "ControlDur" [] Nothing 1 (Special 0) NoId
 
 -- | Server control rate.
+--
+--  ControlRate [IR]
 controlRate :: UGen
 controlRate = mkUGen Nothing [IR] (Left IR) "ControlRate" [] Nothing 1 (Special 0) NoId
 
 -- | Real-time convolver.
+--
+--  Convolution [AR] in=0.0 kernel=0.0 framesize=512.0
 convolution :: Rate -> UGen -> UGen -> UGen -> UGen
 convolution rate in_ kernel framesize = mkUGen Nothing [AR] (Left rate) "Convolution" [in_,kernel,framesize] Nothing 1 (Special 0) NoId
 
 -- | Real-time fixed kernel convolver.
+--
+--  Convolution2 [AR] in=0.0 kernel=0.0 trigger=0.0 framesize=2048.0
 convolution2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 convolution2 rate in_ kernel trigger framesize = mkUGen Nothing [AR] (Left rate) "Convolution2" [in_,kernel,trigger,framesize] Nothing 1 (Special 0) NoId
 
 -- | Real-time convolver with linear interpolation
+--
+--  Convolution2L [AR] in=0.0 kernel=0.0 trigger=0.0 framesize=2048.0 crossfade=1.0
 convolution2L :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 convolution2L rate in_ kernel trigger framesize crossfade = mkUGen Nothing [AR] (Left rate) "Convolution2L" [in_,kernel,trigger,framesize,crossfade] Nothing 1 (Special 0) NoId
 
 -- | Time based convolver.
+--
+--  Convolution3 [KR,AR] in=0.0 kernel=0.0 trigger=0.0 framesize=2048.0
 convolution3 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 convolution3 rate in_ kernel trigger framesize = mkUGen Nothing [KR,AR] (Left rate) "Convolution3" [in_,kernel,trigger,framesize] Nothing 1 (Special 0) NoId
 
 -- | Chaotic noise function.
+--
+--  Crackle [KR,AR] chaosParam=1.5
 crackle :: Rate -> UGen -> UGen
 crackle rate chaosParam = mkUGen Nothing [KR,AR] (Left rate) "Crackle" [chaosParam] Nothing 1 (Special 0) NoId
 
 -- | Cusp map chaotic generator
+--
+--  CuspL [AR] freq=22050.0 a=1.0 b=1.9 xi=0.0
 cuspL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 cuspL rate freq a b xi = mkUGen Nothing [AR] (Left rate) "CuspL" [freq,a,b,xi] Nothing 1 (Special 0) NoId
 
 -- | Cusp map chaotic generator
+--
+--  CuspN [AR] freq=22050.0 a=1.0 b=1.9 xi=0.0
 cuspN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 cuspN rate freq a b xi = mkUGen Nothing [AR] (Left rate) "CuspN" [freq,a,b,xi] Nothing 1 (Special 0) NoId
 
 -- | Create a constant amplitude signal
+--
+--  DC [KR,AR] in=0.0
 dc :: Rate -> UGen -> UGen
 dc rate in_ = mkUGen Nothing [KR,AR] (Left rate) "DC" [in_] Nothing 1 (Special 0) NoId
 
 -- | Demand rate brownian movement generator.
+--
+--  Dbrown [DR] length=1.0e8 lo=0.0 hi=1.0 step=1.0e-2;    REORDERS INPUTS: [1,2,3,0], DEMAND/NONDET
 dbrown :: ID a => a -> UGen -> UGen -> UGen -> UGen -> UGen
 dbrown z length_ lo hi step = mkUGen Nothing [DR] (Left DR) "Dbrown" [length_,lo,hi,step] Nothing 1 (Special 0) (toUId z)
 
 -- | Buffer read demand ugen
+--
+--  Dbufrd [DR] bufnum=0.0 phase=0.0 loop=1.0;    ENUMERATION INPUTS: 2=Loop, DEMAND/NONDET
 dbufrd :: ID a => a -> UGen -> UGen -> Loop -> UGen
 dbufrd z bufnum phase loop = mkUGen Nothing [DR] (Left DR) "Dbufrd" [bufnum,phase,(from_loop loop)] Nothing 1 (Special 0) (toUId z)
 
 -- | Buffer write demand ugen
+--
+--  Dbufwr [DR] bufnum=0.0 phase=0.0 loop=1.0 input=0.0;    REORDERS INPUTS: [3,0,1,2], ENUMERATION INPUTS: 3=Loop, DEMAND/NONDET
 dbufwr :: ID a => a -> UGen -> UGen -> UGen -> Loop -> UGen
 dbufwr z bufnum phase loop input = mkUGen Nothing [DR] (Left DR) "Dbufwr" [bufnum,phase,loop,(from_loop input)] Nothing 1 (Special 0) (toUId z)
 
 -- | Exponential decay
+--
+--  Decay [KR,AR] in=0.0 decayTime=1.0;    FILTER: TRUE
 decay :: UGen -> UGen -> UGen
 decay in_ decayTime = mkUGen Nothing [KR,AR] (Right [0]) "Decay" [in_,decayTime] Nothing 1 (Special 0) NoId
 
 -- | Exponential decay
+--
+--  Decay2 [KR,AR] in=0.0 attackTime=1.0e-2 decayTime=1.0;    FILTER: TRUE
 decay2 :: UGen -> UGen -> UGen -> UGen
 decay2 in_ attackTime decayTime = mkUGen Nothing [KR,AR] (Right [0]) "Decay2" [in_,attackTime,decayTime] Nothing 1 (Special 0) NoId
 
 -- | 2D Ambisonic B-format decoder.
+--
+--  DecodeB2 [KR,AR] w=0.0 x=0.0 y=0.0 orientation=0.5;    NC INPUT: True
 decodeB2 :: Int -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 decodeB2 numChannels rate w x y orientation = mkUGen Nothing [KR,AR] (Left rate) "DecodeB2" [w,x,y,orientation] Nothing numChannels (Special 0) NoId
 
 -- | Convert signal to modal pitch.
+--
+--  DegreeToKey [KR,AR] bufnum=0.0 in=0.0 octave=12.0;    FILTER: TRUE
 degreeToKey :: UGen -> UGen -> UGen -> UGen
 degreeToKey bufnum in_ octave = mkUGen Nothing [KR,AR] (Right [1]) "DegreeToKey" [bufnum,in_,octave] Nothing 1 (Special 0) NoId
 
 -- | Tap a delay line from a DelTapWr UGen
+--
+--  DelTapRd [KR,AR] buffer=0.0 phase=0.0 delTime=0.0 interp=1.0;    FILTER: TRUE
 delTapRd :: UGen -> UGen -> UGen -> UGen -> UGen
 delTapRd buffer phase delTime interp = mkUGen Nothing [KR,AR] (Right [1]) "DelTapRd" [buffer,phase,delTime,interp] Nothing 1 (Special 0) NoId
 
 -- | Write to a buffer for a DelTapRd UGen
+--
+--  DelTapWr [KR,AR] buffer=0.0 in=0.0;    FILTER: TRUE
 delTapWr :: UGen -> UGen -> UGen
 delTapWr buffer in_ = mkUGen Nothing [KR,AR] (Right [1]) "DelTapWr" [buffer,in_] Nothing 1 (Special 0) NoId
 
 -- | Single sample delay.
+--
+--  Delay1 [KR,AR] in=0.0;    FILTER: TRUE
 delay1 :: UGen -> UGen
 delay1 in_ = mkUGen Nothing [KR,AR] (Right [0]) "Delay1" [in_] Nothing 1 (Special 0) NoId
 
 -- | Two sample delay.
+--
+--  Delay2 [KR,AR] in=0.0;    FILTER: TRUE
 delay2 :: UGen -> UGen
 delay2 in_ = mkUGen Nothing [KR,AR] (Right [0]) "Delay2" [in_] Nothing 1 (Special 0) NoId
 
 -- | Simple delay line with cubic interpolation.
+--
+--  DelayC [KR,AR] in=0.0 maxdelaytime=0.2 delaytime=0.2;    FILTER: TRUE
 delayC :: UGen -> UGen -> UGen -> UGen
 delayC in_ maxdelaytime delaytime = mkUGen Nothing [KR,AR] (Right [0]) "DelayC" [in_,maxdelaytime,delaytime] Nothing 1 (Special 0) NoId
 
 -- | Simple delay line with linear interpolation.
+--
+--  DelayL [KR,AR] in=0.0 maxdelaytime=0.2 delaytime=0.2;    FILTER: TRUE
 delayL :: UGen -> UGen -> UGen -> UGen
 delayL in_ maxdelaytime delaytime = mkUGen Nothing [KR,AR] (Right [0]) "DelayL" [in_,maxdelaytime,delaytime] Nothing 1 (Special 0) NoId
 
 -- | Simple delay line with no interpolation.
+--
+--  DelayN [KR,AR] in=0.0 maxdelaytime=0.2 delaytime=0.2;    FILTER: TRUE
 delayN :: UGen -> UGen -> UGen -> UGen
 delayN in_ maxdelaytime delaytime = mkUGen Nothing [KR,AR] (Right [0]) "DelayN" [in_,maxdelaytime,delaytime] Nothing 1 (Special 0) NoId
 
 -- | Demand results from demand rate UGens.
+--
+--  Demand [KR,AR] trig=0.0 reset=0.0 *demandUGens=0.0;    MCE, FILTER: TRUE
 demand :: UGen -> UGen -> UGen -> UGen
 demand trig_ reset demandUGens = mkUGen Nothing [KR,AR] (Right [0]) "Demand" [trig_,reset] (Just demandUGens) (length (mceChannels demandUGens) + 0) (Special 0) NoId
 
 -- | Demand rate envelope generator
+--
+--  DemandEnvGen [KR,AR] level=0.0 dur=0.0 shape=1.0 curve=0.0 gate=1.0 reset=1.0 levelScale=1.0 levelBias=0.0 timeScale=1.0 doneAction=0.0;    ENUMERATION INPUTS: 9=DoneAction
 demandEnvGen :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> DoneAction -> UGen
 demandEnvGen rate level dur shape curve gate_ reset levelScale levelBias timeScale doneAction = mkUGen Nothing [KR,AR] (Left rate) "DemandEnvGen" [level,dur,shape,curve,gate_,reset,levelScale,levelBias,timeScale,(from_done_action doneAction)] Nothing 1 (Special 0) NoId
 
 -- | Search a buffer for a value
+--
+--  DetectIndex [KR,AR] bufnum=0.0 in=0.0;    FILTER: TRUE
 detectIndex :: UGen -> UGen -> UGen
 detectIndex bufnum in_ = mkUGen Nothing [KR,AR] (Right [1]) "DetectIndex" [bufnum,in_] Nothing 1 (Special 0) NoId
 
 -- | When input falls below a threshhold, evaluate doneAction.
+--
+--  DetectSilence [KR,AR] in=0.0 amp=1.0e-4 time=0.1 doneAction=0.0;    FILTER: TRUE, ENUMERATION INPUTS: 3=DoneAction
 detectSilence :: UGen -> UGen -> UGen -> DoneAction -> UGen
 detectSilence in_ amp time doneAction = mkUGen Nothing [KR,AR] (Right [0]) "DetectSilence" [in_,amp,time,(from_done_action doneAction)] Nothing 1 (Special 0) NoId
 
 -- | Demand rate geometric series UGen.
+--
+--  Dgeom [DR] length=1.0e8 start=1.0 grow=2.0;    REORDERS INPUTS: [1,2,0], DEMAND/NONDET
 dgeom :: ID a => a -> UGen -> UGen -> UGen -> UGen
 dgeom z length_ start grow = mkUGen Nothing [DR] (Left DR) "Dgeom" [length_,start,grow] Nothing 1 (Special 0) (toUId z)
 
 -- | Demand rate brownian movement generator.
+--
+--  Dibrown [DR] length=1.0e8 lo=0.0 hi=1.0 step=1.0e-2;    REORDERS INPUTS: [1,2,3,0], DEMAND/NONDET
 dibrown :: ID a => a -> UGen -> UGen -> UGen -> UGen -> UGen
 dibrown z length_ lo hi step = mkUGen Nothing [DR] (Left DR) "Dibrown" [length_,lo,hi,step] Nothing 1 (Special 0) (toUId z)
 
 -- | Stream in audio from a file.
+--
+--  DiskIn [AR] bufnum=0.0 loop=0.0;    NC INPUT: True, ENUMERATION INPUTS: 1=Loop
 diskIn :: Int -> UGen -> Loop -> UGen
 diskIn numChannels bufnum loop = mkUGen Nothing [AR] (Left AR) "DiskIn" [bufnum,(from_loop loop)] Nothing numChannels (Special 0) NoId
 
 -- | Record to a soundfile to disk.
+--
+--  DiskOut [AR] bufnum=0.0 *channelsArray=0.0;    MCE
 diskOut :: UGen -> UGen -> UGen
 diskOut bufnum input = mkUGen Nothing [AR] (Left AR) "DiskOut" [bufnum] (Just input) 1 (Special 0) NoId
 
 -- | Demand rate white noise random generator.
+--
+--  Diwhite [DR] length=1.0e8 lo=0.0 hi=1.0;    REORDERS INPUTS: [1,2,0], DEMAND/NONDET
 diwhite :: ID a => a -> UGen -> UGen -> UGen -> UGen
 diwhite z length_ lo hi = mkUGen Nothing [DR] (Left DR) "Diwhite" [length_,lo,hi] Nothing 1 (Special 0) (toUId z)
 
 -- | (Undocumented class)
+--
+--  Donce [DR] in=0.0;    DEMAND/NONDET
 donce :: ID a => a -> UGen -> UGen
 donce z in_ = mkUGen Nothing [DR] (Left DR) "Donce" [in_] Nothing 1 (Special 0) (toUId z)
 
 -- | Monitors another UGen to see when it is finished
-done :: Rate -> UGen -> UGen
-done rate src = mkUGen Nothing [KR] (Left rate) "Done" [src] Nothing 1 (Special 0) NoId
+--
+--  Done [KR] src=0.0
+done :: UGen -> UGen
+done src = mkUGen Nothing [KR] (Left KR) "Done" [src] Nothing 1 (Special 0) NoId
 
 -- | Print the current output value of a demand rate UGen
+--
+--  Dpoll [DR] in=0.0 label=0.0 run=1.0 trigid=-1.0;    DEMAND/NONDET
 dpoll :: ID a => a -> UGen -> UGen -> UGen -> UGen -> UGen
 dpoll z in_ label_ run trigid = mkUGen Nothing [DR] (Left DR) "Dpoll" [in_,label_,run,trigid] Nothing 1 (Special 0) (toUId z)
 
 -- | Demand rate random sequence generator.
+--
+--  Drand [DR] repeats=1.0 *list=0.0;    MCE, REORDERS INPUTS: [1,0], DEMAND/NONDET
 drand :: ID a => a -> UGen -> UGen -> UGen
 drand z repeats list_ = mkUGen Nothing [DR] (Left DR) "Drand" [repeats] (Just list_) 1 (Special 0) (toUId z)
 
 -- | demand rate reset
+--
+--  Dreset [DR] in=0.0 reset=0.0;    DEMAND/NONDET
 dreset :: ID a => a -> UGen -> UGen -> UGen
 dreset z in_ reset = mkUGen Nothing [DR] (Left DR) "Dreset" [in_,reset] Nothing 1 (Special 0) (toUId z)
 
 -- | Demand rate sequence generator.
+--
+--  Dseq [DR] repeats=1.0 *list=0.0;    MCE, REORDERS INPUTS: [1,0], DEMAND/NONDET
 dseq :: ID a => a -> UGen -> UGen -> UGen
 dseq z repeats list_ = mkUGen Nothing [DR] (Left DR) "Dseq" [repeats] (Just list_) 1 (Special 0) (toUId z)
 
 -- | Demand rate sequence generator.
+--
+--  Dser [DR] repeats=1.0 *list=0.0;    MCE, REORDERS INPUTS: [1,0], DEMAND/NONDET
 dser :: ID a => a -> UGen -> UGen -> UGen
 dser z repeats list_ = mkUGen Nothing [DR] (Left DR) "Dser" [repeats] (Just list_) 1 (Special 0) (toUId z)
 
 -- | Demand rate arithmetic series UGen.
+--
+--  Dseries [DR] length=1.0e8 start=1.0 step=1.0;    REORDERS INPUTS: [1,2,0], DEMAND/NONDET
 dseries :: ID a => a -> UGen -> UGen -> UGen -> UGen
 dseries z length_ start step = mkUGen Nothing [DR] (Left DR) "Dseries" [length_,start,step] Nothing 1 (Special 0) (toUId z)
 
 -- | Demand rate random sequence generator
+--
+--  Dshuf [DR] repeats=1.0 *list=0.0;    MCE, REORDERS INPUTS: [1,0], DEMAND/NONDET
 dshuf :: ID a => a -> UGen -> UGen -> UGen
 dshuf z repeats list_ = mkUGen Nothing [DR] (Left DR) "Dshuf" [repeats] (Just list_) 1 (Special 0) (toUId z)
 
 -- | Demand rate input replicator
+--
+--  Dstutter [DR] n=0.0 in=0.0;    DEMAND/NONDET
 dstutter :: ID a => a -> UGen -> UGen -> UGen
 dstutter z n in_ = mkUGen Nothing [DR] (Left DR) "Dstutter" [n,in_] Nothing 1 (Special 0) (toUId z)
 
 -- | Demand rate generator for embedding different inputs
+--
+--  Dswitch [DR] index=0.0 *list=0.0;    MCE, REORDERS INPUTS: [1,0], DEMAND/NONDET
 dswitch :: ID a => a -> UGen -> UGen -> UGen
 dswitch z index_ list_ = mkUGen Nothing [DR] (Left DR) "Dswitch" [index_] (Just list_) 1 (Special 0) (toUId z)
 
 -- | Demand rate generator for switching between inputs.
+--
+--  Dswitch1 [DR] index=0.0 *list=0.0;    MCE, REORDERS INPUTS: [1,0], DEMAND/NONDET
 dswitch1 :: ID a => a -> UGen -> UGen -> UGen
 dswitch1 z index_ list_ = mkUGen Nothing [DR] (Left DR) "Dswitch1" [index_] (Just list_) 1 (Special 0) (toUId z)
 
 -- | Return the same unique series of values for several demand streams
+--
+--  Dunique [DR] source=0.0 maxBufferSize=1024.0 protected=1.0;    DEMAND/NONDET
 dunique :: ID a => a -> UGen -> UGen -> UGen -> UGen
 dunique z source maxBufferSize protected = mkUGen Nothing [DR] (Left DR) "Dunique" [source,maxBufferSize,protected] Nothing 1 (Special 0) (toUId z)
 
 -- | Random impulses.
+--
+--  Dust [KR,AR] density=0.0;    NONDET
 dust :: ID a => a -> Rate -> UGen -> UGen
 dust z rate density = mkUGen Nothing [KR,AR] (Left rate) "Dust" [density] Nothing 1 (Special 0) (toUId z)
 
 -- | Random impulses.
+--
+--  Dust2 [KR,AR] density=0.0;    NONDET
 dust2 :: ID a => a -> Rate -> UGen -> UGen
 dust2 z rate density = mkUGen Nothing [KR,AR] (Left rate) "Dust2" [density] Nothing 1 (Special 0) (toUId z)
 
 -- | Demand results from demand rate UGens.
+--
+--  Duty [KR,AR] dur=1.0 reset=0.0 doneAction=0.0 level=1.0;    REORDERS INPUTS: [0,1,3,2], ENUMERATION INPUTS: 2=DoneAction
 duty :: Rate -> UGen -> UGen -> DoneAction -> UGen -> UGen
 duty rate dur reset doneAction level = mkUGen Nothing [KR,AR] (Left rate) "Duty" [dur,reset,(from_done_action doneAction),level] Nothing 1 (Special 0) NoId
 
 -- | Demand rate white noise random generator.
+--
+--  Dwhite [DR] length=1.0e8 lo=0.0 hi=1.0;    REORDERS INPUTS: [1,2,0], DEMAND/NONDET
 dwhite :: ID a => a -> UGen -> UGen -> UGen -> UGen
 dwhite z length_ lo hi = mkUGen Nothing [DR] (Left DR) "Dwhite" [length_,lo,hi] Nothing 1 (Special 0) (toUId z)
 
--- | Demand rate weighted random sequence generator
--- dwrand :: ID a => a -> UGen -> UGen -> UGen -> UGen
--- dwrand z repeats weights list_ = mkUGen Nothing [DR] (Left DR) "Dwrand" [repeats,weights] (Just list_) 1 (Special 0) (toUId z)
-
 -- | Demand rate random sequence generator.
+--
+--  Dxrand [DR] repeats=1.0 *list=0.0;    MCE, REORDERS INPUTS: [1,0], DEMAND/NONDET
 dxrand :: ID a => a -> UGen -> UGen -> UGen
 dxrand z repeats list_ = mkUGen Nothing [DR] (Left DR) "Dxrand" [repeats] (Just list_) 1 (Special 0) (toUId z)
 
 -- | Envelope generator
+--
+--  EnvGen [KR,AR] gate=1.0 levelScale=1.0 levelBias=0.0 timeScale=1.0 doneAction=0.0 *envelope=0.0;    MCE, REORDERS INPUTS: [5,0,1,2,3,4,5], ENUMERATION INPUTS: 4=DoneAction, 5=Envelope UGen
 envGen :: Rate -> UGen -> UGen -> UGen -> UGen -> DoneAction -> Envelope UGen -> UGen
 envGen rate gate_ levelScale levelBias timeScale doneAction envelope_ = mkUGen Nothing [KR,AR] (Left rate) "EnvGen" [gate_,levelScale,levelBias,timeScale,(from_done_action doneAction)] (Just (envelope_to_ugen envelope_)) 1 (Special 0) NoId
 
 -- | Exponential single random number generator.
+--
+--  ExpRand [IR] lo=1.0e-2 hi=1.0;    FILTER: TRUE, NONDET
 expRand :: ID a => a -> UGen -> UGen -> UGen
-expRand z lo hi = mkUGen Nothing [IR] (Right [0,1]) "ExpRand" [lo,hi] Nothing 1 (Special 0) (toUId z)
+expRand z lo hi = mkUGen Nothing [IR] (Left IR) "ExpRand" [lo,hi] Nothing 1 (Special 0) (toUId z)
 
 -- | Feedback sine with chaotic phase indexing
-fBSineC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-fBSineC rate freq im fb a c xi yi = mkUGen Nothing [AR] (Left rate) "FBSineC" [freq,im,fb,a,c,xi,yi] Nothing 1 (Special 0) NoId
+--
+--  FBSineC [AR] freq=22050.0 im=1.0 fb=0.1 a=1.1 c=0.5 xi=0.1 yi=0.1
+fbSineC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fbSineC rate freq im fb a c xi yi = mkUGen Nothing [AR] (Left rate) "FBSineC" [freq,im,fb,a,c,xi,yi] Nothing 1 (Special 0) NoId
 
 -- | Feedback sine with chaotic phase indexing
-fBSineL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-fBSineL rate freq im fb a c xi yi = mkUGen Nothing [AR] (Left rate) "FBSineL" [freq,im,fb,a,c,xi,yi] Nothing 1 (Special 0) NoId
+--
+--  FBSineL [AR] freq=22050.0 im=1.0 fb=0.1 a=1.1 c=0.5 xi=0.1 yi=0.1
+fbSineL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fbSineL rate freq im fb a c xi yi = mkUGen Nothing [AR] (Left rate) "FBSineL" [freq,im,fb,a,c,xi,yi] Nothing 1 (Special 0) NoId
 
 -- | Feedback sine with chaotic phase indexing
-fBSineN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-fBSineN rate freq im fb a c xi yi = mkUGen Nothing [AR] (Left rate) "FBSineN" [freq,im,fb,a,c,xi,yi] Nothing 1 (Special 0) NoId
+--
+--  FBSineN [AR] freq=22050.0 im=1.0 fb=0.1 a=1.1 c=0.5 xi=0.1 yi=0.1
+fbSineN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fbSineN rate freq im fb a c xi yi = mkUGen Nothing [AR] (Left rate) "FBSineN" [freq,im,fb,a,c,xi,yi] Nothing 1 (Special 0) NoId
 
 -- | Fast Fourier Transform
+--
+--  FFT [KR] buffer=0.0 in=0.0 hop=0.5 wintype=0.0 active=1.0 winsize=0.0
 fft :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 fft buffer in_ hop wintype active winsize = mkUGen Nothing [KR] (Left KR) "FFT" [buffer,in_,hop,wintype,active,winsize] Nothing 1 (Special 0) NoId
 
 -- | First order filter section.
+--
+--  FOS [KR,AR] in=0.0 a0=0.0 a1=0.0 b1=0.0;    FILTER: TRUE
 fos :: UGen -> UGen -> UGen -> UGen -> UGen
 fos in_ a0 a1 b1 = mkUGen Nothing [KR,AR] (Right [0]) "FOS" [in_,a0,a1,b1] Nothing 1 (Special 0) NoId
 
 -- | Fast sine oscillator.
+--
+--  FSinOsc [KR,AR] freq=440.0 iphase=0.0
 fSinOsc :: Rate -> UGen -> UGen -> UGen
 fSinOsc rate freq iphase = mkUGen Nothing [KR,AR] (Left rate) "FSinOsc" [freq,iphase] Nothing 1 (Special 0) NoId
 
 -- | Fold a signal outside given thresholds.
+--
+--  Fold [IR,KR,AR] in=0.0 lo=0.0 hi=1.0;    FILTER: TRUE
 fold :: UGen -> UGen -> UGen -> UGen
 fold in_ lo hi = mkUGen Nothing [IR,KR,AR] (Right [0]) "Fold" [in_,lo,hi] Nothing 1 (Special 0) NoId
 
 -- | Formant oscillator
+--
+--  Formant [AR] fundfreq=440.0 formfreq=1760.0 bwfreq=880.0
 formant :: Rate -> UGen -> UGen -> UGen -> UGen
 formant rate fundfreq formfreq bwfreq = mkUGen Nothing [AR] (Left rate) "Formant" [fundfreq,formfreq,bwfreq] Nothing 1 (Special 0) NoId
 
 -- | FOF-like filter.
+--
+--  Formlet [KR,AR] in=0.0 freq=440.0 attacktime=1.0 decaytime=1.0;    FILTER: TRUE
 formlet :: UGen -> UGen -> UGen -> UGen -> UGen
 formlet in_ freq attacktime decaytime = mkUGen Nothing [KR,AR] (Right [0]) "Formlet" [in_,freq,attacktime,decaytime] Nothing 1 (Special 0) NoId
 
 -- | When triggered, frees a node.
+--
+--  Free [KR] trig=0.0 id=0.0;    FILTER: TRUE
 free :: UGen -> UGen -> UGen
 free trig_ id_ = mkUGen Nothing [KR] (Right [0]) "Free" [trig_,id_] Nothing 1 (Special 0) NoId
 
 -- | When triggered, free enclosing synth.
+--
+--  FreeSelf [KR] in=0.0
 freeSelf :: UGen -> UGen
 freeSelf in_ = mkUGen Nothing [KR] (Left KR) "FreeSelf" [in_] Nothing 1 (Special 0) NoId
 
 -- | Free the enclosing synth when a UGen is finished
-freeSelfWhenDone :: Rate -> UGen -> UGen
-freeSelfWhenDone rate src = mkUGen Nothing [KR] (Left rate) "FreeSelfWhenDone" [src] Nothing 1 (Special 0) NoId
+--
+--  FreeSelfWhenDone [KR] src=0.0
+freeSelfWhenDone :: UGen -> UGen
+freeSelfWhenDone src = mkUGen Nothing [KR] (Left KR) "FreeSelfWhenDone" [src] Nothing 1 (Special 0) NoId
 
 -- | A reverb
+--
+--  FreeVerb [AR] in=0.0 mix=0.33 room=0.5 damp=0.5;    FILTER: TRUE
 freeVerb :: UGen -> UGen -> UGen -> UGen -> UGen
 freeVerb in_ mix room damp = mkUGen Nothing [AR] (Right [0]) "FreeVerb" [in_,mix,room,damp] Nothing 1 (Special 0) NoId
 
 -- | A two-channel reverb
+--
+--  FreeVerb2 [AR] in=0.0 in2=0.0 mix=0.33 room=0.5 damp=0.5;    FILTER: TRUE
 freeVerb2 :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 freeVerb2 in_ in2 mix room damp = mkUGen Nothing [AR] (Right [0]) "FreeVerb2" [in_,in2,mix,room,damp] Nothing 2 (Special 0) NoId
 
 -- | Frequency Shifter.
+--
+--  FreqShift [AR] in=0.0 freq=0.0 phase=0.0
 freqShift :: UGen -> UGen -> UGen -> UGen
 freqShift in_ freq phase = mkUGen Nothing [AR] (Left AR) "FreqShift" [in_,freq,phase] Nothing 1 (Special 0) NoId
 
 -- | A two-channel reverb
+--
+--  GVerb [AR] in=0.0 roomsize=10.0 revtime=3.0 damping=0.5 inputbw=0.5 spread=15.0 drylevel=1.0 earlyreflevel=0.7 taillevel=0.5 maxroomsize=300.0;    FILTER: TRUE
 gVerb :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 gVerb in_ roomsize revtime damping inputbw spread drylevel earlyreflevel taillevel maxroomsize = mkUGen Nothing [AR] (Right [0]) "GVerb" [in_,roomsize,revtime,damping,inputbw,spread,drylevel,earlyreflevel,taillevel,maxroomsize] Nothing 2 (Special 0) NoId
 
 -- | Gate or hold.
+--
+--  Gate [KR,AR] in=0.0 trig=0.0;    FILTER: TRUE
 gate :: UGen -> UGen -> UGen
 gate in_ trig_ = mkUGen Nothing [KR,AR] (Right [0]) "Gate" [in_,trig_] Nothing 1 (Special 0) NoId
 
 -- | Gingerbreadman map chaotic generator
+--
+--  GbmanL [AR] freq=22050.0 xi=1.2 yi=2.1
 gbmanL :: Rate -> UGen -> UGen -> UGen -> UGen
 gbmanL rate freq xi yi = mkUGen Nothing [AR] (Left rate) "GbmanL" [freq,xi,yi] Nothing 1 (Special 0) NoId
 
 -- | Gingerbreadman map chaotic generator
+--
+--  GbmanN [AR] freq=22050.0 xi=1.2 yi=2.1
 gbmanN :: Rate -> UGen -> UGen -> UGen -> UGen
 gbmanN rate freq xi yi = mkUGen Nothing [AR] (Left rate) "GbmanN" [freq,xi,yi] Nothing 1 (Special 0) NoId
 
 -- | Dynamic stochastic synthesis generator.
+--
+--  Gendy1 [KR,AR] ampdist=1.0 durdist=1.0 adparam=1.0 ddparam=1.0 minfreq=440.0 maxfreq=660.0 ampscale=0.5 durscale=0.5 initCPs=12.0 knum=0.0;    NONDET
 gendy1 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 gendy1 z rate ampdist durdist adparam ddparam minfreq maxfreq ampscale durscale initCPs knum = mkUGen Nothing [KR,AR] (Left rate) "Gendy1" [ampdist,durdist,adparam,ddparam,minfreq,maxfreq,ampscale,durscale,initCPs,knum] Nothing 1 (Special 0) (toUId z)
 
 -- | Dynamic stochastic synthesis generator.
+--
+--  Gendy2 [KR,AR] ampdist=1.0 durdist=1.0 adparam=1.0 ddparam=1.0 minfreq=440.0 maxfreq=660.0 ampscale=0.5 durscale=0.5 initCPs=12.0 knum=0.0 a=1.17 c=0.31;    NONDET
 gendy2 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 gendy2 z rate ampdist durdist adparam ddparam minfreq maxfreq ampscale durscale initCPs knum a c = mkUGen Nothing [KR,AR] (Left rate) "Gendy2" [ampdist,durdist,adparam,ddparam,minfreq,maxfreq,ampscale,durscale,initCPs,knum,a,c] Nothing 1 (Special 0) (toUId z)
 
 -- | Dynamic stochastic synthesis generator.
+--
+--  Gendy3 [KR,AR] ampdist=1.0 durdist=1.0 adparam=1.0 ddparam=1.0 freq=440.0 ampscale=0.5 durscale=0.5 initCPs=12.0 knum=0.0;    NONDET
 gendy3 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 gendy3 z rate ampdist durdist adparam ddparam freq ampscale durscale initCPs knum = mkUGen Nothing [KR,AR] (Left rate) "Gendy3" [ampdist,durdist,adparam,ddparam,freq,ampscale,durscale,initCPs,knum] Nothing 1 (Special 0) (toUId z)
 
 -- | Granular synthesis with sound stored in a buffer
+--
+--  GrainBuf [AR] trigger=0.0 dur=1.0 sndbuf=0.0 rate=1.0 pos=0.0 interp=2.0 pan=0.0 envbufnum=-1.0 maxGrains=512.0;    NC INPUT: True
 grainBuf :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 grainBuf numChannels trigger dur sndbuf rate_ pos interp pan envbufnum maxGrains = mkUGen Nothing [AR] (Left AR) "GrainBuf" [trigger,dur,sndbuf,rate_,pos,interp,pan,envbufnum,maxGrains] Nothing numChannels (Special 0) NoId
 
 -- | Granular synthesis with frequency modulated sine tones
+--
+--  GrainFM [AR] trigger=0.0 dur=1.0 carfreq=440.0 modfreq=200.0 index=1.0 pan=0.0 envbufnum=-1.0 maxGrains=512.0;    NC INPUT: True
 grainFM :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 grainFM numChannels trigger dur carfreq modfreq index_ pan envbufnum maxGrains = mkUGen Nothing [AR] (Left AR) "GrainFM" [trigger,dur,carfreq,modfreq,index_,pan,envbufnum,maxGrains] Nothing numChannels (Special 0) NoId
 
 -- | Granulate an input signal
+--
+--  GrainIn [AR] trigger=0.0 dur=1.0 in=0.0 pan=0.0 envbufnum=-1.0 maxGrains=512.0;    NC INPUT: True
 grainIn :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 grainIn numChannels trigger dur in_ pan envbufnum maxGrains = mkUGen Nothing [AR] (Left AR) "GrainIn" [trigger,dur,in_,pan,envbufnum,maxGrains] Nothing numChannels (Special 0) NoId
 
 -- | Granular synthesis with sine tones
+--
+--  GrainSin [AR] trigger=0.0 dur=1.0 freq=440.0 pan=0.0 envbufnum=-1.0 maxGrains=512.0;    NC INPUT: True
 grainSin :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 grainSin numChannels trigger dur freq pan envbufnum maxGrains = mkUGen Nothing [AR] (Left AR) "GrainSin" [trigger,dur,freq,pan,envbufnum,maxGrains] Nothing numChannels (Special 0) NoId
 
 -- | Gray Noise.
+--
+--  GrayNoise [KR,AR] ;    NONDET
 grayNoise :: ID a => a -> Rate -> UGen
 grayNoise z rate = mkUGen Nothing [KR,AR] (Left rate) "GrayNoise" [] Nothing 1 (Special 0) (toUId z)
 
 -- | 2nd order Butterworth highpass filter.
+--
+--  HPF [KR,AR] in=0.0 freq=440.0;    FILTER: TRUE
 hpf :: UGen -> UGen -> UGen
 hpf in_ freq = mkUGen Nothing [KR,AR] (Right [0]) "HPF" [in_,freq] Nothing 1 (Special 0) NoId
 
 -- | Two point difference filter
+--
+--  HPZ1 [KR,AR] in=0.0;    FILTER: TRUE
 hpz1 :: UGen -> UGen
 hpz1 in_ = mkUGen Nothing [KR,AR] (Right [0]) "HPZ1" [in_] Nothing 1 (Special 0) NoId
 
 -- | Two zero fixed midcut.
+--
+--  HPZ2 [KR,AR] in=0.0;    FILTER: TRUE
 hPZ2 :: UGen -> UGen
 hPZ2 in_ = mkUGen Nothing [KR,AR] (Right [0]) "HPZ2" [in_] Nothing 1 (Special 0) NoId
 
 -- | Randomized value.
+--
+--  Hasher [KR,AR] in=0.0;    FILTER: TRUE
 hasher :: UGen -> UGen
 hasher in_ = mkUGen Nothing [KR,AR] (Right [0]) "Hasher" [in_] Nothing 1 (Special 0) NoId
 
 -- | Henon map chaotic generator
+--
+--  HenonC [AR] freq=22050.0 a=1.4 b=0.3 x0=0.0 x1=0.0
 henonC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 henonC rate freq a b x0 x1 = mkUGen Nothing [AR] (Left rate) "HenonC" [freq,a,b,x0,x1] Nothing 1 (Special 0) NoId
 
 -- | Henon map chaotic generator
+--
+--  HenonL [AR] freq=22050.0 a=1.4 b=0.3 x0=0.0 x1=0.0
 henonL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 henonL rate freq a b x0 x1 = mkUGen Nothing [AR] (Left rate) "HenonL" [freq,a,b,x0,x1] Nothing 1 (Special 0) NoId
 
 -- | Henon map chaotic generator
+--
+--  HenonN [AR] freq=22050.0 a=1.4 b=0.3 x0=0.0 x1=0.0
 henonN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 henonN rate freq a b x0 x1 = mkUGen Nothing [AR] (Left rate) "HenonN" [freq,a,b,x0,x1] Nothing 1 (Special 0) NoId
 
 -- | Applies the Hilbert transform to an input signal.
+--
+--  Hilbert [AR] in=0.0;    FILTER: TRUE
 hilbert :: UGen -> UGen
 hilbert in_ = mkUGen Nothing [AR] (Right [0]) "Hilbert" [in_] Nothing 2 (Special 0) NoId
 
 -- | Applies the Hilbert transform to an input signal.
+--
+--  HilbertFIR [AR] in=0.0 buffer=0.0
 hilbertFIR :: Rate -> UGen -> UGen -> UGen
 hilbertFIR rate in_ buffer = mkUGen Nothing [AR] (Left rate) "HilbertFIR" [in_,buffer] Nothing 2 (Special 0) NoId
 
 -- | Envelope generator for polling values from an Env
+--
+--  IEnvGen [KR,AR] index=0.0 *envelope=0.0;    MCE, REORDERS INPUTS: [1,0], ENUMERATION INPUTS: 1=Envelope UGen
 iEnvGen :: Rate -> UGen -> Envelope UGen -> UGen
 iEnvGen rate index_ envelope_ = mkUGen Nothing [KR,AR] (Left rate) "IEnvGen" [index_] (Just (envelope_to_ugen envelope_)) 1 (Special 0) NoId
 
 -- | Inverse Fast Fourier Transform
+--
+--  IFFT [KR,AR] buffer=0.0 wintype=0.0 winsize=0.0
 ifft :: UGen -> UGen -> UGen -> UGen
 ifft buffer wintype winsize = mkUGen Nothing [KR,AR] (Left AR) "IFFT" [buffer,wintype,winsize] Nothing 1 (Special 0) NoId
 
 -- | Single integer random number generator.
+--
+--  IRand [IR] lo=0.0 hi=127.0;    NONDET
 iRand :: ID a => a -> UGen -> UGen -> UGen
 iRand z lo hi = mkUGen Nothing [IR] (Left IR) "IRand" [lo,hi] Nothing 1 (Special 0) (toUId z)
 
 -- | Impulse oscillator.
+--
+--  Impulse [KR,AR] freq=440.0 phase=0.0
 impulse :: Rate -> UGen -> UGen -> UGen
 impulse rate freq phase = mkUGen Nothing [KR,AR] (Left rate) "Impulse" [freq,phase] Nothing 1 (Special 0) NoId
 
 -- | Read a signal from a bus.
+--
+--  In [KR,AR] bus=0.0;    NC INPUT: True
 in' :: Int -> Rate -> UGen -> UGen
 in' numChannels rate bus = mkUGen Nothing [KR,AR] (Left rate) "In" [bus] Nothing numChannels (Special 0) NoId
 
 -- | Read signal from a bus with a current or one cycle old timestamp.
+--
+--  InFeedback [AR] bus=0.0;    NC INPUT: True
 inFeedback :: Int -> UGen -> UGen
 inFeedback numChannels bus = mkUGen Nothing [AR] (Left AR) "InFeedback" [bus] Nothing numChannels (Special 0) NoId
 
 -- | Tests if a signal is within a given range.
+--
+--  InRange [IR,KR,AR] in=0.0 lo=0.0 hi=1.0;    FILTER: TRUE
 inRange :: UGen -> UGen -> UGen -> UGen
 inRange in_ lo hi = mkUGen Nothing [IR,KR,AR] (Right [0]) "InRange" [in_,lo,hi] Nothing 1 (Special 0) NoId
 
 -- | Test if a point is within a given rectangle.
+--
+--  InRect [KR,AR] x=0.0 y=0.0 rect=0.0
 inRect :: Rate -> UGen -> UGen -> UGen -> UGen
 inRect rate x y rect = mkUGen Nothing [KR,AR] (Left rate) "InRect" [x,y,rect] Nothing 1 (Special 0) NoId
 
 -- | Generate a trigger anytime a bus is set.
-inTrig :: Int -> Rate -> UGen -> UGen
-inTrig numChannels rate bus = mkUGen Nothing [KR] (Left rate) "InTrig" [bus] Nothing numChannels (Special 0) NoId
+--
+--  InTrig [KR] bus=0.0;    NC INPUT: True
+inTrig :: Int -> UGen -> UGen
+inTrig numChannels bus = mkUGen Nothing [KR] (Left KR) "InTrig" [bus] Nothing numChannels (Special 0) NoId
 
 -- | Index into a table with a signal
+--
+--  Index [KR,AR] bufnum=0.0 in=0.0;    FILTER: TRUE
 index :: UGen -> UGen -> UGen
 index bufnum in_ = mkUGen Nothing [KR,AR] (Right [1]) "Index" [bufnum,in_] Nothing 1 (Special 0) NoId
 
 -- | Finds the (lowest) point in the Buffer at which the input signal lies in-between the two values
-indexInBetween :: Rate -> UGen -> UGen -> UGen
-indexInBetween rate bufnum in_ = mkUGen Nothing [KR,AR] (Left rate) "IndexInBetween" [bufnum,in_] Nothing 1 (Special 0) NoId
+--
+--  IndexInBetween [KR,AR] bufnum=0.0 in=0.0;    FILTER: TRUE
+indexInBetween :: UGen -> UGen -> UGen
+indexInBetween bufnum in_ = mkUGen Nothing [KR,AR] (Right [1]) "IndexInBetween" [bufnum,in_] Nothing 1 (Special 0) NoId
 
 -- | Index into a table with a signal, linear interpolated
+--
+--  IndexL [KR,AR] bufnum=0.0 in=0.0
 indexL :: Rate -> UGen -> UGen -> UGen
 indexL rate bufnum in_ = mkUGen Nothing [KR,AR] (Left rate) "IndexL" [bufnum,in_] Nothing 1 (Special 0) NoId
 
 -- | Base class for info ugens
+--
+--  InfoUGenBase [IR]
 infoUGenBase :: Rate -> UGen
 infoUGenBase rate = mkUGen Nothing [IR] (Left rate) "InfoUGenBase" [] Nothing 1 (Special 0) NoId
 
 -- | A leaky integrator.
+--
+--  Integrator [KR,AR] in=0.0 coef=1.0;    FILTER: TRUE
 integrator :: UGen -> UGen -> UGen
 integrator in_ coef = mkUGen Nothing [KR,AR] (Right [0]) "Integrator" [in_,coef] Nothing 1 (Special 0) NoId
 
 -- | Control to audio rate converter.
+--
+--  K2A [AR] in=0.0
 k2A :: UGen -> UGen
 k2A in_ = mkUGen Nothing [AR] (Left AR) "K2A" [in_] Nothing 1 (Special 0) NoId
 
 -- | Respond to the state of a key
+--
+--  KeyState [KR] keycode=0.0 minval=0.0 maxval=1.0 lag=0.2
 keyState :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 keyState rate keycode minval maxval lag_ = mkUGen Nothing [KR] (Left rate) "KeyState" [keycode,minval,maxval,lag_] Nothing 1 (Special 0) NoId
 
 -- | Key tracker
+--
+--  KeyTrack [KR] chain=0.0 keydecay=2.0 chromaleak=0.5
 keyTrack :: Rate -> UGen -> UGen -> UGen -> UGen
 keyTrack rate chain keydecay chromaleak = mkUGen Nothing [KR] (Left rate) "KeyTrack" [chain,keydecay,chromaleak] Nothing 1 (Special 0) NoId
 
 -- | Sine oscillator bank
+--
+--  Klang [AR] freqscale=1.0 freqoffset=0.0 *specificationsArrayRef=0.0;    MCE, REORDERS INPUTS: [2,0,1]
 klang :: Rate -> UGen -> UGen -> UGen -> UGen
 klang rate freqscale freqoffset specificationsArrayRef = mkUGen Nothing [AR] (Left rate) "Klang" [freqscale,freqoffset] (Just specificationsArrayRef) 1 (Special 0) NoId
 
 -- | Bank of resonators
+--
+--  Klank [AR] input=0.0 freqscale=1.0 freqoffset=0.0 decayscale=1.0 *specificationsArrayRef=0.0;    MCE, FILTER: TRUE, REORDERS INPUTS: [4,0,1,2,3]
 klank :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 klank input freqscale freqoffset decayscale specificationsArrayRef = mkUGen Nothing [AR] (Right [0]) "Klank" [input,freqscale,freqoffset,decayscale] (Just specificationsArrayRef) 1 (Special 0) NoId
 
 -- | Clipped noise
+--
+--  LFClipNoise [KR,AR] freq=500.0;    NONDET
 lfClipNoise :: ID a => a -> Rate -> UGen -> UGen
 lfClipNoise z rate freq = mkUGen Nothing [KR,AR] (Left rate) "LFClipNoise" [freq] Nothing 1 (Special 0) (toUId z)
 
 -- | A sine like shape made of two cubic pieces
+--
+--  LFCub [KR,AR] freq=440.0 iphase=0.0
 lfCub :: Rate -> UGen -> UGen -> UGen
 lfCub rate freq iphase = mkUGen Nothing [KR,AR] (Left rate) "LFCub" [freq,iphase] Nothing 1 (Special 0) NoId
 
 -- | Dynamic clipped noise
+--
+--  LFDClipNoise [KR,AR] freq=500.0;    NONDET
 lfdClipNoise :: ID a => a -> Rate -> UGen -> UGen
 lfdClipNoise z rate freq = mkUGen Nothing [KR,AR] (Left rate) "LFDClipNoise" [freq] Nothing 1 (Special 0) (toUId z)
 
 -- | Dynamic step noise
+--
+--  LFDNoise0 [KR,AR] freq=500.0;    NONDET
 lfdNoise0 :: ID a => a -> Rate -> UGen -> UGen
 lfdNoise0 z rate freq = mkUGen Nothing [KR,AR] (Left rate) "LFDNoise0" [freq] Nothing 1 (Special 0) (toUId z)
 
 -- | Dynamic ramp noise
+--
+--  LFDNoise1 [KR,AR] freq=500.0;    NONDET
 lfdNoise1 :: ID a => a -> Rate -> UGen -> UGen
 lfdNoise1 z rate freq = mkUGen Nothing [KR,AR] (Left rate) "LFDNoise1" [freq] Nothing 1 (Special 0) (toUId z)
 
 -- | Dynamic cubic noise
+--
+--  LFDNoise3 [KR,AR] freq=500.0;    NONDET
 lfdNoise3 :: ID a => a -> Rate -> UGen -> UGen
 lfdNoise3 z rate freq = mkUGen Nothing [KR,AR] (Left rate) "LFDNoise3" [freq] Nothing 1 (Special 0) (toUId z)
 
 -- | Gaussian function oscillator
+--
+--  LFGauss [KR,AR] duration=1.0 width=0.1 iphase=0.0 loop=1.0 doneAction=0.0;    ENUMERATION INPUTS: 3=Loop, 4=DoneAction
 lfGauss :: Rate -> UGen -> UGen -> UGen -> Loop -> DoneAction -> UGen
 lfGauss rate duration width iphase loop doneAction = mkUGen Nothing [KR,AR] (Left rate) "LFGauss" [duration,width,iphase,(from_loop loop),(from_done_action doneAction)] Nothing 1 (Special 0) NoId
 
 -- | Step noise
+--
+--  LFNoise0 [KR,AR] freq=500.0;    NONDET
 lfNoise0 :: ID a => a -> Rate -> UGen -> UGen
 lfNoise0 z rate freq = mkUGen Nothing [KR,AR] (Left rate) "LFNoise0" [freq] Nothing 1 (Special 0) (toUId z)
 
 -- | Ramp noise
+--
+--  LFNoise1 [KR,AR] freq=500.0;    NONDET
 lfNoise1 :: ID a => a -> Rate -> UGen -> UGen
 lfNoise1 z rate freq = mkUGen Nothing [KR,AR] (Left rate) "LFNoise1" [freq] Nothing 1 (Special 0) (toUId z)
 
 -- | Quadratic noise.
+--
+--  LFNoise2 [KR,AR] freq=500.0;    NONDET
 lfNoise2 :: ID a => a -> Rate -> UGen -> UGen
 lfNoise2 z rate freq = mkUGen Nothing [KR,AR] (Left rate) "LFNoise2" [freq] Nothing 1 (Special 0) (toUId z)
 
 -- | Parabolic oscillator
+--
+--  LFPar [KR,AR] freq=440.0 iphase=0.0
 lfPar :: Rate -> UGen -> UGen -> UGen
 lfPar rate freq iphase = mkUGen Nothing [KR,AR] (Left rate) "LFPar" [freq,iphase] Nothing 1 (Special 0) NoId
 
 -- | pulse oscillator
+--
+--  LFPulse [KR,AR] freq=440.0 iphase=0.0 width=0.5
 lfPulse :: Rate -> UGen -> UGen -> UGen -> UGen
 lfPulse rate freq iphase width = mkUGen Nothing [KR,AR] (Left rate) "LFPulse" [freq,iphase,width] Nothing 1 (Special 0) NoId
 
 -- | Sawtooth oscillator
+--
+--  LFSaw [KR,AR] freq=440.0 iphase=0.0
 lfSaw :: Rate -> UGen -> UGen -> UGen
 lfSaw rate freq iphase = mkUGen Nothing [KR,AR] (Left rate) "LFSaw" [freq,iphase] Nothing 1 (Special 0) NoId
 
 -- | Triangle oscillator
+--
+--  LFTri [KR,AR] freq=440.0 iphase=0.0
 lfTri :: Rate -> UGen -> UGen -> UGen
 lfTri rate freq iphase = mkUGen Nothing [KR,AR] (Left rate) "LFTri" [freq,iphase] Nothing 1 (Special 0) NoId
 
 -- | 2nd order Butterworth lowpass filter
+--
+--  LPF [KR,AR] in=0.0 freq=440.0;    FILTER: TRUE
 lpf :: UGen -> UGen -> UGen
 lpf in_ freq = mkUGen Nothing [KR,AR] (Right [0]) "LPF" [in_,freq] Nothing 1 (Special 0) NoId
 
 -- | Two point average filter
+--
+--  LPZ1 [KR,AR] in=0.0;    FILTER: TRUE
 lpz1 :: UGen -> UGen
 lpz1 in_ = mkUGen Nothing [KR,AR] (Right [0]) "LPZ1" [in_] Nothing 1 (Special 0) NoId
 
 -- | Two zero fixed lowpass
+--
+--  LPZ2 [KR,AR] in=0.0;    FILTER: TRUE
 lPZ2 :: UGen -> UGen
 lPZ2 in_ = mkUGen Nothing [KR,AR] (Right [0]) "LPZ2" [in_] Nothing 1 (Special 0) NoId
 
 -- | Exponential lag
+--
+--  Lag [KR,AR] in=0.0 lagTime=0.1;    FILTER: TRUE
 lag :: UGen -> UGen -> UGen
 lag in_ lagTime = mkUGen Nothing [KR,AR] (Right [0]) "Lag" [in_,lagTime] Nothing 1 (Special 0) NoId
 
 -- | Exponential lag
+--
+--  Lag2 [KR,AR] in=0.0 lagTime=0.1;    FILTER: TRUE
 lag2 :: UGen -> UGen -> UGen
 lag2 in_ lagTime = mkUGen Nothing [KR,AR] (Right [0]) "Lag2" [in_,lagTime] Nothing 1 (Special 0) NoId
 
 -- | Exponential lag
+--
+--  Lag2UD [KR,AR] in=0.0 lagTimeU=0.1 lagTimeD=0.1;    FILTER: TRUE
 lag2UD :: UGen -> UGen -> UGen -> UGen
 lag2UD in_ lagTimeU lagTimeD = mkUGen Nothing [KR,AR] (Right [0]) "Lag2UD" [in_,lagTimeU,lagTimeD] Nothing 1 (Special 0) NoId
 
 -- | Exponential lag
+--
+--  Lag3 [KR,AR] in=0.0 lagTime=0.1;    FILTER: TRUE
 lag3 :: UGen -> UGen -> UGen
 lag3 in_ lagTime = mkUGen Nothing [KR,AR] (Right [0]) "Lag3" [in_,lagTime] Nothing 1 (Special 0) NoId
 
 -- | Exponential lag
+--
+--  Lag3UD [KR,AR] in=0.0 lagTimeU=0.1 lagTimeD=0.1;    FILTER: TRUE
 lag3UD :: UGen -> UGen -> UGen -> UGen
 lag3UD in_ lagTimeU lagTimeD = mkUGen Nothing [KR,AR] (Right [0]) "Lag3UD" [in_,lagTimeU,lagTimeD] Nothing 1 (Special 0) NoId
 
 -- | Read a control signal from a bus with a lag
+--
+--  LagIn [KR] bus=0.0 lag=0.1;    NC INPUT: True
 lagIn :: Int -> UGen -> UGen -> UGen
 lagIn numChannels bus lag_ = mkUGen Nothing [KR] (Left KR) "LagIn" [bus,lag_] Nothing numChannels (Special 0) NoId
 
 -- | Exponential lag
+--
+--  LagUD [KR,AR] in=0.0 lagTimeU=0.1 lagTimeD=0.1;    FILTER: TRUE
 lagUD :: UGen -> UGen -> UGen -> UGen
 lagUD in_ lagTimeU lagTimeD = mkUGen Nothing [KR,AR] (Right [0]) "LagUD" [in_,lagTimeU,lagTimeD] Nothing 1 (Special 0) NoId
 
 -- | Output the last value before the input changed
+--
+--  LastValue [KR,AR] in=0.0 diff=1.0e-2;    FILTER: TRUE
 lastValue :: UGen -> UGen -> UGen
 lastValue in_ diff = mkUGen Nothing [KR,AR] (Right [0]) "LastValue" [in_,diff] Nothing 1 (Special 0) NoId
 
 -- | Sample and hold
+--
+--  Latch [KR,AR] in=0.0 trig=0.0;    FILTER: TRUE
 latch :: UGen -> UGen -> UGen
 latch in_ trig_ = mkUGen Nothing [KR,AR] (Right [0]) "Latch" [in_,trig_] Nothing 1 (Special 0) NoId
 
 -- | Latoocarfian chaotic generator
+--
+--  LatoocarfianC [AR] freq=22050.0 a=1.0 b=3.0 c=0.5 d=0.5 xi=0.5 yi=0.5
 latoocarfianC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 latoocarfianC rate freq a b c d xi yi = mkUGen Nothing [AR] (Left rate) "LatoocarfianC" [freq,a,b,c,d,xi,yi] Nothing 1 (Special 0) NoId
 
 -- | Latoocarfian chaotic generator
+--
+--  LatoocarfianL [AR] freq=22050.0 a=1.0 b=3.0 c=0.5 d=0.5 xi=0.5 yi=0.5
 latoocarfianL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 latoocarfianL rate freq a b c d xi yi = mkUGen Nothing [AR] (Left rate) "LatoocarfianL" [freq,a,b,c,d,xi,yi] Nothing 1 (Special 0) NoId
 
 -- | Latoocarfian chaotic generator
+--
+--  LatoocarfianN [AR] freq=22050.0 a=1.0 b=3.0 c=0.5 d=0.5 xi=0.5 yi=0.5
 latoocarfianN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 latoocarfianN rate freq a b c d xi yi = mkUGen Nothing [AR] (Left rate) "LatoocarfianN" [freq,a,b,c,d,xi,yi] Nothing 1 (Special 0) NoId
 
 -- | Remove DC
+--
+--  LeakDC [KR,AR] in=0.0 coef=0.995;    FILTER: TRUE
 leakDC :: UGen -> UGen -> UGen
 leakDC in_ coef = mkUGen Nothing [KR,AR] (Right [0]) "LeakDC" [in_,coef] Nothing 1 (Special 0) NoId
 
 -- | Output least changed
+--
+--  LeastChange [KR,AR] a=0.0 b=0.0
 leastChange :: Rate -> UGen -> UGen -> UGen
 leastChange rate a b = mkUGen Nothing [KR,AR] (Left rate) "LeastChange" [a,b] Nothing 1 (Special 0) NoId
 
 -- | Peak limiter
+--
+--  Limiter [AR] in=0.0 level=1.0 dur=1.0e-2;    FILTER: TRUE
 limiter :: UGen -> UGen -> UGen -> UGen
 limiter in_ level dur = mkUGen Nothing [AR] (Right [0]) "Limiter" [in_,level,dur] Nothing 1 (Special 0) NoId
 
 -- | Linear congruential chaotic generator
+--
+--  LinCongC [AR] freq=22050.0 a=1.1 c=0.13 m=1.0 xi=0.0
 linCongC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 linCongC rate freq a c m xi = mkUGen Nothing [AR] (Left rate) "LinCongC" [freq,a,c,m,xi] Nothing 1 (Special 0) NoId
 
 -- | Linear congruential chaotic generator
+--
+--  LinCongL [AR] freq=22050.0 a=1.1 c=0.13 m=1.0 xi=0.0
 linCongL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 linCongL rate freq a c m xi = mkUGen Nothing [AR] (Left rate) "LinCongL" [freq,a,c,m,xi] Nothing 1 (Special 0) NoId
 
 -- | Linear congruential chaotic generator
+--
+--  LinCongN [AR] freq=22050.0 a=1.1 c=0.13 m=1.0 xi=0.0
 linCongN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 linCongN rate freq a c m xi = mkUGen Nothing [AR] (Left rate) "LinCongN" [freq,a,c,m,xi] Nothing 1 (Special 0) NoId
 
 -- | Map a linear range to an exponential range
+--
+--  LinExp [IR,KR,AR] in=0.0 srclo=0.0 srchi=1.0 dstlo=1.0 dsthi=2.0;    FILTER: TRUE
 linExp :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-linExp in_ srclo srchi dstlo dsthi = mkUGen Nothing [KR,AR] (Right [0]) "LinExp" [in_,srclo,srchi,dstlo,dsthi] Nothing 1 (Special 0) NoId
+linExp in_ srclo srchi dstlo dsthi = mkUGen Nothing [IR,KR,AR] (Right [0]) "LinExp" [in_,srclo,srchi,dstlo,dsthi] Nothing 1 (Special 0) NoId
 
 -- | Two channel linear pan.
+--
+--  LinPan2 [KR,AR] in=0.0 pos=0.0 level=1.0;    FILTER: TRUE
 linPan2 :: UGen -> UGen -> UGen -> UGen
 linPan2 in_ pos level = mkUGen Nothing [KR,AR] (Right [0]) "LinPan2" [in_,pos,level] Nothing 2 (Special 0) NoId
 
 -- | Skewed random number generator.
+--
+--  LinRand [IR] lo=0.0 hi=1.0 minmax=0.0;    NONDET
 linRand :: ID a => a -> UGen -> UGen -> UGen -> UGen
 linRand z lo hi minmax = mkUGen Nothing [IR] (Left IR) "LinRand" [lo,hi,minmax] Nothing 1 (Special 0) (toUId z)
 
 -- | Two channel linear crossfade.
+--
+--  LinXFade2 [KR,AR] inA=0.0 inB=0.0 pan=0.0 level=1.0;    FILTER: TRUE, PSUEDO INPUTS: [3]
 linXFade2 :: UGen -> UGen -> UGen -> UGen -> UGen
 linXFade2 inA inB pan level = mkUGen Nothing [KR,AR] (Right [0,1]) "LinXFade2" [inA,inB,pan,level] Nothing 1 (Special 0) NoId
 
 -- | Line generator.
+--
+--  Line [KR,AR] start=0.0 end=1.0 dur=1.0 doneAction=0.0;    ENUMERATION INPUTS: 3=DoneAction
 line :: Rate -> UGen -> UGen -> UGen -> DoneAction -> UGen
 line rate start end dur doneAction = mkUGen Nothing [KR,AR] (Left rate) "Line" [start,end,dur,(from_done_action doneAction)] Nothing 1 (Special 0) NoId
 
 -- | Simple linear envelope generator.
+--
+--  Linen [KR] gate=1.0 attackTime=1.0e-2 susLevel=1.0 releaseTime=1.0 doneAction=0.0;    ENUMERATION INPUTS: 4=DoneAction
 linen :: UGen -> UGen -> UGen -> UGen -> DoneAction -> UGen
 linen gate_ attackTime susLevel releaseTime doneAction = mkUGen Nothing [KR] (Left KR) "Linen" [gate_,attackTime,susLevel,releaseTime,(from_done_action doneAction)] Nothing 1 (Special 0) NoId
 
 -- | Allocate a buffer local to the synth
+--
+--  LocalBuf [IR] numChannels=1.0 numFrames=1.0;    REORDERS INPUTS: [1,0], NONDET
 localBuf :: ID a => a -> UGen -> UGen -> UGen
 localBuf z numChannels numFrames = mkUGen Nothing [IR] (Left IR) "LocalBuf" [numChannels,numFrames] Nothing 1 (Special 0) (toUId z)
 
 -- | Define and read from buses local to a synth.
+--
+--  LocalIn [KR,AR] *default=0.0;    MCE, NC INPUT: True
 localIn :: Int -> Rate -> UGen -> UGen
 localIn numChannels rate default_ = mkUGen Nothing [KR,AR] (Left rate) "LocalIn" [] (Just default_) numChannels (Special 0) NoId
 
 -- | Write to buses local to a synth.
+--
+--  LocalOut [KR,AR] *channelsArray=0.0;    MCE, FILTER: TRUE
 localOut :: UGen -> UGen
 localOut input = mkUGen Nothing [KR,AR] (Right [0]) "LocalOut" [] (Just input) 0 (Special 0) NoId
 
 -- | Chaotic noise function
+--
+--  Logistic [KR,AR] chaosParam=3.0 freq=1000.0 init=0.5
 logistic :: Rate -> UGen -> UGen -> UGen -> UGen
 logistic rate chaosParam freq init_ = mkUGen Nothing [KR,AR] (Left rate) "Logistic" [chaosParam,freq,init_] Nothing 1 (Special 0) NoId
 
 -- | Lorenz chaotic generator
+--
+--  LorenzL [AR] freq=22050.0 s=10.0 r=28.0 b=2.667 h=5.0e-2 xi=0.1 yi=0.0 zi=0.0
 lorenzL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 lorenzL rate freq s r b h xi yi zi = mkUGen Nothing [AR] (Left rate) "LorenzL" [freq,s,r,b,h,xi,yi,zi] Nothing 1 (Special 0) NoId
 
 -- | Extraction of instantaneous loudness in sones
-loudness :: Rate -> UGen -> UGen -> UGen -> UGen
-loudness rate chain smask tmask = mkUGen Nothing [KR] (Left rate) "Loudness" [chain,smask,tmask] Nothing 1 (Special 0) NoId
+--
+--  Loudness [KR] chain=0.0 smask=0.25 tmask=1.0
+loudness :: UGen -> UGen -> UGen -> UGen
+loudness chain smask tmask = mkUGen Nothing [KR] (Left KR) "Loudness" [chain,smask,tmask] Nothing 1 (Special 0) NoId
 
 -- | Mel frequency cepstral coefficients
+--
+--  MFCC [KR] chain=0.0 numcoeff=13.0
 mFCC :: Rate -> UGen -> UGen -> UGen
 mFCC rate chain numcoeff = mkUGen Nothing [KR] (Left rate) "MFCC" [chain,numcoeff] Nothing 13 (Special 0) NoId
 
 -- | Reduce precision.
+--
+--  MantissaMask [KR,AR] in=0.0 bits=3.0;    FILTER: TRUE
 mantissaMask :: UGen -> UGen -> UGen
 mantissaMask in_ bits = mkUGen Nothing [KR,AR] (Right [0]) "MantissaMask" [in_,bits] Nothing 1 (Special 0) NoId
 
 -- | Median filter.
+--
+--  Median [KR,AR] length=3.0 in=0.0;    FILTER: TRUE
 median :: UGen -> UGen -> UGen
 median length_ in_ = mkUGen Nothing [KR,AR] (Right [1]) "Median" [length_,in_] Nothing 1 (Special 0) NoId
 
 -- | Parametric filter.
+--
+--  MidEQ [KR,AR] in=0.0 freq=440.0 rq=1.0 db=0.0;    FILTER: TRUE
 midEQ :: UGen -> UGen -> UGen -> UGen -> UGen
 midEQ in_ freq rq db = mkUGen Nothing [KR,AR] (Right [0]) "MidEQ" [in_,freq,rq,db] Nothing 1 (Special 0) NoId
 
 -- | Minimum difference of two values in modulo arithmetics
+--
+--  ModDif [IR,KR,AR] x=0.0 y=0.0 mod=1.0
 modDif :: Rate -> UGen -> UGen -> UGen -> UGen
 modDif rate x y mod_ = mkUGen Nothing [IR,KR,AR] (Left rate) "ModDif" [x,y,mod_] Nothing 1 (Special 0) NoId
 
 -- | Moog VCF implementation, designed by Federico Fontana
+--
+--  MoogFF [KR,AR] in=0.0 freq=100.0 gain=2.0 reset=0.0;    FILTER: TRUE
 moogFF :: UGen -> UGen -> UGen -> UGen -> UGen
 moogFF in_ freq gain reset = mkUGen Nothing [KR,AR] (Right [0]) "MoogFF" [in_,freq,gain,reset] Nothing 1 (Special 0) NoId
 
 -- | Output most changed.
+--
+--  MostChange [KR,AR] a=0.0 b=0.0;    FILTER: TRUE
 mostChange :: UGen -> UGen -> UGen
 mostChange a b = mkUGen Nothing [KR,AR] (Right [0,1]) "MostChange" [a,b] Nothing 1 (Special 0) NoId
 
 -- | Mouse button UGen.
+--
+--  MouseButton [KR] minval=0.0 maxval=1.0 lag=0.2
 mouseButton :: Rate -> UGen -> UGen -> UGen -> UGen
 mouseButton rate minval maxval lag_ = mkUGen Nothing [KR] (Left rate) "MouseButton" [minval,maxval,lag_] Nothing 1 (Special 0) NoId
 
 -- | Cursor tracking UGen.
+--
+--  MouseX [KR] minval=0.0 maxval=1.0 warp=0.0 lag=0.2;    ENUMERATION INPUTS: 2=Warp
 mouseX :: Rate -> UGen -> UGen -> Warp -> UGen -> UGen
 mouseX rate minval maxval warp lag_ = mkUGen Nothing [KR] (Left rate) "MouseX" [minval,maxval,(from_warp warp),lag_] Nothing 1 (Special 0) NoId
 
 -- | Cursor tracking UGen.
+--
+--  MouseY [KR] minval=0.0 maxval=1.0 warp=0.0 lag=0.2;    ENUMERATION INPUTS: 2=Warp
 mouseY :: Rate -> UGen -> UGen -> Warp -> UGen -> UGen
 mouseY rate minval maxval warp lag_ = mkUGen Nothing [KR] (Left rate) "MouseY" [minval,maxval,(from_warp warp),lag_] Nothing 1 (Special 0) NoId
 
 -- | Sum of uniform distributions.
+--
+--  NRand [IR] lo=0.0 hi=1.0 n=0.0;    NONDET
 nRand :: ID a => a -> UGen -> UGen -> UGen -> UGen
 nRand z lo hi n = mkUGen Nothing [IR] (Left IR) "NRand" [lo,hi,n] Nothing 1 (Special 0) (toUId z)
 
 -- | Flattens dynamics.
+--
+--  Normalizer [AR] in=0.0 level=1.0 dur=1.0e-2;    FILTER: TRUE
 normalizer :: UGen -> UGen -> UGen -> UGen
 normalizer in_ level dur = mkUGen Nothing [AR] (Right [0]) "Normalizer" [in_,level,dur] Nothing 1 (Special 0) NoId
 
 -- | Number of audio busses.
+--
+--  NumAudioBuses [IR]
 numAudioBuses :: UGen
 numAudioBuses = mkUGen Nothing [IR] (Left IR) "NumAudioBuses" [] Nothing 1 (Special 0) NoId
 
 -- | Number of open buffers.
+--
+--  NumBuffers [IR]
 numBuffers :: UGen
 numBuffers = mkUGen Nothing [IR] (Left IR) "NumBuffers" [] Nothing 1 (Special 0) NoId
 
 -- | Number of control busses.
+--
+--  NumControlBuses [IR]
 numControlBuses :: UGen
 numControlBuses = mkUGen Nothing [IR] (Left IR) "NumControlBuses" [] Nothing 1 (Special 0) NoId
 
 -- | Number of input busses.
+--
+--  NumInputBuses [IR]
 numInputBuses :: UGen
 numInputBuses = mkUGen Nothing [IR] (Left IR) "NumInputBuses" [] Nothing 1 (Special 0) NoId
 
 -- | Number of output busses.
+--
+--  NumOutputBuses [IR]
 numOutputBuses :: UGen
 numOutputBuses = mkUGen Nothing [IR] (Left IR) "NumOutputBuses" [] Nothing 1 (Special 0) NoId
 
 -- | Number of currently running synths.
+--
+--  NumRunningSynths [IR,KR]
 numRunningSynths :: UGen
 numRunningSynths = mkUGen Nothing [IR,KR] (Left IR) "NumRunningSynths" [] Nothing 1 (Special 0) NoId
 
 -- | Write a signal to a bus with sample accurate timing.
+--
+--  OffsetOut [KR,AR] bus=0.0 *channelsArray=0.0;    MCE, FILTER: TRUE
 offsetOut :: UGen -> UGen -> UGen
 offsetOut bus input = mkUGen Nothing [KR,AR] (Right [1]) "OffsetOut" [bus] (Just input) 0 (Special 0) NoId
 
 -- | One pole filter.
+--
+--  OnePole [KR,AR] in=0.0 coef=0.5;    FILTER: TRUE
 onePole :: UGen -> UGen -> UGen
 onePole in_ coef = mkUGen Nothing [KR,AR] (Right [0]) "OnePole" [in_,coef] Nothing 1 (Special 0) NoId
 
 -- | One zero filter.
+--
+--  OneZero [KR,AR] in=0.0 coef=0.5;    FILTER: TRUE
 oneZero :: UGen -> UGen -> UGen
 oneZero in_ coef = mkUGen Nothing [KR,AR] (Right [0]) "OneZero" [in_,coef] Nothing 1 (Special 0) NoId
 
 -- | Onset detector
+--
+--  Onsets [KR] chain=0.0 threshold=0.5 odftype=3.0 relaxtime=1.0 floor=0.1 mingap=10.0 medianspan=11.0 whtype=1.0 rawodf=0.0
 onsets :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 onsets chain threshold odftype relaxtime floor_ mingap medianspan whtype rawodf = mkUGen Nothing [KR] (Left KR) "Onsets" [chain,threshold,odftype,relaxtime,floor_,mingap,medianspan,whtype,rawodf] Nothing 1 (Special 0) NoId
 
 -- | Interpolating wavetable oscillator.
+--
+--  Osc [KR,AR] bufnum=0.0 freq=440.0 phase=0.0
 osc :: Rate -> UGen -> UGen -> UGen -> UGen
 osc rate bufnum freq phase = mkUGen Nothing [KR,AR] (Left rate) "Osc" [bufnum,freq,phase] Nothing 1 (Special 0) NoId
 
 -- | Noninterpolating wavetable oscillator.
+--
+--  OscN [KR,AR] bufnum=0.0 freq=440.0 phase=0.0
 oscN :: Rate -> UGen -> UGen -> UGen -> UGen
 oscN rate bufnum freq phase = mkUGen Nothing [KR,AR] (Left rate) "OscN" [bufnum,freq,phase] Nothing 1 (Special 0) NoId
 
 -- | Write a signal to a bus.
+--
+--  Out [KR,AR] bus=0.0 *channelsArray=0.0;    MCE, FILTER: TRUE
 out :: UGen -> UGen -> UGen
 out bus input = mkUGen Nothing [KR,AR] (Right [1]) "Out" [bus] (Just input) 0 (Special 0) NoId
 
 -- | Very fast sine grain with a parabolic envelope
+--
+--  PSinGrain [AR] freq=440.0 dur=0.2 amp=1.0
 pSinGrain :: Rate -> UGen -> UGen -> UGen -> UGen
 pSinGrain rate freq dur amp = mkUGen Nothing [AR] (Left rate) "PSinGrain" [freq,dur,amp] Nothing 1 (Special 0) NoId
 
 -- | Complex addition.
+--
+--  PV_Add [KR] bufferA=0.0 bufferB=0.0
 pv_Add :: UGen -> UGen -> UGen
 pv_Add bufferA bufferB = mkUGen Nothing [KR] (Left KR) "PV_Add" [bufferA,bufferB] Nothing 1 (Special 0) NoId
 
 -- | Scramble bins.
+--
+--  PV_BinScramble [KR] buffer=0.0 wipe=0.0 width=0.2 trig=0.0;    NONDET
 pv_BinScramble :: ID a => a -> UGen -> UGen -> UGen -> UGen -> UGen
 pv_BinScramble z buffer wipe width trig_ = mkUGen Nothing [KR] (Left KR) "PV_BinScramble" [buffer,wipe,width,trig_] Nothing 1 (Special 0) (toUId z)
 
 -- | Shift and stretch bin position.
+--
+--  PV_BinShift [KR] buffer=0.0 stretch=1.0 shift=0.0 interp=0.0
 pv_BinShift :: UGen -> UGen -> UGen -> UGen -> UGen
 pv_BinShift buffer stretch shift interp = mkUGen Nothing [KR] (Left KR) "PV_BinShift" [buffer,stretch,shift,interp] Nothing 1 (Special 0) NoId
 
 -- | Combine low and high bins from two inputs.
+--
+--  PV_BinWipe [KR] bufferA=0.0 bufferB=0.0 wipe=0.0
 pv_BinWipe :: UGen -> UGen -> UGen -> UGen
 pv_BinWipe bufferA bufferB wipe = mkUGen Nothing [KR] (Left KR) "PV_BinWipe" [bufferA,bufferB,wipe] Nothing 1 (Special 0) NoId
 
 -- | Zero bins.
+--
+--  PV_BrickWall [KR] buffer=0.0 wipe=0.0
 pv_BrickWall :: UGen -> UGen -> UGen
 pv_BrickWall buffer wipe = mkUGen Nothing [KR] (Left KR) "PV_BrickWall" [buffer,wipe] Nothing 1 (Special 0) NoId
 
 -- | Base class for UGens that alter FFT chains
+--
+--  PV_ChainUGen [KR] maxSize=0.0
 pv_ChainUGen :: UGen -> UGen
 pv_ChainUGen maxSize = mkUGen Nothing [KR] (Left KR) "PV_ChainUGen" [maxSize] Nothing 1 (Special 0) NoId
 
 -- | Complex plane attack.
+--
+--  PV_ConformalMap [KR] buffer=0.0 areal=0.0 aimag=0.0
 pv_ConformalMap :: UGen -> UGen -> UGen -> UGen
 pv_ConformalMap buffer areal aimag = mkUGen Nothing [KR] (Left KR) "PV_ConformalMap" [buffer,areal,aimag] Nothing 1 (Special 0) NoId
 
 -- | Complex conjugate
+--
+--  PV_Conj [KR] buffer=0.0
 pv_Conj :: UGen -> UGen
 pv_Conj buffer = mkUGen Nothing [KR] (Left KR) "PV_Conj" [buffer] Nothing 1 (Special 0) NoId
 
 -- | Copy an FFT buffer
+--
+--  PV_Copy [KR] bufferA=0.0 bufferB=0.0
 pv_Copy :: UGen -> UGen -> UGen
 pv_Copy bufferA bufferB = mkUGen Nothing [KR] (Left KR) "PV_Copy" [bufferA,bufferB] Nothing 1 (Special 0) NoId
 
 -- | Copy magnitudes and phases.
+--
+--  PV_CopyPhase [KR] bufferA=0.0 bufferB=0.0
 pv_CopyPhase :: UGen -> UGen -> UGen
 pv_CopyPhase bufferA bufferB = mkUGen Nothing [KR] (Left KR) "PV_CopyPhase" [bufferA,bufferB] Nothing 1 (Special 0) NoId
 
 -- | Random phase shifting.
+--
+--  PV_Diffuser [KR] buffer=0.0 trig=0.0
 pv_Diffuser :: UGen -> UGen -> UGen
 pv_Diffuser buffer trig_ = mkUGen Nothing [KR] (Left KR) "PV_Diffuser" [buffer,trig_] Nothing 1 (Special 0) NoId
 
 -- | Complex division
+--
+--  PV_Div [KR] bufferA=0.0 bufferB=0.0
 pv_Div :: UGen -> UGen -> UGen
 pv_Div bufferA bufferB = mkUGen Nothing [KR] (Left KR) "PV_Div" [bufferA,bufferB] Nothing 1 (Special 0) NoId
 
+pv_HainsworthFoote :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_HainsworthFoote buf h f thr wt = mkUGen Nothing [KR] (Left KR) "PV_HainsworthFoote" [buf,h,f,thr,wt] Nothing 1 (Special 0) NoId
+
+pv_JensenAndersen :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_JensenAndersen buf sc hfe hfc sf thr wt = mkUGen Nothing [KR] (Left KR) "PV_JensenAndersen" [buf,sc,hfe,hfc,sf,thr,wt] Nothing 1 (Special 0) NoId
+
+{- hsc3-db
+
+
 -- | FFT onset detector.
+--
+--  PV_HainsworthFoote [KR,AR] maxSize=0.0
 pv_HainsworthFoote :: UGen -> UGen
 pv_HainsworthFoote maxSize = mkUGen Nothing [KR,AR] (Left KR) "PV_HainsworthFoote" [maxSize] Nothing 1 (Special 0) NoId
 
 -- | FFT feature detector for onset detection.
+--
+--  PV_JensenAndersen [KR,AR] maxSize=0.0
 pv_JensenAndersen :: UGen -> UGen
 pv_JensenAndersen maxSize = mkUGen Nothing [KR,AR] (Left KR) "PV_JensenAndersen" [maxSize] Nothing 1 (Special 0) NoId
+-}
 
 -- | Pass bins which are a local maximum.
+--
+--  PV_LocalMax [KR] buffer=0.0 threshold=0.0
 pv_LocalMax :: UGen -> UGen -> UGen
 pv_LocalMax buffer threshold = mkUGen Nothing [KR] (Left KR) "PV_LocalMax" [buffer,threshold] Nothing 1 (Special 0) NoId
 
 -- | Pass bins above a threshold.
+--
+--  PV_MagAbove [KR] buffer=0.0 threshold=0.0
 pv_MagAbove :: UGen -> UGen -> UGen
 pv_MagAbove buffer threshold = mkUGen Nothing [KR] (Left KR) "PV_MagAbove" [buffer,threshold] Nothing 1 (Special 0) NoId
 
 -- | Pass bins below a threshold.
+--
+--  PV_MagBelow [KR] buffer=0.0 threshold=0.0
 pv_MagBelow :: UGen -> UGen -> UGen
 pv_MagBelow buffer threshold = mkUGen Nothing [KR] (Left KR) "PV_MagBelow" [buffer,threshold] Nothing 1 (Special 0) NoId
 
 -- | Clip bins to a threshold.
+--
+--  PV_MagClip [KR] buffer=0.0 threshold=0.0
 pv_MagClip :: UGen -> UGen -> UGen
 pv_MagClip buffer threshold = mkUGen Nothing [KR] (Left KR) "PV_MagClip" [buffer,threshold] Nothing 1 (Special 0) NoId
 
 -- | Division of magnitudes
+--
+--  PV_MagDiv [KR] bufferA=0.0 bufferB=0.0 zeroed=1.0e-4
 pv_MagDiv :: UGen -> UGen -> UGen -> UGen
 pv_MagDiv bufferA bufferB zeroed = mkUGen Nothing [KR] (Left KR) "PV_MagDiv" [bufferA,bufferB,zeroed] Nothing 1 (Special 0) NoId
 
 -- | Freeze magnitudes.
+--
+--  PV_MagFreeze [KR] buffer=0.0 freeze=0.0
 pv_MagFreeze :: UGen -> UGen -> UGen
 pv_MagFreeze buffer freeze = mkUGen Nothing [KR] (Left KR) "PV_MagFreeze" [buffer,freeze] Nothing 1 (Special 0) NoId
 
 -- | Multiply magnitudes.
+--
+--  PV_MagMul [KR] bufferA=0.0 bufferB=0.0
 pv_MagMul :: UGen -> UGen -> UGen
 pv_MagMul bufferA bufferB = mkUGen Nothing [KR] (Left KR) "PV_MagMul" [bufferA,bufferB] Nothing 1 (Special 0) NoId
 
 -- | Multiply magnitudes by noise.
+--
+--  PV_MagNoise [KR] buffer=0.0
 pv_MagNoise :: UGen -> UGen
 pv_MagNoise buffer = mkUGen Nothing [KR] (Left KR) "PV_MagNoise" [buffer] Nothing 1 (Special 0) NoId
 
 -- | shift and stretch magnitude bin position.
+--
+--  PV_MagShift [KR] buffer=0.0 stretch=1.0 shift=0.0
 pv_MagShift :: UGen -> UGen -> UGen -> UGen
 pv_MagShift buffer stretch shift = mkUGen Nothing [KR] (Left KR) "PV_MagShift" [buffer,stretch,shift] Nothing 1 (Special 0) NoId
 
 -- | Average magnitudes across bins.
+--
+--  PV_MagSmear [KR] buffer=0.0 bins=0.0
 pv_MagSmear :: UGen -> UGen -> UGen
 pv_MagSmear buffer bins = mkUGen Nothing [KR] (Left KR) "PV_MagSmear" [buffer,bins] Nothing 1 (Special 0) NoId
 
 -- | Square magnitudes.
+--
+--  PV_MagSquared [KR] buffer=0.0
 pv_MagSquared :: UGen -> UGen
 pv_MagSquared buffer = mkUGen Nothing [KR] (Left KR) "PV_MagSquared" [buffer] Nothing 1 (Special 0) NoId
 
 -- | Maximum magnitude.
+--
+--  PV_Max [KR] bufferA=0.0 bufferB=0.0
 pv_Max :: UGen -> UGen -> UGen
 pv_Max bufferA bufferB = mkUGen Nothing [KR] (Left KR) "PV_Max" [bufferA,bufferB] Nothing 1 (Special 0) NoId
 
 -- | Minimum magnitude.
+--
+--  PV_Min [KR] bufferA=0.0 bufferB=0.0
 pv_Min :: UGen -> UGen -> UGen
 pv_Min bufferA bufferB = mkUGen Nothing [KR] (Left KR) "PV_Min" [bufferA,bufferB] Nothing 1 (Special 0) NoId
 
 -- | Complex multiply.
+--
+--  PV_Mul [KR] bufferA=0.0 bufferB=0.0
 pv_Mul :: UGen -> UGen -> UGen
 pv_Mul bufferA bufferB = mkUGen Nothing [KR] (Left KR) "PV_Mul" [bufferA,bufferB] Nothing 1 (Special 0) NoId
 
 -- | Shift phase.
+--
+--  PV_PhaseShift [KR] buffer=0.0 shift=0.0 integrate=0.0
 pv_PhaseShift :: UGen -> UGen -> UGen -> UGen
 pv_PhaseShift buffer shift integrate = mkUGen Nothing [KR] (Left KR) "PV_PhaseShift" [buffer,shift,integrate] Nothing 1 (Special 0) NoId
 
 -- | Shift phase by 270 degrees.
+--
+--  PV_PhaseShift270 [KR] buffer=0.0
 pv_PhaseShift270 :: UGen -> UGen
 pv_PhaseShift270 buffer = mkUGen Nothing [KR] (Left KR) "PV_PhaseShift270" [buffer] Nothing 1 (Special 0) NoId
 
 -- | Shift phase by 90 degrees.
+--
+--  PV_PhaseShift90 [KR] buffer=0.0
 pv_PhaseShift90 :: UGen -> UGen
 pv_PhaseShift90 buffer = mkUGen Nothing [KR] (Left KR) "PV_PhaseShift90" [buffer] Nothing 1 (Special 0) NoId
 
 -- | Pass random bins.
+--
+--  PV_RandComb [KR] buffer=0.0 wipe=0.0 trig=0.0;    NONDET
 pv_RandComb :: ID a => a -> UGen -> UGen -> UGen -> UGen
 pv_RandComb z buffer wipe trig_ = mkUGen Nothing [KR] (Left KR) "PV_RandComb" [buffer,wipe,trig_] Nothing 1 (Special 0) (toUId z)
 
 -- | Crossfade in random bin order.
+--
+--  PV_RandWipe [KR] bufferA=0.0 bufferB=0.0 wipe=0.0 trig=0.0;    NONDET
 pv_RandWipe :: ID a => a -> UGen -> UGen -> UGen -> UGen -> UGen
 pv_RandWipe z bufferA bufferB wipe trig_ = mkUGen Nothing [KR] (Left KR) "PV_RandWipe" [bufferA,bufferB,wipe,trig_] Nothing 1 (Special 0) (toUId z)
 
 -- | Make gaps in spectrum.
+--
+--  PV_RectComb [KR] buffer=0.0 numTeeth=0.0 phase=0.0 width=0.5
 pv_RectComb :: UGen -> UGen -> UGen -> UGen -> UGen
 pv_RectComb buffer numTeeth phase width = mkUGen Nothing [KR] (Left KR) "PV_RectComb" [buffer,numTeeth,phase,width] Nothing 1 (Special 0) NoId
 
 -- | Make gaps in spectrum.
+--
+--  PV_RectComb2 [KR] bufferA=0.0 bufferB=0.0 numTeeth=0.0 phase=0.0 width=0.5
 pv_RectComb2 :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 pv_RectComb2 bufferA bufferB numTeeth phase width = mkUGen Nothing [KR] (Left KR) "PV_RectComb2" [bufferA,bufferB,numTeeth,phase,width] Nothing 1 (Special 0) NoId
 
 -- | Two channel equal power pan.
+--
+--  Pan2 [KR,AR] in=0.0 pos=0.0 level=1.0;    FILTER: TRUE
 pan2 :: UGen -> UGen -> UGen -> UGen
 pan2 in_ pos level = mkUGen Nothing [KR,AR] (Right [0]) "Pan2" [in_,pos,level] Nothing 2 (Special 0) NoId
 
 -- | Four channel equal power pan.
+--
+--  Pan4 [KR,AR] in=0.0 xpos=0.0 ypos=0.0 level=1.0
 pan4 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 pan4 rate in_ xpos ypos level = mkUGen Nothing [KR,AR] (Left rate) "Pan4" [in_,xpos,ypos,level] Nothing 4 (Special 0) NoId
 
 -- | Azimuth panner
+--
+--  PanAz [KR,AR] in=0.0 pos=0.0 level=1.0 width=2.0 orientation=0.5;    NC INPUT: True, FILTER: TRUE
 panAz :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 panAz numChannels in_ pos level width orientation = mkUGen Nothing [KR,AR] (Right [0]) "PanAz" [in_,pos,level,width,orientation] Nothing numChannels (Special 0) NoId
 
 -- | Ambisonic B-format panner.
+--
+--  PanB [KR,AR] in=0.0 azimuth=0.0 elevation=0.0 gain=1.0
 panB :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 panB rate in_ azimuth elevation gain = mkUGen Nothing [KR,AR] (Left rate) "PanB" [in_,azimuth,elevation,gain] Nothing 4 (Special 0) NoId
 
 -- | 2D Ambisonic B-format panner.
+--
+--  PanB2 [KR,AR] in=0.0 azimuth=0.0 gain=1.0
 panB2 :: Rate -> UGen -> UGen -> UGen -> UGen
 panB2 rate in_ azimuth gain = mkUGen Nothing [KR,AR] (Left rate) "PanB2" [in_,azimuth,gain] Nothing 3 (Special 0) NoId
 
 -- | Real-time partitioned convolution
+--
+--  PartConv [AR] in=0.0 fftsize=0.0 irbufnum=0.0
 partConv :: UGen -> UGen -> UGen -> UGen
 partConv in_ fftsize irbufnum = mkUGen Nothing [AR] (Left AR) "PartConv" [in_,fftsize,irbufnum] Nothing 1 (Special 0) NoId
 
 -- | When triggered, pauses a node.
-pause :: Rate -> UGen -> UGen -> UGen
-pause rate gate_ id_ = mkUGen Nothing [KR] (Left rate) "Pause" [gate_,id_] Nothing 1 (Special 0) NoId
+--
+--  Pause [KR] gate=0.0 id=0.0
+pause :: UGen -> UGen -> UGen
+pause gate_ id_ = mkUGen Nothing [KR] (Left KR) "Pause" [gate_,id_] Nothing 1 (Special 0) NoId
 
 -- | When triggered, pause enclosing synth.
-pauseSelf :: Rate -> UGen -> UGen
-pauseSelf rate in_ = mkUGen Nothing [KR] (Left rate) "PauseSelf" [in_] Nothing 1 (Special 0) NoId
+--
+--  PauseSelf [KR] in=0.0
+pauseSelf :: UGen -> UGen
+pauseSelf in_ = mkUGen Nothing [KR] (Left KR) "PauseSelf" [in_] Nothing 1 (Special 0) NoId
 
 -- | FIXME: PauseSelfWhenDone purpose.
-pauseSelfWhenDone :: Rate -> UGen -> UGen
-pauseSelfWhenDone rate src = mkUGen Nothing [KR] (Left rate) "PauseSelfWhenDone" [src] Nothing 1 (Special 0) NoId
+--
+--  PauseSelfWhenDone [KR] src=0.0
+pauseSelfWhenDone :: UGen -> UGen
+pauseSelfWhenDone src = mkUGen Nothing [KR] (Left KR) "PauseSelfWhenDone" [src] Nothing 1 (Special 0) NoId
 
 -- | Track peak signal amplitude.
+--
+--  Peak [KR,AR] in=0.0 trig=0.0;    FILTER: TRUE
 peak :: UGen -> UGen -> UGen
 peak in_ trig_ = mkUGen Nothing [KR,AR] (Right [0]) "Peak" [in_,trig_] Nothing 1 (Special 0) NoId
 
 -- | Track peak signal amplitude.
+--
+--  PeakFollower [KR,AR] in=0.0 decay=0.999;    FILTER: TRUE
 peakFollower :: UGen -> UGen -> UGen
 peakFollower in_ decay_ = mkUGen Nothing [KR,AR] (Right [0]) "PeakFollower" [in_,decay_] Nothing 1 (Special 0) NoId
 
 -- | A resettable linear ramp between two levels.
+--
+--  Phasor [KR,AR] trig=0.0 rate=1.0 start=0.0 end=1.0 resetPos=0.0
 phasor :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 phasor rate trig_ rate_ start end resetPos = mkUGen Nothing [KR,AR] (Left rate) "Phasor" [trig_,rate_,start,end,resetPos] Nothing 1 (Special 0) NoId
 
 -- | Pink Noise.
+--
+--  PinkNoise [KR,AR] ;    NONDET
 pinkNoise :: ID a => a -> Rate -> UGen
 pinkNoise z rate = mkUGen Nothing [KR,AR] (Left rate) "PinkNoise" [] Nothing 1 (Special 0) (toUId z)
 
 -- | Autocorrelation pitch follower
+--
+--  Pitch [KR] in=0.0 initFreq=440.0 minFreq=60.0 maxFreq=4000.0 execFreq=100.0 maxBinsPerOctave=16.0 median=1.0 ampThreshold=1.0e-2 peakThreshold=0.5 downSample=1.0 clar=0.0
 pitch :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 pitch in_ initFreq minFreq maxFreq execFreq maxBinsPerOctave median_ ampThreshold peakThreshold downSample clar = mkUGen Nothing [KR] (Left KR) "Pitch" [in_,initFreq,minFreq,maxFreq,execFreq,maxBinsPerOctave,median_,ampThreshold,peakThreshold,downSample,clar] Nothing 2 (Special 0) NoId
 
 -- | Time domain pitch shifter.
+--
+--  PitchShift [AR] in=0.0 windowSize=0.2 pitchRatio=1.0 pitchDispersion=0.0 timeDispersion=0.0;    FILTER: TRUE
 pitchShift :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 pitchShift in_ windowSize pitchRatio pitchDispersion timeDispersion = mkUGen Nothing [AR] (Right [0]) "PitchShift" [in_,windowSize,pitchRatio,pitchDispersion,timeDispersion] Nothing 1 (Special 0) NoId
 
 -- | Sample playback oscillator.
+--
+--  PlayBuf [KR,AR] bufnum=0.0 rate=1.0 trigger=1.0 startPos=0.0 loop=0.0 doneAction=0.0;    NC INPUT: True, ENUMERATION INPUTS: 4=Loop, 5=DoneAction
 playBuf :: Int -> Rate -> UGen -> UGen -> UGen -> UGen -> Loop -> DoneAction -> UGen
 playBuf numChannels rate bufnum rate_ trigger startPos loop doneAction = mkUGen Nothing [KR,AR] (Left rate) "PlayBuf" [bufnum,rate_,trigger,startPos,(from_loop loop),(from_done_action doneAction)] Nothing numChannels (Special 0) NoId
 
 -- | A Karplus-Strong UGen
+--
+--  Pluck [AR] in=0.0 trig=1.0 maxdelaytime=0.2 delaytime=0.2 decaytime=1.0 coef=0.5;    FILTER: TRUE
 pluck :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 pluck in_ trig_ maxdelaytime delaytime decaytime coef = mkUGen Nothing [AR] (Right [0]) "Pluck" [in_,trig_,maxdelaytime,delaytime,decaytime,coef] Nothing 1 (Special 0) NoId
 
--- | Print the current output value of a UGen
--- poll :: UGen -> UGen -> UGen -> UGen -> UGen
--- poll trig_ in_ label_ trigid = mkUGen Nothing [KR,AR] (Right [1]) "Poll" [trig_,in_,label_,trigid] Nothing 1 (Special 0) NoId
-
 -- | Band limited pulse wave.
+--
+--  Pulse [KR,AR] freq=440.0 width=0.5
 pulse :: Rate -> UGen -> UGen -> UGen
 pulse rate freq width = mkUGen Nothing [KR,AR] (Left rate) "Pulse" [freq,width] Nothing 1 (Special 0) NoId
 
 -- | Pulse counter.
+--
+--  PulseCount [KR,AR] trig=0.0 reset=0.0;    FILTER: TRUE
 pulseCount :: UGen -> UGen -> UGen
 pulseCount trig_ reset = mkUGen Nothing [KR,AR] (Right [0]) "PulseCount" [trig_,reset] Nothing 1 (Special 0) NoId
 
 -- | Pulse divider.
+--
+--  PulseDivider [KR,AR] trig=0.0 div=2.0 start=0.0;    FILTER: TRUE
 pulseDivider :: UGen -> UGen -> UGen -> UGen
 pulseDivider trig_ div_ start = mkUGen Nothing [KR,AR] (Right [0]) "PulseDivider" [trig_,div_,start] Nothing 1 (Special 0) NoId
 
 -- | General quadratic map chaotic generator
+--
+--  QuadC [AR] freq=22050.0 a=1.0 b=-1.0 c=-0.75 xi=0.0
 quadC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 quadC rate freq a b c xi = mkUGen Nothing [AR] (Left rate) "QuadC" [freq,a,b,c,xi] Nothing 1 (Special 0) NoId
 
 -- | General quadratic map chaotic generator
+--
+--  QuadL [AR] freq=22050.0 a=1.0 b=-1.0 c=-0.75 xi=0.0
 quadL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 quadL rate freq a b c xi = mkUGen Nothing [AR] (Left rate) "QuadL" [freq,a,b,c,xi] Nothing 1 (Special 0) NoId
 
 -- | General quadratic map chaotic generator
+--
+--  QuadN [AR] freq=22050.0 a=1.0 b=-1.0 c=-0.75 xi=0.0
 quadN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 quadN rate freq a b c xi = mkUGen Nothing [AR] (Left rate) "QuadN" [freq,a,b,c,xi] Nothing 1 (Special 0) NoId
 
 -- | A resonant high pass filter.
+--
+--  RHPF [KR,AR] in=0.0 freq=440.0 rq=1.0;    FILTER: TRUE
 rhpf :: UGen -> UGen -> UGen -> UGen
 rhpf in_ freq rq = mkUGen Nothing [KR,AR] (Right [0]) "RHPF" [in_,freq,rq] Nothing 1 (Special 0) NoId
 
 -- | A resonant low pass filter.
+--
+--  RLPF [KR,AR] in=0.0 freq=440.0 rq=1.0;    FILTER: TRUE
 rlpf :: UGen -> UGen -> UGen -> UGen
 rlpf in_ freq rq = mkUGen Nothing [KR,AR] (Right [0]) "RLPF" [in_,freq,rq] Nothing 1 (Special 0) NoId
 
 -- | Number of radians per sample.
+--
+--  RadiansPerSample [IR]
 radiansPerSample :: UGen
 radiansPerSample = mkUGen Nothing [IR] (Left IR) "RadiansPerSample" [] Nothing 1 (Special 0) NoId
 
 -- | Break a continuous signal into line segments
+--
+--  Ramp [KR,AR] in=0.0 lagTime=0.1;    FILTER: TRUE
 ramp :: UGen -> UGen -> UGen
 ramp in_ lagTime = mkUGen Nothing [KR,AR] (Right [0]) "Ramp" [in_,lagTime] Nothing 1 (Special 0) NoId
 
 -- | Single random number generator.
+--
+--  Rand [IR] lo=0.0 hi=1.0;    NONDET
 rand :: ID a => a -> UGen -> UGen -> UGen
 rand z lo hi = mkUGen Nothing [IR] (Left IR) "Rand" [lo,hi] Nothing 1 (Special 0) (toUId z)
 
 -- | Set the synth's random generator ID.
+--
+--  RandID [IR,KR] id=0.0
 randID :: Rate -> UGen -> UGen
 randID rate id_ = mkUGen Nothing [IR,KR] (Left rate) "RandID" [id_] Nothing 0 (Special 0) NoId
 
 -- | Sets the synth's random generator seed.
+--
+--  RandSeed [IR,KR,AR] trig=0.0 seed=56789.0
 randSeed :: Rate -> UGen -> UGen -> UGen
 randSeed rate trig_ seed = mkUGen Nothing [IR,KR,AR] (Left rate) "RandSeed" [trig_,seed] Nothing 0 (Special 0) NoId
 
 -- | Record or overdub into a Buffer.
+--
+--  RecordBuf [KR,AR] bufnum=0.0 offset=0.0 recLevel=1.0 preLevel=0.0 run=1.0 loop=1.0 trigger=1.0 doneAction=0.0 *inputArray=0.0;    MCE, REORDERS INPUTS: [8,0,1,2,3,4,5,6,7], ENUMERATION INPUTS: 5=Loop, 7=DoneAction
 recordBuf :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> Loop -> UGen -> DoneAction -> UGen -> UGen
 recordBuf rate bufnum offset recLevel preLevel run loop trigger doneAction inputArray = mkUGen Nothing [KR,AR] (Left rate) "RecordBuf" [bufnum,offset,recLevel,preLevel,run,(from_loop loop),trigger,(from_done_action doneAction)] (Just inputArray) 1 (Special 0) NoId
 
 -- | Send signal to a bus, overwriting previous contents.
+--
+--  ReplaceOut [KR,AR] bus=0.0 *channelsArray=0.0;    MCE, FILTER: TRUE
 replaceOut :: UGen -> UGen -> UGen
 replaceOut bus input = mkUGen Nothing [KR,AR] (Right [1]) "ReplaceOut" [bus] (Just input) 0 (Special 0) NoId
 
 -- | Resonant filter.
+--
+--  Resonz [KR,AR] in=0.0 freq=440.0 bwr=1.0;    FILTER: TRUE
 resonz :: UGen -> UGen -> UGen -> UGen
 resonz in_ freq bwr = mkUGen Nothing [KR,AR] (Right [0]) "Resonz" [in_,freq,bwr] Nothing 1 (Special 0) NoId
 
 -- | Ringing filter.
+--
+--  Ringz [KR,AR] in=0.0 freq=440.0 decaytime=1.0;    FILTER: TRUE
 ringz :: UGen -> UGen -> UGen -> UGen
 ringz in_ freq decaytime = mkUGen Nothing [KR,AR] (Right [0]) "Ringz" [in_,freq,decaytime] Nothing 1 (Special 0) NoId
 
 -- | Rotate a sound field.
+--
+--  Rotate2 [KR,AR] x=0.0 y=0.0 pos=0.0;    FILTER: TRUE
 rotate2 :: UGen -> UGen -> UGen -> UGen
 rotate2 x y pos = mkUGen Nothing [KR,AR] (Right [0,1]) "Rotate2" [x,y,pos] Nothing 2 (Special 0) NoId
 
 -- | Track maximum level.
+--
+--  RunningMax [KR,AR] in=0.0 trig=0.0;    FILTER: TRUE
 runningMax :: UGen -> UGen -> UGen
 runningMax in_ trig_ = mkUGen Nothing [KR,AR] (Right [0]) "RunningMax" [in_,trig_] Nothing 1 (Special 0) NoId
 
 -- | Track minimum level.
+--
+--  RunningMin [KR,AR] in=0.0 trig=0.0;    FILTER: TRUE
 runningMin :: UGen -> UGen -> UGen
 runningMin in_ trig_ = mkUGen Nothing [KR,AR] (Right [0]) "RunningMin" [in_,trig_] Nothing 1 (Special 0) NoId
 
 -- | Running sum over n frames
+--
+--  RunningSum [KR,AR] in=0.0 numsamp=40.0;    FILTER: TRUE
 runningSum :: UGen -> UGen -> UGen
 runningSum in_ numsamp = mkUGen Nothing [KR,AR] (Right [0]) "RunningSum" [in_,numsamp] Nothing 1 (Special 0) NoId
 
 -- | Second order filter section (biquad).
+--
+--  SOS [KR,AR] in=0.0 a0=0.0 a1=0.0 a2=0.0 b1=0.0 b2=0.0;    FILTER: TRUE
 sos :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 sos in_ a0 a1 a2 b1 b2 = mkUGen Nothing [KR,AR] (Right [0]) "SOS" [in_,a0,a1,a2,b1,b2] Nothing 1 (Special 0) NoId
 
 -- | Duration of one sample.
+--
+--  SampleDur [IR]
 sampleDur :: UGen
 sampleDur = mkUGen Nothing [IR] (Left IR) "SampleDur" [] Nothing 1 (Special 0) NoId
 
 -- | Server sample rate.
+--
+--  SampleRate [IR]
 sampleRate :: UGen
 sampleRate = mkUGen Nothing [IR] (Left IR) "SampleRate" [] Nothing 1 (Special 0) NoId
 
 -- | Band limited sawtooth.
+--
+--  Saw [KR,AR] freq=440.0
 saw :: Rate -> UGen -> UGen
 saw rate freq = mkUGen Nothing [KR,AR] (Left rate) "Saw" [freq] Nothing 1 (Special 0) NoId
 
 -- | Schmidt trigger.
-schmidt :: Rate -> UGen -> UGen -> UGen -> UGen
-schmidt rate in_ lo hi = mkUGen Nothing [IR,KR,AR] (Left rate) "Schmidt" [in_,lo,hi] Nothing 1 (Special 0) NoId
+--
+--  Schmidt [IR,KR,AR] in=0.0 lo=0.0 hi=1.0
+schmidt :: UGen -> UGen -> UGen -> UGen
+schmidt in_ lo hi = mkUGen Nothing [IR,KR,AR] (Right [0]) "Schmidt" [in_,lo,hi] Nothing 1 (Special 0) NoId
 
 -- | FIXME: ScopeOut purpose.
+--
+--  ScopeOut [KR,AR] inputArray=0.0 bufnum=0.0
 scopeOut :: Rate -> UGen -> UGen -> UGen
 scopeOut rate inputArray bufnum = mkUGen Nothing [KR,AR] (Left rate) "ScopeOut" [inputArray,bufnum] Nothing 0 (Special 0) NoId
 
 -- | (Undocumented class)
+--
+--  ScopeOut2 [KR,AR] inputArray=0.0 scopeNum=0.0 maxFrames=4096.0 scopeFrames=0.0
 scopeOut2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 scopeOut2 rate inputArray scopeNum maxFrames scopeFrames = mkUGen Nothing [KR,AR] (Left rate) "ScopeOut2" [inputArray,scopeNum,maxFrames,scopeFrames] Nothing 0 (Special 0) NoId
 
 -- | Select output from an array of inputs.
+--
+--  Select [IR,KR,AR] which=0.0 *array=0.0;    MCE, FILTER: TRUE
 select :: UGen -> UGen -> UGen
 select which array = mkUGen Nothing [IR,KR,AR] (Right [0,1]) "Select" [which] (Just array) 1 (Special 0) NoId
 
 -- | Send a trigger message from the server back to the client.
+--
+--  SendTrig [KR,AR] in=0.0 id=0.0 value=0.0;    FILTER: TRUE
 sendTrig :: UGen -> UGen -> UGen -> UGen
 sendTrig in_ id_ value = mkUGen Nothing [KR,AR] (Right [0]) "SendTrig" [in_,id_,value] Nothing 0 (Special 0) NoId
 
 -- | Set-reset flip flop.
+--
+--  SetResetFF [KR,AR] trig=0.0 reset=0.0;    FILTER: TRUE
 setResetFF :: UGen -> UGen -> UGen
 setResetFF trig_ reset = mkUGen Nothing [KR,AR] (Right [0]) "SetResetFF" [trig_,reset] Nothing 1 (Special 0) NoId
 
 -- | Wave shaper.
+--
+--  Shaper [KR,AR] bufnum=0.0 in=0.0;    FILTER: TRUE
 shaper :: UGen -> UGen -> UGen
 shaper bufnum in_ = mkUGen Nothing [KR,AR] (Right [1]) "Shaper" [bufnum,in_] Nothing 1 (Special 0) NoId
 
 -- | Interpolating sine wavetable oscillator.
+--
+--  SinOsc [KR,AR] freq=440.0 phase=0.0
 sinOsc :: Rate -> UGen -> UGen -> UGen
 sinOsc rate freq phase = mkUGen Nothing [KR,AR] (Left rate) "SinOsc" [freq,phase] Nothing 1 (Special 0) NoId
 
 -- | Feedback FM oscillator
+--
+--  SinOscFB [KR,AR] freq=440.0 feedback=0.0
 sinOscFB :: Rate -> UGen -> UGen -> UGen
 sinOscFB rate freq feedback = mkUGen Nothing [KR,AR] (Left rate) "SinOscFB" [freq,feedback] Nothing 1 (Special 0) NoId
 
 -- | Slew rate limiter.
+--
+--  Slew [KR,AR] in=0.0 up=1.0 dn=1.0;    FILTER: TRUE
 slew :: UGen -> UGen -> UGen -> UGen
 slew in_ up dn = mkUGen Nothing [KR,AR] (Right [0]) "Slew" [in_,up,dn] Nothing 1 (Special 0) NoId
 
 -- | Slope of signal
+--
+--  Slope [KR,AR] in=0.0;    FILTER: TRUE
 slope :: UGen -> UGen
 slope in_ = mkUGen Nothing [KR,AR] (Right [0]) "Slope" [in_] Nothing 1 (Special 0) NoId
 
 -- | Spectral centroid
+--
+--  SpecCentroid [KR] buffer=0.0
 specCentroid :: Rate -> UGen -> UGen
 specCentroid rate buffer = mkUGen Nothing [KR] (Left rate) "SpecCentroid" [buffer] Nothing 1 (Special 0) NoId
 
 -- | Spectral Flatness measure
+--
+--  SpecFlatness [KR] buffer=0.0
 specFlatness :: Rate -> UGen -> UGen
 specFlatness rate buffer = mkUGen Nothing [KR] (Left rate) "SpecFlatness" [buffer] Nothing 1 (Special 0) NoId
 
 -- | Find a percentile of FFT magnitude spectrum
+--
+--  SpecPcile [KR] buffer=0.0 fraction=0.5 interpolate=0.0
 specPcile :: Rate -> UGen -> UGen -> UGen -> UGen
 specPcile rate buffer fraction interpolate = mkUGen Nothing [KR] (Left rate) "SpecPcile" [buffer,fraction,interpolate] Nothing 1 (Special 0) NoId
 
 -- | physical model of resonating spring
+--
+--  Spring [KR,AR] in=0.0 spring=1.0 damp=0.0
 spring :: Rate -> UGen -> UGen -> UGen -> UGen
 spring rate in_ spring_ damp = mkUGen Nothing [KR,AR] (Left rate) "Spring" [in_,spring_,damp] Nothing 1 (Special 0) NoId
 
 -- | Standard map chaotic generator
+--
+--  StandardL [AR] freq=22050.0 k=1.0 xi=0.5 yi=0.0
 standardL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 standardL rate freq k xi yi = mkUGen Nothing [AR] (Left rate) "StandardL" [freq,k,xi,yi] Nothing 1 (Special 0) NoId
 
 -- | Standard map chaotic generator
+--
+--  StandardN [AR] freq=22050.0 k=1.0 xi=0.5 yi=0.0
 standardN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 standardN rate freq k xi yi = mkUGen Nothing [AR] (Left rate) "StandardN" [freq,k,xi,yi] Nothing 1 (Special 0) NoId
 
 -- | Pulse counter.
+--
+--  Stepper [KR,AR] trig=0.0 reset=0.0 min=0.0 max=7.0 step=1.0 resetval=0.0;    FILTER: TRUE
 stepper :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 stepper trig_ reset min_ max_ step resetval = mkUGen Nothing [KR,AR] (Right [0]) "Stepper" [trig_,reset,min_,max_,step,resetval] Nothing 1 (Special 0) NoId
 
 -- | Stereo real-time convolver with linear interpolation
+--
+--  StereoConvolution2L [AR] in=0.0 kernelL=0.0 kernelR=0.0 trigger=0.0 framesize=2048.0 crossfade=1.0
 stereoConvolution2L :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 stereoConvolution2L rate in_ kernelL kernelR trigger framesize crossfade = mkUGen Nothing [AR] (Left rate) "StereoConvolution2L" [in_,kernelL,kernelR,trigger,framesize,crossfade] Nothing 2 (Special 0) NoId
 
 -- | Offset from synth start within one sample.
+--
+--  SubsampleOffset [IR]
 subsampleOffset :: UGen
 subsampleOffset = mkUGen Nothing [IR] (Left IR) "SubsampleOffset" [] Nothing 1 (Special 0) NoId
 
 -- | Sum three signals
+--
+--  Sum3 [] in0=0.0 in1=0.0 in2=0.0;    FILTER: TRUE
 sum3 :: UGen -> UGen -> UGen -> UGen
 sum3 in0 in1 in2 = mkUGen Nothing [IR,KR,AR,DR] (Right [0,1,2]) "Sum3" [in0,in1,in2] Nothing 1 (Special 0) NoId
 
 -- | Sum four signals
+--
+--  Sum4 [] in0=0.0 in1=0.0 in2=0.0 in3=0.0;    FILTER: TRUE
 sum4 :: UGen -> UGen -> UGen -> UGen -> UGen
 sum4 in0 in1 in2 in3 = mkUGen Nothing [IR,KR,AR,DR] (Right [0,1,2,3]) "Sum4" [in0,in1,in2,in3] Nothing 1 (Special 0) NoId
 
 -- | Triggered linear ramp
+--
+--  Sweep [KR,AR] trig=0.0 rate=1.0;    FILTER: TRUE
 sweep :: UGen -> UGen -> UGen
 sweep trig_ rate_ = mkUGen Nothing [KR,AR] (Right [0]) "Sweep" [trig_,rate_] Nothing 1 (Special 0) NoId
 
 -- | Hard sync sawtooth wave.
+--
+--  SyncSaw [KR,AR] syncFreq=440.0 sawFreq=440.0
 syncSaw :: Rate -> UGen -> UGen -> UGen
 syncSaw rate syncFreq sawFreq = mkUGen Nothing [KR,AR] (Left rate) "SyncSaw" [syncFreq,sawFreq] Nothing 1 (Special 0) NoId
 
 -- | Control rate trigger to audio rate trigger converter
+--
+--  T2A [AR] in=0.0 offset=0.0
 t2A :: UGen -> UGen -> UGen
 t2A in_ offset = mkUGen Nothing [AR] (Left AR) "T2A" [in_,offset] Nothing 1 (Special 0) NoId
 
 -- | Audio rate trigger to control rate trigger converter
+--
+--  T2K [KR] in=0.0
 t2K :: Rate -> UGen -> UGen
 t2K rate in_ = mkUGen Nothing [KR] (Left rate) "T2K" [in_] Nothing 1 (Special 0) NoId
 
 -- | physical model of bouncing object
+--
+--  TBall [KR,AR] in=0.0 g=10.0 damp=0.0 friction=1.0e-2
 tBall :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 tBall rate in_ g damp friction = mkUGen Nothing [KR,AR] (Left rate) "TBall" [in_,g,damp,friction] Nothing 1 (Special 0) NoId
 
 -- | Trigger delay.
+--
+--  TDelay [KR,AR] in=0.0 dur=0.1;    FILTER: TRUE
 tDelay :: UGen -> UGen -> UGen
 tDelay in_ dur = mkUGen Nothing [KR,AR] (Right [0]) "TDelay" [in_,dur] Nothing 1 (Special 0) NoId
 
 -- | Demand results as trigger from demand rate UGens.
+--
+--  TDuty [KR,AR] dur=1.0 reset=0.0 doneAction=0.0 level=1.0 gapFirst=0.0;    REORDERS INPUTS: [0,1,3,2,4], ENUMERATION INPUTS: 2=DoneAction
 tDuty :: Rate -> UGen -> UGen -> DoneAction -> UGen -> UGen -> UGen
 tDuty rate dur reset doneAction level gapFirst = mkUGen Nothing [KR,AR] (Left rate) "TDuty" [dur,reset,(from_done_action doneAction),level,gapFirst] Nothing 1 (Special 0) NoId
 
 -- | Triggered exponential random number generator.
+--
+--  TExpRand [KR,AR] lo=1.0e-2 hi=1.0 trig=0.0;    FILTER: TRUE, NONDET
 tExpRand :: ID a => a -> UGen -> UGen -> UGen -> UGen
 tExpRand z lo hi trig_ = mkUGen Nothing [KR,AR] (Right [2]) "TExpRand" [lo,hi,trig_] Nothing 1 (Special 0) (toUId z)
 
 -- | Buffer granulator.
+--
+--  TGrains [AR] trigger=0.0 bufnum=0.0 rate=1.0 centerPos=0.0 dur=0.1 pan=0.0 amp=0.1 interp=4.0;    NC INPUT: True
 tGrains :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 tGrains numChannels trigger bufnum rate_ centerPos dur pan amp interp = mkUGen Nothing [AR] (Left AR) "TGrains" [trigger,bufnum,rate_,centerPos,dur,pan,amp,interp] Nothing numChannels (Special 0) NoId
 
 -- | Triggered integer random number generator.
+--
+--  TIRand [KR,AR] lo=0.0 hi=127.0 trig=0.0;    FILTER: TRUE, NONDET
 tIRand :: ID a => a -> UGen -> UGen -> UGen -> UGen
 tIRand z lo hi trig_ = mkUGen Nothing [KR,AR] (Right [2]) "TIRand" [lo,hi,trig_] Nothing 1 (Special 0) (toUId z)
 
 -- | Triggered random number generator.
+--
+--  TRand [KR,AR] lo=0.0 hi=1.0 trig=0.0;    FILTER: TRUE, NONDET
 tRand :: ID a => a -> UGen -> UGen -> UGen -> UGen
 tRand z lo hi trig_ = mkUGen Nothing [KR,AR] (Right [2]) "TRand" [lo,hi,trig_] Nothing 1 (Special 0) (toUId z)
 
 -- | Triggered windex.
+--
+--  TWindex [KR,AR] in=0.0 normalize=0.0 *array=0.0;    MCE, FILTER: TRUE, REORDERS INPUTS: [0,2,1], NONDET
 tWindex :: ID a => a -> UGen -> UGen -> UGen -> UGen
 tWindex z in_ normalize array = mkUGen Nothing [KR,AR] (Right [0]) "TWindex" [in_,normalize] (Just array) 1 (Special 0) (toUId z)
 
 -- | Returns time since last triggered.
+--
+--  Timer [KR,AR] trig=0.0;    FILTER: TRUE
 timer :: UGen -> UGen
 timer trig_ = mkUGen Nothing [KR,AR] (Right [0]) "Timer" [trig_] Nothing 1 (Special 0) NoId
 
 -- | Toggle flip flop.
+--
+--  ToggleFF [KR,AR] trig=0.0;    FILTER: TRUE
 toggleFF :: UGen -> UGen
 toggleFF trig_ = mkUGen Nothing [KR,AR] (Right [0]) "ToggleFF" [trig_] Nothing 1 (Special 0) NoId
 
 -- | Timed trigger.
+--
+--  Trig [KR,AR] in=0.0 dur=0.1;    FILTER: TRUE
 trig :: UGen -> UGen -> UGen
 trig in_ dur = mkUGen Nothing [KR,AR] (Right [0]) "Trig" [in_,dur] Nothing 1 (Special 0) NoId
 
 -- | Timed trigger.
+--
+--  Trig1 [KR,AR] in=0.0 dur=0.1;    FILTER: TRUE
 trig1 :: UGen -> UGen -> UGen
 trig1 in_ dur = mkUGen Nothing [KR,AR] (Right [0]) "Trig1" [in_,dur] Nothing 1 (Special 0) NoId
 
 -- | FIXME: TrigControl purpose.
+--
+--  TrigControl [IR,KR] values=0.0
 trigControl :: Rate -> UGen -> UGen
 trigControl rate values = mkUGen Nothing [IR,KR] (Left rate) "TrigControl" [values] Nothing 0 (Special 0) NoId
 
 -- | Two pole filter.
+--
+--  TwoPole [KR,AR] in=0.0 freq=440.0 radius=0.8;    FILTER: TRUE
 twoPole :: UGen -> UGen -> UGen -> UGen
 twoPole in_ freq radius = mkUGen Nothing [KR,AR] (Right [0]) "TwoPole" [in_,freq,radius] Nothing 1 (Special 0) NoId
 
 -- | Two zero filter.
+--
+--  TwoZero [KR,AR] in=0.0 freq=440.0 radius=0.8;    FILTER: TRUE
 twoZero :: UGen -> UGen -> UGen -> UGen
 twoZero in_ freq radius = mkUGen Nothing [KR,AR] (Right [0]) "TwoZero" [in_,freq,radius] Nothing 1 (Special 0) NoId
 
 -- | Apply a unary operation to the values of an input ugen
+--
+--  UnaryOpUGen [] a=0.0;    FILTER: TRUE
 unaryOpUGen :: UGen -> UGen
 unaryOpUGen a = mkUGen Nothing [IR,KR,AR,DR] (Right [0]) "UnaryOpUGen" [a] Nothing 1 (Special 0) NoId
 
 -- | Stream in audio from a file, with variable rate
+--
+--  VDiskIn [AR] bufnum=0.0 rate=1.0 loop=0.0 sendID=0.0;    NC INPUT: True, ENUMERATION INPUTS: 2=Loop
 vDiskIn :: Int -> UGen -> UGen -> Loop -> UGen -> UGen
 vDiskIn numChannels bufnum rate_ loop sendID = mkUGen Nothing [AR] (Left AR) "VDiskIn" [bufnum,rate_,(from_loop loop),sendID] Nothing numChannels (Special 0) NoId
 
 -- | Variable wavetable oscillator.
+--
+--  VOsc [KR,AR] bufpos=0.0 freq=440.0 phase=0.0
 vOsc :: Rate -> UGen -> UGen -> UGen -> UGen
 vOsc rate bufpos freq phase = mkUGen Nothing [KR,AR] (Left rate) "VOsc" [bufpos,freq,phase] Nothing 1 (Special 0) NoId
 
 -- | Three variable wavetable oscillators.
+--
+--  VOsc3 [KR,AR] bufpos=0.0 freq1=110.0 freq2=220.0 freq3=440.0
 vOsc3 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
 vOsc3 rate bufpos freq1 freq2 freq3 = mkUGen Nothing [KR,AR] (Left rate) "VOsc3" [bufpos,freq1,freq2,freq3] Nothing 1 (Special 0) NoId
 
 -- | Variable shaped lag
-varLag :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-varLag rate in_ time curvature warp start = mkUGen Nothing [KR,AR] (Left rate) "VarLag" [in_,time,curvature,warp,start] Nothing 0 (Special 0) NoId
+--
+--  VarLag [KR,AR] in=0.0 time=0.1 curvature=0.0 warp=5.0 start=0.0
+varLag :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+varLag in_ time curvature warp start = mkUGen Nothing [KR,AR] (Right [0]) "VarLag" [in_,time,curvature,warp,start] Nothing 1 (Special 0) NoId
 
 -- | Variable duty saw
+--
+--  VarSaw [KR,AR] freq=440.0 iphase=0.0 width=0.5
 varSaw :: Rate -> UGen -> UGen -> UGen -> UGen
 varSaw rate freq iphase width = mkUGen Nothing [KR,AR] (Left rate) "VarSaw" [freq,iphase,width] Nothing 1 (Special 0) NoId
 
 -- | The Vibrato oscillator models a slow frequency modulation.
+--
+--  Vibrato [KR,AR] freq=440.0 rate=6.0 depth=2.0e-2 delay=0.0 onset=0.0 rateVariation=4.0e-2 depthVariation=0.1 iphase=0.0;    NONDET
 vibrato :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 vibrato z rate freq rate_ depth delay onset rateVariation depthVariation iphase = mkUGen Nothing [KR,AR] (Left rate) "Vibrato" [freq,rate_,depth,delay,onset,rateVariation,depthVariation,iphase] Nothing 1 (Special 0) (toUId z)
 
 -- | Warp a buffer with a time pointer
+--
+--  Warp1 [AR] bufnum=0.0 pointer=0.0 freqScale=1.0 windowSize=0.2 envbufnum=-1.0 overlaps=8.0 windowRandRatio=0.0 interp=1.0;    NC INPUT: True
 warp1 :: Int -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 warp1 numChannels bufnum pointer freqScale windowSize envbufnum overlaps windowRandRatio interp = mkUGen Nothing [AR] (Left AR) "Warp1" [bufnum,pointer,freqScale,windowSize,envbufnum,overlaps,windowRandRatio,interp] Nothing numChannels (Special 0) NoId
 
 -- | White noise.
+--
+--  WhiteNoise [KR,AR] ;    NONDET
 whiteNoise :: ID a => a -> Rate -> UGen
 whiteNoise z rate = mkUGen Nothing [KR,AR] (Left rate) "WhiteNoise" [] Nothing 1 (Special 0) (toUId z)
 
 -- | (Undocumented class)
+--
+--  WidthFirstUGen [] maxSize=0.0
 widthFirstUGen :: Rate -> UGen -> UGen
 widthFirstUGen rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "WidthFirstUGen" [maxSize] Nothing 1 (Special 0) NoId
 
 -- | Wrap a signal outside given thresholds.
+--
+--  Wrap [IR,KR,AR] in=0.0 lo=0.0 hi=1.0;    FILTER: TRUE
 wrap :: UGen -> UGen -> UGen -> UGen
 wrap in_ lo hi = mkUGen Nothing [IR,KR,AR] (Right [0]) "Wrap" [in_,lo,hi] Nothing 1 (Special 0) NoId
 
 -- | Index into a table with a signal.
+--
+--  WrapIndex [KR,AR] bufnum=0.0 in=0.0;    FILTER: TRUE
 wrapIndex :: UGen -> UGen -> UGen
 wrapIndex bufnum in_ = mkUGen Nothing [KR,AR] (Right [1]) "WrapIndex" [bufnum,in_] Nothing 1 (Special 0) NoId
 
 -- | Equal power two channel cross fade.
+--
+--  XFade2 [KR,AR] inA=0.0 inB=0.0 pan=0.0 level=1.0;    FILTER: TRUE
 xFade2 :: UGen -> UGen -> UGen -> UGen -> UGen
 xFade2 inA inB pan level = mkUGen Nothing [KR,AR] (Right [0,1]) "XFade2" [inA,inB,pan,level] Nothing 1 (Special 0) NoId
 
 -- | Exponential line generator.
+--
+--  XLine [KR,AR] start=1.0 end=2.0 dur=1.0 doneAction=0.0;    ENUMERATION INPUTS: 3=DoneAction
 xLine :: Rate -> UGen -> UGen -> UGen -> DoneAction -> UGen
 xLine rate start end dur doneAction = mkUGen Nothing [KR,AR] (Left rate) "XLine" [start,end,dur,(from_done_action doneAction)] Nothing 1 (Special 0) NoId
 
 -- | Send signal to a bus, crossfading with previous contents.
+--
+--  XOut [KR,AR] bus=0.0 xfade=0.0 *channelsArray=0.0;    MCE, FILTER: TRUE
 xOut :: UGen -> UGen -> UGen -> UGen
 xOut bus xfade input = mkUGen Nothing [KR,AR] (Right [2]) "XOut" [bus,xfade] (Just input) 0 (Special 0) NoId
 
 -- | Zero crossing frequency follower
+--
+--  ZeroCrossing [KR,AR] in=0.0;    FILTER: TRUE
 zeroCrossing :: UGen -> UGen
 zeroCrossing in_ = mkUGen Nothing [KR,AR] (Right [0]) "ZeroCrossing" [in_] Nothing 1 (Special 0) NoId
 
 -- | LocalBuf count
+--
+--  MaxLocalBufs [IR] count=0.0
 maxLocalBufs :: Rate -> UGen -> UGen
 maxLocalBufs rate count = mkUGen Nothing [IR] (Left rate) "MaxLocalBufs" [count] Nothing 1 (Special 0) NoId
 
 -- | Multiply add
+--
+--  MulAdd [IR,KR,AR] in=0.0 mul=0.0 add=0.0;    FILTER: TRUE
 mulAdd :: UGen -> UGen -> UGen -> UGen
 mulAdd in_ mul add = mkUGen Nothing [IR,KR,AR] (Right [0]) "MulAdd" [in_,mul,add] Nothing 1 (Special 0) NoId
 
 -- | Set local buffer
+--
+--  SetBuf [IR] buf=0.0 offset=0.0 length=0.0 *array=0.0;    MCE, REORDERS INPUTS: [0,1,2,3]
 setBuf :: UGen -> UGen -> UGen -> UGen -> UGen
 setBuf buf offset length_ array = mkUGen Nothing [IR] (Left IR) "SetBuf" [buf,offset,length_] (Just array) 1 (Special 0) NoId
diff --git a/Sound/SC3/UGen/Bindings/HW.hs b/Sound/SC3/UGen/Bindings/HW.hs
--- a/Sound/SC3/UGen/Bindings/HW.hs
+++ b/Sound/SC3/UGen/Bindings/HW.hs
@@ -1,48 +1,48 @@
 -- | Hand-written bindings.
 module Sound.SC3.UGen.Bindings.HW where
 
-import Sound.SC3.UGen.Bindings.HW.Construct
-import Sound.SC3.UGen.Identifier
+import qualified Sound.SC3.UGen.Bindings.HW.Construct as C
+import qualified Sound.SC3.UGen.Identifier as I
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
-import Sound.SC3.UGen.UGen
+import qualified Sound.SC3.UGen.UGen as U
 
 -- | Zero local buffer.
 --
 -- ClearBuf does not copy the buffer number through so this is an MRG node.
 clearBuf :: UGen -> UGen
-clearBuf b = mrg2 b (mkOsc IR "ClearBuf" [b] 1)
+clearBuf b = U.mrg2 b (C.mkOsc IR "ClearBuf" [b] 1)
 
 -- | Demand rate weighted random sequence generator.
-dwrand :: ID i => i -> UGen -> UGen -> UGen -> UGen
+dwrand :: I.ID i => i -> UGen -> UGen -> UGen -> UGen
 dwrand z repeats weights list_ =
-    let n = mceDegree list_
+    let n = mceDegree_err list_
         weights' = mceExtend n weights
         inp = repeats : constant n : weights'
-    in mkUGen Nothing [DR] (Left DR) "Dwrand" inp (Just list_) 1 (Special 0) (toUId z)
+    in mkUGen Nothing [DR] (Left DR) "Dwrand" inp (Just list_) 1 (Special 0) (U.toUId z)
 
 -- | Outputs signal for @FFT@ chains, without performing FFT.
 fftTrigger :: UGen -> UGen -> UGen -> UGen
-fftTrigger b h p = mkOsc KR "FFTTrigger" [b,h,p] 1
+fftTrigger b h p = C.mkOsc KR "FFTTrigger" [b,h,p] 1
 
 -- | 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 =
-    let n = constant (mceDegree mp)
-    in mkOscMCE KR "PackFFT" [b, sz, from, to, z, n] mp 1
+    let n = constant (mceDegree_err mp)
+    in C.mkOscMCE KR "PackFFT" [b, sz, from, to, z, n] mp 1
 
 -- | Poll value of input UGen when triggered.
 poll :: UGen -> UGen -> UGen -> UGen -> UGen
-poll t i l tr = mkFilter "Poll" ([t,i,tr] ++ unpackLabel l) 0
+poll t i l tr = C.mkFilter "Poll" ([t,i,tr] ++ U.unpackLabel l) 0
 
--- | Send a reply message from the server back to the all registered clients.
+-- | Send a reply message from the server back to all registered clients.
 sendReply :: UGen -> UGen -> String -> [UGen] -> UGen
 sendReply i k n v =
     let n' = map (fromIntegral . fromEnum) n
         s = fromIntegral (length n')
-    in mkFilter "SendReply" ([i,k,s] ++ n' ++ v) 0
+    in C.mkFilter "SendReply" ([i,k,s] ++ n' ++ v) 0
 
 -- | Unpack a single value (magnitude or phase) from an FFT chain
 unpack1FFT :: UGen -> UGen -> UGen -> UGen -> UGen
-unpack1FFT buf size index' which = mkOsc DR "Unpack1FFT" [buf, size, index', which] 1
+unpack1FFT buf size index' which = C.mkOsc DR "Unpack1FFT" [buf, size, index', which] 1
 
diff --git a/Sound/SC3/UGen/Bindings/HW/Construct.hs b/Sound/SC3/UGen/Bindings/HW/Construct.hs
--- a/Sound/SC3/UGen/Bindings/HW/Construct.hs
+++ b/Sound/SC3/UGen/Bindings/HW/Construct.hs
@@ -21,11 +21,11 @@
 
 -- | Rate restricted oscillator constructor, setting identifier.
 mkOscIdR :: [Rate] -> UGenId -> Rate -> String -> [UGen] -> Int -> UGen
-mkOscIdR rr z = mk_osc rr z
+mkOscIdR = mk_osc
 
 -- | Oscillator constructor, setting identifier.
 mkOscId :: UGenId -> Rate -> String -> [UGen] -> Int -> UGen
-mkOscId z = mk_osc all_rates z
+mkOscId = mk_osc all_rates
 
 -- | Provided 'UGenId' variant of 'mkOscMCE'.
 mk_osc_mce :: UGenId -> Rate -> String -> [UGen] -> UGen -> Int -> UGen
@@ -39,7 +39,7 @@
 
 -- | Variant oscillator constructor with MCE collapsing input.
 mkOscMCEId :: UGenId -> Rate -> String -> [UGen] -> UGen -> Int -> UGen
-mkOscMCEId z = mk_osc_mce z
+mkOscMCEId = mk_osc_mce
 
 -- | Rate constrained filter 'UGen' constructor.
 mk_filter :: [Rate] -> [Int] -> UGenId -> String -> [UGen] -> Int -> UGen
@@ -47,7 +47,7 @@
 
 -- | Filter UGen constructor.
 mkFilterIdR :: [Rate] -> UGenId -> String -> [UGen] -> Int -> UGen
-mkFilterIdR rs z nm i o = mk_filter rs [0 .. length i - 1] z nm i o
+mkFilterIdR rs z nm i = mk_filter rs [0 .. length i - 1] z nm i
 
 -- | Filter UGen constructor.
 mkFilterR :: [Rate] -> String -> [UGen] -> Int -> UGen
@@ -75,7 +75,7 @@
 
 -- | Variant filter constructor with MCE collapsing input.
 mkFilterMCEId :: UGenId -> String -> [UGen] -> UGen -> Int -> UGen
-mkFilterMCEId z = mk_filter_mce all_rates z
+mkFilterMCEId = mk_filter_mce all_rates
 
 -- | Information unit generators are very specialized.
 mkInfo :: String -> UGen
diff --git a/Sound/SC3/UGen/Bindings/HW/External.hs b/Sound/SC3/UGen/Bindings/HW/External.hs
--- a/Sound/SC3/UGen/Bindings/HW/External.hs
+++ b/Sound/SC3/UGen/Bindings/HW/External.hs
@@ -1,10 +1,6 @@
--- | Bindings to unit generators not distributed with SuperCollider
---   proper.
+-- | Bindings to unit generators not distributed with SuperCollider proper.
 module Sound.SC3.UGen.Bindings.HW.External (module U) where
 
-import Sound.SC3.UGen.Bindings.HW.External.ATS as U
 import Sound.SC3.UGen.Bindings.HW.External.F0 as U
-import Sound.SC3.UGen.Bindings.HW.External.ID as U
-import Sound.SC3.UGen.Bindings.HW.External.LPC as U
 import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins as U
 import Sound.SC3.UGen.Bindings.HW.External.Zita as U
diff --git a/Sound/SC3/UGen/Bindings/HW/External/ATS.hs b/Sound/SC3/UGen/Bindings/HW/External/ATS.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/Bindings/HW/External/ATS.hs
+++ /dev/null
@@ -1,107 +0,0 @@
--- | Reader for ATS analyis data files.
-module Sound.SC3.UGen.Bindings.HW.External.ATS (ATS(..)
-                                               ,ATSHeader(..)
-                                               ,ATSFrame,atsFrames
-                                               ,atsRead) where
-
-import qualified Data.ByteString.Lazy as B {- bytestring -}
-import Data.Int {- base -}
-import Data.List.Split {- split -}
-import Sound.OSC.Coding.Byte {- hosc -}
-
--- | ATS analysis data.
-data ATS = ATS { atsHeader :: ATSHeader
-               , atsData :: [Double] }
-           deriving (Eq, Show)
-
--- | ATS analysis meta-data.
-data ATSHeader = ATSHeader { atsSampleRate :: Double
-                           , atsFrameSize :: Int
-                           , atsWindowSize :: Int
-                           , atsNPartials :: Int
-                           , atsNFrames :: Int
-                           , atsMaxAmplitude :: Double
-                           , atsMaxFrequency :: Double
-                           , atsAnalysisDuration :: Double
-                           , atsFileType :: Int
-                           , atsFrameLength :: Int
-                           } deriving (Eq, Show)
-
--- | ATS analysis frame data.
-type ATSFrame = [Double]
-
-bSep :: Int64 -> Int64 -> B.ByteString -> [B.ByteString]
-bSep n i d =
-    if i == 1
-    then [d]
-    else let (p,q) = B.splitAt n d
-         in p : bSep n (i - 1) q
-
-atsParse :: FilePath -> IO [Double]
-atsParse fn = do
-  d <- B.readFile fn
-  let n = B.length d `div` 8
-      v = B.take 8 d
-      f = get_decoder v
-  return (map f (bSep 8 n d))
-
--- | Read an ATS data file.
-atsRead :: FilePath -> IO ATS
-atsRead fn = do
-  d <- atsParse fn
-  let f j = d !! j
-      g = floor . f
-      ft = g 9
-      (n, x) = ftype_n ft
-      np = g 4
-      nf = g 5
-      fl = np * n + x
-      hdr = ATSHeader (f 1) (g 2) (g 3) np nf (f 6) (f 7) (f 8) ft fl
-  return (ATS hdr d)
-
--- | Extract set of 'ATSFrame's from 'ATS'.
-atsFrames :: ATS -> [ATSFrame]
-atsFrames a = chunksOf (atsFrameLength (atsHeader a)) (atsData a)
-
--- Determine endianess and hence decoder.
-get_decoder :: B.ByteString -> B.ByteString -> Double
-get_decoder v =
-    if decode_f64 v == 123.0
-    then decode_f64
-    else decode_f64 . B.reverse
-
--- Calculate partial depth and frame constant.
-ftype_n :: Int -> (Int, Int)
-ftype_n n =
-    case n of
-      1 -> (2, 1)
-      2 -> (3, 1)
-      3 -> (2, 26)
-      4 -> (3, 26)
-      _ -> error "ftype_n"
-
-{-
--- | Analysis data in format required by the sc3 ATS UGens.
-atsSC3 :: ATS -> [Double]
-atsSC3 (ATS h d) =
-    let f = fromIntegral
-        td = transpose d
-    in f (atsFileType h) :
-       f (atsNPartials h) :
-       f (atsNFrames h) :
-       f (atsWindowSize h) :
-       concatMap (td !!) (atsSC3Indices h)
-
--- Indices for track data in the order required by sc3.
-atsSC3Indices :: ATSHeader -> [Int]
-atsSC3Indices h =
-    let np = atsNPartials h
-        o = 3 * (np - 1)
-        a = [1,4 .. (1 + o)]
-        f = map (+ 1) a
-        p = map (+ 1) f
-        n = map (+ (4+o)) [0..24]
-    in if atsFileType h == 4
-       then a ++ f ++ p ++ n
-       else error "atsSC3Indices: illegal ATS file type (/= 4)"
--}
diff --git a/Sound/SC3/UGen/Bindings/HW/External/ID.hs b/Sound/SC3/UGen/Bindings/HW/External/ID.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/Bindings/HW/External/ID.hs
+++ /dev/null
@@ -1,22 +0,0 @@
--- | Non-deterministic external 'UGen's.
-module Sound.SC3.UGen.Bindings.HW.External.ID where
-
-import Sound.SC3.UGen.Bindings.HW.Construct
-import Sound.SC3.UGen.Identifier
-import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.Type
-import Sound.SC3.UGen.UGen
-
--- * SC3plugins/BhobUGens
-
--- | random walk step
-lfBrownNoise0 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen
-lfBrownNoise0 z r freq dev dist = mkOscIdR [AR,KR] (toUId z) r "LFBrownNoise0" [freq,dev,dist] 1
-
--- | random walk linear interp
-lfBrownNoise1 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen
-lfBrownNoise1 z r freq dev dist = mkOscIdR [AR,KR] (toUId z) r "LFBrownNoise1" [freq,dev,dist] 1
-
--- | random walk cubic interp
-lfBrownNoise2 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen
-lfBrownNoise2 z r freq dev dist = mkOscIdR [AR,KR] (toUId z) r "LFBrownNoise2" [freq,dev,dist] 1
diff --git a/Sound/SC3/UGen/Bindings/HW/External/LPC.hs b/Sound/SC3/UGen/Bindings/HW/External/LPC.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/Bindings/HW/External/LPC.hs
+++ /dev/null
@@ -1,63 +0,0 @@
--- | Reader for LPC analysis data files.
-module Sound.SC3.UGen.Bindings.HW.External.LPC ( LPC(..)
-                                               , LPCHeader(..)
-                                               , LPCFrame
-                                               , lpcRead
-                                               , lpcSC3 ) where
-
-import Control.Monad {- base -}
-import qualified Data.ByteString.Lazy as B {- bytestring -}
-import Data.List {- base -}
-import System.IO {- base -}
-
-import Sound.OSC.Coding.Byte {- hosc -}
-
--- | LPC analysis data.
-data LPC = LPC { lpcHeader :: LPCHeader
-               , lpcFrames :: [LPCFrame] }
-           deriving (Eq, Show)
-
--- | LPC analysis meta-data.
-data LPCHeader = LPCHeader { lpcHeaderSize :: Int
-                           , lpcMagic :: Int
-                           , lpcNPoles :: Int
-                           , lpcFrameSize :: Int
-                           , lpcFrameRate :: Float
-                           , lpcSampleRate :: Float
-                           , lpcAnalysisDuration :: Float
-                           , lpcNFrames :: Int
-                           } deriving (Eq, Show)
-
--- | LPC analysis frame data.
-type LPCFrame = [Float]
-
--- | Read an lpanal format LPC data file.
-lpcRead :: FilePath -> IO LPC
-lpcRead fn = do
-  h <- openFile fn ReadMode
-  l <- hFileSize h
-  [hs, lm, np, fs] <- replicateM 4 (read_i32 h)
-  [fr, sr, fd] <- replicateM 3 (read_f32 h)
-  let nf = ((fromIntegral l - hs) `div` 4) `div` fs
-      hdr = LPCHeader hs lm np fs fr sr fd nf
-      hc = hs - (7 * 4)
-      get_f = replicateM fs (read_f32 h)
-  _ <- B.hGet h hc
-  d <- replicateM nf get_f
-  hClose h
-  return (LPC hdr d)
-
--- | Analysis data in format required by the sc3 LPC UGens.
-lpcSC3 :: LPC -> [Float]
-lpcSC3 (LPC h d) = let f = fromIntegral
-                       np = f (lpcNPoles h)
-                       nf = f (lpcNFrames h)
-                       fs = f (lpcFrameSize h)
-                   in np : nf : fs : concat (transpose d)
-
-read_i32 :: Handle -> IO Int
-read_i32 h = liftM decode_i32 (B.hGet h 4)
-
-read_f32 :: Handle -> IO Float
-read_f32 h = liftM decode_f32 (B.hGet h 4)
-
diff --git a/Sound/SC3/UGen/Bindings/HW/External/SC3_Plugins.hs b/Sound/SC3/UGen/Bindings/HW/External/SC3_Plugins.hs
--- a/Sound/SC3/UGen/Bindings/HW/External/SC3_Plugins.hs
+++ b/Sound/SC3/UGen/Bindings/HW/External/SC3_Plugins.hs
@@ -73,6 +73,18 @@
 gaussTrig :: Rate -> UGen -> UGen -> UGen
 gaussTrig rate freq dev = mkOscR [AR,KR] rate "GaussTrig" [freq,dev] 1
 
+-- | random walk step
+lfBrownNoise0 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen
+lfBrownNoise0 z r freq dev dist = mkOscIdR [AR,KR] (toUId z) r "LFBrownNoise0" [freq,dev,dist] 1
+
+-- | random walk linear interp
+lfBrownNoise1 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen
+lfBrownNoise1 z r freq dev dist = mkOscIdR [AR,KR] (toUId z) r "LFBrownNoise1" [freq,dev,dist] 1
+
+-- | random walk cubic interp
+lfBrownNoise2 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen
+lfBrownNoise2 z r freq dev dist = mkOscIdR [AR,KR] (toUId z) r "LFBrownNoise2" [freq,dev,dist] 1
+
 -- | String resonance filter
 streson :: UGen -> UGen -> UGen -> UGen
 streson input delayTime res = mkFilter "Streson" [input,delayTime,res] 1
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,18 +1,20 @@
 -- | Data types for enumerated and non signal unit generator inputs.
 module Sound.SC3.UGen.Enum where
 
-import Sound.SC3.Common
-import qualified Sound.SC3.UGen.Envelope.Interpolate as I
+import qualified Sound.SC3.Common.Envelope as E
 import Sound.SC3.UGen.Type
 
 -- | Loop indicator input.
-data Loop = Loop
-          | NoLoop
-          | WithLoop UGen
-            deriving (Eq, Show)
+data Loop' t = Loop
+             | NoLoop
+             | WithLoop t
+               deriving (Eq, Show)
 
--- | Resolve 'Loop'.
-from_loop :: Loop -> UGen
+-- | Type-specialised 'Loop''.
+type Loop = Loop' UGen
+
+-- | Resolve 'Loop''.
+from_loop :: Num t => Loop' t -> t
 from_loop e =
     case e of
       NoLoop -> 0
@@ -67,69 +69,8 @@
       Exponential -> 1
       Warp u -> u
 
--- | Envelope curve indicator input.
-data Envelope_Curve a = EnvStep
-                      | EnvLin
-                      | EnvExp
-                      | EnvSin
-                      | EnvWelch -- ^ Note: not implemented at SC3
-                      | EnvNum a
-                      | EnvSqr
-                      | EnvCub
-                      | EnvHold
-                        deriving (Eq, Show)
-
--- | Envelope curve pair.
-type Envelope_Curve2 a = T2 (Envelope_Curve a)
-
--- | Envelope curve triple.
-type Envelope_Curve3 a = T3 (Envelope_Curve a)
-
--- | Envelope curve triple.
-type Envelope_Curve4 a = T4 (Envelope_Curve a)
-
 -- | Type specialised ('UGen') envelope curve.
-type EnvCurve = Envelope_Curve UGen
-
--- | Convert 'Envelope_Curve' to shape value.
---
--- > map env_curve_shape [EnvSin,EnvSqr] == [3,6]
-env_curve_shape :: Num a => Envelope_Curve a -> a
-env_curve_shape e =
-    case e of
-      EnvStep -> 0
-      EnvLin -> 1
-      EnvExp -> 2
-      EnvSin -> 3
-      EnvWelch -> 4
-      EnvNum _ -> 5
-      EnvSqr -> 6
-      EnvCub -> 7
-      EnvHold -> 8
-
--- | The /value/ of 'EnvCurve' is non-zero for 'EnvNum'.
---
--- > map env_curve_value [EnvWelch,EnvNum 2] == [0,2]
-env_curve_value :: Num a => Envelope_Curve a -> a
-env_curve_value e =
-    case e of
-      EnvNum u -> u
-      _ -> 0
-
--- | 'Interpolation_F' of 'Envelope_Curve'.
-env_curve_interpolation_f :: (Ord t, Floating t) =>
-                             Envelope_Curve t -> I.Interpolation_F t
-env_curve_interpolation_f c =
-    case c of
-      EnvStep -> I.step
-      EnvLin -> I.linear
-      EnvExp -> I.exponential
-      EnvSin -> I.sine
-      EnvWelch -> I.welch
-      EnvNum n -> I.curve n
-      EnvSqr -> I.squared
-      EnvCub -> I.cubed
-      EnvHold -> undefined
+type EnvCurve = E.Envelope_Curve UGen
 
 -- | Unification of integer and 'UGen' buffer identifiers.
 data Buffer = Buffer_Id Int
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,223 +1,39 @@
--- | Envelope generators.
+-- | Envelope / UGen.
 module Sound.SC3.UGen.Envelope where
 
-import Data.List
-import Data.Maybe
+import Sound.SC3.Common.Envelope
+
+import Sound.SC3.UGen.Bindings
+import Sound.SC3.UGen.Math
 import Sound.SC3.UGen.Enum
+import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
-
--- * Envelope
-
--- | SC3 envelope segment model
-data Envelope a =
-    Envelope {env_levels :: [a] -- ^ Set of /n/ levels, n is >= 1
-             ,env_times :: [a] -- ^ Set of /n-1/ time intervals
-             ,env_curves :: [Envelope_Curve a] -- ^ Possibly empty curve set
-             ,env_release_node :: Maybe Int -- ^ Maybe index to release node
-             ,env_loop_node :: Maybe Int -- ^ Maybe index to loop node
-             }
-    deriving (Eq,Show)
-
--- | Variant without release and loop node inputs (defaulting to nil).
-envelope :: [a] -> [a] -> [Envelope_Curve a] -> Envelope a
-envelope l t c = Envelope l t c Nothing Nothing
-
--- | Duration of 'Envelope', ie. 'sum' '.' 'env_times'.
-envelope_duration :: Num n => Envelope n -> n
-envelope_duration = sum . env_times
-
--- | Number of segments at 'Envelope', ie. 'length' '.' 'env_times'.
-envelope_n_segments :: (Num n,Integral i) => Envelope n -> i
-envelope_n_segments = genericLength . env_times
-
--- | Determine which envelope segment a given time /t/ falls in.
-envelope_segment_ix :: (Ord a, Num a) => Envelope a -> a -> Maybe Int
-envelope_segment_ix e t =
-    let d = dx_d (env_times e)
-    in findIndex (>= t) d
-
--- | A set of start time, start level, end time, end level and curve.
-type Envelope_Segment t = (t,t,t,t,Envelope_Curve t)
-
--- | Extract envelope segment given at index /i/.
-envelope_segment :: Num t => Envelope t -> Int -> Envelope_Segment t
-envelope_segment e i =
-    let l = env_levels e
-        t = env_times e
-        x0 = l !! i
-        x1 = l !! (i + 1)
-        t0 = (0 : dx_d t) !! i
-        t1 = t0 + t !! i
-        c = envelope_curves e !! i
-    in (t0,x0,t1,x1,c)
-
--- | Extract all segments.
-envelope_segments :: Num t => Envelope t -> [Envelope_Segment t]
-envelope_segments e =
-    let n = envelope_n_segments e
-    in map (envelope_segment e) [0 .. n - 1]
-
--- | Transform list of 'Envelope_Segment's into lists ('env_levels','env_times','env_curves').
-pack_envelope_segments :: Num t => [Envelope_Segment t] -> ([t],[t],[Envelope_Curve t])
-pack_envelope_segments s =
-    case s of
-      [] -> error ""
-      [(t0,l0,t1,l1,c)] -> ([l0,l1],[t1 - t0],[c])
-      (_,l0,_,_,_) : _ ->
-          let t (t0,_,t1,_,_) = t1 - t0
-              c (_,_,_,_,x) = x
-              l (_,_,_,x,_) = x
-          in (l0 : map l s,map t s,map c s)
-
--- | An envelope is /normal/ if it has no segments with zero duration.
-envelope_is_normal :: (Eq n,Num n) => Envelope n -> Bool
-envelope_is_normal = null . filter (== 0) . env_times
-
--- | Normalise envelope by deleting segments of zero duration.
-envelope_normalise :: (Num a, Ord a) => Envelope a -> Envelope a
-envelope_normalise e =
-    let s = envelope_segments e
-        f (t0,_,t1,_,_) = t1 <= t0
-        s' = filter (not . f) s
-        (l,t,c) = pack_envelope_segments s'
-    in case e of
-         Envelope _ _ _ Nothing Nothing -> Envelope l t c Nothing Nothing
-         _ -> error "envelope_normalise: has release or loop node..."
-
--- | Get value for 'Envelope' at time /t/, or zero if /t/ is out of
--- range.  By convention if the envelope has a segment of zero
--- duration we give the rightmost value.
-envelope_at :: (Ord t, Floating t) => Envelope t -> t -> t
-envelope_at e t =
-    case envelope_segment_ix e t of
-      Just n -> let (t0,x0,t1,x1,c) = envelope_segment e n
-                    d = t1 - t0
-                    t' = (t - t0) / d
-                    f = env_curve_interpolation_f c
-                in if d <= 0
-                   then x1
-                   else f x0 x1 t'
-      Nothing -> 0
-
--- | Render 'Envelope' to breakpoint set of /n/ equi-distant places.
-envelope_render :: (Ord t, Floating t, Enum t) => t -> Envelope t -> [(t,t)]
-envelope_render n e =
-    let d = envelope_duration e
-        k = d / (n - 1)
-        t = [0,k .. d]
-    in zip t (map (envelope_at e) t)
-
--- | Contruct a lookup table of /n/ places from 'Envelope'.
-envelope_table :: (Ord t, Floating t, Enum t) => t -> Envelope t -> [t]
-envelope_table n = map snd . envelope_render n
-
--- | Variant on 'env_curves' that expands the, possibly empty, user
--- list by cycling (if not empty) or by filling with 'EnvLin'.
-envelope_curves :: Num a => Envelope a -> [Envelope_Curve a]
-envelope_curves e =
-    let c = env_curves e
-        n = envelope_n_segments e
-    in if null c
-       then replicate n EnvLin
-       else take n (cycle c)
-
--- | Linear SC3 form of 'Envelope' data.
---
--- Form is: l0 #t reset loop l1 t0 c0 c0' ...
---
--- > let {l = [0,0.6,0.3,1.0,0]
--- >     ;t = [0.1,0.02,0.4,1.1]
--- >     ;c = [EnvLin,EnvExp,EnvNum (-6),EnvSin]
--- >     ;e = Envelope l t c Nothing Nothing
--- >     ;r = [0,4,-99,-99,0.6,0.1,1,0,0.3,0.02,2,0,1,0.4,5,-6,0,1.1,3,0]}
--- > in envelope_sc3_array e == Just r
-envelope_sc3_array :: Num a => Envelope a -> Maybe [a]
-envelope_sc3_array e =
-    let Envelope l t _ rn ln = e
-        n = length t
-        n' = fromIntegral n
-        rn' = fromIntegral (fromMaybe (-99) rn)
-        ln' = fromIntegral (fromMaybe (-99) ln)
-        c = envelope_curves e
-        f i j k = [i,j,env_curve_shape k,env_curve_value k]
-    in case l of
-         l0:l' -> Just (l0 : n' : rn' : ln' : concat (zipWith3 f l' t c))
-         _ -> Nothing
-
--- | @IEnvGen@ SC3 form of 'Envelope' data.  Offset not supported (zero).
---
--- > let {l = [0,0.6,0.3,1.0,0]
--- >     ;t = [0.1,0.02,0.4,1.1]
--- >     ;c = [EnvLin,EnvExp,EnvNum (-6),EnvSin]
--- >     ;e = Envelope l t c Nothing Nothing
--- >     ;r = [0,0,4,1.62,0.1,1,0,0.6,0.02,2,0,0.3,0.4,5,-6,1,1.1,3,0,0]}
--- > in envelope_sc3_ienvgen_array e == Just r
-envelope_sc3_ienvgen_array :: Num a => Envelope a -> Maybe [a]
-envelope_sc3_ienvgen_array e =
-    let Envelope l t _ _ _ = e
-        n = length t
-        n' = fromIntegral n
-        c = envelope_curves e
-        f i j k = [j,env_curve_shape k,env_curve_value k,i]
-    in case l of
-         l0:l' -> Just (0 : l0 : n' : sum t : concat (zipWith3 f l' t c))
-         _ -> Nothing
-
--- | 'True' if 'env_release_node' is not 'Nothing'.
-env_is_sustained :: Envelope a -> Bool
-env_is_sustained = isJust . env_release_node
-
--- | Delay the onset of the envelope.
-env_delay :: Envelope a -> a -> Envelope a
-env_delay (Envelope l t c rn ln) d =
-    let (l0:_) = l
-        l' = l0 : l
-        t' = d : t
-        c' = EnvLin : c
-        rn' = fmap (+ 1) rn
-        ln' = fmap (+ 1) ln
-    in Envelope l' t' c' rn' ln'
-
--- | Connect releaseNode (or end) to first node of envelope.
-env_circle :: (Num a,Fractional a) => Envelope a -> a -> Envelope_Curve a -> Envelope a
-env_circle (Envelope l t c rn _) tc cc =
-    let z = 1 {- 1 - impulse KR 0 0 -}
-        n = length t
-    in case rn of
-         Nothing -> let l' = 0 : l ++ [0]
-                        t' = z * tc : t ++ [9e8]
-                        c' = cc : take n (cycle c) ++ [EnvLin]
-                        rn' = Just (n + 1)
-                    in Envelope l' t' c' rn' (Just 0)
-         Just i -> let l' = 0 : l
-                       t' = z * tc : t
-                       c' = cc : take n (cycle c)
-                       rn' = Just (i + 1)
-                   in  Envelope l' t' c' rn' (Just 0)
-
--- * UGen
-
-envelope_to_ugen :: Envelope UGen -> UGen
-envelope_to_ugen =
-    let err = error "envGen: bad Envelope"
-    in mce . fromMaybe err . envelope_sc3_array
+import Sound.SC3.UGen.UGen
 
--- * List
+{- | Trapezoidal envelope generator.
 
--- > d_dx [0,1,3,6] == [0,1,2,3]
-d_dx :: (Num a) => [a] -> [a]
-d_dx l = zipWith (-) l (0:l)
+> import Sound.SC3.Plot
+> plotEnvelope [envTrapezoid 0.99 0.5 1 1,envTrapezoid 0.5 0.75 0.65 0.35]
 
--- > dx_d (d_dx [0,1,3,6]) == [0,1,3,6]
--- > dx_d [0.5,0.5] == [0.5,1]
-dx_d :: Num n => [n] -> [n]
-dx_d = scanl1 (+)
+-}
+envTrapezoid :: OrdE t => t -> t -> t -> t -> Envelope t
+envTrapezoid = envTrapezoid_f ((<=*),(>=*))
 
--- > d_dx' [0,1,3,6] == [1,2,3]
-d_dx' :: Num n => [n] -> [n]
-d_dx' l = zipWith (-) (tail l) l
+-- | Singleton fade envelope.
+envGate :: UGen -> UGen -> UGen -> DoneAction -> Envelope_Curve UGen -> UGen
+envGate level gate_ fadeTime doneAction curve =
+    let startVal = fadeTime <=* 0
+        e = Envelope [startVal,1,0] [1,1] [curve] (Just 1) Nothing
+    in envGen KR gate_ level 0 fadeTime doneAction e
 
--- > dx_d' (d_dx' [0,1,3,6]) == [0,1,3,6]
--- > dx_d' [0.5,0.5] == [0,0.5,1]
-dx_d' :: Num n => [n] -> [n]
-dx_d' = (0 :) . scanl1 (+)
+-- | Variant with default values for all inputs.  @gate@ and
+-- @fadeTime@ are 'control's, @doneAction@ is 'RemoveSynth', @curve@
+-- is 'EnvSin'.
+envGate' :: UGen
+envGate' =
+    let level = 1
+        gate_ = meta_control KR "gate" 1 (0,1,"lin",1,"")
+        fadeTime = meta_control KR "fadeTime" 0.02 (0,10,"lin",0,"s")
+        doneAction = RemoveSynth
+        curve = EnvSin
+    in envGate level gate_ fadeTime doneAction curve
diff --git a/Sound/SC3/UGen/Envelope/Construct.hs b/Sound/SC3/UGen/Envelope/Construct.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/Envelope/Construct.hs
+++ /dev/null
@@ -1,197 +0,0 @@
--- | Functions to generate break point data for standard envelope
---   types.
-module Sound.SC3.UGen.Envelope.Construct where
-
-import Sound.SC3.UGen.Bindings
-import Sound.SC3.UGen.Math
-import Sound.SC3.UGen.Enum
-import Sound.SC3.UGen.Envelope
-import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.Type
-import Sound.SC3.UGen.UGen
-
--- | Co-ordinate based static envelope generator.
---
--- > let e = envCoord [(0,0),(1/4,1),(1,0)] 1 1 EnvLin
--- > in envelope_sc3_array e == Just [0,2,-99,-99,1,1/4,1,0,0,3/4,1,0]
-envCoord :: Num a => [(a,a)] -> a -> a -> Envelope_Curve a -> Envelope a
-envCoord bp dur amp c =
-    let l = map ((* amp) . snd) bp
-        t = map (* dur) (tail (d_dx (map fst bp)))
-    in Envelope l t [c] Nothing Nothing
-
--- | 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 :: (Num a,OrdE a) => a -> a -> a -> a -> Envelope a
-envTrapezoid shape skew dur amp =
-    let x1 = skew * (1 - shape)
-        bp = [(0,skew <=* 0)
-             ,(x1,1)
-             ,(shape + x1,1)
-             ,(1,skew >=* 1)]
-    in envCoord bp dur amp EnvLin
-
--- | Variant 'envPerc' with user specified 'Envelope_Curve a'.
-envPerc' :: Num a => a -> a -> a -> Envelope_Curve2 a -> Envelope a
-envPerc' atk rls lvl (c0,c1) =
-    let c = [c0,c1]
-    in Envelope [0,lvl,0] [atk,rls] c Nothing Nothing
-
--- | Percussive envelope, with attack, release, level and curve
---   inputs.
-envPerc :: Num a => a -> a -> Envelope a
-envPerc atk rls =
-    let cn = EnvNum (-4)
-    in envPerc' atk rls 1 (cn,cn)
-
--- | Triangular envelope, with duration and level inputs.
---
--- > let e = envTriangle 1 0.1
--- > in envelope_sc3_array e = Just [0,2,-99,-99,0.1,0.5,1,0,0,0.5,1,0]
-envTriangle :: (Num a,Fractional a) => a -> a -> Envelope a
-envTriangle dur lvl =
-    let c = replicate 2 EnvLin
-        d = replicate 2 (dur / 2)
-    in Envelope [0,lvl,0] d c Nothing Nothing
-
--- | Sine envelope, with duration and level inputs.
---
--- > let e = envSine 0 0.1
--- > in envelope_sc3_array e == Just [0,2,-99,-99,0.1,0,3.0,0,0,0,3,0]
-envSine :: (Num a,Fractional a) => a -> a -> Envelope a
-envSine dur lvl =
-    let c = replicate 2 EnvSin
-        d = replicate 2 (dur / 2)
-    in Envelope [0,lvl,0] d c Nothing Nothing
-
--- | Parameters for LINEN envelopes.
-data LINEN a = LINEN {linen_attackTime :: a
-                     ,linen_sustainTime :: a
-                     ,linen_releaseTime :: a
-                     ,linen_level :: a
-                     ,linen_curve :: Envelope_Curve3 a}
-
--- | Record ('LINEN') variant of 'envLinen'.
-envLinen_r :: Num a => LINEN a -> Envelope a
-envLinen_r (LINEN aT sT rT lv (c0,c1,c2)) =
-    let l = [0,lv,lv,0]
-        t = [aT,sT,rT]
-        c = [c0,c1,c2]
-    in Envelope l t c Nothing Nothing
-
--- | Variant of 'envLinen' with user specified 'Envelope_Curve a'.
-envLinen' :: Num a => a -> a -> a -> a -> Envelope_Curve3 a -> Envelope a
-envLinen' aT sT rT lv c = envLinen_r (LINEN aT sT rT lv c)
-
--- | Linear envelope parameter constructor.
---
--- > let {e = envLinen 0 1 0 1
--- >     ;s = envelope_segments e
--- >     ;p = pack_envelope_segments s}
--- > in p == (env_levels e,env_times e,env_curves e)
-envLinen :: Num a => a -> a -> a -> a -> Envelope a
-envLinen aT sT rT l =
-    let c = (EnvLin,EnvLin,EnvLin)
-    in envLinen' aT sT rT l c
-
--- | Parameters for ADSR envelopes.  The sustain level is given as a proportion of the peak level.
-data ADSR a = ADSR {adsr_attackTime :: a
-                   ,adsr_decayTime :: a
-                   ,adsr_sustainLevel :: a
-                   ,adsr_releaseTime :: a
-                   ,adsr_peakLevel :: a
-                   ,adsr_curve :: Envelope_Curve3 a
-                   ,adsr_bias :: a}
-
-adsrDefault :: Fractional n => ADSR n
-adsrDefault =
-    let c = EnvNum (-4)
-    in ADSR 0.01 0.3 0.5 1 1 (c,c,c) 0
-
--- | Attack, decay, sustain, release envelope parameter constructor.
-envADSR :: Num a => a -> a -> a -> a -> a -> Envelope_Curve a -> a -> Envelope a
-envADSR aT dT sL rT pL c b = envADSR_r (ADSR aT dT sL rT pL (c,c,c) b)
-
--- | Record ('ADSR') variant of 'envADSR'.
-envADSR_r :: Num a => ADSR a -> Envelope a
-envADSR_r (ADSR aT dT sL rT pL (c0,c1,c2) b) =
-    let l = map (+ b) [0,pL,pL*sL,0]
-        t = [aT,dT,rT]
-        c = [c0,c1,c2]
-    in Envelope l t c (Just 2) Nothing
-
--- | Parameters for Roland type ADSSR envelopes.
-data ADSSR a = ADSSR {adssr_attackTime :: a
-                     ,adssr_attackLevel :: a
-                     ,adssr_decayTime :: a
-                     ,adssr_decayLevel :: a
-                     ,adssr_slopeTime :: a
-                     ,adssr_sustainLevel :: a
-                     ,adssr_releaseTime :: a
-                     ,adssr_curve :: Envelope_Curve4 a
-                     ,adssr_bias :: a}
-
--- | Attack, decay, slope, sustain, release envelope parameter constructor.
-envADSSR :: Num a => a -> a -> a -> a -> a -> a -> a -> Envelope_Curve a -> a -> Envelope a
-envADSSR t1 l1 t2 l2 t3 l3 t4 c b = envADSSR_r (ADSSR t1 l1 t2 l2 t3 l3 t4 (c,c,c,c) b)
-
--- | Record ('ADSSR') variant of 'envADSSR'.
-envADSSR_r :: Num a => ADSSR a -> Envelope a
-envADSSR_r (ADSSR t1 l1 t2 l2 t3 l3 t4 (c1,c2,c3,c4) b) =
-    let l = map (+ b) [0,l1,l2,l3,0]
-        t = [t1,t2,t3,t4]
-        c = [c1,c2,c3,c4]
-    in Envelope l t c (Just 3) Nothing
-
--- | Parameters for ASR envelopes.
-data ASR a = ASR {asr_attackTime :: a
-                 ,asr_sustainLevel :: a
-                 ,asr_releaseTime :: a
-                 ,asr_curve :: Envelope_Curve2 a}
-
--- | Attack, sustain, release envelope parameter constructor.
---
--- > let {c = 3
--- >     ;r = Just [0,2,1,-99,0.1,3,c,0,0,2,c,0]}
--- > in envelope_sc3_array (envASR 3 0.1 2 EnvSin) == r
-envASR :: Num a => a -> a -> a -> Envelope_Curve a -> Envelope a
-envASR aT sL rT c = envASR_r (ASR aT sL rT (c,c))
-
--- | Record ('ASR') variant of 'envASR'.
-envASR_r :: Num a => ASR a -> Envelope a
-envASR_r (ASR aT sL rT (c0,c1)) =
-    let l = [0,sL,0]
-        t = [aT,rT]
-        c' = [c0,c1]
-    in Envelope l t c' (Just 1) Nothing
-
--- | All segments are horizontal lines.
-envStep :: [a] -> [a] -> Maybe Int -> Maybe Int -> Envelope a
-envStep levels times releaseNode loopNode =
-    if length levels /= length times
-    then error ("envStep: levels and times must have same size")
-    else let levels' = head levels : levels
-         in Envelope levels' times [EnvStep] releaseNode loopNode
-
--- | Singleton fade envelope.
-envGate :: UGen -> UGen -> UGen -> DoneAction -> Envelope_Curve UGen -> UGen
-envGate level gate_ fadeTime doneAction curve =
-    let startVal = fadeTime <=* 0
-        e = Envelope [startVal,1,0] [1,1] [curve] (Just 1) Nothing
-    in envGen KR gate_ level 0 fadeTime doneAction e
-
--- | Variant with default values for all inputs.  @gate@ and
--- @fadeTime@ are 'control's, @doneAction@ is 'RemoveSynth', @curve@
--- is 'EnvSin'.
-envGate' :: UGen
-envGate' =
-    let level = 1
-        gate_ = meta_control KR "gate" 1 (0,1,"lin",1,"")
-        fadeTime = meta_control KR "fadeTime" 0.02 (0,10,"lin",0,"s")
-        doneAction = RemoveSynth
-        curve = EnvSin
-    in envGate level gate_ fadeTime doneAction curve
diff --git a/Sound/SC3/UGen/Envelope/Interpolate.hs b/Sound/SC3/UGen/Envelope/Interpolate.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/Envelope/Interpolate.hs
+++ /dev/null
@@ -1,100 +0,0 @@
--- | Interpolation functions for envelope segments.
-module Sound.SC3.UGen.Envelope.Interpolate where
-
--- | An interpolation function take three arguments. /x0/ is the left
--- or begin value, /x1/ is the right or end value, and /t/ is a (0,1)
--- index.
-type Interpolation_F t = t -> t -> t -> t
-
--- | Step function, ignores /t/ and returns /x1/.
-step :: Interpolation_F t
-step _ x1 _ = x1
-
--- | Linear interpolation.
-linear :: Num t => Interpolation_F t
-linear x0 x1 t = t * (x1 - x0) + x0
-
--- | Exponential interpolation, /x0/ must not be @0@, (/x0/,/x1/) must
--- not span @0@.
---
--- > import Sound.SC3.Plot
--- > plotTable1 (map (exponential 0.001 1) [0,0.01 .. 1])
-exponential :: Floating t => Interpolation_F t
-exponential x0 x1 t = x0 * ((x1 / x0) ** t)
-
--- | Variant that allows /x0/ to be @0@, though (/x0/,/x1/) must not
--- span @0@.
---
--- > plotTable1 (map (exponential' 0 1) [0,0.01 .. 1])
--- > plotTable1 (map (exponential' 0 (-1)) [0,0.01 .. 1])
-exponential' :: (Eq t,Floating t) => Interpolation_F t
-exponential' x0 x1 =
-    let epsilon = 1e-6
-        x0' = if x0 == 0 then epsilon * signum x1 else x0
-    in exponential x0' x1
-
--- | 'linear' of 'exponential'', ie. allows (/x0/,/x1/) to span @0@.
---
--- > plotTable1 (map (exponential'' (-1) 1) [0,0.01 .. 1])
-exponential'' :: (Eq t,Floating t) => Interpolation_F t
-exponential'' x0 x1 t = linear x0 x1 (exponential' 0 1 t)
-
--- | 'linear' with /t/ transformed by sine function over (-pi/2,pi/2).
---
--- > plotTable1 (map (sine (-1) 1) [0,0.01 .. 1])
-sine :: Floating t => Interpolation_F t
-sine x0 x1 t =
-    let t' = - cos (pi * t) * 0.5 + 0.5
-    in linear x0 x1 t'
-
-half_pi :: Floating a => a
-half_pi = pi / 2
-
--- | If /x0/ '<' /x1/ rising sine segment (0,pi/2), else falling
--- segment (pi/2,pi).
---
--- > plotTable1 (map (welch (-1) 1) [0,0.01 .. 1])
--- > plotTable1 (map (welch 1 (-1)) [0,0.01 .. 1])
-welch :: (Ord t, Floating t) => Interpolation_F t
-welch x0 x1 t =
-    if x0 < x1
-    then x0 + (x1 - x0) * sin (half_pi * t)
-    else x1 - (x1 - x0) * sin (half_pi - (half_pi * t))
-
--- | Curvature controlled by single parameter /c/.  @0@ is 'linear',
--- increasing /c/ approaches 'exponential'.
---
--- > plotTable1 (map (curve 0 (-1) 1) [0,0.01 .. 1])
--- > plotTable1 (map (curve 9 (-1) 1) [0,0.01 .. 1])
-curve :: (Ord t, Floating t) => t -> Interpolation_F t
-curve c x0 x1 t =
-    if abs c < 0.0001
-    then t * (x1 - x0) + x0
-    else let d = 1 - exp c
-             n = 1 - exp (t * c)
-         in x0 + (x1 - x0) * (n/d)
-
--- | Square of 'linear' of 'sqrt' of /x0/ and /x1/, threfore neither
--- may be negative.
---
--- > plotTable1 (map (squared 0 1) [0,0.01 .. 1])
-squared :: Floating t => Interpolation_F t
-squared x0 x1 t =
-    let x0' = sqrt x0
-        x1' = sqrt x1
-        l = linear x0' x1' t
-    in l * l
-
--- | Cubic variant of 'squared'.
---
--- > plotTable1 (map (cubed 0 1) [0,0.01 .. 1])
-cubed :: Floating t => Interpolation_F t
-cubed x0 x1 t =
-    let x0' = x0 ** (1/3)
-        x1' = x1 ** (1/3)
-        l = linear x0' x1' t
-    in l * l * l
-
--- | x0 until end, then immediately x1.
-hold :: (Num t,Eq t) => Interpolation_F t
-hold x0 x1 t = if t == 1 then x1 else x0
diff --git a/Sound/SC3/UGen/Graph.hs b/Sound/SC3/UGen/Graph.hs
--- a/Sound/SC3/UGen/Graph.hs
+++ b/Sound/SC3/UGen/Graph.hs
@@ -6,6 +6,7 @@
 import Data.List{- base -}
 import Data.Maybe{- base -}
 
+import qualified Sound.SC3.UGen.Analysis as A
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
 import Sound.SC3.UGen.UGen
@@ -71,6 +72,15 @@
           k == k' && rt == rt' && ix == ix' && nm == nm' && df == df' && tr == tr' && me == me'
       _ -> error "node_k_eq? not Node_K"
 
+-- | 'Rate' of 'Node', ie. 'IR' for constants, & see through 'NodeP'.
+node_rate :: Node -> Rate
+node_rate n =
+    case n of
+      NodeC {} -> IR
+      NodeK {} -> node_k_rate n
+      NodeU {} -> node_u_rate n
+      NodeP _ n' _ -> node_rate n'
+
 -- * Building
 
 -- | Find 'Node' with indicated 'NodeId'.
@@ -277,7 +287,7 @@
 -- | If controls have been given indices they must be coherent.
 sort_controls :: [Node] -> [Node]
 sort_controls c =
-    let node_k_ix n = maybe maxBound id (node_k_index n)
+    let node_k_ix n = fromMaybe maxBound (node_k_index n)
         cmp = compare `on` node_k_ix
         c' = sortBy cmp c
         coheres z = maybe True (== z) . node_k_index
@@ -338,15 +348,15 @@
 -- index but the index in relation to controls of the same type.
 fetch_k :: NodeId -> KType -> [Node] -> Int
 fetch_k z t =
-    let rec i ns =
+    let recur i ns =
             case ns of
               [] -> error "fetch_k"
               n:ns' -> if z == node_id n
                        then i
                        else if t == node_k_type n
-                            then rec (i + 1) ns'
-                            else rec i ns'
-    in rec 0
+                            then recur (i + 1) ns'
+                            else recur i ns'
+    in recur 0
 
 -- * Implicit (Control, MaxLocalBuf)
 
@@ -356,7 +366,7 @@
 -- | Count the number of /controls/ of each 'KType'.
 ks_count :: [Node] -> KS_COUNT
 ks_count =
-    let rec r ns =
+    let recur r ns =
             let (i,k,t,a) = r
             in case ns of
                  [] -> r
@@ -365,8 +375,8 @@
                                      K_KR -> (i,k+1,t,a)
                                      K_TR -> (i,k,t+1,a)
                                      K_AR -> (i,k,t,a+1)
-                          in rec r' ns'
-    in rec (0,0,0,0)
+                          in recur r' ns'
+    in recur (0,0,0,0)
 
 -- | Construct implicit /control/ unit generator 'Nodes'.  Unit
 -- generators are only constructed for instances of control types that
@@ -459,7 +469,7 @@
     let e = edges (ugens g)
         c = filter ((== node_id n) . port_nid . fst) e
         f (ToPort k _) = k
-    in mapMaybe (find_node g) (map (f . snd) c)
+    in mapMaybe (find_node g . f . snd) c
 
 -- * PV edge accounting
 
@@ -468,8 +478,8 @@
 pv_multiple_out_edges g =
     let e = edges (ugens g)
         p = multiple_u_out_edges e
-        n = mapMaybe (find_node g) (map port_nid p)
-    in filter (primitive_is_pv_rate . node_u_name) n
+        n = mapMaybe (find_node g . port_nid) p
+    in filter (A.primitive_is_pv_rate . node_u_name) n
 
 -- | Error if graph has invalid @PV@ subgraph, ie. multiple out edges
 -- at @PV@ node not connecting to @Unpack1FFT@ & @PackFFT@.
@@ -478,7 +488,7 @@
     case pv_multiple_out_edges g of
       [] -> g
       n -> let d = concatMap (map node_u_name . node_descendents g) n
-           in if any primitive_is_pv_rate d || any (`elem` ["IFFT"]) d
+           in if any A.primitive_is_pv_rate d || any (`elem` ["IFFT"]) d
               then error (show
                           ("pv_validate: multiple out edges, see pv_split"
                           ,map node_u_name n
@@ -491,4 +501,3 @@
 -- > ugen_to_graph (out 0 (pan2 (sinOsc AR 440 0) 0.5 0.1))
 ugen_to_graph :: UGen -> Graph
 ugen_to_graph = pv_validate . mk_graph
-
diff --git a/Sound/SC3/UGen/Graph/Reconstruct.hs b/Sound/SC3/UGen/Graph/Reconstruct.hs
--- a/Sound/SC3/UGen/Graph/Reconstruct.hs
+++ b/Sound/SC3/UGen/Graph/Reconstruct.hs
@@ -1,4 +1,4 @@
--- | A /disasembler/ for UGen graphs.
+-- | A /disassembler/ for UGen graphs.
 module Sound.SC3.UGen.Graph.Reconstruct where
 
 import Data.Char {- base -}
@@ -35,24 +35,38 @@
     then printf "(%s)" nm
     else nm
 
--- | Generate a reconstruction of a 'Graph'.
---
--- > import Sound.SC3.ID
---
--- > let {k = control KR "bus" 0
--- >     ;o = sinOsc AR 440 0 + whiteNoise 'a' AR
--- >     ;u = out k (pan2 (o * 0.1) 0 1)
--- >     ;m = mrg [u,out 1 (impulse AR 1 0 * 0.1)]}
--- > in putStrLn (reconstruct_graph_str (synth m))
-reconstruct_graph_str :: Graph -> String
-reconstruct_graph_str g =
+reconstruct_graph :: Graph -> ([String],String)
+reconstruct_graph g =
     let (Graph _ c k u) = g
         ls = concat [map reconstruct_c_str (node_sort c)
                     ,map reconstruct_k_str (node_sort k)
-                    ,concatMap reconstruct_u_str u
-                    ,[reconstruct_mrg_str u]]
-    in unlines (filter (not . null) ls)
+                    ,concatMap reconstruct_u_str u]
+    in (filter (not . null) ls,reconstruct_mrg_str u)
 
+reconstruct_graph_module :: String -> Graph -> [String]
+reconstruct_graph_module nm gr =
+  let imp = ["import Sound.SC3"
+            ,"import Sound.SC3.Common"
+            ,"import Sound.SC3.UGen.Plain"]
+      (b0:bnd,res) = reconstruct_graph gr
+      hs = ("  let " ++ b0) : map ("      " ++ ) bnd ++ ["  in " ++ res]
+      pre = [nm ++ " :: UGen",nm ++ " ="]
+  in (imp ++ pre ++ hs)
+
+{- | Generate a reconstruction of a 'Graph'.
+
+> import Sound.SC3
+
+> let {k = control KR "bus" 0
+>     ;o = sinOsc AR 440 0 + whiteNoise 'a' AR
+>     ;u = out k (pan2 (o * 0.1) 0 1)
+>     ;m = mrg [u,out 1 (impulse AR 1 0 * 0.1)]}
+> in putStrLn (reconstruct_graph_str "anon" (ugen_to_graph m))
+
+-}
+reconstruct_graph_str :: String -> Graph -> String
+reconstruct_graph_str nm = unlines . reconstruct_graph_module nm
+
 reconstruct_c_str :: Node -> String
 reconstruct_c_str u =
     let l = node_label u
@@ -84,8 +98,8 @@
 ugen_qname :: String -> Special -> (String,String)
 ugen_qname nm (Special n) =
     case nm of
-      "UnaryOpUGen" -> ("uop",unaryName n)
-      "BinaryOpUGen" -> ("binop",binaryName n)
+      "UnaryOpUGen" -> ("uop CS",unaryName n)
+      "BinaryOpUGen" -> ("binop CS",binaryName n)
       _ -> ("ugen",nm)
 
 reconstruct_mce_str :: Node -> String
diff --git a/Sound/SC3/UGen/Graph/Transform.hs b/Sound/SC3/UGen/Graph/Transform.hs
--- a/Sound/SC3/UGen/Graph/Transform.hs
+++ b/Sound/SC3/UGen/Graph/Transform.hs
@@ -56,12 +56,12 @@
 
 c_lift_ugens :: Graph -> NodeId -> [Node] -> (NodeId,[Node],[Node])
 c_lift_ugens g  =
-    let rec (k,r) z u =
+    let recur (k,r) z u =
             case u of
               [] -> (z,k,reverse r)
               n:u' -> let (z',n',k') = c_lift_ugen g z n
-                      in rec (k++k',n':r) z' u'
-    in rec ([],[])
+                      in recur (k++k',n':r) z' u'
+    in recur ([],[])
 
 -- > import Sound.SC3
 -- > import Sound.SC3.UGen.Dot
diff --git a/Sound/SC3/UGen/HS.hs b/Sound/SC3/UGen/HS.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/HS.hs
@@ -0,0 +1,326 @@
+-- | Haskell implementations of SC3 UGens.
+module Sound.SC3.UGen.HS where
+
+import Data.List {- base -}
+import qualified System.Random as R {- random -}
+
+import Sound.SC3.Common.Math
+
+-- | F = function, ST = state
+type F_ST0 st o = st -> (o,st)
+type F_ST1 st i o = (i,st) -> (o,st)
+
+-- | U = uniform
+type F_U2 n = n -> n -> n
+type F_U3 n = n -> n -> n -> n
+type F_U4 n = n -> n -> n -> n -> n
+type F_U5 n = n -> n -> n -> n -> n -> n
+type F_U6 n = n -> n -> n -> n -> n -> n -> n
+type F_U7 n = n -> n -> n -> n -> n -> n -> n -> n
+type F_U8 n = n -> n -> n -> n -> n -> n -> n -> n -> n
+type F_U9 n = n -> n -> n -> n -> n -> n -> n -> n -> n -> n
+
+-- | T = tuple
+type T2 n = (n,n)
+type T3 n = (n,n,n)
+type T4 n = (n,n,n,n)
+type T5 n = (n,n,n,n,n)
+type T6 n = (n,n,n,n,n,n)
+type T7 n = (n,n,n,n,n,n,n)
+type T8 n = (n,n,n,n,n,n,n,n)
+type T9 n = (n,n,n,n,n,n,n,n,n)
+
+-- | avg = average
+avg2 :: Fractional n => F_U2 n
+avg2 p q = (p + q) / 2
+
+avg3 :: Fractional n => F_U3 n
+avg3 p q r = (p + q + r) / 3
+
+avg4 :: Fractional n => F_U4 n
+avg4 p q r s = (p + q + r + s) / 4
+
+avg5 :: Fractional n => F_U5 n
+avg5 p q r s t = (p + q + r + s + t) / 5
+
+avg9 :: Fractional n => F_U9 n
+avg9 p q r s t u v w x = (p + q + r + s + t + u + v + w + x) / 9
+
+-- | fir = finite impulse response
+fir1 :: F_U2 n -> F_ST1 n n n
+fir1 f (n,z0) = (f n z0,n)
+
+fir2 :: F_U3 n -> F_ST1 (T2 n) n n
+fir2 f (n,(z1,z0)) = (f n z0 z1,(z0,n))
+
+fir3 :: F_U4 n -> F_ST1 (T3 n) n n
+fir3 f (n,(z2,z1,z0)) = (f n z0 z1 z2,(z1,z0,n))
+
+fir4 :: F_U5 n -> F_ST1 (T4 n) n n
+fir4 f (n,(z3,z2,z1,z0)) = (f n z0 z1 z2 z3,(z2,z1,z0,n))
+
+fir8 :: F_U9 n -> F_ST1 (T8 n) n n
+fir8 f (n,(z7,z6,z5,z4,z3,z2,z1,z0)) = (f n z0 z1 z2 z3 z4 z5 z6 z7,(z6,z5,z4,z4,z2,z1,z0,n))
+
+-- | iir = infinite impulse response
+iir1 :: F_U2 n -> F_ST1 n n n
+iir1 f (n,y0) = let r = f n y0 in (r,r)
+
+iir2 :: F_U3 n -> F_ST1 (T2 n) n n
+iir2 f (n,(y1,y0)) = let r = f n y0 y1 in (r,(y0,r))
+
+biquad :: F_U5 n -> F_ST1 (T4 n) n n
+biquad f (n,(x1,x0,y1,y0)) = let r = f n x0 x1 y0 y1 in (r,(x0,n,y0,r))
+
+-- | sos = second order section
+sos_f :: Num n => T5 n -> F_U5 n
+sos_f (a0,a1,a2,b1,b2) x x1 x2 y1 y2 = a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2
+
+sos :: Num n => T5 n -> F_ST1 (T4 n) n n
+sos p = biquad (sos_f p)
+
+-- | hp = high pass
+hpz1 :: Fractional n => F_ST1 n n n
+hpz1 = fir1 (\n z0 -> 0.5 * (n - z0))
+
+hpz2 :: Fractional n => F_ST1 (T2 n) n n
+hpz2 = fir2 (\n z0 z1 -> 0.25 * (n - (2 * z0) + z1))
+
+-- | lp = low pass
+lpz1 :: Fractional n => F_ST1 n n n
+lpz1 = fir1 avg2
+
+lpz2 :: Fractional n => F_ST1 (T2 n) n n
+lpz2 = fir2 (\n z0 z1 -> 0.25 * (n + (2 * z0) + z1))
+
+-- | bp = band pass
+bpz2 :: Fractional n => F_ST1 (T2 n) n n
+bpz2 = fir2 (\n _z0 z1 -> 0.5 * (n - z1))
+
+-- | br = band reject
+brz2 :: Fractional n => F_ST1 (T2 n) n n
+brz2 = fir2 (\n _z0 z1 -> 0.5 * (n + z1))
+
+-- | mavg = moving average
+mavg5 :: Fractional n => F_ST1 (T4 n) n n
+mavg5 = fir4 avg5
+
+mavg9 :: Fractional n => F_ST1 (T8 n) n n
+mavg9 = fir8 avg9
+
+-- | Sample rate (SR) to radians per sample (RPS).
+--
+-- > sr_to_rps 44100 == 0.00014247585730565955
+sr_to_rps :: Floating n => n -> n
+sr_to_rps sr = two_pi / sr
+
+resonz_f :: Floating n => T3 n -> (n -> n -> n -> T2 n)
+resonz_f (radians_per_sample,f,rq) x y1 y2 =
+    let ff = f * radians_per_sample
+        b = ff * rq
+        r = 1.0 - b * 0.5
+        two_r = 2.0 * r
+        r2 = r * r
+        ct = (two_r * cos ff) / (1.0 + r2)
+        b1 = two_r * ct
+        b2 = negate r2
+        a0 = (1.0 - r2) * 0.5
+        y0 = x + b1 * y1 + b2 * y2
+    in (a0 * (y0 - y2),y0)
+
+-- | ff = feed-forward, fb = feed-back
+iir2_ff_fb :: (n -> n -> n -> T2 n) -> (n,T2 n) -> (n,T2 n)
+iir2_ff_fb f (n,(y1,y0)) = let (r,y0') = f n y0 y1 in (r,(y0,y0'))
+
+-- | ir = initialization rate
+resonz_ir :: Floating n => T3 n -> F_ST1 (T2 n) n n
+resonz_ir p = iir2_ff_fb (resonz_f p)
+
+-- | rlp = resonant low pass
+rlpf_f :: Floating n => (n -> n -> n) -> T3 n -> F_U3 n
+rlpf_f max_f (radians_per_sample,f,rq) x y1 y2 =
+    let qr = max_f 0.001 rq
+        pf = f * radians_per_sample
+        d = tan (pf * qr * 0.5)
+        c = (1.0 - d) / (1.0 + d)
+        b1 = (1.0 + c) * cos pf
+        b2 = negate c
+        a0 = (1.0 + c - b1) * 0.25
+    in a0 * x + b1 * y1 + b2 * y2
+
+rlpf_ir :: (Floating n, Ord n) => T3 n -> F_ST1 (T2 n) n n
+rlpf_ir p = iir2 (rlpf_f max p)
+
+bw_lpf_or_hpf_coef :: Floating n => Bool -> n -> n -> T5 n
+bw_lpf_or_hpf_coef is_hpf sample_rate f =
+    let f' = f * pi / sample_rate
+        c = if is_hpf then tan f' else 1.0 / tan f'
+        c2 = c * c
+        s2c = sqrt 2.0 * c
+        a0 = 1.0 / (1.0 + s2c + c2)
+        a1 = if is_hpf then -2.0 * a0 else 2.0 * a0
+        a2 = a0
+        b1 = if is_hpf then 2.0 * (c2 - 1.0) * a0 else 2.0 * (1.0 - c2) * a0
+        b2 = (1.0 - s2c + c2) * a0
+    in (a0,a1,a2,b1,b2)
+
+bw_hpf_ir :: Floating n => T2 n -> F_ST1 (T4 n) n n
+bw_hpf_ir (sample_rate,f) = sos (bw_lpf_or_hpf_coef True sample_rate f)
+
+bw_lpf_ir :: Floating n => T2 n -> F_ST1 (T4 n) n n
+bw_lpf_ir (sample_rate,f) = sos (bw_lpf_or_hpf_coef False sample_rate f)
+
+white_noise :: (R.RandomGen g, Fractional n, R.Random n) => F_ST0 g n
+white_noise = R.randomR (-1.0,1.0)
+
+brown_noise_f :: (Fractional n, Ord n) => n -> n -> n
+brown_noise_f x y1 =
+    let z = x + y1
+    in if z > 1.0 then 2.0 - z else if z < (-1.0) then (-2.0) - z else z
+
+brown_noise :: (R.RandomGen g, Fractional n, R.Random n, Ord n) => F_ST0 (g,n) n
+brown_noise (g,y1) =
+    let (n,g') = white_noise g
+        r = brown_noise_f (n / 8.0) y1
+    in (r,(g',r))
+
+decay_f :: Floating a => a -> a -> a -> a -> a
+decay_f sr dt x y1 =
+    let b1 = exp (log 0.001 / (dt * sr))
+    in x + b1 * y1
+
+lag_f :: Floating a => a -> a -> a -> a -> a
+lag_f sr t x y1 =
+    let b1 = exp (log (0.001 / (t * sr)))
+    in x + b1 * (y1 - x)
+
+lag :: Floating t => t -> F_ST1 t (t,t) t
+lag sr ((i,t),st) = let r = lag_f sr t i st in (r,r)
+
+latch :: F_ST1 t (t,Bool) t
+latch ((n,b),y1) = let r = if b then n else y1 in (r,r)
+
+as_trig :: (Fractional t,Ord t) => F_ST1 t t Bool
+as_trig (n,y1) = (y1 <= 0.0 && n > 0.0,n)
+
+phasor :: RealFrac t => F_ST1 t (Bool,t,t,t,t) t
+phasor ((trig,rate,start,end,resetPos),ph) =
+    let r = if trig then resetPos else sc_wrap start end (ph + rate)
+    in (ph,r)
+
+-- | * LIST PROCESSING
+
+l_apply_f_st0 :: F_ST0 st o -> st -> [o]
+l_apply_f_st0 f st = let (r,st') = f st in r : l_apply_f_st0 f st'
+
+l_white_noise :: (Enum e, Fractional n, R.Random n) => e -> [n]
+l_white_noise e = l_apply_f_st0 white_noise (R.mkStdGen (fromEnum e))
+
+l_brown_noise :: (Enum e, Fractional n, Ord n, R.Random n) => e -> [n]
+l_brown_noise e = l_apply_f_st0 brown_noise (R.mkStdGen (fromEnum e),0.0)
+
+l_apply_f_st1 :: F_ST1 st i o -> st -> [i] -> [o]
+l_apply_f_st1 f st xs =
+    case xs of
+      [] -> []
+      x:xs' -> let (r,st') = f (x,st) in r : l_apply_f_st1 f st' xs'
+
+l_lag :: Floating t => t -> [t] -> [t] -> [t]
+l_lag sr i t = l_apply_f_st1 (lag sr) 0 (zip i t)
+
+-- > let rp = repeat
+-- > take 10 (l_phasor (rp False) (rp 1) (rp 0) (rp 4) (rp 0)) == [0,1,2,3,0,1,2,3,0,1]
+l_phasor :: RealFrac n => [Bool] -> [n] -> [n] -> [n] -> [n] -> [n]
+l_phasor trig rate start end resetPos =
+    let i = zip5 trig rate start end resetPos
+    in l_apply_f_st1 phasor (head start) i
+
+l_phasor_osc :: RealFrac n => n -> n -> [n] -> [n]
+l_phasor_osc sr k f =
+    let rp = repeat
+    in l_phasor (rp False) (map (cps_to_incr sr k) f) (rp 0) (rp k) (rp 0)
+
+l_sin_osc :: (Floating n, RealFrac n) => n -> [n] -> [n]
+l_sin_osc sr f = map sin (l_phasor_osc sr two_pi f)
+
+l_cos_osc :: (Floating n, RealFrac n) => n -> [n] -> [n]
+l_cos_osc sr f = map cos (l_phasor_osc sr two_pi f)
+
+l_hpz1 :: Fractional n => [n] -> [n]
+l_hpz1 = l_apply_f_st1 hpz1 0
+
+l_hpz2 :: Fractional n => [n] -> [n]
+l_hpz2 = l_apply_f_st1 hpz2 (0,0)
+
+l_lpz1 :: Fractional n => [n] -> [n]
+l_lpz1 = l_apply_f_st1 lpz1 0
+
+l_lpz2 :: Fractional n => [n] -> [n]
+l_lpz2 = l_apply_f_st1 lpz2 (0,0)
+
+l_bpz2 :: Fractional n => [n] -> [n]
+l_bpz2 = l_apply_f_st1 bpz2 (0,0)
+
+l_brz2 :: Fractional n => [n] -> [n]
+l_brz2 = l_apply_f_st1 brz2 (0,0)
+
+l_bw_hpf :: Floating n => T2 n -> [n] -> [n]
+l_bw_hpf p = l_apply_f_st1 (bw_hpf_ir p) (0,0,0,0)
+
+l_bw_lpf :: Floating n => T2 n -> [n] -> [n]
+l_bw_lpf p = l_apply_f_st1 (bw_lpf_ir p) (0,0,0,0)
+
+l_resonz_ir :: Floating n => T3 n -> [n] -> [n]
+l_resonz_ir p = l_apply_f_st1 (resonz_ir p) (0,0)
+
+l_rlpf_ir :: (Floating n, Ord n) => T3 n -> [n] -> [n]
+l_rlpf_ir p = l_apply_f_st1 (rlpf_ir p) (0,0)
+
+l_mavg5 :: Fractional n => [n] -> [n]
+l_mavg5 = l_apply_f_st1 mavg5 (0,0,0,0)
+
+l_mavg9 :: Fractional n => [n] -> [n]
+l_mavg9 = l_apply_f_st1 mavg9 (0,0,0,0,0,0,0,0)
+
+{-
+
+import Sound.SC3.Plot {- hsc3-plot -}
+import Sound.SC3.Plot.FFT {- hsc3-plot -}
+
+let n = take 4096 (l_white_noise 'α')
+
+plotTable1 n
+plotTable1 (take 4096 (l_brown_noise 'α'))
+
+plotTable1 (l_lpz1 n)
+plotTable1 (l_lpz2 n)
+plotTable1 (l_hpz1 n)
+plotTable1 (l_hpz2 n)
+
+plotTable1 (rfft_pure n)
+plotTable1 (rfft_pure (l_lpz1 n))
+plotTable1 (rfft_pure (l_lpz2 n))
+plotTable1 (rfft_pure (l_hpz1 n))
+plotTable1 (rfft_pure (l_hpz2 n))
+plotTable1 (rfft_pure (l_bpz2 n))
+plotTable1 (rfft_pure (l_brz2 n))
+plotTable1 (rfft_pure (l_bw_lpf (44100,9000) n))
+plotTable1 (rfft_pure (l_bw_hpf (44100,9000) n))
+plotTable1 (rfft_pure (l_resonz_ir (sr_to_rps 44100,440,0.1) n))
+plotTable1 (rfft_pure (l_rlpf_ir (sr_to_rps 44100,1200,0.1) n))
+
+import Sound.SC3.Common.Math
+
+plot_fft1_mnn 44100 (rfft_pure (l_bw_lpf (44100,midi_to_cps 60) n))
+plot_fft1_mnn 44100 (rfft_pure (l_resonz_ir (sr_to_rps 44100,midi_to_cps 69,0.1) n))
+plot_fft1_mnn 44100 (rfft_pure (l_rlpf_ir (sr_to_rps 44100,midi_to_cps 86,0.1) n))
+
+plotTable1 (l_mavg9 (rfft_pure n))
+plotTable1 (l_mavg9 (rfft_pure (l_lpz2 n)))
+plotTable1 (l_mavg9 (rfft_pure (l_hpz2 n)))
+plotTable1 (l_mavg9 (rfft_pure (l_bpz2 n)))
+plotTable1 (l_mavg9 (l_mavg9 (l_mavg9 (l_mavg9 (rfft_pure (l_brz2 n))))))
+
+plotTable1 (take 512 (l_sin_osc 48000 (repeat 440)))
+plotTable1 (take 512 (l_cos_osc 48000 (repeat 440)))
+-}
diff --git a/Sound/SC3/UGen/Help.hs b/Sound/SC3/UGen/Help.hs
--- a/Sound/SC3/UGen/Help.hs
+++ b/Sound/SC3/UGen/Help.hs
@@ -1,4 +1,6 @@
 -- | Functions to provide mediated access to the SC3 help system.
+--
+-- Requires the HTML files generated by SCDoc.renderAll (sclang).
 module Sound.SC3.UGen.Help where
 
 import Control.Exception
diff --git a/Sound/SC3/UGen/Help/Graph.hs b/Sound/SC3/UGen/Help/Graph.hs
--- a/Sound/SC3/UGen/Help/Graph.hs
+++ b/Sound/SC3/UGen/Help/Graph.hs
@@ -1,8 +1,13 @@
 -- | Standard SC3 graphs, referenced in documentation.
 module Sound.SC3.UGen.Help.Graph where
 
-import Sound.SC3.UGen
+import Sound.SC3.Common.Envelope
+
 import Sound.SC3.UGen.Bindings
+import Sound.SC3.UGen.Enum
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.Type
+import Sound.SC3.UGen.UGen
 
 -- | The SC3 /default/ instrument 'UGen' graph.
 default_ugen_graph :: UGen
@@ -24,7 +29,7 @@
     let o = control IR "out" 0
         f = control IR "freq" 440
         d = control IR "sustain" 1
-        l = control IR "pan" 1
+        l = control IR "pan" 0
         a = control IR "amp" 0.1
         w = control IR "width" 0.25
         e = lfGauss AR d w 0 NoLoop RemoveSynth
@@ -37,10 +42,10 @@
     let o = control IR "out" 0
         f = control IR "freq" 440
         d = control IR "sustain" 1
-        l = control IR "pan" 1
+        l = control IR "pan" 0
         a = control IR "amp" 0.1
         w = control IR "width" 0.25
-        e = envGen AR 1 1 0 1 DoNothing (envSine (d * w) 1)
+        e = envGen AR 1 1 0 1 RemoveSynth (envSine (d * w) 1)
         s = fSinOsc AR f (0.5 * pi) * e
     in offsetOut o (pan2 s l a)
 
diff --git a/Sound/SC3/UGen/MCE.hs b/Sound/SC3/UGen/MCE.hs
--- a/Sound/SC3/UGen/MCE.hs
+++ b/Sound/SC3/UGen/MCE.hs
@@ -1,9 +1,9 @@
--- | Multiple channel expansion.
+-- | The SC3 multiple channel expansion rules over an abstract type.
 module Sound.SC3.UGen.MCE where
 
 -- | Multiple channel expansion.
 data MCE n = MCE_Unit n | MCE_Vector [n]
-             deriving (Eq,Show)
+             deriving (Eq,Read,Show)
 
 mce_elem :: MCE t -> [t]
 mce_elem m =
@@ -28,8 +28,8 @@
 mce_binop f m1 m2 =
     case (m1,m2) of
       (MCE_Unit e1,MCE_Unit e2) -> MCE_Unit (f e1 e2)
-      (MCE_Unit e1,MCE_Vector e2) -> MCE_Vector (zipWith f (repeat e1) e2)
-      (MCE_Vector e1,MCE_Unit e2) -> MCE_Vector (zipWith f e1 (repeat e2))
+      (MCE_Unit e1,MCE_Vector e2) -> MCE_Vector (map (f e1) e2)
+      (MCE_Vector e1,MCE_Unit e2) -> MCE_Vector (map (`f` e2) e1)
       (MCE_Vector e1,MCE_Vector e2) ->
           let n = max (length e1) (length e2)
               ext = take n . cycle
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
@@ -2,8 +2,9 @@
 module Sound.SC3.UGen.Math where
 
 import qualified Data.Fixed as F {- base -}
-import Data.Int
+import Data.Int {- base -}
 
+import Sound.SC3.Common.Math
 import Sound.SC3.UGen.Bindings.DB (mulAdd)
 import Sound.SC3.UGen.Operator
 import Sound.SC3.UGen.Type
@@ -59,27 +60,14 @@
 sc3_gte :: (Num n, Ord n) => n -> n -> n
 sc3_gte = sc3_comparison (>=)
 
--- | Variant of @SC3@ @roundTo@ function.
---
--- > let r = [0,0,0.25,0.25,0.5,0.5,0.5,0.75,0.75,1,1]
--- > in map (`roundTo_` 0.25) [0,0.1 .. 1] == r
-roundTo_ :: (RealFrac n, Ord n) => n -> n -> n
-roundTo_ = sc3_round_to
-
-sc3_round_to :: (RealFrac n, Ord n) => n -> n -> n
-sc3_round_to a b = if b == 0 then a else sc3_floor ((a / b) + 0.5) * b
-
-sc3_idiv :: RealFrac n => n -> n -> n
-sc3_idiv a b = fromInteger (floor a `div` floor b)
-
 -- | Association table for 'Binary' to haskell function implementing operator.
-binop_hs_tbl :: (Real n,Floating n,RealFrac n,Ord n) => [(Binary,n -> n -> n)]
+binop_hs_tbl :: (Real n,Floating n,RealFrac n) => [(Binary,n -> n -> n)]
 binop_hs_tbl =
     [(Add,(+))
     ,(Sub,(-))
     ,(FDiv,(/))
     ,(IDiv,sc3_idiv)
-    ,(Mod,F.mod')
+    ,(Mod,sc3_mod)
     ,(EQ_,sc3_eq)
     ,(NE,sc3_neq)
     ,(LT_,sc3_lt)
@@ -95,29 +83,29 @@
     ,(Round,sc3_round_to)]
 
 -- | 'lookup' 'binop_hs_tbl' via 'toEnum'.
-binop_special_hs :: (Real n,RealFrac n,Floating n, Ord n) => Int -> Maybe (n -> n -> n)
+binop_special_hs :: (RealFrac n,Floating n) => Int -> Maybe (n -> n -> n)
 binop_special_hs z = lookup (toEnum z) binop_hs_tbl
 
 -- | Association table for 'Unary' to haskell function implementing operator.
-uop_hs_tbl :: (RealFrac n,Floating n,Ord n) => [(Unary,n -> n)]
+uop_hs_tbl :: (RealFrac n,Floating n) => [(Unary,n -> n)]
 uop_hs_tbl =
     [(Neg,negate)
     ,(Not,\z -> if z > 0 then 0 else 1)
     ,(Abs,abs)
-    ,(Ceil,sc3_ceiling)
-    ,(Floor,sc3_floor)
-    ,(Squared,squared')
-    ,(Cubed,cubed')
+    ,(Ceil,sc_ceiling)
+    ,(Floor,sc_floor)
+    ,(Squared,\z -> z * z)
+    ,(Cubed,\z -> z * z * z)
     ,(Sqrt,sqrt)
     ,(Recip,recip)
-    ,(MIDICPS,midiCPS')
-    ,(CPSMIDI,cpsMIDI')
+    ,(MIDICPS,midi_to_cps)
+    ,(CPSMIDI,cps_to_midi)
     ,(Sin,sin)
     ,(Cos,cos)
     ,(Tan,tan)]
 
 -- | 'lookup' 'uop_hs_tbl' via 'toEnum'.
-uop_special_hs :: (RealFrac n,Floating n, Ord n) => Int -> Maybe (n -> n)
+uop_special_hs :: (RealFrac n,Floating n) => Int -> Maybe (n -> n)
 uop_special_hs z = lookup (toEnum z) uop_hs_tbl
 
 -- The Eq and Ord classes in the Prelude require Bool, hence the name
@@ -165,42 +153,25 @@
     (>*) = mkBinaryOperator GT_ sc3_gt
     (>=*) = mkBinaryOperator GE sc3_gte
 
-sc3_properFraction :: (RealFrac t, Num t) => t -> (t,t)
-sc3_properFraction a =
-    let (p,q) = properFraction a
-    in (fromInteger p,q)
-
-sc3_truncate :: (RealFrac a, Num a) => a -> a
-sc3_truncate a = fromInteger (truncate a)
-
-sc3_round :: (RealFrac a, Num a) => a -> a
-sc3_round a = fromInteger (round a)
-
-sc3_ceiling :: (RealFrac a, Num a) => a -> a
-sc3_ceiling a = fromInteger (ceiling a)
-
-sc3_floor :: (RealFrac a, Num a) => a -> a
-sc3_floor a = fromInteger (floor a)
-
 -- | Variant of 'RealFrac' with non 'Integral' results.
 class RealFrac a => RealFracE a where
   properFractionE :: a -> (a,a)
   properFractionE = sc3_properFraction
   truncateE :: a -> a
-  truncateE = sc3_truncate
+  truncateE = sc_truncate
   roundE :: a -> a
-  roundE = sc3_round
+  roundE = sc_round
   ceilingE :: a -> a
-  ceilingE = sc3_ceiling
+  ceilingE = sc_ceiling
   floorE :: a -> a
-  floorE = sc3_floor
+  floorE = sc_floor
 
 instance RealFracE Float
 instance RealFracE Double
 
--- | 'UGen' form or 'roundTo_'.
+-- | 'UGen' form or 'sc3_round_to'.
 roundTo :: UGen -> UGen -> UGen
-roundTo = mkBinaryOperator Round roundTo_
+roundTo = mkBinaryOperator Round sc3_round_to
 
 instance RealFracE UGen where
     properFractionE = error "UGen.properFractionE"
@@ -213,56 +184,24 @@
 ceil :: UGen -> UGen
 ceil = ceilingE
 
--- | 'Floating' form of 'midiCPS'.
-midiCPS' :: Floating a => a -> a
-midiCPS' i = 440.0 * (2.0 ** ((i - 69.0) * (1.0 / 12.0)))
-
--- | 'Floating' form of 'cpsMIDI'.
-cpsMIDI' :: Floating a => a -> a
-cpsMIDI' a = (logBase 2 (a * (1.0 / 440.0)) * 12.0) + 69.0
-
-cpsOct' :: Floating a => a -> a
-cpsOct' a = logBase 2 (a * (1.0 / 440.0)) + 4.75
-
-ampDb' :: Floating a => a -> a
-ampDb' a = logBase 10 a * 20
-
-dbAmp' :: Floating a => a -> a
-dbAmp' a = 10 ** (a * 0.05)
-
-cubed' :: Num a => a -> a
-cubed' a = a * a * a
-
-midiRatio' :: Floating a => a -> a
-midiRatio' a = 2.0 ** (a * (1.0 / 12.0))
-
-octCPS' :: Floating a => a -> a
-octCPS' a = 440.0 * (2.0 ** (a - 4.75))
-
-ratioMIDI' :: Floating a => a -> a
-ratioMIDI' a = 12.0 * logBase 2 a
-
-squared' :: Num a => a -> a
-squared' a = a * a
-
 -- | Unary operator class.
 --
 -- > map (floor . (* 1e4) . dbAmp) [-90,-60,-30,0] == [0,10,316,10000]
 class (Floating a, Ord a) => UnaryOp a where
     ampDb :: a -> a
-    ampDb = ampDb'
+    ampDb = amp_to_db
     asFloat :: a -> a
     asFloat = error "asFloat"
     asInt :: a -> a
     asInt = error "asInt"
     cpsMIDI :: a -> a
-    cpsMIDI = cpsMIDI'
+    cpsMIDI = cps_to_midi
     cpsOct :: a -> a
-    cpsOct = cpsOct'
+    cpsOct = cps_to_oct
     cubed :: a -> a
-    cubed = cubed'
+    cubed n = n * n * n
     dbAmp :: a -> a
-    dbAmp = dbAmp'
+    dbAmp = db_to_amp
     distort :: a -> a
     distort = error "distort"
     frac :: a -> a
@@ -274,23 +213,23 @@
     log2 :: a -> a
     log2 = logBase 2
     midiCPS :: a -> a
-    midiCPS = midiCPS'
+    midiCPS = midi_to_cps
     midiRatio :: a -> a
-    midiRatio = midiRatio'
+    midiRatio = midi_to_ratio
     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 = octCPS'
+    octCPS = oct_to_cps
     ramp_ :: a -> a
     ramp_ _ = error "ramp_"
     ratioMIDI :: a -> a
-    ratioMIDI = ratioMIDI'
+    ratioMIDI = ratio_to_midi
     softClip :: a -> a
     softClip = error "softClip"
     squared :: a -> a
-    squared = squared'
+    squared = \z -> z * z
 
 instance UnaryOp Float where
 instance UnaryOp Double where
@@ -318,12 +257,6 @@
     softClip = mkUnaryOperator SoftClip softClip
     squared = mkUnaryOperator Squared squared
 
-difSqr' :: Num a => a -> a -> a
-difSqr' a b = (a * a) - (b * b)
-
-hypotx' :: (Ord a, Floating a) => a -> a -> a
-hypotx' x y = abs x + abs y - ((sqrt 2 - 1) * min (abs x) (abs y))
-
 -- | Binary operator class.
 class (Floating a,RealFrac a, Ord a) => BinaryOp a where
     absDif :: a -> a -> a
@@ -333,11 +266,11 @@
     atan2E :: a -> a -> a
     atan2E a b = atan (b/a)
     clip2 :: a -> a -> a
-    clip2 a b = clip_ a (-b) b
+    clip2 a b = sc_clip a (-b) b
     difSqr :: a -> a -> a
-    difSqr = difSqr'
+    difSqr = sc_dif_sqr
     excess :: a -> a -> a
-    excess a b = a - clip_ a (-b) b
+    excess a b = a - sc_clip a (-b) b
     exprandRange :: a -> a -> a
     exprandRange = error "exprandRange"
     fill :: a -> a -> a
@@ -349,9 +282,9 @@
     gcdE :: a -> a -> a
     gcdE = error "gcdE"
     hypot :: a -> a -> a
-    hypot x y = sqrt (x * x + y * y)
+    hypot = sc_hypot
     hypotx :: a -> a -> a
-    hypotx = hypotx'
+    hypotx = sc_hypotx
     iDiv :: a -> a -> a
     iDiv = sc3_idiv
     lcmE :: a -> a -> a
@@ -385,41 +318,17 @@
     wrap2 :: a -> a -> a
     wrap2 = error "wrap2"
 
--- | The SC3 @%@ operator is the 'F.mod'' function.
---
--- > > 1.5 % 1.2 // ~= 0.3
--- > > -1.5 % 1.2 // ~= 0.9
--- > > 1.5 % -1.2 // ~= -0.9
--- > > -1.5 % -1.2 // ~= -0.3
---
--- > 1.5 `fmod_f32` 1.2 -- ~= 0.3
--- > (-1.5) `fmod_f32` 1.2 -- ~= 0.9
--- > 1.5 `fmod_f32` (-1.2) -- ~= -0.9
--- > (-1.5) `fmod_f32` (-1.2) -- ~= -0.3
---
--- > > 1.2 % 1.5 // ~= 1.2
--- > > -1.2 % 1.5 // ~= 0.3
--- > 1.2 % -1.5 // ~= -0.3
--- > -1.2 % -1.5 // ~= -1.2
---
--- > 1.2 `fmod_f32` 1.5 -- ~= 1.2
--- > (-1.2) `fmod_f32` 1.5 -- ~= 0.3
--- > 1.2 `fmod_f32` (-1.5) -- ~= -0.3
--- > (-1.2) `fmod_f32` (-1.5) -- ~= -1.2
-fmod_f32 :: Float -> Float -> Float
-fmod_f32 = F.mod'
-
 instance BinaryOp Float where
     fold2 a b = fold_ a (-b) b
     modE = F.mod'
     roundUp a b = if b == 0 then a else ceilingE (a/b + 0.5) * b
-    wrap2 a b = wrap_ a (-b) b
+    wrap2 a b = sc_wrap_ni a (-b) b
 
 instance BinaryOp Double where
     fold2 a b = fold_ a (-b) b
     modE = F.mod'
     roundUp a b = if b == 0 then a else ceilingE (a/b + 0.5) * b
-    wrap2 a b = wrap_ a (-b) b
+    wrap2 a b = sc_wrap_ni a (-b) b
 
 instance BinaryOp UGen where
     iDiv = mkBinaryOperator IDiv iDiv
@@ -452,123 +361,24 @@
     randRange = mkBinaryOperator RandRange randRange
     exprandRange = mkBinaryOperator ExpRandRange exprandRange
 
--- | Ternary operator class.
-class Num a => TernaryOp a where
+-- | MulAdd operator class.
+class Num a => MulAdd a where
     mul_add :: a -> a -> a -> a
     mul_add i m a = i * m + a
 
-instance TernaryOp UGen where mul_add = mulAdd
-instance TernaryOp Float where
-instance TernaryOp Double where
-
--- | Wrap /k/ to within range /(i,j)/, ie. @AbstractFunction.wrap@.
---
--- > > [5,6].wrap(0,5) == [5,0]
--- > map (wrap' 0 5) [5,6] == [5,0]
---
--- > > [9,10,5,6,7,8,9,10,5,6].wrap(5,10) == [9,10,5,6,7,8,9,10,5,6]
--- > map (wrap' 5 10) [3..12] == [9,10,5,6,7,8,9,10,5,6]
-wrap' :: RealFracE n => n -> n -> n -> n
-wrap' i j k =
-    let r = j - i + 1
-    in if k >= i && k <= j
-       then k
-       else k - r * floorE ((k-i) / r)
-
--- | Generic variant of 'wrap''.
---
--- > > [5,6].wrap(0,5) == [5,0]
--- > map (genericWrap 0 5) [5,6] == [5,0]
---
--- > > [9,10,5,6,7,8,9,10,5,6].wrap(5,10) == [9,10,5,6,7,8,9,10,5,6]
--- > map (genericWrap (5::Integer) 10) [3..12] == [9,10,5,6,7,8,9,10,5,6]
-genericWrap :: (Ord a, Num a) => a -> a -> a -> a
-genericWrap l r n =
-    let d = r - l + 1
-        f = genericWrap l r
-    in if n < l
-       then f (n + d)
-       else if n > r then f (n - d) else n
-
--- | Variant of 'wrap'' with @SC3@ argument ordering.
---
--- > map (\n -> wrap_ n 5 10) [3..12] == map (wrap' 5 10) [3..12]
-wrap_ :: RealFracE n => n -> n -> n -> n
-wrap_ a b c = wrap' b c a
-
--- | Fold /k/ to within range /(i,j)/, ie. @AbstractFunction.fold@
---
--- > map (foldToRange 5 10) [3..12] == [7,6,5,6,7,8,9,10,9,8]
-foldToRange :: (Ord a,Num a) => a -> a -> a -> a
-foldToRange i j =
-    let f n = if n > j
-              then f (j - (n - j))
-              else if n < i
-                   then f (i - (n - i))
-                   else n
-    in f
-
--- | Variant of 'foldToRange' with @SC3@ argument ordering.
-fold_ :: (Ord a,Num a) => a -> a -> a -> a
-fold_ n i j = foldToRange i j n
-
--- | Clip /k/ to within range /(i,j)/,
---
--- > map (clip' 5 10) [3..12] == [5,5,5,6,7,8,9,10,10,10]
-clip' :: (Ord a) => a -> a -> a -> a
-clip' i j n = if n < i then i else if n > j then j else n
-
--- | Variant of 'clip'' with @SC3@ argument ordering.
-clip_ :: (Ord a) => a -> a -> a -> a
-clip_ n i j = clip' i j n
-
-hypot_ :: (Floating a) => a -> a -> a
-hypot_ x y = sqrt (x * x + y * y)
-
--- | Calculate multiplier and add values for 'linLin' transform.
---
--- > range_muladd 3 4 == (0.5,3.5)
--- > linLin_muladd (-1) 1 3 4 == (0.5,3.5)
--- > linLin_muladd 0 1 3 4 == (1,3)
--- > linLin_muladd (-1) 1 0 1 == (0.5,0.5)
-linLin_muladd :: Fractional t => t -> t -> t -> t -> (t, t)
-linLin_muladd sl sr dl dr =
-    let m = (dr - dl) / (sr - sl)
-        a = dl - (m * sl)
-    in (m,a)
+instance MulAdd UGen where mul_add = mulAdd
+instance MulAdd Float where
+instance MulAdd Double where
 
 -- | Map from one linear range to another linear range.
-linlin :: (Fractional a,TernaryOp a) => a -> a -> a -> a -> a -> a
-linlin i sl sr dl dr = let (m,a) = linLin_muladd sl sr dl dr in mul_add i m a
-
--- | Variant without 'TernaryOp' constraint.
-linlin' :: Fractional a => a -> a -> a -> a -> a -> a
-linlin' i sl sr dl dr = let (m,a) = linLin_muladd sl sr dl dr in i * m + a
+linlin_ma :: (Fractional a,MulAdd a) => a -> a -> a -> a -> a -> a
+linlin_ma i sl sr dl dr = let (m,a) = linlin_muladd sl sr dl dr in mul_add i m a
 
 -- | Scale uni-polar (0,1) input to linear (l,r) range
---
--- > map (urange 3 4) [0,0.5,1] == [3,3.5,4]
-urange :: (Fractional a,TernaryOp a) => a -> a -> a -> a
-urange l r i = let m = r - l in mul_add i m l
-
--- | Variant without 'TernaryOp' constraint.
-urange' :: Fractional a => a -> a -> a -> a
-urange' l r i = let m = r - l in i * m + l
-
--- | Calculate multiplier and add values for 'range' transform.
---
--- > range_muladd 3 4 == (0.5,3.5)
-range_muladd :: Fractional t => t -> t -> (t, t)
-range_muladd = linLin_muladd (-1) 1
+urange_ma :: (Fractional a,MulAdd a) => a -> a -> a -> a
+urange_ma l r i = let m = r - l in mul_add i m l
 
 -- | Scale bi-polar (-1,1) input to linear (l,r) range.  Note that the
 -- argument order is not the same as 'linLin'.
---
--- > map (range 3 4) [-1,0,1] == [3,3.5,4]
--- > map (\x -> let (m,a) = linLin_muladd (-1) 1 3 4 in x * m + a) [-1,0,1]
-range :: (Fractional a,TernaryOp a) => a -> a -> a -> a
-range l r i = let (m,a) = range_muladd l r in mul_add i m a
-
--- | Variant without 'TernaryOp' constraint.
-range' :: Fractional a => a -> a -> a -> a
-range' l r i = let (m,a) = range_muladd l r in i * m + a
+range_ma :: (Fractional a,MulAdd a) => a -> a -> a -> a
+range_ma l r i = let (m,a) = range_muladd l r in mul_add i m a
diff --git a/Sound/SC3/UGen/Math/Composite.hs b/Sound/SC3/UGen/Math/Composite.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/Math/Composite.hs
@@ -0,0 +1,20 @@
+module Sound.SC3.UGen.Math.Composite where
+
+import Sound.SC3.UGen.Math
+import Sound.SC3.UGen.Type
+import Sound.SC3.UGen.UGen
+
+ugen_if :: Num a => a -> a -> a -> a
+ugen_if p q r = (p * q) + ((1 - p) * r)
+
+-- > ugen_integral_and_fractional_parts 1.5 == mce2 1 0.5
+ugen_integral_and_fractional_parts :: UGen -> UGen
+ugen_integral_and_fractional_parts n =
+    let gt_eq_0 = let n' = floorE n in mce2 n' (n - n')
+        lt_0 = let n' = ceilingE n in mce2 n' (n - n')
+    in ugen_if (n >=* 0) gt_eq_0 lt_0
+
+ugen_fmidi_to_midi_detune :: UGen -> UGen
+ugen_fmidi_to_midi_detune mnn =
+    let (n,c) = unmce2 (ugen_integral_and_fractional_parts mnn)
+    in mce2 n (c * 100)
diff --git a/Sound/SC3/UGen/Name.hs b/Sound/SC3/UGen/Name.hs
--- a/Sound/SC3/UGen/Name.hs
+++ b/Sound/SC3/UGen/Name.hs
@@ -7,7 +7,7 @@
 import Data.Char {- base -}
 import Data.List.Split {- split -}
 
-import Sound.SC3.Common
+import Sound.SC3.Common.Prelude {- hsc3 -}
 import Sound.SC3.UGen.Rate {- hsc3 -}
 
 -- | Convert from @hsc3@ name to @SC3@ name.
@@ -15,19 +15,19 @@
 -- > toSC3Name "sinOsc" == "SinOsc"
 -- > toSC3Name "lfSaw" == "LFSaw"
 -- > toSC3Name "pv_Copy" == "PV_Copy"
--- > map toSC3Name ["bpf","fft","tpv","out","in'"]
+-- > map toSC3Name ["bpf","fft","tpv","out","in'","fbSineN"]
 toSC3Name :: String -> String
 toSC3Name nm =
     case nm of
       "in'" -> "In"
       "bpz2" -> "BPZ2"
       "brz2" -> "BRZ2"
-      "hpz1" -> "HPZ1"
       "ifft" -> "IFFT"
-      "lpz1" -> "LPZ1"
       "out" -> "Out"
       "rhpf" -> "RHPF"
       "rlpf" -> "RLPF"
+      'f':'b':nm' -> "FB" ++ nm'
+      'h':'p':'z':nm' -> "HPZ" ++ nm'
       'l':'f':'d':nm' -> "LFD" ++ nm'
       'l':'p':'z':nm' -> "LPZ" ++ nm'
       'l':'f':nm' -> "LF" ++ nm'
@@ -39,8 +39,8 @@
 
 -- | Inverse of 'toSC3Name'.
 --
--- > let nm = ["SinOsc","LFSaw","PV_Copy"]
--- > in map fromSC3Name nm == ["sinOsc","lfSaw","pv_Copy"]
+-- > let nm = ["SinOsc","LFSaw","PV_Copy","FBSineN"]
+-- > in map fromSC3Name nm == ["sinOsc","lfSaw","pv_Copy","fbSineN"]
 --
 -- > map fromSC3Name ["BPF","FFT","TPV"] == ["bpf","fft","tpv"]
 --
@@ -51,13 +51,13 @@
       "In" -> "in'"
       "BPZ2" -> "bpz2"
       "BRZ2" -> "brz2"
-      "HPZ1" -> "hpz1"
       "IFFT" -> "ifft"
-      "LPZ1" -> "lpz1"
       "RHPF" -> "rhpf"
       "RLPF" -> "rlpf"
+      'F':'B':nm' -> "fb" ++ nm'
+      'H':'P':'Z':nm' -> "hpz" ++ nm'
       'L':'F':'D':nm' -> "lfd" ++ nm'
-      'l':'p':'z':nm' -> "lpz" ++ nm'
+      'L':'P':'Z':nm' -> "lpz" ++ nm'
       'L':'F':nm' -> "lf" ++ nm'
       'P':'V':'_':nm' -> "pv_" ++ nm'
       p:q -> if all isUpper nm && length nm <= 3
@@ -66,14 +66,15 @@
       [] -> []
 
 -- | Find SC3 name edges.
+--
+-- > sc3_name_edges "SinOsc" == [False,False,False,True,False,False]
 sc3_name_edges :: String -> [Bool]
 sc3_name_edges =
     let f t = case t of
                 (Nothing,_,_) -> False
                 (Just p,q,Just r) ->
                     (isLower p && isUpper q) ||
-                    (isUpper p && isUpper q && isLower r &&
-                     (not (p == 'U' && q == 'G' && r == 'e')))
+                    (isUpper p && isUpper q && isLower r && [p,q,r] /= "UGe")
                 (Just p,q,Nothing) -> isLower p && isUpper q
     in map f . pcn_triples
 
diff --git a/Sound/SC3/UGen/Operator.hs b/Sound/SC3/UGen/Operator.hs
--- a/Sound/SC3/UGen/Operator.hs
+++ b/Sound/SC3/UGen/Operator.hs
@@ -2,9 +2,10 @@
 -- that conflict with existing names have a @_@ suffix.
 module Sound.SC3.UGen.Operator where
 
+import Control.Monad {- base -}
 import Data.Maybe {- base -}
 
-import Sound.SC3.Common
+import Sound.SC3.Common.Prelude {- hsc3 -}
 
 -- * Unary
 
@@ -67,7 +68,7 @@
 
 -- | Type-specialised 'parse_enum'.
 parse_unary :: Case_Rule -> String -> Maybe Unary
-parse_unary cr = parse_enum cr
+parse_unary = parse_enum
 
 -- | Table of symbolic names for standard unary operators.
 unaryTable :: [(Unary,String)]
@@ -81,24 +82,26 @@
 
 -- | Given name of unary operator derive index.
 --
--- > mapMaybe (unaryIndex True) (words "NEG CUBED") == [0,13]
--- > unaryIndex True "SinOsc" == Nothing
+-- > mapMaybe (unaryIndex CI) (words "NEG CUBED") == [0,13]
+-- > unaryIndex CS "SinOsc" == Nothing
 unaryIndex :: Case_Rule -> String -> Maybe Int
 unaryIndex cr nm =
     let ix = rlookup_str cr nm unaryTable
         ix' = parse_unary cr nm
-    in fmap fromEnum (maybe ix' Just ix)
+    in fmap fromEnum (mplus ix' ix)
 
 -- | 'isJust' of 'unaryIndex'.
 --
--- > map (is_unary True) (words "ABS MIDICPS NEG")
--- > map (is_unary True) (words "- RAND")
+-- > map (is_unary CI) (words "ABS MIDICPS NEG")
+-- > map (is_unary CI) (words "- RAND")
 is_unary :: Case_Rule -> String -> Bool
 is_unary cr = isJust . unaryIndex cr
 
 -- * Binary
 
 -- | Enumeration of @SC3@ unary operator UGens.
+--
+-- > map show [minBound :: Binary .. maxBound]
 data Binary = Add -- 0
             | Sub -- 1
             | Mul -- 2
@@ -152,7 +155,7 @@
 
 -- | Type-specialised 'parse_enum'.
 parse_binary :: Case_Rule -> String -> Maybe Binary
-parse_binary cr = parse_enum cr
+parse_binary = parse_enum
 
 -- | Table of symbolic names for standard binary operators.
 binaryTable :: [(Binary,String)]
@@ -180,17 +183,17 @@
 
 -- | Given name of binary operator derive index.
 --
--- > mapMaybe (binaryIndex True) (words "* MUL RING1") == [2,2,30]
--- > binaryIndex True "SINOSC" == Nothing
+-- > mapMaybe (binaryIndex CI) (words "* MUL RING1") == [2,2,30]
+-- > binaryIndex CI "SINOSC" == Nothing
 binaryIndex :: Case_Rule -> String -> Maybe Int
 binaryIndex cr nm =
     let ix = rlookup_str cr nm binaryTable
         ix' = parse_binary cr nm
-    in fmap fromEnum (maybe ix' Just ix)
+    in fmap fromEnum (mplus ix' ix)
 
 -- | 'isJust' of 'binaryIndex'.
 --
--- > map (is_binary True) (words "== > % TRUNC MAX")
+-- > map (is_binary CI) (words "== > % TRUNC MAX")
 is_binary :: Case_Rule -> String -> Bool
 is_binary cr = isJust . binaryIndex cr
 
@@ -198,7 +201,7 @@
 
 -- | Order of lookup: binary then unary.
 --
--- > map (resolve_operator True) (words "+ - ADD SUB NEG")
+-- > map (resolve_operator CI) (words "+ - ADD SUB NEG")
 resolve_operator :: Case_Rule -> String -> (String,Maybe Int)
 resolve_operator cr nm =
     case binaryIndex cr nm of
diff --git a/Sound/SC3/UGen/Plain.hs b/Sound/SC3/UGen/Plain.hs
--- a/Sound/SC3/UGen/Plain.hs
+++ b/Sound/SC3/UGen/Plain.hs
@@ -1,4 +1,4 @@
-
+-- | Plain notation for SuperCollider UGen graphs.
 --
 -- > let {s = ugen "SinOsc" AR [440,0] 1
 -- >     ;m = binop "*" AR s 0.1
@@ -8,7 +8,7 @@
 -- > audition (out 0 (sinOsc AR 440 0 * 0.1))
 module Sound.SC3.UGen.Plain where
 
-import Sound.SC3.Common
+import Sound.SC3.Common.Prelude
 import Sound.SC3.UGen.Operator
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
@@ -19,7 +19,7 @@
 
 -- | Construct unary operator, the name can textual or symbolic.
 --
--- > uop True "NEG" AR 1
+-- > uop CI "NEG" AR 1
 uop :: Case_Rule -> String -> Rate -> UGen -> UGen
 uop cr nm r p =
     case unaryIndex cr nm of
@@ -28,8 +28,8 @@
 
 -- | Construct binary operator, the name can textual or symbolic.
 --
--- > binop True "*" AR 1 2 == binop True "MUL" AR 1 2
--- > binop False "*" AR (ugen "SinOsc" AR [440,0] 1) 0.1 == sinOsc AR 440 0 * 0.1
+-- > binop CI "*" AR 1 2 == binop CI "MUL" AR 1 2
+-- > binop CS "*" AR (ugen "SinOsc" AR [440,0] 1) 0.1 == sinOsc AR 440 0 * 0.1
 binop :: Case_Rule -> String -> Rate -> UGen -> UGen -> UGen
 binop cr nm r p q =
     case binaryIndex cr nm of
diff --git a/Sound/SC3/UGen/Type.hs b/Sound/SC3/UGen/Type.hs
--- a/Sound/SC3/UGen/Type.hs
+++ b/Sound/SC3/UGen/Type.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE CPP #-}
-
 --  | Unit Generator ('UGen'), and associated types and instances.
 module Sound.SC3.UGen.Type where
 
@@ -18,7 +16,7 @@
 
 -- | Data type for internalised identifier at 'UGen'.
 data UGenId = NoId | UId Int
-              deriving (Eq,Show)
+              deriving (Eq,Read,Show)
 
 -- | Alias of 'NoId', the 'UGenId' used for deterministic UGens.
 no_id :: UGenId
@@ -35,7 +33,7 @@
 -- > Constant 3 == Constant 3
 -- > (Constant 3 > Constant 1) == True
 data Constant = Constant {constantValue :: Sample}
-                deriving (Eq,Ord,Show)
+                deriving (Eq,Ord,Read,Show)
 
 -- | Control meta-data.
 data C_Meta n =
@@ -45,14 +43,14 @@
            ,ctl_step :: n -- ^ The step to increment & decrement by.
            ,ctl_units :: String -- ^ Unit of measure (ie hz, ms etc.).
            }
-    deriving (Eq,Show)
+    deriving (Eq,Read,Show)
 
 -- | 5-tuple form of 'C_Meta' data.
-type C_Meta' n = (n,n,String,n,String)
+type C_Meta_T5 n = (n,n,String,n,String)
 
--- | Lift 'C_Meta'' to 'C_Meta' allowing type coercion.
-c_meta' :: (n -> m) -> C_Meta' n -> C_Meta m
-c_meta' f (l,r,w,stp,u) = C_Meta (f l) (f r) w (f stp) u
+-- | Lift 'C_Meta_5' to 'C_Meta' allowing type coercion.
+c_meta_t5 :: (n -> m) -> C_Meta_T5 n -> C_Meta m
+c_meta_t5 f (l,r,w,stp,u) = C_Meta (f l) (f r) w (f stp) u
 
 -- | Control inputs.  It is an invariant that controls with equal
 -- names within a UGen graph must be equal in all other respects.
@@ -62,18 +60,18 @@
                        ,controlDefault :: Sample
                        ,controlTriggered :: Bool
                        ,controlMeta :: Maybe (C_Meta Sample)}
-               deriving (Eq,Show)
+               deriving (Eq,Read,Show)
 
 -- | Labels.
 data Label = Label {ugenLabel :: String}
-             deriving (Eq,Show)
+             deriving (Eq,Read,Show)
 
 -- | Unit generator output descriptor.
 type Output = Rate
 
 -- | Operating mode of unary and binary operators.
 newtype Special = Special Int
-    deriving (Eq, Show)
+    deriving (Eq,Read,Show)
 
 -- | UGen primitives.
 data Primitive = Primitive {ugenRate :: Rate
@@ -82,17 +80,17 @@
                            ,ugenOutputs :: [Output]
                            ,ugenSpecial :: Special
                            ,ugenId :: UGenId}
-                 deriving (Eq,Show)
+                 deriving (Eq,Read,Show)
 
 -- | Proxy to multiple channel input.
 data Proxy = Proxy {proxySource :: Primitive
                    ,proxyIndex :: Int}
-            deriving (Eq,Show)
+            deriving (Eq,Read,Show)
 
 -- | Multiple root graph.
 data MRG = MRG {mrgLeft :: UGen
                ,mrgRight :: UGen}
-           deriving (Eq,Show)
+           deriving (Eq,Read,Show)
 
 -- | Union type of Unit Generator forms.
 data UGen = Constant_U Constant
@@ -102,15 +100,16 @@
           | Proxy_U Proxy
           | MCE_U (MCE UGen)
           | MRG_U MRG
-            deriving (Eq,Show)
+            deriving (Eq,Read,Show)
 
 -- * Parser
 
+-- | Type-specialised 'R.readMaybe'.
+parse_double :: String -> Maybe Double
+parse_double = R.readMaybe
+
 parse_constant :: String -> Maybe UGen
-parse_constant s =
-    let d :: Maybe Double
-        d = R.readMaybe s
-    in fmap constant d
+parse_constant = fmap constant . parse_double
 
 -- * Accessors
 
@@ -125,19 +124,39 @@
 u_constant :: UGen -> Maybe Sample
 u_constant = fmap constantValue . un_constant
 
+-- | Erroring variant.
+u_constant_err :: UGen -> Sample
+u_constant_err = fromMaybe (error "u_constant") . u_constant
+
+-- * MRG
+
+-- | Multiple root graph constructor.
+mrg :: [UGen] -> UGen
+mrg u =
+    case u of
+      [] -> error "mrg: []"
+      [x] -> x
+      (x:xs) -> MRG_U (MRG x (mrg xs))
+
+-- | See into 'MRG_U', follows leftmost rule until arriving at non-MRG node.
+mrg_leftmost :: UGen -> UGen
+mrg_leftmost u =
+    case u of
+      MRG_U m -> mrg_leftmost (mrgLeft m)
+      _ -> u
+
 -- * Predicates
 
 -- | Constant node predicate.
 isConstant :: UGen -> Bool
 isConstant = isJust . un_constant
 
--- | True if input is a sink 'UGen', ie. has no outputs.
+-- | True if input is a sink 'UGen', ie. has no outputs.  Sees into MRG.
 isSink :: UGen -> Bool
 isSink u =
-    case u of
+    case mrg_leftmost u of
       Primitive_U p -> null (ugenOutputs p)
-      MCE_U m -> all isSink (mceProxies m)
-      MRG_U m -> isSink (mrgLeft m)
+      MCE_U m -> all isSink (mce_elem m)
       _ -> False
 
 -- | See into 'Proxy_U'.
@@ -150,32 +169,7 @@
 isProxy :: UGen -> Bool
 isProxy = isJust . un_proxy
 
--- * Validators
-
--- | Ensure input 'UGen' is valid, ie. not a sink.
-checkInput :: UGen -> UGen
-checkInput u =
-    if isSink u
-    then error ("checkInput: " ++ show u)
-    else u
-
--- * Constructors
-
--- | Constant value node constructor.
-constant :: Real n => n -> UGen
-constant = Constant_U . Constant . realToFrac
-
--- | Type specialised 'constant'.
-int_to_ugen :: Int -> UGen
-int_to_ugen = constant
-
--- | Type specialised 'constant'.
-float_to_ugen :: Float -> UGen
-float_to_ugen = constant
-
--- | Type specialised 'constant'.
-double_to_ugen :: Double -> UGen
-double_to_ugen = constant
+-- * MCE
 
 -- | Multiple channel expansion node constructor.
 mce :: [UGen] -> UGen
@@ -185,52 +179,39 @@
       [x] -> x
       _ -> MCE_U (MCE_Vector xs)
 
--- | Multiple root graph constructor.
-mrg :: [UGen] -> UGen
-mrg u =
-    case u of
-      [] -> error "mrg: []"
-      [x] -> x
-      (x:xs) -> MRG_U (MRG x (mrg xs))
-
--- | Unit generator proxy node constructor.
-proxy :: UGen -> Int -> UGen
-proxy u n =
-    case u of
-      Primitive_U p -> Proxy_U (Proxy p n)
-      _ -> error "proxy: not primitive"
-
--- * MCE
-
 -- | Type specified 'mce_elem'.
 mceProxies :: MCE UGen -> [UGen]
 mceProxies = mce_elem
 
--- | Multiple channel expansion node ('MCE_U') predicate.
+-- | Multiple channel expansion node ('MCE_U') predicate.  Sees into MRG.
 isMCE :: UGen -> Bool
 isMCE u =
-    case u of
+    case mrg_leftmost u of
       MCE_U _ -> True
-      MRG_U (MRG u' _) -> isMCE u'
       _ -> False
 
--- | Output channels of UGen as a list.
+-- | Output channels of UGen as a list.  If required, preserves the
+-- RHS of and MRG node in channel 0.
 mceChannels :: UGen -> [UGen]
 mceChannels u =
     case u of
-      MCE_U m -> mceProxies m
+      MCE_U m -> mce_elem m
       MRG_U (MRG x y) -> let r:rs = mceChannels x in MRG_U (MRG r y) : rs
       _ -> [u]
 
--- | Number of channels to expand to.
-mceDegree :: UGen -> Int
+-- | Number of channels to expand to.  This function sees into MRG,
+-- and is defined only for MCE nodes.
+mceDegree :: UGen -> Maybe Int
 mceDegree u =
-    case u of
-      MCE_U m -> length (mceProxies m)
-      MRG_U (MRG x _) -> mceDegree x
-      _ -> error "mceDegree: not mce"
+    case mrg_leftmost u of
+      MCE_U m -> Just (length (mceProxies m))
+      _ -> Nothing
 
--- | Extend UGen to specified degree.
+-- | Erroring variant.
+mceDegree_err :: UGen -> Int
+mceDegree_err = fromMaybe (error "mceDegree: not mce") . mceDegree
+
+-- | Extend UGen to specified degree.  Follows "leftmost" rule for MRG nodes.
 mceExtend :: Int -> UGen -> [UGen]
 mceExtend n u =
     case u of
@@ -243,7 +224,7 @@
 mceInputTransform :: [UGen] -> Maybe [[UGen]]
 mceInputTransform i =
     if any isMCE i
-    then let n = maximum (map mceDegree (filter isMCE i))
+    then let n = maximum (map mceDegree_err (filter isMCE i))
          in Just (transpose (map (mceExtend n) i))
     else Nothing
 
@@ -255,6 +236,7 @@
       Just i' -> MCE_U (MCE_Vector (map (mceBuild f) i'))
 
 -- | True if MCE is an immediate proxy for a multiple-out Primitive.
+--   This is useful when disassembling graphs, ie. ugen_graph_forth_pp at hsc3-db.
 mce_is_direct_proxy :: MCE UGen -> Bool
 mce_is_direct_proxy m =
     case m of
@@ -266,6 +248,40 @@
              length (nub (map proxySource p')) == 1 &&
              map proxyIndex p' `isPrefixOf` [0..]
 
+-- * Validators
+
+-- | Ensure input 'UGen' is valid, ie. not a sink.
+checkInput :: UGen -> UGen
+checkInput u =
+    if isSink u
+    then error ("checkInput: " ++ show u)
+    else u
+
+-- * Constructors
+
+-- | Constant value node constructor.
+constant :: Real n => n -> UGen
+constant = Constant_U . Constant . realToFrac
+
+-- | Type specialised 'constant'.
+int_to_ugen :: Int -> UGen
+int_to_ugen = constant
+
+-- | Type specialised 'constant'.
+float_to_ugen :: Float -> UGen
+float_to_ugen = constant
+
+-- | Type specialised 'constant'.
+double_to_ugen :: Double -> UGen
+double_to_ugen = constant
+
+-- | Unit generator proxy node constructor.
+proxy :: UGen -> Int -> UGen
+proxy u n =
+    case u of
+      Primitive_U p -> Proxy_U (Proxy p n)
+      _ -> error "proxy: not primitive"
+
 -- | Determine the rate of a UGen.
 rateOf :: UGen -> Rate
 rateOf u =
@@ -282,7 +298,7 @@
 proxify :: UGen -> UGen
 proxify u =
     case u of
-      MCE_U m -> mce (map proxify (mceProxies m))
+      MCE_U m -> mce (map proxify (mce_elem m))
       MRG_U m -> mrg [proxify (mrgLeft m), mrgRight m]
       Primitive_U p ->
           let o = ugenOutputs p
@@ -300,7 +316,7 @@
           String -> [UGen] -> Maybe UGen -> Int -> Special -> UGenId -> UGen
 mkUGen cf rs r nm i i_mce o s z =
     let i' = maybe i ((i ++) . mceChannels) i_mce
-        f h = let r' = either id (maximum . map (rateOf . (atNote ("mkUGen: " ++ nm) h))) r
+        f h = let r' = either id (maximum . map (rateOf . atNote ("mkUGen: " ++ nm) h)) r
                   o' = replicate o r'
                   u = Primitive_U (Primitive r' nm h o' s z)
               in if r' `elem` rs
@@ -352,8 +368,7 @@
    in fromMaybe (mkOperator g "BinaryOpUGen" [a, b] (fromEnum i)) r
 
 -- | Binary math constructor with constant optimization.
-mkBinaryOperator :: Binary -> (Sample -> Sample -> Sample) ->
-                    UGen -> UGen -> UGen
+mkBinaryOperator :: Binary -> (Sample -> Sample -> Sample) -> UGen -> UGen -> UGen
 mkBinaryOperator i f a b =
    let g [x,y] = f x y
        g _ = error "mkBinaryOperator: non binary input"
@@ -468,9 +483,7 @@
     bit = error "UGen.bit"
     testBit = error "UGen.testBit"
     popCount = error "UGen.popCount"
-#if MIN_VERSION_base(4,7,0)
     bitSizeMaybe = error "UGen.bitSizeMaybe"
-#endif
     isSigned _ = True
 
 {-
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
@@ -5,22 +5,23 @@
 import Data.Maybe {- base -}
 import Data.List {- base -}
 
-import Sound.SC3.UGen.Identifier
-import Sound.SC3.UGen.MCE
-import Sound.SC3.UGen.Operator
-import Sound.SC3.UGen.Rate
+import qualified Sound.SC3.Common.Envelope as E
+import qualified Sound.SC3.Common.Prelude as P
+import qualified Sound.SC3.UGen.Identifier as ID
+import qualified Sound.SC3.UGen.Operator as O
+import qualified Sound.SC3.UGen.Rate as R
 import Sound.SC3.UGen.Type
 
 -- | 'UId' of 'resolveID'.
-toUId :: (ID a) => a -> UGenId
-toUId = UId . resolveID
+toUId :: ID.ID a => a -> UGenId
+toUId = UId . ID.resolveID
 
 -- | Lookup operator name for operator UGens, else UGen name.
 ugen_user_name :: String -> Special -> String
 ugen_user_name nm (Special n) =
     case nm of
-      "UnaryOpUGen" -> unaryName n
-      "BinaryOpUGen" -> binaryName n
+      "UnaryOpUGen" -> O.unaryName n
+      "BinaryOpUGen" -> O.binaryName n
       _ -> nm
 
 -- * UGen graph functions
@@ -28,61 +29,61 @@
 -- | Depth first traversal of graph at `u' applying `f' to each node.
 ugenTraverse :: (UGen -> UGen) -> UGen -> UGen
 ugenTraverse f u =
-    let rec = ugenTraverse f
+    let recur = ugenTraverse f
     in case u of
          Primitive_U p ->
              let i = ugenInputs p
-             in f (Primitive_U (p {ugenInputs = map rec i}))
+             in f (Primitive_U (p {ugenInputs = map recur i}))
          Proxy_U p ->
              let s = Primitive_U (proxySource p)
-             in case rec s of
+             in case recur s of
                   Primitive_U p' -> f (Proxy_U (p {proxySource = p'}))
                   _ -> error "ugenTraverse"
-         MCE_U m -> f (mce (map rec (mceProxies m)))
-         MRG_U (MRG l r) -> f (MRG_U (MRG (rec l) (rec r)))
+         MCE_U m -> f (mce (map recur (mceProxies m)))
+         MRG_U (MRG l r) -> f (MRG_U (MRG (recur l) (recur r)))
          _ -> f u
 
 -- | Right fold of UGen graph.
 ugenFoldr :: (UGen -> a -> a) -> a -> UGen -> a
 ugenFoldr f st u =
-    let rec = flip (ugenFoldr f)
+    let recur = flip (ugenFoldr f)
     in case u of
          Primitive_U p ->
              let i = ugenInputs p
-             in f u (foldr rec st i)
+             in f u (foldr recur st i)
          Proxy_U p ->
              let s = proxySource p
              in f u (f (Primitive_U s) st)
-         MCE_U m -> f u (foldr rec st (mceProxies m))
+         MCE_U m -> f u (foldr recur st (mceProxies m))
          MRG_U (MRG l r) -> f u (f l (f r st))
          _ -> f u st
 
 -- * Unit generator node constructors
 
 -- | Control input node constructor.
-control_f64 :: Rate -> Maybe Int -> String -> Sample -> UGen
+control_f64 :: R.Rate -> Maybe Int -> String -> Sample -> UGen
 control_f64 r ix nm d = Control_U (Control r ix nm d False Nothing)
 
 -- | Control input node constructor.
 --
 -- Note that if the name begins with a t_ prefix the control is /not/
 -- converted to a triggered control.  Please see 'tr_control'.
-control :: Rate -> String -> Double -> UGen
-control r nm = control_f64 r Nothing nm -- . realToFrac
+control :: R.Rate -> String -> Double -> UGen
+control r = control_f64 r Nothing
 
 -- | Variant of 'control' with meta data.
-meta_control :: Rate -> String -> Double -> C_Meta' Double -> UGen
+meta_control :: R.Rate -> String -> Double -> C_Meta_T5 Double -> UGen
 meta_control rt nm df meta =
-    let m = c_meta' id meta
+    let m = c_meta_t5 id meta
     in Control_U (Control rt Nothing nm df False (Just m))
 
 -- | Triggered (kr) control input node constructor.
 tr_control_f64 :: Maybe Int -> String -> Sample -> UGen
-tr_control_f64 ix nm d = Control_U (Control KR ix nm d True Nothing)
+tr_control_f64 ix nm d = Control_U (Control R.KR ix nm d True Nothing)
 
 -- | Triggered (kr) control input node constructor.
 tr_control :: String -> Double -> UGen
-tr_control nm = tr_control_f64 Nothing nm -- . realToFrac
+tr_control = tr_control_f64 Nothing
 
 -- | Set indices at a list of controls.
 control_set :: [UGen] -> [UGen]
@@ -102,16 +103,22 @@
 mce2 :: UGen -> UGen -> UGen
 mce2 x y = mce [x,y]
 
--- | Extract two channels from possible MCE.
+-- | Extract two channels from possible MCE, if there is only one
+-- channel it is duplicated.
 mce2c :: UGen -> (UGen,UGen)
 mce2c u =
-    case u of
-      MCE_U m -> case mceProxies m of
-                     [] -> error "mce2c: nil mce"
-                     p:[] -> (p,p)
-                     p:q:_ -> (p,q)
-      _ -> (u,u)
+    case mceChannels u of
+      [] -> error "mce2c"
+      [p] -> (p,p)
+      p:q:_ -> (p,q)
 
+t2_from_list :: [t] -> (t,t)
+t2_from_list l = case l of {[p,q] -> (p,q);_ -> error "t2_from_list"}
+
+-- | Variant of 'mce2c' that requires input to have two channels.
+unmce2 :: UGen -> (UGen, UGen)
+unmce2 = t2_from_list . mceChannels
+
 -- | Multiple channel expansion for two inputs.
 mce3 :: UGen -> UGen -> UGen -> UGen
 mce3 x y z = mce [x,y,z]
@@ -120,6 +127,14 @@
 mceMap :: (UGen -> UGen) -> UGen -> UGen
 mceMap f u = mce (map f (mceChannels u))
 
+-- | Map with element index.
+map_ix :: ((Int,a) -> b) -> [a] -> [b]
+map_ix f = map f . zip [0..]
+
+-- | Variant of 'mceMap' with element index.
+mce_map_ix :: ((Int,UGen) -> UGen) -> UGen -> UGen
+mce_map_ix f u = mce (map_ix f (mceChannels u))
+
 -- | Apply UGen list operation on MCE contents.
 mceEdit :: ([UGen] -> [UGen]) -> UGen -> UGen
 mceEdit f u =
@@ -148,27 +163,10 @@
 
 -- * Transform
 
--- | Separate first list element.
---
--- > sep_first "astring" == Just ('a',"string")
-sep_first :: [t] -> Maybe (t,[t])
-sep_first l =
-    case l of
-      e:l' -> Just (e,l')
-      _ -> Nothing
-
--- | Separate last list element.
---
--- > sep_last "stringb" == Just ("string",'b')
-sep_last :: [t] -> Maybe ([t], t)
-sep_last =
-    let f (e,l) = (reverse l,e)
-    in fmap f . sep_first . reverse
-
 -- | Given /unmce/ function make halt mce transform.
 halt_mce_transform' :: (a -> [a]) -> [a] -> [a]
 halt_mce_transform' f l =
-    let (l',e) = fromMaybe (error "halt_mce_transform: null?") (sep_last l)
+    let (l',e) = fromMaybe (error "halt_mce_transform: null?") (P.sep_last l)
     in l' ++ f e
 
 -- | The halt MCE transform, ie. lift channels of last input into list.
@@ -185,13 +183,6 @@
 label :: String -> UGen
 label = Label_U . Label
 
--- | Are lists of equal length?
---
--- > equal_length_p ["t1","t2"] == True
--- > equal_length_p ["t","t1","t2"] == False
-equal_length_p :: [[a]] -> Bool
-equal_length_p = (== 1) . length . nub . map length
-
 -- | Unpack a label to a length prefixed list of 'Constant's.  There
 -- is a special case for mce nodes, but it requires labels to be equal
 -- length.  Properly, 'poll' would not unpack the label, it would be
@@ -207,99 +198,43 @@
           in n : s'
       MCE_U m ->
           let x = map unpackLabel (mceProxies m)
-          in if equal_length_p x
+          in if P.equal_length_p x
              then map mce (transpose x)
              else error (show ("unpackLabel: mce length /=",x))
       _ -> error (show ("unpackLabel: non-label",u))
 
+-- * Envelope
+
+envelope_to_ugen :: E.Envelope UGen -> UGen
+envelope_to_ugen =
+    let err = error "envGen: bad Envelope"
+    in mce . fromMaybe err . E.envelope_sc3_array
+
 -- * Bitwise
 
 bitAnd :: UGen -> UGen -> UGen
-bitAnd = mkBinaryOperator BitAnd undefined
+bitAnd = mkBinaryOperator O.BitAnd undefined
 
 bitOr :: UGen -> UGen -> UGen
-bitOr = mkBinaryOperator BitOr undefined
+bitOr = mkBinaryOperator O.BitOr undefined
 
 bitXOr :: UGen -> UGen -> UGen
-bitXOr = mkBinaryOperator BitXor undefined
+bitXOr = mkBinaryOperator O.BitXor undefined
 
 bitNot :: UGen -> UGen
-bitNot = mkUnaryOperator BitNot undefined
+bitNot = mkUnaryOperator O.BitNot undefined
 
 shiftLeft :: UGen -> UGen -> UGen
-shiftLeft = mkBinaryOperator ShiftLeft undefined
+shiftLeft = mkBinaryOperator O.ShiftLeft undefined
 
 shiftRight :: UGen -> UGen -> UGen
-shiftRight = mkBinaryOperator ShiftRight undefined
+shiftRight = mkBinaryOperator O.ShiftRight undefined
 
 unsignedShift :: UGen -> UGen -> UGen
-unsignedShift = mkBinaryOperator UnsignedShift undefined
+unsignedShift = mkBinaryOperator O.UnsignedShift undefined
 
 (.<<.) :: UGen -> UGen -> UGen
 (.<<.) = shiftLeft
 
 (.>>.) :: UGen -> UGen -> UGen
 (.>>.) = shiftRight
-
--- * Analysis
-
--- | UGen primitive.  Sees through Proxy and MRG, possible multiple
--- primitives for MCE.
-ugen_primitive :: UGen -> [Primitive]
-ugen_primitive u =
-    case u of
-      Constant_U _ -> []
-      Control_U _ -> []
-      Label_U _ -> []
-      Primitive_U p -> [p]
-      Proxy_U p -> [proxySource p]
-      MCE_U m -> concatMap ugen_primitive (mce_elem m)
-      MRG_U m -> ugen_primitive (mrgLeft m)
-
--- | Heuristic based on primitive name (@FFT@, @PV_@).  Note that
--- @IFFT@ is at /control/ rate, not @PV@ rate.
-primitive_is_pv_rate :: String -> Bool
-primitive_is_pv_rate nm = nm == "FFT" || "PV_" `isPrefixOf` nm
-
--- | Variant on primitive_is_pv_rate.
-ugen_is_pv_rate :: UGen -> Bool
-ugen_is_pv_rate = any (primitive_is_pv_rate . ugenName)
-                  . ugen_primitive
-
--- | Traverse input graph until an @FFT@ or @PV_Split@ node is
--- encountered, and then locate the buffer input.  Biases left at MCE
--- nodes.
---
--- > import Sound.SC3
--- > let z = soundIn 4
--- > let f1 = fft 10 z 0.5 0 1 0
--- > let f2 = ffta 'a' 1024 z 0.5 0 1 0
--- > pv_track_buffer (pv_BrickWall f1 0.5) == Right 10
--- > pv_track_buffer (pv_BrickWall f2 0.5) == Right (localBuf 'a' 1024 1)
-pv_track_buffer :: UGen -> Either String UGen
-pv_track_buffer u =
-    case ugen_primitive u of
-      [] -> Left "pv_track_buffer: not located"
-      p:_ -> case ugenName p of
-               "FFT" -> Right (ugenInputs p !! 0)
-               "PV_Split" -> Right (ugenInputs p !! 1)
-               _ -> pv_track_buffer (ugenInputs p !! 0)
-
--- | Buffer node number of frames. Biases left at MCE nodes.  Sees
--- through @LocalBuf@, otherwise uses 'bufFrames'.
---
--- > buffer_nframes 10 == bufFrames IR 10
--- > buffer_nframes (control KR "b" 0) == bufFrames KR (control KR "b" 0)
--- > buffer_nframes (localBuf 'α' 2048 1) == 2048
-buffer_nframes :: UGen -> UGen
-buffer_nframes u =
-    let b = mkUGen Nothing [IR,KR] (Left (rateOf u)) "BufFrames" [u] Nothing 1 (Special 0) NoId
-    in case ugen_primitive u of
-         [] -> b
-         p:_ -> case ugenName p of
-                  "LocalBuf" -> ugenInputs p !! 1
-                  _ -> b
-
--- | 'pv_track_buffer' then 'buffer_nframes'.
-pv_track_nframes :: UGen -> Either String UGen
-pv_track_nframes u = pv_track_buffer u >>= Right . buffer_nframes
diff --git a/Sound/SC3/UGen/UId.hs b/Sound/SC3/UGen/UId.hs
--- a/Sound/SC3/UGen/UId.hs
+++ b/Sound/SC3/UGen/UId.hs
@@ -1,29 +1,54 @@
+{-# LANGUAGE FlexibleInstances #-}
+
 -- | Unique identifier class for use by non-deterministic (noise) and
 -- non-sharable (demand) unit generators.
 module Sound.SC3.UGen.UId where
 
-import Control.Applicative {- base -}
 import Control.Monad {- base -}
-import Control.Monad.IO.Class as M {- transformers -}
-import Control.Monad.Trans.Reader {- transformers -}
-import Data.Unique {- base -}
+import Data.Functor.Identity {- base -}
+import Data.List {- base -}
+import qualified Data.Unique as U {- base -}
 
-import Sound.OSC.Transport.FD as T {- hosc -}
+import qualified Control.Monad.Trans.Reader as R {- transformers -}
+import qualified Control.Monad.Trans.State as S {- transformers -}
 
-import Sound.SC3.UGen.Type
+import Sound.SC3.UGen.Type {- hsc3 -}
 
--- | A class indicating a monad that will generate a sequence of
---   unique integer identifiers.
-class (Functor m,Applicative m,M.MonadIO m) => UId m where
+-- | A class indicating a monad (and functor and applicative) that will
+-- generate a sequence of unique integer identifiers.
+class (Functor m,Applicative m,Monad m) => UId m where
    generateUId :: m Int
-   generateUId = fmap hashUnique (M.liftIO newUnique)
 
+-- | 'S.State' UId.
+type UId_ST = S.State Int
+
+-- | 'S.evalState' with initial state of zero.
+--
+-- > uid_st_eval (replicateM 3 generateUId) == [0,1,2]
+uid_st_eval :: UId_ST t -> t
+uid_st_eval x = S.evalState x 0
+
+-- | Thread state through sequence of 'S.runState'.
+uid_st_seq :: [UId_ST t] -> ([t],Int)
+uid_st_seq =
+    let swap (p,q) = (q,p)
+        step_f n x = swap (S.runState x n)
+    in swap . mapAccumL step_f 0
+
+-- | 'fst' of 'uid_st_seq'.
+--
+-- > uid_st_seq_ (replicate 3 generateUId) == [0,1,2]
+uid_st_seq_ :: [UId_ST t] -> [t]
+uid_st_seq_ = fst . uid_st_seq
+
+instance UId (S.StateT Int Identity) where
+    generateUId = S.get >>= \n -> S.put (n + 1) >> return n
+
 instance UId IO where
-    generateUId = liftM hashUnique newUnique
+    generateUId = liftM U.hashUnique U.newUnique
 
-instance (T.Transport t,Functor io,Applicative io,MonadIO io) =>
-    UId (ReaderT t io) where
-   generateUId = ReaderT (M.liftIO . const generateUId)
+instance UId m => UId (R.ReaderT t m) where
+   generateUId = R.ReaderT (const generateUId)
 
 -- * Lift
 
diff --git a/emacs/hsc3.el b/emacs/hsc3.el
--- a/emacs/hsc3.el
+++ b/emacs/hsc3.el
@@ -1,15 +1,13 @@
-;; This mode is implemented as a derivation of `haskell' mode,
-;; indentation and font locking is courtesy that mode.  The
-;; inter-process communication is courtesy `comint'.  The symbol at
-;; point acquisition is courtesy `thingatpt'.  The directory search
-;; facilities are courtesy `find-lisp'.
+;; Indentation and font locking is courtesy `haskell' mode.
+;; Inter-process communication is courtesy `comint' and `inf-haskell'.
+;; Symbol at point acquisition is courtesy `thingatpt'.
+;; Directory search facilities are courtesy `find-lisp'.
 
 (require 'scheme)
 (require 'comint)
 (require 'thingatpt)
 (require 'find-lisp)
 (require 'inf-haskell)
-;;(require 'sclang)
 
 (defvar hsc3-help-directory
   nil
@@ -21,6 +19,23 @@
 
 (make-variable-buffer-local 'hsc3-literate-p)
 
+(defun hsc3-chunk-string (n s)
+  "Split a string into chunks of 'n' characters."
+  (let* ((l (length s))
+         (m (min l n))
+         (c (substring s 0 m)))
+    (if (<= l n)
+        (list c)
+      (cons c (hsc3-chunk-string n (substring s n))))))
+
+(defun hsc3-send-string (s)
+  (if (comint-check-proc inferior-haskell-buffer)
+      (let ((cs (hsc3-chunk-string 64 (concat s "\n"))))
+        (mapcar
+         (lambda (c) (comint-send-string inferior-haskell-buffer c))
+         cs))
+    (error "no hsc3 process running?")))
+
 (defun hsc3-quit-haskell ()
   "Quit haskell."
   (interactive)
@@ -30,15 +45,10 @@
   "Remove bird literate marks and preceding comment marker"
    (replace-regexp-in-string "^[> ]* ?" "" s))
 
-;; (hsc3-uncomment "  no comment")
 (defun hsc3-uncomment (s)
   "Remove initial comment and Bird-literate markers if present."
    (replace-regexp-in-string "^[- ]*[> ]*" "" s))
 
-(defun hsc3-remove-non-literates (s)
-  "Remove non-bird literate lines"
-  (replace-regexp-in-string "^[^>]*$" "" s))
-
 (defun hsc3-help ()
   "Lookup up the name at point in the hsc3 help files."
   (interactive)
@@ -64,30 +74,15 @@
    (format "Sound.SC3.Server.Help.viewServerHelp \"%s\""
            (thing-at-point 'symbol))))
 
-(defun hsc3-sc3-forth-pp () "Forth PP" (interactive)
-  (hsc3-send-string
-   (format "Sound.SC3.UGen.DB.PP.ugen_graph_forth_pp False %s" (thing-at-point 'symbol))))
-
 (defun hsc3-ugen-summary ()
   "Lookup up the UGen at point in hsc3-db"
   (interactive)
   (hsc3-send-string
-   (format "Sound.SC3.UGen.DB.ugenSummary \"%s\""
-           (thing-at-point 'symbol))))
-
-(defun hsc3-request-type ()
-  "Ask ghci for the type of the name at point."
-  (interactive)
-  (hsc3-send-string (concat ":t " (thing-at-point 'symbol))))
+      (format "Sound.SC3.UGen.DB.ugenSummary \"%s\""
+              (thing-at-point 'symbol))))
 
-(defun chunk-string (n s)
-  "Split a string into chunks of 'n' characters."
-  (let* ((l (length s))
-         (m (min l n))
-         (c (substring s 0 m)))
-    (if (<= l n)
-        (list c)
-      (cons c (chunk-string n (substring s n))))))
+(defun hsc3-remove-trailing-newline (s)
+  (replace-regexp-in-string "\n\\'" "" s))
 
 (defun hsc3-cd ()
   "Change directory at ghci to current value of 'default-directory'."
@@ -101,14 +96,6 @@
   (hsc3-see-haskell)
   (hsc3-send-string (format ":load \"%s\"" buffer-file-name)))
 
-(defun hsc3-send-string (s)
-  (if (comint-check-proc inferior-haskell-buffer)
-      (let ((cs (chunk-string 64 (concat s "\n"))))
-        (mapcar
-         (lambda (c) (comint-send-string inferior-haskell-buffer c))
-         cs))
-    (error "no hsc3 process running?")))
-
 (defun hsc3-run-line ()
   "Send the current line to the interpreter."
   (interactive)
@@ -119,65 +106,11 @@
 	       (hsc3-uncomment s))))
     (hsc3-send-string s*)))
 
-(defun region-string ()
-  "Get region as string (no properties)"
-  (buffer-substring-no-properties
-   (region-beginning)
-   (region-end)))
-
-(defun hsc3-concat (l)
-  (apply #'concat l))
-
-(defun hsc3-region-string ()
-  "The current region (unlit, uncomment)."
-  (let* ((s (region-string)))
-    (if hsc3-literate-p
-        (hsc3-unlit (hsc3-remove-non-literates s))
-      (hsc3-concat (mapcar 'hsc3-uncomment (split-string s "\n"))))))
-
-(defun hsc3-region-string-one-line ()
-  "Replace newlines with spaces in `hsc3-region-string'."
-  (replace-regexp-in-string "\n" " " (hsc3-region-string)))
-
-(defun hsc3-run-multiple-lines ()
-  "Send the current region to the haskell interpreter as a single line."
-  (interactive)
-  (hsc3-send-string (hsc3-region-string-one-line)))
-
-(defun hsc3-run-multiple-lines-sclang ()
-  "Send the current region to the sclang interpreter as a single line."
-  (interactive)
-  (sclang-eval-string (hsc3-region-string-one-line) t))
-
-(defun hsc3-run-consecutive-lines ()
-  "Send the current region to the interpreter one line at a time."
-  (interactive)
-  (mapcar 'hsc3-send-string
-          (split-string (hsc3-region-string) "\n")))
-
-(defun hsc3-run-layout-block ()
-  "Variant of `hsc3-run-consecutive-lines' with ghci layout quoting."
-  (interactive)
-  (hsc3-send-string ":{")
-  (hsc3-send-string (hsc3-region-string))
-  (hsc3-send-string ":}"))
-
 (defun hsc3-run-main ()
   "Run current main."
   (interactive)
   (hsc3-send-string "main"))
 
-(defun hsc3-load-main ()
-  "Load current buffer and run main."
-  (interactive)
-  (hsc3-load-buffer)
-  (hsc3-run-main))
-
-(defun hsc3-wait ()
-  "Wait for prompt after sending command."
-  (interactive)
-  (inferior-haskell-wait-for-prompt (inferior-haskell-process)))
-
 (defun hsc3-id-rewrite-region ()
   (interactive)
   (shell-command-on-region
@@ -227,12 +160,12 @@
 (defun hsc3-update-hsc3-tags ()
   "Update hsc3 TAGS file, must be run from hsc3 directory."
   (interactive)
-  (if (file-exists-p "hsc3.cabal")
+  (if (and (executable-find "hasktags") (file-exists-p "hsc3.cabal"))
       (call-process-shell-command
        "find Sound . -name '*.*hs' | xargs hasktags -e"
        nil
        nil)
-    (error "not at hsc3 directory?")))
+    (error "no hasktags binary or not at hsc3 directory?")))
 
 (defun hsc3-audition-graph ()
   "Audition the UGen graph at point."
@@ -258,18 +191,6 @@
   (hsc3-send-string
    (concat "Sound.SC3.UGen.Dot.draw =<<" (thing-at-point 'symbol))))
 
-(defun hsc3-local-dot ()
-  "Copy '/tmp/hsc3.dot' to 'buffer-name' .dot."
-  (interactive)
-  (let ((nm (concat (file-name-sans-extension (buffer-name)) ".dot")))
-    (copy-file "/tmp/hsc3.dot" nm t)))
-
-(defun hsc3-gen-param ()
-  "Rewrite an SC3 argument list as control definitions."
-  (interactive)
-  (hsc3-send-string
-   (concat "putStrLn $ Sound.SC3.RW.PSynth.rewrite_param_list \"" (region-string) "\"")))
-
 (defun hsc3-set-prompt ()
   "Set ghci prompt to hsc3."
   (interactive)
@@ -297,10 +218,6 @@
   (define-key map [?\C-c ?<] 'hsc3-load-buffer)
   (define-key map [?\C-c ?>] 'hsc3-see-haskell)
   (define-key map [?\C-c ?\C-c] 'hsc3-run-line)
-  (define-key map [?\C-c ?\C-e] 'hsc3-run-multiple-lines)
-  (define-key map [?\C-c ?\M-e] 'hsc3-run-multiple-lines-sclang)
-  (define-key map [?\C-c ?\C-r] 'hsc3-run-consecutive-lines)
-  (define-key map [?\C-c ?\C-f] 'hsc3-run-layout-block)
   (define-key map [?\C-c ?\C-h] 'hsc3-help)
   (define-key map [?\C-c ?\C-a] 'hsc3-audition-graph)
   (define-key map [?\C-c ?\M-a] 'hsc3-audition-graph-m)
@@ -308,15 +225,13 @@
   (define-key map [?\C-c ?\M-g] 'hsc3-draw-graph-m)
   (define-key map [?\C-c ?\C-j] 'hsc3-sc3-ugen-help)
   (define-key map [?\C-c ?\C-/] 'hsc3-sc3-server-help)
-  (define-key map [?\C-c ?\M-f] 'hsc3-sc3-forth-pp)
-  (define-key map [?\C-c ?\C-i] 'hsc3-interrupt-haskell)
+  (define-key map [?\C-c ?i] 'hsc3-interrupt-haskell)
   (define-key map [?\C-c ?\C-k] 'hsc3-reset-scsynth)
   (define-key map [?\C-c ?\C-m] 'hsc3-run-main)
-  (define-key map [?\C-c ?\M-m] 'hsc3-load-main)
   (define-key map [?\C-c ?\C-p] 'hsc3-status-scsynth)
   (define-key map [?\C-c ?\C-q] 'hsc3-quit-haskell)
   (define-key map [?\C-c ?\C-0] 'hsc3-quit-scsynth)
-  (define-key map [?\C-c ?\C-s] 'hsc3-stop)
+  (define-key map [?\C-c ?\C-.] 'hsc3-stop)
   (define-key map [?\C-c ?\C-u] 'hsc3-ugen-summary))
 
 (defun hsc3-mode-menu (map)
@@ -343,12 +258,6 @@
     '("Load buffer" . hsc3-load-buffer))
   (define-key map [menu-bar hsc3 expression run-main]
     '("Run main" . hsc3-run-main))
-  (define-key map [menu-bar hsc3 expression run-layout-block]
-    '("Run layout block" . hsc3-run-layout-block))
-  (define-key map [menu-bar hsc3 expression run-consecutive-lines]
-    '("Run consecutive lines" . hsc3-run-consecutive-lines))
-  (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]
@@ -397,3 +306,125 @@
 (add-to-list 'auto-mode-alist '("\\.hs$" . hsc3-mode))
 
 (provide 'hsc3)
+
+;; (require 'haskell-interactive-mode)
+;; (require 'haskell-process)
+
+;; (defun hsc3-send-string (s)
+;;   (haskell-process-send-string (haskell-interactive-process) s))
+
+;; (defun hsc3-send-string-and-print (s)
+;;   (haskell-process-show-repl-response s))
+
+;; (defun hsc3-interrupt-haskell ()
+;;   (haskell-process-interrupt))
+
+;; (defun hsc3-see-haskell ()
+;;   "Show haskell output."
+;;   (interactive)
+;;   (haskell-interactive-bring))
+
+;; (require 'sclang)
+
+;; (define-key map [?\C-c ?\C-e] 'hsc3-run-multiple-lines)
+;; (define-key map [?\C-c ?\M-e] 'hsc3-run-multiple-lines-sclang)
+;; (define-key map [?\C-c ?\C-r] 'hsc3-run-consecutive-lines)
+;; (define-key map [?\C-c ?\C-f] 'hsc3-run-layout-block)
+;; (define-key map [?\C-c ?\M-f] 'hsc3-sc3-forth-pp)
+;; (define-key map [?\C-c ?\M-m] 'hsc3-load-main)
+;; (define-key map [?\C-c ?\C-,] 'hsc3-ugen-default-param)
+
+;; (define-key map [menu-bar hsc3 expression gen-default-param]
+;;   '("Insert default parameters" . hsc3-ugen-default-param))
+;; (define-key map [menu-bar hsc3 expression run-layout-block]
+;;   '("Run layout block" . hsc3-run-layout-block))
+;; (define-key map [menu-bar hsc3 expression run-consecutive-lines]
+;;   '("Run consecutive lines" . hsc3-run-consecutive-lines))
+;; (define-key map [menu-bar hsc3 expression run-multiple-lines]
+;;   '("Run multiple lines" . hsc3-run-multiple-lines))
+
+;; (defun hsc3-wait ()
+;;   "Wait for prompt after sending command."
+;;   (interactive)
+;;   (inferior-haskell-wait-for-prompt (inferior-haskell-process)))
+
+;; (defun hsc3-request-type ()
+;;   "Ask ghci for the type of the name at point."
+;;   (interactive)
+;;   (hsc3-send-string (concat ":t " (thing-at-point 'symbol))))
+
+;; (defun hsc3-load-main ()
+;;   "Load current buffer and run main."
+;;   (interactive)
+;;   (hsc3-load-buffer)
+;;   (hsc3-run-main))
+
+;; (defun hsc3-ugen-default-param ()
+;;   "Insert the default UGen parameters for the UGen before <point>."
+;;   (interactive)
+;;   (let ((p (format "hsc3-default-param %s" (thing-at-point 'symbol))))
+;;     (insert " ")
+;;     (insert (hsc3-remove-trailing-newline (shell-command-to-string p)))))
+
+;; (defun hsc3-sc3-forth-pp () "Forth PP" (interactive)
+;;   (hsc3-send-string
+;;    (format "Sound.SC3.UGen.DB.PP.ugen_graph_forth_pp False %s" (thing-at-point 'symbol))))
+
+;; (defun hsc3-region-string ()
+;;   "Get region as string (no properties)"
+;;   (buffer-substring-no-properties
+;;    (region-beginning)
+;;    (region-end)))
+
+;; (defun hsc3-gen-param ()
+;;   "Rewrite an SC3 argument list as control definitions."
+;;   (interactive)
+;;   (hsc3-send-string
+;;    (concat "putStrLn $ Sound.SC3.RW.PSynth.rewrite_param_list \"" (hsc3-region-string) "\"")))
+
+;; (defun hsc3-local-dot ()
+;;   "Copy '/tmp/hsc3.dot' to 'buffer-name' .dot."
+;;   (interactive)
+;;   (let ((nm (concat (file-name-sans-extension (buffer-name)) ".dot")))
+;;     (copy-file "/tmp/hsc3.dot" nm t)))
+
+;; (defun hsc3-concat (l)
+;;   (apply #'concat l))
+
+;; (defun hsc3-remove-non-literates (s)
+;;   "Remove non-bird literate lines"
+;;   (replace-regexp-in-string "^[^>]*$" "" s))
+
+;; (defun hsc3-region-string-unlit ()
+;;   "The current region (unlit, uncomment)."
+;;   (let* ((s (hsc3-region-string)))
+;;     (if hsc3-literate-p
+;;         (hsc3-unlit (hsc3-remove-non-literates s))
+;;       (hsc3-concat (mapcar 'hsc3-uncomment (split-string s "\n"))))))
+
+;; (defun hsc3-region-string-one-line ()
+;;   "Replace newlines with spaces in `hsc3-region-string'."
+;;   (replace-regexp-in-string "\n" " " (hsc3-region-string-unlit)))
+
+;; (defun hsc3-run-multiple-lines ()
+;;   "Send the current region to the haskell interpreter as a single line."
+;;   (interactive)
+;;   (hsc3-send-string (hsc3-region-string-one-line)))
+
+;; (defun hsc3-run-multiple-lines-sclang ()
+;;   "Send the current region to the sclang interpreter as a single line."
+;;   (interactive)
+;;   (sclang-eval-string (hsc3-region-string-one-line) t))
+
+;; (defun hsc3-run-consecutive-lines ()
+;;   "Send the current region to the interpreter one line at a time."
+;;   (interactive)
+;;   (mapcar 'hsc3-send-string
+;;           (split-string (hsc3-region-string) "\n")))
+
+;; (defun hsc3-run-layout-block ()
+;;   "Variant of `hsc3-run-consecutive-lines' with ghci layout quoting."
+;;   (interactive)
+;;   (hsc3-send-string ":{")
+;;   (hsc3-send-string (hsc3-region-string))
+;;   (hsc3-send-string ":}"))
diff --git a/hsc3.cabal b/hsc3.cabal
--- a/hsc3.cabal
+++ b/hsc3.cabal
@@ -1,5 +1,5 @@
 Name:              hsc3
-Version:           0.15.1
+Version:           0.16
 Synopsis:          Haskell SuperCollider
 Description:       Haskell client for the SuperCollider synthesis server,
                    <http://audiosynth.com/>.
@@ -8,41 +8,24 @@
                    <http://rd.slavepianos.org/t/hsc3-texts>.
 License:           GPL
 Category:          Sound
-Copyright:         (c) Rohan Drape and others, 2005-2014
+Copyright:         (c) Rohan Drape and others, 2005-2017
 Author:            Rohan Drape
 Maintainer:        rd@slavepianos.org
 Stability:         Experimental
 Homepage:          http://rd.slavepianos.org/t/hsc3
-Tested-With:       GHC == 7.8.2
+Tested-With:       GHC == 8.0.1
 Build-Type:        Simple
 Cabal-Version:     >= 1.8
 
 Data-files:        README
                    emacs/hsc3.el
                    Help/Server/*.help.lhs
-                   Help/UGen/Analysis/*.help.lhs
-                   Help/UGen/Buffer/*.help.lhs
-                   Help/UGen/Chaos/*.help.lhs
-                   Help/UGen/Control/*.help.lhs
-                   Help/UGen/Demand/*.help.lhs
-                   Help/UGen/DiskIO/*.help.lhs
-                   Help/UGen/Envelope/*.help.lhs
-                   Help/UGen/External/*.help.lhs
-                   Help/UGen/FFT/*.help.lhs
-                   Help/UGen/Filter/*.help.lhs
-                   Help/UGen/Granular/*.help.lhs
-                   Help/UGen/Information/*.help.lhs
-                   Help/UGen/IO/*.help.lhs
-                   Help/UGen/MachineListening/*.help.lhs
-                   Help/UGen/Math/*.help.lhs
-                   Help/UGen/Noise/*.help.lhs
-                   Help/UGen/Oscillator/*.help.lhs
-                   Help/UGen/Panner/*.help.lhs
-                   Help/UGen/Trigger/*.help.lhs
-                   Help/UGen/Wavelets/*.help.lhs
+                   Help/UGen/ix.md
+                   Help/UGen/*.help.lhs
 
 Library
-  Build-Depends:   base == 4.*,
+  Build-Depends:   array,
+                   base >= 4.7 && < 5,
                    binary,
                    bytestring,
                    containers,
@@ -51,17 +34,28 @@
                    directory,
                    filepath,
                    hashable,
-                   hosc == 0.15.*,
+                   hosc == 0.16.*,
                    network,
                    process,
                    random,
                    safe,
                    split >= 0.2,
-                   transformers
+                   transformers,
+                   vector
   GHC-Options:     -Wall -fwarn-tabs
   Exposed-modules: Sound.SC3
                    Sound.SC3.Common
-                   Sound.SC3.Common.Monad.Syntax
+                   Sound.SC3.Common.Buffer
+                   Sound.SC3.Common.Buffer.Array
+                   Sound.SC3.Common.Buffer.Gen
+                   Sound.SC3.Common.Buffer.Vector
+                   Sound.SC3.Common.Envelope
+                   Sound.SC3.Common.Math
+                   Sound.SC3.Common.Math.Interpolate
+                   Sound.SC3.Common.Math.Window
+                   Sound.SC3.Common.Monad
+                   Sound.SC3.Common.Monad.Operators
+                   Sound.SC3.Common.Prelude
                    Sound.SC3.FD
                    Sound.SC3.Server
                    Sound.SC3.Server.Command
@@ -84,6 +78,7 @@
                    Sound.SC3.Server.Transport.FD
                    Sound.SC3.Server.Transport.Monad
                    Sound.SC3.UGen
+                   Sound.SC3.UGen.Analysis
                    Sound.SC3.UGen.Bindings
                    Sound.SC3.UGen.Bindings.Composite
                    Sound.SC3.UGen.Bindings.DB
@@ -96,10 +91,7 @@
                    --Sound.SC3.UGen.Bindings.HW.Demand
                    --Sound.SC3.UGen.Bindings.HW.DiskIO
                    Sound.SC3.UGen.Bindings.HW.External
-                   Sound.SC3.UGen.Bindings.HW.External.ATS
                    Sound.SC3.UGen.Bindings.HW.External.F0
-                   Sound.SC3.UGen.Bindings.HW.External.ID
-                   Sound.SC3.UGen.Bindings.HW.External.LPC
                    Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins
                    Sound.SC3.UGen.Bindings.HW.External.Wavelets
                    Sound.SC3.UGen.Bindings.HW.External.Zita
@@ -114,15 +106,15 @@
                    --Sound.SC3.UGen.Bindings.HW.Panner
                    Sound.SC3.UGen.Enum
                    Sound.SC3.UGen.Envelope
-                   Sound.SC3.UGen.Envelope.Construct
-                   Sound.SC3.UGen.Envelope.Interpolate
                    Sound.SC3.UGen.Graph
                    Sound.SC3.UGen.Graph.Reconstruct
                    Sound.SC3.UGen.Graph.Transform
                    Sound.SC3.UGen.Help
                    Sound.SC3.UGen.Help.Graph
+                   Sound.SC3.UGen.HS
                    Sound.SC3.UGen.Identifier
                    Sound.SC3.UGen.Math
+                   Sound.SC3.UGen.Math.Composite
                    Sound.SC3.UGen.MCE
                    Sound.SC3.UGen.Name
                    Sound.SC3.UGen.Operator
