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,7 +1,9 @@
     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 2 ^ 15.
+at the server.  Below allocates a buffer at index 2 ^ 15.  Note the
+b_alloc_setn1, which adds a b_set completion message to the b_alloc
+message, is still asynchronous.
 
 > import Sound.SC3 {- hsc3 -}
 
@@ -10,7 +12,9 @@
 
 > m0 = b_alloc_setn1 b0 0 [0,3,7,10]
 
+    b0 == 2 ^ 15
     withSC3 (async m0)
+    withSC3 (b_getn1_data b0 (0,4))
 
 > g0 =
 >     let x = mouseX KR 0 9 Linear 0.1
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
@@ -1,36 +1,48 @@
-> Sound.SC3.Server.Help.viewServerHelp "/b_query"
+    Sound.SC3.Server.Help.viewServerHelp "/b_query"
 
 > import Sound.OSC {- hosc -}
 > import Sound.SC3 {- hsc3 -}
 
 Allocate and generate wavetable buffer
 
-> withSC3 (do {_ <- async (b_alloc 0 256 1)
->             ;let f = [Normalise,Wavetable,Clear]
->              in send (b_gen_sine1 0 f [1,1/2,1/3,1/4,1/5])})
+> mk_b :: Transport m => m ()
+> mk_b = do
+>   _ <- async (b_alloc 0 256 1)
+>   let f = [Normalise,Wavetable,Clear]
+>   sendMessage (b_gen_sine1 0 f [1,1/2,1/3,1/4,1/5])
 
+    withSC3 mk_b
+
 Query buffer
 
-> withSC3 (do {send (b_query [0])
->             ;r <- waitReply "/b_info"
->             ;liftIO (print r)})
+> qr_b :: Transport m => m ()
+> qr_b = do
+>   sendMessage (b_query [0])
+>   r <- waitReply "/b_info"
+>   liftIO (print r)
 
+    withSC3 qr_b
+
 Variant that unpacks the result.
 
 Query is of (buffer-id/int,#-frames/int,#-channels/int,sample-rate/float).
 
-> withSC3 (b_query1_unpack 0)
+    withSC3 (b_query1_unpack 0)
 
 Play buffer
 
-> audition (out 0 (osc AR 0 220 0 * 0.1))
+> g_01 = osc AR 0 220 0 * 0.1
 
 Free buffer
 
-> withSC3 (async (b_free 0))
+    withSC3 (async (b_free 0))
 
 Query multiple un-allocated buffers
 
-> withSC3 (do {send (b_query [2^14,2^15])
->             ;r <- waitReply "/b_info"
->             ;liftIO (print r)})
+> qr_unalloc :: Transport m => m ()
+> qr_unalloc = do
+>   sendMessage (b_query [2^14,2^15])
+>   r <- waitReply "/b_info"
+>   liftIO (print r)
+
+    withSC3 qr_unalloc
diff --git a/Help/Server/c_getn.help.lhs b/Help/Server/c_getn.help.lhs
--- a/Help/Server/c_getn.help.lhs
+++ b/Help/Server/c_getn.help.lhs
@@ -1,1 +1,19 @@
-> Sound.SC3.Server.Help.viewServerHelp "/c_getn"
+    Sound.SC3.Server.Help.viewServerHelp "/c_getn"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+
+Get control bus data.
+
+> get_c :: Transport m => m ()
+> get_c = do
+>   sendMessage (c_getn [(0,3)])
+>   r <- waitReply "/c_setn"
+>   liftIO (print r)
+
+    withSC3 (sendMessage (c_setn [(0,[1,880,0.5])]))
+    withSC3 get_c
+
+Function to get and unpack control bus data.
+
+    withSC3 (c_getn1_data (0,3))
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,18 +1,21 @@
-    > 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 -}
 
-> d_0 =
->     let f = control KR "freq" 440
->         o = saw AR f * 0.05
->     in synthdef "saw" (out 0 o)
+    withSC3 serverTree >>= mapM_ putStrLn
 
-> m_0 = [d_recv d_0,g_new [(100,AddToTail,1)],s_new0 "saw" 1000 AddToTail 100]
+> g_00 =
+>   let f = control KR "freq" 440
+>   in saw AR f * 0.05
 
-    > withSC3 (mapM_ maybe_async m_0)
+> d_01 = synthdef "saw" (out 0 g_00)
 
+> m_02 = [d_recv d_01,g_new [(100,AddToTail,1)],s_new0 "saw" 1000 AddToTail 100]
+
+    > withSC3 (mapM_ maybe_async m_02)
+
 > run_query_tree = withSC3 (g_queryTree1_unpack 0)
 
     > qt <- run_query_tree
@@ -25,3 +28,16 @@
 
     > r_tr = queryTree_rt qt
     > putStrLn (unlines ["::TREE::",T.drawTree (fmap query_node_pp r_tr)])
+
+> q_03 =
+>   [int32 1,int32 0,int32 2,int32 1,int32 1
+>   ,int32 100,int32 1
+>   ,int32 1000,int32 (-1),string "saw"
+>   ,int32 1,string "freq",float 440.0
+>   ,int32 2,int32 0]
+
+> t_04 = queryTree q_03
+
+> t_05 = queryTree_rt t_04
+
+    >> putStrLn (unlines ["::TREE::",T.drawTree (fmap query_node_pp t_05)])
diff --git a/Help/Server/n_mapn.help.lhs b/Help/Server/n_mapn.help.lhs
--- a/Help/Server/n_mapn.help.lhs
+++ b/Help/Server/n_mapn.help.lhs
@@ -1,1 +1,31 @@
-> Sound.SC3.Server.Help.viewServerHelp "/n_mapn"
+    Sound.SC3.Server.Help.viewServerHelp "/n_mapn"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+
+> f_01 nm def ix = control_f64 KR (Just ix) nm def
+> g_01 = out (f_01 "bus" 0 0) (sinOsc AR (f_01 "freq" 440 1) 0 * f_01 "amp" 0.1 2)
+> s_01 = synthdef "sin" g_01
+> m_01 = d_recv s_01
+> m_02 = s_new "sin" 1001 AddToHead 1 []
+> m_03 = n_mapn 1001 [(0,0,3)]
+
+    withSC3 (async (d_recv s_01) >> mapM_ sendMessage [m_02,m_03])
+
+    withSC3 (sendMessage (n_mapn 1001 [(0,0,3)]))
+    withSC3 (sendMessage (c_setn [(0,[1,880,0.2])]))
+    withSC3 (sendMessage (c_setn [(0,[0,220,0.3])]))
+
+    withSC3 (sendMessage (n_set1 1001 "bus" 1))
+    withSC3 (sendMessage (n_set1 1001 "freq" 440))
+    withSC3 (sendMessage (n_set1 1001 "amp" 0.2))
+    withSC3 (sendMessage (n_setn 1001 [(0,[1,880,0.2])]))
+
+n_mapn and n_setn only work if the control is given as an index and not as a name.
+
+s.sendMsg("/n_mapn",1001,"bus",0,3);
+s.sendMsg("/c_setn",0,3,0,880,0.1);
+
+s.sendMsg("/n_mapn",1001,0,0,3);
+s.sendMsg("/c_setn",0,3,0,880,0.1);
+s.sendMsg("/c_setn",0,3,1,220,0.3);
diff --git a/Help/Server/n_setn.help.lhs b/Help/Server/n_setn.help.lhs
--- a/Help/Server/n_setn.help.lhs
+++ b/Help/Server/n_setn.help.lhs
@@ -1,1 +1,1 @@
-> Sound.SC3.Server.Help.viewServerHelp "/n_setn"
+    Sound.SC3.Server.Help.viewServerHelp "/n_setn"
diff --git a/Help/Server/n_trace.help.lhs b/Help/Server/n_trace.help.lhs
--- a/Help/Server/n_trace.help.lhs
+++ b/Help/Server/n_trace.help.lhs
@@ -1,1 +1,13 @@
-> Sound.SC3.Server.Help.viewServerHelp "/n_trace"
+     > Sound.SC3.Server.Help.viewServerHelp "/n_trace"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+
+> m_01 =
+>   [d_recv defaultSynthdef
+>   ,s_new "default" 100 AddToHead 1 []]
+
+> m_02 = n_trace [1,100]
+
+    > withSC3 (mapM_ maybe_async m_01)
+    > withSC3 (sendMessage m_02)
diff --git a/Help/Server/status.help.lhs b/Help/Server/status.help.lhs
--- a/Help/Server/status.help.lhs
+++ b/Help/Server/status.help.lhs
@@ -1,1 +1,5 @@
-> Sound.SC3.Server.Help.viewServerHelp "/status"
+    Sound.SC3.Server.Help.viewServerHelp "/status"
+
+> import Sound.SC3 {- hsc3 -}
+
+    withSC3 serverStatus >>= mapM putStrLn
diff --git a/Help/UGen/abs.help.lhs b/Help/UGen/abs.help.lhs
--- a/Help/UGen/abs.help.lhs
+++ b/Help/UGen/abs.help.lhs
@@ -2,5 +2,5 @@
     > :t abs
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 = abs (syncSaw AR 100 440 * 0.1)
diff --git a/Help/UGen/add.help.lhs b/Help/UGen/add.help.lhs
--- a/Help/UGen/add.help.lhs
+++ b/Help/UGen/add.help.lhs
@@ -2,7 +2,7 @@
     > :t (+)
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 =
 >     let o = fSinOsc AR 800 0
 >         n = pinkNoise 'α' AR
diff --git a/Help/UGen/amClip.help.lhs b/Help/UGen/amClip.help.lhs
--- a/Help/UGen/amClip.help.lhs
+++ b/Help/UGen/amClip.help.lhs
@@ -2,5 +2,5 @@
     > :t amClip
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 = amClip (whiteNoise 'α' AR) (fSinOsc KR 1 0 * 0.2)
diff --git a/Help/UGen/amplitude.help.lhs b/Help/UGen/amplitude.help.lhs
--- a/Help/UGen/amplitude.help.lhs
+++ b/Help/UGen/amplitude.help.lhs
@@ -2,17 +2,17 @@
     > 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
diff --git a/Help/UGen/atari2600.help.lhs b/Help/UGen/atari2600.help.lhs
--- a/Help/UGen/atari2600.help.lhs
+++ b/Help/UGen/atari2600.help.lhs
@@ -1,8 +1,9 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "Atari2600"
-    > Sound.SC3.UGen.DB.ugenSummary "Atari2600"
+    Sound.SC3.UGen.Help.viewSC3Help "Atari2600"
+    Sound.SC3.UGen.DB.ugenSummary "Atari2600"
 
 > import Sound.SC3 {- hsc3 -}
 > import Sound.SC3.Lang.Pattern {- hsc3-lang -}
+> import Sound.SC3.UGen.Bindings.HW.External.F0 {- hsc3 -}
 
 > gr_00 = atari2600 1 2 3 4 5 5 1
 
@@ -65,7 +66,7 @@
 >     ,(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)
+    paudition (pbind p_02)
 
 > p_03 =
 >     [(K_instr,psynth ati_syn)
diff --git a/Help/UGen/atsNoiSynth.help.lhs b/Help/UGen/atsNoiSynth.help.lhs
--- a/Help/UGen/atsNoiSynth.help.lhs
+++ b/Help/UGen/atsNoiSynth.help.lhs
@@ -3,8 +3,9 @@
 
 > import System.IO.Unsafe {- base -}
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- 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"
 
@@ -26,11 +27,11 @@
 > 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
+>     in atsNoiSynth AR 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
+>     in atsNoiSynth AR 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
--- a/Help/UGen/atsSynth.help.lhs
+++ b/Help/UGen/atsSynth.help.lhs
@@ -3,6 +3,7 @@
 
 > import System.IO.Unsafe {- base -}
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 > import Sound.SC3.Data.ATS {- hsc3-data -}
 
 > ats_fn_0 = "/home/rohan/data/audio/pf-c5.4.ats"
@@ -26,4 +27,4 @@
 >     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
+>     in atsSynth AR 0 np 0 1 x y 0
diff --git a/Help/UGen/audioMSG.help.lhs b/Help/UGen/audioMSG.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/audioMSG.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "AudioMSG"
+    Sound.SC3.UGen.DB.ugenSummary "AudioMSG"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 = audioMSG AR (sinOsc AR 220 0 * 0.1) (mouseX KR 0 (2 * pi) Linear 0.2)
+
+> g_02 = audioMSG AR (soundIn 0) (mouseX KR 0 (2 * pi) Linear 0.2)
+
diff --git a/Help/UGen/ay.help.lhs b/Help/UGen/ay.help.lhs
--- a/Help/UGen/ay.help.lhs
+++ b/Help/UGen/ay.help.lhs
@@ -2,9 +2,10 @@
     Sound.SC3.UGen.DB.ugenSummary "AY"
 
 > import Sound.SC3 {- hsc3 -}
->
+> import Sound.SC3.UGen.Bindings.DB.External {- 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
@@ -14,7 +15,7 @@
 >         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
diff --git a/Help/UGen/bAllpass.help.lhs b/Help/UGen/bAllpass.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bAllpass.help.lhs
@@ -0,0 +1,27 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BAllPass"
+    > Sound.SC3.UGen.DB.ugenSummary "BAllPass"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Common.Math.Filter.BEQ {- hsc3 -}
+
+thoughpass
+
+> g_01 =
+>     let i = soundIn (mce2 0 1)
+>         f = mouseX KR 10 18000 Exponential 0.2
+>     in bAllPass i f 0.8
+
+bandpass
+
+> g_02 =
+>     let i = soundIn (mce2 0 1) * 0.5
+>         f = mouseX KR 100 18000 Exponential 0.2
+>     in bAllPass i f 0.8 + negate i
+
+calculate coefficients and use sos
+
+> g_03 =
+>     let i = soundIn (mce2 0 1) * 0.5
+>         f = mouseX KR 100 18000 Exponential 0.2
+>         (a0, a1, a2, b1, b2) = bAllPassCoef sampleRate f 0.8
+>     in sos i a0 a1 a2 b1 b2 + negate i
diff --git a/Help/UGen/bBandPass.help.lhs b/Help/UGen/bBandPass.help.lhs
--- a/Help/UGen/bBandPass.help.lhs
+++ b/Help/UGen/bBandPass.help.lhs
@@ -2,9 +2,19 @@
     Sound.SC3.UGen.DB.ugenSummary "BBandPass"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Common.Math.Filter.BEQ {- hsc3 -}
 
 > g_01 =
->     let i = soundIn 4
+>     let i = soundIn 0
 >         f = mouseX KR 20 20000 Exponential 0.2
 >         bw = mouseY KR 0 10 Linear 0.2
 >     in bBandPass i f bw
+
+calculate coefficients and use sos
+
+> g_02 =
+>     let i = soundIn 0
+>         f = mouseX KR 20 20000 Exponential 0.2
+>         bw = mouseY KR 0 10 Linear 0.2
+>         (a0, a1, a2, b1, b2) = bBandPassCoef sampleRate f bw
+>     in sos i a0 a1 a2 b1 b2
diff --git a/Help/UGen/bBandStop.help.lhs b/Help/UGen/bBandStop.help.lhs
--- a/Help/UGen/bBandStop.help.lhs
+++ b/Help/UGen/bBandStop.help.lhs
@@ -2,6 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "BBandStop"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Common.Math.Filter.BEQ {- hsc3 -}
 
 > g_01 =
 >     let i = soundIn (mce2 0 1)
@@ -14,3 +15,12 @@
 >         f = mouseX KR 800 1200 Exponential 0.2
 >         bw = mouseY KR 0 10 Linear 0.2
 >     in bBandStop i f bw
+
+calculate coefficients and use sos
+
+> g_03 =
+>     let i = soundIn (mce2 0 1)
+>         f = mouseX KR 800 1200 Exponential 0.2
+>         bw = mouseY KR 0 10 Linear 0.2
+>         (a0, a1, a2, b1, b2) = bBandStopCoef sampleRate f bw
+>     in sos i a0 a1 a2 b1 b2
diff --git a/Help/UGen/bHiPass.help.lhs b/Help/UGen/bHiPass.help.lhs
--- a/Help/UGen/bHiPass.help.lhs
+++ b/Help/UGen/bHiPass.help.lhs
@@ -2,9 +2,19 @@
     Sound.SC3.UGen.DB.ugenSummary "BHiPass"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Common.Math.Filter.BEQ {- 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
+
+calculate coefficients and use sos (see also bHiPass4)
+
+> g_02 =
+>     let i = whiteNoise 'α' AR
+>         f = mouseX KR 10 20000 Exponential 0.2
+>         rq = mouseY KR 0 1 Linear 0.2
+>         (a0, a1, a2, b1, b2) = bHiPassCoef sampleRate f rq
+>     in sos i a0 a1 a2 b1 b2
diff --git a/Help/UGen/bHiPass4.help.lhs b/Help/UGen/bHiPass4.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bHiPass4.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BHiPass4"
+    > :t bHiPass4
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let i = mix (saw AR (mce [0.99, 1, 1.01] * 440) * 0.3)
+>         f = mouseX KR 20 20000 Exponential 0.2
+>         rq = mouseY KR 0.1 1 Linear 0.2
+>     in bHiPass4 i f rq
diff --git a/Help/UGen/bHiShelf.help.lhs b/Help/UGen/bHiShelf.help.lhs
--- a/Help/UGen/bHiShelf.help.lhs
+++ b/Help/UGen/bHiShelf.help.lhs
@@ -2,6 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "BHiShelf"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Common.Math.Filter.BEQ {- hsc3 -}
 
 > g_01 =
 >     let i = soundIn 0
@@ -10,7 +11,16 @@
 >     in bHiShelf i f 1 db
 
 > g_02 =
->     let i = soundIn 4
+>     let i = soundIn 0
 >         f = mouseX KR 2200 18000 Exponential 0.2
 >         rs = mouseY KR 0.1 1 Linear 0.2
 >     in bHiShelf i f rs 6
+
+calculate coefficients and use sos
+
+> g_03 =
+>     let i = soundIn 0
+>         f = mouseX KR 2200 18000 Exponential 0.2
+>         rs = mouseY KR 0.1 1 Linear 0.2
+>         (a0, a1, a2, b1, b2) = bHiShelfCoef sampleRate f rs 6
+>     in sos i a0 a1 a2 b1 b2
diff --git a/Help/UGen/bLowPass.help.lhs b/Help/UGen/bLowPass.help.lhs
--- a/Help/UGen/bLowPass.help.lhs
+++ b/Help/UGen/bLowPass.help.lhs
@@ -3,25 +3,25 @@
     > :t bLowPassCoef
 
 > import Sound.SC3 {- hsc3 -}
->
+> import Sound.SC3.Common.Math.Filter.BEQ {- 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.
+calculate coefficients and use sos (see also bLowPass4)
 
 > 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)
+>     in sos i a0 a1 a2 b1 b2
diff --git a/Help/UGen/bLowPass4.help.lhs b/Help/UGen/bLowPass4.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bLowPass4.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BLowPass4"
+    > :t bLowPass4
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     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 bLowPass4 i f rq
diff --git a/Help/UGen/bLowShelf.help.lhs b/Help/UGen/bLowShelf.help.lhs
--- a/Help/UGen/bLowShelf.help.lhs
+++ b/Help/UGen/bLowShelf.help.lhs
@@ -2,6 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "BLowShelf"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Common.Math.Filter.BEQ {- hsc3 -}
 
 > g_01 =
 >     let i = soundIn (mce2 0 1)
@@ -16,3 +17,13 @@
 >         rs = mouseY KR 0.1 1 Linear 0.2
 >         db = 6
 >     in bLowShelf i freq rs db
+
+calculate coefficients and use sos
+
+> g_03 =
+>     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
+>         (a0, a1, a2, b1, b2) = bLowShelfCoef sampleRate freq rs db
+>     in sos i a0 a1 a2 b1 b2
diff --git a/Help/UGen/bMoog.help.lhs b/Help/UGen/bMoog.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/bMoog.help.lhs
@@ -0,0 +1,24 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BMoog"
+    Sound.SC3.UGen.DB.ugenSummary "BMoog"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> f_01 md =
+>   let dup x = mce2 x x
+>       x = mouseX KR 20 12000 Exponential 0.2
+>       o = dup (lfSaw AR (mce2 (x * 0.99) (x * 1.01)) 0 * 0.1)
+>       cf = sinOsc KR (sinOsc KR 0.1 0) (1.5 * pi) * 1550 + 1800
+>       y = mouseY KR 1 0 Linear 0.2
+>       sig = bMoog o cf y md 0.95
+>   in (combN sig 0.5 (mce2 0.4 0.35) 2 * 0.4) + (sig * 0.5)
+
+modes are: 0 = lowpass, 1 = highpass, 2 = bandpass
+
+> g_01 = f_01 0
+
+> g_02 = f_01 1
+
+> g_03 = f_01 2
+
+> g_04 = f_01 (lfSaw KR 1 0 * 3)
diff --git a/Help/UGen/bPeakEQ.help.lhs b/Help/UGen/bPeakEQ.help.lhs
--- a/Help/UGen/bPeakEQ.help.lhs
+++ b/Help/UGen/bPeakEQ.help.lhs
@@ -2,6 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "BPeakEQ"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.Common.Math.Filter.BEQ {- hsc3 -}
 
 > g_01 =
 >     let i = soundIn 0
@@ -14,3 +15,12 @@
 >         freq = mouseX KR 2200 18000 Exponential 0.2
 >         rq = mouseY KR 10 0.4 Linear 0.2
 >     in bPeakEQ i freq rq 6
+
+calculate coefficients and use sos (see also bLowPass4)
+
+> g_03 =
+>     let i = soundIn 0
+>         freq = mouseX KR 2200 18000 Exponential 0.2
+>         rq = mouseY KR 10 0.4 Linear 0.2
+>         (a0, a1, a2, b1, b2) = bPeakEQCoef sampleRate freq rq 6
+>     in sos i a0 a1 a2 b1 b2
diff --git a/Help/UGen/balance2.help.lhs b/Help/UGen/balance2.help.lhs
--- a/Help/UGen/balance2.help.lhs
+++ b/Help/UGen/balance2.help.lhs
@@ -41,3 +41,10 @@
 >         s1 = sinOsc AR 550 0
 >         x = mouseX KR (-1) 1 Linear 0.2
 >     in balance2 s0 s1 x 0.2
+
+> g_06 =
+>     let s = soundIn 0
+>         l = lpf s 500
+>         h = s - l
+>         n = lfNoise0 'α' KR 4
+>     in balance2 l h n 0.3
diff --git a/Help/UGen/beatTrack.help.lhs b/Help/UGen/beatTrack.help.lhs
--- a/Help/UGen/beatTrack.help.lhs
+++ b/Help/UGen/beatTrack.help.lhs
@@ -12,6 +12,6 @@
 >         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
+>     in i + s
 
 
diff --git a/Help/UGen/blitB3.help.lhs b/Help/UGen/blitB3.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/blitB3.help.lhs
@@ -0,0 +1,24 @@
+    Sound.SC3.UGen.Help.viewSC3Help "BlitB3Square"
+    Sound.SC3.UGen.DB.ugenSummary "BlitB3Square"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 = blitB3 AR (xLine KR 10000 20 10 DoNothing) * 0.2
+
+spot the aliasing
+
+> g_02 = impulse AR (xLine KR 10000 20 10 DoNothing) 0 * 0.2
+
+sawtooth
+
+> g_03 =
+>   let x = mouseX KR 20 1000 Exponential 0.2
+>   in leakDC (integrator (blitB3 AR x * 0.2) 0.99) 0.995
+
+sawtooth; super-saw, can integrate mix
+leaks dealt with one by one so don't accumulate
+
+> g_04 =
+>   let x = mouseX KR 1 4 Linear 0.2
+>   in mix (leakDC (integrator (blitB3 AR (x * mce [220,221,223,224]) * 0.125) 0.99) 0.995)
diff --git a/Help/UGen/blitB3Saw.help.lhs b/Help/UGen/blitB3Saw.help.lhs
--- a/Help/UGen/blitB3Saw.help.lhs
+++ b/Help/UGen/blitB3Saw.help.lhs
@@ -2,6 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "BlitB3Saw"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 > g_01 =
 >     let f = xLine KR 1000 20 10 DoNothing
diff --git a/Help/UGen/blitB3Square.help.lhs b/Help/UGen/blitB3Square.help.lhs
--- a/Help/UGen/blitB3Square.help.lhs
+++ b/Help/UGen/blitB3Square.help.lhs
@@ -2,7 +2,12 @@
     Sound.SC3.UGen.DB.ugenSummary "BlitB3Square"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
+> g_00 =
+>   let x = mouseX KR 20 400 Exponential 0.2
+>   in blitB3Square AR x 0.99 * 0.1
+
 > g_01 =
 >     let f = xLine KR 1000 20 10 DoNothing
 >     in blitB3Square AR f 0.99 * 0.1
@@ -16,11 +21,11 @@
 
 difference in CPU usage (excessive wire use,-w 1024)
 
-> g_03 sqr_osc =
+> f_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)
+> g_03 = f_03 (\rt f -> blitB3Square rt f 0.99)
+> g_04 = f_03 (\rt f -> pulse rt f 0.5)
diff --git a/Help/UGen/blitB3Tri.help.lhs b/Help/UGen/blitB3Tri.help.lhs
--- a/Help/UGen/blitB3Tri.help.lhs
+++ b/Help/UGen/blitB3Tri.help.lhs
@@ -2,18 +2,21 @@
     Sound.SC3.UGen.DB.ugenSummary "BlitB3Tri"
 
 > import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as E {- hsc3 -}
 
-> g_01 = blitB3Tri AR (xLine KR 1000 20 10 DoNothing) 0.99 0.99 * 0.1
+> g_01 = E.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
+(over 5000Hz or so) with a vengence (very beautiful in point scope)
 
-> 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
+> g_02 =
+>   let x = mouseX KR 20 8000 Exponential 0.2
+>       y = mouseY KR 0.001 0.99 Linear 0.2
+>   in E.blitB3Tri AR x 0.99 y * 0.1
 
 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
+> g_03 =
+>   let x = mouseX KR 20 8000 Exponential 0.2
+>   in lfTri AR x 0 * 0.1
diff --git a/Help/UGen/blockSize.help.lhs b/Help/UGen/blockSize.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/blockSize.help.lhs
@@ -0,0 +1,10 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "BlockSize"
+    > Sound.SC3.UGen.DB.ugenSummary "BlockSize"
+
+> import Sound.SC3 {- hsc3 -}
+
+default block size is 64 samples
+
+> g_01 = sinOsc AR (mce2 (blockSize * 3) (64 * 3 + 1)) 0 * 0.1
+
+> g_02 = sinOsc AR (mce2 (blockSize * 3) ((controlDur * sampleRate * 3) + 1)) 0 * 0.1
diff --git a/Help/UGen/brownNoise.help.lhs b/Help/UGen/brownNoise.help.lhs
--- a/Help/UGen/brownNoise.help.lhs
+++ b/Help/UGen/brownNoise.help.lhs
@@ -2,9 +2,11 @@
     Sound.SC3.UGen.DB.ugenSummary "BrownNoise"
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 = brownNoise 'α' AR * 0.1
->
+
+KR rate noise as frequency control
+
 > g_02 =
 >     let n = brownNoise 'α' KR
 >     in sinOsc AR (linExp n (-1) 1 64 9600) 0 * 0.1
diff --git a/Help/UGen/bufChannels.help.lhs b/Help/UGen/bufChannels.help.lhs
--- a/Help/UGen/bufChannels.help.lhs
+++ b/Help/UGen/bufChannels.help.lhs
@@ -1,2 +1,2 @@
-> Sound.SC3.UGen.Help.viewSC3Help "BufChannels"
-> Sound.SC3.UGen.DB.ugenSummary "BufChannels"
+    Sound.SC3.UGen.Help.viewSC3Help "BufChannels"
+    Sound.SC3.UGen.DB.ugenSummary "BufChannels"
diff --git a/Help/UGen/bufDur.help.lhs b/Help/UGen/bufDur.help.lhs
--- a/Help/UGen/bufDur.help.lhs
+++ b/Help/UGen/bufDur.help.lhs
@@ -7,7 +7,9 @@
 
 > fn_01 = "/home/rohan/data/audio/pf-c5.aif"
 
-    > withSC3 (async (b_allocRead 0 fn_01 0 0))
+> m_01 = b_allocRead 0 fn_01 0 0
+
+    > withSC3 (async m_01)
 
 Read without loop, trigger reset based on buffer duration
 
diff --git a/Help/UGen/bufFrames.help.lhs b/Help/UGen/bufFrames.help.lhs
--- a/Help/UGen/bufFrames.help.lhs
+++ b/Help/UGen/bufFrames.help.lhs
@@ -7,8 +7,11 @@
 
 > fn_01 = "/home/rohan/data/audio/pf-c5.aif"
 
-    > withSC3 (async (b_allocRead 0 fn_01 0 0))
 
+> m_01 = b_allocRead 0 fn_01 0 0
+
+    > withSC3 (async m_01)
+
 Read without loop, trigger reset based on buffer duration
 
 > g_01 =
@@ -19,5 +22,5 @@
 
 > g_02 =
 >     let r = mce [0.05,0.075 .. 0.15]
->         p = k2A (mouseX KR 0 (bufFrames KR 0) Linear r)
+>         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
--- a/Help/UGen/bufRateScale.help.lhs
+++ b/Help/UGen/bufRateScale.help.lhs
@@ -7,7 +7,9 @@
 
 > fn_01 = "/home/rohan/data/audio/pf-c5.aif"
 
-    > withSC3 (async (b_allocRead 0 fn_01 0 0))
+> m_01 = b_allocRead 0 fn_01 0 0
+
+    > withSC3 (async m_01)
 
 Read buffer at 3/4 reported sample rate.
 
diff --git a/Help/UGen/bufSampleRate.help.lhs b/Help/UGen/bufSampleRate.help.lhs
--- a/Help/UGen/bufSampleRate.help.lhs
+++ b/Help/UGen/bufSampleRate.help.lhs
@@ -7,9 +7,11 @@
 
 > fn_01 = "/home/rohan/data/audio/pf-c5.aif"
 
-    > withSC3 (async (b_allocRead 0 fn_01 0 0))
+> m_01 = b_allocRead 0 fn_01 0 0
 
-Sine tone derived from sample rate of buffer an 440Hz tone.
+    > withSC3 (async m_01)
+
+Sine tone derived from sample rate of buffer (ie. 48000 / 100 == 480) and a 440Hz tone.
 
 > g_01 =
 >     let f = mce [bufSampleRate KR 0 * 0.01, 440]
diff --git a/Help/UGen/changed.help.lhs b/Help/UGen/changed.help.lhs
--- a/Help/UGen/changed.help.lhs
+++ b/Help/UGen/changed.help.lhs
@@ -10,3 +10,10 @@
 >         c = changed s 0
 >         c' = decay2 c 0.01 0.5
 >     in sinOsc AR (440 + mce2 s c' * 440) 0 * 0.1
+
+sinOsc is constantly changing...
+
+> g_02 =
+>   let s = sinOsc AR 440 0
+>       c = changed s 0
+>   in s * c * 0.2
diff --git a/Help/UGen/compander.help.lhs b/Help/UGen/compander.help.lhs
--- a/Help/UGen/compander.help.lhs
+++ b/Help/UGen/compander.help.lhs
@@ -1,45 +1,49 @@
-Sound.SC3.UGen.Help.viewSC3Help "Compander"
-Sound.SC3.UGen.DB.ugenSummary "Compander"
+    Sound.SC3.UGen.Help.viewSC3Help "Compander"
+    Sound.SC3.UGen.DB.ugenSummary "Compander"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
 Example signal to process.
 
-> z =
+> g_01 =
 >     let e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
 >         p = mix (pulse AR (mce [80, 81]) 0.3)
 >     in e * p
 
-> z' = soundIn 2
-
-    audition (out 0 z)
+> g_02 = soundIn 0
 
 Noise gate (no hold, no hysteresis)
 
-> g_01 =
+> f_01 z =
 >     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 =
+> f_02 z =
 >     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 =
+> f_03 z =
 >     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 =
+> f_04 z =
 >     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 =
+> f_05 z =
 >     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]
+
+> g_03 = f_01 g_01
+> g_04 = f_02 g_01
+> g_05 = f_03 g_01
+> g_06 = f_04 g_01
+> g_07 = f_05 g_01
diff --git a/Help/UGen/complexRes.help.lhs b/Help/UGen/complexRes.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/complexRes.help.lhs
@@ -0,0 +1,11 @@
+    Sound.SC3.UGen.Help.viewSC3Help "ComplexRes"
+    Sound.SC3.UGen.DB.ugenSummary "ComplexRes"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as External {- hsc3 -}
+
+> g_01 =
+>   let s = pulse AR 0.1 0.001 * 0.1
+>       fr = 50 + 5000 * sinOsc AR 50 0
+>       dt = 0.5
+>   in External.complexRes s fr dt
diff --git a/Help/UGen/controlDur.help.lhs b/Help/UGen/controlDur.help.lhs
--- a/Help/UGen/controlDur.help.lhs
+++ b/Help/UGen/controlDur.help.lhs
@@ -3,8 +3,8 @@
 
 > import Sound.SC3 {- hsc3 -}
 
-controlRate and controlDur are reciprocals
+default block size = 64, default sample rate = 48000
 
-> g_01 =
->    let f = mce2 controlRate (recip controlDur)
->    in sinOsc AR f 0 * 0.1
+> g_01 = sinOsc AR (mce2 (recip controlDur) (controlRate + 1)) 0 * 0.1
+
+> g_02 = sinOsc AR (mce2 (recip controlDur) (recip (blockSize / sampleRate) + 1)) 0 * 0.1
diff --git a/Help/UGen/convolution.help.lhs b/Help/UGen/convolution.help.lhs
--- a/Help/UGen/convolution.help.lhs
+++ b/Help/UGen/convolution.help.lhs
@@ -1,8 +1,14 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Convolution"
-> Sound.SC3.UGen.DB.ugenSummary "Convolution"
+    > Sound.SC3.UGen.Help.viewSC3Help "Convolution"
+    > Sound.SC3.UGen.DB.ugenSummary "Convolution"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> let {k = whiteNoise 'α' AR
->     ;i = in' 2 AR numOutputBuses}
-> in audition (out 0 (convolution i k 2048 * 0.1))
+> g_01 =
+>   let k = pinkNoise 'α' AR * 0.1
+>       i = soundIn 0
+>   in convolution AR i k 2048
+
+> g_02 =
+>   let k = mix (lfSaw AR (mce [300,500,800,1000] * mouseX KR 1.0 2.0 Linear 0.2) 0 * 0.1)
+>       i = soundIn 0
+>   in convolution AR i k 1024 * 0.5
diff --git a/Help/UGen/coyote.help.lhs b/Help/UGen/coyote.help.lhs
--- a/Help/UGen/coyote.help.lhs
+++ b/Help/UGen/coyote.help.lhs
@@ -1,9 +1,11 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Coyote"
-> Sound.SC3.UGen.DB.ugenSummary "Coyote"
+    Sound.SC3.UGen.Help.viewSC3Help "Coyote"
+    Sound.SC3.UGen.DB.ugenSummary "Coyote"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
-> 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))
+> g_01 =
+>   let i = soundIn 0
+>       c = coyote KR i 0.2 0.2 0.01 0.5 0.05 0.1
+>       o = pinkNoise 'α' AR * decay c 1
+>   in mce2 i o
diff --git a/Help/UGen/crackle.help.lhs b/Help/UGen/crackle.help.lhs
--- a/Help/UGen/crackle.help.lhs
+++ b/Help/UGen/crackle.help.lhs
@@ -2,7 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "Crackle"
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 = crackle AR 1.95 * 0.2
 
 Modulate chaos parameter
diff --git a/Help/UGen/crossoverDistortion.help.lhs b/Help/UGen/crossoverDistortion.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/crossoverDistortion.help.lhs
@@ -0,0 +1,19 @@
+    Sound.SC3.UGen.Help.viewSC3Help "CrossoverDistortion"
+    Sound.SC3.UGen.DB.ugenSummary "CrossoverDistortion"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+{CrossoverDistortion.ar(SinOsc.ar([400, 404], 0, 0.2), MouseX.kr(0, 1), MouseY.kr(0, 1))}.play
+
+> g_01 =
+>   let x = mouseX KR 0 1 Linear 0.2
+>       y = mouseY KR 0 1 Linear 0.2
+>   in crossoverDistortion (sinOsc AR (mce2 400 404) 0 * 0.2) x y
+
+{CrossoverDistortion.ar(SoundIn.ar, MouseX.kr(0, 1), MouseY.kr(0, 1))}.play
+
+> g_02 =
+>   let x = mouseX KR 0 1 Linear 0.2
+>       y = mouseY KR 0 1 Linear 0.2
+>   in crossoverDistortion (soundIn 0) x y
diff --git a/Help/UGen/cuspL.help.lhs b/Help/UGen/cuspL.help.lhs
--- a/Help/UGen/cuspL.help.lhs
+++ b/Help/UGen/cuspL.help.lhs
@@ -23,3 +23,11 @@
 >         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
+
+Haskell implementation of equation.
+
+> cuspl_hs a b = iterate (\x -> a - (b * sqrt (abs x))) 0
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plotTable1 (take 600 (cuspl_hs 1.0 1.9))
+    plot_ugen_nrt (600,1) 1.0 (cuspL AR 600 1.0 1.9 0)
diff --git a/Help/UGen/dNoiseRing.help.lhs b/Help/UGen/dNoiseRing.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dNoiseRing.help.lhs
@@ -0,0 +1,13 @@
+    Sound.SC3.UGen.Help.viewSC3Help "DNoiseRing"
+    Sound.SC3.UGen.DB.ugenSummary "DNoiseRing"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as External {- hsc3 -}
+
+> g_01 =
+>   let tr = impulse AR 10 0
+>       x = mouseX KR 0 1 Linear 0.2
+>       y = mouseY KR 0 1 Linear 0.2
+>       nr = demand tr 0 (External.dNoiseRing x y 1.0 32.0 0.0)
+>       freq = midiCPS (linLin nr 0 (2**32) 40 (40 + 48))
+>   in sinOsc AR freq 0 * 0.1
diff --git a/Help/UGen/dPW3Tri.help.lhs b/Help/UGen/dPW3Tri.help.lhs
deleted file mode 100644
--- a/Help/UGen/dPW3Tri.help.lhs
+++ /dev/null
@@ -1,44 +0,0 @@
-    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
--- a/Help/UGen/dWGPlucked2.help.lhs
+++ b/Help/UGen/dWGPlucked2.help.lhs
@@ -1,39 +1,53 @@
-> Sound.SC3.UGen.Help.viewSC3Help "DWGPlucked2"
-> Sound.SC3.UGen.DB.ugenSummary "DWGPlucked2"
+    Sound.SC3.UGen.Help.viewSC3Help "DWGPlucked2"
+    Sound.SC3.UGen.DB.ugenSummary "DWGPlucked2"
 
 > import Sound.SC3
+> import qualified Sound.SC3.UGen.Bindings.DB.External as E {- hsc3 -}
 
 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))
+> g_01 =
+>   let freq = 440
+>       amp = 0.5
+>       gate_ = 1
+>       c3 = 20
+>       inp = let e = envelope [0,1,1,0] [0.001,0.006,0.0005] (map EnvNum [5,-5,-8])
+>             in amp * lfClipNoise 'α' AR 2000 * envGen AR gate_ 1 0 1 DoNothing e
+>       ps = E.dWGPlucked2 AR freq amp gate_ 0.1 1 c3 inp 0.1 1.008 0.55 0.01
+>       pan = 0
+>       z = detectSilence ps 0.001 0.1 RemoveSynth
+>   in mrg2 (pan2 ps 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))
+> f_02 dur =
+>   let sequ e s tr = demand tr 0 (dseq e dinf (mce s))
+>       t = let d = dseq 'α' dinf dur
+>           in tDuty AR d 0 DoNothing 1 0
+>       freq = let n0 = sequ 'β' [60,62,63,58,48,55] t
+>                  n1 = sequ 'γ' [63,60,48,62,55,58] t
+>              in midiCPS (mce2 n0 n1)
+>       amp = tRand 'δ' 0.01 0.35 t -- pulse amplitude (0  - 1, def = 0.5)
+>       gate_ = 1 -- synth release
+>       pos = tRand 'ε' 0.05 0.25 t -- pluck position (0 - 1, def = 0.14)
+>       c1 = 1 / tRand 'ζ' 0.25 1.75 t -- reciprocal of decay time (def = 1.0)
+>       c3 = tRand 'η' 10 1400 t -- high frequency loss factor (def = 30)
+>       inp = let e_dt = tRand 'θ' 0.05 0.150 t
+>                 env = decay2 t 0.001 e_dt * lfClipNoise 'ι' AR 2000
+>             in amp * lfClipNoise 'κ' AR 2000 * env -- pluck signal
+>       release = tRand 'λ' 0.05 0.15 t -- release time (seconds, def = 0.1)
+>       mistune = tRand 'μ' 0.992 1.008 t -- factor for detuning second string (def = 1.008)
+>       mp = tRand 'ν' 0.35 0.65 t -- exitation mixer (def = 0.55)
+>       gc = tRand 'ξ' 0.001 0.020 t -- coupling string factor (def = 0.01)
+>       ps = E.dWGPlucked2 AR freq amp gate_ pos c1 c3 inp release mistune mp gc
+>       pan = tRand 'ο' (-1) 1 t
+>   in pan2 ps pan 0.1
+
+> g_02 = f_02 (mce [1,1,2,1,1,1,2,3,1,1,1,1,2,3,4] * 0.175)
+
+and scaling
+
+> g_03 =
+>   let m = mouseX KR 0.25 2.0 Linear 0.2
+>       d = 1 / (2 ** roundE (mce [1,1,2,1,1,1,2,3,1,1,1,1,2,3,4]))
+>   in f_02 (d * m)
diff --git a/Help/UGen/dWGPluckedStiff.help.lhs b/Help/UGen/dWGPluckedStiff.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dWGPluckedStiff.help.lhs
@@ -0,0 +1,46 @@
+    Sound.SC3.UGen.Help.viewSC3Help "DWGPluckedStiff"
+    Sound.SC3.UGen.DB.ugenSummary "DWGPluckedStiff"
+
+> import Sound.SC3
+> import qualified Sound.SC3.UGen.Bindings.DB.External as E {- hsc3 -}
+
+self deleting
+
+> g_01 =
+>   let freq = 440
+>       amp = 0.5
+>       gate_ = 1
+>       pos = 0.14
+>       c1 = 1
+>       c3 = 30
+>       inp = let e = envelope [0,1,1,0] [0.001,0.006,0.0005] (map EnvNum [5,-5,-8])
+>             in amp * lfClipNoise 'α' AR 2000 * envGen AR gate_ 1 0 1 DoNothing e
+>       release = 0.1
+>       fB = 2.0
+>       ps = E.dWGPluckedStiff AR freq amp gate_ pos c1 c3 inp release fB
+>       pan = 0
+>       z = detectSilence ps 0.001 0.1 RemoveSynth
+>   in mrg2 (pan2 ps pan 0.1) z
+
+re-sounding
+
+> g_02 =
+>   let sequ e s tr = demand tr 0 (dseq e dinf (mce s))
+>       t = let d = dseq 'α' dinf (mce [1,1,2,1,1,1,2,3,1,1,1,1,2,3,4] * 0.175)
+>           in tDuty AR d 0 DoNothing 1 0
+>       freq = let n0 = sequ 'β' [60,62,63,58,48,55] t
+>                  n1 = sequ 'γ' [63,60,48,62,55,58] t
+>              in midiCPS (mce2 n0 n1)
+>       amp = tRand 'δ' 0.05 0.65 t -- pulse amplitude (0  - 1, def = 0.5)
+>       gate_ = 1 -- synth release
+>       pos = tRand 'ε' 0.05 0.25 t -- pluck position (0 - 1, def = 0.14)
+>       c1 = 1 / tRand 'ζ' 0.25 1.75 t -- reciprocal of decay time (def = 1.0)
+>       c3 = tRand 'η' 10 1400 t -- high frequency loss factor (def = 30)
+>       inp = let e_dt = tRand 'θ' 0.05 0.150 t
+>                 env = decay2 t 0.001 e_dt * lfClipNoise 'ι' AR 2000
+>             in amp * lfClipNoise 'κ' AR 2000 * env -- pluck signal
+>       release = tRand 'λ' 0.05 0.15 t -- release time (seconds, def = 0.1)
+>       fB = tRand 'μ' 1.0 4.0 t -- inharmonicity factor (def = 2.0)
+>       ps = E.dWGPluckedStiff AR freq amp gate_ pos c1 c3 inp release fB
+>       pan = tRand 'ο' (-1) 1 t
+>   in pan2 ps pan 0.1
diff --git a/Help/UGen/dbrown.help.lhs b/Help/UGen/dbrown.help.lhs
--- a/Help/UGen/dbrown.help.lhs
+++ b/Help/UGen/dbrown.help.lhs
@@ -1,10 +1,16 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Dbrown"
-> Sound.SC3.UGen.DB.ugenSummary "Dbrown"
+    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))
+> g_01 =
+>   let n = dbrown 'α' dinf 0 15 1 {- Dbrown(0, 15, 1, inf) -}
+>       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
+
+> g_02 =
+>   let n = demand (impulse KR 10 0) 0 (dbrown 'α' dinf (-1) 1 0.05)
+>       f = linExp n (-1) 1 64 9600
+>   in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/degreeToKey.help.lhs b/Help/UGen/degreeToKey.help.lhs
--- a/Help/UGen/degreeToKey.help.lhs
+++ b/Help/UGen/degreeToKey.help.lhs
@@ -5,17 +5,23 @@
 
 allocate & initialise buffer zero
 
-    > withSC3 (async (b_alloc_setn1 0 0 [0,2,3.2,5,7,9,10]))
+> m_01 = b_alloc_setn1 0 0 [0,2,3.2,5,7,9,10]
 
+    > withSC3 (async m_01)
+
 modal space, mouse x controls discrete pitch in dorian mode
 
-> g_01 =
+> f_01 b =
 >     let n = lfNoise1 'α' KR (mce [3,3.05])
 >         x = mouseX KR 0 15 Linear 0.1
->         k = degreeToKey 0 x 12
+>         k = degreeToKey b 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
+
+> g_01 = f_01 0
+
+> g_02 = f_01 (asLocalBuf 'β' [0,2,3.2,5,7,9,10])
diff --git a/Help/UGen/delay1.help.lhs b/Help/UGen/delay1.help.lhs
--- a/Help/UGen/delay1.help.lhs
+++ b/Help/UGen/delay1.help.lhs
@@ -2,7 +2,7 @@
     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
diff --git a/Help/UGen/delayN.help.lhs b/Help/UGen/delayN.help.lhs
--- a/Help/UGen/delayN.help.lhs
+++ b/Help/UGen/delayN.help.lhs
@@ -4,13 +4,11 @@
 > 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.
+for the WhiteNoise input source.  The input is left, the delay right.
 
 > 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
+>     in mce2 i (delayN i 0.1 0.1)
 
 The delay time can be varied at control rate.  An oscillator either
 reinforcing or cancelling with the delayed copy of itself.
diff --git a/Help/UGen/demandEnvGen.help.lhs b/Help/UGen/demandEnvGen.help.lhs
--- a/Help/UGen/demandEnvGen.help.lhs
+++ b/Help/UGen/demandEnvGen.help.lhs
@@ -93,3 +93,19 @@
 >         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
+
+lfNoise1
+
+> g_09 =
+>     let y = mouseY KR 0.5 20 Linear 0.2
+>         lvl = dwhite 'β' dinf (-0.1) 0.1
+>         dur = sampleDur * y
+>     in demandEnvGen AR lvl dur 5 (-4) 1 1 1 0 1 RemoveSynth
+
+lfBrownNoise
+
+> g_10 =
+>     let y = mouseY KR 1 100 Exponential 0.2
+>         lvl = dbrown 'β' dinf (-0.1) 0.1 0.1
+>         dur = sampleDur * y
+>     in demandEnvGen AR lvl dur 1 0 1 1 1 0 1 RemoveSynth
diff --git a/Help/UGen/detectIndex.help.lhs b/Help/UGen/detectIndex.help.lhs
--- a/Help/UGen/detectIndex.help.lhs
+++ b/Help/UGen/detectIndex.help.lhs
@@ -3,18 +3,10 @@
 
 > 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
+>         i = detectIndex (asLocalBuf 'α' [2,3,4,0,1,5]) 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/dfm1.help.lhs b/Help/UGen/dfm1.help.lhs
--- a/Help/UGen/dfm1.help.lhs
+++ b/Help/UGen/dfm1.help.lhs
@@ -1,19 +1,20 @@
     Sound.SC3.UGen.Help.viewSC3Help "DFM1"
     Sound.SC3.UGen.DB.ugenSummary "DFM1"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 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
+>         y = mouseY 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
+>     let i = mix (pulse AR (mce2 100 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
+>     in dfm1 i f 1.1 2 0 0.0003 * 0.1
diff --git a/Help/UGen/diodeRingMod.help.lhs b/Help/UGen/diodeRingMod.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/diodeRingMod.help.lhs
@@ -0,0 +1,51 @@
+    Sound.SC3.UGen.Help.viewSC3Help "DiodeRingMod"
+    Sound.SC3.UGen.DB.ugenSummary "DiodeRingMod"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as External {- hsc3 -}
+
+> o_01 = sinOsc AR 440 0
+> o_02 = sinOsc AR (xLine KR 1 100 10 DoNothing) 0
+> o_03 = sinOsc AR (xLine KR 200 500 5 DoNothing) 0
+> g_01 = External.diodeRingMod o_01 o_02 * 0.125
+> g_02 = (o_01 * o_02) * 0.125
+> g_03 = External.diodeRingMod o_01 o_03 * 0.125
+> g_04 = (o_01 * o_03) * 0.125
+
+> g_05 =
+>   let s1 = sinOsc AR (3700 * mce [1, 1.1, 1.2] * range 1 2 (sinOsc AR 200 0)) 0
+>       s2 = sinOsc AR (100 * mce [0.75, 1, 0.5]) 0
+>       s3 = External.diodeRingMod s1 s2
+>   in mix s3 * lfPulse AR (10.3 * 0.5) 0 0.04 * 0.1
+
+> mf_sin = sinOsc AR
+
+> mf_square f _ = External.blitB3Square AR f 0.99
+
+c_freq = carrier frequency (mf = six-octave range, 2-130 and 60-4000 hz)
+
+lfo_type = LFO signal function, ie. mf_sin or mf_square
+
+lfo_freq = LFO frequency (mf = 0.1 - 25.0 hz)
+
+lfo_amp = the amount that the LFO output sweeps the carrier sin oscillator
+
+drive = pre-multiplier for mod_sig
+
+x_mix = crossfade from unmodulated to modulated audio (-1 to 1)
+
+> mf_ring_mod (lfo_ph,car_ph) car_freq lfo_type lfo_freq lfo_amp drive x_mix mod_sig =
+>   let range_2oct = range 0.25 2
+>       lfo = range_2oct (lfo_type lfo_freq lfo_ph * lfo_amp)
+>       car_sig = sinOsc AR (car_freq * lfo) car_ph
+>       mod_sig_post = mod_sig * drive
+>   in xFade2 mod_sig_post (External.diodeRingMod car_sig mod_sig_post) x_mix 1
+
+> g_07 =
+>   let c_freq = 6.25
+>       lfo_freq = 0.1
+>       lfo_amp = mouseY KR 0 1 Linear 0.2
+>       drive = 1
+>       x_mix = mouseX KR (-1) 1 Linear 0.2
+>       mod_sig = soundIn 0
+>   in mf_ring_mod (0,0) c_freq mf_sin lfo_freq lfo_amp drive x_mix mod_sig
diff --git a/Help/UGen/disintegrator.help.lhs b/Help/UGen/disintegrator.help.lhs
--- a/Help/UGen/disintegrator.help.lhs
+++ b/Help/UGen/disintegrator.help.lhs
@@ -2,6 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "Disintegrator"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 > gr_01 =
 >     let x = mouseX KR 0 1 Linear 0.2
diff --git a/Help/UGen/diskIn.help.lhs b/Help/UGen/diskIn.help.lhs
--- a/Help/UGen/diskIn.help.lhs
+++ b/Help/UGen/diskIn.help.lhs
@@ -1,8 +1,8 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "DiskIn"
-    > Sound.SC3.UGen.DB.ugenSummary "DiskIn"
+    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]
diff --git a/Help/UGen/diskOut.help.lhs b/Help/UGen/diskOut.help.lhs
--- a/Help/UGen/diskOut.help.lhs
+++ b/Help/UGen/diskOut.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "DiskOut"
-    > Sound.SC3.UGen.DB.ugenSummary "DiskOut"
+    Sound.SC3.UGen.Help.viewSC3Help "DiskOut"
+    Sound.SC3.UGen.DB.ugenSummary "DiskOut"
 
 > import Sound.OSC {- hosc -}
 > import Sound.SC3 {- hsc3 -}
@@ -14,7 +14,7 @@
 
 Check incoming signal (either graph above or the outside world, or `C-cC-a`)
 
-    > audition (out 0 g_01)
+    audition (out 0 g_01)
 
 Record incoming signal (or above...), print some informational traces...
 
@@ -25,24 +25,28 @@
 > 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 ()})
+> act_01 :: Transport m => m ()
+> act_01 = 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"
+>   sendMessage (n_free [2001])
+>   mapM_ async msg_02
+>   return ()
 
+    withSC3 act_01
+
 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)
+    withSC3 (mapM_ async msg_03)
 
 > g_03 = diskIn nc_01 0 Loop
 
 Tidy up...
 
-    > withSC3 (mapM_ async msg_02)
+    withSC3 (mapM_ async msg_02)
diff --git a/Help/UGen/distort.help.lhs b/Help/UGen/distort.help.lhs
--- a/Help/UGen/distort.help.lhs
+++ b/Help/UGen/distort.help.lhs
@@ -2,7 +2,7 @@
     > :t distort
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 =
 >     let e = xLine KR 0.1 10 10 DoNothing
 >         o = fSinOsc AR 500 0.0
diff --git a/Help/UGen/diwhite.help.lhs b/Help/UGen/diwhite.help.lhs
--- a/Help/UGen/diwhite.help.lhs
+++ b/Help/UGen/diwhite.help.lhs
@@ -1,4 +1,4 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Diwhite"
-> Sound.SC3.UGen.DB.ugenSummary "Diwhite"
+    > Sound.SC3.UGen.Help.viewSC3Help "Diwhite"
+    > Sound.SC3.UGen.DB.ugenSummary "Diwhite"
 
 See dwhite
diff --git a/Help/UGen/doubleWell3.help.lhs b/Help/UGen/doubleWell3.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/doubleWell3.help.lhs
@@ -0,0 +1,20 @@
+    Sound.SC3.UGen.Help.viewSC3Help "DoubleWell3"
+    Sound.SC3.UGen.DB.ugenSummary "DoubleWell3"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+bass synth
+
+> g_01 =
+>   let x = mouseX KR 0 200 Linear 0.2
+>       y = mouseY KR 0.5 4.0 Linear 0.2
+>       f = sinOsc AR x 0 * y
+>   in doubleWell3 AR 0 0.01 f 0.25 0 0
+
+gradually changing
+
+> g_02 =
+>   let f = lfSaw AR (line KR 10 1000 10 DoNothing) 0
+>       delta = line KR 0.0 0.3 20 DoNothing
+>   in doubleWell3 AR 0 0.05 f delta 0 0
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.DB.External as E {- hsc3 -}
+
+> import qualified Sound.SC3.UGen.Bindings.DB.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/dpw4Saw.help.lhs b/Help/UGen/dpw4Saw.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/dpw4Saw.help.lhs
@@ -0,0 +1,13 @@
+    Sound.SC3.UGen.Help.viewSC3Help "DPW4Saw"
+    Sound.SC3.UGen.DB.ugenSummary "DPW4Saw"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as E {- hsc3 -}
+
+> import qualified Sound.SC3.UGen.Bindings.DB.RDU as RDU {- sc3-rdu -}
+
+> g_01 = E.dpw4Saw AR (xLine KR 2000 20 10 DoNothing) * 0.1
+
+> g_02 = E.dpw4Saw AR (mouseX KR 200 12000 Exponential 0.2) * 0.2
+
+> g_03 = saw AR (mouseX KR 200 12000 Exponential 0.2) * 0.1
diff --git a/Help/UGen/dshuf.help.lhs b/Help/UGen/dshuf.help.lhs
--- a/Help/UGen/dshuf.help.lhs
+++ b/Help/UGen/dshuf.help.lhs
@@ -2,7 +2,7 @@
     > Sound.SC3.UGen.DB.ugenSummary "Dshuf"
 
 > import Sound.SC3 {- hsc3 -}
-> import qualified Sound.SC3.UGen.External.RDU as RDU {- sc3-rdu -}
+> import qualified Sound.SC3.UGen.Bindings.DB.RDU as RDU {- sc3-rdu -}
 
 > g_01 =
 >     let a = dseq 'α' dinf (dshuf 'β' 3 (mce [1,3,2,7,8.5]))
diff --git a/Help/UGen/dust.help.lhs b/Help/UGen/dust.help.lhs
--- a/Help/UGen/dust.help.lhs
+++ b/Help/UGen/dust.help.lhs
@@ -1,10 +1,10 @@
     Sound.SC3.UGen.Help.viewSC3Help "Dust"
     Sound.SC3.UGen.DB.ugenSummary "Dust"
 
-> import Sound.SC3
->
-> g_01 = dust 'α' AR 200 * 0.25
->
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = dust 'α' AR 2 * 0.25
+
 > g_02 =
 >     let d = xLine KR 20000 2 10 RemoveSynth
 >     in dust 'β' AR d * 0.15
diff --git a/Help/UGen/dwhite.help.lhs b/Help/UGen/dwhite.help.lhs
--- a/Help/UGen/dwhite.help.lhs
+++ b/Help/UGen/dwhite.help.lhs
@@ -2,9 +2,9 @@
     > Sound.SC3.UGen.DB.ugenSummary "Dwhite"
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 =
->     let n = dwhite 'α' 30 0 15
+>     let n = dwhite 'α' dinf 0 15 {- Dwhite(0, 15, inf) -}
 >         x = mouseX KR 1 40 Exponential 0.1
 >         t = impulse KR x 0
 >         f = demand t 0 n * 30 + 340
diff --git a/Help/UGen/envCoord.help.lhs b/Help/UGen/envCoord.help.lhs
--- a/Help/UGen/envCoord.help.lhs
+++ b/Help/UGen/envCoord.help.lhs
@@ -1,6 +1,6 @@
     :t envCoord
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
 co-ordinate (break-point) envelope
 
diff --git a/Help/UGen/envDetect.help.lhs b/Help/UGen/envDetect.help.lhs
--- a/Help/UGen/envDetect.help.lhs
+++ b/Help/UGen/envDetect.help.lhs
@@ -2,10 +2,10 @@
     Sound.SC3.UGen.DB.ugenSummary "EnvDetect"
 
 > import Sound.SC3 {- hsc3 -}
-> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 > g_01 =
->     let i = soundIn 4
+>     let i = soundIn 0
 >         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
diff --git a/Help/UGen/envFollow.help.lhs b/Help/UGen/envFollow.help.lhs
--- a/Help/UGen/envFollow.help.lhs
+++ b/Help/UGen/envFollow.help.lhs
@@ -2,10 +2,10 @@
     > Sound.SC3.UGen.DB.ugenSummary "EnvFollow"
 
 > import Sound.SC3 {- hsc3 -}
-> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 > g_01 =
->     let z = soundIn 4
+>     let z = soundIn 0
 >         d = mouseX KR 0.990 0.999 Linear 0.2
 >         c = envFollow KR z d
 >         o = pinkNoise 'α' AR * c
diff --git a/Help/UGen/envGate.help.lhs b/Help/UGen/envGate.help.lhs
--- a/Help/UGen/envGate.help.lhs
+++ b/Help/UGen/envGate.help.lhs
@@ -2,7 +2,7 @@
 
 > import Sound.SC3 {- hsc3 -}
 
-Make envGate, giving the /default/ arguments, as used by envGate'.
+Make envGate, giving the /default/ arguments, as used by envGate_def.
 
 > g_01 =
 >     let k = control KR
@@ -18,14 +18,14 @@
 The same, but built in defaults.
 
 > g_02 =
->     let e = envGate'
+>     let e = envGate_def
 >     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'
+>     let e = envGate_def
 >         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
diff --git a/Help/UGen/envGen.help.lhs b/Help/UGen/envGen.help.lhs
--- a/Help/UGen/envGen.help.lhs
+++ b/Help/UGen/envGen.help.lhs
@@ -1,33 +1,73 @@
     > 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.
+See also help files for the following envelope constructors:
 
+- envADSR
+- envASR
+- envCoord
+- envGate
+- envLinen
+- envPairs
+- envPerc
+- envSine
+- envStep
+- envTrapezoid
+- envTriangle
+- envXYC
+
 > import Sound.SC3 {- hsc3 -}
 
 env_circle joins the end of the envelope to the start
 
+> e_01 :: Fractional n => Envelope n
+> e_01 = Envelope [6000,700,100] [1,1] [EnvExp,EnvLin] Nothing Nothing 0
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plotEnvelope [e_01]
+
+> e_01_c :: Fractional n => Envelope n
+> e_01_c = env_circle_0 e_01
+
+    plotEnvelope [e_01_c]
+
 > 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)
+>     let f = envGen KR 1 1 0 1 DoNothing e_01_c
 >     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
+    > r = [0,4,3,0,6000,0,1,0,700,1,2,0,100,1,1,0,0,9e8,1,0]
+    > envelope_sc3_array (env_circle e_01 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]
+    > e = Envelope [0,1] [0.1] [EnvLin] Nothing Nothing 0
+    > 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
 
+> e_02 =
+>   let n = range 0.01 0.15 (lfNoise1 'α' KR 2)
+>   in Envelope [0,1] [n] [EnvLin] Nothing (Just 0) 0
+
+> e_02_c = env_circle_0 e_02
+
 > 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)
+>     let a = envGen AR 1 1 0 1 DoNothing e_02_c
 >     in sinOsc AR (a * 400 + 500) 0 * 0.1
+
+EnvGen used as non-linear Phasor, here the positive half of a sin
+function is traversed more quickly than the negative half.
+
+> e_03 :: (Floating n,Ord n) => Envelope n
+> e_03 = envXYC [(0,0,EnvNum (-0.5)),(0.4,pi,EnvNum 0.5),(1,two_pi,EnvLin)]
+> e_03_c = env_circle_0 e_03
+
+    plotEnvelope [e_03]
+
+> f_03 rt ts = sinOsc rt 0 (envGen rt 1 1 0 ts DoNothing e_03_c)
+
+> g_03 = soundIn 0 * range 0.25 1 (f_03 KR 2)
+
+   plot_ugen 0.1 (f_03 AR 0.1)
diff --git a/Help/UGen/envLinen.help.lhs b/Help/UGen/envLinen.help.lhs
--- a/Help/UGen/envLinen.help.lhs
+++ b/Help/UGen/envLinen.help.lhs
@@ -18,6 +18,8 @@
     import Sound.SC3.Plot {- hsc3-plot -}
     plotEnvelope e_01
 
+Language access
+
 > e_02 =
 >     let e = envLinen 0 1 0 1
 >     in (envelope_duration e
@@ -28,3 +30,5 @@
 >        ,envelope_at e 0
 >        ,envelope_at e 1
 >        ,envelope_render 10 e)
+
+    print e_02
diff --git a/Help/UGen/envPairs.help.lhs b/Help/UGen/envPairs.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envPairs.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Env.*pairs"
+    :t envPairs
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let c = EnvLin
+>         p = envPairs [(0,0),(5,0.01),(5.5,0.1),(10,0)] c
+>         e = envGen KR 1 1 0 1 RemoveSynth p
+>     in sinOsc AR 440 0 * e
diff --git a/Help/UGen/envXYC.help.lhs b/Help/UGen/envXYC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/envXYC.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Env.*xyc"
+    :t Sound.SC3.envXYC
+
+> import Sound.SC3 {- hsc3 -}
+
+> e_01 :: (Fractional n,Ord n) => Envelope n
+> e_01 = envXYC [(0, 330, EnvExp), (0.5, 440, EnvExp), (1.0, 1760, EnvLin)]
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plotEnvelope [e_01]
diff --git a/Help/UGen/expRand.help.lhs b/Help/UGen/expRand.help.lhs
--- a/Help/UGen/expRand.help.lhs
+++ b/Help/UGen/expRand.help.lhs
@@ -2,7 +2,7 @@
     > 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
diff --git a/Help/UGen/fftTrigger.help.lhs b/Help/UGen/fftTrigger.help.lhs
--- a/Help/UGen/fftTrigger.help.lhs
+++ b/Help/UGen/fftTrigger.help.lhs
@@ -1,2 +1,2 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FFTTrigger"
-> Sound.SC3.UGen.DB.ugenSummary "FFTTrigger"
+    > 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
--- a/Help/UGen/fm7.help.lhs
+++ b/Help/UGen/fm7.help.lhs
@@ -2,8 +2,10 @@
     Sound.SC3.UGen.DB.ugenSummary "FM7"
 
 > import Sound.SC3 {- hsc3 -}
-> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as E {- hsc3 -}
 
+two of six...
+
 > gr_01 =
 >     let c = [[xLine KR 300 310 4 DoNothing,0,1]
 >             ,[xLine KR 300 310 8 DoNothing,0,1]
@@ -17,7 +19,7 @@
 >             ,[0,0,0,0,0,0]
 >             ,[0,0,0,0,0,0]
 >             ,[0,0,0,0,0,0] ]
->         [l,r,_,_,_,_] = mceChannels (fm7 c m)
+>         [l,r,_,_,_,_] = mceChannels (fm7_mx c m)
 >     in mce2 l r * 0.1
 
 An algorithmically generated graph courtesy f0.
@@ -79,7 +81,7 @@
 >              ,[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)
+>         [c1,c2,c3,c4,c5,c6] = mceChannels (fm7_mx 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]
+>         g6 = dbAmp (-3)
+>     in mce [c1 + c3 * g3 + c5,c2 + c4 + c6 * g6]
diff --git a/Help/UGen/fmGrain.help.lhs b/Help/UGen/fmGrain.help.lhs
--- a/Help/UGen/fmGrain.help.lhs
+++ b/Help/UGen/fmGrain.help.lhs
@@ -2,6 +2,7 @@
     > Sound.SC3.UGen.DB.ugenSummary "FMGrain"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 > g_01 =
 >     let t = impulse AR 20 0
diff --git a/Help/UGen/fmGrainB.help.lhs b/Help/UGen/fmGrainB.help.lhs
--- a/Help/UGen/fmGrainB.help.lhs
+++ b/Help/UGen/fmGrainB.help.lhs
@@ -1,15 +1,18 @@
-> Sound.SC3.UGen.Help.viewSC3Help "FMGrainB"
-> Sound.SC3.UGen.DB.ugenSummary "FMGrainB"
+    Sound.SC3.UGen.Help.viewSC3Help "FMGrainB"
+    Sound.SC3.UGen.DB.ugenSummary "FMGrainB"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
-> withSC3 (do {_ <- async (b_alloc 10 512 1)
->             ;let f = [Normalise,Wavetable,Clear]
->              in send (b_gen_sine2 10 f [(0.5,0.1)])})
+> m_01 =
+>   [b_alloc 10 512 1
+>   ,b_gen_sine2 10 [Normalise,Wavetable,Clear] [(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)
+    withSC3 (mapM_ maybe_async m_01)
+
+> 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 fmGrainB t 0.2 440 220 n 10 * e
diff --git a/Help/UGen/formant.help.lhs b/Help/UGen/formant.help.lhs
--- a/Help/UGen/formant.help.lhs
+++ b/Help/UGen/formant.help.lhs
@@ -3,6 +3,10 @@
 
 > import Sound.SC3
 
+Default values
+
+> g_00 = formant AR 440 1760 880 * 0.125
+
 Modulate fundamental frequency, formant frequency stays constant.
 
 > g_01 = formant AR (xLine KR 400 1000 8 RemoveSynth) 2000 800 * 0.125
diff --git a/Help/UGen/formlet.help.lhs b/Help/UGen/formlet.help.lhs
--- a/Help/UGen/formlet.help.lhs
+++ b/Help/UGen/formlet.help.lhs
@@ -24,11 +24,11 @@
 >         y = mouseY KR 700 2000 Exponential 0.2
 >     in formlet s y 0.005 x
 
-and again...
+and again (control-rate)...
 
 > 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
+>     in k2a f + sinOsc AR (f * 200 + mce2 500 600 - 100) 0 * 0.2
diff --git a/Help/UGen/gate.help.lhs b/Help/UGen/gate.help.lhs
--- a/Help/UGen/gate.help.lhs
+++ b/Help/UGen/gate.help.lhs
@@ -1,7 +1,8 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Gate"
-> Sound.SC3.UGen.DB.ugenSummary "Gate"
+    Sound.SC3.UGen.Help.viewSC3Help "Gate"
+    Sound.SC3.UGen.DB.ugenSummary "Gate"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> let t = lfPulse AR 1 0 0.1
-> in audition (out 0 (gate (fSinOsc AR 500 0 * 0.25) t))
+> g_01 =
+>   let t = lfPulse AR 1 0 0.1
+>   in gate (fSinOsc AR 500 0 * 0.25) t
diff --git a/Help/UGen/gaussTrig.help.lhs b/Help/UGen/gaussTrig.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/gaussTrig.help.lhs
@@ -0,0 +1,12 @@
+    Sound.SC3.UGen.Help.viewSC3Help "GaussTrig"
+    Sound.SC3.UGen.DB.ugenSummary "GaussTrig"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>   let x = mouseX KR 0 0.9 Linear 0.2
+>       t1 = gaussTrig KR 10 x * abs (whiteNoise 'α' KR) * 0.5
+>       t2 = dust 'β' KR 10 * 0.5
+>       n = pinkNoise 'γ' AR * decay (mce2 t1 t2) 0.02 * 0.5
+>   in fold2 (ringz n 2000 0.02) 0.5
diff --git a/Help/UGen/gendy1.help.lhs b/Help/UGen/gendy1.help.lhs
--- a/Help/UGen/gendy1.help.lhs
+++ b/Help/UGen/gendy1.help.lhs
@@ -103,7 +103,7 @@
 >                      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 ['β'..'γ']))
+>     in mix (mce (map node (take 10 (enumFrom 'β'))))
 
 Try durscale 10.0 and 0.0 too.
 
diff --git a/Help/UGen/grainBuf.help.lhs b/Help/UGen/grainBuf.help.lhs
--- a/Help/UGen/grainBuf.help.lhs
+++ b/Help/UGen/grainBuf.help.lhs
@@ -5,7 +5,9 @@
 
 > fn_01 = "/home/rohan/data/audio/pf-c5.snd"
 
-    > withSC3 (async (b_allocRead 10 fn_01 0 0))
+> m_01 = b_allocRead 10 fn_01 0 0
+
+    > withSC3 (async m_01)
 
 > g_01 =
 >     let buf = 10
diff --git a/Help/UGen/grainIn.help.lhs b/Help/UGen/grainIn.help.lhs
--- a/Help/UGen/grainIn.help.lhs
+++ b/Help/UGen/grainIn.help.lhs
@@ -1,11 +1,14 @@
     Sound.SC3.UGen.Help.viewSC3Help "GrainIn"
     Sound.SC3.UGen.DB.ugenSummary "GrainIn"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> g_01 =
->     let n = pinkNoise 'α' AR
->         x = mouseX KR (-0.5) 0.5 Linear 0.1
+> f_01 s =
+>     let 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
+>     in grainIn 2 t 0.1 s x (-1) 512 * 0.1
+
+> g_01 = f_01 (pinkNoise 'α' AR)
+
+> g_02 = let s = soundIn 0 in s * 0.05 + f_01 s
diff --git a/Help/UGen/grayNoise.help.lhs b/Help/UGen/grayNoise.help.lhs
--- a/Help/UGen/grayNoise.help.lhs
+++ b/Help/UGen/grayNoise.help.lhs
@@ -2,7 +2,7 @@
     > Sound.SC3.UGen.DB.ugenSummary "GrayNoise"
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 = grayNoise 'α' AR * 0.1
 
 Drawing
diff --git a/Help/UGen/greyholeRaw.help.lhs b/Help/UGen/greyholeRaw.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/greyholeRaw.help.lhs
@@ -0,0 +1,11 @@
+    Sound.SC3.UGen.Help.viewSC3Help "GreyholeRaw"
+    Sound.SC3.UGen.DB.ugenSummary "GreyholeRaw"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as External {- hsc3 -}
+
+default values
+
+> g_01 =
+>   let (i1,i2) = (soundIn 0,soundIn 1)
+>   in External.greyholeRaw i1 i2 0.0 2.0 0.5 0.9 0.1 2.0 1.0
diff --git a/Help/UGen/hasher.help.lhs b/Help/UGen/hasher.help.lhs
--- a/Help/UGen/hasher.help.lhs
+++ b/Help/UGen/hasher.help.lhs
@@ -1,14 +1,24 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Hasher"
-> Sound.SC3.UGen.DB.ugenSummary "Hasher"
+    Sound.SC3.UGen.Help.viewSC3Help "Hasher"
+    Sound.SC3.UGen.DB.ugenSummary "Hasher"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
 noise
 
-> audition (out 0 (hasher (line AR 0 1 1 RemoveSynth) * 0.2))
+> g_01 = 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))
+> f_02 x_f =
+>   let x = mouseX KR 0 10 Linear 0.2
+>       f = hasher (x_f x) * 300 + 500
+>   in sinOsc AR f 0 * 0.1
+
+> g_02 = f_02 (\x -> roundTo x 1)
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen_nrt (400,1) 1.0 (hasher (line AR 0 1 1 RemoveSynth))
+
+> g_03 = f_02 id
+
+> g_04 = sinOsc AR (whiteNoise 'α' KR * 300 + 500) 0 * 0.1
diff --git a/Help/UGen/hilbertFIR.help.lhs b/Help/UGen/hilbertFIR.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/hilbertFIR.help.lhs
@@ -0,0 +1,8 @@
+    Sound.SC3.UGen.Help.viewSC3Help "HilbertFIR"
+    Sound.SC3.UGen.DB.ugenSummary "HilbertFIR"
+
+> import Sound.SC3 {- hsc3 -}
+
+composite UGen
+
+> g_01 = hilbertFIR (sinOsc AR 100 0 * dbAmp (-20)) (localBuf 'α' 2048 1)
diff --git a/Help/UGen/hpz1.help.lhs b/Help/UGen/hpz1.help.lhs
--- a/Help/UGen/hpz1.help.lhs
+++ b/Help/UGen/hpz1.help.lhs
@@ -8,3 +8,12 @@
     import Sound.SC3.Plot.FFT {- hsc3-plot -}
     plot_ugen_fft1 0.05 (hpz1 (whiteNoise 'α' AR))
 
+detect changes in a signal (see also hpz2)
+
+> g_02 =
+>   let n = lfNoise0 'a' AR 1000
+>       h = hpz1 n
+>   in mce [h,h >* 0,abs h >* 0]
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen 0.01 g_02
diff --git a/Help/UGen/hpz2.help.lhs b/Help/UGen/hpz2.help.lhs
--- a/Help/UGen/hpz2.help.lhs
+++ b/Help/UGen/hpz2.help.lhs
@@ -1,7 +1,8 @@
-> Sound.SC3.UGen.Help.viewSC3Help "HPZ2"
-> Sound.SC3.UGen.DB.ugenSummary "HPZ2"
+    Sound.SC3.UGen.Help.viewSC3Help "HPZ2"
+    Sound.SC3.UGen.DB.ugenSummary "HPZ2"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> let n = whiteNoise 'α' AR
-> in audition (out 0 (hpz2 (n * 0.25)))
+> g_01 =
+>   let n = whiteNoise 'α' AR
+>   in hpz2 (n * 0.25)
diff --git a/Help/UGen/iEnvGen.help.lhs b/Help/UGen/iEnvGen.help.lhs
--- a/Help/UGen/iEnvGen.help.lhs
+++ b/Help/UGen/iEnvGen.help.lhs
@@ -3,23 +3,45 @@
 
 > import Sound.SC3 {- hsc3 -}
 
+> e_01 :: (Fractional n,Ord n) => Envelope n
+> e_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]
+>   in Envelope l t c Nothing Nothing 0
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plotEnvelope [e_01]
+
 > 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
+>     let x = mouseX KR 0 (envelope_duration e_01) Linear 0.2
+>         g = iEnvGen KR x e_01
 >     in sinOsc AR (g * 500 + 440) 0 * 0.1
 
-index with an SinOsc ... mouse controls amplitude of SinOsc
+index with SinOsc. mouse controls amplitude of SinOsc.
 use offset so negative values of SinOsc will map into the Env
 
+> e_02 :: (Fractional n,Ord n) => Envelope n
+> e_02 =
+>   let l = [-1,-0.7,0.7,1]
+>       t = [0.8666,0.2666,0.8668]
+>       c = [EnvLin,EnvLin]
+>   in Envelope l t c Nothing Nothing 0
+
+    plotEnvelope [e_02]
+
 > 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
+>     let x = mouseX KR 0 1 Linear 0.2
 >         o = (sinOsc AR 440 0 + 1) * x
->     in iEnvGen AR o e * 0.1
+>     in iEnvGen AR o e_02 * 0.1
+
+index with Amplitude of input, control freq of SinOsc (uses SoundIn)
+
+> e_03 :: (Fractional n,Ord n) => Envelope n
+> e_03 = envXYC [(0, 330, EnvExp), (0.5, 440, EnvExp), (1.0, 1760, EnvLin)]
+
+    plotEnvelope [e_03]
+
+> g_03 =
+>     let pt = amplitude AR (soundIn 0) 0.01 0.2
+>     in sinOsc AR (iEnvGen KR pt e_03) 0 * 0.2
diff --git a/Help/UGen/iRand.help.lhs b/Help/UGen/iRand.help.lhs
--- a/Help/UGen/iRand.help.lhs
+++ b/Help/UGen/iRand.help.lhs
@@ -2,7 +2,7 @@
     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
diff --git a/Help/UGen/ifft.help.lhs b/Help/UGen/ifft.help.lhs
--- a/Help/UGen/ifft.help.lhs
+++ b/Help/UGen/ifft.help.lhs
@@ -1,5 +1,5 @@
-> Sound.SC3.UGen.Help.viewSC3Help "IFFT"
-> Sound.SC3.UGen.DB.ugenSummary "IFFT"
-> :t ifft'
+    > 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/iirFilter.help.lhs b/Help/UGen/iirFilter.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/iirFilter.help.lhs
@@ -0,0 +1,13 @@
+    Sound.SC3.UGen.Help.viewSC3Help "IIRFilter"
+    Sound.SC3.UGen.DB.ugenSummary "IIRFilter"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>   let x = mouseX KR 20 12000 Exponential 0.2
+>       y = mouseY KR 0.01 1 Linear 0.2
+>       o = lfSaw AR (mce [x * 0.99,x * 1.01]) 0 * 0.1
+>       freq = sinOsc KR (sinOsc KR 0.1 0) (1.5 * pi) * 1550 + 1800
+>       s = iirFilter o freq y
+>   in combN s 0.5 (mce2 0.4 0.35) 2 * 0.4 + s * 0.5
diff --git a/Help/UGen/in.help.lhs b/Help/UGen/in.help.lhs
--- a/Help/UGen/in.help.lhs
+++ b/Help/UGen/in.help.lhs
@@ -3,6 +3,7 @@
 
 Note: `hsc3` renames UGen to `in'` since `in` is a reserved keyword
 
+> import Sound.OSC {- hosc -}
 > import Sound.SC3 {- hsc3 -}
 
 Patching input to output (see also soundIn).
@@ -37,7 +38,7 @@
 
 Set value on a control bus
 
-    > withSC3 (send (c_set1 0 300))
+    > withSC3 (sendMessage (c_set1 0 300))
 
 Read a control bus
 
@@ -45,7 +46,7 @@
 
 Re-set value on bus
 
-    > withSC3 (send (c_set1 0 600))
+    > withSC3 (sendMessage (c_set1 0 600))
 
 Control rate graph writing buses 0 & 1.
 
diff --git a/Help/UGen/inFeedback.help.lhs b/Help/UGen/inFeedback.help.lhs
--- a/Help/UGen/inFeedback.help.lhs
+++ b/Help/UGen/inFeedback.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "InFeedback"
-    > Sound.SC3.UGen.DB.ugenSummary "InFeedback"
+    Sound.SC3.UGen.Help.viewSC3Help "InFeedback"
+    Sound.SC3.UGen.DB.ugenSummary "InFeedback"
 
 > import Sound.SC3 {- hsc3 -}
 
@@ -12,7 +12,7 @@
 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)
diff --git a/Help/UGen/inTrig.help.lhs b/Help/UGen/inTrig.help.lhs
--- a/Help/UGen/inTrig.help.lhs
+++ b/Help/UGen/inTrig.help.lhs
@@ -12,4 +12,4 @@
 
 Set bus 10, each set will trigger a ping.
 
-    > withSC3 (send (c_set1 10 0.1))
+    > withSC3 (sendMessage (c_set1 10 0.1))
diff --git a/Help/UGen/index.help.lhs b/Help/UGen/index.help.lhs
--- a/Help/UGen/index.help.lhs
+++ b/Help/UGen/index.help.lhs
@@ -3,16 +3,14 @@
 
 > 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
+>   let b = asLocalBuf 'α' [50,100,200,400,800,1600]
+>       f = index b (lfSaw KR 2 3 * 4)
+>   in sinOsc AR (mce [f,f * 9]) 0 * 0.1
 
-    > withSC3 (send (b_free 10))
+> g_02 =
+>   let b = asLocalBuf 'α' [200, 300, 400, 500, 600, 800]
+>       f = index b (mouseX KR 0 7 Linear 0.2)
+>   in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/indexInBetween.help.lhs b/Help/UGen/indexInBetween.help.lhs
--- a/Help/UGen/indexInBetween.help.lhs
+++ b/Help/UGen/indexInBetween.help.lhs
@@ -3,23 +3,16 @@
 
 > 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)
+>         b = asLocalBuf 'α' [200,210,400,430,600,800]
+>         i = indexInBetween b f0
+>         l0 = index b i
+>         l1 = index b (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]
diff --git a/Help/UGen/indexL.help.lhs b/Help/UGen/indexL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/indexL.help.lhs
@@ -0,0 +1,17 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "IndexL"
+    > Sound.SC3.UGen.DB.ugenSummary "IndexL"
+
+> import Sound.SC3 {- hsc3 -}
+
+Index buffer for frequency values
+
+> g_01 =
+>   let b = asLocalBuf 'α' [50,100,200,400,800,1600]
+>       ph = 1 -- 0
+>       i = range 0 7 (lfSaw KR 0.1 ph)
+>   in sinOsc AR (mce2 (indexL b i) (index b i)) 0 * 0.1
+
+> g_02 =
+>   let b = asLocalBuf 'α' [200,300,400,500,600,800]
+>       x = mouseX KR 0 7 Linear 0.2
+>   in sinOsc AR (mce2 (indexL b x) (index b x)) 0 * 0.1
diff --git a/Help/UGen/jPverbRaw.help.lhs b/Help/UGen/jPverbRaw.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/jPverbRaw.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "JPverbRaw"
+    Sound.SC3.UGen.DB.ugenSummary "JPverbRaw"
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as External {- hsc3 -}
+
+> g_01 =
+>   let (i1,i2) = (soundIn 0,soundIn 1)
+>   in External.jPverbRaw i1 i2 0 0.707 2000 1 500 1 0.1 2 1 1 1
+
diff --git a/Help/UGen/k2A.help.lhs b/Help/UGen/k2A.help.lhs
deleted file mode 100644
--- a/Help/UGen/k2A.help.lhs
+++ /dev/null
@@ -1,17 +0,0 @@
-    > 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/k2a.help.lhs b/Help/UGen/k2a.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/k2a.help.lhs
@@ -0,0 +1,16 @@
+    > 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 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
--- a/Help/UGen/keyState.help.lhs
+++ b/Help/UGen/keyState.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "KeyState"
-    > Sound.SC3.UGen.DB.ugenSummary "KeyState"
+    Sound.SC3.UGen.Help.viewSC3Help "KeyState"
+    Sound.SC3.UGen.DB.ugenSummary "KeyState"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/klank.help.lhs b/Help/UGen/klank.help.lhs
--- a/Help/UGen/klank.help.lhs
+++ b/Help/UGen/klank.help.lhs
@@ -3,32 +3,33 @@
 
 > 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
+The klankSpec family of functions can help create the 'spec' entry.
 
-A variant spec function takes non-UGen inputs
+> f_01 impulse_freq reson_freq decay_time =
+>   let u n = replicate (length reson_freq) n
+>       k = klankSpec_k reson_freq (u 1) (u decay_time)
+>   in klank (impulse AR impulse_freq 0 * 0.1) 1 0 1 k
 
-> 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
+> g_01 = f_01 2 [800,1071,1153,1723] 1
 
 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 =
+> g_02 =
 >     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]
+>         k = mce [klankSpec_k p u u,klankSpec_k q u u,klankSpec_k 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)
+
+Modal data
+
+    > import Sound.SC3.Data.Modal {- hsc3-data -}
+    > let Just reson_freq =lookup "Spinel sphere (diameter=3.6675mm)" modal_frequencies
+    > audition (out 0 (f_01 0.125 reson_freq 16))
diff --git a/Help/UGen/ladspa.help.lhs b/Help/UGen/ladspa.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ladspa.help.lhs
@@ -0,0 +1,246 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LADSPA"
+    Sound.SC3.UGen.DB.ugenSummary "LADSPA"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+Note: debian sc3-plugins doesn't build ladspalist, to build type:
+
+    cd opt/src/sc3-plugins/source/LadspaUGen
+    gcc -ldl search.c ladspalist.c -o ladspalist
+
+CAPS = http://quitte.de/dsp/caps.html, http://packages.debian.org/stretch/caps
+
+    # 1767 C* ChorusI - Mono chorus/flanger
+    > k: t (ms) (2.5 to 40)
+    > k: width (ms) (0.5 to 10)
+    > k: rate (Hz) (0.02 to 5)
+    > k: blend (0 to 1)
+    > k: feedforward (0 to 1)
+    > k: feedback (0 to 1)
+    > a: in (0 to 0)
+    < a: out
+
+> caps_1767_01 =
+>   let s = soundIn 0
+>       x = mouseX KR 0 1 Linear 0.2
+>       y = mouseY KR 0 1 Linear 0.2
+>       n1 = range 2.5 40 (lfNoise2 'α' KR 0.2)
+>       n2 = range 0.5 10 (lfNoise2 'β' KR 0.2)
+>   in ladspa 1 AR 1767 [n1,n2,0.5,0.5,x,y,s]
+
+    # 1769 C* Click - Metronome
+    > k: model (0 to 3)
+    > k: bpm (4 to 240)
+    > k: volume (0 to 1)
+    > k: damping (0 to 1)
+    < a: out
+
+> caps_1769_01 =
+>   let x = roundE (mouseX KR 0 3 Linear 0.2)
+>       y = mouseY KR 4 240 Linear 0.2
+>   in ladspa 1 AR 1769 [x,y,0.5,0.5]
+
+    # 1773 C* Eq10 - 10-band equaliser
+    > k: 31 Hz (-48 to 24)
+    > k: 63 Hz (-48 to 24)
+    > k: 125 Hz (-48 to 24)
+    > k: 250 Hz (-48 to 24)
+    > k: 500 Hz (-48 to 24)
+    > k: 1 kHz (-48 to 24)
+    > k: 2 kHz (-48 to 24)
+    > k: 4 kHz (-48 to 24)
+    > k: 8 kHz (-48 to 24)
+    > k: 16 kHz (-48 to 24)
+    > a: in (0 to 0)
+    < a: out
+
+> enumN n e = take n (enumFrom e)
+
+> caps_1773_01 =
+>   let s = soundIn 0
+>       n = map (\z -> range (-24) 48 (lfNoise2 z KR 0.2)) (enumN 10 'α')
+>   in ladspa 1 AR 1773 (n ++ [s]) * 0.5
+
+    # 1771 C* Saturate - Various static nonlinearities, 8x oversampled
+    > k: mode (0 to 11)
+    > k: gain (dB) (-24 to 72)
+    > k: bias (0 to 1)
+    > a: in (0 to 0)
+    < a: out
+
+> caps_1771_01 =
+>   let s = soundIn 0
+>   in ladspa 1 AR 1771 [1,0,0,s]
+
+> caps_1771_02 =
+>   let s = soundIn 0
+>       x = roundE (mouseX KR 0 11 Linear 0.2)
+>       y = mouseY KR (-24) 72 Linear 0.2
+>   in ladspa 1 AR 1771 [x,y,0.0,s]
+
+    # 1772 C* Compress - Compressor and saturating limiter
+    > k: measure (0 to 1)
+    > k: mode (0 to 2)
+    > k: threshold (0 to 1)
+    > k: strength (0 to 1)
+    > k: attack (0 to 1)
+    > k: release (0 to 1)
+    > k: gain (dB) (-12 to 18)
+    < k: state (dB)
+    > a: in (-1 to 1)
+    < a: out
+
+> caps_1772_01 =
+>   let s = soundIn 0
+>       x = roundE (mouseX KR 0 2 Linear 0.2)
+>       y = mouseY KR 0 1 Linear 0.2
+>   in ladspa 1 AR 1772 [0.5,x,y,0.5,0.5,0.1,0,s]
+
+    # 1779 C* Plate - Versatile plate reverb
+    > k: bandwidth (0 to 1)
+    > k: tail (0 to 1)
+    > k: damping (0 to 1)
+    > k: blend (0 to 1)
+    > a: in (0 to 0)
+    < a: out.l
+    < a: out.r
+
+> caps_1779_01 =
+>   let s = soundIn 0
+>       x = mouseX KR 0 1 Linear 0.2
+>       y = mouseY KR 0 1 Linear 0.2
+>   in ladspa 2 AR 1779 [x,y,0.5,0.5,s]
+
+    # 1788 C* Wider - Stereo image synthesis
+    > k: pan (-1 to 1)
+    > k: width (0 to 1)
+    > a: in (0 to 0)
+    < a: out.l
+    < a: out.r
+
+> caps_1788_01 =
+>   let s = soundIn 0
+>       x = mouseX KR (-1) 1 Linear 0.2
+>       y = mouseY KR 0 1 Linear 0.2
+>   in ladspa 2 AR 1788 [x,y,s]
+
+    # 2586 C* PhaserII - Mono phaser
+    > k: rate (0 to 1)
+    > k: lfo (0 to 1)
+    > k: depth (0 to 1)
+    > k: spread (0 to 1)
+    > k: resonance (0 to 1)
+    > a: in (0 to 0)
+    < a: out
+
+> caps_2586_01 =
+>   let s = soundIn 0
+>       x = mouseX KR 0 1 Linear 0.2
+>       y = mouseY KR 0 1 Linear 0.2
+>   in ladspa 1 AR 2586 [0.3,x,0.5,y,0.8,s]
+
+    # 2588 C* Scape - Stereo delay with chromatic resonances
+    > k: bpm (30 to 164)
+    > k: divider (2 to 4)
+    > k: feedback (0 to 1)
+    > k: dry (0 to 1)
+    > k: blend (0 to 1)
+    > k: tune (Hz) (415 to 467)
+    > a: in (0 to 0)
+    < a: out.l
+    < a: out.r
+
+> caps_2588_01 =
+>   let s = soundIn 0
+>       x = mouseX KR 30 164 Linear 0.2
+>       y = roundE (mouseY KR 2 4 Linear 0.2)
+>       n1 = lfNoise2 'α' KR 0.2
+>       n2 = lfNoise2 'β' KR 0.2
+>   in ladspa 2 AR 2588 [x,y,n1,n2,0.5,440,s]
+
+    # 2592 C* AmpVTS - Idealised guitar amplification
+    > k: over (0 to 2)
+    > k: gain (0 to 1)
+    > k: bright (0 to 1)
+    > k: power (0 to 1)
+    > k: tonestack (0 to 8)
+    > k: bass (0 to 1)
+    > k: mid (0 to 1)
+    > k: treble (0 to 1)
+    > k: attack (0 to 1)
+    > k: squash (0 to 1)
+    > k: lowcut (0 to 1)
+    > a: in (0 to 0)
+    < a: out
+
+> caps_2592_def s = [1,0.25,0.75,0.5,1,0.25,1,0.75,0.75,0.25,0.5,s]
+
+> caps_2592_01 = ladspa 1 AR 2592 (caps_2592_def (soundIn 0))
+
+> caps_2592_02 =
+>   let s = soundIn 0
+>       x = roundE (mouseX KR 0 8 Linear 0.2)
+>       y = mouseY KR 0 1 Linear 0.2
+>       [n1,n2,n3,n4,n5,n6,n7,n8] = map (\z -> lfNoise2 z KR 0.2) (enumN 8 'α')
+>   in ladspa 1 AR 2592 [1,y,n1,n2,x,n3,n4,n5,n6,n7,n8,s]
+
+    # 2603 C* Spice - Not an exciter
+    > k: lo.f (Hz) (50 to 400)
+    > k: lo.compress (0 to 1)
+    > k: lo.gain (0 to 1)
+    > k: hi.f (Hz) (400 to 5000)
+    > k: hi.gain (0 to 1)
+    > a: in (0 to 0)
+    < a: out
+
+> caps_2603_01 =
+>   let s = soundIn 0
+>       x = mouseX KR 50 400 Exponential 0.2
+>       y = mouseY KR 400 5000 Exponential 0.2
+>   in ladspa 1 AR 2603 [x,0.5,0.5,y,0.5,s]
+
+    # 2609 C* EqFA4p - 4-band parametric eq
+    > k: a.act (0 to 1)
+    > k: a.f (Hz) (20 to 14000)
+    > k: a.bw (0.125 to 8)
+    > k: a.gain (dB) (-24 to 24)
+    > k: b.act (0 to 1)
+    > k: b.f (Hz) (20 to 14000)
+    > k: b.bw (0.125 to 8)
+    > k: b.gain (dB) (-24 to 24)
+    > k: c.act (0 to 1)
+    > k: c.f (Hz) (20 to 14000)
+    > k: c.bw (0.125 to 8)
+    > k: c.gain (dB) (-24 to 24)
+    > k: d.act (0 to 1)
+    > k: d.f (Hz) (20 to 14000)
+    > k: d.bw (0.125 to 8)
+    > k: d.gain (dB) (-24 to 24)
+    > k: gain (-24 to 24)
+    < k: _latency
+    > a: in (0 to 0)
+    < a: out
+
+> caps_2609_01 =
+>   let s = soundIn 0
+>       f z m l r = m (lfNoise2 z KR 0.2) (-1) 1 l r
+>       p = [f 'α' linLin 0 1
+>           ,f 'β' linExp 20 14000
+>           ,f 'γ' linExp 0.125 8
+>           ,f 'δ' linLin (-24) 24
+>           ,f 'ε' linLin 0 1
+>           ,f 'ζ' linExp 20 14000
+>           ,f 'η' linExp 0.125 8
+>           ,f 'θ' linLin (-24) 24
+>           ,f 'ι' linLin 0 1
+>           ,f 'κ' linExp 20 14000
+>           ,f 'λ' linExp 0.125 8
+>           ,f 'μ' linLin (-24) 24
+>           ,f 'ν' linLin 0 1
+>           ,f 'ξ' linExp 20 14000
+>           ,f 'ο' linExp 0.125 8
+>           ,f 'π' linLin (-24) 24
+>           ,0
+>           ,s]
+>   in ladspa 1 AR 2609 p * 0.5
diff --git a/Help/UGen/lag.help.lhs b/Help/UGen/lag.help.lhs
--- a/Help/UGen/lag.help.lhs
+++ b/Help/UGen/lag.help.lhs
@@ -1,16 +1,24 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "Lag"
-    > Sound.SC3.UGen.DB.ugenSummary "Lag"
+    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
+>     let n = lfNoise0 'α' KR 0.5
 >     in sinOsc AR (220 + (lag n 1 * 220)) 0 * (lag n 2 * 0.1)
+
+> g_03 = lag (impulse AR 100 0) (mouseX KR 0.0 0.01 Linear 0.2)
+
+> g_04 = lag (lfPulse AR 50 0 0.5) (mouseX KR 0.0 (1/50) Linear 0.2) * 0.2
+
+> g_05 =
+>   let s = sinOsc AR 0.05 0.0
+>       f1 = linLin s (-1.0) 1.0 220.0 440.0
+>       o1 = sinOsc AR f1 0.0
+>       f2 = lag f1 1.0
+>       o2 = sinOsc AR f2 0.0
+>   in mce2 (o1 * 0.2) (o2 * 0.2)
diff --git a/Help/UGen/lag2.help.lhs b/Help/UGen/lag2.help.lhs
--- a/Help/UGen/lag2.help.lhs
+++ b/Help/UGen/lag2.help.lhs
@@ -6,3 +6,5 @@
 > g_01 =
 >     let x = mouseX KR 220 440 Exponential 0.1
 >     in sinOsc AR (mce [x, lag2 x 1]) 0 * 0.1
+
+> g_02 = lag2 (impulse AR 100 0) (mouseX KR 0.0 0.01 Linear 0.2)
diff --git a/Help/UGen/lag3.help.lhs b/Help/UGen/lag3.help.lhs
--- a/Help/UGen/lag3.help.lhs
+++ b/Help/UGen/lag3.help.lhs
@@ -1,4 +1,4 @@
-     Sound.SC3.UGen.Help.viewSC3Help "Lag3"
+    Sound.SC3.UGen.Help.viewSC3Help "Lag3"
     Sound.SC3.UGen.DB.ugenSummary "Lag3"
 
 > import Sound.SC3 {- hsc3 -}
@@ -6,3 +6,11 @@
 > g_01 =
 >     let x = mouseX KR 220 440 Exponential 0.1
 >     in sinOsc AR (mce [x, lag3 x 1]) 0 * 0.1
+
+> g_02 = lag3 (impulse AR 100 0) (mouseX KR 0.0 0.01 Linear 0.2)
+
+> g_03 = lag3 (lfPulse AR 100 0 0.5) (mouseX KR 0.0 0.01 Linear 0.2)
+
+> g_04 =
+>   let x = mouseX KR 0.0 0.01 Linear 0.2
+>   in lag (lag (lag (lfPulse AR 100 0 0.5 * 2 - 1) x) x) x
diff --git a/Help/UGen/lagIn.help.lhs b/Help/UGen/lagIn.help.lhs
--- a/Help/UGen/lagIn.help.lhs
+++ b/Help/UGen/lagIn.help.lhs
@@ -1,11 +1,12 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "LagIn"
-    > Sound.SC3.UGen.DB.ugenSummary "LagIn"
+    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))
+    import Sound.OSC {- hosc -}
+    withSC3 (sendMessage (c_set1 10 200))
 
 Oscillator reading frequency at control bus
 
@@ -13,4 +14,4 @@
 
 Re-set frequency at control bus
 
-    > withSC3 (send (c_set1 10 2000))
+    withSC3 (sendMessage (c_set1 10 2000))
diff --git a/Help/UGen/lagUD.help.lhs b/Help/UGen/lagUD.help.lhs
--- a/Help/UGen/lagUD.help.lhs
+++ b/Help/UGen/lagUD.help.lhs
@@ -6,5 +6,29 @@
 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
+>   let x = mouseX KR 220 440 Linear 0.2
+>   in sinOsc AR (mce2 x (lagUD x 1 5)) 0 * 0.1
+
+as signal filter
+
+> f_01 l s =
+>   let x = mouseX KR 0.0001 0.01 Exponential 0.2
+>       y = mouseY KR 0.0001 0.01 Exponential 0.2
+>   in l s x y
+
+> f_02 = f_01 lagUD
+> f_03 = f_01 lag2UD
+> f_04 = f_01 lag3UD
+
+> g_02 = f_02 (0 - saw AR 440) * 0.15
+> g_03 = f_02 (impulse AR (range 6 24 (lfNoise2 'α' KR 4)) 0) * 0.5
+> g_04 = f_04 (lfPulse AR 800 0 0.5 * 2 - 1) * 0.25
+
+> g_05 =
+>   let s = varSaw AR 220 0 (range 0 1 (sinOsc KR 0.25 0))
+>   in f_02 s * 0.1
+
+> g_06 =
+>   let x = mouseX KR 0.0 (1/100) Linear 0.2
+>       y = mouseY KR 0.0 (3/100) Linear 0.2
+>   in lagUD (lfPulse AR 50 0 0.25) x y * 0.2
diff --git a/Help/UGen/latoocarfianC.help.lhs b/Help/UGen/latoocarfianC.help.lhs
--- a/Help/UGen/latoocarfianC.help.lhs
+++ b/Help/UGen/latoocarfianC.help.lhs
@@ -1,20 +1,21 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LatoocarfianC"
-> Sound.SC3.UGen.DB.ugenSummary "LatoocarfianC"
+    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))
+> g_01 =
+>   let x = mouseX KR 20 sampleRate Linear 0.1
+>   in 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)
+> g_02 =
+>   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
+>   in latoocarfianC AR f a b c d 0.5 0.5 * 0.2
diff --git a/Help/UGen/lfBrownNoise0.help.lhs b/Help/UGen/lfBrownNoise0.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lfBrownNoise0.help.lhs
@@ -0,0 +1,9 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LFBrownNoise2"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>   let n = lfBrownNoise0 'α' AR 10 0.05 0
+>       f = linExp n (-1) 1 64 9600
+>   in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/lfBrownNoise2.help.lhs b/Help/UGen/lfBrownNoise2.help.lhs
--- a/Help/UGen/lfBrownNoise2.help.lhs
+++ b/Help/UGen/lfBrownNoise2.help.lhs
@@ -1,17 +1,33 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "LFBrownNoise2"
-    > Sound.SC3.UGen.DB.ugenSummary "LFBrownNoise2"
+    Sound.SC3.UGen.Help.viewSC3Help "LFBrownNoise2"
 
 > import Sound.SC3 {- hsc3 -}
-> import qualified Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins as E {- hsc3 -}
-
-Modulate frequency.
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 > g_01 =
->     let x = mouseX KR 0 5 Linear 0.2
->     in E.lfBrownNoise2 'α' AR 1000 1 x * 0.25
+>   let freq = 1000
+>       dev = mouseX KR 0 1 Linear 0.2
+>       dist = mouseY KR 0 5 Linear 0.2
+>   in lfBrownNoise2 'α' AR freq dev dist * 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
+>   let freq = 8
+>       dev = mouseX KR 0 1 Linear 0.2
+>       dist = mouseY KR 0 5 Linear 0.2
+>       n1:n2:n3:_ = map (\z -> lfBrownNoise2 z KR freq dev dist) ['α'..]
+>       o = impulse AR (range 6 24 n1) 0
+>   in lagUD o (range 0.0001 0.001 n2) (range 0.0001 0.001 n3) * 0.5
+
+Use as pan & volume controls (external sound input)
+
+> f_01 s =
+>   let freq = range 0.5 2 (lfBrownNoise2 'α' KR 2 0.1 5)
+>       dev = mouseX KR 0.01 0.35 Linear 0.2
+>       dist = mouseY KR 0 5 Linear 0.2
+>       n1:n2:_ = map (\z -> lfBrownNoise2 z KR freq dev dist) ['β'..]
+>   in pan2 s (range (-0.75) 0.75 n1) 1 * range 0.01 0.5 n2
+
+> g_03 = f_01 (soundIn 0)
+
+> g_04 = f_01 (sinOsc AR 440 0 * 0.1)
diff --git a/Help/UGen/lfClipNoise.help.lhs b/Help/UGen/lfClipNoise.help.lhs
--- a/Help/UGen/lfClipNoise.help.lhs
+++ b/Help/UGen/lfClipNoise.help.lhs
@@ -2,7 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "LFClipNoise"
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 = lfClipNoise 'α' AR 1000 * 0.05
 
 Modulate frequency
diff --git a/Help/UGen/lfNoise0.help.lhs b/Help/UGen/lfNoise0.help.lhs
--- a/Help/UGen/lfNoise0.help.lhs
+++ b/Help/UGen/lfNoise0.help.lhs
@@ -2,7 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "LFNoise0"
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 = lfNoise0 'α' AR 1000 * 0.05
 
 Modulate frequency.
diff --git a/Help/UGen/lfNoise1.help.lhs b/Help/UGen/lfNoise1.help.lhs
--- a/Help/UGen/lfNoise1.help.lhs
+++ b/Help/UGen/lfNoise1.help.lhs
@@ -1,18 +1,19 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFNoise1"
-> Sound.SC3.UGen.DB.ugenSummary "LFNoise1"
+    Sound.SC3.UGen.Help.viewSC3Help "LFNoise1"
+    Sound.SC3.UGen.DB.ugenSummary "LFNoise1"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> audition (out 0 (lfNoise1 'α' AR 1000 * 0.05))
+> g_01 = 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))
+> g_02 =
+>   let f = xLine KR 1000 10000 10 RemoveSynth
+>   in lfNoise1 'α' AR f * 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))
+> g_03 =
+>   let n = lfNoise1 'α' KR 4
+>       f = n * 400 + 450
+>   in sinOsc AR f 0 * 0.1
diff --git a/Help/UGen/lfNoise2.help.lhs b/Help/UGen/lfNoise2.help.lhs
--- a/Help/UGen/lfNoise2.help.lhs
+++ b/Help/UGen/lfNoise2.help.lhs
@@ -2,7 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "LFNoise2"
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 = lfNoise2 'α' AR 1000 * 0.05
 
 Modulate frequency.
diff --git a/Help/UGen/lfPar.help.lhs b/Help/UGen/lfPar.help.lhs
--- a/Help/UGen/lfPar.help.lhs
+++ b/Help/UGen/lfPar.help.lhs
@@ -1,4 +1,4 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFPar"
-> Sound.SC3.UGen.DB.ugenSummary "LFPar"
+    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
--- a/Help/UGen/lfPulse.help.lhs
+++ b/Help/UGen/lfPulse.help.lhs
@@ -4,9 +4,9 @@
 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.
diff --git a/Help/UGen/lfSaw.help.lhs b/Help/UGen/lfSaw.help.lhs
--- a/Help/UGen/lfSaw.help.lhs
+++ b/Help/UGen/lfSaw.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "LFSaw"
-    > Sound.SC3.UGen.DB.ugenSummary "LFSaw"
+    Sound.SC3.UGen.Help.viewSC3Help "LFSaw"
+    Sound.SC3.UGen.DB.ugenSummary "LFSaw"
 
 Note: SC2 did not have the initial phase argument.
 
@@ -33,6 +33,21 @@
 >         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
+
+as phasor input to sin function
+
+> g_05 = sin (range 0 two_pi (lfSaw AR 440 0)) * 0.2
+
+mixed with sin, then with distortions
+
+> g_06 =
+>   let f = xLine KR 220 440 10 DoNothing
+>       o1 = sinOsc AR (f + mce2 0 0.7) 0
+>       o2 = lfSaw AR (f + mce2 0 0.7) 0 * 0.3
+>       o3 = cubed (distort (log (distort (o1 + o2))))
+>   in o3 * 0.1
+
+
 
 Drawings
 
diff --git a/Help/UGen/lfTri.help.lhs b/Help/UGen/lfTri.help.lhs
--- a/Help/UGen/lfTri.help.lhs
+++ b/Help/UGen/lfTri.help.lhs
@@ -4,7 +4,7 @@
 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.
diff --git a/Help/UGen/lfdClipNoise.help.lhs b/Help/UGen/lfdClipNoise.help.lhs
--- a/Help/UGen/lfdClipNoise.help.lhs
+++ b/Help/UGen/lfdClipNoise.help.lhs
@@ -1,22 +1,26 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LFDClipNoise"
-> Sound.SC3.UGen.DB.ugenSummary "LFDClipNoise"
+    Sound.SC3.UGen.Help.viewSC3Help "LFDClipNoise"
+    Sound.SC3.UGen.DB.ugenSummary "LFDClipNoise"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
 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))
+> g_01 =
+>   let x = mouseX KR 0.1 1000 Exponential 0.2
+>       n = lfdClipNoise 'α' AR x
+>   in 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))
+> g_02 =
+>   let x = mouseX KR 0.1 1000 Exponential 0.2
+>       n = lfClipNoise 'β' AR x
+>   in 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
+> g_03 =
+>   let f = xLine KR 1000 20000 10 RemoveSynth
+>   in lfdClipNoise 'γ' AR f * 0.05
 
-> let f = xLine KR 1000 20000 10 RemoveSynth
-> in audition . (out 0) . (* 0.05) =<< lfClipNoiseM AR f
+> g_04 =
+>   let f = xLine KR 1000 20000 10 RemoveSynth
+>   in lfClipNoise 'δ' AR f * 0.05
diff --git a/Help/UGen/lfdNoise0.help.lhs b/Help/UGen/lfdNoise0.help.lhs
--- a/Help/UGen/lfdNoise0.help.lhs
+++ b/Help/UGen/lfdNoise0.help.lhs
@@ -6,19 +6,19 @@
 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
diff --git a/Help/UGen/lfdNoise3.help.lhs b/Help/UGen/lfdNoise3.help.lhs
--- a/Help/UGen/lfdNoise3.help.lhs
+++ b/Help/UGen/lfdNoise3.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "LFDNoise3"
-    > Sound.SC3.UGen.DB.ugenSummary "LFDNoise3"
+    Sound.SC3.UGen.Help.viewSC3Help "LFDNoise3"
+    Sound.SC3.UGen.DB.ugenSummary "LFDNoise3"
 
 See lfdNoise0
 
diff --git a/Help/UGen/linCongC.help.lhs b/Help/UGen/linCongC.help.lhs
--- a/Help/UGen/linCongC.help.lhs
+++ b/Help/UGen/linCongC.help.lhs
@@ -1,18 +1,22 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LinCongC"
-> Sound.SC3.UGen.DB.ugenSummary "LinCongC"
+    Sound.SC3.UGen.Help.viewSC3Help "LinCongC"
+    Sound.SC3.UGen.DB.ugenSummary "LinCongC"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
 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))
+> g_00 = linCongC AR 22050 1.1 0.13 1 0 * 0.2
 
+> g_01 =
+>   let x = mouseX KR 20 sampleRate Linear 0.1
+>   in 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))
+> g_02 =
+>   let fr = [1,0.1,0.1,0.1]
+>       [n0,n1,n2,m] = map (\(i,j) -> lfNoise2 i KR j) (zip ['α'..] fr)
+>       f = n0 * 1e4 + 1e4
+>       a = n1 * 0.5 + 1.4
+>       c = n2 * 0.1 + 0.1
+>   in linCongC AR f a c m 0 * 0.2
diff --git a/Help/UGen/linExp.help.lhs b/Help/UGen/linExp.help.lhs
--- a/Help/UGen/linExp.help.lhs
+++ b/Help/UGen/linExp.help.lhs
@@ -2,7 +2,7 @@
     > 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
diff --git a/Help/UGen/linPan2.help.lhs b/Help/UGen/linPan2.help.lhs
--- a/Help/UGen/linPan2.help.lhs
+++ b/Help/UGen/linPan2.help.lhs
@@ -2,9 +2,9 @@
     > 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
--- a/Help/UGen/linRand.help.lhs
+++ b/Help/UGen/linRand.help.lhs
@@ -1,8 +1,9 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LinRand"
-> Sound.SC3.UGen.DB.ugenSummary "LinRand"
+    Sound.SC3.UGen.Help.viewSC3Help "LinRand"
+    Sound.SC3.UGen.DB.ugenSummary "LinRand"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> 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))
+> g_01 =
+>   let f = linRand 'α' 200.0 10000.0 (mce [-1, 1])
+>       e = line KR 0.4 0 0.01 RemoveSynth
+>   in fSinOsc AR f 0 * e
diff --git a/Help/UGen/line.help.lhs b/Help/UGen/line.help.lhs
--- a/Help/UGen/line.help.lhs
+++ b/Help/UGen/line.help.lhs
@@ -4,13 +4,18 @@
 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
 
+> 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)]))
+    > import Sound.OSC {- hosc -}
+    > withSC3 (sendMessage (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))
+>    in sinOsc AR f 0 * 0.1
+
+    > audition_at (-1,AddToTail,10,[]) (out 0 g_02)
diff --git a/Help/UGen/linen.help.lhs b/Help/UGen/linen.help.lhs
--- a/Help/UGen/linen.help.lhs
+++ b/Help/UGen/linen.help.lhs
@@ -2,11 +2,11 @@
     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
diff --git a/Help/UGen/localBuf.help.lhs b/Help/UGen/localBuf.help.lhs
--- a/Help/UGen/localBuf.help.lhs
+++ b/Help/UGen/localBuf.help.lhs
@@ -49,7 +49,7 @@
 > 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
+>         f = indexL b x * 100 + 40
 >     in saw AR (f * mce2 1 1.1) * 0.1
 
 detectIndex example using local buffer
diff --git a/Help/UGen/localIn.help.lhs b/Help/UGen/localIn.help.lhs
--- a/Help/UGen/localIn.help.lhs
+++ b/Help/UGen/localIn.help.lhs
@@ -1,28 +1,28 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "LocalIn"
-    > Sound.SC3.UGen.DB.ugenSummary "LocalIn"
+    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
->
+
+> outside_world = soundIn 0
+
 > 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)
@@ -34,6 +34,6 @@
 >         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
--- a/Help/UGen/localOut.help.lhs
+++ b/Help/UGen/localOut.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "LocalOut"
-    > Sound.SC3.UGen.DB.ugenSummary "LocalOut"
+    Sound.SC3.UGen.Help.viewSC3Help "LocalOut"
+    Sound.SC3.UGen.DB.ugenSummary "LocalOut"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/logistic.help.lhs b/Help/UGen/logistic.help.lhs
--- a/Help/UGen/logistic.help.lhs
+++ b/Help/UGen/logistic.help.lhs
@@ -1,15 +1,19 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Logistic"
-> Sound.SC3.UGen.DB.ugenSummary "Logistic"
+    Sound.SC3.UGen.Help.viewSC3Help "Logistic"
+    Sound.SC3.UGen.DB.ugenSummary "Logistic"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
 SC3 default parameters
-> audition (out 0 (logistic AR 3 1000 0.5))
 
+> g_01 = 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))
 
+> g_02 = 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))
+
+> g_03 =
+>   let x = mouseX KR 3 3.99 Linear 0.1
+>       y = mouseY KR 10 10000 Exponential 0.1
+>   in logistic AR x y 0.25 * 0.5
diff --git a/Help/UGen/loopBuf.help.lhs b/Help/UGen/loopBuf.help.lhs
--- a/Help/UGen/loopBuf.help.lhs
+++ b/Help/UGen/loopBuf.help.lhs
@@ -2,7 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "LoopBuf"
 
 > import Sound.SC3 {- hsc3 -}
-> import qualified Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins as E {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as E {- hsc3 -}
 
 Read audio file into memory
 
@@ -37,19 +37,21 @@
 
     import Sound.OSC {- hosc -}
     let send = sendMessage
-    withSC3 (send (s_new "lb0" 3000 AddToTail 1 [("bufnum",0),("startLoop",5000),("endLoop",15000)]))
+    let run = withSC3 . send
 
-    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
+    run (s_new "lb0" 3000 AddToTail 1 [("bufnum",0),("startLoop",5000),("endLoop",15000)])
 
-    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
+    run (n_set1 3000 "rate" (-1)) -- backwards
+    run (n_set1 3000 "rate" 1) -- forwards
+    run (n_set 3000 [("startLoop",11000),("endLoop",13000)]) -- change loop points
+    run (n_set1 3000 "glide" 5) -- 5 second glide
+    run (n_set1 3000 "rate" 2) -- up an octave
+    run (n_set1 3000 "rate" (-1)) -- backwards
+    run (n_set1 3000 "rate" 1) -- back to normal
+    run (n_set1 3000 "ipol" 1) -- no interpolation
+    run (n_set1 3000 "ipol" 2) -- linear interpolation
+    run (n_set1 3000 "ipol" 4) -- cubic interpolation
+    run (n_set1 3000 "gate" 0) -- release gate to hear post-loop
+
+    run (s_new "lb0" 3000 AddToTail 1 [("bufnum",0),("startLoop",5000),("endLoop",15000)])
+    run (n_set 3000 [("loopRel",1),("gate",0)]) -- release instrument without post-loop
diff --git a/Help/UGen/lorenzTrig.help.lhs b/Help/UGen/lorenzTrig.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lorenzTrig.help.lhs
@@ -0,0 +1,27 @@
+    Sound.SC3.UGen.Help.viewSC3Help "LorenzTrig"
+    Sound.SC3.UGen.DB.ugenSummary "LorenzTrig"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> f_01 minfreq maxfreq s b =
+>   let r = 28
+>       h = 0.02
+>       x0 = 0.090879182417163
+>       y0 = 2.97077458055
+>       z0 = 24.282041054363
+>   in lorenzTrig AR minfreq maxfreq s r b h x0 y0 z0
+
+> f_02 = f_01 11025 44100
+
+> g_01 = f_02 10 2.6666667
+
+Randomly modulate params
+
+> g_02 = f_02 (lfNoise0 'α' KR 1 * 2 + 10) (lfNoise0 'β' KR 1 * 1.5 + 2)
+
+as a frequency control
+
+> g_03 =
+>   let n = f_01 1 8 10 28
+>   in sinOsc AR (decay n 1.0 * 800 + 900) 0 * 0.4
diff --git a/Help/UGen/lpcAnalyzer.help.lhs b/Help/UGen/lpcAnalyzer.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/lpcAnalyzer.help.lhs
@@ -0,0 +1,21 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "LPCAnalyzer"
+    > Sound.SC3.UGen.DB.ugenSummary "LPCAnalyzer"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 = lpcAnalyzer (soundIn 0) (impulse AR 440 0 * 0.2) 256 50 0 0.999 0
+
+> g_02 = lpcAnalyzer (soundIn 0) (impulse AR 440 0 * 0.2) 256 50 0 0.999 1
+
+> g_03 =
+>   let x = mouseX KR 1 128 Linear 0.2
+>   in lpcAnalyzer (soundIn 0) (impulse AR 440 0 * 0.2) 128 x 0 0.999 0
+
+> g_04 =
+>   let x = mouseX KR 1 128 Linear 0.2
+>   in lpcAnalyzer (soundIn 0) (impulse AR 440 0 * 0.2) 1024 x 0 0.999 1
+
+> g_05 =
+>   let x = mouseX KR 1 256 Linear 0.2
+>   in lpcAnalyzer (soundIn 0) (whiteNoise 'α' AR * 0.1) 256 x 0 0.999 0
diff --git a/Help/UGen/lpcSynth.help.lhs b/Help/UGen/lpcSynth.help.lhs
--- a/Help/UGen/lpcSynth.help.lhs
+++ b/Help/UGen/lpcSynth.help.lhs
@@ -3,12 +3,14 @@
 
 > import Sound.OSC {- hosc -}
 > import Sound.SC3 {- hsc3 -}
-> import Sound.SC3.Data.LPC {- hsc3-data -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
+> import qualified Sound.SC3.Data.LPC as 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))
+>         f = x / constant (LPC.lpcAnalysisDuration (LPC.lpcHeader lpc))
 >         ptr = lfSaw AR f 1 * 0.5 + 0.5
 >         [cps, rms, err] = mceChannels (lpcVals AR b ptr)
 >         nh = floorE (22000 / cps)
@@ -16,14 +18,14 @@
 >         s = lpcSynth b (voc + (n * err * 20)) ptr
 >     in s * 1e-5 * rms
 
-> fn_01 = "/home/rohan/cvs/tn/tn-56/lpc/fate.lpc"
+> fn_01 = "/home/rohan/sw/hsc3-data/data/lpc/fate.lpc"
 
 > au_01 lpc = do
->   let d = map realToFrac (lpcSC3 lpc)
+>   let d = map realToFrac (LPC.lpcSC3 lpc)
 >   _ <- async (b_alloc 10 (length d) 1)
->   mapM_ send (b_setn1_segmented 512 10 0 d)
+>   mapM_ sendMessage (b_setn1_segmented 512 10 0 d)
 >   let s = lpc_instr 10 (pinkNoise 'α' AR) lpc
 >   play (out 0 s)
 
-    lpc <- lpcRead fn_01
+    lpc <- LPC.lpcRead fn_01
     withSC3 (au_01 lpc)
diff --git a/Help/UGen/lpz2.help.lhs b/Help/UGen/lpz2.help.lhs
--- a/Help/UGen/lpz2.help.lhs
+++ b/Help/UGen/lpz2.help.lhs
@@ -1,7 +1,8 @@
-> Sound.SC3.UGen.Help.viewSC3Help "LPZ2"
-> Sound.SC3.UGen.DB.ugenSummary "LPZ2"
+    Sound.SC3.UGen.Help.viewSC3Help "LPZ2"
+    Sound.SC3.UGen.DB.ugenSummary "LPZ2"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> let n = whiteNoise 'α' AR
-> in audition (out 0 (lpz2 (n * 0.25)))
+> g_01 =
+>   let n = whiteNoise 'α' AR
+>   in lpz2 (n * 0.25)
diff --git a/Help/UGen/lti.help.lhs b/Help/UGen/lti.help.lhs
--- a/Help/UGen/lti.help.lhs
+++ b/Help/UGen/lti.help.lhs
@@ -2,9 +2,10 @@
     Sound.SC3.UGen.DB.ugenSummary "LTI"
 
 > import Sound.SC3 {- hsc3 -}
->
+> import Sound.SC3.UGen.Bindings.DB.External {- 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 -}
+>         z = pinkNoise 'α' AR * 0.1
 >     in lti AR z (asLocalBuf 'β' a) (asLocalBuf 'γ' b)
diff --git a/Help/UGen/membraneCircle.help.lhs b/Help/UGen/membraneCircle.help.lhs
--- a/Help/UGen/membraneCircle.help.lhs
+++ b/Help/UGen/membraneCircle.help.lhs
@@ -1,20 +1,20 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MembraneCircle"
-> Sound.SC3.UGen.DB.ugenSummary "MembraneCircle"
+    Sound.SC3.UGen.Help.viewSC3Help "MembraneCircle"
+    Sound.SC3.UGen.DB.ugenSummary "MembraneCircle"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 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))
+> g_01 =
+>   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
+>   in membraneCircle AR (pinkNoise 'α' AR * e) tension loss
diff --git a/Help/UGen/metro.help.lhs b/Help/UGen/metro.help.lhs
--- a/Help/UGen/metro.help.lhs
+++ b/Help/UGen/metro.help.lhs
@@ -1,16 +1,18 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Metro"
-> Sound.SC3.UGen.DB.ugenSummary "Metro"
+    Sound.SC3.UGen.Help.viewSC3Help "Metro"
+    Sound.SC3.UGen.DB.ugenSummary "Metro"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
-> audition (out 0 (metro AR 60 1))
+> g_01 = 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))
+> g_02 =
+>   let b = xLine KR 60 120 5 DoNothing
+>       m = metro KR b 1
+>       o = sinOsc AR 440 0 * 0.1
+>   in 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)
+> g_03 =
+>   let b = range 30 240 (lfNoise2 'α' KR 0.2)
+>       n = dseq 'β' dinf (mce [1,0.25,0.5,0.25])
+>   in decay (metro KR b n) 0.2 * sinOsc AR 440 0 * 0.1
diff --git a/Help/UGen/mix.help.lhs b/Help/UGen/mix.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mix.help.lhs
@@ -0,0 +1,12 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Mix"
+    Sound.SC3.UGen.DB.ugenSummary "Mix"
+
+> import Sound.SC3 {- hsc3 -}
+
+optimized summation (see sum_opt), ie. Sum3
+
+> g_01 = mix (mce [pinkNoise 'α' AR,fSinOsc AR 801 0,lfSaw AR 40 0]) * 0.1
+
+and Sum4
+
+> g_02 = mix (sinOsc AR (mce (take 10 (iterate (* 2) 36))) 0) * 0.05
diff --git a/Help/UGen/moogLadder.help.lhs b/Help/UGen/moogLadder.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/moogLadder.help.lhs
@@ -0,0 +1,15 @@
+    Sound.SC3.UGen.Help.viewSC3Help "MoogLadder"
+    Sound.SC3.UGen.DB.ugenSummary "MoogLadder"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>   let o = mix (lfSaw AR (mce2 120 180) 0 * 0.33)
+>       cf = linExp (lfCub KR 0.1 (0.5 * pi)) (-1) 1 180 8500
+>   in moogLadder o cf 0.75
+
+> g_02 =
+>   let n = dust 'α' AR 3
+>   in moogLadder n 2000 (mouseY KR 0 1 Linear 0.2)
+
diff --git a/Help/UGen/moogVCF.help.lhs b/Help/UGen/moogVCF.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/moogVCF.help.lhs
@@ -0,0 +1,15 @@
+    Sound.SC3.UGen.Help.viewSC3Help "MoogVCF"
+    Sound.SC3.UGen.DB.ugenSummary "MoogVCF"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>   let o = mix (lfSaw AR (mce2 120 180) 0 * 0.33)
+>       cf = linExp (lfCub KR 0.1 (0.5 * pi)) (-1) 1 180 8500
+>   in moogVCF o cf 0.75
+
+> g_02 =
+>   let o = pulse AR (mce2 40 121) (mce2 0.3 0.7)
+>       cf = range 30 4200 (sinOsc KR (range 0.001 2.2 (lfNoise0 'α' KR 0.42)) 0)
+>   in moogVCF o cf 0.8
diff --git a/Help/UGen/mouseButton.help.lhs b/Help/UGen/mouseButton.help.lhs
--- a/Help/UGen/mouseButton.help.lhs
+++ b/Help/UGen/mouseButton.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "MouseButton"
-    > Sound.SC3.UGen.DB.ugenSummary "MouseButton"
+    Sound.SC3.UGen.Help.viewSC3Help "MouseButton"
+    Sound.SC3.UGen.DB.ugenSummary "MouseButton"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/mul.help.lhs b/Help/UGen/mul.help.lhs
--- a/Help/UGen/mul.help.lhs
+++ b/Help/UGen/mul.help.lhs
@@ -1,8 +1,8 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "Operator.*"
-    > :t (*)
+    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).
diff --git a/Help/UGen/mulAdd.help.lhs b/Help/UGen/mulAdd.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/mulAdd.help.lhs
@@ -0,0 +1,12 @@
+    Sound.SC3.UGen.Help.viewSC3Help "MulAdd"
+    Sound.SC3.UGen.DB.ugenSummary "MulAdd"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = mulAdd (sinOsc AR 440 0) 0.1 0.05
+
+These should both optimise to the same graph...
+
+> g_02 = sinOsc AR 440 0 * 0.1 + 0.05
+
+> g_03 = 0.05 + sinOsc AR 440 0 * 0.1
diff --git a/Help/UGen/mzPokey.help.lhs b/Help/UGen/mzPokey.help.lhs
--- a/Help/UGen/mzPokey.help.lhs
+++ b/Help/UGen/mzPokey.help.lhs
@@ -1,31 +1,38 @@
-> Sound.SC3.UGen.Help.viewSC3Help "MZPokey"
-> Sound.SC3.UGen.DB.ugenSummary "MZPokey"
+    Sound.SC3.UGen.Help.viewSC3Help "MZPokey"
+    Sound.SC3.UGen.DB.ugenSummary "MZPokey"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.F0 {- hsc3 -}
 > 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
+> bits_to_int :: String -> Int
+> bits_to_int = M.parseBits
 
-> 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")))
+> bits_to_ugen :: String -> UGen
+> bits_to_ugen = fromIntegral . bits_to_int
 
-> 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
+> b = bits_to_ugen
+> bln = line KR 0 255 5 RemoveSynth
+> mz1 i j = mzPokey i j 0 0 0 0 0 0 0
+> mz1c i j c = mzPokey i j 0 0 0 0 0 0 c
 
-> audition (out 0 (mz2c bX (b "10101010") bY (b "10101010") (b "00000001")))
+> g_01 = mz1 bln (b "00001111")
+> g_02 = mz1 bln (b "00101111")
+> g_03 = mz1 bln (b "10101111")
+> g_04 = mz1c bln (b "10101111") (b "00000001")
+> g_05 = mz1c bln (b "10101111") (b "01000001")
 
-> let mz4pc (f1,c1) (f2,c2) (f3,c3) (f4,c4) c = mzPokey f1 c1 f2 c2 f3 c3 f4 c4 c
+> mz2c i j p q c = mzPokey i j p q 0 0 0 0 c
+> bX = mouseX KR 0 255 Linear 0.1
+> bY = mouseY KR 0 255 Linear 0.1
 
-> 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))
+> g_06 = mz2c bX (b "10101010") bY (b "10101010") (b "00000001")
+
+> mz4pc (f1,c1) (f2,c2) (f3,c3) (f4,c4) c = mzPokey f1 c1 f2 c2 f3 c3 f4 c4 c
+
+> g_07 =
+>   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")
+>   in mz4pc v1 v2 v3 v4 (b "00000000")
diff --git a/Help/UGen/nRand.help.lhs b/Help/UGen/nRand.help.lhs
--- a/Help/UGen/nRand.help.lhs
+++ b/Help/UGen/nRand.help.lhs
@@ -1,8 +1,9 @@
-> Sound.SC3.UGen.Help.viewSC3Help "NRand"
-> Sound.SC3.UGen.DB.ugenSummary "NRand"
+    Sound.SC3.UGen.Help.viewSC3Help "NRand"
+    Sound.SC3.UGen.DB.ugenSummary "NRand"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> 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))
+> g_01 =
+>   let n = nRand 'α' 1200.0 4000.0 (mce [2,5])
+>       e = line KR 0.2 0 0.1 RemoveSynth
+>   in fSinOsc AR n 0 * e
diff --git a/Help/UGen/nestedAllpassC.help.lhs b/Help/UGen/nestedAllpassC.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/nestedAllpassC.help.lhs
@@ -0,0 +1,64 @@
+    Sound.SC3.UGen.Help.viewSC3Help "NestedAllpassL"
+    Sound.SC3.UGen.DB.ugenSummary "NestedAllpassL"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> nestedAllpassL_def s =
+>   let d1 = 0.036
+>       d2 = 0.030
+>   in nestedAllpassL s d1 d1 0.08 d2 d2 0.3
+
+> doubleNestedAllpassL_def s =
+>   let d1 = 0.0047
+>       d2 = 0.022
+>       d3 = 0.0084
+>   in doubleNestedAllpassL s d1 d1 0.15 d2 d2 0.25 d3 d3 0.3
+
+> f_01 nc s =
+>   let fb = localIn nc AR 0
+>       lp0 = lpf s 6000
+>       lp1 = delayL lp0 0.024 0.024
+>       ap1 = doubleNestedAllpassL_def (lp1 + (0.5 * fb))
+>       ap2 = nestedAllpassL_def ap1
+>       revout = ap1 * 0.5 + ap2 * 0.6
+>       locout = localOut (bpf (revout * 0.5) 1600 0.5)
+>   in mrg2 revout locout
+
+> f_02 nc s =
+>   let fb = localIn nc AR 0
+>       lp = lpf s 6000
+>       ap1 = doubleNestedAllpassL (lp + (0.5 * fb)) 0.0047 0.0047 0.25 0.0083 0.0083 0.35 0.022 0.022 0.45
+>       ap2 = delayL (nestedAllpassL (delayL ap1 0.05 0.05) 0.03 0.03 0.25952 0.03 0.03 0.3) 0.067 0.067
+>       ap3 = nestedAllpassL (lp + (delayL ap2 0.015 0.015 * 0.4)) 0.0292 0.0292 0.25 0.0098 0.0098 0.35
+>       revout = sum_opt [ap1,ap2,ap3] * 0.5
+>       locout = localOut (bpf (revout * 0.4) 1000 0.5)
+>   in mrg2 revout locout
+
+> f_03 nc s =
+>   let fb = localIn nc AR 0
+>       lp = lpf s 4000
+>       ap1 = allpassL (lp + (0.5 * fb)) 0.008 0.008 0.0459
+>       ap2 = delayL (allpassL ap1 0.012 0.012 0.06885) 0.004 0.004
+>       ap3 = delayL (nestedAllpassL (delayL ap2 0.017 0.017) 0.025 0.025 0.5 0.062 0.062 0.25) 0.031 0.031
+>       ap4 = doubleNestedAllpassL (delayL ap3 0.003 0.003) 0.120 0.120 0.5 0.076 0.076 0.25 0.030 0.030 0.25
+>       revout = sum_opt [ap4 * 0.8,ap3 * 0.8,ap2 * 1.5]
+>       locout = localOut (bpf (revout * 0.4) 1000 0.5)
+>   in mrg2 revout locout
+
+> g_00 = soundIn 0
+
+> g_01 =
+>   let sig = soundIn 0
+>       rev = f_01 2 sig
+>   in 0.5 * rev + sig
+
+> g_02 =
+>   let sig = soundIn 0
+>       rev = f_02 2 sig
+>   in 0.5 * rev + sig
+
+> g_03 =
+>   let sig = soundIn 0
+>       rev = f_03 2 sig
+>   in 0.5 * rev + sig
diff --git a/Help/UGen/nhHall.help.lhs b/Help/UGen/nhHall.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/nhHall.help.lhs
@@ -0,0 +1,11 @@
+    Sound.SC3.UGen.Help.viewSC3Help "NHHall"
+    Sound.SC3.UGen.DB.ugenSummary "NHHall"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>   let in1 = soundIn 0
+>       in2 = soundIn 1
+>       rt60 = mouseX KR 0.1 10.0 Linear 0.1
+>   in nhHall in1 in2 rt60 0.5 200 0.5 4000 0.5 0.5 0.5 0.2 0.3
diff --git a/Help/UGen/numAudioBuses.help.lhs b/Help/UGen/numAudioBuses.help.lhs
--- a/Help/UGen/numAudioBuses.help.lhs
+++ b/Help/UGen/numAudioBuses.help.lhs
@@ -1,3 +1,3 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "NumAudioBuses"
-    > Sound.SC3.UGen.DB.ugenSummary "NumAudioBuses"
+    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
--- a/Help/UGen/numBuffers.help.lhs
+++ b/Help/UGen/numBuffers.help.lhs
@@ -1,10 +1,10 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "NumBuffers"
-    > Sound.SC3.UGen.DB.ugenSummary "NumBuffers"
+    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_01 = poll (impulse KR 1 0) numBuffers 0 (label "numBuffers")
+
 > 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
--- a/Help/UGen/numControlBuses.help.lhs
+++ b/Help/UGen/numControlBuses.help.lhs
@@ -1,2 +1,2 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "NumControlBuses"
-    > Sound.SC3.UGen.DB.ugenSummary "NumControlBuses"
+    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
--- a/Help/UGen/numInputBuses.help.lhs
+++ b/Help/UGen/numInputBuses.help.lhs
@@ -1,2 +1,2 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "NumInputBuses"
-    > Sound.SC3.UGen.DB.ugenSummary "NumInputBuses"
+    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
--- a/Help/UGen/numOutputBuses.help.lhs
+++ b/Help/UGen/numOutputBuses.help.lhs
@@ -1,2 +1,2 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "NumOutputBuses"
-    > Sound.SC3.UGen.DB.ugenSummary "NumOutputBuses"
+    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
--- a/Help/UGen/numRunningSynths.help.lhs
+++ b/Help/UGen/numRunningSynths.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "NumRunningSynths"
-    > Sound.SC3.UGen.DB.ugenSummary "NumRunningSynths"
+    Sound.SC3.UGen.Help.viewSC3Help "NumRunningSynths"
+    Sound.SC3.UGen.DB.ugenSummary "NumRunningSynths"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/offsetOut.help.lhs b/Help/UGen/offsetOut.help.lhs
--- a/Help/UGen/offsetOut.help.lhs
+++ b/Help/UGen/offsetOut.help.lhs
@@ -1,14 +1,14 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "OffsetOut"
-    > Sound.SC3.UGen.DB.ugenSummary "OffsetOut"
+    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)
@@ -21,7 +21,7 @@
 >     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 -}
@@ -29,7 +29,7 @@
 >         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
diff --git a/Help/UGen/onsets.help.lhs b/Help/UGen/onsets.help.lhs
--- a/Help/UGen/onsets.help.lhs
+++ b/Help/UGen/onsets.help.lhs
@@ -5,7 +5,7 @@
 
     > withSC3 (async (b_alloc 10 512 1))
 
-> f_01 t = t2A t 0
+> f_01 t = t2a t 0
 
 > f_02 t =
 >     let s = sinOsc AR 440 0 * 0.2
@@ -27,7 +27,7 @@
 
 > g_03 =
 >     let e = linLin (saw AR 2) (-1) 1 0 1
->         p = let f = midiCPS (tIRand 'α' 63 75 (impulse KR 2 0))
+>         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
diff --git a/Help/UGen/osc.help.lhs b/Help/UGen/osc.help.lhs
--- a/Help/UGen/osc.help.lhs
+++ b/Help/UGen/osc.help.lhs
@@ -5,10 +5,12 @@
 
 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])})
+> m_01 =
+>   [b_alloc 10 512 1
+>   ,b_gen_sine1 10 [Normalise,Wavetable,Clear] [1,1/2,1/3,1/4,1/5]]
 
+    > withSC3 (mapM_ maybe_async m_01)
+
 Fixed frequency wavetable oscillator
 
 > g_01 = osc AR 10 220 0 * 0.1
@@ -25,7 +27,7 @@
 >     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
+As phase modulator
 
 > g_04 =
 >     let p = osc AR 10 (xLine KR 20 8000 10 RemoveSynth) 0 * 2 * pi
@@ -37,12 +39,11 @@
 
 Change the wavetable while its playing
 
-    > let f = [Normalise,Wavetable,Clear]
-    > in withSC3 (send (b_gen_sine1 10 f [1,0.6,1/4]))
+    > withSC3 (maybe_async (b_gen_sine1 10 [Normalise,Wavetable,Clear] [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))
+    > withSC3 (maybe_async (b_setn1 10 0 t))
diff --git a/Help/UGen/out.help.lhs b/Help/UGen/out.help.lhs
--- a/Help/UGen/out.help.lhs
+++ b/Help/UGen/out.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "Out"
-    > Sound.SC3.UGen.DB.ugenSummary "Out"
+    Sound.SC3.UGen.Help.viewSC3Help "Out"
+    Sound.SC3.UGen.DB.ugenSummary "Out"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/pan2.help.lhs b/Help/UGen/pan2.help.lhs
--- a/Help/UGen/pan2.help.lhs
+++ b/Help/UGen/pan2.help.lhs
@@ -2,11 +2,11 @@
     > 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
diff --git a/Help/UGen/panAz.help.lhs b/Help/UGen/panAz.help.lhs
--- a/Help/UGen/panAz.help.lhs
+++ b/Help/UGen/panAz.help.lhs
@@ -2,7 +2,7 @@
     > Sound.SC3.UGen.DB.ugenSummary "PanAz"
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 =
 >     let o = pinkNoise 'α' AR
 >         nc = 4
diff --git a/Help/UGen/partConv.help.lhs b/Help/UGen/partConv.help.lhs
--- a/Help/UGen/partConv.help.lhs
+++ b/Help/UGen/partConv.help.lhs
@@ -1,23 +1,29 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PartConv"
-> Sound.SC3.UGen.DB.ugenSummary "PartConv"
+    Sound.SC3.UGen.Help.viewSC3Help "PartConv"
+    Sound.SC3.UGen.DB.ugenSummary "PartConv"
 
-> import Sound.SC3
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
 
-> 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 })
+> f_01 :: Transport m => m UGen
+> f_01 = do
+>   let target_b = 12 {- source signal -}
+>       target_file = "/home/rohan/data/audio/pf-c5.snd"
+>   _ <- async (b_allocRead target_b target_file 0 0)
+>   return (playBuf 1 AR (constant target_b) 1 0 0 Loop DoNothing)
+
+> f_02 :: Transport m => UGen -> m UGen
+> f_02 s = do
+>   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 -}
+>   _ <- async (b_allocRead ir_td_b ir_file 0 ir_length)
+>   _ <- async (b_alloc ir_fd_b accum_size 1)
+>   sendMessage (pc_preparePartConv ir_fd_b ir_td_b fft_size)
+>   return (partConv s (constant fft_size) (constant ir_fd_b))
+
+    g_01 <- withSC3 f_01
+    g_02 <- withSC3 (f_02 (g_01 * 0.1)
+    g_03 <- withSC3 (f_02 (soundIn 0))
diff --git a/Help/UGen/perlin3.help.lhs b/Help/UGen/perlin3.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/perlin3.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Perlin3"
+    Sound.SC3.UGen.DB.ugenSummary "Perlin3"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>     let x = integrator (k2a (mouseX KR 0 0.1 Linear 0.2)) 1.0
+>         y = integrator (k2a (mouseY KR 0 0.1 Linear 0.2)) 1.0
+>     in perlin3 AR x y 0
diff --git a/Help/UGen/phasor.help.lhs b/Help/UGen/phasor.help.lhs
--- a/Help/UGen/phasor.help.lhs
+++ b/Help/UGen/phasor.help.lhs
@@ -6,7 +6,7 @@
 
 phasor controls sine frequency, end frequency matches second sine.
 
-> g_01 =
+> g_00 =
 >     let rate = mouseX KR 0.2 2 Exponential 0.1
 >         tr = impulse AR rate 0
 >         sr = sampleRate
@@ -14,6 +14,15 @@
 >         f = mce [linLin x 0 1 600 1000, 1000]
 >     in sinOsc AR f 0 * 0.2
 
+two phasors control two sine frequencies: mouse y controls resetPos of the second
+
+> g_01 =
+>     let rate = mouseX KR 1 200 Linear 0.1
+>         tr = impulse AR rate 0
+>         sr = sampleRate
+>         x = phasor AR tr (rate / sr) 0 1 (mce2 0 (mouseY KR 0 1 Linear 0.2))
+>     in sinOsc AR (x * 500 + 500) 0 * 0.2
+
 Load sound file to buffer zero
 
     let fn = "/home/rohan/data/audio/pf-c5.aif"
@@ -28,7 +37,7 @@
 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]))
+    withSC3 (mapM_ maybe_async [b_alloc 1 256 1,b_gen_sine1 1 [Normalise,Clear] [1]])
 
 Audio rate phasor oscillator as phase input to bufRd
 
@@ -52,3 +61,22 @@
 >         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'
+
+If one wants Phasor to output a signal with frequency freq oscilating
+between start and end, then the rate should be (end - start) * freq /
+sr where sr is the sampling rate.  F32 precision is an issue.
+
+> g_05 =
+>     let f = mouseX KR 220 880 Exponential 0.1
+>         tr = impulse AR f 0
+>         sr = sampleRate
+>         x = phasor AR tr (two_pi * f / sr) 0 two_pi 0
+>     in sin x * 0.1
+
+phasor as lfSaw, but with precision issues
+
+> g_06 = phasor AR (impulse AR 440 0) (2 * 440 / sampleRate) (-1) 1 0 * 0.2
+
+> g_07 =
+>   let ph = phasor AR (impulse AR 440 0) (two_pi * 440 / sampleRate) 0 two_pi 0
+>   in sin ph * 0.2
diff --git a/Help/UGen/pinkNoise.help.lhs b/Help/UGen/pinkNoise.help.lhs
--- a/Help/UGen/pinkNoise.help.lhs
+++ b/Help/UGen/pinkNoise.help.lhs
@@ -9,21 +9,29 @@
 
 speaker balance
 
-> g_01 = let n = pinkNoise 'α' AR * 0.05 in mce2 n n
->
+> 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
+>         n = pinkNoise 'δ' AR * 0.05
 >     in mce2 (n * x') (n * x)
 
+identifiers & referential transparency
+
+> g_03 = (pinkNoise 'α' AR - pinkNoise 'α' AR) * 0.2
+
+> g_04 = (pinkNoise 'α' AR - pinkNoise 'β' AR) * 0.2
+
+> g_05 = let n = pinkNoise 'α' AR in n - n * 0.2
+
 Drawing
 
     import Sound.SC3.Plot {- hsc3-plot -}
-    plot_ugen1 0.1 (pinkNoise 'α' AR)
+    plot_ugen1 0.1 (pinkNoise 'ε' AR)
 
     import Sound.SC3.Plot.FFT {- hsc3-plot -}
-    plot_ugen_fft1 0.1 (pinkNoise 'α' AR)
+    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
--- a/Help/UGen/pitch.help.lhs
+++ b/Help/UGen/pitch.help.lhs
@@ -12,10 +12,10 @@
 >     in mce [s, sinOsc AR (mceChannel 0 f / 2) 0 * a]
 
 > g_02 =
->     let s = soundIn 4
+>     let s = soundIn 0
 >         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]
+>     in mce [s * 0.1, 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.
@@ -26,6 +26,6 @@
 >         [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
+>         pf = poll t f 0 (label "f")
+>         px = poll t x 0 (label "x")
 >     in mce [out 0 (mce2 o r),pf,px]
diff --git a/Help/UGen/playBuf.help.lhs b/Help/UGen/playBuf.help.lhs
--- a/Help/UGen/playBuf.help.lhs
+++ b/Help/UGen/playBuf.help.lhs
@@ -5,10 +5,12 @@
 
 Load sound file to buffer zero (single channel file required for examples)
 
-> fn = "/home/rohan/data/audio/pf-c5.aif"
+> f_01 = "/home/rohan/data/audio/pf-c5.aif"
 
-    withSC3 (async (b_allocRead 0 fn 0 0))
+> m_01 = (b_allocRead 0 f_01 0 0)
 
+    withSC3 (async m_01)
+
 Play once only.
 
 > gr_01 = playBuf 1 AR 0 (bufRateScale KR 0) 1 0 NoLoop RemoveSynth
@@ -54,9 +56,11 @@
 Graph will play both channels after loading a two channel signal to
 buffer.
 
-> fn' = "/home/rohan/data/audio/sp/tinguely.aif"
+> f_02 = "/home/rohan/data/audio/sp/tinguely.aif"
 
-    withSC3 (async (b_allocRead 0 fn' 0 0))
+> m_02 = b_allocRead 0 f_02 0 0
+
+    withSC3 (async m_02)
 
 Release buffer.
 
diff --git a/Help/UGen/playBufCF.help.lhs b/Help/UGen/playBufCF.help.lhs
--- a/Help/UGen/playBufCF.help.lhs
+++ b/Help/UGen/playBufCF.help.lhs
@@ -1,3 +1,5 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "PlayBufCF"
+
 wslib: external/composite
 
 > import Sound.SC3 {- hsc3 -}
diff --git a/Help/UGen/poll.help.lhs b/Help/UGen/poll.help.lhs
--- a/Help/UGen/poll.help.lhs
+++ b/Help/UGen/poll.help.lhs
@@ -6,11 +6,32 @@
 > g_01 =
 >     let t = impulse KR 10 0
 >         l = line KR 0 1 1 RemoveSynth
->     in poll t l (label "polling...") 0
+>     in poll t l 0 (label "polling...")
 
 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
+>     in poll t l 0 (mce2 (label "t1") (label "t2"))
+
+poll will not poll once with a trigger of one, use impulse with frequency zero
+
+> g_03 =
+>   let k = control KR "k" 0.3
+>       x = negate (k * 1.1)
+>       t = impulse KR 0 0 {- 1 -}
+>   in mrg2 x (poll t x (-1) (label "x"))
+
+poll at trigger control
+
+> g_04 =
+>   let t = tr_control "t" 0.3
+>       f1 = lfNoise2 'α' AR 0.25 * 100 + 110
+>       f2 = lfNoise2 'β' AR 0.25 * 200 + 220
+>       s = gendy1 'γ' AR 1 1 1 1 f1 f2 0.5 0.5 12 0 * 0.1
+>       p = poll t (mce2 f1 f2) (-1) (mce2 (label "f1") (label "f2"))
+>   in mrg2 s p
+
+    import Sound.OSC {- hosc -}
+    withSC3 (sendMessage (n_set1 (-1) "t" 1))
diff --git a/Help/UGen/pulse.help.lhs b/Help/UGen/pulse.help.lhs
--- a/Help/UGen/pulse.help.lhs
+++ b/Help/UGen/pulse.help.lhs
@@ -9,7 +9,7 @@
 >     let f = xLine KR 40 4000 6 RemoveSynth
 >     in pulse AR f 0.1 * 0.1
 
-Modulate pulse width
+Modulate pulse width, 0.5 = square wave
 
 > g_02 =
 >     let w = line KR 0.01 0.99 8 RemoveSynth
diff --git a/Help/UGen/pulseDPW.help.lhs b/Help/UGen/pulseDPW.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pulseDPW.help.lhs
@@ -0,0 +1,8 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PulseDPW"
+    Sound.SC3.UGen.DB.ugenSummary "PulseDPW"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 = pulseDPW AR (xLine KR 2000 20 10 DoNothing) 0.5 * 0.1
+
+> g_02 = pulseDPW AR (mouseX KR 200 12000 Exponential 0.2) 0.5 * 0.2
diff --git a/Help/UGen/pv_BinDelay.help.lhs b/Help/UGen/pv_BinDelay.help.lhs
--- a/Help/UGen/pv_BinDelay.help.lhs
+++ b/Help/UGen/pv_BinDelay.help.lhs
@@ -1,9 +1,12 @@
     > Sound.SC3.UGen.Help.viewSC3Help "PV_BinDelay"
     > Sound.SC3.UGen.DB.ugenSummary "PV_BinDelay"
 
+> import Sound.OSC {- hsc3 -}
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 function to allocate buffers (fft,delay,feedback)
+non-local so that they can be set using b_set &etc.
 
 > mk_buf sz = do
 >   _ <- async (b_alloc 10 (sz * 2) 1)
@@ -28,11 +31,11 @@
 
 set delay times (unary)
 
-    withSC3 (send (b_fill 11 [(0,128,0.25)]))
+    withSC3 (sendMessage (b_fill 11 [(0,128,0.25)]))
 
 set feedback gain
 
-    withSC3 (send (b_fill 12 [(0,128,0.75)]))
+    withSC3 (sendMessage (b_fill 12 [(0,128,0.75)]))
 
 function to generate sin table of n places in range (l,r)
 
@@ -42,11 +45,11 @@
 
 set delay times (sin)
 
-    withSC3 (send (b_setn1 11 0 (gen_sin 0 0.35 128 0)))
+    withSC3 (sendMessage (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)))
+    withSC3 (sendMessage (b_setn1 12 0 (gen_sin 0.75 0.95 128 pi)))
 
 modulate delay times (lfo)
 
diff --git a/Help/UGen/pv_BinScramble.help.lhs b/Help/UGen/pv_BinScramble.help.lhs
--- a/Help/UGen/pv_BinScramble.help.lhs
+++ b/Help/UGen/pv_BinScramble.help.lhs
@@ -1,26 +1,30 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_BinScramble"
-> Sound.SC3.UGen.DB.ugenSummary "PV_BinScramble"
+    Sound.SC3.UGen.Help.viewSC3Help "PV_BinScramble"
+    Sound.SC3.UGen.DB.ugenSummary "PV_BinScramble"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> 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)})
+> n_01 = "/home/rohan/data/audio/pf-c5.snd"
 
-> 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))
+> m_01 = b_allocRead 12 n_01 0 0
 
+     withSC3 (async m_01)
+
+> g_01 =
+>   let a = playBuf 1 AR 12 (bufRateScale KR 12) 1 0 Loop DoNothing
+>       f = fft' (localBuf 'α' 2048 1) 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 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))
+> g_02 =
+>   let a = soundIn 0
+>       f = fft' (localBuf 'γ' 2048 1) 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 pan2 h 0 1
diff --git a/Help/UGen/pv_BinShift.help.lhs b/Help/UGen/pv_BinShift.help.lhs
--- a/Help/UGen/pv_BinShift.help.lhs
+++ b/Help/UGen/pv_BinShift.help.lhs
@@ -1,30 +1,32 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_BinShift"
-> Sound.SC3.UGen.DB.ugenSummary "PV_BinShift"
-
-> import Sound.SC3
-
-allocate buffer
+    Sound.SC3.UGen.Help.viewSC3Help "PV_BinShift"
+    Sound.SC3.UGen.DB.ugenSummary "PV_BinShift"
 
-> withSC3 (async (b_alloc 10 2048 1))
+> import Sound.SC3 {- hsc3 -}
 
 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
+> g_01 =
+>   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
+> g_02 = soundIn 0
 
 default values
 
-> audition (out 0 (ifft' (pv_BinShift (fft' 10 z) 1 0 0)))
+> f_01 z = ifft' (pv_BinShift (ffta 'α' 2048 z 0.5 0 1 0) 1 0 0)
 
+> g_03 = f_01 g_02
+
 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))
+> f_02 z =
+>   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 (ffta 'β' 2048 z 0.5 0 1 0) y x b
+>   in ifft' pv
+
+> g_04 = f_02 g_02
diff --git a/Help/UGen/pv_BinWipe.help.lhs b/Help/UGen/pv_BinWipe.help.lhs
--- a/Help/UGen/pv_BinWipe.help.lhs
+++ b/Help/UGen/pv_BinWipe.help.lhs
@@ -1,17 +1,24 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_BinWipe"
-> Sound.SC3.UGen.DB.ugenSummary "PV_BinWipe"
+    Sound.SC3.UGen.Help.viewSC3Help "PV_BinWipe"
+    Sound.SC3.UGen.DB.ugenSummary "PV_BinWipe"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> 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)})
+> n_01 = "/home/rohan/data/audio/pf-c5.snd"
 
-> 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))
+    withSC3 (async (b_allocRead 12 n_01 0 0))
+
+> g_01 = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+
+> g_02 = soundIn 0
+
+> f_01 z =
+>   let n = whiteNoise 'α' AR * 0.2
+>       f = fft' (localBuf 'β' 2048 1) n
+>       g = fft' (localBuf 'γ' 2048 1) z
+>       x = mouseX KR 0.0 1.0 Linear 0.1
+>       h = pv_BinWipe f g x
+>   in pan2 (ifft' h) 0 0.5
+
+> g_03 = f_01 g_01
+
+> g_04 = f_01 g_02
diff --git a/Help/UGen/pv_BrickWall.help.lhs b/Help/UGen/pv_BrickWall.help.lhs
--- a/Help/UGen/pv_BrickWall.help.lhs
+++ b/Help/UGen/pv_BrickWall.help.lhs
@@ -1,10 +1,14 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_BrickWall"
-> Sound.SC3.UGen.DB.ugenSummary "PV_BrickWall"
+    Sound.SC3.UGen.Help.viewSC3Help "PV_BrickWall"
+    Sound.SC3.UGen.DB.ugenSummary "PV_BrickWall"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> withSC3 (async (b_alloc 10 2048 1))
+> f_01 z =
+>   let x = mouseX KR (-1) 1 Linear 0.1
+>       c = fft' (localBuf 'α' 2048 1) z
+>   in ifft' (pv_BrickWall c x)
 
-> 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)))
+> g_01 = f_01 (whiteNoise 'α' AR * 0.2)
+
+> g_02 = f_01 (soundIn 0)
+
diff --git a/Help/UGen/pv_BufRd.help.lhs b/Help/UGen/pv_BufRd.help.lhs
--- a/Help/UGen/pv_BufRd.help.lhs
+++ b/Help/UGen/pv_BufRd.help.lhs
@@ -1,32 +1,40 @@
-> import Sound.SC3
+    Sound.SC3.UGen.Help.viewSC3Help "PV_BufRd"
+    Sound.SC3.UGen.DB.ugenSummary "PV_BufRd"
 
-allocate anazlysis buffer and load soundfile
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
-> 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)})
+allocate analysis buffer and load soundfile
 
+> n_01 = "/home/rohan/opt/src/supercollider/sounds/a11wlk01.wav"
+
+> m_01 =
+>   let f = 1024 {- frame size -}
+>       h = 0.25 {- hop size -}
+>       p_dur = 4.2832879818594 {- duration (in seconds) of n_01 -}
+>       b_size = pv_calcPVRecSize p_dur f h 48000
+>   in [b_alloc 0 b_size 1,b_allocRead 1 n_01 0 0]
+
+    withSC3 (mapM_ async m_01)
+
 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)
+> g_01 =
+>   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 mrg2 (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)
+> g_02 =
+>   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
+>   in ifft c0 1 0
diff --git a/Help/UGen/pv_Compander.help.lhs b/Help/UGen/pv_Compander.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_Compander.help.lhs
@@ -0,0 +1,39 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Compander"
+    Sound.SC3.UGen.DB.ugenSummary "Compander"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+Example signal to process.
+
+> g_01 =
+>     let e = decay2 (impulse AR 8 0 * lfSaw KR 0.3 0 * 0.3) 0.001 0.3
+>         p = mix (pulse AR (mce [80, 81]) 0.3)
+>     in e * p
+
+> g_02 = soundIn 0
+
+mostly compress
+
+> f_01 z =
+>     let x = mouseX KR 1 50 Linear 0.2
+>     in mce [z, ifft' (pv_Compander (fft' (localBuf 'α' 2048 1) z) x 1.2 0.25)]
+
+> g_03 = f_01 g_01
+
+moslt expand
+
+> f_02 z =
+>     let x = mouseX KR 1 50 Linear 0.1
+>     in mce [z, ifft' (pv_Compander (fft' (localBuf 'β' 2048 1) z) x 2.0 0.85)]
+
+> g_04 = f_02 g_01
+
+pv sustainer
+
+> f_03 z =
+>   let x = mouseX KR 1 80 Linear 0.1
+>       s = ifft' (pv_Compander (fft' (localBuf 'γ' 2048 1) z) x 0.5 1.0)
+>   in mce [z, limiter s 0.999 0.05]
+
+> g_05 = f_03 g_01
diff --git a/Help/UGen/pv_ConformalMap.help.lhs b/Help/UGen/pv_ConformalMap.help.lhs
--- a/Help/UGen/pv_ConformalMap.help.lhs
+++ b/Help/UGen/pv_ConformalMap.help.lhs
@@ -1,27 +1,30 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_ConformalMap"
-> Sound.SC3.UGen.DB.ugenSummary "PV_ConformalMap"
-
-> import Sound.SC3
+    Sound.SC3.UGen.Help.viewSC3Help "PV_ConformalMap"
+    Sound.SC3.UGen.DB.ugenSummary "PV_ConformalMap"
 
-> withSC3 (async (b_alloc 10 1024 1))
+> import Sound.SC3 {- hsc3 -}
 
-> 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))
+> g_01 =
+>   let i = soundIn 0
+>       x = mouseX KR (-1) 1 Linear 0.1
+>       y = mouseY KR (-1) 1 Linear 0.1
+>   in pan2 (ifft' (pv_ConformalMap (fft' (localBuf 'α' 1024 1) i) x y)) 0 1
 
 With filtering.
 
-> withSC3 (async (b_alloc 0 2048 1))
+> f_01 z =
+>   let x = mouseX KR 0.01  2.0 Linear 0.1
+>       y = mouseY KR 0.01 10.0 Linear 0.1
+>       c = fft' (localBuf 'β' 2048 1) z
+>       m = ifft' (pv_ConformalMap c x y)
+>   in pan2 (combN m 0.1 0.1 10 * 0.5 + m) 0 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
+> g_02 =
+>   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
+> g_03 = soundIn 0
 
-> 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))
+> g_04 = f_01 g_02
+
+> g_05 = f_01 g_03
diff --git a/Help/UGen/pv_Copy.help.lhs b/Help/UGen/pv_Copy.help.lhs
--- a/Help/UGen/pv_Copy.help.lhs
+++ b/Help/UGen/pv_Copy.help.lhs
@@ -8,7 +8,7 @@
 is not apparent from the edge structure of the graph.  See instead
 PV_Split.
 
-> cpy0 =
+> g_01 =
 >     let z = lfClipNoise 'α' AR 100 * 0.1
 >         c0 = fft' (localBuf 'β' 2048 1) z
 >         c1 = pv_Copy c0 (localBuf 'γ' 2048 1)
diff --git a/Help/UGen/pv_Diffuser.help.lhs b/Help/UGen/pv_Diffuser.help.lhs
--- a/Help/UGen/pv_Diffuser.help.lhs
+++ b/Help/UGen/pv_Diffuser.help.lhs
@@ -3,18 +3,22 @@
 
 > 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))
+> n_01 = "/home/rohan/data/audio/pf-c5.snd"
 
-> diff_02 = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+> m_01 = b_allocRead 12 n_01 0 0
 
-> diff_02' = soundIn 0
+    withSC3 (async m_01)
 
+> g_01 = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+
+> g_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
+> f_01 z =
+>   let f = fft' (localBuf 'α' 2048 1) z
+>       x = mouseX KR 0 1 Linear 0.1
+>       h = pv_Diffuser f (x >* 0.5)
+>   in ifft' h * 0.5
+
+> g_03 = f_01 g_02
diff --git a/Help/UGen/pv_Freeze.help.lhs b/Help/UGen/pv_Freeze.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_Freeze.help.lhs
@@ -0,0 +1,11 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_Freeze"
+    Sound.SC3.UGen.DB.ugenSummary "PV_Freeze"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>   let f = fft' (localBuf 'α' 2048 1) (soundIn 0)
+>       x = mouseX KR 0 1 Linear 0.1
+>       h = pv_Freeze 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
--- a/Help/UGen/pv_HainsworthFoote.help.lhs
+++ b/Help/UGen/pv_HainsworthFoote.help.lhs
@@ -4,19 +4,19 @@
 > import Sound.SC3 {- hsc3 -}
 
 > g_01 =
->     let i = soundIn 4
+>     let i = soundIn 0
 >         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
+>         o = sinOsc AR (mrg2 440 445) 0 * decay (h * 0.1) 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
+>     let s = lfSaw AR (lfNoise0 'β' 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
diff --git a/Help/UGen/pv_Invert.help.lhs b/Help/UGen/pv_Invert.help.lhs
--- a/Help/UGen/pv_Invert.help.lhs
+++ b/Help/UGen/pv_Invert.help.lhs
@@ -1,13 +1,19 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_Invert"
-> Sound.SC3.UGen.DB.ugenSummary "PV_Invert"
+    Sound.SC3.UGen.Help.viewSC3Help "PV_Invert"
+    Sound.SC3.UGen.DB.ugenSummary "PV_Invert"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
-> 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
+> g_01 =
+>   let s = sinOsc AR 440 0 * 0.4
+>       n = pinkNoise 'α' AR * 0.1
+>   in s + n
+
+> f_01 z =
+>   let c0 = fft' (localBuf 'β' 2048 1) z
+>       c1 = pv_Invert c0
+>   in mce2 z (ifft' c1) * 0.5
+
+> g_02 = f_01 g_01
+
+> g_03 = f_01 (soundIn 0)
diff --git a/Help/UGen/pv_LocalMax.help.lhs b/Help/UGen/pv_LocalMax.help.lhs
--- a/Help/UGen/pv_LocalMax.help.lhs
+++ b/Help/UGen/pv_LocalMax.help.lhs
@@ -1,14 +1,22 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_LocalMax"
-> Sound.SC3.UGen.DB.ugenSummary "PV_LocalMax"
+    Sound.SC3.UGen.Help.viewSC3Help "PV_LocalMax"
+    Sound.SC3.UGen.DB.ugenSummary "PV_LocalMax"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> 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)})
+> n_01 = "/home/rohan/data/audio/pf-c5.snd"
 
-> 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))
+> m_01 = b_allocRead 12 n_01 0 0
+
+     withSC3 (async m_01)
+
+> g_01 = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+
+> f_01 z =
+>   let f = fft' (localBuf 'α' 2048 1) z
+>       x = mouseX KR 0 100 Linear 0.1
+>       h = pv_LocalMax f x
+>   in ifft' h * 0.5
+
+> g_02 = f_01 g_01
+
+> g_03 = f_01 (soundIn 0)
diff --git a/Help/UGen/pv_MagAbove.help.lhs b/Help/UGen/pv_MagAbove.help.lhs
--- a/Help/UGen/pv_MagAbove.help.lhs
+++ b/Help/UGen/pv_MagAbove.help.lhs
@@ -1,22 +1,30 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_MagAbove"
-> Sound.SC3.UGen.DB.ugenSummary "PV_MagAbove"
+    Sound.SC3.UGen.Help.viewSC3Help "PV_MagAbove"
+    Sound.SC3.UGen.DB.ugenSummary "PV_MagAbove"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> 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) })
+> n_01 = "/home/rohan/data/audio/pf-c5.snd"
 
-> 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))
+> m_01 = b_allocRead 12 n_01 0 0
 
+     withSC3 (async m_01)
+
+> g_01 = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+
+> f_01 z n =
+>   let f = fft' (localBuf 'α' 2048 1) z
+>       x = mouseX KR 0 n Linear 0.1
+>       h = pv_MagAbove f x
+>   in ifft' h * 0.5
+
+> g_02 = f_01 g_01 100
+
 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))
+
+> g_03 =
+>   let a = sinOsc KR (squared (sinOsc KR 0.08 0 * 6 + 6.2)) 0 * 100 + 800
+>   in sinOsc AR a 0
+
+> g_04 = f_01 g_03 1024
+
+> g_05 = f_01 (soundIn 0) 32
diff --git a/Help/UGen/pv_MagBelow.help.lhs b/Help/UGen/pv_MagBelow.help.lhs
--- a/Help/UGen/pv_MagBelow.help.lhs
+++ b/Help/UGen/pv_MagBelow.help.lhs
@@ -1,22 +1,30 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_MagBelow"
-> Sound.SC3.UGen.DB.ugenSummary "PV_MagBelow"
+    Sound.SC3.UGen.Help.viewSC3Help "PV_MagBelow"
+    Sound.SC3.UGen.DB.ugenSummary "PV_MagBelow"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> 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)})
+> n_01 = "/home/rohan/data/audio/pf-c5.snd"
 
-> 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))
+> m_01 = b_allocRead 12 n_01 0 0
 
+     withSC3 (async m_01)
+
+> g_01 = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+
+> f_01 z n =
+>   let f = fft' (localBuf 'α' 2048 1) z
+>       x = mouseX KR 0 n Linear 0.1
+>       h = pv_MagBelow f x
+>   in ifft' h * 0.5
+
+> g_02 = f_01 g_01 100
+
 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))
+
+> g_03 =
+>   let a = sinOsc KR (squared (sinOsc KR 0.08 0 * 6 + 6.2)) 0 * 100 + 800
+>   in sinOsc AR a 0
+
+> g_04 = f_01 g_03 1024
+
+> g_05 = f_01 (soundIn 0) 32
diff --git a/Help/UGen/pv_MagClip.help.lhs b/Help/UGen/pv_MagClip.help.lhs
--- a/Help/UGen/pv_MagClip.help.lhs
+++ b/Help/UGen/pv_MagClip.help.lhs
@@ -1,28 +1,11 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_MagClip"
-> Sound.SC3.UGen.DB.ugenSummary "PV_MagClip"
+    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))
+> g_01 =
+>   let f = fft' (localBuf 'α' 2048 1) (soundIn 0)
+>       c = 128
+>       x = mouseX KR 0 c Linear 0.1
+>       h = pv_MagClip f x
+>   in ifft' h * 0.5
diff --git a/Help/UGen/pv_MagFreeze.help.lhs b/Help/UGen/pv_MagFreeze.help.lhs
--- a/Help/UGen/pv_MagFreeze.help.lhs
+++ b/Help/UGen/pv_MagFreeze.help.lhs
@@ -1,31 +1,37 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_MagFreeze"
-> Sound.SC3.UGen.DB.ugenSummary "PV_MagFreeze"
+    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)})
+> n_01 = "/home/rohan/data/audio/pf-c5.snd"
 
+> m_01 = [b_allocRead 12 n_01 0 0]
+
+    withSC3 (mapM_ async m_01)
+
 File as signal...
 
-> let z = playBuf 1 AR 12 (bufRateScale KR 12) 0 0 Loop DoNothing
+> g_01 = 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
+> g_02 =
+>   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
+> g_03 = soundIn 0
 
 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))
+> f_01 z =
+>   let f = fft' (localBuf 'α' 2048 1) z
+>       x = mouseX KR 0 1 Linear 0.1
+>       h = pv_MagFreeze f (x >* 0.5)
+>   in ifft' h * 0.5
+
+> g_04 = f_01 g_03
diff --git a/Help/UGen/pv_MagGate.help.lhs b/Help/UGen/pv_MagGate.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_MagGate.help.lhs
@@ -0,0 +1,17 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_MagGate"
+    Sound.SC3.UGen.DB.ugenSummary "PV_MagGate"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> f_01 (lhs,rhs) =
+>   let i = soundIn 0
+>       c = fft' (localBuf 'α' 2048 1) i
+>       x = mouseX KR lhs rhs Linear 0.2
+>       y = mouseY KR 0 1 Linear 0.2
+>       h = pv_MagGate c x y
+>   in ifft' h * 0.5
+
+> g_01 = f_01 (0,100)
+
+> g_02 = f_01 (-50,0)
diff --git a/Help/UGen/pv_MagMap.help.lhs b/Help/UGen/pv_MagMap.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_MagMap.help.lhs
@@ -0,0 +1,36 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_MagMap"
+    Sound.SC3.UGen.DB.ugenSummary "PV_MagMap"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 = pinkNoise 'α' AR * 0.03 + sinOsc AR 440 0 * 0.5
+
+> f_01 sig map_buf =
+>     let c0 = fft' (localBuf 'β' 1 2048) sig
+>         c1 = pv_MagMap c0 map_buf
+>     in ifft' c1
+
+> f_02 l t c = envelope_table 256 (Envelope l t [c] Nothing Nothing 0)
+
+the curve to map the sound onto
+
+> t_01 :: (Ord t,Floating t,Enum t) => [t]
+> t_01 = f_02 [0,1,0] [0.05,0.95] EnvWelch
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plotTable1 t_01
+
+> f_03 t l c = withSC3 (sendMessage (b_setn1 10 0 (f_02 t l c)))
+
+    withSC3 (async (b_alloc 10 256 1) >> sendMessage (b_setn1 10 0 t_01))
+    f_03 [0,1] [1] EnvLin
+    f_03 [1,0] [1] EnvLin
+
+> g_03 = f_01 g_01 10
+
+loclBuf fails...
+
+> g_09 = f_01 g_01 (asLocalBuf 'γ' t_01)
+
diff --git a/Help/UGen/pv_MagMul.help.lhs b/Help/UGen/pv_MagMul.help.lhs
--- a/Help/UGen/pv_MagMul.help.lhs
+++ b/Help/UGen/pv_MagMul.help.lhs
@@ -1,16 +1,15 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "PV_MagMul"
-    > Sound.SC3.UGen.DB.ugenSummary "PV_MagMul"
+    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 =
+> f_01 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)
+> g_01 = f_01 (whiteNoise 'γ' AR * 0.2)
+
+> g_02 = f_01 (soundIn 0 * 0.5)
diff --git a/Help/UGen/pv_MagSmear.help.lhs b/Help/UGen/pv_MagSmear.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_MagSmear.help.lhs
@@ -0,0 +1,11 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_MagSmear"
+    Sound.SC3.UGen.DB.ugenSummary "PV_MagSmear"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>   let i = soundIn 0
+>       c = fft' (localBuf 'α' 2048 1) i
+>       x = mouseX KR 0 100 Linear 0.2
+>       h = pv_MagSmear c x
+>   in ifft' h * 0.5
diff --git a/Help/UGen/pv_Morph.help.lhs b/Help/UGen/pv_Morph.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_Morph.help.lhs
@@ -0,0 +1,14 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_Morph"
+    Sound.SC3.UGen.DB.ugenSummary "PV_Morph"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>   let o1 = pulse AR 180 (lfCub KR 1 0 * 0.1 + 0.3) * 0.5
+>       o2 = varSaw AR 190 0 (lfCub KR 0.8 0 * 0.4 + 0.5) * 0.5
+>       c1 = fft' (localBuf 'α' 2048 1) o1
+>       c2 = fft' (localBuf 'β' 2048 1) o2
+>       x = mouseX KR 0 1 Linear 0.2
+>       h = pv_Morph c1 c2 x
+>   in ifft' h * 0.5
diff --git a/Help/UGen/pv_Mul.help.lhs b/Help/UGen/pv_Mul.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_Mul.help.lhs
@@ -0,0 +1,12 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_Mul"
+    Sound.SC3.UGen.DB.ugenSummary "PV_Mul"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>   let o1 = sinOsc AR 500 0 * 0.5
+>       o2 = sinOsc AR (line KR 50 400 5 RemoveSynth) 0 * 0.5
+>       c1 = fft' (localBuf 'α' 2048 1) o1
+>       c2 = fft' (localBuf 'β' 2048 1) o2
+>       h = pv_Mul c1 c2
+>   in ifft' h * 0.5
diff --git a/Help/UGen/pv_PlayBuf.help.lhs b/Help/UGen/pv_PlayBuf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_PlayBuf.help.lhs
@@ -0,0 +1,21 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_PlayBuf"
+    Sound.SC3.UGen.DB.ugenSummary "PV_PlayBuf"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+see pv_BufRd for code to allocate and fill analysis buffer (rec_buf)
+
+> g_01 =
+>   let rec_buf = 0
+>       l_buf = localBuf 'α' 1024 1
+>       x = mouseX KR (-1) 1 Linear 0.2
+>       c = pv_PlayBuf l_buf rec_buf x 50 1
+>   in ifft c 1 0
+
+> g_02 =
+>   let rec_buf = 0
+>       l_buf = localBuf 'β' 1024 1
+>       n = range (-1) 2 (lfNoise2 'γ' KR 0.2)
+>       c = pv_PlayBuf l_buf rec_buf n 0 1
+>   in ifft c 1 0
diff --git a/Help/UGen/pv_RandComb.help.lhs b/Help/UGen/pv_RandComb.help.lhs
--- a/Help/UGen/pv_RandComb.help.lhs
+++ b/Help/UGen/pv_RandComb.help.lhs
@@ -1,23 +1,22 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_RandComb"
-> Sound.SC3.UGen.DB.ugenSummary "PV_RandComb"
-
-> import Sound.SC3
-
-allocate buffer
+    Sound.SC3.UGen.Help.viewSC3Help "PV_RandComb"
+    Sound.SC3.UGen.DB.ugenSummary "PV_RandComb"
 
-> withSC3 (async (b_alloc 10 2048 1))
+> import Sound.SC3 {- hsc3 -}
 
 noise signal
 
-> let z = whiteNoise 'α' AR * 0.5
+> g_01 = whiteNoise 'α' AR * 0.5
 
 outside world
 
-> let z = soundIn 4
+> g_02 = soundIn 0
 
 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))
+> f_01 f z =
+>   let t = impulse KR f 0
+>       x = mouseX KR 0.6 0.95 Linear 0.1
+>       c = pv_RandComb 'α' (fft' (localBuf 'α' 2048 1) z) x t
+>   in pan2 (ifft' c) 0 1
+
+> g_03 = f_01 0.5 g_02
diff --git a/Help/UGen/pv_RandWipe.help.lhs b/Help/UGen/pv_RandWipe.help.lhs
--- a/Help/UGen/pv_RandWipe.help.lhs
+++ b/Help/UGen/pv_RandWipe.help.lhs
@@ -1,23 +1,25 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_RandWipe"
-> Sound.SC3.UGen.DB.ugenSummary "PV_RandWipe"
+    Sound.SC3.UGen.Help.viewSC3Help "PV_RandWipe"
+    Sound.SC3.UGen.DB.ugenSummary "PV_RandWipe"
 
-> import Sound.SC3
-> import qualified System.Random as R
+> import Sound.SC3 {- hsc3 -}
+> import qualified System.Random as R {- random -}
 
-> withSC3 (do {_ <- async (b_alloc 10 2048 1)
->             ;async (b_alloc 11 2048 1)})
+> g_01 =
+>   let n0 = R.randomRs (400.0, 1000.0) (R.mkStdGen 0)
+>       o0 = map (\n -> lfSaw AR n 0 * 0.1) (take 6 n0)
+>   in sum_opt o0
 
-> 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))
+> g_02 =
+>   let n1 = R.randomRs (80.0, 400.0) (R.mkStdGen 1)
+>       n2 = R.randomRs (0.0, 8.0) (R.mkStdGen 2)
+>       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)
+>   in sum_opt (zipWith (\p s -> p * (max s 0.0)) o1 o2)
+
+> g_03 =
+>   let f1 = fft' (localBuf 'α' 2048 1) g_01
+>       f2 = fft' (localBuf 'β' 2048 1) g_02
+>       x = mouseX KR 0 1 Linear 0.1
+>       y = mouseY KR 0 1 Linear 0.1
+>       h = pv_RandWipe 'γ' f1 f2 x (y >* 0.5)
+>   in pan2 (ifft' h) 0 0.5
diff --git a/Help/UGen/pv_RecordBuf.help.lhs b/Help/UGen/pv_RecordBuf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_RecordBuf.help.lhs
@@ -0,0 +1,4 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_RecordBuf"
+    Sound.SC3.UGen.DB.ugenSummary "PV_RecordBuf"
+
+see pv_BufRd
diff --git a/Help/UGen/pv_RectComb.help.lhs b/Help/UGen/pv_RectComb.help.lhs
--- a/Help/UGen/pv_RectComb.help.lhs
+++ b/Help/UGen/pv_RectComb.help.lhs
@@ -1,24 +1,34 @@
-> Sound.SC3.UGen.Help.viewSC3Help "PV_RectComb"
-> Sound.SC3.UGen.DB.ugenSummary "PV_RectComb"
-
-> import Sound.SC3
+    Sound.SC3.UGen.Help.viewSC3Help "PV_RectComb"
+    Sound.SC3.UGen.DB.ugenSummary "PV_RectComb"
 
-> withSC3 (async (b_alloc 10 2048 1))
+> import Sound.SC3 {- hsc3 -}
 
 noise source
 
-> let z = whiteNoise 'α' AR * 0.3
+> g_01 = whiteNoise 'α' AR * 0.3
 
 outside world
 
-> let z = soundIn 4
+> g_02 = soundIn 0
 
-> 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))
+mouse control
 
-> 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))
+> f_01 z =
+>   let b = localBuf 'β' 2048 1
+>       x = mouseX KR 0 0.5 Linear 0.1
+>       y = mouseY KR 0 0.5 Linear 0.1
+>       c = pv_RectComb (fft' b z) 8 x y
+>   in pan2 (ifft' c) 0 1
+
+> g_03 = f_01 g_02
+
+lfo control
+
+> f_02 z =
+>   let b = localBuf 'γ' 2048 1
+>       p = lfTri KR 0.097 0 *   0.4  + 0.5
+>       w = lfTri KR 0.240 0 * (-0.5) + 0.5
+>       c = pv_RectComb (fft' b z) 8 p w
+>   in pan2 (ifft' c) 0 1
+
+> g_04 = f_02 g_02
diff --git a/Help/UGen/pv_SpectralMap.help.lhs b/Help/UGen/pv_SpectralMap.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_SpectralMap.help.lhs
@@ -0,0 +1,20 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_SpectralMap"
+    Sound.SC3.UGen.DB.ugenSummary "PV_SpectralMap"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> n_01 = "/home/rohan/opt/src/supercollider/sounds/a11wlk01.wav"
+
+> m_01 = b_allocRead 10 n_01 0 0
+
+    withSC3 (async m_01)
+
+> g_01 =
+>   let freeze = mouseY KR (-1) 1 Linear 0.2
+>       a = localBuf 'α' 2048 1
+>       b = localBuf 'β' 2048 1
+>       c1 = fft' a (soundIn 0)
+>       c2 = fft' b (playBuf 1 AR 10 1 1 0 Loop DoNothing)
+>       c3 = pv_SpectralMap c1 c2 0.0 freeze (mouseX KR (-1) 1 Linear 0.2) 1 0
+>   in ifft' c3
diff --git a/Help/UGen/pv_XFade.help.lhs b/Help/UGen/pv_XFade.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/pv_XFade.help.lhs
@@ -0,0 +1,14 @@
+    Sound.SC3.UGen.Help.viewSC3Help "PV_XFade"
+    Sound.SC3.UGen.DB.ugenSummary "PV_XFade"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>   let o1 = pulse AR 180 (lfCub KR 1 0 * 0.1 + 0.3) * 0.5
+>       o2 = varSaw AR 190 0 (lfCub KR 0.8 0 * 0.4 + 0.5) * 0.5
+>       c1 = fft' (localBuf 'α' 2048 1) o1
+>       c2 = fft' (localBuf 'β' 2048 1) o2
+>       x = mouseX KR 0 1 Linear 0.2
+>       h = pv_XFade c1 c2 x
+>   in ifft' h * 0.5
diff --git a/Help/UGen/quadN.help.lhs b/Help/UGen/quadN.help.lhs
--- a/Help/UGen/quadN.help.lhs
+++ b/Help/UGen/quadN.help.lhs
@@ -1,13 +1,15 @@
-> Sound.SC3.UGen.Help.viewSC3Help "QuadN"
-> Sound.SC3.UGen.DB.ugenSummary "QuadN"
+    Sound.SC3.UGen.Help.viewSC3Help "QuadN"
+    Sound.SC3.UGen.DB.ugenSummary "QuadN"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> audition (out 0 (quadC AR 4000 1 (-1) (-0.75) 0 * 0.2))
+> g_01 = quadC AR (sampleRate / 4) 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))
+> g_02 =
+>   let x = mouseX KR 3.5441 4 Linear 0.1
+>   in 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))
+> g_03 =
+>   let x = mouseX KR 3.5441 4 Linear 0.1
+>       f = quadC AR 4 (negate x) x 0 0.1 * 800 + 900
+>   in sinOsc AR f 0 * 0.4
diff --git a/Help/UGen/ramp.help.lhs b/Help/UGen/ramp.help.lhs
--- a/Help/UGen/ramp.help.lhs
+++ b/Help/UGen/ramp.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "Ramp"
-    > Sound.SC3.UGen.DB.ugenSummary "Ramp"
+    Sound.SC3.UGen.Help.viewSC3Help "Ramp"
+    Sound.SC3.UGen.DB.ugenSummary "Ramp"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/rand.help.lhs b/Help/UGen/rand.help.lhs
--- a/Help/UGen/rand.help.lhs
+++ b/Help/UGen/rand.help.lhs
@@ -1,10 +1,11 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Rand"
-> Sound.SC3.UGen.DB.ugenSummary "Rand"
+    Sound.SC3.UGen.Help.viewSC3Help "Rand"
+    Sound.SC3.UGen.DB.ugenSummary "Rand"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> 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))
+> g_01 =
+>   let f = rand 'α' 200 1200
+>       l = rand 'β' (-1) 1
+>       e = line KR 0.2 0 0.1 RemoveSynth
+>       o = fSinOsc AR f 0
+>   in pan2 (o * e) l 1
diff --git a/Help/UGen/randID.help.lhs b/Help/UGen/randID.help.lhs
--- a/Help/UGen/randID.help.lhs
+++ b/Help/UGen/randID.help.lhs
@@ -1,2 +1,2 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RandID"
-> Sound.SC3.UGen.DB.ugenSummary "RandID"
+    > 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
--- a/Help/UGen/randSeed.help.lhs
+++ b/Help/UGen/randSeed.help.lhs
@@ -1,27 +1,27 @@
-Sound.SC3.UGen.Help.viewSC3Help "RandSeed"
-Sound.SC3.UGen.DB.ugenSummary "RandSeed"
+    Sound.SC3.UGen.Help.viewSC3Help "RandSeed"
+    Sound.SC3.UGen.DB.ugenSummary "RandSeed"
 
 > import Sound.SC3
 
 start a noise patch
 
-> u0 =
+> g_01 =
 >     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 =
+> g_02 =
 >      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)...
+always the same (for a given seed)... (crash!)
 
-> u2 =
+> g_03 =
 >     let sd = 1957
->         n = tIRand 'α' 4 12 (dust 'β' KR 1)
+>         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
--- a/Help/UGen/recordBuf.help.lhs
+++ b/Help/UGen/recordBuf.help.lhs
@@ -1,24 +1,29 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "RecordBuf"
-    > Sound.SC3.UGen.DB.ugenSummary "RecordBuf"
+    Sound.SC3.UGen.Help.viewSC3Help "RecordBuf"
+    Sound.SC3.UGen.DB.ugenSummary "RecordBuf"
 
 > import Sound.SC3 {- hsc3 -}
 
+> b_01 :: Num n => n
+> b_01 = 0
+
 Allocate a buffer (assume SR of 48k)
 
-    > withSC3 (async (b_alloc 0 (48000 * 4) 1))
+> m_01 = b_alloc b_01 (48000 * 4) 1
 
+    > withSC3 (async m_01)
+
 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)
+>     in mrg2 o (recordBuf AR b_01 0 1 0 1 NoLoop 1 RemoveSynth o)
 
 Play it back
 
-> g_02 = playBuf 1 AR 0 1 1 0 NoLoop RemoveSynth
+> g_02 = playBuf 1 AR b_01 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)
+>     in mrg2 o (recordBuf AR b_01 0 0.5 0.5 1 NoLoop 1 RemoveSynth o)
diff --git a/Help/UGen/redPhasor.help.lhs b/Help/UGen/redPhasor.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/redPhasor.help.lhs
@@ -0,0 +1,25 @@
+    Sound.SC3.UGen.Help.viewSC3Help "RedPhasor"
+    Sound.SC3.UGen.DB.ugenSummary "RedPhasor"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.HW.External.F0 {- hsc3 -}
+
+no looping & it will play through once. Mouse x acts as trigger
+
+> g_01 =
+>   let tr = mouseX KR 0 1 Linear 0.2 >* 0.5
+>   in sinOsc AR (redPhasor KR tr 0.3 400 800 0 500 600) 0 * 0.2
+
+mouse y controls looping on/off, mouse x trigger
+
+> g_02 =
+>   let tr = mouseX KR 0 1 Linear 0.2 >* 0.5
+>       lp = mouseY KR 0 1 Linear 0.2 >* 0.5
+>   in sinOsc AR (redPhasor KR tr 0.3 400 800 lp 500 600) 0 * 0.2
+
+mouse x controls loop rate, mouse y scales the start looppoint
+
+> g_03 =
+>   let x = mouseX KR 0 5 Linear 0.2
+>       y = mouseY KR 200 500 Linear 0.2
+>   in sinOsc AR (redPhasor KR 0 x 400 800 1 y 600) 0 * 0.2
diff --git a/Help/UGen/replaceOut.help.lhs b/Help/UGen/replaceOut.help.lhs
--- a/Help/UGen/replaceOut.help.lhs
+++ b/Help/UGen/replaceOut.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "ReplaceOut"
-    > Sound.SC3.UGen.DB.ugenSummary "ReplaceOut"
+    Sound.SC3.UGen.Help.viewSC3Help "ReplaceOut"
+    Sound.SC3.UGen.DB.ugenSummary "ReplaceOut"
 
 > import Sound.OSC {- hosc -}
 > import Sound.SC3 {- hsc3 -}
@@ -67,6 +67,6 @@
 > f_01 m =
 >     if isAsync m
 >     then async m >> return ()
->     else send m
+>     else sendMessage m
 
-   > withSC3 (mapM_ f_01 m_01)
+    withSC3 (mapM_ f_01 m_01)
diff --git a/Help/UGen/resonz.help.lhs b/Help/UGen/resonz.help.lhs
--- a/Help/UGen/resonz.help.lhs
+++ b/Help/UGen/resonz.help.lhs
@@ -1,35 +1,39 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Resonz"
-> Sound.SC3.UGen.DB.ugenSummary "Resonz"
+    Sound.SC3.UGen.Help.viewSC3Help "Resonz"
+    Sound.SC3.UGen.DB.ugenSummary "Resonz"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> let n = whiteNoise 'α' AR
-> in audition (out 0 (resonz (n * 0.5) 2000 0.1))
+> g_01 =
+>   let n = whiteNoise 'α' AR
+>   in 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))
+> g_02 =
+>   let n = whiteNoise 'α' AR
+>       f = xLine KR 1000 8000 10 RemoveSynth
+>   in 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))
+> g_03 =
+>   let n = whiteNoise 'α' AR
+>       bw = xLine KR 1 0.001 8 RemoveSynth
+>   in 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))
+> g_04 =
+>   let n = whiteNoise 'α' AR
+>       bw = xLine KR 0.001 1 8 RemoveSynth
+>   in 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)
+> g_05 =
+>   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) -}
+>   in resonz (n * 0.5) f rq
diff --git a/Help/UGen/rhpf.help.lhs b/Help/UGen/rhpf.help.lhs
--- a/Help/UGen/rhpf.help.lhs
+++ b/Help/UGen/rhpf.help.lhs
@@ -1,7 +1,8 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RHPF"
-> Sound.SC3.UGen.DB.ugenSummary "RHPF"
+    Sound.SC3.UGen.Help.viewSC3Help "RHPF"
+    Sound.SC3.UGen.DB.ugenSummary "RHPF"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> 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))
+> g_01 =
+>   let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
+>   in rhpf (saw AR 200 * 0.1) f 0.2
diff --git a/Help/UGen/ring1.help.lhs b/Help/UGen/ring1.help.lhs
--- a/Help/UGen/ring1.help.lhs
+++ b/Help/UGen/ring1.help.lhs
@@ -1,8 +1,8 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "Operator.ring1"
-    > :t ring1
+    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
diff --git a/Help/UGen/ring2.help.lhs b/Help/UGen/ring2.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ring2.help.lhs
@@ -0,0 +1,12 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Operator.ring2"
+    :t ring2
+
+> import Sound.SC3 {- hsc3 -}
+
+> o_01 = fSinOsc AR 800 0
+> o_02 = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
+> g_01 = ring2 o_01 o_02 * 0.125
+
+is equivalent to:
+
+> g_02 = ((o_01 * o_02) + o_01 + o_02) * 0.125
diff --git a/Help/UGen/ring3.help.lhs b/Help/UGen/ring3.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ring3.help.lhs
@@ -0,0 +1,12 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Operator.ring3"
+    :t ring3
+
+> import Sound.SC3 {- hsc3 -}
+
+> o_01 = fSinOsc AR 800 0
+> o_02 = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
+> g_01 = ring3 o_01 o_02 * 0.125
+
+is equivalent to:
+
+> g_02 = (o_01 * o_01 * o_02) * 0.125
diff --git a/Help/UGen/ring4.help.lhs b/Help/UGen/ring4.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/ring4.help.lhs
@@ -0,0 +1,12 @@
+    Sound.SC3.UGen.Help.viewSC3Help "Operator.ring4"
+    :t ring4
+
+> import Sound.SC3 {- hsc3 -}
+
+> a = fSinOsc AR 800 0
+> b = fSinOsc AR (xLine KR 200 500 5 DoNothing) 0
+> g_01 = ring4 a b * 0.125
+
+is equivalent to:
+
+> g_02 = (((a * a * b) - (a * b * b))) * 0.125
diff --git a/Help/UGen/ringz.help.lhs b/Help/UGen/ringz.help.lhs
--- a/Help/UGen/ringz.help.lhs
+++ b/Help/UGen/ringz.help.lhs
@@ -1,29 +1,35 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Ringz"
-> Sound.SC3.UGen.DB.ugenSummary "Ringz"
+    Sound.SC3.UGen.Help.viewSC3Help "Ringz"
+    Sound.SC3.UGen.DB.ugenSummary "Ringz"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> let n = dust 'α' AR 3
-> in audition (out 0 (ringz (n * 0.3) 2000 2))
+> g_01 =
+>   let n = dust 'α' AR 3
+>   in ringz (n * 0.3) 2000 2
 
-> let n = whiteNoise 'α' AR
-> in audition (out 0 (ringz (n * 0.005) 2000 0.5))
+> g_02 =
+>   let n = whiteNoise 'α' AR
+>   in ringz (n * 0.005) 2000 0.5
 
 Modulate frequency
 
-> let {n = whiteNoise 'α' AR
+> g_03 =
+>   let {n = whiteNoise 'α' AR
 >     ;f = xLine KR 100 3000 10 RemoveSynth}
-> in audition (out 0 (ringz (n * 0.005) f 0.5))
+>   in 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))
+> g_04 =
+>   let f = xLine KR 100 3000 10 RemoveSynth
+>   in 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))
+> g_05 =
+>   let rt = xLine KR 4 0.04 8 RemoveSynth
+>   in 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))
+> g_06 =
+>   let rt = xLine KR 0.04 4 8 RemoveSynth
+>   in ringz (impulse AR 6 0.3) 2000 rt
diff --git a/Help/UGen/rlpf.help.lhs b/Help/UGen/rlpf.help.lhs
--- a/Help/UGen/rlpf.help.lhs
+++ b/Help/UGen/rlpf.help.lhs
@@ -1,12 +1,23 @@
-> Sound.SC3.UGen.Help.viewSC3Help "RLPF"
-> Sound.SC3.UGen.DB.ugenSummary "RLPF"
+    Sound.SC3.UGen.Help.viewSC3Help "RLPF"
+    Sound.SC3.UGen.DB.ugenSummary "RLPF"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
-> let {n = whiteNoise 'α' AR
->     ;f = sinOsc AR 0.5 0 * 40 + 220
->     ;r = rlpf n f 0.1}
-> in audition (out 0 r)
+> g_01 =
+>   let n = whiteNoise 'α' AR
+>       f = sinOsc AR 0.5 0 * 40 + 220
+>   in rlpf n f 0.1
 
-> 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))
+> g_02 =
+>   let f = fSinOsc KR (xLine KR 0.7 300 20 RemoveSynth) 0 * 3600 + 4000
+>   in rlpf (saw AR 200 * 0.1) f 0.2
+
+> g_03 =
+>   let ctl = rlpf (saw AR 5 * 0.1) 25 0.03
+>   in sinOsc AR (ctl * 200 + 400) 0 * 0.1
+
+> g_04 =
+>   let x = mouseX KR 2 200 Exponential 0.2
+>       y = mouseY KR 0.01 1 Exponential 0.2
+>       ctl = rlpf (saw AR 5 * 0.1) x y
+>   in sinOsc AR (ctl * 200 + 400) 0 * 0.1
diff --git a/Help/UGen/saw.help.lhs b/Help/UGen/saw.help.lhs
--- a/Help/UGen/saw.help.lhs
+++ b/Help/UGen/saw.help.lhs
@@ -1,19 +1,29 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "Saw"
-    > Sound.SC3.UGen.DB.ugenSummary "Saw"
+    Sound.SC3.UGen.Help.viewSC3Help "Saw"
+    Sound.SC3.UGen.DB.ugenSummary "Saw"
 
 > import Sound.SC3 {- hsc3 -}
->
+
+SC3 saw is descending
+
 > g_01 = saw AR (xLine KR 40 4000 6 RemoveSynth) * 0.1
 
+negation is ascending
+
+> g_02 = negate g_01
+
 compare to the non-bandlimited lfSaw
 
-> g_02 = lfSaw AR (xLine KR 40 4000 6 RemoveSynth) 0 * 0.1
+> g_03 = lfSaw AR (xLine KR 40 4000 6 RemoveSynth) 0 * 0.1
 
 Two band limited sawtooth waves thru a resonant low pass filter
 
-> g_03 =
+> g_04 =
 >     let f = xLine KR 8000 400 5 DoNothing
 >     in rlpf (saw AR (mce2 100 250) * 0.1) f 0.05
+
+saw is not useful as a phasor, see lfSaw or phasor
+
+> g_05 = sin (range 0 two_pi (negate (saw AR 440))) * 0.2
 
 Drawings
 
diff --git a/Help/UGen/sawDPW.help.lhs b/Help/UGen/sawDPW.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sawDPW.help.lhs
@@ -0,0 +1,9 @@
+    Sound.SC3.UGen.Help.viewSC3Help "SawDPW"
+    Sound.SC3.UGen.DB.ugenSummary "SawDPW"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 = sawDPW AR (xLine KR 2000 20 10 DoNothing) 0 * 0.1
+
+> g_02 = sawDPW AR (mouseX KR 200 12000 Exponential 0.2) 0 * 0.2
diff --git a/Help/UGen/selectX.help.lhs b/Help/UGen/selectX.help.lhs
--- a/Help/UGen/selectX.help.lhs
+++ b/Help/UGen/selectX.help.lhs
@@ -1,22 +1,21 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SelectX"
-> :t selectX
+    Sound.SC3.UGen.Help.viewSC3Help "SelectX"
+    :t selectX
 
-# composite ugen graph
+selectX is a 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
+> g_01 =
+>   let n = 3/2
+>       f = mce2 440 441
+>       a = mce [sinOsc AR f 0, saw AR f, pulse AR f 0.1]
+>   in mceSum (selectX (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 = mceSum (selectX (lfSaw KR 0.5 0 * c + c) a)
->     ; s = saw AR f * 0.2 }
-> in audition (out 0 s) >> draw s
+> g_02 =
+>   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)
+>   in saw AR f * 0.2
diff --git a/Help/UGen/sendReply.help.lhs b/Help/UGen/sendReply.help.lhs
--- a/Help/UGen/sendReply.help.lhs
+++ b/Help/UGen/sendReply.help.lhs
@@ -1,5 +1,5 @@
-    Sound.SC3.UGen.Help.viewSC3Help "SendReply"
-    Sound.SC3.UGen.DB.ugenSummary "SendReply"
+    > Sound.SC3.UGen.Help.viewSC3Help "SendReply"
+    > Sound.SC3.UGen.DB.ugenSummary "SendReply"
 
 > import Sound.OSC {- hosc3 -}
 > import Sound.SC3 {- hsc3 -}
diff --git a/Help/UGen/shaper.help.lhs b/Help/UGen/shaper.help.lhs
--- a/Help/UGen/shaper.help.lhs
+++ b/Help/UGen/shaper.help.lhs
@@ -2,6 +2,7 @@
     > Sound.SC3.UGen.DB.ugenSummary "Shaper"
 
 > import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.Common.Buffer.Gen as Gen {- hsc3 -}
 
 function to generate wavetable buffer using b_gen_cheby
 
@@ -10,12 +11,12 @@
 >         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]
 
+hear waveshaper at pure (sin) tone
+
 > g_01 =
->     let z = sinOsc AR 300 0 * line KR 0 1 6 RemoveSynth
+>     let z = sinOsc AR 300 0 * line KR 0 1 6 DoNothing
 >     in shaper 10 z * 0.1
 
 plot wavetable (as in-buffer layout, as plain wavetable)
@@ -32,7 +33,7 @@
     > mk_b [0.25,0.5,0.25]
 
 > g_02 =
->     let z = sinOsc AR 400 (pi / 2) * line KR 0 1 6 RemoveSynth
+>     let z = sinOsc AR 400 (pi / 2) * line KR 0 1 6 DoNothing
 >     in shaper 10 z * 0.1
 
 wave shape external signal
@@ -47,6 +48,26 @@
     > mk_b [1,0,1,1,0,1,0.5,0,0.25,0,0.75,1]
 
 > g_04 =
->     let z = soundIn 4
+>     let z = soundIn 0
 >         x = mouseX KR (-1) 1 Linear 0.2
 >     in xFade2 z (shaper 10 z) x 0.5
+
+generate table and use localBuf
+
+> t_01 :: (Enum n,Floating n,Ord n) => [n]
+> t_01 = Gen.cheby 257 [1,0,1,1,0,1] -- [1,0,1,1,0,1,0.5,0,0.25,0,0.75,1]
+
+> t_02 :: (Enum n,Floating n,Ord n) => [n]
+> t_02 = to_wavetable_nowrap t_01
+
+    > plotTable1 t_01
+    > plotTable1 t_02
+    > length t_02 == 512
+
+![](sw/hsc3/Help/SVG/shaper.2.svg)
+![](sw/hsc3/Help/SVG/shaper.3.svg)
+
+> g_05 =
+>     let z = sinOsc AR 300 0 * line KR 0 1 6 DoNothing
+>         b = asLocalBuf 'α' t_02
+>     in shaper b z * 0.1
diff --git a/Help/UGen/sinOsc.help.lhs b/Help/UGen/sinOsc.help.lhs
--- a/Help/UGen/sinOsc.help.lhs
+++ b/Help/UGen/sinOsc.help.lhs
@@ -1,21 +1,29 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "SinOsc"
-    > Sound.SC3.UGen.DB.ugenSummary "SinOsc"
+    Sound.SC3.UGen.Help.viewSC3Help "SinOsc"
+    Sound.SC3.UGen.DB.ugenSummary "SinOsc"
 
 > import Sound.SC3 {- hsc3 -}
 
-Fixed frequency
+Fixed frequency (hz) and initial-phase (radians)
 
-> g_01 = sinOsc AR (midiCPS 69) 0 * 0.25
+> g_00 = sinOsc AR 440 0 * 0.25
 
+Control input for frequency
+
+> g_01 = sinOsc AR (midiCPS (control KR "mnn" 69)) 0 * 0.25
+
+    import Sound.OSC {- hosc -}
+    withSC3 (sendMessage (n_set1 (-1) "mnn" 64))
+
 Modulate freq
 
-> g_02 = sinOsc AR (xLine KR 2000 200 9 RemoveSynth) 0 * 0.5
+> g_02 = sinOsc AR (xLine KR 2000 200 1 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
+>     let f1 = xLine KR 1 1000 9 RemoveSynth
+>         f2 = sinOsc AR f1 0 * 200 + 800 -- (-1,1) ; (-200,200) ; (600,1000)
+>     in sinOsc AR f2 0 * 0.25
 
 Modulate phase
 
@@ -47,7 +55,8 @@
 >     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
+>         i = impulse AR d 0 * max (sinOsc KR 0.05 0 * 0.1) 0
+>     in sinOsc AR (mce2 f0 f1) 0 * 0.1 + i
 
 "When two tones are sounded together, a tone of lower frequency is
 frequently heard. Such a tone is called a combination tone.  The most
@@ -55,7 +64,47 @@
 
 > 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
+>         f2 = 300 * 3/2 {- 450 -}
+>         f3 = abs (f2 - f1) {- 150 -}
+>         a3 = max (sinOsc KR 0.05 0 * 0.1) 0
+>     in mix (sinOsc AR (mce3 f1 f2 f3) 0 * mce3 0.1 0.1 a3)
+
+With frequency of zero, operates as table lookup variant of sin.
+
+> mk_phasor (l,r) f = phasor AR 0 ((r - l) * f / sampleRate) l r l
+
+> g_09 =
+>   let ph = mk_phasor (0,two_pi) 440
+>       o1 = sinOsc AR 440 0
+>       o2 = sinOsc AR 0 ph
+>       o3 = sin ph
+>   in mce2 o1 (xFade2 o2 o3 (lfTri KR 0.1 0) 1) * 0.1
+
+sync, ie. <https://www.listarc.bham.ac.uk/lists/sc-dev/msg58316.html>
+
+> g_10 =
+>   let dt = mce2 1.0 1.003
+>	freq = mouseX KR (100 * dt) (3000 * dt) Exponential 0.2
+>       sync_freq = mouseY KR 100 500 Exponential 0.2
+>       ph_freq = impulse AR sync_freq 0 + impulse AR freq 0
+>       o = sinOsc AR 0 (phasor AR ph_freq (freq / sampleRate) 0 1 0 * 2 * pi)
+>   in o * 0.15
+
+reverse sync
+
+> g_11 =
+>   let dt = mce2 1.0 1.003
+>       freq = mouseX KR (100 * dt) (3000 * dt) Exponential 0.2
+>       sync_freq = mouseY KR 100 500 Exponential 0.2
+>       direction = toggleFF (impulse AR sync_freq 0) * (-2) + 1
+>       o = sinOsc AR 0 (wrap (sweep (impulse AR freq 0) (direction * freq)) 0 (2 * pi))
+>   in o * 0.15
+
+reverse cycle & reverse sync
+
+> g_12 =
+>   let freq = mouseX KR (100 * mce2 1.0 1.003) (3000 * mce2 1.0 1.003) Exponential 0.2
+>       sync_freq = mouseY KR 100 500 Exponential 0.2
+>       direction = toggleFF (impulse AR sync_freq 0 + impulse AR freq 0) * (-2) + 1
+>       o = sinOsc AR 0 (wrap (sweep (k2a 0) (direction * freq)) 0 (2 * pi))
+>   in o * 0.5
diff --git a/Help/UGen/sinOscFB.help.lhs b/Help/UGen/sinOscFB.help.lhs
--- a/Help/UGen/sinOscFB.help.lhs
+++ b/Help/UGen/sinOscFB.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "SinOscFB"
-    > Sound.SC3.UGen.DB.ugenSummary "SinOscFB"
+    Sound.SC3.UGen.Help.viewSC3Help "SinOscFB"
+    Sound.SC3.UGen.DB.ugenSummary "SinOscFB"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/sineShaper.help.lhs b/Help/UGen/sineShaper.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/sineShaper.help.lhs
@@ -0,0 +1,13 @@
+    Sound.SC3.UGen.Help.viewSC3Help "SineShaper"
+    Sound.SC3.UGen.DB.ugenSummary "SineShaper"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+{SineShaper.ar(SinOsc.ar([400, 404], 0, 0.2), MouseX.kr(0, 1))}.play
+
+> g_01 = sineShaper (sinOsc AR (mce2 400 404) 0 * 0.2) (mouseX KR 0 1 Linear 0.2)
+
+{SineShaper.ar(SoundIn.ar, MouseX.kr(0, 1))}.play
+
+> g_02 = sineShaper (soundIn 0) (mouseX KR 0 1 Linear 0.2)
diff --git a/Help/UGen/slew.help.lhs b/Help/UGen/slew.help.lhs
--- a/Help/UGen/slew.help.lhs
+++ b/Help/UGen/slew.help.lhs
@@ -2,10 +2,18 @@
     > 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)
+
+> f_01 s =
+>   let x = mouseX KR 200 12000 Exponential 0.2
+>       y = mouseY KR 200 12000 Exponential 0.2
+>   in slew s x y * 0.15
+
+> g_03 = f_01 (0 - saw AR 440)
+> g_04 = f_01 (lfPulse AR 800 0 0.5)
 
 Drawings
 
diff --git a/Help/UGen/slope.help.lhs b/Help/UGen/slope.help.lhs
--- a/Help/UGen/slope.help.lhs
+++ b/Help/UGen/slope.help.lhs
@@ -2,21 +2,21 @@
     > Sound.SC3.UGen.DB.ugenSummary "Slope"
 
 > import Sound.SC3 {- hsc3 -}
->
-> sig f0 =
+
+> f_01 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
+>     let f = mce (f_01 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))
+    > plot_ugen 0.05 (mce (f_01 2000))
 
 ![](sw/hsc3/Help/SVG/slope.0.svg)
diff --git a/Help/UGen/sms.help.lhs b/Help/UGen/sms.help.lhs
--- a/Help/UGen/sms.help.lhs
+++ b/Help/UGen/sms.help.lhs
@@ -1,12 +1,19 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SMS"
-> Sound.SC3.UGen.DB.ugenSummary "SMS"
+    Sound.SC3.UGen.Help.viewSC3Help "SMS"
+    Sound.SC3.UGen.DB.ugenSummary "SMS"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 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)
+> g_01 =
+>   let z = soundIn 0
+>       y = mouseY KR 1 50 Linear 0.2
+>       x = mouseX KR 0.5 4 Linear 0.2
+>   in sms AR z 50 y 8 0.3 x 0 0 0 1 (-1)
+
+default param
+
+> g_02 =
+>   let z = soundIn 0
+>   in sms AR z 80 80 4 0.2 1 0 0 0 1 (-1)
diff --git a/Help/UGen/softClip.help.lhs b/Help/UGen/softClip.help.lhs
--- a/Help/UGen/softClip.help.lhs
+++ b/Help/UGen/softClip.help.lhs
@@ -2,7 +2,7 @@
     > :t softClip
 
 > import Sound.SC3 {- hsc3 -}
->
+
 > g_01 =
 >     let e = xLine KR 0.1 10 10 RemoveSynth
 >         o = fSinOsc AR 500 0.0
diff --git a/Help/UGen/softClipAmp.help.lhs b/Help/UGen/softClipAmp.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/softClipAmp.help.lhs
@@ -0,0 +1,10 @@
+    Sound.SC3.UGen.Help.viewSC3Help "SoftClipAmp"
+    Sound.SC3.UGen.DB.ugenSummary "SoftClipAmp"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 = softClipAmp4 AR (sinOsc AR 220 0 * 0.1) (mouseX KR 1 16 Linear 0.2)
+
+> g_02 = softClipAmp4 AR (soundIn 0) (mouseX KR 1 8 Linear 0.2)
+
diff --git a/Help/UGen/soundIn.help.lhs b/Help/UGen/soundIn.help.lhs
--- a/Help/UGen/soundIn.help.lhs
+++ b/Help/UGen/soundIn.help.lhs
@@ -6,11 +6,11 @@
 
 copy fifth second channel (index 4) to first output channel (index 0)
 
-> gr_01 = out 0 (soundIn 0)
+> gr_01 = soundIn 0
 
 Copy input from 1 & 0 to outputs 0 & 1.
 
-> gr_02 = out 0 (soundIn (mce2 1 0))
+> gr_02 = soundIn (mce2 1 0)
 
 io matrix:
 
@@ -20,4 +20,4 @@
 2   *
 3       *
 
-> gr_03 = out 0 (soundIn (mce [0, 2, 1, 3]))
+> gr_03 = soundIn (mce [0, 2, 1, 3])
diff --git a/Help/UGen/specCentroid.help.lhs b/Help/UGen/specCentroid.help.lhs
--- a/Help/UGen/specCentroid.help.lhs
+++ b/Help/UGen/specCentroid.help.lhs
@@ -1,14 +1,15 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SpecCentroid"
-> Sound.SC3.UGen.DB.ugenSummary "SpecCentroid"
+    Sound.SC3.UGen.Help.viewSC3Help "SpecCentroid"
+    Sound.SC3.UGen.DB.ugenSummary "SpecCentroid"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
 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)
+
+> g_01 =
+>   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 KR f
+>       p = poll' (impulse KR 1 0) c 0 (label "c")
+>   in sinOsc AR p 0 * 0.1
diff --git a/Help/UGen/specFlatness.help.lhs b/Help/UGen/specFlatness.help.lhs
--- a/Help/UGen/specFlatness.help.lhs
+++ b/Help/UGen/specFlatness.help.lhs
@@ -1,13 +1,14 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SpecFlatness"
-> Sound.SC3.UGen.DB.ugenSummary "SpecFlatness"
+    Sound.SC3.UGen.Help.viewSC3Help "SpecFlatness"
+    Sound.SC3.UGen.DB.ugenSummary "SpecFlatness"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
-> 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)
+> g_01 =
+>   let z = soundIn 0
+>       g = 1 {- gain, set as required -}
+>       a = poll' 1 (wAmp KR z 0.05) 0 (label "a")
+>       f = fft' (localBuf 'α' 2048 1) z
+>       c = poll' 1 (specCentroid KR f) 0 (label "c")
+>       w = poll' 1 (specFlatness KR f) 0 (label "w")
+>   in bpf (pinkNoise 'a' AR) c w * a * g
diff --git a/Help/UGen/squiz.help.lhs b/Help/UGen/squiz.help.lhs
--- a/Help/UGen/squiz.help.lhs
+++ b/Help/UGen/squiz.help.lhs
@@ -1,27 +1,29 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Squiz"
-> Sound.SC3.UGen.DB.ugenSummary "Squiz"
+    Sound.SC3.UGen.Help.viewSC3Help "Squiz"
+    Sound.SC3.UGen.DB.ugenSummary "Squiz"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
+> f_01 zmax s =
+>   let x = mouseX KR 1 10 Exponential 0.2
+>       y = mouseY KR 1 zmax Linear 0.2
+>   in squiz s x y 0.1 * 0.1
+
 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)
+> g_01 = f_01 10 (sinOsc AR 440 0)
 
+> g_02 = f_01 100 (soundIn 0)
+
 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))
+    > let fn = "/home/rohan/data/audio/pf-c5.aif"
+    > let fn = "/home/rohan/opt/src/supercollider/sounds/a11wlk01.wav"
+    > 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)
+> g_03 =
+>   let r = bufRateScale KR 0
+>       p = playBuf 1 AR 0 (r * 0.5) 1 0 Loop DoNothing
+>   in f_01 100 p
diff --git a/Help/UGen/standard2DL.help.lhs b/Help/UGen/standard2DL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/standard2DL.help.lhs
@@ -0,0 +1,19 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Standard2DL"
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> def_k = 1.4
+> def_x0 = 4.9789799812499
+> def_y0 = 5.7473416156381
+
+mouse-controlled param
+
+> g_01 = standard2DL AR 11025 44100 (mouseX KR 0.9 4 Linear 0.2) def_x0 def_y0 * 0.3
+
+as a frequency control
+
+> g_02 =
+>   let x = mouseX KR 0.9 4 Linear 0.2
+>       f = standard2DL AR 10 20 x def_x0 def_y0 * 800 + 900
+>   in sinOsc AR f 0 * 0.3
diff --git a/Help/UGen/standardL.help.lhs b/Help/UGen/standardL.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/standardL.help.lhs
@@ -0,0 +1,15 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "StandardL"
+
+> import Sound.SC3 {- hsc3 -}
+
+vary frequency
+
+> g_01 = standardL AR (mouseX KR 20 sampleRate Linear 0.2) 1 0.5 0 * 0.3
+
+mouse-controlled param
+
+> g_02 = standardL AR (sampleRate / 2) (mouseX KR 0.9 4 Linear 0.2) 0.5 0 * 0.3
+
+as a frequency control
+
+> g_03 = sinOsc AR (standardL AR 40 (mouseX KR 0.9 4 Linear 0.2) 0.5 0 * 800 + 900) 0 * 0.3
diff --git a/Help/UGen/stkBowed.help.lhs b/Help/UGen/stkBowed.help.lhs
--- a/Help/UGen/stkBowed.help.lhs
+++ b/Help/UGen/stkBowed.help.lhs
@@ -1,8 +1,22 @@
-> Sound.SC3.UGen.Help.viewSC3Help "StkBowed"
-> Sound.SC3.UGen.DB.ugenSummary "StkBowed"
+    Sound.SC3.UGen.Help.viewSC3Help "StkBowed"
+    Sound.SC3.UGen.DB.ugenSummary "StkBowed"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
-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))
+...not working...
+
+> g_01 =
+>   let g = toggleFF (impulse KR 1 0)
+>       freq = 220.0
+>       bowpressure = 64.0
+>       bowposition = 64.0
+>       vibfreq = 64.0
+>       vibgain = 64.0
+>       loudness_ = 64.0
+>       gate_ = 1.0
+>       attackrate = 1
+>       decayrate = 1
+>   in stkBowed AR freq bowpressure bowposition vibfreq vibgain loudness_ gate_ attackrate decayrate
+
+<https://ccrma.stanford.edu/software/stk/classstk_1_1Bowed.html>
diff --git a/Help/UGen/stkFlute.help.lhs b/Help/UGen/stkFlute.help.lhs
--- a/Help/UGen/stkFlute.help.lhs
+++ b/Help/UGen/stkFlute.help.lhs
@@ -1,8 +1,24 @@
-> Sound.SC3.UGen.Help.viewSC3Help "StkFlute"
-> Sound.SC3.UGen.DB.ugenSummary "StkFlute"
+    Sound.SC3.UGen.Help.viewSC3Help "StkFlute"
+    Sound.SC3.UGen.DB.ugenSummary "StkFlute"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as External {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.RDU as RDU {- sc3-rdu -}
 
-> 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))
+...not working...
+
+> g_01 =
+>   let freq = 440
+>       jetDelay = 49
+>       noisegain = 0.15
+>       jetRatio = 0.32
+>   in External.stkFlute AR freq jetDelay noisegain jetRatio
+
+> g_02 =
+>   let freq = 440
+>       jetDelay = 49
+>       noisegain = line KR 0.05 0.25 3 DoNothing -- def = 0.15
+>       jetRatio = line KR 0.10 0.60 3 RemoveSynth -- def = 0.32
+>   in External.stkFlute AR freq jetDelay noisegain jetRatio
+
+<https://ccrma.stanford.edu/software/stk/classstk_1_1Flute.html>
diff --git a/Help/UGen/stkMandolin.help.lhs b/Help/UGen/stkMandolin.help.lhs
--- a/Help/UGen/stkMandolin.help.lhs
+++ b/Help/UGen/stkMandolin.help.lhs
@@ -1,24 +1,25 @@
-> Sound.SC3.UGen.Help.viewSC3Help "StkMandolin"
-> Sound.SC3.UGen.DB.ugenSummary "StkMandolin"
-
-> import Control.Monad
-> import Sound.SC3
+    Sound.SC3.UGen.Help.viewSC3Help "StkMandolin"
+    Sound.SC3.UGen.DB.ugenSummary "StkMandolin"
 
-requires "../../rawwaves/mand1.raw"
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as External {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.RDU as RDU {- sc3-rdu -}
 
-> 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))}
+> g_01 =
+>   let x = mouseX KR 0.25 4 Linear 0.2
+>       tr = impulse KR x 0 - 0.5
+>       freq = midiCPS (tRand 'α' 54 66 tr)
+>       [bs, pp, dm, dt, at] = mceChannels (RDU.tRandN 5 'β' 0 127 tr)
+>   in External.stkMandolin AR freq 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))}
+> g_02 =
+>   let x = mouseX KR 3 16 Linear 0.2
+>       tr = impulse KR x 0 - 0.5 -- trig
+>       tr3 = pulseDivider tr 3 0
+>       freq = midiCPS (tiRand 'α' 54 66 tr)
+>       bs = tRand 'β' 72 94 tr3 -- bodysize
+>       pp = tRand 'γ' 32 42 tr3 -- pickposition
+>       dm = tRand 'δ' 64 72 tr3 -- stringdamping
+>       dt = tRand 'ε' 0 4 tr3 -- stringdetune
+>       at = tRand 'ζ' 2 8 tr3 -- aftertouch
+>   in External.stkMandolin AR freq bs pp dm dt at tr
diff --git a/Help/UGen/stkModalBar.help.lhs b/Help/UGen/stkModalBar.help.lhs
--- a/Help/UGen/stkModalBar.help.lhs
+++ b/Help/UGen/stkModalBar.help.lhs
@@ -1,29 +1,31 @@
-> Sound.SC3.UGen.Help.viewSC3Help "StkModalBar"
-> Sound.SC3.UGen.DB.ugenSummary "StkModalBar"
+    Sound.SC3.UGen.Help.viewSC3Help "StkModalBar"
+    Sound.SC3.UGen.DB.ugenSummary "StkModalBar"
 
-> import Control.Monad
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as External {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.RDU as RDU {- sc3-rdu -}
 
-requires "../../rawwaves/marmstk1.raw"
+> g_01 =
+>   let x = mouseX KR 0.25 12 Linear 0.2
+>       tr = impulse KR x 0 - 0.5
+>       tR = tRand 'α' 0 127 tr
+>       i = tRand 'β' 0 9 tr
+>       mn = tiRand 'γ' 25 96 tr
+>       [sh,sp,vg,vf,mx,v] = mceChannels (RDU.tRandN 6 'δ' 0 127 tr)
+>   in External.stkModalBar AR (midiCPS mn) i sh sp vg vf mx v tr
 
-> 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)}
+> g_02 =
+>   let x = mouseX KR 1 12 Linear 0.2
+>       tr = impulse KR x 0 - 0.5
+>       tr3 = pulseDivider tr 3 0
+>       freq = midiCPS (tiRand 'α' 52 64 tr)
+>       instr = 1 -- instrument (0 - 9)
+>       sh = tRand 'β' 10 50 tr3 -- stickhardness
+>       sp = tRand 'γ' 40 80 tr3 -- stickposition
+>       vg = tRand 'δ' 66 98 tr3 -- vibratogain
+>       vf = tRand 'ε' 4 12 tr3 -- vibratofreq
+>       mx = tRand 'ζ' 0 1 tr3 -- directstickmix
+>       v = tRand 'η' 16 48 tr3 -- volume
+>   in External.stkModalBar AR freq instr sh sp vg vf mx v tr
 
-> let {x = mouseX KR 1 6 Linear 0.2
->     ;t = impulse KR x 0 - 0.5
->     ;tr = pulseDivider t 6 0}
-> in do {mn <- 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)}
+<https://ccrma.stanford.edu/software/stk/classstk_1_1ModalBar.html>
diff --git a/Help/UGen/stkShakers.help.lhs b/Help/UGen/stkShakers.help.lhs
--- a/Help/UGen/stkShakers.help.lhs
+++ b/Help/UGen/stkShakers.help.lhs
@@ -2,16 +2,16 @@
     > 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 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as Ext {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.RDU as RDU {- sc3-rdu -}
 
 > 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
+>         instr = tRand 'α' 0 23 tr
+>         [energy,decay,objects,resfreq] = mceChannels (RDU.tRandN 4 'β' 0 127 tr)
+>     in Ext.stkShakers AR instr energy decay objects resfreq
 
-> gr_02 =
->     let tr = impulse KR 1 0 - 0.5
->     in stkShakers AR 4 64 64 64 64 tr
+> gr_02 = Ext.stkShakers AR 4 64 64 64 64
+
+<https://ccrma.stanford.edu/software/stk/classstk_1_1Shakers.html>
diff --git a/Help/UGen/streson.help.lhs b/Help/UGen/streson.help.lhs
--- a/Help/UGen/streson.help.lhs
+++ b/Help/UGen/streson.help.lhs
@@ -1,8 +1,20 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Streson"
-> Sound.SC3.UGen.DB.ugenSummary "Streson"
+    Sound.SC3.UGen.Help.viewSC3Help "Streson"
+    Sound.SC3.UGen.DB.ugenSummary "Streson"
 
-> import Sound.SC3
+    <http://www.csounds.com/manual/html/streson.html>
 
-> 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)
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.DB.External as External {- hsc3 -}
+
+> k_01 = recip (linExp (lfCub KR 0.1 (0.5 * pi)) (-1) 1 280 377)
+
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plot_ugen_nrt (20,1) 16.0 k_01
+
+> f_01 z = External.streson z k_01 0.9 * 0.3
+
+> g_01 = f_01 (lfSaw AR (mce2 220 180) 0 * 0.2)
+
+> g_02 = f_01 (soundIn 0)
+
+see also Sound.SC3.Data.Modal.modal_frequency_ratios
diff --git a/Help/UGen/sum3.help.lhs b/Help/UGen/sum3.help.lhs
--- a/Help/UGen/sum3.help.lhs
+++ b/Help/UGen/sum3.help.lhs
@@ -2,5 +2,9 @@
     > 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
+
+> g_02 = (sinOsc AR 440 0 + sinOsc AR 441 0 + sinOsc AR 442 0) * 0.1
+
+> g_03 = mix (sinOsc AR (mce [440 .. 442]) 0) * 0.1
diff --git a/Help/UGen/sum4.help.lhs b/Help/UGen/sum4.help.lhs
--- a/Help/UGen/sum4.help.lhs
+++ b/Help/UGen/sum4.help.lhs
@@ -2,5 +2,7 @@
     > 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
+
+> g_02 = mix (sinOsc AR (mce [440 .. 443]) 0) * 0.1
diff --git a/Help/UGen/sumSqr.help.lhs b/Help/UGen/sumSqr.help.lhs
--- a/Help/UGen/sumSqr.help.lhs
+++ b/Help/UGen/sumSqr.help.lhs
@@ -1,8 +1,8 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "Operator.sumsqr"
-    > :t sumSqr
+    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
diff --git a/Help/UGen/svf.help.lhs b/Help/UGen/svf.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/svf.help.lhs
@@ -0,0 +1,26 @@
+    Sound.SC3.UGen.Help.viewSC3Help "SVF"
+    Sound.SC3.UGen.DB.ugenSummary "SVF"
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
+
+> g_01 =
+>   let o = lfSaw AR (range 110 35 (lfSaw KR 2 0)) 0
+>       x = mouseX KR 20 20000 Exponential 0.2
+>       y = mouseY KR 1 0 Linear 0.2
+>       k = control KR
+>       low = k "low" 0.1
+>       band = k "band" 0.0
+>       high = k "high" 0.0
+>       notch = k "notch" 0.0
+>       peak_ = k "peak" 0.0
+>   in svf o x y low band high notch peak_
+
+> f_01 k v = withSC3 (sendMessage (n_set1 (-1) k v))
+
+    f_01 "low" 0.1
+    f_01 "band" 0.0
+    f_01 "high" 0.0
+    f_01 "notch" 0.0
+    f_01 "peak" 0.0
diff --git a/Help/UGen/sweep.help.lhs b/Help/UGen/sweep.help.lhs
--- a/Help/UGen/sweep.help.lhs
+++ b/Help/UGen/sweep.help.lhs
@@ -1,64 +1,73 @@
-> Sound.SC3.UGen.Help.viewSC3Help "Sweep"
-> Sound.SC3.UGen.DB.ugenSummary "Sweep"
+    Sound.SC3.UGen.Help.viewSC3Help "Sweep"
+    Sound.SC3.UGen.DB.ugenSummary "Sweep"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
 
 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))
+> g_01 =
+>   let x = mouseX KR 0.5 20 Exponential 0.1
+>       t = impulse KR x 0
+>       f = sweep t 700 + 500
+>   in 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))
+> n_01 = "/home/rohan/data/audio/pf-c5.aif"
 
+> m_01 = b_allocRead 0 n_01 0 0
+
+    > withSC3 (maybe_async m_01)
+
 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))
+> g_02 =
+>   let x = mouseX KR 0.5 20 Exponential 0.1
+>       t = impulse AR x 0
+>       p = sweep t (bufSampleRate KR 0)
+>   in 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))
+> g_03 =
+>   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 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))
+> g_04 =
+>   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 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)
+> g_05 =
+>   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
+>   in sinOsc AR fr 0 * 0.2
 
 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))
+> g_06 =
+>   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 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)]))
+    > import Sound.OSC
+    > withSC3 (sendMessage (n_set (-1) [("st",660),("en",550),("tm",4),("tr",1)]))
+    > withSC3 (sendMessage (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
--- a/Help/UGen/switchDelay.help.lhs
+++ b/Help/UGen/switchDelay.help.lhs
@@ -1,13 +1,18 @@
-> Sound.SC3.UGen.Help.viewSC3Help "SwitchDelay"
-> Sound.SC3.UGen.DB.ugenSummary "SwitchDelay"
+    Sound.SC3.UGen.Help.viewSC3Help "SwitchDelay"
+    Sound.SC3.UGen.DB.ugenSummary "SwitchDelay"
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 simple feedback delay
-> audition (out 0 (switchDelay (soundIn 4) 1 1 1 0.99 20))
 
+> g_01 = switchDelay (soundIn 0) 1 1 1 0.99 20
+
+> g_02 = switchDelay (soundIn 0) 1 0.7 0.4 0.6 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)
+
+> g_03 =
+>   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])
+>   in switchDelay (soundIn 0) 1 0.6 dt 0.7 20
diff --git a/Help/UGen/syncSaw.help.lhs b/Help/UGen/syncSaw.help.lhs
--- a/Help/UGen/syncSaw.help.lhs
+++ b/Help/UGen/syncSaw.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "SyncSaw"
-    > Sound.SC3.UGen.DB.ugenSummary "SyncSaw"
+    Sound.SC3.UGen.Help.viewSC3Help "SyncSaw"
+    Sound.SC3.UGen.DB.ugenSummary "SyncSaw"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/t2K.help.lhs b/Help/UGen/t2K.help.lhs
deleted file mode 100644
--- a/Help/UGen/t2K.help.lhs
+++ /dev/null
@@ -1,22 +0,0 @@
-    > 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/t2a.help.lhs b/Help/UGen/t2a.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/t2a.help.lhs
@@ -0,0 +1,22 @@
+    Sound.SC3.UGen.Help.viewSC3Help "T2A"
+    Sound.SC3.UGen.DB.ugenSummary "T2A"
+
+> 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
+
+> 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/t2k.help.lhs b/Help/UGen/t2k.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/t2k.help.lhs
@@ -0,0 +1,8 @@
+    Sound.SC3.UGen.Help.viewSC3Help "T2K"
+    Sound.SC3.UGen.DB.ugenSummary "T2K"
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>   let tr = t2k (dust 'α' AR 4)
+>   in trig tr 0.1 * sinOsc AR 800 0 * 0.1
diff --git a/Help/UGen/tBetaRand.help.lhs b/Help/UGen/tBetaRand.help.lhs
--- a/Help/UGen/tBetaRand.help.lhs
+++ b/Help/UGen/tBetaRand.help.lhs
@@ -2,7 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "TBetaRand"
 
 > import Sound.SC3 {- hsc3 -}
-> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 > g_01 =
 >     let t = dust 'α' KR 10
@@ -12,8 +12,16 @@
 mouse control of parameters
 
 > g_02 =
->     let t = dust 'α' KR 10
+>     let t = dust 'α' AR 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
+
+...audio rate crashes server...
+
+> g_03 =
+>     let t = dust 'α' AR 100
+>         p1 = mouseX KR 1 5 Linear 0.2
+>         p2 = mouseY KR 1 5 Linear 0.2
+>     in lag (tBetaRand 'β' (-1) 1 p1 p2 t) (10 / 48000)
diff --git a/Help/UGen/tBrownRand.help.lhs b/Help/UGen/tBrownRand.help.lhs
--- a/Help/UGen/tBrownRand.help.lhs
+++ b/Help/UGen/tBrownRand.help.lhs
@@ -2,7 +2,7 @@
     Sound.SC3.UGen.DB.ugenSummary "TBrownRand"
 
 > import Sound.SC3 {- hsc3 -}
-> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
 > g_01 =
 >     let t = dust 'α' KR 10
@@ -17,3 +17,11 @@
 >         o = sinOsc AR f 0
 >         l = tBrownRand 'γ' (-1) 1 1 4 t
 >     in pan2 o l 0.1
+
+audio rate noise
+
+> g_03 =
+>   let x = mouseX KR 500 5000 Exponential 0.2
+>       y = mouseY KR 10 500 Exponential 0.2
+>       t = dust 'α' AR x
+>   in lag (tBrownRand 'β' (-1) 1 0.2 0 t) (y / 48000)
diff --git a/Help/UGen/tGaussRand.help.lhs b/Help/UGen/tGaussRand.help.lhs
--- a/Help/UGen/tGaussRand.help.lhs
+++ b/Help/UGen/tGaussRand.help.lhs
@@ -2,20 +2,17 @@
     Sound.SC3.UGen.DB.ugenSummary "TGaussRand"
 
 > import Sound.SC3 {- hsc3 -}
-> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
-> g_01 =
+> f_01 rand_f =
 >     let t = dust 'α' KR 10
->         f = tGaussRand 'β' 300 3000 t
+>         f = rand_f 'β' 300 3000 t
 >         o = sinOsc AR f 0
->         l = tGaussRand 'γ' (-1) 1 t
->     in  pan2 o l 0.1
+>         l = rand_f 'γ' (-1) 1 t
+>     in pan2 o l 0.1
 
+> g_01 = f_01 tGaussRand
+
 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
+> g_02 = f_01 tRand
diff --git a/Help/UGen/tGrains.help.lhs b/Help/UGen/tGrains.help.lhs
--- a/Help/UGen/tGrains.help.lhs
+++ b/Help/UGen/tGrains.help.lhs
@@ -5,9 +5,12 @@
 
 Load audio (#10) data
 
-    > let fn = "/home/rohan/data/audio/pf-c5.aif"
-    > withSC3 (async (b_allocRead 10 fn 0 0))
+> f_01 = "/home/rohan/data/audio/pf-c5.aif"
 
+> m_01 = b_allocRead 10 f_01 0 0
+
+    > withSC3 (async m_01)
+
 Mouse control
 
 > g_01 =
@@ -54,3 +57,13 @@
 >         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
+
+http://sc-users.bham.ac.narkive.com/sj4Tw3ub/sync-osc#post5
+
+> g_05 =
+>   let b = 10
+>       freq = 100
+>       dur = 2 / freq
+>       clk = impulse AR freq 0
+>       x = mouseX KR 0.5 16 Exponential 0.2
+>   in tGrains 2 clk b x (0.3 * bufDur KR b) dur 0 0.1 2
diff --git a/Help/UGen/tIRand.help.lhs b/Help/UGen/tIRand.help.lhs
deleted file mode 100644
--- a/Help/UGen/tIRand.help.lhs
+++ /dev/null
@@ -1,16 +0,0 @@
-    > 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
--- a/Help/UGen/tRand.help.lhs
+++ b/Help/UGen/tRand.help.lhs
@@ -3,14 +3,14 @@
 
 > import Sound.SC3 {- hsc3 -}
 
-> gr_01 =
+> g_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
+> g_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
+> g_02 = uid_st_eval g_02_m
diff --git a/Help/UGen/tanh.help.lhs b/Help/UGen/tanh.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/tanh.help.lhs
@@ -0,0 +1,9 @@
+    > Sound.SC3.UGen.Help.viewSC3Help "Operator.tanh"
+    > :t tanh
+
+> import Sound.SC3 {- hsc3 -}
+
+> g_01 =
+>     let e = xLine KR 0.1 10 10 DoNothing
+>         o = fSinOsc AR 500 0.0
+>     in tanh (o * e) * 0.25
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/tpv.help.lhs b/Help/UGen/tpv.help.lhs
--- a/Help/UGen/tpv.help.lhs
+++ b/Help/UGen/tpv.help.lhs
@@ -2,16 +2,16 @@
     Sound.SC3.UGen.DB.ugenSummary "TPV"
 
 > import Sound.SC3 {- hsc3 -}
-> import Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- 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)
+> msg = [b_alloc 0 fft_sz 1,b_allocRead 1 fn_1 0 0]
 
-    > withSC3 (do {_ <- async (b_alloc 0 fft_sz 1)
-    >             ;async (b_allocRead 1 fn_1 0 0)})
+    > withSC3 (mapM_ async msg)
 
 > g_01 =
 >     let i = playBuf 1 AR 1 (bufRateScale KR 1) 1 0 Loop DoNothing
diff --git a/Help/UGen/trig1.help.lhs b/Help/UGen/trig1.help.lhs
--- a/Help/UGen/trig1.help.lhs
+++ b/Help/UGen/trig1.help.lhs
@@ -7,3 +7,5 @@
 >     let d = dust 'α' AR 1
 >         o = fSinOsc AR 800 0 * 0.2
 >     in o * trig1 d 0.2
+
+> g_02 = sinOsc AR 440 0 * trig1 (impulse KR 10 0) 0.1 * 0.25
diff --git a/Help/UGen/trigControl.help.lhs b/Help/UGen/trigControl.help.lhs
--- a/Help/UGen/trigControl.help.lhs
+++ b/Help/UGen/trigControl.help.lhs
@@ -21,8 +21,9 @@
 
 Set frequency and the trigger gate.
 
-    > withSC3 (send (n_set1 10 "freq" 2200))
-    > withSC3 (send (n_set1 10 "gate" 1))
+    > import Sound.OSC {- hosc -}
+    > withSC3 (sendMessage (n_set1 10 "freq" 2200))
+    > withSC3 (sendMessage (n_set1 10 "gate" 1))
 
 Make a control rate graph to write freq and gate values.
 
@@ -34,4 +35,4 @@
 
 Map the control values at the audio graph.
 
-    > withSC3 (send (n_map 10 [("freq",0),("gate",1)]))
+    > withSC3 (sendMessage (n_map 10 [("freq",0),("gate",1)]))
diff --git a/Help/UGen/vDiskIn.help.lhs b/Help/UGen/vDiskIn.help.lhs
--- a/Help/UGen/vDiskIn.help.lhs
+++ b/Help/UGen/vDiskIn.help.lhs
@@ -1,8 +1,8 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "VDiskIn"
-    > Sound.SC3.UGen.DB.ugenSummary "VDiskIn"
+    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]
diff --git a/Help/UGen/vOsc.help.lhs b/Help/UGen/vOsc.help.lhs
--- a/Help/UGen/vOsc.help.lhs
+++ b/Help/UGen/vOsc.help.lhs
@@ -1,35 +1,38 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "VOsc"
-    > Sound.SC3.UGen.DB.ugenSummary "VOsc"
+    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]
+> b_flags = [Normalise,Wavetable,Clear]
 > gen_harm i =
->     let n = square (i + 1)
+>     let square a = a * a
+>         n = square (fromIntegral 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'))
+> gen_setup i = (b_alloc i 1024 1,b_gen_sine1 i b_flags (gen_harm i))
 > run_setup (p,q) = (async p >> sendMessage q)
 
-    > withSC3 (mapM_ (run_setup . gen_setup) [0 .. 7])
+    import Sound.SC3.Plot {- hsc3-plot -}
+    plotImpulses [gen_harm 7]
+    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
+> f_01 k n =
+>     let x = mouseX KR k (k + n - 1) Linear 0.1
 >         y = mouseY KR 0.01 0.2 Exponential 0.2
 >     in vOsc AR x (mce [120, 121]) 0 * y
 
+> g_01 = f_01 0 8
+
+    > audition (f_01 0 24)
+
 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])
+    > resetTable i = do {h <- nrrand 12 0 1;sendMessage (b_gen_sine1 i b_flags h)}
+    > withSC3 (mapM_ resetTable [0 .. 7])
diff --git a/Help/UGen/vOsc3.help.lhs b/Help/UGen/vOsc3.help.lhs
--- a/Help/UGen/vOsc3.help.lhs
+++ b/Help/UGen/vOsc3.help.lhs
@@ -7,9 +7,15 @@
 
 oscillator at buffers 0 through 7, mouse selects buffer.
 
-> g_01 =
->     let x = mouseX KR 0 7 Linear 0.1
+> f_01 k0 kN =
+>     let x = mouseX KR k0 (k0 + kN - 1) 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
+
+> g_01 = f_01 0 8
+
+  let k = 0 in audition (f_01 k 24)
+  audition (f_01 0 102)
+  audition (f_01 19 31)
diff --git a/Help/UGen/varLag.help.lhs b/Help/UGen/varLag.help.lhs
--- a/Help/UGen/varLag.help.lhs
+++ b/Help/UGen/varLag.help.lhs
@@ -1,19 +1,45 @@
     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
+The implemented varLag UGen has three inputs: (input, lagTime, start)
 
-> 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
+> g_00 = varLag (lfPulse AR 50 0 0.5) (mouseX KR 0.0 (1/50) Linear 0.2) 0 * 0.2
 
-compare to lag UGen
+> g_01 = varLag (impulse AR 50 0) (mouseX KR 0.0 (1/50) Linear 0.2) 0 * 0.2
 
-> g_02 =
+The varLag_env composite UGen has various odd behaviours
+
+> f_01 f = sinOsc AR (f (exprange 200 400 (lfNoise1 'α' KR 5)) 0.1) 0 * 0.2
+
+> g_02 = f_01 lag
+
+> g_03 = f_01 (\s t -> varLag_env s t (EnvNum 0) s)
+
+> f_02 f =
 >     let x = mouseX KR 220 440 Linear 0.2
->     in sinOsc AR (mce [x, lag x 1]) 0 * 0.1
+>     in sinOsc AR (mce [x, f x 1]) 0 * 0.1
+
+> g_04 = f_02 lag
+
+> g_05 = f_02 (\s t -> varLag_env s t (EnvNum 0) s)
+
+> g_06 =
+>   let fr = range 100 400 (lfPulse KR 1 0 0.5) -- frequency modulator
+>       sh = line KR (-8) 8 15 RemoveSynth -- modulate shape
+>       fr_lag = varLag_env fr 0.2 (EnvNum sh) 0 -- lag the modulator
+>   in sinOsc AR fr_lag 0 * 0.3
+
+as signal filter (step behaviour is wrong?)
+
+> f_03 s =
+>   let x = mouseX KR 0.0001 0.01 Exponential 0.2
+>   in varLag s x s
+
+> g_07 = f_03 (0 - saw AR 440) * 0.15
+> g_08 = f_03 (impulse AR (range 6 24 (lfNoise2 'γ' KR 4)) 0) * 0.5
+
+> g_09 =
+>   let s = varSaw AR 220 0 (range 0 1 (sinOsc KR 0.25 0))
+>   in f_03 s * 0.1
diff --git a/Help/UGen/varSaw.help.lhs b/Help/UGen/varSaw.help.lhs
--- a/Help/UGen/varSaw.help.lhs
+++ b/Help/UGen/varSaw.help.lhs
@@ -1,8 +1,12 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "VarSaw"
-    > Sound.SC3.UGen.DB.ugenSummary "VarSaw"
+    Sound.SC3.UGen.Help.viewSC3Help "VarSaw"
+    Sound.SC3.UGen.DB.ugenSummary "VarSaw"
 
 > import Sound.SC3 {- hsc3 -}
 
+> g_00 =
+>   let x = mouseX KR 0 1 Linear 0.2
+>   in varSaw AR 220 0 x * 0.1
+
 > 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
@@ -28,3 +32,30 @@
 >         o = varSaw AR f 0 w * e * 0.1
 >         l = tRand 'ε' (-1) 1 t
 >     in pan2 o l 1
+
+http://sc-users.bham.ac.narkive.com/sj4Tw3ub/sync-osc#post6
+
+> g_04 =
+>   let freq = control KR "freq" 110
+>       factor = control KR "factor" 1
+>       x = mouseX KR 0 1.0 Linear 0.2
+>       y = mouseY KR (mce2 23 17) 0 Linear 0.2
+>       ph = varSaw AR (freq * factor) 0 x * y
+>   in sinOsc AR (freq * mce2 1.001 1) ph * 0.2
+
+    > import Sound.OSC {- hosc -}
+    > set_factor n = withSC3 (sendMessage (n_set1 (-1) "factor" n))
+    > set_factor 0.125 {- 0.5 1.5 23.0 0.125 1.3 -}
+
+slow indeterminate modulation of width, <http://sccode.org/1-5as>
+
+> g_05 =
+>   let midinote = 60
+>       gate_ = 1
+>       amp = 0.25
+>       asr = envASR 0.1 1 0.1 (EnvNum (-4))
+> 	env = envGen KR gate_ 1 0 1 RemoveSynth asr
+>       freq = midiCPS midinote
+>       width = range 0.2 0.8 (lfNoise2 'β' KR 1) *
+>               range 0.7 0.8 (sinOsc KR 5 (rand 'α' 0.0 1.0))
+>   in varSaw AR freq 0 width * env * amp
diff --git a/Help/UGen/vibrato.help.lhs b/Help/UGen/vibrato.help.lhs
--- a/Help/UGen/vibrato.help.lhs
+++ b/Help/UGen/vibrato.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "Vibrato"
-    > Sound.SC3.UGen.DB.ugenSummary "Vibrato"
+    Sound.SC3.UGen.Help.viewSC3Help "Vibrato"
+    Sound.SC3.UGen.DB.ugenSummary "Vibrato"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/vosim.help.lhs b/Help/UGen/vosim.help.lhs
--- a/Help/UGen/vosim.help.lhs
+++ b/Help/UGen/vosim.help.lhs
@@ -2,14 +2,14 @@
     > Sound.SC3.UGen.DB.ugenSummary "VOSIM"
 
 > import Sound.SC3 {- hsc3 -}
-> import qualified Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins as E {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- 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
+>     in vosim AR trg frq n_cycles dcy * 0.25
 
 > gr_01 =
 >     let p = tRand 'α' 0 1 (impulse AR 6 0)
@@ -27,5 +27,5 @@
 >         l = tR 'ζ' [-1] [1] t
 >         xn = mk_n 'η'
 >         yn = mk_n 'θ'
->         v = E.vosim t (f * x * xn) n (d * y * yn) * a
+>         v = vosim AR 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
--- a/Help/UGen/warp1.help.lhs
+++ b/Help/UGen/warp1.help.lhs
@@ -1,11 +1,14 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "Warp1"
-    > Sound.SC3.UGen.DB.ugenSummary "Warp1"
+    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))
+> fn_01 = "/home/rohan/data/audio/pf-c5.aif"
 
+> m_01 = b_allocRead 10 fn_01 0 0
+
+    withSC3 (async m_01)
+
 > g_01 =
 >     let p = linLin (lfSaw KR 0.05 0) (-1) 1 0 1
 >         x = mouseX KR 0.5 2 Linear 0.1
@@ -13,10 +16,12 @@
 
 real-time (delayed) input
 
-    > withSC3 (async (b_alloc 10 8192 1))
+> m_02 = b_alloc 10 8192 1
 
+    withSC3 (async m_02)
+
 > g_02 =
->     let i = soundIn 4
+>     let i = soundIn 0
 >         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
diff --git a/Help/UGen/waveTerrain.help.lhs b/Help/UGen/waveTerrain.help.lhs
--- a/Help/UGen/waveTerrain.help.lhs
+++ b/Help/UGen/waveTerrain.help.lhs
@@ -2,8 +2,9 @@
     > Sound.SC3.UGen.DB.ugenSummary "WaveTerrain"
 
 > import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Bindings.DB.External {- hsc3 -}
 
-Terrain function
+Terrain function, ie. (x,y) -> z
 
 > ter_f (x,y) =
 >     let a = x ** 2
@@ -25,7 +26,7 @@
 Confirm terrain
 
     import Sound.SC3.Plot {- hsc3-plot -}
-    plot_p3_pt [gen_t ter_f]
+    plot_p3_ln [gen_t ter_f]
 
 Create table.
 
diff --git a/Help/UGen/whiteNoise.help.lhs b/Help/UGen/whiteNoise.help.lhs
--- a/Help/UGen/whiteNoise.help.lhs
+++ b/Help/UGen/whiteNoise.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "WhiteNoise"
-    > Sound.SC3.UGen.DB.ugenSummary "WhiteNoise"
+    Sound.SC3.UGen.Help.viewSC3Help "WhiteNoise"
+    Sound.SC3.UGen.DB.ugenSummary "WhiteNoise"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/wrapIndex.help.lhs b/Help/UGen/wrapIndex.help.lhs
--- a/Help/UGen/wrapIndex.help.lhs
+++ b/Help/UGen/wrapIndex.help.lhs
@@ -1,16 +1,9 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "WrapIndex"
-    > Sound.SC3.UGen.DB.ugenSummary "WrapIndex"
+    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
diff --git a/Help/UGen/xFade2.help.lhs b/Help/UGen/xFade2.help.lhs
--- a/Help/UGen/xFade2.help.lhs
+++ b/Help/UGen/xFade2.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "XFade2"
-    > Sound.SC3.UGen.DB.ugenSummary "XFade2"
+    Sound.SC3.UGen.Help.viewSC3Help "XFade2"
+    Sound.SC3.UGen.DB.ugenSummary "XFade2"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/xLine.help.lhs b/Help/UGen/xLine.help.lhs
--- a/Help/UGen/xLine.help.lhs
+++ b/Help/UGen/xLine.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "XLine"
-    > Sound.SC3.UGen.DB.ugenSummary "XLine"
+    Sound.SC3.UGen.Help.viewSC3Help "XLine"
+    Sound.SC3.UGen.DB.ugenSummary "XLine"
 
 Note: SC3 reorders mul and add inputs to precede the doneAction input.
 
diff --git a/Help/UGen/xOut.help.lhs b/Help/UGen/xOut.help.lhs
--- a/Help/UGen/xOut.help.lhs
+++ b/Help/UGen/xOut.help.lhs
@@ -1,5 +1,5 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "XOut"
-    > Sound.SC3.UGen.DB.ugenSummary "XOut"
+    Sound.SC3.UGen.Help.viewSC3Help "XOut"
+    Sound.SC3.UGen.DB.ugenSummary "XOut"
 
 > import Sound.SC3 {- hsc3 -}
 
diff --git a/Help/UGen/zeroCrossing.help.lhs b/Help/UGen/zeroCrossing.help.lhs
--- a/Help/UGen/zeroCrossing.help.lhs
+++ b/Help/UGen/zeroCrossing.help.lhs
@@ -1,8 +1,12 @@
-    > Sound.SC3.UGen.Help.viewSC3Help "ZeroCrossing"
-    > Sound.SC3.UGen.DB.ugenSummary "ZeroCrossing"
+    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]
+
+> g_02 =
+>     let a = soundIn 0
+>     in mce [a, sinOsc AR (zeroCrossing a) 0 * 0.1]
diff --git a/Help/UGen/zitaRev.help.lhs b/Help/UGen/zitaRev.help.lhs
new file mode 100644
--- /dev/null
+++ b/Help/UGen/zitaRev.help.lhs
@@ -0,0 +1,49 @@
+http://kokkinizita.linuxaudio.org/linuxaudio/zita-rev1-doc/quickguide.html
+
+> import Sound.SC3 {- hsc3 -}
+> import qualified Sound.SC3.UGen.Bindings.HW.External.Zita as Zita {- hsc3 -}
+
+    > Zita.zitaRev_param
+
+mostly default settings
+
+> g_01 =
+>     let i = soundIn 0
+>         in_delay = 60
+>         eq1_freq = 315
+>         eq2_freq = 1500
+>         dry_wet_mix = 0.5
+>         level = 0
+>     in Zita.zitaRev i i in_delay 200 3 2 6000 eq1_freq 0 eq2_freq 0 dry_wet_mix level
+
+longer
+
+> g_02 =
+>     let i = soundIn 0
+>         in_delay = 80
+>         low_rt60 = 6
+>         mid_rt60 = 4
+>         eq1_freq = 190
+>         eq1_level = -6
+>         eq2_freq = 3500
+>         eq2_level = 6
+>         dry_wet_mix = 0
+>         level = 0
+>     in Zita.zitaRev i i in_delay 200 low_rt60 mid_rt60 6000 eq1_freq eq1_level eq2_freq eq2_level dry_wet_mix level
+
+longer still
+
+> g_03 =
+>     let i = soundIn 0
+>         in_delay = 100
+>         low_rt60 = 6
+>         mid_rt60 = 8
+>         eq1_freq = 190
+>         eq1_level = -6
+>         eq2_freq = 3500
+>         eq2_level = 6
+>         dry_wet_mix = 0.5
+>         level = 0.0
+>     in Zita.zitaRev i i in_delay 200 low_rt60 mid_rt60 6000 eq1_freq eq1_level eq2_freq eq2_level dry_wet_mix level
+
+
diff --git a/Help/UGen/zitaRev1.help.lhs b/Help/UGen/zitaRev1.help.lhs
deleted file mode 100644
--- a/Help/UGen/zitaRev1.help.lhs
+++ /dev/null
@@ -1,35 +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 {- 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
@@ -10,15 +10,21 @@
 
 There are a number of related projects:
 
-- [hsc3-dot](?t=hsc3-dot): UGen Graph Drawing
-- [hsc3-graphs](?t=hsc3-graphs): UGen Graphs
-- [hsc3-lang](?t=hsc3-lang): SC3 Language
-- [hsc3-cairo](?t=hsc3-cairo) & [hsc3-plot](?t=hsc3-plot): Drawing & Plotting
-- [hsc3-rec](?t=hsc3-rec) & [hsc3-unsafe](?t=hsc3-rec): UGen Variants
-- [hsc3-db](?t=hsc3-db): UGen Database
-- [hsc3-rw](?t=hsc3-rw): UGen Graph Re-writing
-- [hsc3-forth](?t=hsc3-forth): FORTH SuperCollider
-- [hsc3-lisp](?t=hsc3-lisp): LISP SuperCollider
+- [hsc3-dot](?t=hsc3-dot): UGen graph drawing (2006)
+- [hsc3-graphs](?t=hsc3-graphs): UGen graph collection (2006)
+- [hsc3-db](?t=hsc3-db): UGen Database (2006)
+- [hsc3-sf](?t=hsc3-sf): Sound file IO (2006)
+- [hsc3-unsafe](?t=hsc3-unsafe): Unsafe UGen variants (2006)
+- [hsc3-lang](?t=hsc3-lang): SC3 language (2007)
+- [hsc3-rec](?t=hsc3-rec): Record UGens (2008)
+- [hsc3-sf-hsndfile](?t=hsc3-sf): Sound file IO (libsndfile) (2010)
+- [hsc3-auditor](?t=hsc3-auditor): Simple-minded auditioner (2010)
+- [hsc3-cairo](?t=hsc3-cairo): Drawing (2012)
+- [hsc3-plot](?t=hsc3-plot): Plotting (2013)
+- [hsc3-data](?t=hsc3-data): Data formats &etc. (2013)
+- [hsc3-rw](?t=hsc3-rw): UGen Graph Re-writing (2013)
+- [hsc3-forth](?t=hsc3-forth): FORTH SuperCollider (2014)
+- [hsc3-lisp](?t=hsc3-lisp): LISP SuperCollider (2014)
 
 The hsc3 interaction environment ([hsc3.el](?t=hsc3&e=emacs/hsc3.el))
 is written for [GNU][gnu] [Emacs][emacs].
@@ -30,7 +36,7 @@
 [scsynth](?t=hsc3&e=md/scsynth.md),
 [setup](?t=hsc3&e=md/setup.md)
 
-© [rohan drape][rd] and others, 2005-2017, [gpl][gpl].
+© [rohan drape][rd] and others, 2005-2018, [gpl][gpl].
 with contributions by:
 
 - henning thielemann
@@ -39,19 +45,18 @@
 - brent yorgey
 - shae erisson
 
-see the [darcs][darcs] [history](?t=hsc3&q=history) for details
+see the [git](https://git-scm.com/) [history](?t=hsc3&q=history) for details
 
 initial announcement:
 [[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
+[rd]: http://rohandrape.net/
+[hsc3]: http://rohandrape.net/?t=hsc3
 [hs]: http://haskell.org/
 [sc3]: http://audiosynth.com/
-[tutorial]: http://rd.slavepianos.org/?t=hsc3-texts&e=lhs/hsc3-tutorial.lhs
-[hsc3-texts]: http://rd.slavepianos.org/?t=hsc3-texts
+[tutorial]: http://rohandrape.net/?t=hsc3-texts&e=lhs/hsc3-tutorial.lhs
+[hsc3-texts]: http://rohandrape.net/?t=hsc3-texts
 [gnu]: http://gnu.org/
 [emacs]: http://gnu.org/software/emacs/
-[darcs]: http://darcs.net/
 [gpl]: http://gnu.org/copyleft/
diff --git a/Sound/SC3/Common.hs b/Sound/SC3/Common.hs
--- a/Sound/SC3/Common.hs
+++ b/Sound/SC3/Common.hs
@@ -1,6 +1,8 @@
+-- | Composite of SC3.Common sub-modules.
 module Sound.SC3.Common (module M) where
 
 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
+import Sound.SC3.Common.UId as M
diff --git a/Sound/SC3/Common/Base.hs b/Sound/SC3/Common/Base.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Base.hs
@@ -0,0 +1,204 @@
+-- | Common core functions.
+module Sound.SC3.Common.Base where
+
+import Data.Char {- base -}
+import Data.List {- base -}
+
+-- * Function
+
+-- | Unary function.
+type Fn1 a b = a -> b
+
+-- | Binary function.
+type Fn2 a b c = a -> b -> c
+
+-- | Ternary function.
+type Fn3 a b c d = a -> b -> c -> d
+
+-- | Quaternary function.
+type Fn4 a b c d e = a -> b -> c -> d -> e
+
+-- * Read
+
+-- | 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
+
+-- | Left to right composition of a list of functions.
+--
+-- > compose_l [(* 2),(+ 1)] 3 == 7
+compose_l :: [t -> t] -> t -> t
+compose_l = flip (foldl (\x f -> f x))
+
+-- | Right to left composition of a list of functions.
+--
+-- > compose_r [(* 2),(+ 1)] 3 == 8
+compose_r :: [t -> t] -> t -> t
+compose_r = flip (foldr (\f x -> f x))
+
+{- | SequenceableCollection.differentiate
+
+> > [3,4,1,1].differentiate == [3,1,-3,0]
+
+> d_dx [3,4,1,1] == [3,1,-3,0]
+> d_dx [0,1,3,6] == [0,1,2,3]
+-}
+d_dx :: (Num a) => [a] -> [a]
+d_dx l = zipWith (-) l (0:l)
+
+{- | Variant that does not prepend zero to input, ie. 'tail' of 'd_dx'.
+
+> d_dx' [3,4,1,1] == [1,-3,0]
+> d_dx' [0,1,3,6] == [1,2,3]
+-}
+d_dx' :: Num n => [n] -> [n]
+d_dx' l = zipWith (-) (tail l) l
+
+{- | SequenceableCollection.integrate
+
+> > [3,4,1,1].integrate == [3,7,8,9]
+
+> dx_d [3,4,1,1] == [3,7,8,9]
+> 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 (+)
+
+{- | Variant pre-prending zero to output.
+
+> dx_d' [3,4,1,1] == [0,3,7,8,9]
+> 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 :) . dx_d
+
+-- | '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
+
+-- | Zip two 4-tuples.
+p4_zip :: (a,b,c,d) -> (e,f,g,h) -> ((a,e),(b,f),(c,g),(d,h))
+p4_zip (a,b,c,d) (e,f,g,h) = ((a,e),(b,f),(c,g),(d,h))
+
+-- | Two-tuple.
+type T2 a = (a,a)
+
+-- | Three-tuple.
+type T3 a = (a,a,a)
+
+-- | Four-tuple.
+type T4 a = (a,a,a,a)
+
+-- | t -> (t,t)
+dup2 :: t -> T2 t
+dup2 t = (t,t)
+
+-- | t -> (t,t,t)
+dup3 :: t -> T3 t
+dup3 t = (t,t,t)
+
+-- | t -> (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])
+
+-- | [x,y] -> (x,y)
+t2_from_list :: [t] -> T2 t
+t2_from_list l = case l of {[p,q] -> (p,q);_ -> error "t2_from_list"}
diff --git a/Sound/SC3/Common/Buffer.hs b/Sound/SC3/Common/Buffer.hs
--- a/Sound/SC3/Common/Buffer.hs
+++ b/Sound/SC3/Common/Buffer.hs
@@ -82,7 +82,7 @@
 
 -- | 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)
+normalise_rng (il,ir) (l,r) = map (\e -> S.sc3_linlin e il ir l r)
 
 -- | @ArrayedCollection.normalize@ returns a new Array with the receiver
 -- items normalized between min and max.
@@ -147,9 +147,15 @@
 > 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 =
+to_wavetable  = to_wavetable_nowrap . (++ [0])
+
+-- | Shaper requires wavetables without wrap.
+--
+-- > to_wavetable_nowrap [0,0.5,1,0.5] == [-0.5,0.5,0,0.5,1.5,-0.5]
+to_wavetable_nowrap :: Num a => [a] -> [a]
+to_wavetable_nowrap =
     let f (e0,e1) = (2 * e0 - e1,e1 - e0)
-    in t2_concat . map f . t2_overlap . (++ [0])
+    in t2_concat . map f . t2_overlap
 
 {- | Variant of 'sineFill' that gives each component table.
 
diff --git a/Sound/SC3/Common/Buffer/Gen.hs b/Sound/SC3/Common/Buffer/Gen.hs
--- a/Sound/SC3/Common/Buffer/Gen.hs
+++ b/Sound/SC3/Common/Buffer/Gen.hs
@@ -6,8 +6,8 @@
 
 import Data.List {- base -}
 
-import Sound.SC3.Common.Buffer {- hsc3 -}
-import Sound.SC3.Common.Math {- hsc3 -}
+import qualified Sound.SC3.Common.Buffer as Buffer {- hsc3 -}
+import qualified Sound.SC3.Common.Math as Math {- hsc3 -}
 
 -- | Sum (mix) multiple tables into one.
 sum_l :: Num n => [[n]] -> [n]
@@ -15,48 +15,65 @@
 
 -- | Unit normalisation.
 nrm_u :: (Fractional n,Ord n) => [n] -> [n]
-nrm_u = normalize (-1) 1
+nrm_u = Buffer.normalize (-1) 1
 
 -- * sine1
 
+-- | 'sine3_p' with zero phase.
+--
+-- > import Sound.SC3.Plot {- hsc3-plot -}
+-- > plotTable1 (sine1_p 512 (1,1))
 sine1_p :: (Enum n,Floating n) => Int -> (n,n) -> [n]
 sine1_p n (pfreq,ampl) = sine3_p n (pfreq,ampl,0)
 
+-- | Series of sine wave harmonics using specified amplitudes.
 sine1_l :: (Enum n,Floating n) => Int -> [n] -> [[n]]
 sine1_l n ampl = map (sine1_p n) (zip [1..] ampl)
 
--- > import Sound.SC3.Plot
+-- | 'sum_l' of 'sine1_l'.
+--
+-- > import Sound.SC3.Plot {- hsc3-plot -}
 -- > plotTable1 (sine1 256 [1,0.95 .. 0.5])
 sine1 :: (Enum n,Floating n) => Int -> [n] -> [n]
 sine1 n = sum_l . sine1_l n
 
+-- | 'nrm_u' of 'sine1_l'.
+--
 -- > 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
 
+-- | Series of /n/ sine wave partials using specified frequencies and amplitudes.
 sine2_l :: (Enum n,Floating n) => Int -> [(n,n)] -> [[n]]
 sine2_l n = map (sine1_p n)
 
+-- | 'sum_l' of 'sine2_l'.
+--
 -- > 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
 
+-- | 'nrm_u' of 'sine2_l'.
 sine2_nrm :: (Enum n,Floating n,Ord n) => Int -> [n] -> [n]
 sine2_nrm n = nrm_u . sine1 n
 
 -- * sine3
 
+-- | Sine wave table at specified frequency, amplitude and phase.
 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
+    let incr = (Math.two_pi / (fromIntegral n - 1)) * pfreq
     in map ((*) ampl . sin) (take n [phase,phase + incr ..])
 
+-- | 'map' of 'sine3_p'.
 sine3_l :: (Enum n,Floating n) => Int -> [(n,n,n)] -> [[n]]
 sine3_l n = map (sine3_p n)
 
+-- | 'sum_l' of 'sine3_l'.
+--
 -- > 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
@@ -78,5 +95,6 @@
         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..]
 
+-- | Type specialised 'gen_cheby'.
 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
--- a/Sound/SC3/Common/Buffer/Vector.hs
+++ b/Sound/SC3/Common/Buffer/Vector.hs
@@ -1,12 +1,12 @@
 -- | 'V.Vector' variants of "Sound.SC3.Common.Buffer".
 module Sound.SC3.Common.Buffer.Vector where
 
-import qualified Data.Vector as V {- vector -}
+import qualified Data.Vector.Storable as V {- vector -}
 
 import qualified Sound.SC3.Common.Buffer as C {- hsc3 -}
 
 -- | 'C.clipAt'.
-clipAt :: Int -> V.Vector a -> a
+clipAt :: V.Storable t => Int -> V.Vector t -> t
 clipAt ix c =
     let r = V.length c
         f = (V.!) c
@@ -17,14 +17,23 @@
 -- > 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 :: (V.Storable t,RealFrac t) => t -> V.Vector t -> t
 blendAt = C.blendAtBy clipAt
 
+-- | 'C.from_wavetable'
+--
+-- > from_wavetable (V.fromList [-0.5,0.5,0,0.5,1.5,-0.5,1,-0.5])
+from_wavetable :: (V.Storable t,Num t) => V.Vector t -> V.Vector t
+from_wavetable wt =
+  let n = V.length wt
+      f k = let k2 = k * 2 in (wt V.! k2) + (wt V.! (k2 + 1))
+  in V.generate (n `div` 2) f
+
 -- | '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 :: (V.Storable t,RealFrac t) => Int -> V.Vector t -> V.Vector t
 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
--- a/Sound/SC3/Common/Envelope.hs
+++ b/Sound/SC3/Common/Envelope.hs
@@ -4,7 +4,7 @@
 import Data.List {- base -}
 import Data.Maybe {- base -}
 
-import qualified Sound.SC3.Common.Prelude as P
+import qualified Sound.SC3.Common.Base as Base
 import qualified Sound.SC3.Common.Math.Interpolate as I
 
 -- * Curve
@@ -22,13 +22,13 @@
                         deriving (Eq, Show)
 
 -- | Envelope curve pair.
-type Envelope_Curve2 a = P.T2 (Envelope_Curve a)
+type Envelope_Curve_2 a = Base.T2 (Envelope_Curve a)
 
 -- | Envelope curve triple.
-type Envelope_Curve3 a = P.T3 (Envelope_Curve a)
+type Envelope_Curve_3 a = Base.T3 (Envelope_Curve a)
 
 -- | Envelope curve quadruple.
-type Envelope_Curve4 a = P.T4 (Envelope_Curve a)
+type Envelope_Curve_4 a = Base.T4 (Envelope_Curve a)
 
 -- | Convert 'Envelope_Curve' to shape value.
 --
@@ -92,18 +92,19 @@
              ,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
+             ,env_offset :: a -- ^ An offset for all time values (IEnvGen only)
              }
     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
+    let Envelope l t c rn ln os = e
+    in Envelope (map f l) (map f t) (map (env_curve_coerce f) c) rn ln (f os)
 
 -- | 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
+envelope :: Num a => [a] -> [a] -> [Envelope_Curve a] -> Envelope a
+envelope l t c = Envelope l t c Nothing Nothing 0
 
 -- | Duration of 'Envelope', ie. 'sum' '.' 'env_times'.
 envelope_duration :: Num n => Envelope n -> n
@@ -116,7 +117,7 @@
 -- | 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)
+    let d = Base.dx_d (env_times e)
     in findIndex (>= t) d
 
 -- | A set of start time, start level, end time, end level and curve.
@@ -129,7 +130,7 @@
         t = env_times e
         x0 = l !! i
         x1 = l !! (i + 1)
-        t0 = (0 : P.dx_d t) !! i
+        t0 = (0 : Base.dx_d t) !! i
         t1 = t0 + t !! i
         c = envelope_curves e !! i
     in (t0,x0,t1,x1,c)
@@ -164,7 +165,7 @@
         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
+         Envelope _ _ _ Nothing Nothing  os -> Envelope l t c Nothing Nothing os
          _ -> error "envelope_normalise: has release or loop node..."
 
 -- | Get value for 'Envelope' at time /t/, or zero if /t/ is out of
@@ -183,15 +184,15 @@
       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 :: (Ord t, Floating t, Enum t) => Int -> Envelope t -> [(t,t)]
 envelope_render n e =
     let d = envelope_duration e
-        k = d / (n - 1)
+        k = d / (fromIntegral 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 :: (Ord t, Floating t, Enum t) => Int -> Envelope t -> [t]
 envelope_table n = map snd . envelope_render n
 
 -- | Variant on 'env_curves' that expands the, possibly empty, user
@@ -216,7 +217,7 @@
 -- > 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
+    let Envelope l t _ rn ln _ = e
         n = length t
         n' = fromIntegral n
         rn' = fromIntegral (fromMaybe (-99) rn)
@@ -227,7 +228,7 @@
          l0:l' -> Just (l0 : n' : rn' : ln' : concat (zipWith3 f l' t c))
          _ -> Nothing
 
--- | @IEnvGen@ SC3 form of 'Envelope' data.  Offset not supported (zero).
+-- | @IEnvGen@ SC3 form of 'Envelope' data.
 --
 -- > let {l = [0,0.6,0.3,1.0,0]
 -- >     ;t = [0.1,0.02,0.4,1.1]
@@ -237,47 +238,52 @@
 -- > 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
+    let Envelope l t _ _ _ os = 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))
+         l0:l' -> Just (os : 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.
+-- | Delay the onset of the envelope (add initial segment).
 env_delay :: Envelope a -> a -> Envelope a
-env_delay (Envelope l t c rn ln) d =
+env_delay (Envelope l t c rn ln os) 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'
+    in Envelope l' t' c' rn' ln' os
 
 -- | 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
+-- z is a value that is first zero and thereafter one.
+-- tc & cc are time and curve from first to last.
+env_circle_z :: Fractional a => a -> a -> Envelope_Curve a -> Envelope a -> Envelope a
+env_circle_z z tc cc (Envelope l t c rn _ os) =
+    let n = length t
     in case rn of
          Nothing -> let l' = 0 : l ++ [0]
-                        t' = z * tc : t ++ [9e8]
+                        t' = z * tc : t ++ [1] -- inf (but drawings are poor)
                         c' = cc : take n (cycle c) ++ [EnvLin]
                         rn' = Just (n + 1)
-                    in Envelope l' t' c' rn' (Just 0)
+                    in Envelope l' t' c' rn' (Just 0) os
          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)
+                   in  Envelope l' t' c' rn' (Just 0) os
 
+-- | env_circle_z with cycle time of zero.
+env_circle_0 :: Fractional a => Envelope a -> Envelope a
+env_circle_0 = env_circle_z 1 0 EnvLin
+
 -- * Construct
 
 {- | Trapezoidal envelope generator.
@@ -303,31 +309,41 @@
 {- | 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]
+> 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
+envCoord :: Num n => [(n,n)] -> n -> n -> Envelope_Curve n -> Envelope n
+envCoord xy dur amp c =
+    let n = length xy
+        (times,levels) = unzip xy
+        times' = map (* dur) (Base.d_dx' times)
+        levels' = map (* amp) levels
+        offset = times' !! 0
+    in Envelope levels' times' (replicate (n - 1) c) Nothing Nothing offset
 
+-- | Segments given as pairs of (time,level).
+--   The input is sorted by time before processing.
+--
+-- > envPairs [(0, 1), (3, 1.4), (2.1, 0.5)] EnvSin
+envPairs :: (Num n,Ord n) => [(n,n)] -> Envelope_Curve n -> Envelope n
+envPairs xy c = envCoord (sortOn fst xy) 1 1 c
+
 -- | 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) =
+envPerc_c :: Num a => a -> a -> a -> Envelope_Curve_2 a -> Envelope a
+envPerc_c atk rls lvl (c0,c1) =
     let c = [c0,c1]
-    in Envelope [0,lvl,0] [atk,rls] c Nothing Nothing
+    in Envelope [0,lvl,0] [atk,rls] c Nothing Nothing 0
 
 -- | 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)
+    in envPerc_c atk rls 1 (cn,cn)
 
 -- | Triangular envelope, with duration and level inputs.
 --
@@ -337,7 +353,7 @@
 envTriangle dur lvl =
     let c = replicate 2 EnvLin
         d = replicate 2 (dur / 2)
-    in Envelope [0,lvl,0] d c Nothing Nothing
+    in Envelope [0,lvl,0] d c Nothing Nothing 0
 
 -- | Sine envelope, with duration and level inputs.
 --
@@ -347,26 +363,30 @@
 envSine dur lvl =
     let c = replicate 2 EnvSin
         d = replicate 2 (dur / 2)
-    in Envelope [0,lvl,0] d c Nothing Nothing
+    in Envelope [0,lvl,0] d c Nothing Nothing 0
 
 -- | 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}
+                     ,linen_curve :: Envelope_Curve_3 a}
 
+-- | SC3 defaults for LINEN.
+linen_def :: Fractional t => LINEN t
+linen_def = let c = EnvLin in LINEN 0.01 1 1 1 (c,c,c)
+
 -- | 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
+    in Envelope l t c Nothing Nothing 0
 
 -- | 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)
+envLinen_c :: Num a => a -> a -> a -> a -> Envelope_Curve_3 a -> Envelope a
+envLinen_c aT sT rT lv c = envLinen_r (LINEN aT sT rT lv c)
 
 -- | Linear envelope parameter constructor.
 --
@@ -375,9 +395,9 @@
 -- >     ;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 =
+envLinen aT sT rT lv =
     let c = (EnvLin,EnvLin,EnvLin)
-    in envLinen' aT sT rT l c
+    in envLinen_c aT sT rT lv c
 
 -- | Parameters for ADSR envelopes.
 --   The sustain level is given as a proportion of the peak level.
@@ -386,19 +406,20 @@
                    ,adsr_sustainLevel :: a
                    ,adsr_releaseTime :: a
                    ,adsr_peakLevel :: a
-                   ,adsr_curve :: Envelope_Curve3 a
+                   ,adsr_curve :: Envelope_Curve_3 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
+-- | SC3 defaults for ADSR.
+adsr_def :: Fractional n => ADSR n
+adsr_def = 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
+-- | Variant with defaults for pL, c and b.
+envADSR_def :: Num a => a -> a -> a -> a -> Envelope a
+envADSR_def 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
@@ -406,7 +427,7 @@
     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
+    in Envelope l t c (Just 2) Nothing 0
 
 -- | Parameters for Roland type ADSSR envelopes.
 data ADSSR a = ADSSR {adssr_attackTime :: a
@@ -416,7 +437,7 @@
                      ,adssr_slopeTime :: a
                      ,adssr_sustainLevel :: a
                      ,adssr_releaseTime :: a
-                     ,adssr_curve :: Envelope_Curve4 a
+                     ,adssr_curve :: Envelope_Curve_4 a
                      ,adssr_bias :: a}
 
 -- | Attack, decay, slope, sustain, release envelope parameter constructor.
@@ -429,16 +450,20 @@
     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
+    in Envelope l t c (Just 3) Nothing 0
 
 -- | Parameters for ASR envelopes.
 data ASR a = ASR {asr_attackTime :: a
                  ,asr_sustainLevel :: a
                  ,asr_releaseTime :: a
-                 ,asr_curve :: Envelope_Curve2 a}
+                 ,asr_curve :: Envelope_Curve_2 a}
 
+-- | SC3 default values for ASR.
+asr_def :: Fractional t => ASR t
+asr_def = let c = EnvNum (-4) in ASR 0.01 1 1 (c,c)
+
 -- | SC3 .asr has singular curve argument, hence _c suffix.
-envASR_c :: Num a => a -> a -> a -> Envelope_Curve2 a -> Envelope a
+envASR_c :: Num a => a -> a -> a -> Envelope_Curve_2 a -> Envelope a
 envASR_c aT sL rT c = envASR_r (ASR aT sL rT c)
 
 -- | Attack, sustain, release envelope parameter constructor.
@@ -455,12 +480,24 @@
     let l = [0,sL,0]
         t = [aT,rT]
         c' = [c0,c1]
-    in Envelope l t c' (Just 1) Nothing
+    in Envelope l t c' (Just 1) Nothing 0
 
 -- | All segments are horizontal lines.
-envStep :: [a] -> [a] -> Maybe Int -> Maybe Int -> Envelope a
+envStep :: Num a => [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
+         in Envelope levels' times [EnvStep] releaseNode loopNode 0
+
+-- | Segments given as triples of (time,level,curve).  The final curve
+-- is ignored. The input is sorted by time before processing.
+--
+-- > envXYC [(0, 1, EnvSin), (3, 1.4, EnvLin), (2.1, 0.5, EnvLin)]
+envXYC :: (Num n,Ord n) => [(n,n,Envelope_Curve n)] -> Envelope n
+envXYC xyc =
+  let n = length xyc
+      xyc_asc = sortOn (\(x,_,_) -> x) xyc
+      (times,levels,curves) = unzip3 xyc_asc
+      offset = times !! 0
+  in Envelope levels (Base.d_dx' times) (take (n - 1) curves) Nothing Nothing offset
diff --git a/Sound/SC3/Common/Math.hs b/Sound/SC3/Common/Math.hs
--- a/Sound/SC3/Common/Math.hs
+++ b/Sound/SC3/Common/Math.hs
@@ -1,7 +1,11 @@
+-- | Common math functions.
 module Sound.SC3.Common.Math where
 
-import qualified Data.Fixed as F {- base -}
+import Data.Fixed {- base -}
 import Data.Maybe {- base -}
+import Data.Ratio {- base -}
+import Numeric {- base -}
+import Text.Read {- base -}
 
 -- | Half pi.
 --
@@ -16,35 +20,42 @@
 two_pi = 2 * pi
 
 -- | Multiply and add, ordinary haskell argument order.
--- 'mul_add' is a method of the 'MulAdd' class.
+-- See also 'mul_add' 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
+-- | 'fromInteger' of 'truncate'.
+sc3_truncate :: RealFrac a => a -> a
+sc3_truncate = fromInteger . truncate
 
-sc_round :: RealFrac a => a -> a
-sc_round = fromInteger . round
+-- | 'fromInteger' of 'round'.
+sc3_round :: RealFrac a => a -> a
+sc3_round = fromInteger . round
 
-sc_ceiling :: RealFrac a => a -> a
-sc_ceiling = fromInteger . ceiling
+-- | 'fromInteger' of 'ceiling'.
+sc3_ceiling :: RealFrac a => a -> a
+sc3_ceiling = fromInteger . ceiling
 
-sc_floor :: RealFrac a => a -> a
-sc_floor = fromInteger . floor
+-- | 'fromInteger' of 'floor'.
+sc3_floor :: RealFrac a => a -> a
+sc3_floor = fromInteger . floor
 
 -- | Variant of @SC3@ @roundTo@ function.
 --
+-- > sc3_round_to (2/3) 0.25 == 0.75
+--
 -- > 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
+-- > 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_round_to a b = if b == 0 then a else sc3_floor ((a / b) + 0.5) * b
 
+-- | 'fromInteger' of 'div' of 'floor'.
 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.
+{- | The SC3 @%@ UGen operator is the 'Numeric.mod'' function.
 
 > > 1.5 % 1.2 // ~= 0.3
 > > -1.5 % 1.2 // ~= 0.9
@@ -70,7 +81,7 @@
 > 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'
+sc3_mod = mod'
 
 -- | Type specialised 'sc3_mod'.
 fmod_f32 :: Float -> Float -> Float
@@ -82,35 +93,36 @@
 
 -- | @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
+-- > map (\n -> sc3_clip n 5 10) [3..12] == [5,5,5,6,7,8,9,10,10,10]
+sc3_clip :: Ord a => a -> a -> a -> a
+sc3_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.
+-- | Variant of 'sc3_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
+clip_hs (i,j) n = sc3_clip n i j
 
--- | Fractional modulo.
+-- | Fractional modulo, alternate implementation.
 --
--- > 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 =
+-- > map (\n -> sc3_mod_alt n 12.0) [-1.0,12.25,15.0] == [11.0,0.25,3.0]
+sc3_mod_alt :: RealFrac a => a -> a -> a
+sc3_mod_alt 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)
+            else n - hi * sc3_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]
+> map (sc3_wrap_ni 0 5) [4,5,6] == [4,0,1]
+> map (sc3_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
+sc3_wrap_ni :: RealFrac a => a -> a -> a -> a
+sc3_wrap_ni lo hi n = sc3_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.
@@ -127,13 +139,13 @@
     let r = j - i + 1
     in if n >= i && n <= j
        then n
-       else n - r * sc_floor ((n - i) / r)
+       else n - r * sc3_floor ((n - i) / r)
 
--- | Variant of 'wrap'' with @SC3@ argument ordering.
+-- | Variant of 'wrap_hs' 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
+-- > map (\n -> sc3_wrap n 5 10) [3..12] == map (wrap_hs (5,10)) [3..12]
+sc3_wrap :: RealFrac n => n -> n -> n -> n
+sc3_wrap a b c = wrap_hs (b,c) a
 
 {- | Generic variant of 'wrap''.
 
@@ -151,6 +163,8 @@
        then f (n + d)
        else if n > r then f (n - d) else n
 
+-- | Given sample-rate /sr/ and bin-count /n/ calculate frequency of /i/th bin.
+--
 -- > 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
@@ -162,30 +176,44 @@
 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.
+-- | Cycles per second to fractional 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
 
+-- | Cycles per second to linear octave (4.75 = A4 = 440).
+--
+-- > map (cps_to_oct . midi_to_cps) [60,63,69] == [4.0,4.25,4.75]
 cps_to_oct :: Floating a => a -> a
 cps_to_oct a = logBase 2 (a * (1.0 / 440.0)) + 4.75
 
+-- | Linear octave to cycles per second.
+--
+-- > map (cps_to_midi . oct_to_cps) [4.0,4.25,4.75] == [60,63,69]
 oct_to_cps :: Floating a => a -> a
 oct_to_cps a = 440.0 * (2.0 ** (a - 4.75))
 
+-- | Degree, scale and steps per octave to key.
+degree_to_key :: RealFrac a => [a] -> a -> a -> a
+degree_to_key s n d =
+    let l = length s
+        d' = round d
+        a = (d - fromIntegral d') * 10.0 * (n / 12.0)
+    in (n * fromIntegral (d' `div` l)) + (s !! (d' `mod` l)) + a
+
 -- | 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
+amp_to_db = (* 20) . logBase 10
 
 -- | 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)
+db_to_amp = (10 **) .  (* 0.05)
 
 -- | Fractional midi note interval to frequency multiplier.
 --
@@ -199,6 +227,153 @@
 ratio_to_midi :: Floating a => a -> a
 ratio_to_midi a = 12.0 * logBase 2 a
 
+-- | /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)
+
+-- | Pan2 function, identity is linear, sqrt is equal power.
+pan2_f :: Fractional t => (t -> t) -> t -> t -> (t, t)
+pan2_f f p q =
+    let q' = (q / 2) + 0.5
+    in (p * f (1 - q'),p * f q')
+
+-- | Linear pan.
+--
+-- > map (lin_pan2 1) [-1,-0.5,0,0.5,1] == [(1,0),(0.75,0.25),(0.5,0.5),(0.25,0.75),(0,1)]
+lin_pan2 :: Fractional t => t -> t -> (t, t)
+lin_pan2 = pan2_f id
+
+-- | Equal power pan.
+--
+-- > map (eq_pan2 1) [-1,-0.5,0,0.5,1]
+eq_pan2 :: Floating t => t -> t -> (t, t)
+eq_pan2 = pan2_f sqrt
+
+-- | 'fromInteger' of 'properFraction'.
+sc3_properFraction :: RealFrac t => t -> (t,t)
+sc3_properFraction a =
+    let (p,q) = properFraction a
+    in (fromInteger p,q)
+
+-- | a^2 - b^2.
+sc3_dif_sqr :: Num a => a -> a -> a
+sc3_dif_sqr a b = (a * a) - (b * b)
+
+-- | Euclidean distance function ('sqrt' of sum of squares).
+sc3_hypot :: Floating a => a -> a -> a
+sc3_hypot x y = sqrt (x * x + y * y)
+
+-- | SC3 hypotenuse approximation function.
+sc3_hypotx :: (Ord a, Floating a) => a -> a -> a
+sc3_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.
+sc3_fold :: (Ord a,Num a) => a -> a -> a -> a
+sc3_fold n i j = foldToRange i j n
+
+-- | SC3 distort operator.
+sc3_distort :: Fractional n => n -> n
+sc3_distort x = x / (1 + abs x)
+
+-- | SC3 softclip operator.
+sc3_softclip :: (Ord n, Fractional n) => n -> n
+sc3_softclip x = let x' = abs x in if x' <= 0.5 then x else (x' - 0.25) / x
+
+-- * Bool
+
+-- | True is conventionally 1.  The test to determine true is @> 0@.
+sc3_true :: Num n => n
+sc3_true = 1
+
+-- | False is conventionally 0.  The test to determine true is @<= 0@.
+sc3_false :: Num n => n
+sc3_false = 0
+
+-- | Lifted 'not'.
+--
+-- > sc3_not sc3_true == sc3_false
+-- > sc3_not sc3_false == sc3_true
+sc3_not :: (Ord n,Num n) => n -> n
+sc3_not = sc3_bool . not . (> 0)
+
+-- | Translate 'Bool' to 'sc3_true' and 'sc3_false'.
+sc3_bool :: Num n => Bool -> n
+sc3_bool b = if b then sc3_true else sc3_false
+
+-- | Lift comparison function.
+sc3_comparison :: Num n => (n -> n -> Bool) -> n -> n -> n
+sc3_comparison f p q = sc3_bool (f p q)
+
+-- * Eq
+
+-- | Lifted '=='.
+sc3_eq :: (Num n, Eq n) => n -> n -> n
+sc3_eq = sc3_comparison (==)
+
+-- | Lifted '/='.
+sc3_neq :: (Num n, Eq n) => n -> n -> n
+sc3_neq = sc3_comparison (/=)
+
+-- * Ord
+
+-- | Lifted '<'.
+sc3_lt :: (Num n, Ord n) => n -> n -> n
+sc3_lt = sc3_comparison (<)
+
+-- | Lifted '<='.
+sc3_lte :: (Num n, Ord n) => n -> n -> n
+sc3_lte = sc3_comparison (<=)
+
+-- | Lifted '>'.
+sc3_gt :: (Num n, Ord n) => n -> n -> n
+sc3_gt = sc3_comparison (>)
+
+-- | Lifted '>='.
+sc3_gte :: (Num n, Ord n) => n -> n -> n
+sc3_gte = sc3_comparison (>=)
+
+-- * Clip Rule
+
+-- | Enumeration of clipping rules.
+data Clip_Rule = Clip_None | Clip_Left | Clip_Right | Clip_Both
+                 deriving (Enum,Bounded)
+
+-- | Clip a value that is expected to be within an input range to an output range,
+--   according to a rule.
+--
+-- > 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
+
+-- * LinLin
+
 -- | Scale uni-polar (0,1) input to linear (l,r) range
 --
 -- > map (urange 3 4) [0,0.5,1] == [3,3.5,4]
@@ -219,22 +394,10 @@
 range :: Fractional a => a -> a -> a -> a
 range l r i = let (m,a) = range_muladd l r in i * m + a
 
+-- | Tuple variant of 'range'.
 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)
@@ -248,27 +411,30 @@
         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.
+-- | 'sc3_linlin' with a more typical haskell 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
+linlin_hs (sl,sr) (dl,dr) i = let (m,a) = linlin_muladd sl sr dl dr in i * m + a
 
+{- | Map from one linear range to another linear range.
+
+> r = [0,0.125,0.25,0.375,0.5,0.625,0.75,0.875,1]
+> map (\i -> sc3_linlin i (-1) 1 0 1) [-1,-0.75 .. 1] == r
+
+-}
+sc3_linlin :: Fractional a => a -> a -> a -> a -> a -> a
+sc3_linlin i sl sr dl dr = linlin_hs (sl,sr) (dl,dr) i
+
 -- | 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))
+-- > linlin _enum_plain 'a' 'A' 'e' == 'E'
+-- > linlin_enum_plain 0 (-50) 16 == -34
+-- > linlin_enum_plain 0 (-50) (-1) == -51
+linlin_enum_plain :: (Enum t,Enum u) => t -> u -> t -> u
+linlin_enum_plain 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,
+-- | Variant of 'linlin_enum_plain' 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)
@@ -277,7 +443,7 @@
 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)
+    then Just (linlin_enum_plain l l' n)
     else Nothing
 
 -- | Erroring variant.
@@ -300,32 +466,64 @@
 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
 
+-- * LinExp
+
+{- | Linear to exponential range conversion.
+     Rule is as at linExp UGen, haskell manner argument ordering.
+     Destination values must be nonzero and have the same sign.
+
+> map (floor . linexp_hs (1,2) (10,100)) [0,1,1.5,2,3] == [1,10,31,100,1000]
+> map (floor . linexp_hs (-2,2) (1,100)) [-3,-2,-1,0,1,2,3] == [0,1,3,10,31,100,316]
+
+-}
+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))
+
+-- | Variant of 'linexp_hs' with argument ordering as at 'linExp' UGen.
+--
+-- > map (\i -> lin_exp i 1 2 1 3) [1,1.1 .. 2]
+-- > map (\i -> floor (lin_exp i 1 2 10 100)) [0,1,1.5,2,3]
+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
+
 -- | @SimpleNumber.linexp@ shifts from linear to exponential ranges.
 --
+-- > map (sc3_linexp 1 2 1 3) [1,1.1 .. 2]
+--
 -- > > [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 =
+-- > map (floor . sc3_linexp 1 2 10 100) [0,1,1.5,2,3] == [10,10,31,100,100]
+sc3_linexp :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a
+sc3_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 =
+-- > map (sc3_explin 10 100 1 2) [10,10,31,100,100]
+sc3_explin :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a
+sc3_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 =
+-- * ExpExp
+
+-- | Translate from one exponential range to another.
+--
+-- > map (sc3_expexp 0.1 10 4.3 100) [1.. 10]
+sc3_expexp :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a
+sc3_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
 
+-- * LinCurve
+
 {- | 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
@@ -333,15 +531,15 @@
 
 > > (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
+> let f = round . sc3_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])
+> plotTable (map (\c-> map (sc3_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 =
+sc3_lincurve :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a -> a
+sc3_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 ->
@@ -353,12 +551,12 @@
                    scaled = (x - src_l) / (src_r - src_l)
                in b - (a * (grow ** scaled))
 
--- | Inverse of 'sc_lincurve'.
+-- | Inverse of 'sc3_lincurve'.
 --
--- > let f = round . sc_curvelin (-3) (-4.3) 100 0 10
+-- > let f = round . sc3_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 =
+sc3_curvelin :: (Ord a, Floating a) => a -> a -> a -> a -> a -> a -> a
+sc3_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 ->
@@ -369,67 +567,30 @@
                    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
+-- * PP
 
--- | Inverse of 'cps_to_incr'.
+-- | The default show is odd, 0.05 shows as 5.0e-2.
 --
--- > 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)
+-- > unwords (map (double_pp 4) [0.0001,0.001,0.01,0.1,1.0]) == "0.0001 0.001 0.01 0.1 1.0"
+double_pp :: Int -> Double -> String
+double_pp k n =
+    let rev_f f = reverse . f . reverse
+        remv l = case l of
+                   '0':'.':_ -> l
+                   '0':l' -> remv l'
+                   _ -> l
+    in rev_f remv (showFFloat (Just k) n "")
 
--- | Linear pan.
+-- | Print as integer if integral, else as real.
 --
--- > 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))
+-- > unwords (map real_pp [0.0001,0.001,0.01,0.1,1.0]) == "0.0001 0.001 0.01 0.1 1"
+real_pp :: Double -> String
+real_pp n =
+    let r = toRational n
+    in if denominator r == 1 then show (numerator r) else double_pp 5 n
 
--- | 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
+-- * Parser
 
--- | Variant of 'foldToRange' with @SC3@ argument ordering.
-fold_ :: (Ord a,Num a) => a -> a -> a -> a
-fold_ n i j = foldToRange i j n
+-- | Type-specialised 'R.readMaybe'.
+parse_double :: String -> Maybe Double
+parse_double = readMaybe
diff --git a/Sound/SC3/Common/Math/Filter.hs b/Sound/SC3/Common/Math/Filter.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Math/Filter.hs
@@ -0,0 +1,42 @@
+-- | Filter coefficient calculations.
+module Sound.SC3.Common.Math.Filter where
+
+-- | Butterworth low pass or high pass SOS filter coefficients, (a0,a1,a2,b0,b1).
+bw_lpf_or_hpf_coef :: Floating n => Bool -> n -> n -> (n,n,n,n,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)
+
+-- | rlpf coefficients, (a0,b1,b2).
+rlpf_coef :: Floating n => (n -> n -> n) -> (n,n,n) -> (n,n,n)
+rlpf_coef max_f (radians_per_sample,f,rq) =
+    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,b1,b2)
+
+-- | resonz coefficients, (a0,b1,b2).
+resonz_coef :: Floating n => (n,n,n) -> (n,n,n)
+resonz_coef (radians_per_sample,f,rq) =
+    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
+    in (a0,b1,b2)
diff --git a/Sound/SC3/Common/Math/Filter/BEQ.hs b/Sound/SC3/Common/Math/Filter/BEQ.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/Math/Filter/BEQ.hs
@@ -0,0 +1,114 @@
+-- | BEQ filter coefficient calculations, results are (a0,a1,a2,b0,b1).
+module Sound.SC3.Common.Math.Filter.BEQ where
+
+-- | Calculate coefficients for bi-quad low pass filter.
+bLowPassCoef :: Floating a => a -> a -> a -> (a,a,a,a,a)
+bLowPassCoef sr freq rq =
+    let w0 = pi * 2 * freq * (1 / sr)
+        cos_w0 = cos w0
+        i = 1 - cos_w0
+        alpha = sin w0 * 0.5 * rq
+        b0rz = recip (1 + alpha)
+        a0 = i * 0.5 * b0rz
+        a1 = i * b0rz
+        b1 = cos_w0 * 2 * b0rz
+        b2 = (1 - alpha) * negate b0rz
+    in (a0,a1,a0,b1,b2)
+
+-- | Calculate coefficients for bi-quad high pass filter.
+bHiPassCoef :: Floating t => t -> t -> t -> (t, t, t, t, t)
+bHiPassCoef sr freq rq =
+  let w0 = pi * 2 * freq * (1 / sr)
+      cos_w0 = cos w0
+      i = 1 + cos_w0
+      alpha = sin w0 * 0.5 * rq
+      b0rz = recip (1 + alpha)
+      a0 = i * 0.5 * b0rz
+      a1 = negate i * b0rz
+      b1 = cos_w0 * 2 * b0rz
+      b2 = (1 - alpha) * negate b0rz
+  in (a0, a1, a0, b1, b2)
+
+-- | Calculate coefficients for bi-quad all pass filter.
+bAllPassCoef :: Floating t => t -> t -> t -> (t, t, t, t, t)
+bAllPassCoef sr freq rq =
+  let w0 = pi * 2 * freq * (1 / sr)
+      alpha = sin w0 * 0.5 * rq
+      b0rz = recip (1 + alpha)
+      a0 = (1 - alpha) * b0rz
+      b1 = 2.0 * cos w0 * b0rz
+  in (a0,negate b1, 1.0, b1,negate a0)
+
+-- | Calculate coefficients for bi-quad band pass filter.
+bBandPassCoef :: Floating t => t -> t -> t -> (t, t, t, t, t)
+bBandPassCoef sr freq bw =
+  let w0 = pi * 2 * freq * (1 / sr)
+      sin_w0 = sin w0
+      alpha = sin_w0 * sinh (0.34657359027997 * bw * w0 / sin_w0)
+      b0rz = recip (1 + alpha)
+      a0 = alpha * b0rz
+      b1 = cos w0 * 2 * b0rz
+      b2 = (1 - alpha) * negate b0rz
+  in (a0, 0.0, negate a0, b1, b2)
+
+-- | Calculate coefficients for bi-quad stop band filter.
+bBandStopCoef :: Floating t => t -> t -> t -> (t, t, t, t, t)
+bBandStopCoef sr freq bw =
+  let w0 = pi * 2 * freq * (1 / sr)
+      sin_w0 = sin w0
+      alpha = sin_w0 * sinh (0.34657359027997 * bw * w0 / sin_w0)
+      b0rz = recip (1 + alpha)
+      b1 = 2.0 * cos w0 * b0rz
+      b2 = (1 - alpha) * negate b0rz
+  in (b0rz, negate b1, b0rz, b1, b2)
+
+-- | Calculate coefficients for bi-quad peaking EQ filter.
+bPeakEQCoef :: Floating t => t -> t -> t -> t -> (t, t, t, t, t)
+bPeakEQCoef sr freq rq db =
+  let a = 10 ** (db / 40)
+      w0 = pi * 2 * freq * (1 / sr)
+      alpha = sin w0 * 0.5 * rq
+      b0rz = recip (1 + (alpha / a))
+      a0 = (1 + (alpha * a)) * b0rz
+      a2 = (1 - (alpha * a)) * b0rz
+      b1 = 2.0 * cos w0 * b0rz
+      b2 = (1 - (alpha / a)) * negate b0rz
+  in (a0, negate b1, a2, b1, b2)
+
+-- | Calculate coefficients for bi-quad low shelf filter.
+bLowShelfCoef :: Floating t => t -> t -> t -> t -> (t, t, t, t, t)
+bLowShelfCoef sr freq rs db =
+  let a = 10 ** (db / 40)
+      w0 = pi * 2 * freq * (1 / sr)
+      cos_w0 = cos w0
+      sin_w0 = sin w0
+      alpha = sin_w0 * 0.5 * sqrt ((a + recip a) * (rs - 1) + 2.0)
+      i = (a + 1) * cos_w0
+      j = (a - 1) * cos_w0
+      k = 2 * sqrt a * alpha
+      b0rz = recip ((a + 1) + j + k)
+      a0 = a * ((a + 1) - j + k) * b0rz
+      a1 = 2 * a * ((a - 1) - i) * b0rz
+      a2 = a * ((a + 1) - j - k) * b0rz
+      b1 = 2.0 * ((a - 1) + i) * b0rz
+      b2 = ((a + 1) + j - k) * negate b0rz
+  in (a0, a1, a2, b1, b2)
+
+-- | Calculate coefficients for bi-quad high shelf filter.
+bHiShelfCoef :: Floating t => t -> t -> t -> t -> (t, t, t, t, t)
+bHiShelfCoef sr freq rs db =
+  let a = 10 ** (db / 40)
+      w0 = pi * 2 * freq * (1 / sr)
+      cos_w0 = cos w0
+      sin_w0 = sin w0
+      alpha = sin_w0 * 0.5 * sqrt((a + recip a) * (rs - 1) + 2.0)
+      i = (a+1) * cos_w0
+      j = (a-1) * cos_w0
+      k = 2 * sqrt(a) * alpha
+      b0rz = recip ((a + 1) - j + k)
+      a0 = a * ((a + 1) + j + k) * b0rz
+      a1 = -2.0 * a * ((a - 1) + i) * b0rz
+      a2 = a * ((a + 1) + j - k) * b0rz
+      b1 = -2.0 * ((a - 1) - i) * b0rz
+      b2 = ((a + 1) - j - k) * negate b0rz
+  in (a0, a1, a2, b1, b2)
diff --git a/Sound/SC3/Common/Math/Interpolate.hs b/Sound/SC3/Common/Math/Interpolate.hs
--- a/Sound/SC3/Common/Math/Interpolate.hs
+++ b/Sound/SC3/Common/Math/Interpolate.hs
@@ -18,7 +18,9 @@
 step :: Interpolation_F t
 step _ x1 _ = x1
 
--- | Linear interpolation.
+-- | Linear interpolation funtion, /x0/ is at /t/ of zero, and /x1/ at /t/ of one.
+--
+-- > map (linear 1 10) [0,0.25 .. 1] == [1,3.25,5.5,7.75,10]
 --
 -- > import Sound.SC3.Plot {- hsc3-plot -}
 -- > plotTable1 (map (linear (-1) 1) [0,0.01 .. 1])
diff --git a/Sound/SC3/Common/Monad.hs b/Sound/SC3/Common/Monad.hs
--- a/Sound/SC3/Common/Monad.hs
+++ b/Sound/SC3/Common/Monad.hs
@@ -1,3 +1,4 @@
+-- | Common 'Control.Monad' variations.
 module Sound.SC3.Common.Monad where
 
 import Control.Monad {- base -}
diff --git a/Sound/SC3/Common/Monad/Operators.hs b/Sound/SC3/Common/Monad/Operators.hs
--- a/Sound/SC3/Common/Monad/Operators.hs
+++ b/Sound/SC3/Common/Monad/Operators.hs
@@ -1,5 +1,4 @@
--- | Functions to make writing 'Applicative' and 'Monad' UGen graphs
--- less clumsy.
+-- | Functions to make writing 'Applicative' and 'Monad' UGen graphs less clumsy.
 module Sound.SC3.Common.Monad.Operators where
 
 import Control.Applicative {- base -}
diff --git a/Sound/SC3/Common/Prelude.hs b/Sound/SC3/Common/Prelude.hs
deleted file mode 100644
--- a/Sound/SC3/Common/Prelude.hs
+++ /dev/null
@@ -1,139 +0,0 @@
-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/Common/UId.hs b/Sound/SC3/Common/UId.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/Common/UId.hs
@@ -0,0 +1,108 @@
+{-# Language FlexibleInstances #-}
+
+-- | Unique identifier types and classes.
+--   Used by non-deterministic (noise) and non-sharable (demand) unit generators.
+module Sound.SC3.Common.UId where
+
+import Control.Monad {- base -}
+import Data.Functor.Identity {- base -}
+import Data.List {- base -}
+import qualified Data.Unique as Unique {- base -}
+
+import qualified Control.Monad.Trans.Reader as Reader {- transformers -}
+import qualified Control.Monad.Trans.State as State {- transformers -}
+import qualified Data.Digest.Murmur32 as Murmur32 {- hashable -}
+
+import qualified Sound.SC3.Common.Base as Base {- hsc3 -}
+
+-- * Id & UId
+
+-- | Identifiers are integers.
+type Id = Int
+
+-- | 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
+
+-- | Requires FlexibleInstances.
+instance UId (State.StateT Int Identity) where
+    generateUId = State.get >>= \n -> State.put (n + 1) >> return n
+
+instance UId IO where
+    generateUId = liftM Unique.hashUnique Unique.newUnique
+
+instance UId m => UId (Reader.ReaderT t m) where
+   generateUId = Reader.ReaderT (const generateUId)
+
+-- * UId_ST
+
+-- | 'State.State' UId.
+type UId_ST = State.State Int
+
+-- | 'State.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 = State.evalState x 0
+
+-- | Thread state through sequence of 'State.runState'.
+uid_st_seq :: [UId_ST t] -> ([t],Int)
+uid_st_seq =
+    let swap (p,q) = (q,p)
+        step_f n x = swap (State.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
+
+-- * Lift
+
+-- | Unary UId lift.
+liftUId1 :: UId m => (Int -> Base.Fn1 a b) -> Base.Fn1 a (m b)
+liftUId1 f a = do
+  n <- generateUId
+  return (f n a)
+
+-- | Binary UId lift.
+liftUId2 :: UId m => (Int -> Base.Fn2 a b c) -> Base.Fn2 a b (m c)
+liftUId2 f a b = do
+  n <- generateUId
+  return (f n a b)
+
+-- | Ternary UId lift.
+liftUId3 :: UId m => (Int -> Base.Fn3 a b c d) -> Base.Fn3 a b c (m d)
+liftUId3 f a b c = do
+  n <- generateUId
+  return (f n a b c)
+
+-- | Quaternary UId lift.
+liftUId4 :: UId m => (Int -> Base.Fn4 a b c d e) -> Base.Fn4 a b c d (m e)
+liftUId4 f a b c d = do
+  n <- generateUId
+  return (f n a b c d)
+
+-- * ID
+
+-- | Typeclass to constrain UGen identifiers.
+--
+-- > map resolveID [0::Int,1] == [3151710696,1500603050]
+-- > map resolveID ['α','β'] == [1439603815,4131151318]
+-- > map resolveID [('α','β'),('β','α')] == [3538183581,3750624898]
+-- > map resolveID [('α',('α','β')),('β',('α','β'))] == [0020082907,2688286317]
+class Murmur32.Hashable32 a => ID a where
+    resolveID :: a -> Id
+    resolveID = fromIntegral . Murmur32.asWord32 . Murmur32.hash32
+
+instance ID Char where
+instance ID Int where
+instance (ID p,ID q) => ID (p,q) where
+
+-- | /n/ identifiers from /x/.
+--
+-- > id_seq 10 'α' == [945 .. 954]
+id_seq :: ID a => Int -> a -> [Id]
+id_seq n x = take n [resolveID x ..]
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
@@ -17,51 +17,51 @@
 
 -- | Install a bytecode instrument definition. (Asynchronous)
 d_recv :: Packet -> Synthdef -> Message
-d_recv osc d = Message "/d_recv" [Blob (synthdefData d),encode_blob osc]
+d_recv pkt d = Message "/d_recv" [Blob (synthdefData d),encode_blob pkt]
 
 -- | Load an instrument definition from a named file. (Asynchronous)
 d_load :: Packet -> String -> Message
-d_load osc p = Message "/d_load" [string p,encode_blob osc]
+d_load pkt p = Message "/d_load" [string p,encode_blob pkt]
 
 -- | Load a directory of instrument definitions files. (Asynchronous)
 d_loadDir :: Packet -> String -> Message
-d_loadDir osc p = Message "/d_loadDir" [string p,encode_blob osc]
+d_loadDir pkt p = Message "/d_loadDir" [string p,encode_blob pkt]
 
 -- | Allocates zero filled buffer to number of channels and samples. (Asynchronous)
 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]
+b_alloc pkt nid frames channels = Message "/b_alloc" [int32 nid,int32 frames,int32 channels,encode_blob pkt]
 
 -- | Allocate buffer space and read a sound file. (Asynchronous)
 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]
+b_allocRead pkt nid p f n = Message "/b_allocRead" [int32 nid,string p,int32 f,int32 n,encode_blob pkt]
 
 -- | Allocate buffer space and read a sound file, picking specific channels. (Asynchronous)
 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])
+b_allocReadChannel pkt nid p f n cs = Message "/b_allocReadChannel" ([int32 nid,string p,int32 f,int32 n] ++ map int32 cs ++ [encode_blob pkt])
 
 -- | Free buffer data. (Asynchronous)
 b_free :: Packet -> Int -> Message
-b_free osc nid = Message "/b_free" [int32 nid,encode_blob osc]
+b_free pkt nid = Message "/b_free" [int32 nid,encode_blob pkt]
 
 -- | Close attached soundfile and write header information. (Asynchronous)
 b_close :: Packet -> Int -> Message
-b_close osc nid = Message "/b_close" [int32 nid,encode_blob osc]
+b_close pkt nid = Message "/b_close" [int32 nid,encode_blob pkt]
 
 -- | Read sound file data into an existing buffer. (Asynchronous)
 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]
+b_read pkt nid p f n f' z = Message "/b_read" [int32 nid,string p,int32 f,int32 n,int32 f',int32 (fromEnum z),encode_blob pkt]
 
 -- | Read sound file data into an existing buffer. (Asynchronous)
 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])
+b_readChannel pkt 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 pkt])
 
 -- | Write sound file data. (Asynchronous)
 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]
+b_write pkt 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 pkt]
 
 -- | Zero sample data. (Asynchronous)
 b_zero :: Packet -> Int -> Message
-b_zero osc nid = Message "/b_zero" [int32 nid,encode_blob osc]
+b_zero pkt nid = Message "/b_zero" [int32 nid,encode_blob pkt]
 
 -- Local Variables:
 -- truncate-lines:t
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
@@ -6,7 +6,7 @@
 
 import Sound.OSC.Core {- hosc -}
 
-import qualified Sound.SC3.Common.Prelude as P
+import qualified Sound.SC3.Common.Base as B
 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
@@ -32,7 +32,7 @@
 
 -- | 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 : P.mk_triples int32 int32 float l)
+b_fill nid l = message "/b_fill" (int32 nid : B.mk_triples int32 int32 float l)
 
 -- | Free buffer data. (Asynchronous)
 b_free :: Integral i => i -> Message
@@ -48,11 +48,11 @@
 
 -- | Call @sine2@ 'b_gen' command.
 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)
+b_gen_sine2 z f n = b_gen z "sine2" (int32 (E.b_gen_flag f) : B.mk_duples float float n)
 
 -- | Call @sine3@ 'b_gen' command.
 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)
+b_gen_sine3 z f n = b_gen z "sine3" (int32 (E.b_gen_flag f) : B.mk_triples float float float n)
 
 -- | Call @cheby@ 'b_gen' command.
 b_gen_cheby :: (Integral i,Real n) => i -> [E.B_Gen] -> [n] -> Message
@@ -70,7 +70,7 @@
 
 -- | Get ranges of sample values.
 b_getn :: Integral i => i -> [(i,i)] -> Message
-b_getn nid l = message "/b_getn" (int32 nid : P.mk_duples int32 int32 l)
+b_getn nid l = message "/b_getn" (int32 nid : B.mk_duples int32 int32 l)
 
 -- | Request \/b_info messages.
 b_query :: Integral i => [i] -> Message
@@ -86,7 +86,7 @@
 
 -- | Set sample values.
 b_set :: (Integral i,Real n) => i -> [(i,n)] -> Message
-b_set nid l = message "/b_set" (int32 nid : P.mk_duples int32 float l)
+b_set nid l = message "/b_set" (int32 nid : B.mk_duples int32 float l)
 
 -- | Set ranges of sample values.
 b_setn :: (Integral i,Real n) => i -> [(i,[n])] -> Message
@@ -109,7 +109,7 @@
 
 -- |  Fill ranges of bus values.
 c_fill :: (Integral i,Real n) => [(i,i,n)] -> Message
-c_fill = message "/c_fill" . P.mk_triples int32 int32 float
+c_fill = message "/c_fill" . B.mk_triples int32 int32 float
 
 -- | Get bus values.
 c_get :: Integral i => [i] -> Message
@@ -117,11 +117,11 @@
 
 -- | Get ranges of bus values.
 c_getn :: Integral i => [(i,i)] -> Message
-c_getn = message "/c_getn" . P.mk_duples int32 int32
+c_getn = message "/c_getn" . B.mk_duples int32 int32
 
 -- | Set bus values.
 c_set :: (Integral i,Real n) => [(i,n)] -> Message
-c_set = message "/c_set" . P.mk_duples int32 float
+c_set = message "/c_set" . B.mk_duples int32 float
 
 -- | Set ranges of bus values.
 c_setn :: (Integral i,Real n) => [(i,[n])] -> Message
@@ -163,19 +163,19 @@
 
 -- | Add node to head of group.
 g_head :: Integral i => [(i,i)] -> Message
-g_head = message "/g_head" . P.mk_duples int32 int32
+g_head = message "/g_head" . B.mk_duples int32 int32
 
 -- | Create a new group.
 g_new :: Integral i => [(i,E.AddAction,i)] -> Message
-g_new = message "/g_new" . P.mk_triples int32 (int32 . fromEnum) int32
+g_new = message "/g_new" . B.mk_triples int32 (int32 . fromEnum) int32
 
 -- | Add node to tail of group.
 g_tail :: Integral i => [(i,i)] -> Message
-g_tail = message "/g_tail" . P.mk_duples int32 int32
+g_tail = message "/g_tail" . B.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" . P.mk_duples int32 (int32 . fromEnum)
+g_dumpTree = message "/g_dumpTree" . B.mk_duples int32 (int32 . fromEnum)
 
 -- | Request a representation of a group's node subtree, optionally including the current control values for synths.
 --
@@ -203,40 +203,41 @@
 --
 -- 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" . P.mk_duples int32 (int32 . fromEnum)
+g_queryTree = message "/g_queryTree" . B.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" . P.mk_duples int32 int32
+n_after = message "/n_after" . B.mk_duples int32 int32
 
 -- | Place a node before another.
 n_before :: Integral i => [(i,i)] -> Message
-n_before = message "/n_before" . P.mk_duples int32 int32
+n_before = message "/n_before" . B.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 : P.mk_triples string int32 float l)
+n_fill nid l = message "/n_fill" (int32 nid : B.mk_triples string int32 float l)
 
 -- | Delete a node.
 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 : P.mk_duples string int32 l)
+n_map nid l = message "/n_map" (int32 nid : B.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 : P.mk_triples string int32 int32 l)
+--   n_mapn only works if the control is given as an index and not as a name (3.8.0).
+n_mapn :: Integral i => i -> [(i,i,i)] -> Message
+n_mapn nid l = message "/n_mapn" (int32 nid : B.mk_triples int32 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 : P.mk_duples string int32 l)
+n_mapa nid l = message "/n_mapa" (int32 nid : B.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 : P.mk_triples string int32 int32 l)
+n_mapan nid l = message "/n_mapan" (int32 nid : B.mk_triples string int32 int32 l)
 
 -- | Get info about a node.
 n_query :: Integral i => [i] -> Message
@@ -244,16 +245,17 @@
 
 -- | Turn node on or off.
 n_run :: Integral i => [(i,Bool)] -> Message
-n_run = message "/n_run" . P.mk_duples int32 (int32 . fromEnum)
+n_run = message "/n_run" . B.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 : P.mk_duples string float c)
+n_set nid c = message "/n_set" (int32 nid : B.mk_duples string float c)
 
 -- | Set ranges of a node's control values.
-n_setn :: (Integral i,Real n) => i -> [(String,[n])] -> Message
+-- n_mapn and n_setn only work if the control is given as an index and not as a name.
+n_setn :: (Integral i,Real n) => i -> [(i,[n])] -> Message
 n_setn nid l =
-    let f (s,d) = string s : int32 (length d) : map float d
+    let f (s,d) = int32 s : int32 (length d) : map float d
     in message "/n_setn" (int32 nid : concatMap f l)
 
 -- | Trace a node.
@@ -268,7 +270,7 @@
 
 -- | Create a new parallel group (supernova specific).
 p_new :: Integral i => [(i,E.AddAction,i)] -> Message
-p_new = message "/p_new" . P.mk_triples int32 (int32 . fromEnum) int32
+p_new = message "/p_new" . B.mk_triples int32 (int32 . fromEnum) int32
 
 -- * Synthesis node commands (s_)
 
@@ -278,11 +280,11 @@
 
 -- | Get ranges of control values.
 s_getn :: Integral i => i -> [(String,i)] -> Message
-s_getn nid l = message "/s_getn" (int32 nid : P.mk_duples string int32 l)
+s_getn nid l = message "/s_getn" (int32 nid : B.mk_duples string int32 l)
 
 -- | Create a new synth.
 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)
+s_new n i a t c = message "/s_new" (string n : int32 i : int32 (fromEnum a) : int32 t : B.mk_duples string float c)
 
 -- | Auto-reassign synth's ID to a reserved value.
 s_noid :: Integral i => [i] -> Message
@@ -430,7 +432,7 @@
 b_indices :: Integral i => i -> i -> i -> [(i,i)]
 b_indices n m k =
     let s = b_segment n m
-        i = 0 : P.dx_d s
+        i = 0 : B.dx_d s
     in zip (map (+ k) i) s
 
 -- * UGen commands.
@@ -442,7 +444,7 @@
 
 -- * Unpack
 
--- | Result is null for non-conforming data, or has five or sevel elements.
+-- | Result is null for non-conforming data, or has five or seven elements.
 unpack_n_info_datum_plain :: Num i => [Datum] -> [i]
 unpack_n_info_datum_plain m =
     let to_i = fromIntegral
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
@@ -19,7 +19,7 @@
 -- | File connection flag.
 type Buffer_Leave_File_Open = Bool
 
--- | Control bus identifier (number).
+-- | Audio/control bus identifier (number).
 type Bus_Id = Int
 
 -- | Node identifier (number).
@@ -193,7 +193,8 @@
 n_map = G.n_map
 
 -- | Map a node's controls to read from buses.
-n_mapn :: Node_Id -> [(String,Bus_Id,Int)] -> Message
+--   n_mapn only works if the control is given as an index and not as a name (3.8.0).
+n_mapn :: Node_Id -> [(Int,Bus_Id,Int)] -> Message
 n_mapn = G.n_mapn
 
 -- | Map a node's controls to read from an audio bus.
@@ -217,7 +218,7 @@
 n_set = G.n_set
 
 -- | Set ranges of a node's control values.
-n_setn :: Node_Id -> [(String,[Double])] -> Message
+n_setn :: Node_Id -> [(Int,[Double])] -> Message
 n_setn = G.n_setn
 
 -- | Trace a node.
diff --git a/Sound/SC3/Server/Enum.hs b/Sound/SC3/Server/Enum.hs
--- a/Sound/SC3/Server/Enum.hs
+++ b/Sound/SC3/Server/Enum.hs
@@ -1,7 +1,11 @@
 -- | Server input enumerations.
 module Sound.SC3.Server.Enum where
 
+import Data.Maybe {- base -}
+
 -- | Enumeration of possible locations to add new nodes (s_new and g_new).
+--
+-- > fromEnum AddToTail == 1
 data AddAction = AddToHead
                | AddToTail
                | AddBefore
@@ -76,6 +80,13 @@
               ,("wav",Wave)]
     in flip lookup tbl
 
+-- | Erroring variant.
+soundFileFormat_from_extension_err :: String -> SoundFileFormat
+soundFileFormat_from_extension_err =
+  fromMaybe (error "soundFileFormat_from_extension: unknown sf extension") .
+  soundFileFormat_from_extension
+
+-- | 'SampleFormat' string as recognised by scsynth NRT mode.
 sampleFormatString :: SampleFormat -> String
 sampleFormatString f =
     case f of
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
@@ -1,116 +1,130 @@
 -- | Binary 'Graph Definition' as understood by @scsynth@.
+--   There are both encoders and decoders.
 module Sound.SC3.Server.Graphdef where
 
 import Control.Monad {- base -}
 import qualified Data.ByteString.Lazy as L {- bytestring -}
-import Data.List
+import Data.List {- base -}
 import System.IO {- base -}
 
-import qualified Sound.OSC.Coding.Byte as B {- hosc -}
-import qualified Sound.OSC.Coding.Cast as C {- hosc -}
-import Sound.OSC.Datum {- hosc -}
+import qualified Sound.OSC.Coding.Byte as Byte {- hosc -}
+import qualified Sound.OSC.Coding.Cast as Cast {- hosc -}
+import qualified Sound.OSC.Datum as Datum {- hosc -}
 
 -- * Type
 
-type Name = ASCII
+-- | Names are ASCII strings.
+type Name = Datum.ASCII
 
+-- | Controls are a name and a ugen-index.
 type Control = (Name,Int)
 
+-- | Constants are floating point.
 type Sample = Double
 
+-- | Inputs are a ugen-index and a port-index.
+--   If the ugen-index is -1 it indicates a constant.
 data Input = Input Int Int deriving (Eq,Show)
 
+-- | Read ugen-index of input, else Nothing.
 input_ugen_ix :: Input -> Maybe Int
 input_ugen_ix (Input u p) = if p == -1 then Nothing else Just u
 
-type Output = Int
-
+-- | Rates are encoded as integers (IR = 0, KR = 1, AR = 2, DR = 3).
 type Rate = Int
 
+-- | Outputs each indicate a Rate.
+type Output = Rate
+
+-- | Secondary (special) index, used by operator UGens to select operation.
 type Special = Int
 
+-- | Unit generator type.
 type UGen = (Name,Rate,[Input],[Output],Special)
 
+-- | 'UGen' 'Rate'.
+ugen_rate :: UGen -> Rate
+ugen_rate (_,r,_,_,_) = r
+
+-- | 'UGen' 'Input's.
 ugen_inputs :: UGen -> [Input]
 ugen_inputs (_,_,i,_,_) = i
 
+-- | 'UGen' 'Output's.
 ugen_outputs :: UGen -> [Output]
 ugen_outputs (_,_,_,o,_) = o
 
+-- | Predicate to examine Ugen name and decide if it is a control.
 ugen_is_control :: UGen -> Bool
-ugen_is_control (nm,_,_,_,_) = ascii_to_string nm `elem` ["Control","LagControl","TrigControl"]
-
-ugen_rate :: UGen -> Rate
-ugen_rate (_,r,_,_,_) = r
+ugen_is_control (nm,_,_,_,_) =
+  Datum.ascii_to_string nm `elem` ["Control","LagControl","TrigControl"]
 
+-- | Input is a UGen and the UGen is a control.
 input_is_control :: Graphdef -> Input -> Bool
 input_is_control g (Input u _) =
     if u == -1
     then False
     else ugen_is_control (graphdef_ugen g u)
 
+-- | Graph definition type.
 data Graphdef = Graphdef {graphdef_name :: Name
                          ,graphdef_constants :: [Sample]
                          ,graphdef_controls :: [(Control,Sample)]
                          ,graphdef_ugens :: [UGen]}
                 deriving (Eq,Show)
 
+-- | Lookup UGen by index.
 graphdef_ugen :: Graphdef -> Int -> UGen
 graphdef_ugen g = (graphdef_ugens g !!)
 
+-- | Lookup Control and default value by index.
 graphdef_control :: Graphdef -> Int -> (Control,Sample)
 graphdef_control g = (graphdef_controls g !!)
 
+-- | nid of constant.
 graphdef_constant_nid :: Graphdef -> Int -> Int
 graphdef_constant_nid _ = id
 
+-- | nid of control.
 graphdef_control_nid :: Graphdef -> Int -> Int
 graphdef_control_nid g = (+) (length (graphdef_constants g))
 
+-- | nid of UGen.
 graphdef_ugen_nid :: Graphdef -> Int -> Int
 graphdef_ugen_nid g n = graphdef_control_nid g 0 + length (graphdef_controls g) + n
 
--- * Read
-
-read_i8 :: Handle -> IO Int
-read_i8 h = fmap B.decode_i8 (L.hGet h 1)
-
-read_i16 :: Handle -> IO Int
-read_i16 h = fmap B.decode_i16 (L.hGet h 2)
-
-read_i32 :: Handle -> IO Int
-read_i32 h = fmap B.decode_i32 (L.hGet h 4)
+-- * Read (version 0 or 2).
 
+-- | Read a 'Sample'.
 read_sample :: Handle -> IO Sample
-read_sample h = fmap (realToFrac . B.decode_f32) (L.hGet h 4)
-
-read_pstr :: Handle -> IO ASCII
-read_pstr h = do
-  n <- fmap B.decode_u8 (L.hGet h 1)
-  fmap B.decode_str (L.hGet h n)
+read_sample = fmap realToFrac . Byte.read_f32
 
+-- | Read a 'Control'.
 read_control :: (Handle -> IO Int) -> Handle -> IO Control
 read_control read_i h = do
-  nm <- read_pstr h
+  nm <- Byte.read_pstr h
   ix <- read_i h
   return (nm,ix)
 
+-- | Read an 'Input'.
 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 an 'output'.
+read_output :: Handle -> IO Output
+read_output = Byte.read_i8
 
+-- | Read a 'UGen'.
 read_ugen :: (Handle -> IO Int) -> Handle -> IO UGen
 read_ugen read_i h = do
-  name <- read_pstr h
-  rate <- read_i8 h
+  name <- Byte.read_pstr h
+  rate <- Byte.read_i8 h
   number_of_inputs <- read_i h
   number_of_outputs <- read_i h
-  special <- read_i16 h
+  special <- Byte.read_i16 h
   inputs <- replicateM number_of_inputs (read_input read_i h)
   outputs <- replicateM number_of_outputs (read_output h)
   return (name
@@ -119,21 +133,22 @@
          ,outputs
          ,special)
 
+-- | Read a 'Graphdef'. Ignores variants.
 read_graphdef :: Handle -> IO Graphdef
 read_graphdef h = do
-  magic <- fmap B.decode_str (L.hGet h 4)
-  version <- read_i32 h
+  magic <- fmap Byte.decode_str (L.hGet h 4)
+  version <- Byte.read_i32 h
   let read_i =
           case version of
-            0 -> read_i16
-            2 -> read_i32
+            0 -> Byte.read_i16
+            2 -> Byte.read_i32
             _ -> error ("read_graphdef: version not at {zero | two}: " ++ show version)
-  number_of_definitions <- read_i16 h
-  when (magic /= ascii "SCgf")
+  number_of_definitions <- Byte.read_i16 h
+  when (magic /= Datum.ascii "SCgf")
        (error "read_graphdef: illegal magic string")
   when (number_of_definitions /= 1)
        (error "read_graphdef: non unary graphdef file")
-  name <- read_pstr h
+  name <- Byte.read_pstr h
   number_of_constants <- read_i h
   constants <- replicateM number_of_constants (read_sample h)
   number_of_control_defaults <- read_i h
@@ -142,17 +157,21 @@
   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)
                    ugens)
 
--- > g <- read_graphdef_file "/home/rohan/sw/rsc3-disassembler/scsyndef/simple.scsyndef"
--- > 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 from file.
+
+> dir = "/home/rohan/sw/rsc3-disassembler/scsyndef/"
+> pp nm = read_graphdef_file (dir ++ nm) >>= putStrLn . graphdef_stat
+> pp "simple.scsyndef"
+> pp "with-ctl.scsyndef"
+> pp "mce.scsyndef"
+> pp "mrg.scsyndef"
+
+-}
 read_graphdef_file :: FilePath -> IO Graphdef
 read_graphdef_file nm = do
   h <- openFile nm ReadMode
@@ -160,54 +179,58 @@
   hClose h
   return g
 
--- * Encode, we write version zero files
+-- * Encode (version zero)
 
 -- | Pascal (length prefixed) encoding of string.
-encode_pstr :: ASCII -> L.ByteString
-encode_pstr = L.pack . C.str_pstr . ascii_to_string
+encode_pstr :: Name -> L.ByteString
+encode_pstr = L.pack . Cast.str_pstr . Datum.ascii_to_string
 
--- | Byte-encode 'Input' value.
+-- | Byte-encode 'Input'.
 encode_input :: Input -> L.ByteString
-encode_input (Input u p) = L.append (B.encode_i16 u) (B.encode_i16 p)
+encode_input (Input u p) = L.append (Byte.encode_i16 u) (Byte.encode_i16 p)
 
+-- | Byte-encode 'Control'.
 encode_control :: Control -> L.ByteString
-encode_control (nm,k) = L.concat [encode_pstr nm,B.encode_i16 k]
+encode_control (nm,k) = L.concat [encode_pstr nm,Byte.encode_i16 k]
 
 -- | Byte-encode 'UGen'.
 encode_ugen :: UGen -> L.ByteString
 encode_ugen (nm,r,i,o,s) =
     L.concat [encode_pstr nm
-             ,B.encode_i8 r
-             ,B.encode_i16 (length i)
-             ,B.encode_i16 (length o)
-             ,B.encode_i16 s
+             ,Byte.encode_i8 r
+             ,Byte.encode_i16 (length i)
+             ,Byte.encode_i16 (length o)
+             ,Byte.encode_i16 s
              ,L.concat (map encode_input i)
-             ,L.concat (map B.encode_i8 o)]
+             ,L.concat (map Byte.encode_i8 o)]
 
+-- | Encode 'Sample' as 32-bit IEEE float.
 encode_sample :: Sample -> L.ByteString
-encode_sample = B.encode_f32 . realToFrac
+encode_sample = Byte.encode_f32 . realToFrac
 
+-- | Encode 'Graphdef'.
 encode_graphdef :: Graphdef -> L.ByteString
 encode_graphdef (Graphdef nm cs ks us) =
     let (ks_ctl,ks_def) = unzip ks
-    in L.concat [B.encode_str (ascii "SCgf")
-                ,B.encode_i32 0 -- version
-                ,B.encode_i16 1 -- number of graphs
+    in L.concat [Byte.encode_str (Datum.ascii "SCgf")
+                ,Byte.encode_i32 0 -- version
+                ,Byte.encode_i16 1 -- number of graphs
                 ,encode_pstr nm
-                ,B.encode_i16 (length cs)
+                ,Byte.encode_i16 (length cs)
                 ,L.concat (map encode_sample cs)
-                ,B.encode_i16 (length ks_def)
+                ,Byte.encode_i16 (length ks_def)
                 ,L.concat (map encode_sample ks_def)
-                ,B.encode_i16 (length ks_ctl)
+                ,Byte.encode_i16 (length ks_ctl)
                 ,L.concat (map encode_control ks_ctl)
-                ,B.encode_i16 (length us)
+                ,Byte.encode_i16 (length us)
                 ,L.concat (map encode_ugen us)]
 
 -- * Stat
 
+-- | Simple statistics printer for 'Graphdef'.
 graphdef_stat :: Graphdef -> String
 graphdef_stat (Graphdef nm cs ks us) =
-    let u_nm (sc3_nm,_,_,_,_) = ascii_to_string sc3_nm
+    let u_nm (sc3_nm,_,_,_,_) = Datum.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
@@ -219,3 +242,4 @@
                ,"unit generator rates      : " ++ f ugen_rate us
                ,"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
@@ -1,48 +1,78 @@
--- | Transform 'Graph' to 'Graphdef'.
+-- | Transform 'Graph.U_Graph' to 'Graphdef.Graphdef'.
 module Sound.SC3.Server.Graphdef.Graph where
 
-import Data.Maybe{- base -}
+import qualified Data.IntMap as M {- containers -}
+import Data.Maybe {- base -}
 
-import Sound.OSC.Datum {- hosc -}
+import qualified Sound.OSC.Datum as Datum {- hosc -}
 
-import qualified Sound.SC3.Server.Graphdef as G
-import Sound.SC3.UGen.Graph
-import Sound.SC3.UGen.Rate
-import Sound.SC3.UGen.Type
+import qualified Sound.SC3.UGen.Graph as Graph
+import qualified Sound.SC3.UGen.Rate as Rate
+import qualified Sound.SC3.UGen.Type as Type
+import qualified Sound.SC3.Server.Graphdef as Graphdef
 
--- * Encode to 'G.Graphdef'
+-- * Maps
 
--- | Construct 'Input' form required by byte-code generator.
-make_input :: Maps -> FromPort -> G.Input
+-- | (Int,Int) map.
+type Int_Map = M.IntMap Int
+
+-- | (constants-map,controls,controls-map,ugen-map,ktype-map)
+type Encoding_Maps = (Int_Map,[Graph.U_Node],Int_Map,Int_Map,[(Rate.K_Type,Int)])
+
+-- | Generate 'Encoding_Maps' translating node identifiers to synthdef indexes.
+mk_encoding_maps :: Graph.U_Graph -> Encoding_Maps
+mk_encoding_maps (Graph.U_Graph _ cs ks us) =
+    (M.fromList (zip (map Graph.u_node_id cs) [0..])
+    ,ks
+    ,M.fromList (zip (map Graph.u_node_id ks) [0..])
+    ,M.fromList (zip (map Graph.u_node_id us) [0..])
+    ,Graph.u_node_mk_ktype_map us)
+
+-- | Locate index in map given node identifer 'UID_t'.
+uid_lookup :: Type.UID_t -> Int_Map -> Int
+uid_lookup = M.findWithDefault (error "uid_lookup")
+
+-- | Lookup 'K_Type' index from map (erroring variant of 'lookup').
+ktype_map_lookup :: Rate.K_Type -> [(Rate.K_Type,Int)] -> Int
+ktype_map_lookup k =
+    let e = error (show ("ktype_map_lookup",k))
+    in fromMaybe e . lookup k
+
+-- * Encoding
+
+-- | Byte-encode 'Graph.From_Port' primitive node.
+make_input :: Encoding_Maps -> Graph.From_Port -> Graphdef.Input
 make_input (cs,ks,_,us,kt) fp =
     case fp of
-      FromPort_C n -> G.Input (-1) (fetch n cs)
-      FromPort_K n t -> let i = ktype_map_lookup t kt
-                        in G.Input i (fetch_k n t ks)
-      FromPort_U n p -> G.Input (fetch n us) (fromMaybe 0 p)
+      Graph.From_Port_C n -> Graphdef.Input (-1) (uid_lookup n cs)
+      Graph.From_Port_K n t ->
+        let i = ktype_map_lookup t kt
+        in Graphdef.Input i (Graph.u_node_fetch_k n t ks)
+      Graph.From_Port_U n p -> Graphdef.Input (uid_lookup n us) (fromMaybe 0 p)
 
-node_k_to_control :: Maps -> Node -> G.Control
-node_k_to_control (_,_,ks,_,_) nd =
+-- | Byte-encode 'Graph.U_Node_K' primitive node.
+make_control :: Encoding_Maps -> Graph.U_Node -> Graphdef.Control
+make_control (_,_,ks,_,_) nd =
     case nd of
-      NodeK n _ _ nm _ _ _ -> (ascii nm,fetch n ks)
-      _ -> error "node_k_to_control"
+      Graph.U_Node_K n _ _ nm _ _ _ -> (Datum.ascii nm,uid_lookup n ks)
+      _ -> error "make_control"
 
--- | Byte-encode 'NodeU' primitive node.
-node_u_to_ugen :: Maps -> Node -> G.UGen
-node_u_to_ugen m n =
+-- | Byte-encode 'Graph.U_Node_U' primitive node.
+make_ugen :: Encoding_Maps -> Graph.U_Node -> Graphdef.UGen
+make_ugen m n =
     case n of
-      NodeU _ r nm i o (Special s) _ ->
+      Graph.U_Node_U _ r nm i o (Type.Special s) _ ->
           let i' = map (make_input m) i
-          in (ascii nm,rateId r,i',map rateId o,s)
+          in (Datum.ascii nm,Rate.rateId r,i',map Rate.rateId o,s)
       _ -> error "encode_node_u: illegal input"
 
 -- | Construct instrument definition bytecode.
-graph_to_graphdef :: String -> Graph -> G.Graphdef
+graph_to_graphdef :: String -> Graph.U_Graph -> Graphdef.Graphdef
 graph_to_graphdef nm g =
-    let Graph _ cs ks us = g
-        cs' = map node_c_value cs
-        mm = mk_maps g
-        ks_def = map node_k_default ks
-        ks_ctl = map (node_k_to_control mm) ks
-        us' = map (node_u_to_ugen mm) us
-    in G.Graphdef (ascii nm) cs' (zip ks_ctl ks_def) us'
+    let Graph.U_Graph _ cs ks us = g
+        cs' = map Graph.u_node_c_value cs
+        mm = mk_encoding_maps g
+        ks_def = map Graph.u_node_k_default ks
+        ks_ctl = map (make_control mm) ks
+        us' = map (make_ugen mm) us
+    in Graphdef.Graphdef (Datum.ascii nm) cs' (zip ks_ctl ks_def) us'
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,49 +1,49 @@
--- | Transform (read) a 'Graphdef' into a 'Graph'.
+-- | Decode (read) a 'Graphdef' into a 'Graph'.
 module Sound.SC3.Server.Graphdef.Read where
 
 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
-import qualified Sound.SC3.UGen.Type as U
+import qualified Sound.SC3.UGen.Graph as Graph
+import qualified Sound.SC3.UGen.Rate as Rate
+import qualified Sound.SC3.UGen.Type as Type
 
-mk_node_k :: Graphdef -> G.NodeId -> (Control,U.Sample) -> G.Node
-mk_node_k g z ((nm,ix),v) =
+control_to_node :: Graphdef -> Type.UID_t -> (Control,Type.Sample) -> Graph.U_Node
+control_to_node g z ((nm,ix),v) =
     let z' = graphdef_control_nid g z
         nm' = ascii_to_string nm
-    in G.NodeK z' R.KR (Just ix) nm' v G.K_KR Nothing
+    in Graph.U_Node_K z' Rate.KR (Just ix) nm' v Rate.K_KR Nothing
 
-input_to_from_port :: Graphdef -> Input -> G.FromPort
+input_to_from_port :: Graphdef -> Input -> Graph.From_Port
 input_to_from_port g (Input u p) =
     if u == -1
-    then G.FromPort_C (graphdef_constant_nid g p)
+    then Graph.From_Port_C (graphdef_constant_nid g p)
     else if input_is_control g (Input u p)
          then if u /= 0
               then error "multiple control UGens..."
-              else G.FromPort_K (graphdef_control_nid g p) G.K_KR
+              else Graph.From_Port_K (graphdef_control_nid g p) Rate.K_KR
          else let ugen = graphdef_ugens g !! u
                   port = if length (ugen_outputs ugen) > 1
                          then Just p
                          else Nothing
-              in G.FromPort_U (graphdef_ugen_nid g u) port
+              in Graph.From_Port_U (graphdef_ugen_nid g u) port
 
-mk_node_u :: Graphdef -> G.NodeId -> UGen -> G.Node
-mk_node_u g z u =
+ugen_to_node :: Graphdef -> Type.UID_t -> UGen -> Graph.U_Node
+ugen_to_node g z u =
     let (name,rate,inputs,outputs,special) = u
         z' = graphdef_ugen_nid g z
         rate' = toEnum rate
         name' = ascii_to_string name
         inputs' = map (input_to_from_port g) inputs
         outputs' = map toEnum outputs
-        special' = U.Special special
-    in G.NodeU z' rate' name' inputs' outputs' special' (U.UId z')
+        special' = Type.Special special
+    in Graph.U_Node_U z' rate' name' inputs' outputs' special' (Type.UId z')
 
-graphdef_to_graph :: Graphdef -> (String,G.Graph)
+graphdef_to_graph :: Graphdef -> (String,Graph.U_Graph)
 graphdef_to_graph g =
-    let constants_nd = zipWith G.NodeC [0..] (graphdef_constants g)
-        controls_nd = zipWith (mk_node_k g) [0 ..] (graphdef_controls g)
-        ugens_nd = zipWith (mk_node_u g) [0 ..] (graphdef_ugens g)
+    let constants_nd = zipWith Graph.U_Node_C [0..] (graphdef_constants g)
+        controls_nd = zipWith (control_to_node g) [0 ..] (graphdef_controls g)
+        ugens_nd = zipWith (ugen_to_node g) [0 ..] (graphdef_ugens g)
         nm = ascii_to_string (graphdef_name g)
-        gr = G.Graph (-1) constants_nd controls_nd ugens_nd
+        gr = Graph.U_Graph (-1) constants_nd controls_nd ugens_nd
     in (nm,gr) -- S.Synthdef nm gr
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
@@ -5,13 +5,13 @@
 import System.FilePath {- filepath -}
 import System.Process {- process -}
 
-import Sound.SC3.UGen.Help
+import qualified Sound.SC3.UGen.Help as Help
 
 {- | 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 "." "b_alloc" == r
 
 -}
 sc3_server_command_ref :: FilePath -> String -> FilePath
@@ -29,7 +29,7 @@
 -}
 viewServerHelp :: String -> IO ()
 viewServerHelp c = do
-  d <- sc3HelpDirectory
+  d <- Help.sc3HelpDirectory
   let nm = sc3_server_command_ref d c
-  br <- get_env_default "BROWSER" "x-www-browser"
+  br <- Help.get_env_default "BROWSER" "x-www-browser"
   void (rawSystem br ["file://" ++ nm])
diff --git a/Sound/SC3/Server/NRT.hs b/Sound/SC3/Server/NRT.hs
--- a/Sound/SC3/Server/NRT.hs
+++ b/Sound/SC3/Server/NRT.hs
@@ -1,7 +1,6 @@
 -- | Non-realtime score generation.
 module Sound.SC3.Server.NRT where
 
-import Data.Maybe {- base -}
 import qualified Data.ByteString.Lazy as B {- bytestring -}
 import System.FilePath {- filepath -}
 import System.IO {- base -}
@@ -10,7 +9,7 @@
 import Sound.OSC.Core {- hosc -}
 import qualified Sound.OSC.Coding.Byte as Byte {- hosc -}
 
-import Sound.SC3.Common.Prelude
+import Sound.SC3.Common.Base
 import Sound.SC3.Server.Enum
 
 -- | Encode and prefix with encoded length.
@@ -23,20 +22,27 @@
 -- | An 'NRT' score is a sequence of 'Bundle's.
 data NRT = NRT {nrt_bundles :: [Bundle]} deriving (Show)
 
+-- | Trivial NRT statistics.
 type NRT_STAT =
     ((String, Time)
     ,(String, Int)
     ,(String, Int)
     ,(String, [(String,Int)]))
 
+-- | NRT_STAT names.
+nrt_stat_param :: (String, String, String, String)
+nrt_stat_param = ("duration","# bundles","# messages","command set")
+
 -- | 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)))
+    in p4_zip
+       nrt_stat_param
+       (bundleTime (last b_seq)
+       ,length b_seq
+       ,sum (map length b_msg)
+       ,histogram (concatMap (map messageAddress) b_msg))
 
 -- | 'span' of 'f' of 'bundleTime'.  Can be used to separate the
 -- /initialisation/ and /remainder/ parts of a score.
@@ -47,7 +53,19 @@
 encodeNRT :: NRT -> B.ByteString
 encodeNRT = B.concat . map oscWithSize . nrt_bundles
 
--- | Write an 'NRT' score.
+{- | Write an 'NRT' score.
+
+import Sound.OSC
+import Sound.SC3
+m1 = g_new [(1, AddToTail, 0)]
+m2 = d_recv (synthdef "sin" (out 0 (sinOsc AR 660 0 * 0.15)))
+m3 = s_new "sin" 100 AddToTail 1 []
+m4 = n_free [100]
+m5 = nrt_end
+sc = NRT [bundle 0 [m1,m2],bundle 1 [m3],bundle 10 [m4],bundle 15 [m5]]
+writeNRT "/tmp/t.osc" sc
+
+-}
 writeNRT :: FilePath -> NRT -> IO ()
 writeNRT fn = B.writeFile fn . encodeNRT
 
@@ -76,29 +94,65 @@
 
 -- * Render
 
--- | 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, 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 parameters.
 
+The sound file type is inferred from the file name extension.
+Structure is:
+OSC file name,
+input audio file name and input number of channels,
+output audio file name and output number of channels,
+sample rate,
+sample format,
+further parameters (ie. ["-m","32768"]) to be inserted before the NRT -N option.
+
+-}
+type NRT_Param_Plain = (FilePath,(FilePath,Int),(FilePath,Int),Int,SampleFormat,[String])
+
+{- | Compile argument list from NRT_Param_Plain.
+
+> let opt = ("/tmp/t.osc",("_",0),("/tmp/t.wav",1),48000,PcmInt16,[])
+> let r = ["-i","0","-o","1","-N","/tmp/t.osc","_","/tmp/t.wav","48000","wav","int16"]
+> nrt_param_plain_to_arg opt == r
+
+-}
+nrt_param_plain_to_arg :: NRT_Param_Plain -> [String]
+nrt_param_plain_to_arg (osc_nm,(in_sf,in_nc),(out_sf,out_nc),sr,sf,param) =
+  let sf_ty = case takeExtension out_sf of
+                '.':ext -> soundFileFormat_from_extension_err ext
+                _ -> error "nrt_exec_plain: invalid sf extension"
+  in concat [["-i",show in_nc
+             ,"-o",show out_nc]
+            ,param
+            ,["-N"
+             ,osc_nm,in_sf,out_sf
+             ,show sr,soundFileFormatString sf_ty,sampleFormatString sf]]
+
+{- | Compile argument list from NRT_Param_Plain and run scynth.
+
+> nrt_exec_plain opt
+
+-}
+nrt_exec_plain :: NRT_Param_Plain -> IO ()
+nrt_exec_plain opt = callProcess "scsynth" (nrt_param_plain_to_arg opt)
+
 -- | 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,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
-                _ -> error "nrt_render_plain: invalid sf extension"
-      sys = unwords ["scsynth"
-                    ,"-i","0"
-                    ,"-o",show nc
-                    ,unwords param
-                    ,"-N"
-                    ,osc_nm,"_"
-                    ,sf_nm,show sr,soundFileFormatString sf_ty,sampleFormatString sf]
+nrt_proc_plain :: NRT_Param_Plain -> NRT -> IO ()
+nrt_proc_plain opt sc = do
+  let (osc_nm,_,_,_,_,_) = opt
   writeNRT osc_nm sc
-  _ <- system sys
-  return ()
+  nrt_exec_plain opt
+
+-- | Variant for no input case.
+type NRT_Render_Plain = (FilePath,FilePath,Int,Int,SampleFormat,[String])
+
+{- | Add ("-",0) as input parameters and run 'nrt_proc_plain'.
+
+> nrt_render_plain opt sc
+
+-}
+nrt_render_plain :: NRT_Render_Plain -> NRT -> IO ()
+nrt_render_plain (osc_nm,sf_nm,nc,sr,sf,param) sc =
+  let opt = (osc_nm,("_",0),(sf_nm,nc),sr,sf,param)
+  in nrt_proc_plain opt sc
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
@@ -1,7 +1,6 @@
 -- | Recording @scsynth@.
 module Sound.SC3.Server.Recorder where
 
-import Data.Default {- data-default -}
 import Sound.OSC {- hosc -}
 
 import Sound.SC3.Server.Command
@@ -38,8 +37,6 @@
                  ,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
diff --git a/Sound/SC3/Server/Status.hs b/Sound/SC3/Server/Status.hs
--- a/Sound/SC3/Server/Status.hs
+++ b/Sound/SC3/Server/Status.hs
@@ -1,4 +1,10 @@
--- | Request and display status information from the synthesis server.
+{- | Request and display status information from the synthesis server.
+
+\/status messages receive \/status.reply messages.
+
+\/g_queryTree messages recieve \/g_queryTree.reply messages.
+
+-}
 module Sound.SC3.Server.Status where
 
 import qualified Data.ByteString.Char8 as C {- bytestring -}
@@ -8,6 +14,10 @@
 
 import Sound.OSC.Datum {- hosc -}
 
+import Sound.SC3.Server.Command.Plain
+
+-- * Status
+
 -- | Get /n/th field of status as 'Floating'.
 extractStatusField :: Floating n => Int -> [Datum] -> n
 extractStatusField n =
@@ -40,13 +50,15 @@
 type Query_Ctl = (Either String Int,Either Double Int)
 
 -- | Nodes are either groups of synths.
-data Query_Node = Query_Group Int [Query_Node]
-                | Query_Synth Int String (Maybe [Query_Ctl])
+data Query_Node = Query_Group Group_Id [Query_Node]
+                | Query_Synth Synth_Id String (Maybe [Query_Ctl])
                 deriving (Eq,Show)
 
+-- | Pretty-print 'Query_Ctl'
 query_ctl_pp :: Query_Ctl -> String
 query_ctl_pp (p,q) = either id show p ++ ":" ++ either show show q
 
+-- | Pretty-print 'Query_Node'
 query_node_pp :: Query_Node -> String
 query_node_pp n =
     case n of
@@ -75,14 +87,14 @@
                 _ -> err "float/string" d
     in (f p,g q)
 
-{- | If /rc/ is 'True' then 'Query_Ctl' data is expected (ie. flag was set at @/g_queryTree@).
+{- | 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 :: Bool -> Synth_Id -> String -> [Datum] -> (Query_Node,[Datum])
 queryTree_synth rc k nm d =
     let pairs l = case l of
                     e0:e1:l' -> (e0,e1) : pairs l'
@@ -96,7 +108,8 @@
             in (Query_Synth k nm (Just p),d')
        else (Query_Synth k nm Nothing,d)
 
-queryTree_group :: Bool -> Int -> Int -> [Datum] -> (Query_Node,[Datum])
+-- | Generate 'Query_Node' for indicated 'Group_Id'.
+queryTree_group :: Bool -> Group_Id -> Int -> [Datum] -> (Query_Node,[Datum])
 queryTree_group rc gid nc =
     let recur n r d =
             if n == 0
@@ -105,6 +118,7 @@
                  in recur (n - 1) (c : r) d'
     in recur nc []
 
+-- | Either 'queryTree_synth' or 'queryTree_group'.
 queryTree_child :: Bool -> [Datum] -> (Query_Node,[Datum])
 queryTree_child rc d =
     case d of
@@ -114,14 +128,7 @@
           queryTree_group rc (fromIntegral gid) (fromIntegral nc) d'
       _ -> error "queryTree_child"
 
--- | Parse result of 'g_queryTree'.
---
--- > let r = [int32 1,int32 0,int32 2,int32 1,int32 1
--- >         ,int32 100,int32 1
--- >         ,int32 1000,int32 (-1),string "saw"
--- >         ,int32 1,string "freq",float 440.0
--- >         ,int32 2,int32 0]
--- > in queryTree r
+-- | Parse result of ' g_queryTree '.
 queryTree :: [Datum] -> Query_Node
 queryTree d =
     case d of
@@ -134,25 +141,14 @@
                _ -> error "queryTree"
       _ -> error "queryTree"
 
--- | Extact sequence of group-ids from 'Query_Node'.
-queryNode_to_group_seq :: Query_Node -> [Int]
+-- | Extact sequence of 'Group_Id's from 'Query_Node'.
+queryNode_to_group_seq :: Query_Node -> [Group_Id]
 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'.
---
--- > putStrLn (T.drawTree (fmap query_node_pp (queryTree_rt (queryTree r))))
--- > > 0
--- > > |
--- > > +- 1
--- > > |  |
--- > > |  `- 100
--- > > |     |
--- > > |     `- (1000,"saw","freq:440.0")
--- > > |
--- > > `- 2
 queryTree_rt :: Query_Node -> T.Tree Query_Node
 queryTree_rt n =
     case n of
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
@@ -1,38 +1,33 @@
--- | The unit-generator graph structure implemented by the
---   SuperCollider synthesis server.
+-- | The unit-generator graph structure implemented by the SuperCollider synthesis server.
 module Sound.SC3.Server.Synthdef where
 
 import qualified Data.ByteString.Lazy as L {- bytestring -}
-import Data.Default {- data-default -}
-import Data.List {- base -}
-import Data.Maybe {- base -}
 import System.FilePath {- filepath -}
 
-import qualified Sound.SC3.Server.Graphdef as G
-import qualified Sound.SC3.Server.Graphdef.Graph as G
 import Sound.SC3.UGen.Graph
 import Sound.SC3.UGen.Help.Graph
 import Sound.SC3.UGen.Type
-import Sound.SC3.UGen.UGen
 
+import qualified Sound.SC3.Server.Graphdef as Graphdef
+import qualified Sound.SC3.Server.Graphdef.Graph as Graph
+
 -- | A named unit generator graph.
 data Synthdef = Synthdef {synthdefName :: String
                          ,synthdefUGen :: UGen}
                 deriving (Eq,Show)
 
-instance Default Synthdef where def = defaultSynthdef
-
--- | Lift a 'UGen' graph into a 'Synthdef'.
+-- | Alias for 'Synthdef'.
 synthdef :: String -> UGen -> Synthdef
 synthdef = Synthdef
 
--- | The SC3 /default/ instrument 'Synthdef', see
--- 'default_ugen_graph'.
---
--- > import Sound.OSC {- hosc -}
--- > import Sound.SC3 {- hsc3 -}
--- > withSC3 (sendMessage (d_recv defaultSynthdef))
--- > audition defaultSynthdef
+{- | The SC3 /default/ instrument 'Synthdef', see 'default_ugen_graph'.
+
+> import Sound.OSC {- hosc -}
+> import Sound.SC3 {- hsc3 -}
+> withSC3 (sendMessage (d_recv defaultSynthdef))
+> audition defaultSynthdef
+
+-}
 defaultSynthdef :: Synthdef
 defaultSynthdef = synthdef "default" default_ugen_graph
 
@@ -47,32 +42,22 @@
     in synthdef nm (default_sampler_ugen_graph use_gate)
 
 -- | 'ugen_to_graph' of 'synthdefUGen'.
-synthdefGraph :: Synthdef -> Graph
+synthdefGraph :: Synthdef -> U_Graph
 synthdefGraph = ugen_to_graph . synthdefUGen
 
 -- | Parameter names at 'Synthdef'.
 --
 -- > synthdefParam defaultSynthdef == ["amp","pan","gate","freq","out"]
 synthdefParam :: Synthdef -> [String]
-synthdefParam = map node_k_name . controls . synthdefGraph
-
--- | Find the indices of the named UGen at 'Graph'.  The index is
--- required when using 'Sound.SC3.Server.Command.u_cmd'.
-ugenIndices :: String -> Graph -> [Integer]
-ugenIndices nm =
-    let f (k,nd) =
-            case nd of
-              NodeU _ _ nm' _ _ _ _ -> if nm == nm' then Just k else Nothing
-              _ -> Nothing
-    in mapMaybe f . zip [0..] . ugens
+synthdefParam = map u_node_k_name . ug_controls . synthdefGraph
 
 -- | 'graph_to_graphdef' at 'Synthdef'.
-synthdef_to_graphdef :: Synthdef -> G.Graphdef
-synthdef_to_graphdef (Synthdef nm u) = G.graph_to_graphdef nm (ugen_to_graph u)
+synthdef_to_graphdef :: Synthdef -> Graphdef.Graphdef
+synthdef_to_graphdef (Synthdef nm u) = Graph.graph_to_graphdef nm (ugen_to_graph u)
 
 -- | Encode 'Synthdef' as a binary data stream.
 synthdefData :: Synthdef -> L.ByteString
-synthdefData = G.encode_graphdef . synthdef_to_graphdef
+synthdefData = Graphdef.encode_graphdef . synthdef_to_graphdef
 
 -- | Write 'Synthdef' to indicated directory.  The filename is the
 -- 'synthdefName' with the appropriate extension (@scsyndef@).
@@ -81,30 +66,18 @@
     let nm = dir </> synthdefName s <.> "scsyndef"
     in L.writeFile nm (synthdefData s)
 
--- | Simple statistical analysis of a unit generator graph.
-graph_stat :: Graph -> [String]
-graph_stat s =
-    let cs = constants s
-        ks = controls s
-        us = ugens s
-        u_nm z = ugen_user_name (node_u_name z) (node_u_special z)
-        f g = let h (x:xs) = (x,length (x:xs))
-                  h [] = error "graph_stat"
-              in show . map h . group . sort . map g
-        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_ln' of 'synth'.
+synthstat_ln :: UGen -> [String]
+synthstat_ln = ug_stat_ln . ugen_to_graph
 
--- | 'graph_stat' of 'synth'.
+-- | 'unlines' of 'synthstat_ln'.
+--
+-- > putStrLn $ synthstat Sound.SC3.UGen.Help.Graph.default_ugen_graph
 synthstat :: UGen -> String
-synthstat = unlines . synthstat'
-
+synthstat = unlines . synthstat_ln
 
+-- | Variant without UGen sequence.
+--
+-- > putStrLn $ synthstat_concise (default_sampler_ugen_graph True)
+synthstat_concise :: UGen -> String
+synthstat_concise = unlines . reverse . drop 1 . reverse . synthstat_ln
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,10 +4,10 @@
 -- 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 Data.List {- base -}
+import qualified Data.List.Split as Split {- split -}
+
 import Sound.OSC.FD {- hosc -}
 
 import Sound.SC3.Server.Command
@@ -82,6 +82,7 @@
 nrt_play :: Transport t => t -> NRT -> IO ()
 nrt_play fd sc = time >>= \t0 -> mapM_ (run_bundle fd t0) (nrt_bundles sc)
 
+-- | 'withSC3' of 'nrt_play'
 nrt_audition :: NRT -> IO ()
 nrt_audition sc = withSC3 (\fd -> nrt_play fd sc)
 
@@ -102,9 +103,11 @@
 instance Audible UGen where
     play_id = playUGen
 
+-- | 'withSC3' of 'play_id'
 audition_id :: Audible e => Int -> e -> IO ()
 audition_id k e = withSC3 (\fd -> play_id k fd e)
 
+-- | 'audition_id' of @-1@.
 audition :: Audible e => e -> IO ()
 audition = audition_id (-1)
 
@@ -126,11 +129,9 @@
 -- > withSC3 (\fd -> b_getn1_data fd 0 (0,5))
 b_getn1_data :: Transport t => t -> Int -> (Int,Int) -> IO [Double]
 b_getn1_data fd 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 fd (b_getn1 b s)
-  fmap f (waitDatum fd "/b_setn")
+  fmap f (waitReply fd "/b_setn")
 
 -- | Variant of 'b_getn1_data' that segments individual 'b_getn'
 -- messages to /n/ elements.
@@ -145,15 +146,14 @@
 -- | Variant of 'b_getn1_data_segment' that gets the entire buffer.
 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))
-                      deinterleave = transpose . chunksOf (fromIntegral nc)
-                  in liftM deinterleave (b_getn1_data_segment fd n b ix)
-              _ -> error "b_fetch"
+  let f m = let (_,nf,nc,_) = unpack_b_info_err m
+                ix = (0,nf * nc)
+                deinterleave = transpose . Split.chunksOf nc
+            in liftM deinterleave (b_getn1_data_segment fd n b ix)
   sendMessage fd (b_query1 b)
-  waitDatum fd "/b_info" >>= f
+  waitReply fd "/b_info" >>= f
 
+-- | 'head' of 'b_fetch'.
 b_fetch1 :: Transport t => t -> Int -> Int -> IO [Double]
 b_fetch1 fd n b = liftM head (b_fetch fd n b)
 
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
@@ -3,22 +3,23 @@
 
 import Control.Monad {- base -}
 import Data.List {- base -}
-import Data.List.Split {- split -}
+import qualified Data.List.Split as Split {- split -}
 import Data.Maybe {- base -}
-import Safe {- safe -}
+import qualified Data.Tree as Tree {- containers -}
+import qualified 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
-import Sound.SC3.Server.Status
-import Sound.SC3.Server.Synthdef
+import qualified Sound.SC3.Server.Enum as Enum
+import qualified Sound.SC3.Server.Graphdef as Graphdef
+import qualified Sound.SC3.Server.NRT as NRT
+import qualified Sound.SC3.Server.Status as Status
+import qualified Sound.SC3.Server.Synthdef as Synthdef
 
 import Sound.SC3.UGen.Bindings.Composite (wrapOut)
-import Sound.SC3.UGen.Type
+import Sound.SC3.UGen.Type (UGen)
 
 -- * hosc variants
 
@@ -57,6 +58,10 @@
 withSC3_ :: Connection UDP a -> IO ()
 withSC3_ = void . withSC3
 
+-- | 'timeout_r' of 'withSC3'
+withSC3_tm :: Double -> Connection UDP a -> IO (Maybe a)
+withSC3_tm tm = timeout_r tm . withSC3
+
 -- * Server control
 
 -- | Free all nodes ('g_freeAll') at group @1@.
@@ -70,33 +75,35 @@
 reset =
     let m = [clearSched
             ,n_free [1,2]
-            ,g_new [(1,AddToHead,0),(2,AddToTail,0)]]
+            ,g_new [(1,Enum.AddToHead,0),(2,Enum.AddToTail,0)]]
     in sendBundle (bundle immediately m)
 
 -- | (node-id,add-action,group-id,parameters)
-type Play_Opt = (Node_Id,AddAction,Group_Id,[(String,Double)])
+type Play_Opt = (Node_Id,Enum.AddAction,Group_Id,[(String,Double)])
 
-play_graphdef_msg :: Play_Opt -> G.Graphdef -> Message
+-- | Make 's_new' message to play 'Graphdef.Graphdef'.
+play_graphdef_msg :: Play_Opt -> Graphdef.Graphdef -> Message
 play_graphdef_msg (nid,act,gid,param) g =
-    let nm = ascii_to_string (G.graphdef_name g)
+    let nm = ascii_to_string (Graphdef.graphdef_name g)
     in s_new nm nid act gid param
 
 -- | Send 'd_recv' and 's_new' messages to scsynth.
-playGraphdef :: DuplexOSC m => Play_Opt -> G.Graphdef -> m ()
+playGraphdef :: DuplexOSC m => Play_Opt -> Graphdef.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
+-- | Make 's_new' message to play 'Synthdef.Synthdef'.
+play_synthdef_msg :: Play_Opt -> Synthdef.Synthdef -> Message
+play_synthdef_msg (nid,act,gid,param) syn = s_new (Synthdef.synthdefName syn) nid act gid param
 
 -- | Send 'd_recv' and 's_new' messages to scsynth.
-playSynthdef :: DuplexOSC m => Play_Opt -> Synthdef -> m ()
+playSynthdef :: DuplexOSC m => Play_Opt -> Synthdef.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 => Play_Opt -> UGen -> m ()
 playUGen loc =
     playSynthdef loc .
-    synthdef "Anonymous" .
+    Synthdef.synthdef "Anonymous" .
     wrapOut Nothing
 
 -- * NRT
@@ -118,24 +125,25 @@
 > in withSC3 (nrt_play sc)
 
 -}
-nrt_play :: Transport m => NRT -> m ()
+nrt_play :: Transport m => NRT.NRT -> m ()
 nrt_play sc = do
   t0 <- liftIO time
-  mapM_ (run_bundle t0) (nrt_bundles sc)
+  mapM_ (run_bundle t0) (NRT.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@.
-nrt_play_reorder :: Transport m => NRT -> m ()
+nrt_play_reorder :: Transport m => NRT.NRT -> m ()
 nrt_play_reorder s = do
-  let (i,r) = nrt_span (<= 0) s
+  let (i,r) = NRT.nrt_span (<= 0) s
       i' = concatMap bundleMessages i
       (a,b) = partition_async i'
   mapM_ async a
   t <- liftIO time
   mapM_ (run_bundle t) (Bundle 0 b : r)
 
-nrt_audition :: NRT -> IO ()
+-- | 'withSC3' of 'nrt_play'.
+nrt_audition :: NRT.NRT -> IO ()
 nrt_audition = withSC3 . nrt_play
 
 -- * Audible
@@ -145,12 +153,12 @@
     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,Enum.AddToHead,1,[])
 
-instance Audible G.Graphdef where
+instance Audible Graphdef.Graphdef where
     play_at = playGraphdef
 
-instance Audible Synthdef where
+instance Audible Synthdef.Synthdef where
     play_at = playSynthdef
 
 instance Audible UGen where
@@ -162,7 +170,7 @@
 
 -- | Variant where /id/ is @-1@.
 audition :: Audible e => e -> IO ()
-audition = audition_at (-1,AddToHead,1,[])
+audition = audition_at (-1,Enum.AddToHead,1,[])
 
 -- * Notifications
 
@@ -178,7 +186,7 @@
 
 -- | Variant of 'b_getn1' that waits for return message and unpacks it.
 --
--- > withSC3 (b_getn1_data 0 (0,5))
+-- > withSC3_tm 1.0 (b_getn1_data 0 (0,5))
 b_getn1_data :: DuplexOSC m => Int -> (Int,Int) -> m [Double]
 b_getn1_data b s = do
   let f m = let (_,_,_,r) = unpack_b_setn_err m in r
@@ -188,7 +196,7 @@
 -- | Variant of 'b_getn1_data' that segments individual 'b_getn'
 -- messages to /n/ elements.
 --
--- > withSC3 (b_getn1_data_segment 1 0 (0,5))
+-- > withSC3_tm 1.0 (b_getn1_data_segment 1 0 (0,5))
 b_getn1_data_segment :: DuplexOSC m =>
                         Int -> Int -> (Int,Int) -> m [Double]
 b_getn1_data_segment n b (i,j) = do
@@ -197,12 +205,11 @@
   return (concat d)
 
 -- | Variant of 'b_getn1_data_segment' that gets the entire buffer.
---
 b_fetch :: DuplexOSC m => Int -> Int -> m [[Double]]
 b_fetch n b = do
   let f m = let (_,nf,nc,_) = unpack_b_info_err m
                 ix = (0,nf * nc)
-                deinterleave = transpose . chunksOf nc
+                deinterleave = transpose . Split.chunksOf nc
             in liftM deinterleave (b_getn1_data_segment n b ix)
   sendMessage (b_query1 b)
   waitReply "/b_info" >>= f
@@ -211,7 +218,7 @@
 --
 -- > 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)
+b_fetch1 n b = liftM (Safe.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]])
@@ -242,6 +249,7 @@
   sendMessage (c_getn1 s)
   liftM f (waitDatum "/c_setn")
 
+-- | Apply /f/ to result of 'n_query'.
 n_query1_unpack_f :: Transport m => (Message -> t) -> Node_Id -> m t
 n_query1_unpack_f f n = do
   sendMessage (n_query [n])
@@ -252,36 +260,50 @@
 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
 
+-- | Variant of 'n_query1_unpack' that returns plain (un-lifted) result.
 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 :: Transport m => Group_Id -> m Status.Query_Node
 g_queryTree1_unpack n = do
   sendMessage (g_queryTree [(n,True)])
   r <- waitReply "/g_queryTree.reply"
-  return (queryTree (messageDatum r))
+  return (Status.queryTree (messageDatum r))
 
 -- * Status
 
 -- | Collect server status information.
+--
+-- > withSC3 serverStatus >>= mapM putStrLn
 serverStatus :: DuplexOSC m => m [String]
-serverStatus = liftM statusFormat serverStatusData
+serverStatus = liftM Status.statusFormat serverStatusData
 
 -- | Read nominal sample rate of server.
 --
 -- > withSC3 serverSampleRateNominal
 serverSampleRateNominal :: DuplexOSC m => m Double
-serverSampleRateNominal = liftM (extractStatusField 7) serverStatusData
+serverSampleRateNominal = liftM (Status.extractStatusField 7) serverStatusData
 
 -- | Read actual sample rate of server.
 --
 -- > withSC3 serverSampleRateActual
 serverSampleRateActual :: DuplexOSC m => m Double
-serverSampleRateActual = liftM (extractStatusField 8) serverStatusData
+serverSampleRateActual = liftM (Status.extractStatusField 8) serverStatusData
 
 -- | Retrieve status data from server.
 serverStatusData :: DuplexOSC m => m [Datum]
 serverStatusData = do
   sendMessage status
   waitDatum "/status.reply"
+
+-- * Tree
+
+-- | Collect server node tree information.
+--
+-- > withSC3 serverTree >>= mapM_ putStrLn
+serverTree :: Transport m => m [String]
+serverTree = do
+  qt <- g_queryTree1_unpack 0
+  let tr = Status.queryTree_rt qt
+  return (["***** SuperCollider Server Tree *****",Tree.drawTree (fmap Status.query_node_pp tr)])
diff --git a/Sound/SC3/UGen.hs b/Sound/SC3/UGen.hs
--- a/Sound/SC3/UGen.hs
+++ b/Sound/SC3/UGen.hs
@@ -6,13 +6,10 @@
 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
 import Sound.SC3.UGen.Operator as U
 import Sound.SC3.UGen.Optimise as U
-import Sound.SC3.UGen.Protect as U
 import Sound.SC3.UGen.Rate as U
 import Sound.SC3.UGen.Type as U
 import Sound.SC3.UGen.UGen as U
-import Sound.SC3.UGen.UId as U
diff --git a/Sound/SC3/UGen/Analysis.hs b/Sound/SC3/UGen/Analysis.hs
--- a/Sound/SC3/UGen/Analysis.hs
+++ b/Sound/SC3/UGen/Analysis.hs
@@ -7,18 +7,18 @@
 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 =
+-- | UGen primitive set.
+--   Sees through Proxy and MRG, possible multiple primitives for MCE.
+ugen_primitive_set :: UGen -> [Primitive]
+ugen_primitive_set 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)
+      MCE_U m -> concatMap ugen_primitive_set (MCE.mce_elem m)
+      MRG_U m -> ugen_primitive_set (mrgLeft m)
 
 -- | Heuristic based on primitive name (@FFT@, @PV_@).  Note that
 -- @IFFT@ is at /control/ rate, not @PV@ rate.
@@ -27,7 +27,7 @@
 
 -- | Variant on primitive_is_pv_rate.
 ugen_is_pv_rate :: UGen -> Bool
-ugen_is_pv_rate = any (primitive_is_pv_rate . ugenName) . ugen_primitive
+ugen_is_pv_rate = any (primitive_is_pv_rate . ugenName) . ugen_primitive_set
 
 -- | Traverse input graph until an @FFT@ or @PV_Split@ node is
 -- encountered, and then locate the buffer input.  Biases left at MCE
@@ -41,7 +41,7 @@
 -- > 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
+    case ugen_primitive_set u of
       [] -> Left "pv_track_buffer: not located"
       p:_ -> case ugenName p of
                "FFT" -> Right (ugenInputs p !! 0)
@@ -56,7 +56,7 @@
 -- > buffer_nframes (localBuf 'α' 2048 1) == 2048
 buffer_nframes :: UGen -> UGen
 buffer_nframes u =
-    case ugen_primitive u of
+    case ugen_primitive_set u of
       [] -> DB.bufFrames (rateOf u) u
       p:_ -> case ugenName p of
                "LocalBuf" -> ugenInputs p !! 1
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
@@ -1,3 +1,4 @@
+-- | SC3 UGen bindings (composite module).
 module Sound.SC3.UGen.Bindings (module B) where
 
 import Sound.SC3.UGen.Bindings.Composite 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
@@ -3,21 +3,23 @@
 
 import Control.Monad {- base -}
 import Data.List {- base -}
-import Data.List.Split {- split -}
+import qualified Data.List.Split as Split {- split -}
 import Data.Maybe {- base -}
 
 import Sound.SC3.Common.Envelope
+import Sound.SC3.Common.Math
+import Sound.SC3.Common.Math.Filter.BEQ
 
+import Sound.SC3.Common.UId
 import Sound.SC3.UGen.Bindings.DB
+import qualified Sound.SC3.UGen.Bindings.DB.External as External
 import Sound.SC3.UGen.Bindings.HW
 import Sound.SC3.UGen.Bindings.Monad
 import Sound.SC3.UGen.Enum
-import Sound.SC3.UGen.Identifier
 import Sound.SC3.UGen.Math
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
 import Sound.SC3.UGen.UGen
-import Sound.SC3.UGen.UId
 
 -- | Generate a localBuf and use setBuf to initialise it.
 asLocalBuf :: ID i => i -> [UGen] -> UGen
@@ -26,20 +28,20 @@
         s = setBuf' b xs 0
     in mrg2 b s
 
--- | Calculate coefficients for bi-quad low pass filter.
-bLowPassCoef :: Floating a => a -> a -> a -> (a,a,a,a,a)
-bLowPassCoef sr freq rq =
-    let w0 = pi * 2 * freq * (1 / sr)
-        cos_w0 = cos w0
-        i = 1 - cos_w0
-        alpha = sin w0 * 0.5 * rq
-        b0rz = recip (1 + alpha)
-        a0 = i * 0.5 * b0rz
-        a1 = i * b0rz
-        b1 = cos_w0 * 2 * b0rz
-        b2 = (1 - alpha) * negate b0rz
-    in (a0,a1,a0,b1,b2)
+-- | 24db/oct rolloff - 4th order resonant Low Pass Filter
+bLowPass4 :: UGen -> UGen -> UGen -> UGen
+bLowPass4 i f rq =
+  let (a0, a1, a2, b1, b2) = bLowPassCoef sampleRate f rq
+      flt z = sos z a0 a1 a2 b1 b2
+  in flt (flt i)
 
+-- | 24db/oct rolloff - 4th order resonant Hi Pass Filter
+bHiPass4 :: UGen -> UGen -> UGen -> UGen
+bHiPass4 i f rq =
+  let (a0, a1, a2, b1, b2) = bHiPassCoef sampleRate f rq
+      flt z = sos z a0 a1 a2 b1 b2
+  in flt (flt i)
+
 -- | Buffer reader (no interpolation).
 bufRdN :: Int -> Rate -> UGen -> UGen -> Loop -> UGen
 bufRdN n r b p l = bufRd n r b p l NoInterpolation
@@ -62,7 +64,7 @@
 
 -- | 'liftUId' of 'choose'.
 chooseM :: UId m => UGen -> m UGen
-chooseM = liftUId choose
+chooseM = liftUId1 choose
 
 -- | 'clearBuf' of 'localBuf'.
 clearLocalBuf :: ID a => a -> UGen -> UGen -> UGen
@@ -96,6 +98,10 @@
         gen _ = 0
     in gen (mceChannels s)
 
+-- | 'linExp' with input range of (-1,1).
+exprange :: UGen -> UGen -> UGen -> UGen
+exprange l r s = linExp s (-1) 1 l r
+
 -- | Variant FFT constructor with default values for hop size (0.5),
 -- window type (0), active status (1) and window size (0).
 fft' :: UGen -> UGen -> UGen
@@ -121,6 +127,17 @@
         h = hilbert i
     in mix (h * o)
 
+-- | Variant of 'hilbert' using FFT (with a delay) for better results.
+-- Buffer should be 2048 or 1024.
+-- 2048 = better results, more delay.
+-- 1024 = less delay, little choppier results.
+hilbertFIR :: UGen -> UGen -> UGen
+hilbertFIR s b =
+  let c0 = fft' b s
+      c1 = pv_PhaseShift90 c0
+      delay = bufDur KR b
+  in mce2 (delayN s delay delay) (ifft' c1)
+
 -- | Variant ifft with default value for window type.
 ifft' :: UGen -> UGen
 ifft' buf = ifft buf 0 0
@@ -146,8 +163,8 @@
 klangSpec = klanx_spec_f id mce
 
 -- | Variant of 'klangSpec' for non-UGen inputs.
-klangSpec' :: Real n => [n] -> [n] -> [n] -> UGen
-klangSpec' = klanx_spec_f (map constant) mce
+klangSpec_k :: Real n => [n] -> [n] -> [n] -> UGen
+klangSpec_k = klanx_spec_f (map constant) mce
 
 -- | Variant of 'klangSpec' for 'MCE' inputs.
 klangSpec_mce :: UGen -> UGen -> UGen -> UGen
@@ -158,8 +175,8 @@
 klankSpec = klanx_spec_f id mce
 
 -- | Variant for non-UGen inputs.
-klankSpec' :: Real n => [n] -> [n] -> [n] -> UGen
-klankSpec' = klanx_spec_f (map constant) mce
+klankSpec_k :: Real n => [n] -> [n] -> [n] -> UGen
+klankSpec_k = klanx_spec_f (map constant) mce
 
 -- | Variant of 'klankSpec' for 'MCE' inputs.
 klankSpec_mce :: UGen -> UGen -> UGen -> UGen
@@ -171,7 +188,7 @@
 
 -- | 'liftUId' of 'lchoose'.
 lchooseM :: UId m => [UGen] -> m UGen
-lchooseM = liftUId lchoose
+lchooseM = liftUId1 lchoose
 
 -- | 'linExp' of (-1,1).
 linExp_b :: UGen -> UGen -> UGen -> UGen
@@ -207,7 +224,7 @@
     let dt = control KR "fadeTime" (realToFrac fadeTime)
         gate_ = control KR "gate" 1
         startVal = dt <=* 0
-        env = Envelope [startVal,1,0] [1,1] [EnvLin,EnvLin] (Just 1) Nothing
+        env = Envelope [startVal,1,0] [1,1] [EnvLin,EnvLin] (Just 1) Nothing 0
     in envGen KR gate_ 1 0 dt RemoveSynth env
 
 -- | Count 'mce' channels.
@@ -221,7 +238,7 @@
 -- | Mix variant, sum to n channels.
 mixN :: Int -> UGen -> UGen
 mixN n u =
-    let xs = transpose (chunksOf n (mceChannels u))
+    let xs = transpose (Split.chunksOf n (mceChannels u))
     in mce (map sum xs)
 
 -- | Construct and sum a set of UGens.
@@ -309,6 +326,16 @@
         mp = uncurry packFFTSpec (unzip e)
     in packFFT c nf from to z mp
 
+-- | /dur/ and /hop/ are in seconds, /frameSize/ and /sampleRate/ in
+-- frames, though the latter maybe fractional.
+--
+-- > pv_calcPVRecSize 4.2832879818594 1024 0.25 48000.0 == 823299
+pv_calcPVRecSize :: Double -> Int -> Double -> Double -> Int
+pv_calcPVRecSize dur frame_size hop sample_rate =
+    let frame_size' = fromIntegral frame_size
+        raw_size = ceiling ((dur * sample_rate) / frame_size') * frame_size
+    in ceiling (fromIntegral raw_size * recip hop + 3)
+
 -- | 'rand' with left edge set to zero.
 rand0 :: ID a => a -> UGen -> UGen
 rand0 z = rand z 0
@@ -344,7 +371,13 @@
 silent :: Int -> UGen
 silent n = let s = dc AR 0 in mce (replicate n s)
 
--- | Zero indexed audio input buses.
+{- | Zero indexed audio input buses.
+     Optimises case of consecutive UGens.
+
+> soundIn (mce2 0 1) == in' 2 AR numOutputBuses
+> soundIn (mce2 0 2) == in' 1 AR (numOutputBuses + mce2 0 2)
+
+-}
 soundIn :: UGen -> UGen
 soundIn u =
     let r = in' 1 AR (numOutputBuses + u)
@@ -383,12 +416,12 @@
 
 -- | Randomly select one of several inputs on trigger.
 tChoose :: ID m => m -> UGen -> UGen -> UGen
-tChoose z t a = select (tIRand z 0 (mceN a) t) a
+tChoose z t a = select (tiRand z 0 (mceN a) t) a
 
 -- | Randomly select one of several inputs.
 tChooseM :: (UId m) => UGen -> UGen -> m UGen
 tChooseM t a = do
-  r <- tIRandM 0 (constant (length (mceChannels a))) t
+  r <- tiRandM 0 (constant (length (mceChannels a))) t
   return (select r a)
 
 -- | Triangle wave as sum of /n/ sines.
@@ -418,6 +451,15 @@
 unpackFFT :: UGen -> UGen -> UGen -> UGen -> UGen -> [UGen]
 unpackFFT c nf from to w = map (\i -> unpack1FFT c nf i w) [from .. to]
 
+-- | VarLag in terms of envGen
+varLag_env :: UGen -> UGen -> Envelope_Curve UGen -> UGen -> UGen
+varLag_env in_ time curve start =
+  let rt = rateOf in_
+      e = Envelope [start,in_] [time] [curve] Nothing Nothing 0
+      time_ch = if rateOf time == IR then 0 else changed time 0
+      tr = changed in_ 0 + time_ch + impulse rt 0 0
+  in envGen rt tr 1 0 1 DoNothing e
+
 -- | If @z@ isn't a sink node route to an @out@ node writing to @bus@.
 -- If @fadeTime@ is given multiply by 'makeFadeEnv'.
 --
@@ -433,6 +475,7 @@
 
 -- * wslib
 
+-- | Cross-fading version of 'playBuf'.
 playBufCF :: Int -> UGen -> UGen -> UGen -> UGen -> Loop -> UGen -> Int -> UGen
 playBufCF nc bufnum rate trigger startPos loop lag' n =
     let trigger' = if rateOf trigger == DR
@@ -464,3 +507,16 @@
 osc1 rt buf dur doneAction =
     let ph = line rt 0 (bufFrames IR buf - 1) dur doneAction
     in bufRd 1 rt buf ph NoLoop LinearInterpolation
+
+-- * External
+
+-- | FM7 variant where input matrices are not in MCE form.
+fm7_mx :: [[UGen]] -> [[UGen]] -> UGen
+fm7_mx ctlMatrix modMatrix = External.fm7 AR (mce (concat ctlMatrix)) (mce (concat modMatrix))
+
+-- | pulse signal as difference of two 'sawDPW' signals.
+pulseDPW :: Rate -> UGen -> UGen -> UGen
+pulseDPW rt freq width =
+  let o1 = External.sawDPW rt freq 0
+      o2 = External.sawDPW rt freq (wrap_hs (-1,1) (width+width))
+  in o1 - o2
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,9 +1,9 @@
+-- | SC3 UGen bindings (auto-generated).
 module Sound.SC3.UGen.Bindings.DB where
 
 import Sound.SC3.Common.Envelope
-
+import Sound.SC3.Common.UId
 import Sound.SC3.UGen.Enum
-import Sound.SC3.UGen.Identifier
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
 import Sound.SC3.UGen.UGen
@@ -11,8 +11,8 @@
 -- | 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
+a2k :: UGen -> UGen
+a2k in_ = mkUGen Nothing [KR] (Left KR) "A2K" [in_] Nothing 1 (Special 0) NoId
 
 -- | FIXME: APF purpose.
 --
@@ -190,19 +190,19 @@
 
 -- | Buffer based all pass delay line with cubic interpolation.
 --
---  BufAllpassC [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0
+--  BufAllpassC [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
 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 [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0
+--  BufAllpassL [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
 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 [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0
+--  BufAllpassN [AR] buf=0.0 in=0.0 delaytime=0.2 decaytime=1.0;    FILTER: TRUE
 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
 
@@ -232,19 +232,19 @@
 
 -- | Buffer based simple delay line with cubic interpolation.
 --
---  BufDelayC [KR,AR] buf=0.0 in=0.0 delaytime=0.2
+--  BufDelayC [KR,AR] buf=0.0 in=0.0 delaytime=0.2;    FILTER: TRUE
 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 [KR,AR] buf=0.0 in=0.0 delaytime=0.2
+--  BufDelayL [KR,AR] buf=0.0 in=0.0 delaytime=0.2;    FILTER: TRUE
 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 [KR,AR] buf=0.0 in=0.0 delaytime=0.2
+--  BufDelayN [KR,AR] buf=0.0 in=0.0 delaytime=0.2;    FILTER: TRUE
 bufDelayN :: UGen -> UGen -> UGen -> UGen
 bufDelayN buf in_ delaytime = mkUGen Nothing [KR,AR] (Right [1]) "BufDelayN" [buf,in_,delaytime] Nothing 1 (Special 0) NoId
 
@@ -288,7 +288,7 @@
 --
 --  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
+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.
 --
@@ -498,7 +498,7 @@
 --
 --  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 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
 --
@@ -540,7 +540,7 @@
 --
 --  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
+diskOut bufnum input = mkUGen Nothing [AR] (Left AR) "DiskOut" [bufnum] (Just [input]) 1 (Special 0) NoId
 
 -- | Demand rate white noise random generator.
 --
@@ -570,7 +570,7 @@
 --
 --  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)
+drand z repeats list_ = mkUGen Nothing [DR] (Left DR) "Drand" [repeats] (Just [list_]) 1 (Special 0) (toUId z)
 
 -- | demand rate reset
 --
@@ -582,13 +582,13 @@
 --
 --  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)
+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)
+dser z repeats list_ = mkUGen Nothing [DR] (Left DR) "Dser" [repeats] (Just [list_]) 1 (Special 0) (toUId z)
 
 -- | Demand rate arithmetic series UGen.
 --
@@ -600,7 +600,7 @@
 --
 --  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)
+dshuf z repeats list_ = mkUGen Nothing [DR] (Left DR) "Dshuf" [repeats] (Just [list_]) 1 (Special 0) (toUId z)
 
 -- | Demand rate input replicator
 --
@@ -612,13 +612,13 @@
 --
 --  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)
+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)
+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
 --
@@ -650,21 +650,29 @@
 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 [DR] repeats=1.0 weights=0.0 *list=0.0;    MCE, REORDERS INPUTS: [2,1,0], DEMAND/NONDET
+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)
+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
+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 [IR] lo=1.0e-2 hi=1.0;    NONDET
 expRand :: ID a => a -> UGen -> UGen -> UGen
 expRand z lo hi = mkUGen Nothing [IR] (Left IR) "ExpRand" [lo,hi] Nothing 1 (Special 0) (toUId z)
 
@@ -845,8 +853,8 @@
 -- | 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
+hpz2 :: UGen -> UGen
+hpz2 in_ = mkUGen Nothing [KR,AR] (Right [0]) "HPZ2" [in_] Nothing 1 (Special 0) NoId
 
 -- | Randomized value.
 --
@@ -878,17 +886,11 @@
 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
+iEnvGen rate index_ envelope_ = mkUGen Nothing [KR,AR] (Left rate) "IEnvGen" [index_] (Just [envelope_to_ienvgen_ugen envelope_]) 1 (Special 0) NoId
 
 -- | Inverse Fast Fourier Transform
 --
@@ -953,8 +955,8 @@
 -- | 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
+indexL :: UGen -> UGen -> UGen
+indexL bufnum in_ = mkUGen Nothing [KR,AR] (Right [1]) "IndexL" [bufnum,in_] Nothing 1 (Special 0) NoId
 
 -- | Base class for info ugens
 --
@@ -971,8 +973,8 @@
 -- | 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
+k2a :: UGen -> UGen
+k2a in_ = mkUGen Nothing [AR] (Left AR) "K2A" [in_] Nothing 1 (Special 0) NoId
 
 -- | Respond to the state of a key
 --
@@ -990,13 +992,13 @@
 --
 --  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
+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
+klank input freqscale freqoffset decayscale specificationsArrayRef = mkUGen Nothing [AR] (Right [0]) "Klank" [input,freqscale,freqoffset,decayscale] (Just [specificationsArrayRef]) 1 (Special 0) NoId
 
 -- | Clipped noise
 --
@@ -1097,8 +1099,8 @@
 -- | 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
+lpz2 :: UGen -> UGen
+lpz2 in_ = mkUGen Nothing [KR,AR] (Right [0]) "LPZ2" [in_] Nothing 1 (Special 0) NoId
 
 -- | Exponential lag
 --
@@ -1152,7 +1154,7 @@
 --
 --  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
+latch in_ trig_ = mkUGen Nothing [KR,AR] (Right [0,1]) "Latch" [in_,trig_] Nothing 1 (Special 0) NoId
 
 -- | Latoocarfian chaotic generator
 --
@@ -1254,13 +1256,13 @@
 --
 --  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
+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
+localOut input = mkUGen Nothing [KR,AR] (Right [0]) "LocalOut" [] (Just [input]) 0 (Special 0) NoId
 
 -- | Chaotic noise function
 --
@@ -1283,8 +1285,8 @@
 -- | 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
+mfcc :: Rate -> UGen -> UGen -> UGen
+mfcc rate chain numcoeff = mkUGen Nothing [KR] (Left rate) "MFCC" [chain,numcoeff] Nothing 13 (Special 0) NoId
 
 -- | Reduce precision.
 --
@@ -1392,7 +1394,7 @@
 --
 --  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
+offsetOut bus input = mkUGen Nothing [KR,AR] (Right [1]) "OffsetOut" [bus] (Just [input]) 0 (Special 0) NoId
 
 -- | One pole filter.
 --
@@ -1428,7 +1430,7 @@
 --
 --  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
+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
 --
@@ -1508,27 +1510,19 @@
 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.
 --
@@ -1758,6 +1752,14 @@
 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 [KR,AR] trig=0.0 in=0.0 label=0.0 trigid=-1.0;    FILTER: TRUE
+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
@@ -1840,13 +1842,13 @@
 --
 --  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
+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
+replaceOut bus input = mkUGen Nothing [KR,AR] (Right [1]) "ReplaceOut" [bus] (Just [input]) 0 (Special 0) NoId
 
 -- | Resonant filter.
 --
@@ -1910,7 +1912,7 @@
 
 -- | Schmidt trigger.
 --
---  Schmidt [IR,KR,AR] in=0.0 lo=0.0 hi=1.0
+--  Schmidt [IR,KR,AR] in=0.0 lo=0.0 hi=1.0;    FILTER: TRUE
 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
 
@@ -1930,7 +1932,7 @@
 --
 --  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
+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.
 --
@@ -2055,14 +2057,14 @@
 -- | 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
+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
+t2k :: UGen -> UGen
+t2k in_ = mkUGen Nothing [KR] (Left KR) "T2K" [in_] Nothing 1 (Special 0) NoId
 
 -- | physical model of bouncing object
 --
@@ -2097,8 +2099,8 @@
 -- | 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)
+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.
 --
@@ -2110,7 +2112,7 @@
 --
 --  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)
+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.
 --
@@ -2180,9 +2182,9 @@
 
 -- | Variable shaped lag
 --
---  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
+--  VarLag [KR,AR] in=0.0 time=0.1 level=0.0;    FILTER: TRUE
+varLag :: UGen -> UGen -> UGen -> UGen
+varLag in_ time level = mkUGen Nothing [KR,AR] (Right [0]) "VarLag" [in_,time,level] Nothing 1 (Special 0) NoId
 
 -- | Variable duty saw
 --
@@ -2242,7 +2244,7 @@
 --
 --  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
+xOut bus xfade input = mkUGen Nothing [KR,AR] (Right [2]) "XOut" [bus,xfade] (Just [input]) 0 (Special 0) NoId
 
 -- | Zero crossing frequency follower
 --
@@ -2253,8 +2255,8 @@
 -- | 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
+maxLocalBufs :: UGen -> UGen
+maxLocalBufs count = mkUGen Nothing [IR] (Left IR) "MaxLocalBufs" [count] Nothing 1 (Special 0) NoId
 
 -- | Multiply add
 --
@@ -2266,4 +2268,4 @@
 --
 --  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
+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/DB/External.hs b/Sound/SC3/UGen/Bindings/DB/External.hs
new file mode 100644
--- /dev/null
+++ b/Sound/SC3/UGen/Bindings/DB/External.hs
@@ -0,0 +1,2462 @@
+-- | SC3 external (sce3-plugins) UGen bindings (auto-generated).
+module Sound.SC3.UGen.Bindings.DB.External where
+
+import Sound.SC3.Common.UId
+import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.Type
+import Sound.SC3.UGen.UGen
+
+-- | (Undocumented class)
+--
+--  A2B [AR] a=0.0 b=0.0 c=0.0 d=0.0
+a2B :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+a2B rate a b c d = mkUGen Nothing [AR] (Left rate) "A2B" [a,b,c,d] Nothing 4 (Special 0) NoId
+
+-- | Emulator of the AY (aka YM) soundchip, used in Spectrum/Atari
+--
+--  AY [AR] tonea=1777.0 toneb=1666.0 tonec=1555.0 noise=1.0 control=7.0 vola=15.0 volb=15.0 volc=15.0 envfreq=4.0 envstyle=1.0 chiptype=0.0
+ay :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+ay tonea toneb tonec noise control_ vola volb volc envfreq envstyle chiptype = mkUGen Nothing [AR] (Left AR) "AY" [tonea,toneb,tonec,noise,control_,vola,volb,volc,envfreq,envstyle,chiptype] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Allpass1 [AR] in=0.0 freq=1200.0
+allpass1 :: Rate -> UGen -> UGen -> UGen
+allpass1 rate in_ freq = mkUGen Nothing [AR] (Left rate) "Allpass1" [in_,freq] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Allpass2 [AR] in=0.0 freq=1200.0 rq=1.0
+allpass2 :: Rate -> UGen -> UGen -> UGen -> UGen
+allpass2 rate in_ freq rq = mkUGen Nothing [AR] (Left rate) "Allpass2" [in_,freq,rq] Nothing 1 (Special 0) NoId
+
+-- | amplitude follower
+--
+--  AmplitudeMod [KR,AR] in=0.0 attackTime=1.0e-2 releaseTime=1.0e-2
+amplitudeMod :: Rate -> UGen -> UGen -> UGen -> UGen
+amplitudeMod rate in_ attackTime releaseTime = mkUGen Nothing [KR,AR] (Left rate) "AmplitudeMod" [in_,attackTime,releaseTime] Nothing 1 (Special 0) NoId
+
+-- | event analyser (BBCut)
+--
+--  AnalyseEvents2 [AR] in=0.0 bufnum=0.0 threshold=0.34 triggerid=101.0 circular=0.0 pitch=0.0
+analyseEvents2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+analyseEvents2 rate in_ bufnum threshold triggerid circular pitch_ = mkUGen Nothing [AR] (Left rate) "AnalyseEvents2" [in_,bufnum,threshold,triggerid,circular,pitch_] Nothing 1 (Special 0) NoId
+
+-- | detect the largest value (and its position) in an array of UGens
+--
+--  ArrayMax [KR,AR] array=0.0
+arrayMax :: Rate -> UGen -> UGen
+arrayMax rate array = mkUGen Nothing [KR,AR] (Left rate) "ArrayMax" [array] Nothing 2 (Special 0) NoId
+
+-- | detect the smallest value (and its position) in an array of UGens
+--
+--  ArrayMin [KR,AR] array=0.0
+arrayMin :: Rate -> UGen -> UGen
+arrayMin rate array = mkUGen Nothing [KR,AR] (Left rate) "ArrayMin" [array] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  AtsAmp [KR,AR] atsbuffer=0.0 partialNum=0.0 filePointer=0.0
+atsAmp :: Rate -> UGen -> UGen -> UGen -> UGen
+atsAmp rate atsbuffer partialNum filePointer = mkUGen Nothing [KR,AR] (Left rate) "AtsAmp" [atsbuffer,partialNum,filePointer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  AtsBand [AR] atsbuffer=0.0 band=0.0 filePointer=0.0
+atsBand :: Rate -> UGen -> UGen -> UGen -> UGen
+atsBand rate atsbuffer band filePointer = mkUGen Nothing [AR] (Left rate) "AtsBand" [atsbuffer,band,filePointer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  AtsFreq [KR,AR] atsbuffer=0.0 partialNum=0.0 filePointer=0.0
+atsFreq :: Rate -> UGen -> UGen -> UGen -> UGen
+atsFreq rate atsbuffer partialNum filePointer = mkUGen Nothing [KR,AR] (Left rate) "AtsFreq" [atsbuffer,partialNum,filePointer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  AtsNoiSynth [AR] atsbuffer=0.0 numPartials=0.0 partialStart=0.0 partialSkip=1.0 filePointer=0.0 sinePct=1.0 noisePct=1.0 freqMul=1.0 freqAdd=0.0 numBands=25.0 bandStart=0.0 bandSkip=1.0
+atsNoiSynth :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+atsNoiSynth rate atsbuffer numPartials partialStart partialSkip filePointer sinePct noisePct freqMul freqAdd numBands bandStart bandSkip = mkUGen Nothing [AR] (Left rate) "AtsNoiSynth" [atsbuffer,numPartials,partialStart,partialSkip,filePointer,sinePct,noisePct,freqMul,freqAdd,numBands,bandStart,bandSkip] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  AtsNoise [KR,AR] atsbuffer=0.0 bandNum=0.0 filePointer=0.0
+atsNoise :: Rate -> UGen -> UGen -> UGen -> UGen
+atsNoise rate atsbuffer bandNum filePointer = mkUGen Nothing [KR,AR] (Left rate) "AtsNoise" [atsbuffer,bandNum,filePointer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  AtsParInfo [KR,AR] atsbuffer=0.0 partialNum=0.0 filePointer=0.0
+atsParInfo :: Rate -> UGen -> UGen -> UGen -> UGen
+atsParInfo rate atsbuffer partialNum filePointer = mkUGen Nothing [KR,AR] (Left rate) "AtsParInfo" [atsbuffer,partialNum,filePointer] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  AtsPartial [AR] atsbuffer=0.0 partial=0.0 filePointer=0.0 freqMul=1.0 freqAdd=0.0
+atsPartial :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+atsPartial rate atsbuffer partial filePointer freqMul freqAdd = mkUGen Nothing [AR] (Left rate) "AtsPartial" [atsbuffer,partial,filePointer,freqMul,freqAdd] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  AtsSynth [AR] atsbuffer=0.0 numPartials=0.0 partialStart=0.0 partialSkip=1.0 filePointer=0.0 freqMul=1.0 freqAdd=0.0
+atsSynth :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+atsSynth rate atsbuffer numPartials partialStart partialSkip filePointer freqMul freqAdd = mkUGen Nothing [AR] (Left rate) "AtsSynth" [atsbuffer,numPartials,partialStart,partialSkip,filePointer,freqMul,freqAdd] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  AtsUGen [] maxSize=0.0
+atsUGen :: Rate -> UGen -> UGen
+atsUGen rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "AtsUGen" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | Detect onsets and assess the nature of the attack slope
+--
+--  AttackSlope [KR] input=0.0 windowsize=1024.0 peakpicksize=20.0 leak=0.999 energythreshold=1.0e-2 sumthreshold=20.0 mingap=30.0 numslopesaveraged=10.0
+attackSlope :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+attackSlope rate input windowsize peakpicksize leak energythreshold sumthreshold mingap numslopesaveraged = mkUGen Nothing [KR] (Left rate) "AttackSlope" [input,windowsize,peakpicksize,leak,energythreshold,sumthreshold,mingap,numslopesaveraged] Nothing 6 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  AudioMSG [AR] in=0.0 index=0.0
+audioMSG :: Rate -> UGen -> UGen -> UGen
+audioMSG rate in_ index_ = mkUGen Nothing [AR] (Left rate) "AudioMSG" [in_,index_] Nothing 1 (Special 0) NoId
+
+-- | calculates mean average of audio or control rate signal
+--
+--  AverageOutput [KR,AR] in=0.0 trig=0.0
+averageOutput :: UGen -> UGen -> UGen
+averageOutput in_ trig_ = mkUGen Nothing [KR,AR] (Right [0]) "AverageOutput" [in_,trig_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  B2A [AR] w=0.0 x=0.0 y=0.0 z=0.0
+b2A :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+b2A rate w x y z = mkUGen Nothing [AR] (Left rate) "B2A" [w,x,y,z] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  B2Ster [AR] w=0.0 x=0.0 y=0.0
+b2Ster :: Rate -> UGen -> UGen -> UGen -> UGen
+b2Ster rate w x y = mkUGen Nothing [AR] (Left rate) "B2Ster" [w,x,y] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  B2UHJ [AR] w=0.0 x=0.0 y=0.0
+b2UHJ :: Rate -> UGen -> UGen -> UGen -> UGen
+b2UHJ rate w x y = mkUGen Nothing [AR] (Left rate) "B2UHJ" [w,x,y] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BBlockerBuf [AR] freq=0.0 bufnum=0.0 startpoint=0.0
+bBlockerBuf :: Rate -> UGen -> UGen -> UGen -> UGen
+bBlockerBuf rate freq bufnum startpoint = mkUGen Nothing [AR] (Left rate) "BBlockerBuf" [freq,bufnum,startpoint] Nothing 9 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BFDecode1 [AR] w=0.0 x=0.0 y=0.0 z=0.0 azimuth=0.0 elevation=0.0 wComp=0.0
+bFDecode1 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bFDecode1 rate w x y z azimuth elevation wComp = mkUGen Nothing [AR] (Left rate) "BFDecode1" [w,x,y,z,azimuth,elevation,wComp] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BFDecoder [] maxSize=0.0
+bFDecoder :: Rate -> UGen -> UGen
+bFDecoder rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "BFDecoder" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BFEncode1 [AR] in=0.0 azimuth=0.0 elevation=0.0 rho=1.0 gain=1.0 wComp=0.0
+bFEncode1 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bFEncode1 rate in_ azimuth elevation rho gain wComp = mkUGen Nothing [AR] (Left rate) "BFEncode1" [in_,azimuth,elevation,rho,gain,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BFEncode2 [AR] in=0.0 point_x=1.0 point_y=1.0 elevation=0.0 gain=1.0 wComp=0.0
+bFEncode2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bFEncode2 rate in_ point_x point_y elevation gain wComp = mkUGen Nothing [AR] (Left rate) "BFEncode2" [in_,point_x,point_y,elevation,gain,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BFEncodeSter [AR] l=0.0 r=0.0 azimuth=0.0 width=1.5707963267949 elevation=0.0 rho=1.0 gain=1.0 wComp=0.0
+bFEncodeSter :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bFEncodeSter rate l r azimuth width elevation rho gain wComp = mkUGen Nothing [AR] (Left rate) "BFEncodeSter" [l,r,azimuth,width,elevation,rho,gain,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BFGrainPanner [] maxSize=0.0
+bFGrainPanner :: Rate -> UGen -> UGen
+bFGrainPanner rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "BFGrainPanner" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BFManipulate [AR] w=0.0 x=0.0 y=0.0 z=0.0 rotate=0.0 tilt=0.0 tumble=0.0
+bFManipulate :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bFManipulate rate w x y z rotate_ tilt_ tumble_ = mkUGen Nothing [AR] (Left rate) "BFManipulate" [w,x,y,z,rotate_,tilt_,tumble_] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BFPanner [] maxSize=0.0
+bFPanner :: Rate -> UGen -> UGen
+bFPanner rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "BFPanner" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BLBufRd [KR,AR] bufnum=0.0 phase=0.0 ratio=1.0
+bLBufRd :: Rate -> UGen -> UGen -> UGen -> UGen
+bLBufRd rate bufnum phase ratio = mkUGen Nothing [KR,AR] (Left rate) "BLBufRd" [bufnum,phase,ratio] Nothing 1 (Special 0) NoId
+
+-- | 24db/oct rolloff - 4nd order resonant Low/High/Band Pass Filter
+--
+--  BMoog [AR] in=0.0 freq=440.0 q=0.2 mode=0.0 saturation=0.95
+bMoog :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bMoog in_ freq q mode saturation = mkUGen Nothing [AR] (Right [0]) "BMoog" [in_,freq,q,mode,saturation] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Balance [AR] in=0.0 test=0.0 hp=10.0 stor=0.0
+balance :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+balance rate in_ test hp stor = mkUGen Nothing [AR] (Left rate) "Balance" [in_,test,hp,stor] Nothing 1 (Special 0) NoId
+
+-- | Extracts statistics on a beat histogram
+--
+--  BeatStatistics [KR] fft=0.0 leak=0.995 numpreviousbeats=4.0
+beatStatistics :: Rate -> UGen -> UGen -> UGen -> UGen
+beatStatistics rate fft_ leak numpreviousbeats = mkUGen Nothing [KR] (Left rate) "BeatStatistics" [fft_,leak,numpreviousbeats] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BinData [KR,AR] buffer=0.0 bin=0.0 overlaps=0.5
+binData :: Rate -> UGen -> UGen -> UGen -> UGen
+binData rate buffer bin overlaps = mkUGen Nothing [KR,AR] (Left rate) "BinData" [buffer,bin,overlaps] Nothing 2 (Special 0) NoId
+
+-- | Band limited impulse generation
+--
+--  BlitB3 [AR] freq=440.0
+blitB3 :: Rate -> UGen -> UGen
+blitB3 rate freq = mkUGen Nothing [AR] (Left rate) "BlitB3" [freq] Nothing 1 (Special 0) NoId
+
+-- | BLIT derived sawtooth
+--
+--  BlitB3Saw [AR] freq=440.0 leak=0.99
+blitB3Saw :: Rate -> UGen -> UGen -> UGen
+blitB3Saw rate freq leak = mkUGen Nothing [AR] (Left rate) "BlitB3Saw" [freq,leak] Nothing 1 (Special 0) NoId
+
+-- | Bipolar BLIT derived square waveform
+--
+--  BlitB3Square [AR] freq=440.0 leak=0.99
+blitB3Square :: Rate -> UGen -> UGen -> UGen
+blitB3Square rate freq leak = mkUGen Nothing [AR] (Left rate) "BlitB3Square" [freq,leak] Nothing 1 (Special 0) NoId
+
+-- | Bipolar BLIT derived triangle
+--
+--  BlitB3Tri [AR] freq=440.0 leak=0.99 leak2=0.99
+blitB3Tri :: Rate -> UGen -> UGen -> UGen -> UGen
+blitB3Tri rate freq leak leak2 = mkUGen Nothing [AR] (Left rate) "BlitB3Tri" [freq,leak,leak2] Nothing 1 (Special 0) NoId
+
+-- | breakcore simulator
+--
+--  Breakcore [AR] bufnum=0.0 capturein=0.0 capturetrigger=0.0 duration=0.1 ampdropout=0.0
+breakcore :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+breakcore rate bufnum capturein capturetrigger duration ampdropout = mkUGen Nothing [AR] (Left rate) "Breakcore" [bufnum,capturein,capturetrigger,duration,ampdropout] Nothing 1 (Special 0) NoId
+
+-- | Prigogine oscillator
+--
+--  Brusselator [AR] reset=0.0 rate=1.0e-2 mu=1.0 gamma=1.0 initx=0.5 inity=0.5
+brusselator :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+brusselator rate reset rate_ mu gamma initx inity = mkUGen Nothing [AR] (Left rate) "Brusselator" [reset,rate_,mu,gamma,initx,inity] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BufGrain [AR] trigger=0.0 dur=1.0 sndbuf=0.0 rate=1.0 pos=0.0 interp=2.0
+bufGrain :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bufGrain rate trigger dur sndbuf rate_ pos interp = mkUGen Nothing [AR] (Left rate) "BufGrain" [trigger,dur,sndbuf,rate_,pos,interp] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BufGrainB [AR] trigger=0.0 dur=1.0 sndbuf=0.0 rate=1.0 pos=0.0 envbuf=0.0 interp=2.0
+bufGrainB :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bufGrainB rate trigger dur sndbuf rate_ pos envbuf interp = mkUGen Nothing [AR] (Left rate) "BufGrainB" [trigger,dur,sndbuf,rate_,pos,envbuf,interp] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BufGrainBBF [AR] trigger=0.0 dur=1.0 sndbuf=0.0 rate=1.0 pos=0.0 envbuf=0.0 azimuth=0.0 elevation=0.0 rho=1.0 interp=2.0 wComp=0.0
+bufGrainBBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bufGrainBBF rate trigger dur sndbuf rate_ pos envbuf azimuth elevation rho interp wComp = mkUGen Nothing [AR] (Left rate) "BufGrainBBF" [trigger,dur,sndbuf,rate_,pos,envbuf,azimuth,elevation,rho,interp,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BufGrainBF [AR] trigger=0.0 dur=1.0 sndbuf=0.0 rate=1.0 pos=0.0 azimuth=0.0 elevation=0.0 rho=1.0 interp=2.0 wComp=0.0
+bufGrainBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bufGrainBF rate trigger dur sndbuf rate_ pos azimuth elevation rho interp wComp = mkUGen Nothing [AR] (Left rate) "BufGrainBF" [trigger,dur,sndbuf,rate_,pos,azimuth,elevation,rho,interp,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BufGrainI [AR] trigger=0.0 dur=1.0 sndbuf=0.0 rate=1.0 pos=0.0 envbuf1=0.0 envbuf2=0.0 ifac=0.5 interp=2.0
+bufGrainI :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bufGrainI rate trigger dur sndbuf rate_ pos envbuf1 envbuf2 ifac interp = mkUGen Nothing [AR] (Left rate) "BufGrainI" [trigger,dur,sndbuf,rate_,pos,envbuf1,envbuf2,ifac,interp] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  BufGrainIBF [AR] trigger=0.0 dur=1.0 sndbuf=0.0 rate=1.0 pos=0.0 envbuf1=0.0 envbuf2=0.0 ifac=0.5 azimuth=0.0 elevation=0.0 rho=1.0 interp=2.0 wComp=0.0
+bufGrainIBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+bufGrainIBF rate trigger dur sndbuf rate_ pos envbuf1 envbuf2 ifac azimuth elevation rho interp wComp = mkUGen Nothing [AR] (Left rate) "BufGrainIBF" [trigger,dur,sndbuf,rate_,pos,envbuf1,envbuf2,ifac,azimuth,elevation,rho,interp,wComp] Nothing 4 (Special 0) NoId
+
+-- | detect the largest value (and its position) in an array of UGens
+--
+--  BufMax [KR] bufnum=0.0 gate=1.0
+bufMax :: Rate -> UGen -> UGen -> UGen
+bufMax rate bufnum gate_ = mkUGen Nothing [KR] (Left rate) "BufMax" [bufnum,gate_] Nothing 2 (Special 0) NoId
+
+-- | detect the largest value (and its position) in an array of UGens
+--
+--  BufMin [KR] bufnum=0.0 gate=1.0
+bufMin :: Rate -> UGen -> UGen -> UGen
+bufMin rate bufnum gate_ = mkUGen Nothing [KR] (Left rate) "BufMin" [bufnum,gate_] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  CQ_Diff [KR] in1=0.0 in2=0.0 databufnum=0.0
+cQ_Diff :: Rate -> UGen -> UGen -> UGen -> UGen
+cQ_Diff rate in1 in2 databufnum = mkUGen Nothing [KR] (Left rate) "CQ_Diff" [in1,in2,databufnum] Nothing 1 (Special 0) NoId
+
+-- | Quefrency analysis and liftering
+--
+--  Cepstrum [] cepbuf=0.0 fftchain=0.0
+cepstrum :: Rate -> UGen -> UGen -> UGen
+cepstrum rate cepbuf fftchain = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "Cepstrum" [cepbuf,fftchain] Nothing 1 (Special 0) NoId
+
+-- | Octave chroma band based representation of energy in a signal; Chromagram for nTET tuning systems with any base reference
+--
+--  Chromagram [KR] fft=0.0 fftsize=2048.0 n=12.0 tuningbase=32.703195662575 octaves=8.0 integrationflag=0.0 coeff=0.9 octaveratio=2.0 perframenormalize=0.0
+chromagram :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+chromagram rate fft_ fftsize n tuningbase octaves integrationflag coeff octaveratio perframenormalize = mkUGen Nothing [KR] (Left rate) "Chromagram" [fft_,fftsize,n,tuningbase,octaves,integrationflag,coeff,octaveratio,perframenormalize] Nothing 12 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  ChuaL [AR] freq=22050.0 a=0.3286 b=0.9336 c=-0.8126 d=0.399 rr=0.0 h=5.0e-2 xi=0.1 yi=0.0 zi=0.0
+chuaL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+chuaL rate freq a b c d rr h xi yi zi = mkUGen Nothing [AR] (Left rate) "ChuaL" [freq,a,b,c,d,rr,h,xi,yi,zi] Nothing 1 (Special 0) NoId
+
+-- | circular linear lag
+--
+--  CircleRamp [KR,AR] in=0.0 lagTime=0.1 circmin=-180.0 circmax=180.0
+circleRamp :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+circleRamp rate in_ lagTime circmin circmax = mkUGen Nothing [KR,AR] (Left rate) "CircleRamp" [in_,lagTime,circmin,circmax] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Clipper32 [AR] in=0.0 lo=-0.8 hi=0.8
+clipper32 :: Rate -> UGen -> UGen -> UGen -> UGen
+clipper32 rate in_ lo hi = mkUGen Nothing [AR] (Left rate) "Clipper32" [in_,lo,hi] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Clipper4 [AR] in=0.0 lo=-0.8 hi=0.8
+clipper4 :: Rate -> UGen -> UGen -> UGen -> UGen
+clipper4 rate in_ lo hi = mkUGen Nothing [AR] (Left rate) "Clipper4" [in_,lo,hi] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Clipper8 [AR] in=0.0 lo=-0.8 hi=0.8
+clipper8 :: Rate -> UGen -> UGen -> UGen -> UGen
+clipper8 rate in_ lo hi = mkUGen Nothing [AR] (Left rate) "Clipper8" [in_,lo,hi] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Clockmus [KR] 
+clockmus :: Rate -> UGen
+clockmus rate = mkUGen Nothing [KR] (Left rate) "Clockmus" [] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  CombLP [AR] in=0.0 gate=1.0 maxdelaytime=0.2 delaytime=0.2 decaytime=1.0 coef=0.5
+combLP :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+combLP rate in_ gate_ maxdelaytime delaytime decaytime coef = mkUGen Nothing [AR] (Left rate) "CombLP" [in_,gate_,maxdelaytime,delaytime,decaytime,coef] Nothing 1 (Special 0) NoId
+
+-- | FM-modulable resonating filter
+--
+--  ComplexRes [AR] in=0.0 freq=100.0 decay=0.2;    FILTER: TRUE
+complexRes :: UGen -> UGen -> UGen -> UGen
+complexRes in_ freq decay_ = mkUGen Nothing [AR] (Right [0]) "ComplexRes" [in_,freq,decay_] Nothing 1 (Special 0) NoId
+
+-- | Concatenative Cross-Synthesis on Live Streams
+--
+--  Concat [AR] control=0.0 source=0.0 storesize=1.0 seektime=1.0 seekdur=1.0 matchlength=5.0e-2 freezestore=0.0 zcr=1.0 lms=1.0 sc=1.0 st=0.0 randscore=0.0
+concat :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+concat rate control_ source storesize seektime seekdur matchlength freezestore zcr lms sc st randscore = mkUGen Nothing [AR] (Left rate) "Concat" [control_,source,storesize,seektime,seekdur,matchlength,freezestore,zcr,lms,sc,st,randscore] Nothing 1 (Special 0) NoId
+
+-- | Concatenative Cross-Synthesis on Live Streams
+--
+--  Concat2 [AR] control=0.0 source=0.0 storesize=1.0 seektime=1.0 seekdur=1.0 matchlength=5.0e-2 freezestore=0.0 zcr=1.0 lms=1.0 sc=1.0 st=0.0 randscore=0.0 threshold=1.0e-2
+concat2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+concat2 rate control_ source storesize seektime seekdur matchlength freezestore zcr lms sc st randscore threshold = mkUGen Nothing [AR] (Left rate) "Concat2" [control_,source,storesize,seektime,seekdur,matchlength,freezestore,zcr,lms,sc,st,randscore,threshold] Nothing 1 (Special 0) NoId
+
+-- | an amplitude tracking based onset detector
+--
+--  Coyote [KR] in=0.0 trackFall=0.2 slowLag=0.2 fastLag=1.0e-2 fastMul=0.5 thresh=5.0e-2 minDur=0.1
+coyote :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+coyote rate in_ trackFall slowLag fastLag fastMul thresh minDur = mkUGen Nothing [KR] (Left rate) "Coyote" [in_,trackFall,slowLag,fastLag,fastMul,thresh,minDur] Nothing 1 (Special 0) NoId
+
+-- | Measure the temporal crest factor of a signal
+--
+--  Crest [KR] in=0.0 numsamps=400.0 gate=1.0
+crest :: Rate -> UGen -> UGen -> UGen -> UGen
+crest rate in_ numsamps gate_ = mkUGen Nothing [KR] (Left rate) "Crest" [in_,numsamps,gate_] Nothing 1 (Special 0) NoId
+
+-- | port of some ladspa plugins
+--
+--  CrossoverDistortion [AR] in=0.0 amp=0.5 smooth=0.5
+crossoverDistortion :: UGen -> UGen -> UGen -> UGen
+crossoverDistortion in_ amp smooth = mkUGen Nothing [AR] (Right [0]) "CrossoverDistortion" [in_,amp,smooth] Nothing 1 (Special 0) NoId
+
+-- | Digitally modelled analog filter
+--
+--  DFM1 [AR] in=0.0 freq=1000.0 res=0.1 inputgain=1.0 type=0.0 noiselevel=3.0e-4
+dfm1 :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dfm1 in_ freq res inputgain type_ noiselevel = mkUGen Nothing [AR] (Right [0]) "DFM1" [in_,freq,res,inputgain,type_,noiselevel] Nothing 1 (Special 0) NoId
+
+-- | Demand rate implementation of a Wiard noise ring
+--
+--  DNoiseRing [DR] change=0.5 chance=0.5 shift=1.0 numBits=8.0 resetval=0.0;    DEMAND/NONDET
+dNoiseRing :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dNoiseRing change chance shift numBits resetval = mkUGen Nothing [DR] (Left DR) "DNoiseRing" [change,chance,shift,numBits,resetval] Nothing 1 (Special 0) NoId
+
+-- | Triangle via 3rd order differerentiated polynomial waveform
+--
+--  DPW3Tri [AR] freq=440.0
+dpw3Tri :: Rate -> UGen -> UGen
+dpw3Tri rate freq = mkUGen Nothing [AR] (Left rate) "DPW3Tri" [freq] Nothing 1 (Special 0) NoId
+
+-- | Sawtooth via 4th order differerentiated polynomial waveform
+--
+--  DPW4Saw [AR] freq=440.0
+dpw4Saw :: Rate -> UGen -> UGen
+dpw4Saw rate freq = mkUGen Nothing [AR] (Left rate) "DPW4Saw" [freq] Nothing 1 (Special 0) NoId
+
+-- | Plucked physical model.
+--
+--  DWGBowed [AR] freq=440.0 velb=0.5 force=1.0 gate=1.0 pos=0.14 release=0.1 c1=1.0 c3=3.0 impZ=0.55 fB=2.0
+dWGBowed :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dWGBowed rate freq velb force gate_ pos release c1 c3 impZ fB = mkUGen Nothing [AR] (Left rate) "DWGBowed" [freq,velb,force,gate_,pos,release,c1,c3,impZ,fB] Nothing 1 (Special 0) NoId
+
+-- | Plucked physical model.
+--
+--  DWGBowedSimple [AR] freq=440.0 velb=0.5 force=1.0 gate=1.0 pos=0.14 release=0.1 c1=1.0 c3=30.0
+dWGBowedSimple :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dWGBowedSimple rate freq velb force gate_ pos release c1 c3 = mkUGen Nothing [AR] (Left rate) "DWGBowedSimple" [freq,velb,force,gate_,pos,release,c1,c3] Nothing 1 (Special 0) NoId
+
+-- | Plucked physical model.
+--
+--  DWGBowedTor [AR] freq=440.0 velb=0.5 force=1.0 gate=1.0 pos=0.14 release=0.1 c1=1.0 c3=3.0 impZ=0.55 fB=2.0 mistune=5.2 c1tor=1.0 c3tor=3000.0 iZtor=1.8
+dWGBowedTor :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dWGBowedTor rate freq velb force gate_ pos release c1 c3 impZ fB mistune c1tor c3tor iZtor = mkUGen Nothing [AR] (Left rate) "DWGBowedTor" [freq,velb,force,gate_,pos,release,c1,c3,impZ,fB,mistune,c1tor,c3tor,iZtor] Nothing 1 (Special 0) NoId
+
+-- | Plucked physical model.
+--
+--  DWGPlucked [AR] freq=440.0 amp=0.5 gate=1.0 pos=0.14 c1=1.0 c3=30.0 inp=0.0 release=0.1
+dWGPlucked :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dWGPlucked rate freq amp gate_ pos c1 c3 inp release = mkUGen Nothing [AR] (Left rate) "DWGPlucked" [freq,amp,gate_,pos,c1,c3,inp,release] Nothing 1 (Special 0) NoId
+
+-- | Plucked physical model.
+--
+--  DWGPlucked2 [AR] freq=440.0 amp=0.5 gate=1.0 pos=0.14 c1=1.0 c3=30.0 inp=0.0 release=0.1 mistune=1.008 mp=0.55 gc=1.0e-2
+dWGPlucked2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dWGPlucked2 rate freq amp gate_ pos c1 c3 inp release mistune mp gc = mkUGen Nothing [AR] (Left rate) "DWGPlucked2" [freq,amp,gate_,pos,c1,c3,inp,release,mistune,mp,gc] Nothing 1 (Special 0) NoId
+
+-- | Plucked physical model.
+--
+--  DWGPluckedStiff [AR] freq=440.0 amp=0.5 gate=1.0 pos=0.14 c1=1.0 c3=30.0 inp=0.0 release=0.1 fB=2.0
+dWGPluckedStiff :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dWGPluckedStiff rate freq amp gate_ pos c1 c3 inp release fB = mkUGen Nothing [AR] (Left rate) "DWGPluckedStiff" [freq,amp,gate_,pos,c1,c3,inp,release,fB] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  DWGSoundBoard [AR] inp=0.0 c1=20.0 c3=20.0 mix=0.8 d1=199.0 d2=211.0 d3=223.0 d4=227.0 d5=229.0 d6=233.0 d7=239.0 d8=241.0
+dWGSoundBoard :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dWGSoundBoard rate inp c1 c3 mix d1 d2 d3 d4 d5 d6 d7 d8 = mkUGen Nothing [AR] (Left rate) "DWGSoundBoard" [inp,c1,c3,mix,d1,d2,d3,d4,d5,d6,d7,d8] Nothing 1 (Special 0) NoId
+
+-- | demand rate brownian movement with Gendyn distributions
+--
+--  Dbrown2 [] lo=0.0 hi=0.0 step=0.0 dist=0.0 length=1.0e8
+dbrown2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dbrown2 rate lo hi step dist length_ = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "Dbrown2" [lo,hi,step,dist,length_] Nothing 1 (Special 0) NoId
+
+-- | demand rate tag system on a buffer
+--
+--  DbufTag [DR] bufnum=0.0 v=0.0 axiom=0.0 rules=0.0 recycle=0.0 mode=0.0;    DEMAND/NONDET
+dbufTag :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dbufTag rate bufnum v axiom rules recycle mode = mkUGen Nothing [DR] (Left rate) "DbufTag" [bufnum,v,axiom,rules,recycle,mode] Nothing 1 (Special 0) NoId
+
+-- | port of some ladspa plugins
+--
+--  Decimator [AR] in=0.0 rate=44100.0 bits=24.0
+decimator :: Rate -> UGen -> UGen -> UGen -> UGen
+decimator rate in_ rate_ bits = mkUGen Nothing [AR] (Left rate) "Decimator" [in_,rate_,bits] Nothing 1 (Special 0) NoId
+
+-- | Demand version of the BetaBlocker VChip
+--
+--  DetaBlockerBuf [DR] bufnum=0.0 startpoint=0.0;    DEMAND/NONDET
+detaBlockerBuf :: Rate -> UGen -> UGen -> UGen
+detaBlockerBuf rate bufnum startpoint = mkUGen Nothing [DR] (Left rate) "DetaBlockerBuf" [bufnum,startpoint] Nothing 1 (Special 0) NoId
+
+-- | demand rate finite state machine
+--
+--  Dfsm [DR] rules=0.0 n=1.0 rgen=0.0;    DEMAND/NONDET
+dfsm :: Rate -> UGen -> UGen -> UGen -> UGen
+dfsm rate rules n rgen = mkUGen Nothing [DR] (Left rate) "Dfsm" [rules,n,rgen] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Dgauss [] lo=0.0 hi=0.0 length=1.0e8
+dgauss :: Rate -> UGen -> UGen -> UGen -> UGen
+dgauss rate lo hi length_ = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "Dgauss" [lo,hi,length_] Nothing 1 (Special 0) NoId
+
+-- | Ring modulation based on the physical model of a diode.
+--
+--  DiodeRingMod [AR] car=0.0 mod=0.0;    FILTER: TRUE
+diodeRingMod :: UGen -> UGen -> UGen
+diodeRingMod car mod_ = mkUGen Nothing [AR] (Right [0]) "DiodeRingMod" [car,mod_] Nothing 1 (Special 0) NoId
+
+-- | port of some ladspa plugins
+--
+--  Disintegrator [AR] in=0.0 probability=0.5 multiplier=0.0;    FILTER: TRUE, NONDET
+disintegrator :: ID a => a -> UGen -> UGen -> UGen -> UGen
+disintegrator z in_ probability multiplier = mkUGen Nothing [AR] (Right [0]) "Disintegrator" [in_,probability,multiplier] Nothing 1 (Special 0) (toUId z)
+
+-- | discrete time neurodynamics
+--
+--  Dneuromodule [KR,AR] dt=0.0 numChannels=0.0 theta=0.0 x=0.0 weights=0.0
+dneuromodule :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dneuromodule rate dt numChannels theta x weights = mkUGen Nothing [KR,AR] (Left rate) "Dneuromodule" [dt,numChannels,theta,x,weights] Nothing 1 (Special 0) NoId
+
+-- | Nested Allpass filters as proposed by Vercoe and Pluckett
+--
+--  DoubleNestedAllpassC [AR] in=0.0 maxdelay1=4.7e-3 delay1=4.7e-3 gain1=0.15 maxdelay2=2.2e-2 delay2=2.2e-2 gain2=0.25 maxdelay3=8.3e-3 delay3=8.3e-3 gain3=0.3;    FILTER: TRUE
+doubleNestedAllpassC :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+doubleNestedAllpassC in_ maxdelay1 delay1_ gain1 maxdelay2 delay2_ gain2 maxdelay3 delay3 gain3 = mkUGen Nothing [AR] (Right [0]) "DoubleNestedAllpassC" [in_,maxdelay1,delay1_,gain1,maxdelay2,delay2_,gain2,maxdelay3,delay3,gain3] Nothing 1 (Special 0) NoId
+
+-- | Nested Allpass filters as proposed by Vercoe and Pluckett
+--
+--  DoubleNestedAllpassL [AR] in=0.0 maxdelay1=4.7e-3 delay1=4.7e-3 gain1=0.15 maxdelay2=2.2e-2 delay2=2.2e-2 gain2=0.25 maxdelay3=8.3e-3 delay3=8.3e-3 gain3=0.3;    FILTER: TRUE
+doubleNestedAllpassL :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+doubleNestedAllpassL in_ maxdelay1 delay1_ gain1 maxdelay2 delay2_ gain2 maxdelay3 delay3 gain3 = mkUGen Nothing [AR] (Right [0]) "DoubleNestedAllpassL" [in_,maxdelay1,delay1_,gain1,maxdelay2,delay2_,gain2,maxdelay3,delay3,gain3] Nothing 1 (Special 0) NoId
+
+-- | Nested Allpass filters as proposed by Vercoe and Pluckett
+--
+--  DoubleNestedAllpassN [AR] in=0.0 maxdelay1=4.7e-3 delay1=4.7e-3 gain1=0.15 maxdelay2=2.2e-2 delay2=2.2e-2 gain2=0.25 maxdelay3=8.3e-3 delay3=8.3e-3 gain3=0.3;    FILTER: TRUE
+doubleNestedAllpassN :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+doubleNestedAllpassN in_ maxdelay1 delay1_ gain1 maxdelay2 delay2_ gain2 maxdelay3 delay3 gain3 = mkUGen Nothing [AR] (Right [0]) "DoubleNestedAllpassN" [in_,maxdelay1,delay1_,gain1,maxdelay2,delay2_,gain2,maxdelay3,delay3,gain3] Nothing 1 (Special 0) NoId
+
+
+-- | Forced DoubleWell Oscillator
+--
+--  DoubleWell [AR] reset=0.0 ratex=1.0e-2 ratey=1.0e-2 f=1.0 w=1.0e-3 delta=1.0 initx=0.0 inity=0.0
+doubleWell :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+doubleWell rate reset ratex ratey f w delta initx inity = mkUGen Nothing [AR] (Left rate) "DoubleWell" [reset,ratex,ratey,f,w,delta,initx,inity] Nothing 1 (Special 0) NoId
+
+-- | Forced DoubleWell Oscillator
+--
+--  DoubleWell2 [AR] reset=0.0 ratex=1.0e-2 ratey=1.0e-2 f=1.0 w=1.0e-3 delta=1.0 initx=0.0 inity=0.0
+doubleWell2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+doubleWell2 rate reset ratex ratey f w delta initx inity = mkUGen Nothing [AR] (Left rate) "DoubleWell2" [reset,ratex,ratey,f,w,delta,initx,inity] Nothing 1 (Special 0) NoId
+
+-- | Forced DoubleWell Oscillator
+--
+--  DoubleWell3 [AR] reset=0.0 rate=1.0e-2 f=0.0 delta=0.25 initx=0.0 inity=0.0
+doubleWell3 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+doubleWell3 rate reset rate_ f delta initx inity = mkUGen Nothing [AR] (Left rate) "DoubleWell3" [reset,rate_,f,delta,initx,inity] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  DriveNoise [AR] in=0.0 amount=1.0 multi=5.0
+driveNoise :: Rate -> UGen -> UGen -> UGen -> UGen
+driveNoise rate in_ amount multi = mkUGen Nothing [AR] (Left rate) "DriveNoise" [in_,amount,multi] Nothing 1 (Special 0) NoId
+
+-- | Crosscorrelation search and drum pattern matching beat tracker
+--
+--  DrumTrack [KR] in=0.0 lock=0.0 dynleak=0.0 tempowt=0.0 phasewt=0.0 basswt=0.0 patternwt=1.0 prior=0.0 kicksensitivity=1.0 snaresensitivity=1.0 debugmode=0.0
+drumTrack :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+drumTrack rate in_ lock dynleak tempowt phasewt basswt patternwt prior kicksensitivity snaresensitivity debugmode = mkUGen Nothing [KR] (Left rate) "DrumTrack" [in_,lock,dynleak,tempowt,phasewt,basswt,patternwt,prior,kicksensitivity,snaresensitivity,debugmode] Nothing 4 (Special 0) NoId
+
+-- | demand rate tag system
+--
+--  Dtag [] bufsize=0.0 v=0.0 axiom=0.0 rules=0.0 recycle=0.0 mode=0.0
+dtag :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+dtag rate bufsize v axiom rules recycle mode = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "Dtag" [bufsize,v,axiom,rules,recycle,mode] Nothing 1 (Special 0) NoId
+
+-- | Envelope Follower Filter
+--
+--  EnvDetect [AR] in=0.0 attack=100.0 release=0.0
+envDetect :: Rate -> UGen -> UGen -> UGen -> UGen
+envDetect rate in_ attack release = mkUGen Nothing [AR] (Left rate) "EnvDetect" [in_,attack,release] Nothing 1 (Special 0) NoId
+
+-- | Envelope Follower
+--
+--  EnvFollow [KR,AR] input=0.0 decaycoeff=0.99
+envFollow :: Rate -> UGen -> UGen -> UGen
+envFollow rate input decaycoeff = mkUGen Nothing [KR,AR] (Left rate) "EnvFollow" [input,decaycoeff] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FFTComplexDev [KR] buffer=0.0 rectify=0.0 powthresh=0.1
+fFTComplexDev :: Rate -> UGen -> UGen -> UGen -> UGen
+fFTComplexDev rate buffer rectify powthresh = mkUGen Nothing [KR] (Left rate) "FFTComplexDev" [buffer,rectify,powthresh] Nothing 1 (Special 0) NoId
+
+-- | Spectral crest measure
+--
+--  FFTCrest [KR] buffer=0.0 freqlo=0.0 freqhi=50000.0
+fFTCrest :: Rate -> UGen -> UGen -> UGen -> UGen
+fFTCrest rate buffer freqlo freqhi = mkUGen Nothing [KR] (Left rate) "FFTCrest" [buffer,freqlo,freqhi] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FFTDiffMags [KR] bufferA=0.0 bufferB=0.0
+fFTDiffMags :: Rate -> UGen -> UGen -> UGen
+fFTDiffMags rate bufferA bufferB = mkUGen Nothing [KR] (Left rate) "FFTDiffMags" [bufferA,bufferB] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FFTFlux [KR] buffer=0.0 normalise=1.0
+fFTFlux :: Rate -> UGen -> UGen -> UGen
+fFTFlux rate buffer normalise = mkUGen Nothing [KR] (Left rate) "FFTFlux" [buffer,normalise] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FFTFluxPos [KR] buffer=0.0 normalise=1.0
+fFTFluxPos :: Rate -> UGen -> UGen -> UGen
+fFTFluxPos rate buffer normalise = mkUGen Nothing [KR] (Left rate) "FFTFluxPos" [buffer,normalise] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FFTMKL [KR] buffer=0.0 epsilon=1.0e-6
+fFTMKL :: Rate -> UGen -> UGen -> UGen
+fFTMKL rate buffer epsilon = mkUGen Nothing [KR] (Left rate) "FFTMKL" [buffer,epsilon] Nothing 1 (Special 0) NoId
+
+-- | Find peak value in an FFT frame
+--
+--  FFTPeak [KR] buffer=0.0 freqlo=0.0 freqhi=50000.0
+fFTPeak :: Rate -> UGen -> UGen -> UGen -> UGen
+fFTPeak rate buffer freqlo freqhi = mkUGen Nothing [KR] (Left rate) "FFTPeak" [buffer,freqlo,freqhi] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FFTPhaseDev [KR] buffer=0.0 weight=0.0 powthresh=0.1
+fFTPhaseDev :: Rate -> UGen -> UGen -> UGen -> UGen
+fFTPhaseDev rate buffer weight powthresh = mkUGen Nothing [KR] (Left rate) "FFTPhaseDev" [buffer,weight,powthresh] Nothing 1 (Special 0) NoId
+
+-- | Instantaneous spectral power
+--
+--  FFTPower [KR] buffer=0.0 square=1.0
+fFTPower :: Rate -> UGen -> UGen -> UGen
+fFTPower rate buffer square = mkUGen Nothing [KR] (Left rate) "FFTPower" [buffer,square] Nothing 1 (Special 0) NoId
+
+-- | Spectral slope
+--
+--  FFTSlope [KR] buffer=0.0
+fFTSlope :: Rate -> UGen -> UGen
+fFTSlope rate buffer = mkUGen Nothing [KR] (Left rate) "FFTSlope" [buffer] Nothing 1 (Special 0) NoId
+
+-- | Spectral spread
+--
+--  FFTSpread [KR] buffer=0.0 centroid=0.0
+fFTSpread :: Rate -> UGen -> UGen -> UGen
+fFTSpread rate buffer centroid = mkUGen Nothing [KR] (Left rate) "FFTSpread" [buffer,centroid] Nothing 1 (Special 0) NoId
+
+-- | Spectral flatness, divided into subbands
+--
+--  FFTSubbandFlatness [KR] chain=0.0 cutfreqs=0.0
+fFTSubbandFlatness :: Rate -> UGen -> UGen -> UGen
+fFTSubbandFlatness rate chain cutfreqs = mkUGen Nothing [KR] (Left rate) "FFTSubbandFlatness" [chain,cutfreqs] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FFTSubbandFlux [KR] chain=0.0 cutfreqs=0.0 posonly=0.0
+fFTSubbandFlux :: Rate -> UGen -> UGen -> UGen -> UGen
+fFTSubbandFlux rate chain cutfreqs posonly = mkUGen Nothing [KR] (Left rate) "FFTSubbandFlux" [chain,cutfreqs,posonly] Nothing 1 (Special 0) NoId
+
+-- | Spectral power, divided into subbands
+--
+--  FFTSubbandPower [KR] chain=0.0 cutfreqs=0.0 square=1.0 scalemode=1.0
+fFTSubbandPower :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+fFTSubbandPower rate chain cutfreqs square scalemode = mkUGen Nothing [KR] (Left rate) "FFTSubbandPower" [chain,cutfreqs,square,scalemode] Nothing 1 (Special 0) NoId
+
+-- | Phase modulation oscillator matrix.
+--
+--  FM7 [AR] *ctlMatrix=0.0 *modMatrix=0.0
+fm7 :: Rate -> UGen -> UGen -> UGen
+fm7 rate ctlMatrix modMatrix = mkUGen Nothing [AR] (Left rate) "FM7" [] (Just [ctlMatrix,modMatrix]) 6 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FMGrain [AR] trigger=0.0 dur=1.0 carfreq=440.0 modfreq=200.0 index=1.0
+fmGrain :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fmGrain trigger dur carfreq modfreq index_ = mkUGen Nothing [AR] (Right [0]) "FMGrain" [trigger,dur,carfreq,modfreq,index_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FMGrainB [AR] trigger=0.0 dur=1.0 carfreq=440.0 modfreq=200.0 index=1.0 envbuf=0.0
+fmGrainB :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fmGrainB trigger dur carfreq modfreq index_ envbuf = mkUGen Nothing [AR] (Right [0]) "FMGrainB" [trigger,dur,carfreq,modfreq,index_,envbuf] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FMGrainBBF [AR] trigger=0.0 dur=1.0 carfreq=440.0 modfreq=200.0 index=1.0 envbuf=0.0 azimuth=0.0 elevation=0.0 rho=1.0 wComp=0.0
+fmGrainBBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fmGrainBBF rate trigger dur carfreq modfreq index_ envbuf azimuth elevation rho wComp = mkUGen Nothing [AR] (Left rate) "FMGrainBBF" [trigger,dur,carfreq,modfreq,index_,envbuf,azimuth,elevation,rho,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FMGrainBF [AR] trigger=0.0 dur=1.0 carfreq=440.0 modfreq=200.0 index=1.0 azimuth=0.0 elevation=0.0 rho=1.0 wComp=0.0
+fmGrainBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fmGrainBF rate trigger dur carfreq modfreq index_ azimuth elevation rho wComp = mkUGen Nothing [AR] (Left rate) "FMGrainBF" [trigger,dur,carfreq,modfreq,index_,azimuth,elevation,rho,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FMGrainI [AR] trigger=0.0 dur=1.0 carfreq=440.0 modfreq=200.0 index=1.0 envbuf1=0.0 envbuf2=0.0 ifac=0.5
+fmGrainI :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fmGrainI rate trigger dur carfreq modfreq index_ envbuf1 envbuf2 ifac = mkUGen Nothing [AR] (Left rate) "FMGrainI" [trigger,dur,carfreq,modfreq,index_,envbuf1,envbuf2,ifac] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FMGrainIBF [AR] trigger=0.0 dur=1.0 carfreq=440.0 modfreq=200.0 index=1.0 envbuf1=0.0 envbuf2=0.0 ifac=0.5 azimuth=0.0 elevation=0.0 rho=1.0 wComp=0.0
+fmGrainIBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fmGrainIBF rate trigger dur carfreq modfreq index_ envbuf1 envbuf2 ifac azimuth elevation rho wComp = mkUGen Nothing [AR] (Left rate) "FMGrainIBF" [trigger,dur,carfreq,modfreq,index_,envbuf1,envbuf2,ifac,azimuth,elevation,rho,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FMHDecode1 [AR] w=0.0 x=0.0 y=0.0 z=0.0 r=0.0 s=0.0 t=0.0 u=0.0 v=0.0 azimuth=0.0 elevation=0.0
+fMHDecode1 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fMHDecode1 rate w x y z r s t u v azimuth elevation = mkUGen Nothing [AR] (Left rate) "FMHDecode1" [w,x,y,z,r,s,t,u,v,azimuth,elevation] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FMHEncode0 [AR] in=0.0 azimuth=0.0 elevation=0.0 gain=1.0
+fMHEncode0 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+fMHEncode0 rate in_ azimuth elevation gain = mkUGen Nothing [AR] (Left rate) "FMHEncode0" [in_,azimuth,elevation,gain] Nothing 9 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FMHEncode1 [AR] in=0.0 azimuth=0.0 elevation=0.0 rho=1.0 gain=1.0 wComp=0.0
+fMHEncode1 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fMHEncode1 rate in_ azimuth elevation rho gain wComp = mkUGen Nothing [AR] (Left rate) "FMHEncode1" [in_,azimuth,elevation,rho,gain,wComp] Nothing 9 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FMHEncode2 [AR] in=0.0 point_x=0.0 point_y=0.0 elevation=0.0 gain=1.0 wComp=0.0
+fMHEncode2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fMHEncode2 rate in_ point_x point_y elevation gain wComp = mkUGen Nothing [AR] (Left rate) "FMHEncode2" [in_,point_x,point_y,elevation,gain,wComp] Nothing 9 (Special 0) NoId
+
+-- | Storing feature data from UGens in NRT mode
+--
+--  FeatureSave [KR] features=0.0 trig=0.0
+featureSave :: Rate -> UGen -> UGen -> UGen
+featureSave rate features trig_ = mkUGen Nothing [KR] (Left rate) "FeatureSave" [features,trig_] Nothing 1 (Special 0) NoId
+
+-- | FitzHughNagumo Neuron Firing Oscillator
+--
+--  Fhn2DC [KR,AR] minfreq=11025.0 maxfreq=22050.0 urate=0.1 wrate=0.1 b0=0.6 b1=0.8 i=0.0 u0=0.0 w0=0.0
+fhn2DC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fhn2DC rate minfreq maxfreq urate wrate b0 b1 i u0 w0 = mkUGen Nothing [KR,AR] (Left rate) "Fhn2DC" [minfreq,maxfreq,urate,wrate,b0,b1,i,u0,w0] Nothing 1 (Special 0) NoId
+
+-- | FitzHughNagumo Neuron Firing Oscillator
+--
+--  Fhn2DL [KR,AR] minfreq=11025.0 maxfreq=22050.0 urate=0.1 wrate=0.1 b0=0.6 b1=0.8 i=0.0 u0=0.0 w0=0.0
+fhn2DL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fhn2DL rate minfreq maxfreq urate wrate b0 b1 i u0 w0 = mkUGen Nothing [KR,AR] (Left rate) "Fhn2DL" [minfreq,maxfreq,urate,wrate,b0,b1,i,u0,w0] Nothing 1 (Special 0) NoId
+
+-- | FitzHughNagumo Neuron Firing Oscillator
+--
+--  Fhn2DN [KR,AR] minfreq=11025.0 maxfreq=22050.0 urate=0.1 wrate=0.1 b0=0.6 b1=0.8 i=0.0 u0=0.0 w0=0.0
+fhn2DN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fhn2DN rate minfreq maxfreq urate wrate b0 b1 i u0 w0 = mkUGen Nothing [KR,AR] (Left rate) "Fhn2DN" [minfreq,maxfreq,urate,wrate,b0,b1,i,u0,w0] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FhnTrig [KR,AR] minfreq=4.0 maxfreq=10.0 urate=0.1 wrate=0.1 b0=0.6 b1=0.8 i=0.0 u0=0.0 w0=0.0
+fhnTrig :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fhnTrig rate minfreq maxfreq urate wrate b0 b1 i u0 w0 = mkUGen Nothing [KR,AR] (Left rate) "FhnTrig" [minfreq,maxfreq,urate,wrate,b0,b1,i,u0,w0] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FincoSprottL [AR] freq=22050.0 a=2.45 h=5.0e-2 xi=0.0 yi=0.0 zi=0.0
+fincoSprottL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fincoSprottL rate freq a h xi yi zi = mkUGen Nothing [AR] (Left rate) "FincoSprottL" [freq,a,h,xi,yi,zi] Nothing 3 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FincoSprottM [AR] freq=22050.0 a=-7.0 b=4.0 h=5.0e-2 xi=0.0 yi=0.0 zi=0.0
+fincoSprottM :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fincoSprottM rate freq a b h xi yi zi = mkUGen Nothing [AR] (Left rate) "FincoSprottM" [freq,a,b,h,xi,yi,zi] Nothing 3 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  FincoSprottS [AR] freq=22050.0 a=8.0 b=2.0 h=5.0e-2 xi=0.0 yi=0.0 zi=0.0
+fincoSprottS :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fincoSprottS rate freq a b h xi yi zi = mkUGen Nothing [AR] (Left rate) "FincoSprottS" [freq,a,b,h,xi,yi,zi] Nothing 3 (Special 0) NoId
+
+-- | Neuron Firing Model Oscillator
+--
+--  FitzHughNagumo [AR] reset=0.0 rateu=1.0e-2 ratew=1.0e-2 b0=1.0 b1=1.0 initu=0.0 initw=0.0
+fitzHughNagumo :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+fitzHughNagumo rate reset rateu ratew b0 b1 initu initw = mkUGen Nothing [AR] (Left rate) "FitzHughNagumo" [reset,rateu,ratew,b0,b1,initu,initw] Nothing 1 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) UGen superclass
+--
+--  Foa [] maxSize=0.0
+foa :: Rate -> UGen -> UGen
+foa rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "Foa" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) asymmetry transformer
+--
+--  FoaAsymmetry [AR] in=0.0 angle=0.0
+foaAsymmetry :: Rate -> UGen -> UGen -> UGen
+foaAsymmetry rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaAsymmetry" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) directivity transformer
+--
+--  FoaDirectO [AR] in=0.0 angle=0.0
+foaDirectO :: Rate -> UGen -> UGen -> UGen
+foaDirectO rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaDirectO" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) directivity transformer
+--
+--  FoaDirectX [AR] in=0.0 angle=0.0
+foaDirectX :: Rate -> UGen -> UGen -> UGen
+foaDirectX rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaDirectX" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) directivity transformer
+--
+--  FoaDirectY [AR] in=0.0 angle=0.0
+foaDirectY :: Rate -> UGen -> UGen -> UGen
+foaDirectY rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaDirectY" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) directivity transformer
+--
+--  FoaDirectZ [AR] in=0.0 angle=0.0
+foaDirectZ :: Rate -> UGen -> UGen -> UGen
+foaDirectZ rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaDirectZ" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) dominance transformer
+--
+--  FoaDominateX [AR] in=0.0 gain=0.0
+foaDominateX :: Rate -> UGen -> UGen -> UGen
+foaDominateX rate in_ gain = mkUGen Nothing [AR] (Left rate) "FoaDominateX" [in_,gain] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) dominance transformer
+--
+--  FoaDominateY [AR] in=0.0 gain=0.0
+foaDominateY :: Rate -> UGen -> UGen -> UGen
+foaDominateY rate in_ gain = mkUGen Nothing [AR] (Left rate) "FoaDominateY" [in_,gain] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) dominance transformer
+--
+--  FoaDominateZ [AR] in=0.0 gain=0.0
+foaDominateZ :: Rate -> UGen -> UGen -> UGen
+foaDominateZ rate in_ gain = mkUGen Nothing [AR] (Left rate) "FoaDominateZ" [in_,gain] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) focus transformer
+--
+--  FoaFocusX [AR] in=0.0 angle=0.0
+foaFocusX :: Rate -> UGen -> UGen -> UGen
+foaFocusX rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaFocusX" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) focus transformer
+--
+--  FoaFocusY [AR] in=0.0 angle=0.0
+foaFocusY :: Rate -> UGen -> UGen -> UGen
+foaFocusY rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaFocusY" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) focus transformer
+--
+--  FoaFocusZ [AR] in=0.0 angle=0.0
+foaFocusZ :: Rate -> UGen -> UGen -> UGen
+foaFocusZ rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaFocusZ" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) nearfield compensation filter
+--
+--  FoaNFC [AR] in=0.0 distance=1.0
+foaNFC :: Rate -> UGen -> UGen -> UGen
+foaNFC rate in_ distance = mkUGen Nothing [AR] (Left rate) "FoaNFC" [in_,distance] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) panner
+--
+--  FoaPanB [AR] in=0.0 azimuth=0.0 elevation=0.0
+foaPanB :: Rate -> UGen -> UGen -> UGen -> UGen
+foaPanB rate in_ azimuth elevation = mkUGen Nothing [AR] (Left rate) "FoaPanB" [in_,azimuth,elevation] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) press transformer
+--
+--  FoaPressX [AR] in=0.0 angle=0.0
+foaPressX :: Rate -> UGen -> UGen -> UGen
+foaPressX rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaPressX" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) press transformer
+--
+--  FoaPressY [AR] in=0.0 angle=0.0
+foaPressY :: Rate -> UGen -> UGen -> UGen
+foaPressY rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaPressY" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) press transformer
+--
+--  FoaPressZ [AR] in=0.0 angle=0.0
+foaPressZ :: Rate -> UGen -> UGen -> UGen
+foaPressZ rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaPressZ" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) proximity effect filter
+--
+--  FoaProximity [AR] in=0.0 distance=1.0
+foaProximity :: Rate -> UGen -> UGen -> UGen
+foaProximity rate in_ distance = mkUGen Nothing [AR] (Left rate) "FoaProximity" [in_,distance] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) psychoacoustic shelf filter
+--
+--  FoaPsychoShelf [AR] in=0.0 freq=400.0 k0=0.0 k1=0.0
+foaPsychoShelf :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+foaPsychoShelf rate in_ freq k0 k1 = mkUGen Nothing [AR] (Left rate) "FoaPsychoShelf" [in_,freq,k0,k1] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) push transformer
+--
+--  FoaPushX [AR] in=0.0 angle=0.0
+foaPushX :: Rate -> UGen -> UGen -> UGen
+foaPushX rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaPushX" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) push transformer
+--
+--  FoaPushY [AR] in=0.0 angle=0.0
+foaPushY :: Rate -> UGen -> UGen -> UGen
+foaPushY rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaPushY" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) push transformer
+--
+--  FoaPushZ [AR] in=0.0 angle=0.0
+foaPushZ :: Rate -> UGen -> UGen -> UGen
+foaPushZ rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaPushZ" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) rotation transformer
+--
+--  FoaRotate [AR] in=0.0 angle=0.0
+foaRotate :: Rate -> UGen -> UGen -> UGen
+foaRotate rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaRotate" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) rotation transformer
+--
+--  FoaTilt [AR] in=0.0 angle=0.0
+foaTilt :: Rate -> UGen -> UGen -> UGen
+foaTilt rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaTilt" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) rotation transformer
+--
+--  FoaTumble [AR] in=0.0 angle=0.0
+foaTumble :: Rate -> UGen -> UGen -> UGen
+foaTumble rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaTumble" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) zoom transformer
+--
+--  FoaZoomX [AR] in=0.0 angle=0.0
+foaZoomX :: Rate -> UGen -> UGen -> UGen
+foaZoomX rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaZoomX" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) zoom transformer
+--
+--  FoaZoomY [AR] in=0.0 angle=0.0
+foaZoomY :: Rate -> UGen -> UGen -> UGen
+foaZoomY rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaZoomY" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | First Order Ambisonic (FOA) zoom transformer
+--
+--  FoaZoomZ [AR] in=0.0 angle=0.0
+foaZoomZ :: Rate -> UGen -> UGen -> UGen
+foaZoomZ rate in_ angle = mkUGen Nothing [AR] (Left rate) "FoaZoomZ" [in_,angle] Nothing 4 (Special 0) NoId
+
+-- | calculates spectral MSE distance of two fft chains
+--
+--  FrameCompare [KR] buffer1=0.0 buffer2=0.0 wAmount=0.5
+frameCompare :: Rate -> UGen -> UGen -> UGen -> UGen
+frameCompare rate buffer1 buffer2 wAmount = mkUGen Nothing [KR] (Left rate) "FrameCompare" [buffer1,buffer2,wAmount] Nothing 1 (Special 0) NoId
+
+-- | A physical model of a system with dry-friction. A chaotic filter.
+--
+--  Friction [KR,AR] in=0.0 friction=0.5 spring=0.414 damp=0.313 mass=0.1 beltmass=1.0
+friction :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+friction rate in_ friction_ spring_ damp mass beltmass = mkUGen Nothing [KR,AR] (Left rate) "Friction" [in_,friction_,spring_,damp,mass,beltmass] Nothing 1 (Special 0) NoId
+
+-- | Single gammatone filter
+--
+--  Gammatone [AR] input=0.0 centrefrequency=440.0 bandwidth=200.0
+gammatone :: Rate -> UGen -> UGen -> UGen -> UGen
+gammatone rate input centrefrequency bandwidth = mkUGen Nothing [AR] (Left rate) "Gammatone" [input,centrefrequency,bandwidth] Nothing 1 (Special 0) NoId
+
+-- | Gaussian classifier
+--
+--  GaussClass [KR] in=0.0 bufnum=0.0 gate=0.0
+gaussClass :: Rate -> UGen -> UGen -> UGen -> UGen
+gaussClass rate in_ bufnum gate_ = mkUGen Nothing [KR] (Left rate) "GaussClass" [in_,bufnum,gate_] Nothing 1 (Special 0) NoId
+
+-- | impulses around a certain frequency
+--
+--  GaussTrig [KR,AR] freq=440.0 dev=0.3
+gaussTrig :: Rate -> UGen -> UGen -> UGen
+gaussTrig rate freq dev = mkUGen Nothing [KR,AR] (Left rate) "GaussTrig" [freq,dev] Nothing 1 (Special 0) NoId
+
+-- | gingerbreadman map 2D chaotic generator
+--
+--  Gbman2DC [KR,AR] minfreq=11025.0 maxfreq=22050.0 x0=1.2 y0=2.1
+gbman2DC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+gbman2DC rate minfreq maxfreq x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Gbman2DC" [minfreq,maxfreq,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | gingerbreadman map 2D chaotic generator
+--
+--  Gbman2DL [KR,AR] minfreq=11025.0 maxfreq=22050.0 x0=1.2 y0=2.1
+gbman2DL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+gbman2DL rate minfreq maxfreq x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Gbman2DL" [minfreq,maxfreq,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | gingerbreadman map 2D chaotic generator
+--
+--  Gbman2DN [KR,AR] minfreq=11025.0 maxfreq=22050.0 x0=1.2 y0=2.1
+gbman2DN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+gbman2DN rate minfreq maxfreq x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Gbman2DN" [minfreq,maxfreq,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  GbmanTrig [KR,AR] minfreq=5.0 maxfreq=10.0 x0=1.2 y0=2.1
+gbmanTrig :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+gbmanTrig rate minfreq maxfreq x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "GbmanTrig" [minfreq,maxfreq,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | Dynamic stochastic synthesis generator
+--
+--  Gendy4 [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
+gendy4 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+gendy4 rate ampdist durdist adparam ddparam minfreq maxfreq ampscale durscale initCPs knum = mkUGen Nothing [KR,AR] (Left rate) "Gendy4" [ampdist,durdist,adparam,ddparam,minfreq,maxfreq,ampscale,durscale,initCPs,knum] Nothing 1 (Special 0) NoId
+
+-- | Dynamic stochastic synthesis generator
+--
+--  Gendy5 [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
+gendy5 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+gendy5 rate ampdist durdist adparam ddparam minfreq maxfreq ampscale durscale initCPs knum = mkUGen Nothing [KR,AR] (Left rate) "Gendy5" [ampdist,durdist,adparam,ddparam,minfreq,maxfreq,ampscale,durscale,initCPs,knum] Nothing 1 (Special 0) NoId
+
+-- | Read (numeric) shell environment variables into a synth
+--
+--  Getenv [] key=0.0 defaultval=0.0
+getenv :: Rate -> UGen -> UGen -> UGen
+getenv rate key defaultval = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "Getenv" [key,defaultval] Nothing 1 (Special 0) NoId
+
+-- | backward compatibility
+--
+--  GlitchBPF [KR,AR] in=0.0 freq=440.0 rq=1.0
+glitchBPF :: Rate -> UGen -> UGen -> UGen -> UGen
+glitchBPF rate in_ freq rq = mkUGen Nothing [KR,AR] (Left rate) "GlitchBPF" [in_,freq,rq] Nothing 1 (Special 0) NoId
+
+-- | backward compatibility
+--
+--  GlitchBRF [KR,AR] in=0.0 freq=440.0 rq=1.0
+glitchBRF :: Rate -> UGen -> UGen -> UGen -> UGen
+glitchBRF rate in_ freq rq = mkUGen Nothing [KR,AR] (Left rate) "GlitchBRF" [in_,freq,rq] Nothing 1 (Special 0) NoId
+
+-- | backward compatibility
+--
+--  GlitchHPF [KR,AR] in=0.0 freq=440.0
+glitchHPF :: Rate -> UGen -> UGen -> UGen
+glitchHPF rate in_ freq = mkUGen Nothing [KR,AR] (Left rate) "GlitchHPF" [in_,freq] Nothing 1 (Special 0) NoId
+
+-- | backward compatibility
+--
+--  GlitchRHPF [KR,AR] in=0.0 freq=440.0 rq=1.0
+glitchRHPF :: Rate -> UGen -> UGen -> UGen -> UGen
+glitchRHPF rate in_ freq rq = mkUGen Nothing [KR,AR] (Left rate) "GlitchRHPF" [in_,freq,rq] Nothing 1 (Special 0) NoId
+
+-- | Calculate a single DFT bin, to detect presence of a frequency
+--
+--  Goertzel [KR] in=0.0 bufsize=1024.0 freq=0.0 hop=1.0
+goertzel :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+goertzel rate in_ bufsize freq hop = mkUGen Nothing [KR] (Left rate) "Goertzel" [in_,bufsize,freq,hop] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  GrainBufJ [AR] numChannels=1.0 trigger=0.0 dur=1.0 sndbuf=0.0 rate=1.0 pos=0.0 loop=0.0 interp=2.0 grainAmp=1.0 pan=0.0 envbufnum=-1.0 maxGrains=512.0
+grainBufJ :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+grainBufJ rate numChannels trigger dur sndbuf rate_ pos loop interp grainAmp pan envbufnum maxGrains = mkUGen Nothing [AR] (Left rate) "GrainBufJ" [numChannels,trigger,dur,sndbuf,rate_,pos,loop,interp,grainAmp,pan,envbufnum,maxGrains] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  GrainFMJ [AR] numChannels=1.0 trigger=0.0 dur=1.0 carfreq=440.0 modfreq=200.0 index=1.0 grainAmp=1.0 pan=0.0 envbufnum=-1.0 maxGrains=512.0
+grainFMJ :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+grainFMJ rate numChannels trigger dur carfreq modfreq index_ grainAmp pan envbufnum maxGrains = mkUGen Nothing [AR] (Left rate) "GrainFMJ" [numChannels,trigger,dur,carfreq,modfreq,index_,grainAmp,pan,envbufnum,maxGrains] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  GrainInJ [AR] numChannels=1.0 trigger=0.0 dur=1.0 in=0.0 grainAmp=1.0 pan=0.0 envbufnum=-1.0 maxGrains=512.0
+grainInJ :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+grainInJ rate numChannels trigger dur in_ grainAmp pan envbufnum maxGrains = mkUGen Nothing [AR] (Left rate) "GrainInJ" [numChannels,trigger,dur,in_,grainAmp,pan,envbufnum,maxGrains] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  GrainSinJ [AR] numChannels=1.0 trigger=0.0 dur=1.0 freq=440.0 grainAmp=1.0 pan=0.0 envbufnum=-1.0 maxGrains=512.0
+grainSinJ :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+grainSinJ rate numChannels trigger dur freq grainAmp pan envbufnum maxGrains = mkUGen Nothing [AR] (Left rate) "GrainSinJ" [numChannels,trigger,dur,freq,grainAmp,pan,envbufnum,maxGrains] Nothing 1 (Special 0) NoId
+
+-- | dynamical system simulation (Newtonian gravitational force)
+--
+--  GravityGrid [AR] reset=0.0 rate=0.1 newx=0.0 newy=0.0 bufnum=0.0
+gravityGrid :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+gravityGrid rate reset rate_ newx newy bufnum = mkUGen Nothing [AR] (Left rate) "GravityGrid" [reset,rate_,newx,newy,bufnum] Nothing 1 (Special 0) NoId
+
+-- | dynamical system simulation (Newtonian gravitational force)
+--
+--  GravityGrid2 [AR] reset=0.0 rate=0.1 newx=0.0 newy=0.0 bufnum=0.0
+gravityGrid2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+gravityGrid2 rate reset rate_ newx newy bufnum = mkUGen Nothing [AR] (Left rate) "GravityGrid2" [reset,rate_,newx,newy,bufnum] Nothing 1 (Special 0) NoId
+
+-- | algorithmic delay
+--
+--  GreyholeRaw [AR] in1=0.0 in2=0.0 damping=0.0 delaytime=2.0 diffusion=0.5 feedback=0.9 moddepth=0.1 modfreq=2.0 size=1.0
+greyholeRaw :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+greyholeRaw in1 in2 damping delaytime diffusion feedback moddepth modfreq size = mkUGen Nothing [AR] (Right [0,1]) "GreyholeRaw" [in1,in2,damping,delaytime,diffusion,feedback,moddepth,modfreq,size] Nothing 2 (Special 0) NoId
+
+-- | Simple cochlear hair cell model
+--
+--  HairCell [KR,AR] input=0.0 spontaneousrate=0.0 boostrate=200.0 restorerate=1000.0 loss=0.99
+hairCell :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+hairCell rate input spontaneousrate boostrate restorerate loss = mkUGen Nothing [KR,AR] (Left rate) "HairCell" [input,spontaneousrate,boostrate,restorerate,loss] Nothing 1 (Special 0) NoId
+
+-- | henon map 2D chaotic generator
+--
+--  Henon2DC [KR,AR] minfreq=11025.0 maxfreq=22050.0 a=1.4 b=0.3 x0=0.30501993062401 y0=0.20938865431933
+henon2DC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+henon2DC rate minfreq maxfreq a b x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Henon2DC" [minfreq,maxfreq,a,b,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | henon map 2D chaotic generator
+--
+--  Henon2DL [KR,AR] minfreq=11025.0 maxfreq=22050.0 a=1.4 b=0.3 x0=0.30501993062401 y0=0.20938865431933
+henon2DL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+henon2DL rate minfreq maxfreq a b x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Henon2DL" [minfreq,maxfreq,a,b,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | henon map 2D chaotic generator
+--
+--  Henon2DN [KR,AR] minfreq=11025.0 maxfreq=22050.0 a=1.4 b=0.3 x0=0.30501993062401 y0=0.20938865431933
+henon2DN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+henon2DN rate minfreq maxfreq a b x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Henon2DN" [minfreq,maxfreq,a,b,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  HenonTrig [KR,AR] minfreq=5.0 maxfreq=10.0 a=1.4 b=0.3 x0=0.30501993062401 y0=0.20938865431933
+henonTrig :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+henonTrig rate minfreq maxfreq a b x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "HenonTrig" [minfreq,maxfreq,a,b,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | Transform a cepstrum back to a spectrum
+--
+--  ICepstrum [] cepchain=0.0 fftbuf=0.0
+iCepstrum :: Rate -> UGen -> UGen -> UGen
+iCepstrum rate cepchain fftbuf = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "ICepstrum" [cepchain,fftbuf] Nothing 1 (Special 0) NoId
+
+-- | 24db/oct rolloff, 4nd order resonant Low Pass Filter
+--
+--  IIRFilter [AR] in=0.0 freq=440.0 rq=1.0
+iirFilter :: UGen -> UGen -> UGen -> UGen
+iirFilter in_ freq rq = mkUGen Nothing [AR] (Right [0]) "IIRFilter" [in_,freq,rq] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  InGrain [AR] trigger=0.0 dur=1.0 in=0.0
+inGrain :: Rate -> UGen -> UGen -> UGen -> UGen
+inGrain rate trigger dur in_ = mkUGen Nothing [AR] (Left rate) "InGrain" [trigger,dur,in_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  InGrainB [AR] trigger=0.0 dur=1.0 in=0.0 envbuf=0.0
+inGrainB :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+inGrainB rate trigger dur in_ envbuf = mkUGen Nothing [AR] (Left rate) "InGrainB" [trigger,dur,in_,envbuf] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  InGrainBBF [AR] trigger=0.0 dur=1.0 in=0.0 envbuf=0.0 azimuth=0.0 elevation=0.0 rho=1.0 wComp=0.0
+inGrainBBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+inGrainBBF rate trigger dur in_ envbuf azimuth elevation rho wComp = mkUGen Nothing [AR] (Left rate) "InGrainBBF" [trigger,dur,in_,envbuf,azimuth,elevation,rho,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  InGrainBF [AR] trigger=0.0 dur=1.0 in=0.0 azimuth=0.0 elevation=0.0 rho=1.0 wComp=0.0
+inGrainBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+inGrainBF rate trigger dur in_ azimuth elevation rho wComp = mkUGen Nothing [AR] (Left rate) "InGrainBF" [trigger,dur,in_,azimuth,elevation,rho,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  InGrainI [AR] trigger=0.0 dur=1.0 in=0.0 envbuf1=0.0 envbuf2=0.0 ifac=0.5
+inGrainI :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+inGrainI rate trigger dur in_ envbuf1 envbuf2 ifac = mkUGen Nothing [AR] (Left rate) "InGrainI" [trigger,dur,in_,envbuf1,envbuf2,ifac] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  InGrainIBF [AR] trigger=0.0 dur=1.0 in=0.0 envbuf1=0.0 envbuf2=0.0 ifac=0.5 azimuth=0.0 elevation=0.0 rho=1.0 wComp=0.0
+inGrainIBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+inGrainIBF rate trigger dur in_ envbuf1 envbuf2 ifac azimuth elevation rho wComp = mkUGen Nothing [AR] (Left rate) "InGrainIBF" [trigger,dur,in_,envbuf1,envbuf2,ifac,azimuth,elevation,rho,wComp] Nothing 4 (Special 0) NoId
+
+-- | Distortion by subtracting magnitude from 1
+--
+--  InsideOut [KR,AR] in=0.0
+insideOut :: Rate -> UGen -> UGen
+insideOut rate in_ = mkUGen Nothing [KR,AR] (Left rate) "InsideOut" [in_] Nothing 1 (Special 0) NoId
+
+-- | instruction synthesis (breakpoint set interpreter)
+--
+--  Instruction [AR] bufnum=0.0
+instruction :: Rate -> UGen -> UGen
+instruction rate bufnum = mkUGen Nothing [AR] (Left rate) "Instruction" [bufnum] Nothing 1 (Special 0) NoId
+
+-- | Raw version of the JPverb algorithmic reverberator, designed to produce long tails with chorusing
+--
+--  JPverbRaw [KR,AR] in1=0.0 in2=0.0 damp=0.0 earlydiff=0.707 highband=2000.0 highx=1.0 lowband=500.0 lowx=1.0 mdepth=0.1 mfreq=2.0 midx=1.0 size=1.0 t60=1.0;    FILTER: TRUE
+jPverbRaw :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+jPverbRaw in1 in2 damp earlydiff highband highx lowband lowx mdepth mfreq midx size t60 = mkUGen Nothing [KR,AR] (Right [0]) "JPverbRaw" [in1,in2,damp,earlydiff,highband,highx,lowband,lowx,mdepth,mfreq,midx,size,t60] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  JoshGrain [] maxSize=0.0
+joshGrain :: Rate -> UGen -> UGen
+joshGrain rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "JoshGrain" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  JoshMultiChannelGrain [] maxSize=0.0
+joshMultiChannelGrain :: Rate -> UGen -> UGen
+joshMultiChannelGrain rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "JoshMultiChannelGrain" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  JoshMultiOutGrain [] maxSize=0.0
+joshMultiOutGrain :: Rate -> UGen -> UGen
+joshMultiOutGrain rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "JoshMultiOutGrain" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | k-means classification in real time
+--
+--  KMeansRT [KR] bufnum=0.0 inputdata=0.0 k=5.0 gate=1.0 reset=0.0 learn=1.0
+kMeansRT :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+kMeansRT rate bufnum inputdata k gate_ reset learn = mkUGen Nothing [KR] (Left rate) "KMeansRT" [bufnum,inputdata,k,gate_,reset,learn] Nothing 1 (Special 0) NoId
+
+-- | Running score of maximum correlation of chromagram with key profiles
+--
+--  KeyClarity [KR] chain=0.0 keydecay=2.0 chromaleak=0.5
+keyClarity :: Rate -> UGen -> UGen -> UGen -> UGen
+keyClarity rate chain keydecay chromaleak = mkUGen Nothing [KR] (Left rate) "KeyClarity" [chain,keydecay,chromaleak] Nothing 1 (Special 0) NoId
+
+-- | Find best correlated key mode with chromagram between major, minor and chromatic cluster
+--
+--  KeyMode [KR] chain=0.0 keydecay=2.0 chromaleak=0.5
+keyMode :: Rate -> UGen -> UGen -> UGen -> UGen
+keyMode rate chain keydecay chromaleak = mkUGen Nothing [KR] (Left rate) "KeyMode" [chain,keydecay,chromaleak] Nothing 1 (Special 0) NoId
+
+-- | K-means Oscillator
+--
+--  KmeansToBPSet1 [AR] freq=440.0 numdatapoints=20.0 maxnummeans=4.0 nummeans=4.0 tnewdata=1.0 tnewmeans=1.0 soft=1.0 bufnum=0.0
+kmeansToBPSet1 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+kmeansToBPSet1 rate freq numdatapoints maxnummeans nummeans tnewdata tnewmeans soft bufnum = mkUGen Nothing [AR] (Left rate) "KmeansToBPSet1" [freq,numdatapoints,maxnummeans,nummeans,tnewdata,tnewmeans,soft,bufnum] Nothing 1 (Special 0) NoId
+
+-- | random walk step
+--
+--  LFBrownNoise0 [KR,AR] freq=20.0 dev=1.0 dist=0.0;    NONDET
+lfBrownNoise0 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen
+lfBrownNoise0 z rate freq dev dist = mkUGen Nothing [KR,AR] (Left rate) "LFBrownNoise0" [freq,dev,dist] Nothing 1 (Special 0) (toUId z)
+
+-- | random walk linear interp
+--
+--  LFBrownNoise1 [KR,AR] freq=20.0 dev=1.0 dist=0.0;    NONDET
+lfBrownNoise1 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen
+lfBrownNoise1 z rate freq dev dist = mkUGen Nothing [KR,AR] (Left rate) "LFBrownNoise1" [freq,dev,dist] Nothing 1 (Special 0) (toUId z)
+
+-- | random walk cubic interp
+--
+--  LFBrownNoise2 [KR,AR] freq=20.0 dev=1.0 dist=0.0;    NONDET
+lfBrownNoise2 :: ID a => a -> Rate -> UGen -> UGen -> UGen -> UGen
+lfBrownNoise2 z rate freq dev dist = mkUGen Nothing [KR,AR] (Left rate) "LFBrownNoise2" [freq,dev,dist] Nothing 1 (Special 0) (toUId z)
+
+-- | Live Linear Predictive Coding Analysis and Resynthesis
+--
+--  LPCAnalyzer [AR] input=0.0 source=1.0e-2 n=256.0 p=10.0 testE=0.0 delta=0.999 windowtype=0.0;    FILTER: TRUE
+lpcAnalyzer :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+lpcAnalyzer input source n p testE delta windowtype = mkUGen Nothing [AR] (Right [0,1]) "LPCAnalyzer" [input,source,n,p,testE,delta,windowtype] Nothing 1 (Special 0) NoId
+
+-- | Linear Predictive Coding Gone Wrong
+--
+--  LPCError [AR] input=0.0 p=10.0
+lpcError :: Rate -> UGen -> UGen -> UGen
+lpcError rate input p = mkUGen Nothing [AR] (Left rate) "LPCError" [input,p] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  LPCSynth [AR] buffer=0.0 signal=0.0 pointer=0.0
+lpcSynth :: UGen -> UGen -> UGen -> UGen
+lpcSynth buffer signal pointer = mkUGen Nothing [AR] (Left AR) "LPCSynth" [buffer,signal,pointer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  LPCVals [KR,AR] buffer=0.0 pointer=0.0
+lpcVals :: Rate -> UGen -> UGen -> UGen
+lpcVals rate buffer pointer = mkUGen Nothing [KR,AR] (Left rate) "LPCVals" [buffer,pointer] Nothing 3 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  LPF1 [KR,AR] in=0.0 freq=1000.0
+lPF1 :: Rate -> UGen -> UGen -> UGen
+lPF1 rate in_ freq = mkUGen Nothing [KR,AR] (Left rate) "LPF1" [in_,freq] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  LPF18 [AR] in=0.0 freq=100.0 res=1.0 dist=0.4
+lPF18 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+lPF18 rate in_ freq res dist = mkUGen Nothing [AR] (Left rate) "LPF18" [in_,freq,res,dist] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  LPFVS6 [KR,AR] in=0.0 freq=1000.0 slope=0.5
+lPFVS6 :: Rate -> UGen -> UGen -> UGen -> UGen
+lPFVS6 rate in_ freq slope_ = mkUGen Nothing [KR,AR] (Left rate) "LPFVS6" [in_,freq,slope_] Nothing 1 (Special 0) NoId
+
+-- | Linear Time Invariant General Filter Equation
+--
+--  LTI [AR] input=0.0 bufnuma=0.0 bufnumb=1.0
+lti :: Rate -> UGen -> UGen -> UGen -> UGen
+lti rate input bufnuma bufnumb = mkUGen Nothing [AR] (Left rate) "LTI" [input,bufnuma,bufnumb] Nothing 1 (Special 0) NoId
+
+-- | latoocarfian 2D chaotic generator
+--
+--  Latoocarfian2DC [KR,AR] minfreq=11025.0 maxfreq=22050.0 a=1.0 b=3.0 c=0.5 d=0.5 x0=0.34082301375036 y0=-0.38270086971332
+latoocarfian2DC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+latoocarfian2DC rate minfreq maxfreq a b c d x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Latoocarfian2DC" [minfreq,maxfreq,a,b,c,d,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | latoocarfian 2D chaotic generator
+--
+--  Latoocarfian2DL [KR,AR] minfreq=11025.0 maxfreq=22050.0 a=1.0 b=3.0 c=0.5 d=0.5 x0=0.34082301375036 y0=-0.38270086971332
+latoocarfian2DL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+latoocarfian2DL rate minfreq maxfreq a b c d x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Latoocarfian2DL" [minfreq,maxfreq,a,b,c,d,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | latoocarfian 2D chaotic generator
+--
+--  Latoocarfian2DN [KR,AR] minfreq=11025.0 maxfreq=22050.0 a=1.0 b=3.0 c=0.5 d=0.5 x0=0.34082301375036 y0=-0.38270086971332
+latoocarfian2DN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+latoocarfian2DN rate minfreq maxfreq a b c d x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Latoocarfian2DN" [minfreq,maxfreq,a,b,c,d,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  LatoocarfianTrig [KR,AR] minfreq=5.0 maxfreq=10.0 a=1.0 b=3.0 c=0.5 d=0.5 x0=0.34082301375036 y0=-0.38270086971332
+latoocarfianTrig :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+latoocarfianTrig rate minfreq maxfreq a b c d x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "LatoocarfianTrig" [minfreq,maxfreq,a,b,c,d,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | Emit a sequence of triggers at specified time offsets
+--
+--  ListTrig [KR] bufnum=0.0 reset=0.0 offset=0.0 numframes=0.0
+listTrig :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+listTrig rate bufnum reset offset numframes = mkUGen Nothing [KR] (Left rate) "ListTrig" [bufnum,reset,offset,numframes] Nothing 1 (Special 0) NoId
+
+-- | Emit a sequence of triggers at specified time offsets
+--
+--  ListTrig2 [KR] bufnum=0.0 reset=0.0 numframes=0.0
+listTrig2 :: Rate -> UGen -> UGen -> UGen -> UGen
+listTrig2 rate bufnum reset numframes = mkUGen Nothing [KR] (Left rate) "ListTrig2" [bufnum,reset,numframes] Nothing 1 (Special 0) NoId
+
+-- | Store values to a buffer, whenever triggered
+--
+--  Logger [KR] inputArray=0.0 trig=0.0 bufnum=0.0 reset=0.0
+logger :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+logger rate inputArray trig_ bufnum reset = mkUGen Nothing [KR] (Left rate) "Logger" [inputArray,trig_,bufnum,reset] Nothing 1 (Special 0) NoId
+
+-- | sample looping oscillator
+--
+--  LoopBuf [AR] bufnum=0.0 rate=1.0 gate=1.0 startPos=0.0 startLoop=0.0 endLoop=0.0 interpolation=2.0;    NC INPUT: True
+loopBuf :: Int -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+loopBuf numChannels rate bufnum rate_ gate_ startPos startLoop endLoop interpolation = mkUGen Nothing [AR] (Left rate) "LoopBuf" [bufnum,rate_,gate_,startPos,startLoop,endLoop,interpolation] Nothing numChannels (Special 0) NoId
+
+-- | lorenz 2D chaotic generator
+--
+--  Lorenz2DC [KR,AR] minfreq=11025.0 maxfreq=22050.0 s=10.0 r=28.0 b=2.6666667 h=2.0e-2 x0=9.0879182417163e-2 y0=2.97077458055 z0=24.282041054363
+lorenz2DC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+lorenz2DC rate minfreq maxfreq s r b h x0 y0 z0 = mkUGen Nothing [KR,AR] (Left rate) "Lorenz2DC" [minfreq,maxfreq,s,r,b,h,x0,y0,z0] Nothing 1 (Special 0) NoId
+
+-- | lorenz 2D chaotic generator
+--
+--  Lorenz2DL [KR,AR] minfreq=11025.0 maxfreq=22050.0 s=10.0 r=28.0 b=2.6666667 h=2.0e-2 x0=9.0879182417163e-2 y0=2.97077458055 z0=24.282041054363
+lorenz2DL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+lorenz2DL rate minfreq maxfreq s r b h x0 y0 z0 = mkUGen Nothing [KR,AR] (Left rate) "Lorenz2DL" [minfreq,maxfreq,s,r,b,h,x0,y0,z0] Nothing 1 (Special 0) NoId
+
+-- | lorenz 2D chaotic generator
+--
+--  Lorenz2DN [KR,AR] minfreq=11025.0 maxfreq=22050.0 s=10.0 r=28.0 b=2.6666667 h=2.0e-2 x0=9.0879182417163e-2 y0=2.97077458055 z0=24.282041054363
+lorenz2DN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+lorenz2DN rate minfreq maxfreq s r b h x0 y0 z0 = mkUGen Nothing [KR,AR] (Left rate) "Lorenz2DN" [minfreq,maxfreq,s,r,b,h,x0,y0,z0] Nothing 1 (Special 0) NoId
+
+-- | lorenz chaotic trigger generator
+--
+--  LorenzTrig [KR,AR] minfreq=11025.0 maxfreq=22050.0 s=10.0 r=28.0 b=2.6666667 h=2.0e-2 x0=9.0879182417163e-2 y0=2.97077458055 z0=24.282041054363
+lorenzTrig :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+lorenzTrig rate minfreq maxfreq s r b h x0 y0 z0 = mkUGen Nothing [KR,AR] (Left rate) "LorenzTrig" [minfreq,maxfreq,s,r,b,h,x0,y0,z0] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  MCLDChaosGen [] maxSize=0.0
+mCLDChaosGen :: Rate -> UGen -> UGen
+mCLDChaosGen rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "MCLDChaosGen" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | First order Markov Chain implementation for audio signals
+--
+--  MarkovSynth [AR] in=0.0 isRecording=1.0 waitTime=2.0 tableSize=10.0
+markovSynth :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+markovSynth rate in_ isRecording waitTime tableSize = mkUGen Nothing [AR] (Left rate) "MarkovSynth" [in_,isRecording,waitTime,tableSize] Nothing 1 (Special 0) NoId
+
+-- | Real time sparse representation
+--
+--  MatchingP [KR,AR] dict=0.0 in=0.0 dictsize=1.0 ntofind=1.0 hop=1.0 method=0.0
+matchingP :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+matchingP rate dict in_ dictsize ntofind hop method = mkUGen Nothing [KR,AR] (Left rate) "MatchingP" [dict,in_,dictsize,ntofind,hop,method] Nothing 4 (Special 0) NoId
+
+-- | maximum within last x samples
+--
+--  Max [KR] in=0.0 numsamp=64.0
+max :: Rate -> UGen -> UGen -> UGen
+max rate in_ numsamp = mkUGen Nothing [KR] (Left rate) "Max" [in_,numsamp] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Maxamp [AR] in=0.0 numSamps=1000.0
+maxamp :: Rate -> UGen -> UGen -> UGen
+maxamp rate in_ numSamps = mkUGen Nothing [AR] (Left rate) "Maxamp" [in_,numSamps] Nothing 1 (Special 0) NoId
+
+-- | Piano synthesiser
+--
+--  MdaPiano [AR] freq=440.0 gate=1.0 vel=100.0 decay=0.8 release=0.8 hard=0.8 velhard=0.8 muffle=0.8 velmuff=0.8 velcurve=0.8 stereo=0.2 tune=0.5 random=0.1 stretch=0.1 sustain=0.0
+mdaPiano :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+mdaPiano rate freq gate_ vel decay_ release hard velhard muffle velmuff velcurve stereo tune random stretch sustain = mkUGen Nothing [AR] (Left rate) "MdaPiano" [freq,gate_,vel,decay_,release,hard,velhard,muffle,velmuff,velcurve,stereo,tune,random,stretch,sustain] Nothing 2 (Special 0) NoId
+
+-- | Mean of recent values, triggered
+--
+--  MeanTriggered [KR,AR] in=0.0 trig=0.0 length=10.0
+meanTriggered :: Rate -> UGen -> UGen -> UGen -> UGen
+meanTriggered rate in_ trig_ length_ = mkUGen Nothing [KR,AR] (Left rate) "MeanTriggered" [in_,trig_,length_] Nothing 1 (Special 0) NoId
+
+-- | Meddis cochlear hair cell model
+--
+--  Meddis [KR,AR] input=0.0
+meddis :: Rate -> UGen -> UGen
+meddis rate input = mkUGen Nothing [KR,AR] (Left rate) "Meddis" [input] Nothing 1 (Special 0) NoId
+
+-- | Separate harmonic and percussive parts of a signal
+--
+--  MedianSeparation [] fft=0.0 fftharmonic=0.0 fftpercussive=0.0 fftsize=1024.0 mediansize=17.0 hardorsoft=0.0 p=2.0 medianormax=0.0
+medianSeparation :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+medianSeparation rate fft_ fftharmonic fftpercussive fftsize mediansize hardorsoft p medianormax = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "MedianSeparation" [fft_,fftharmonic,fftpercussive,fftsize,mediansize,hardorsoft,p,medianormax] Nothing 2 (Special 0) NoId
+
+-- | Median of recent values, triggered
+--
+--  MedianTriggered [KR,AR] in=0.0 trig=0.0 length=10.0
+medianTriggered :: Rate -> UGen -> UGen -> UGen -> UGen
+medianTriggered rate in_ trig_ length_ = mkUGen Nothing [KR,AR] (Left rate) "MedianTriggered" [in_,trig_,length_] Nothing 1 (Special 0) NoId
+
+-- | Waveguide mesh physical models of drum membranes
+--
+--  MembraneCircle [AR] excitation=0.0 tension=5.0e-2 loss=0.99999
+membraneCircle :: Rate -> UGen -> UGen -> UGen -> UGen
+membraneCircle rate excitation tension loss = mkUGen Nothing [AR] (Left rate) "MembraneCircle" [excitation,tension,loss] Nothing 1 (Special 0) NoId
+
+-- | Waveguide mesh physical models of drum membranes
+--
+--  MembraneHexagon [AR] excitation=0.0 tension=5.0e-2 loss=0.99999
+membraneHexagon :: Rate -> UGen -> UGen -> UGen -> UGen
+membraneHexagon rate excitation tension loss = mkUGen Nothing [AR] (Left rate) "MembraneHexagon" [excitation,tension,loss] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Metro [KR,AR] bpm=0.0 numBeats=0.0
+metro :: Rate -> UGen -> UGen -> UGen
+metro rate bpm numBeats = mkUGen Nothing [KR,AR] (Left rate) "Metro" [bpm,numBeats] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  MonoGrain [AR] in=0.0 winsize=0.1 grainrate=10.0 winrandpct=0.0
+monoGrain :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+monoGrain rate in_ winsize grainrate winrandpct = mkUGen Nothing [AR] (Left rate) "MonoGrain" [in_,winsize,grainrate,winrandpct] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  MonoGrainBF [AR] in=0.0 winsize=0.1 grainrate=10.0 winrandpct=0.0 azimuth=0.0 azrand=0.0 elevation=0.0 elrand=0.0 rho=1.0
+monoGrainBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+monoGrainBF rate in_ winsize grainrate winrandpct azimuth azrand elevation elrand rho = mkUGen Nothing [AR] (Left rate) "MonoGrainBF" [in_,winsize,grainrate,winrandpct,azimuth,azrand,elevation,elrand,rho] Nothing 4 (Special 0) NoId
+
+-- | Moog Filter Emulation
+--
+--  MoogLadder [KR,AR] in=0.0 ffreq=440.0 res=0.0
+moogLadder :: UGen -> UGen -> UGen -> UGen
+moogLadder in_ ffreq res = mkUGen Nothing [KR,AR] (Right [0]) "MoogLadder" [in_,ffreq,res] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  MoogVCF [AR] in=0.0 fco=0.0 res=0.0
+moogVCF :: UGen -> UGen -> UGen -> UGen
+moogVCF in_ fco res = mkUGen Nothing [AR] (Right [0]) "MoogVCF" [in_,fco,res] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  MultiOutDemandUGen [DR] maxSize=0.0;    DEMAND/NONDET
+multiOutDemandUGen :: Rate -> UGen -> UGen
+multiOutDemandUGen rate maxSize = mkUGen Nothing [DR] (Left rate) "MultiOutDemandUGen" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | Stereo reverb
+--
+--  NHHall [AR] in1=0.0 in2=0.0 rt60=1.0 stereo=0.5 lowFreq=200.0 lowRatio=0.5 hiFreq=4000.0 hiRatio=0.5 earlyDiffusion=0.5 lateDiffusion=0.5 modRate=0.2 modDepth=0.3
+nhHall :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+nhHall in1 in2 rt60 stereo lowFreq lowRatio hiFreq hiRatio earlyDiffusion lateDiffusion modRate modDepth = mkUGen Nothing [AR] (Right [0,1]) "NHHall" [in1,in2,rt60,stereo,lowFreq,lowRatio,hiFreq,hiRatio,earlyDiffusion,lateDiffusion,modRate,modDepth] Nothing 2 (Special 0) NoId
+
+-- | Non Linear Filter Equation
+--
+--  NL [AR] input=0.0 bufnuma=0.0 bufnumb=1.0 guard1=1000.0 guard2=100.0
+nl :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+nl rate input bufnuma bufnumb guard1 guard2 = mkUGen Nothing [AR] (Left rate) "NL" [input,bufnuma,bufnumb,guard1,guard2] Nothing 1 (Special 0) NoId
+
+-- | Arbitrary Non Linear Filter Equation
+--
+--  NL2 [AR] input=0.0 bufnum=0.0 maxsizea=10.0 maxsizeb=10.0 guard1=1000.0 guard2=100.0
+nL2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+nL2 rate input bufnum maxsizea maxsizeb guard1 guard2 = mkUGen Nothing [AR] (Left rate) "NL2" [input,bufnum,maxsizea,maxsizeb,guard1,guard2] Nothing 1 (Special 0) NoId
+
+-- | Non-linear Filter
+--
+--  NLFiltC [KR,AR] input=0.0 a=0.0 b=0.0 d=0.0 c=0.0 l=0.0
+nLFiltC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+nLFiltC rate input a b d c l = mkUGen Nothing [KR,AR] (Left rate) "NLFiltC" [input,a,b,d,c,l] Nothing 1 (Special 0) NoId
+
+-- | Non-linear Filter
+--
+--  NLFiltL [KR,AR] input=0.0 a=0.0 b=0.0 d=0.0 c=0.0 l=0.0
+nLFiltL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+nLFiltL rate input a b d c l = mkUGen Nothing [KR,AR] (Left rate) "NLFiltL" [input,a,b,d,c,l] Nothing 1 (Special 0) NoId
+
+-- | Non-linear Filter
+--
+--  NLFiltN [KR,AR] input=0.0 a=0.0 b=0.0 d=0.0 c=0.0 l=0.0
+nLFiltN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+nLFiltN rate input a b d c l = mkUGen Nothing [KR,AR] (Left rate) "NLFiltN" [input,a,b,d,c,l] Nothing 1 (Special 0) NoId
+
+-- | physical modeling simulation; N tubes
+--
+--  NTube [AR] input=0.0 lossarray=1.0 karray=0.0 delaylengtharray=0.0
+nTube :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+nTube rate input lossarray karray delaylengtharray = mkUGen Nothing [AR] (Left rate) "NTube" [input,lossarray,karray,delaylengtharray] Nothing 1 (Special 0) NoId
+
+-- | Find the nearest-neighbours in a set of points
+--
+--  NearestN [KR] treebuf=0.0 in=0.0 gate=1.0 num=1.0
+nearestN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+nearestN rate treebuf in_ gate_ num = mkUGen Nothing [KR] (Left rate) "NearestN" [treebuf,in_,gate_,num] Nothing 3 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  NeedleRect [AR] rate=1.0 imgWidth=100.0 imgHeight=100.0 rectX=0.0 rectY=0.0 rectW=100.0 rectH=100.0
+needleRect :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+needleRect rate rate_ imgWidth imgHeight rectX rectY rectW rectH = mkUGen Nothing [AR] (Left rate) "NeedleRect" [rate_,imgWidth,imgHeight,rectX,rectY,rectW,rectH] Nothing 1 (Special 0) NoId
+
+-- | Nested Allpass filters as proposed by Vercoe and Pluckett
+--
+--  NestedAllpassC [AR] in=0.0 maxdelay1=3.6e-2 delay1=3.6e-2 gain1=8.0e-2 maxdelay2=3.0e-2 delay2=3.0e-2 gain2=0.3;    FILTER: TRUE
+nestedAllpassC :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+nestedAllpassC in_ maxdelay1 delay1_ gain1 maxdelay2 delay2_ gain2 = mkUGen Nothing [AR] (Right [0]) "NestedAllpassC" [in_,maxdelay1,delay1_,gain1,maxdelay2,delay2_,gain2] Nothing 1 (Special 0) NoId
+
+-- | Nested Allpass filters as proposed by Vercoe and Pluckett
+--
+--  NestedAllpassL [AR] in=0.0 maxdelay1=3.6e-2 delay1=3.6e-2 gain1=8.0e-2 maxdelay2=3.0e-2 delay2=3.0e-2 gain2=0.3;    FILTER: TRUE
+nestedAllpassL :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+nestedAllpassL in_ maxdelay1 delay1_ gain1 maxdelay2 delay2_ gain2 = mkUGen Nothing [AR] (Right [0]) "NestedAllpassL" [in_,maxdelay1,delay1_,gain1,maxdelay2,delay2_,gain2] Nothing 1 (Special 0) NoId
+
+-- | Nested Allpass filters as proposed by Vercoe and Pluckett
+--
+--  NestedAllpassN [AR] in=0.0 maxdelay1=3.6e-2 delay1=3.6e-2 gain1=8.0e-2 maxdelay2=3.0e-2 delay2=3.0e-2 gain2=0.3;    FILTER: TRUE
+nestedAllpassN :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+nestedAllpassN in_ maxdelay1 delay1_ gain1 maxdelay2 delay2_ gain2 = mkUGen Nothing [AR] (Right [0]) "NestedAllpassN" [in_,maxdelay1,delay1_,gain1,maxdelay2,delay2_,gain2] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  OSFold4 [AR] in=0.0 lo=0.0 hi=0.0
+oSFold4 :: Rate -> UGen -> UGen -> UGen -> UGen
+oSFold4 rate in_ lo hi = mkUGen Nothing [AR] (Left rate) "OSFold4" [in_,lo,hi] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  OSFold8 [AR] in=0.0 lo=0.0 hi=0.0
+oSFold8 :: Rate -> UGen -> UGen -> UGen -> UGen
+oSFold8 rate in_ lo hi = mkUGen Nothing [AR] (Left rate) "OSFold8" [in_,lo,hi] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  OSTrunc4 [AR] in=0.0 quant=0.5
+oSTrunc4 :: Rate -> UGen -> UGen -> UGen
+oSTrunc4 rate in_ quant = mkUGen Nothing [AR] (Left rate) "OSTrunc4" [in_,quant] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  OSTrunc8 [AR] in=0.0 quant=0.5
+oSTrunc8 :: Rate -> UGen -> UGen -> UGen
+oSTrunc8 rate in_ quant = mkUGen Nothing [AR] (Left rate) "OSTrunc8" [in_,quant] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  OSWrap4 [AR] in=0.0 lo=0.0 hi=0.0
+oSWrap4 :: Rate -> UGen -> UGen -> UGen -> UGen
+oSWrap4 rate in_ lo hi = mkUGen Nothing [AR] (Left rate) "OSWrap4" [in_,lo,hi] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  OSWrap8 [AR] in=0.0 lo=0.0 hi=0.0
+oSWrap8 :: Rate -> UGen -> UGen -> UGen -> UGen
+oSWrap8 rate in_ lo hi = mkUGen Nothing [AR] (Left rate) "OSWrap8" [in_,lo,hi] Nothing 1 (Special 0) NoId
+
+-- | Extract basic statistics from a series of onset triggers
+--
+--  OnsetStatistics [KR] input=0.0 windowsize=1.0 hopsize=0.1
+onsetStatistics :: Rate -> UGen -> UGen -> UGen -> UGen
+onsetStatistics rate input windowsize hopsize = mkUGen Nothing [KR] (Left rate) "OnsetStatistics" [input,windowsize,hopsize] Nothing 3 (Special 0) NoId
+
+-- | Chemical reaction modelling Oscillator
+--
+--  Oregonator [AR] reset=0.0 rate=1.0e-2 epsilon=1.0 mu=1.0 q=1.0 initx=0.5 inity=0.5 initz=0.5
+oregonator :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+oregonator rate reset rate_ epsilon mu q initx inity initz = mkUGen Nothing [AR] (Left rate) "Oregonator" [reset,rate_,epsilon,mu,q,initx,inity,initz] Nothing 3 (Special 0) NoId
+
+-- | Piano physical model.
+--
+--  OteyPiano [AR] freq=440.0 vel=1.0 t_gate=0.0 rmin=0.35 rmax=2.0 rampl=4.0 rampr=8.0 rcore=1.0 lmin=7.0e-2 lmax=1.4 lampl=-4.0 lampr=4.0 rho=1.0 e=1.0 zb=1.0 zh=0.0 mh=1.0 k=0.2 alpha=1.0 p=1.0 hpos=0.142 loss=1.0 detune=3.0e-4 hammer_type=1.0
+oteyPiano :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+oteyPiano rate freq vel t_gate rmin rmax rampl rampr rcore lmin lmax lampl lampr rho e zb zh mh k alpha p hpos loss detune hammer_type = mkUGen Nothing [AR] (Left rate) "OteyPiano" [freq,vel,t_gate,rmin,rmax,rampl,rampr,rcore,lmin,lmax,lampl,lampr,rho,e,zb,zh,mh,k,alpha,p,hpos,loss,detune,hammer_type] Nothing 1 (Special 0) NoId
+
+-- | Piano physical model.
+--
+--  OteyPianoStrings [AR] freq=440.0 vel=1.0 t_gate=0.0 rmin=0.35 rmax=2.0 rampl=4.0 rampr=8.0 rcore=1.0 lmin=7.0e-2 lmax=1.4 lampl=-4.0 lampr=4.0 rho=1.0 e=1.0 zb=1.0 zh=0.0 mh=1.0 k=0.2 alpha=1.0 p=1.0 hpos=0.142 loss=1.0 detune=3.0e-4 hammer_type=1.0
+oteyPianoStrings :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+oteyPianoStrings rate freq vel t_gate rmin rmax rampl rampr rcore lmin lmax lampl lampr rho e zb zh mh k alpha p hpos loss detune hammer_type = mkUGen Nothing [AR] (Left rate) "OteyPianoStrings" [freq,vel,t_gate,rmin,rmax,rampl,rampr,rcore,lmin,lmax,lampl,lampr,rho,e,zb,zh,mh,k,alpha,p,hpos,loss,detune,hammer_type] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  OteySoundBoard [AR] inp=0.0 c1=20.0 c3=20.0 mix=0.8
+oteySoundBoard :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+oteySoundBoard rate inp c1 c3 mix = mkUGen Nothing [AR] (Left rate) "OteySoundBoard" [inp,c1,c3,mix] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PVInfo [KR,AR] pvbuffer=0.0 binNum=0.0 filePointer=0.0
+pVInfo :: Rate -> UGen -> UGen -> UGen -> UGen
+pVInfo rate pvbuffer binNum filePointer = mkUGen Nothing [KR,AR] (Left rate) "PVInfo" [pvbuffer,binNum,filePointer] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PVSynth [AR] pvbuffer=0.0 numBins=0.0 binStart=0.0 binSkip=1.0 filePointer=0.0 freqMul=1.0 freqAdd=0.0
+pVSynth :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pVSynth rate pvbuffer numBins binStart binSkip filePointer freqMul freqAdd = mkUGen Nothing [AR] (Left rate) "PVSynth" [pvbuffer,numBins,binStart,binSkip,filePointer,freqMul,freqAdd] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_BinBufRd [KR] buffer=0.0 playbuf=0.0 point=1.0 binStart=0.0 binSkip=1.0 numBins=1.0 clear=0.0
+pv_BinBufRd :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_BinBufRd buffer playbuf_ point binStart binSkip numBins clear = mkUGen Nothing [KR] (Left KR) "PV_BinBufRd" [buffer,playbuf_,point,binStart,binSkip,numBins,clear] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_BinDelay [KR] buffer=0.0 maxdelay=0.0 delaybuf=0.0 fbbuf=0.0 hop=0.5
+pv_BinDelay :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_BinDelay buffer maxdelay delaybuf fbbuf hop = mkUGen Nothing [KR] (Left KR) "PV_BinDelay" [buffer,maxdelay,delaybuf,fbbuf,hop] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_BinFilter [KR] buffer=0.0 start=0.0 end=0.0
+pv_BinFilter :: UGen -> UGen -> UGen -> UGen
+pv_BinFilter buffer start end = mkUGen Nothing [KR] (Left KR) "PV_BinFilter" [buffer,start,end] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_BinPlayBuf [KR] buffer=0.0 playbuf=0.0 rate=1.0 offset=0.0 binStart=0.0 binSkip=1.0 numBins=1.0 loop=0.0 clear=0.0
+pv_BinPlayBuf :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_BinPlayBuf buffer playbuf_ rate_ offset binStart binSkip numBins loop clear = mkUGen Nothing [KR] (Left KR) "PV_BinPlayBuf" [buffer,playbuf_,rate_,offset,binStart,binSkip,numBins,loop,clear] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_BufRd [KR] buffer=0.0 playbuf=0.0 point=1.0
+pv_BufRd :: UGen -> UGen -> UGen -> UGen
+pv_BufRd buffer playbuf_ point = mkUGen Nothing [KR] (Left KR) "PV_BufRd" [buffer,playbuf_,point] Nothing 1 (Special 0) NoId
+
+-- | returns common magnitudes
+--
+--  PV_CommonMag [KR] bufferA=0.0 bufferB=0.0 tolerance=0.0 remove=0.0
+pv_CommonMag :: UGen -> UGen -> UGen -> UGen -> UGen
+pv_CommonMag bufferA bufferB tolerance remove = mkUGen Nothing [KR] (Left KR) "PV_CommonMag" [bufferA,bufferB,tolerance,remove] Nothing 1 (Special 0) NoId
+
+-- | multiplies common magnitudes
+--
+--  PV_CommonMul [KR] bufferA=0.0 bufferB=0.0 tolerance=0.0 remove=0.0
+pv_CommonMul :: UGen -> UGen -> UGen -> UGen -> UGen
+pv_CommonMul bufferA bufferB tolerance remove = mkUGen Nothing [KR] (Left KR) "PV_CommonMul" [bufferA,bufferB,tolerance,remove] Nothing 1 (Special 0) NoId
+
+-- | simple spectral compression/expansion
+--
+--  PV_Compander [KR] buffer=0.0 thresh=50.0 slopeBelow=1.0 slopeAbove=1.0
+pv_Compander :: UGen -> UGen -> UGen -> UGen -> UGen
+pv_Compander buffer thresh slopeBelow slopeAbove = mkUGen Nothing [KR] (Left KR) "PV_Compander" [buffer,thresh,slopeBelow,slopeAbove] Nothing 1 (Special 0) NoId
+
+-- | zero bins with interpolation
+--
+--  PV_Cutoff [KR] bufferA=0.0 bufferB=0.0 wipe=0.0
+pv_Cutoff :: UGen -> UGen -> UGen -> UGen
+pv_Cutoff bufferA bufferB wipe = mkUGen Nothing [KR] (Left KR) "PV_Cutoff" [bufferA,bufferB,wipe] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_EvenBin [KR] buffer=0.0
+pv_EvenBin :: UGen -> UGen
+pv_EvenBin buffer = mkUGen Nothing [KR] (Left KR) "PV_EvenBin" [buffer] Nothing 1 (Special 0) NoId
+
+-- | extract a repeating loop out from audio
+--
+--  PV_ExtractRepeat [KR] buffer=0.0 loopbuf=0.0 loopdur=0.0 memorytime=30.0 which=0.0 ffthop=0.5 thresh=1.0
+pv_ExtractRepeat :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_ExtractRepeat buffer loopbuf loopdur memorytime which ffthop thresh = mkUGen Nothing [KR] (Left KR) "PV_ExtractRepeat" [buffer,loopbuf,loopdur,memorytime,which,ffthop,thresh] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_Freeze [KR] buffer=0.0 freeze=0.0
+pv_Freeze :: UGen -> UGen -> UGen
+pv_Freeze buffer freeze = mkUGen Nothing [KR] (Left KR) "PV_Freeze" [buffer,freeze] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_FreqBuffer [KR] buffer=0.0 databuffer=0.0
+pv_FreqBuffer :: UGen -> UGen -> UGen
+pv_FreqBuffer buffer databuffer = mkUGen Nothing [KR] (Left KR) "PV_FreqBuffer" [buffer,databuffer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_Invert [KR] buffer=0.0
+pv_Invert :: UGen -> UGen
+pv_Invert buffer = mkUGen Nothing [KR] (Left KR) "PV_Invert" [buffer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_MagBuffer [KR] buffer=0.0 databuffer=0.0
+pv_MagBuffer :: UGen -> UGen -> UGen
+pv_MagBuffer buffer databuffer = mkUGen Nothing [KR] (Left KR) "PV_MagBuffer" [buffer,databuffer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_MagExp [KR] buffer=0.0
+pv_MagExp :: UGen -> UGen
+pv_MagExp buffer = mkUGen Nothing [KR] (Left KR) "PV_MagExp" [buffer] Nothing 1 (Special 0) NoId
+
+-- | reduces magnitudes above or below thresh
+--
+--  PV_MagGate [KR] buffer=0.0 thresh=1.0 remove=0.0
+pv_MagGate :: UGen -> UGen -> UGen -> UGen
+pv_MagGate buffer thresh remove = mkUGen Nothing [KR] (Left KR) "PV_MagGate" [buffer,thresh,remove] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_MagLog [KR] buffer=0.0
+pv_MagLog :: UGen -> UGen
+pv_MagLog buffer = mkUGen Nothing [KR] (Left KR) "PV_MagLog" [buffer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_MagMap [KR] buffer=0.0 mapbuf=0.0
+pv_MagMap :: UGen -> UGen -> UGen
+pv_MagMap buffer mapbuf = mkUGen Nothing [KR] (Left KR) "PV_MagMap" [buffer,mapbuf] Nothing 1 (Special 0) NoId
+
+-- | subtract spectral energy
+--
+--  PV_MagMinus [KR] bufferA=0.0 bufferB=0.0 remove=1.0
+pv_MagMinus :: UGen -> UGen -> UGen -> UGen
+pv_MagMinus bufferA bufferB remove = mkUGen Nothing [KR] (Left KR) "PV_MagMinus" [bufferA,bufferB,remove] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_MagMulAdd [KR] buffer=0.0
+pv_MagMulAdd :: UGen -> UGen
+pv_MagMulAdd buffer = mkUGen Nothing [KR] (Left KR) "PV_MagMulAdd" [buffer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_MagScale [KR] bufferA=0.0 bufferB=0.0
+pv_MagScale :: UGen -> UGen -> UGen
+pv_MagScale bufferA bufferB = mkUGen Nothing [KR] (Left KR) "PV_MagScale" [bufferA,bufferB] Nothing 1 (Special 0) NoId
+
+-- | Smooth spectral magnitudes over time
+--
+--  PV_MagSmooth [KR] buffer=0.0 factor=0.1
+pv_MagSmooth :: UGen -> UGen -> UGen
+pv_MagSmooth buffer factor = mkUGen Nothing [KR] (Left KR) "PV_MagSmooth" [buffer,factor] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_MagSubtract [KR] bufferA=0.0 bufferB=0.0 zerolimit=0.0
+pv_MagSubtract :: UGen -> UGen -> UGen -> UGen
+pv_MagSubtract bufferA bufferB zerolimit = mkUGen Nothing [KR] (Left KR) "PV_MagSubtract" [bufferA,bufferB,zerolimit] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_MaxMagN [KR] buffer=0.0 numbins=0.0
+pv_MaxMagN :: UGen -> UGen -> UGen
+pv_MaxMagN buffer numbins = mkUGen Nothing [KR] (Left KR) "PV_MaxMagN" [buffer,numbins] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_MinMagN [KR] buffer=0.0 numbins=0.0
+pv_MinMagN :: UGen -> UGen -> UGen
+pv_MinMagN buffer numbins = mkUGen Nothing [KR] (Left KR) "PV_MinMagN" [buffer,numbins] Nothing 1 (Special 0) NoId
+
+-- | one kind of spectral morphing
+--
+--  PV_Morph [KR] bufferA=0.0 bufferB=0.0 morph=0.0
+pv_Morph :: UGen -> UGen -> UGen -> UGen
+pv_Morph bufferA bufferB morph = mkUGen Nothing [KR] (Left KR) "PV_Morph" [bufferA,bufferB,morph] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_NoiseSynthF [KR] buffer=0.0 threshold=0.1 numFrames=2.0 initflag=0.0
+pv_NoiseSynthF :: UGen -> UGen -> UGen -> UGen -> UGen
+pv_NoiseSynthF buffer threshold numFrames initflag = mkUGen Nothing [KR] (Left KR) "PV_NoiseSynthF" [buffer,threshold,numFrames,initflag] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_NoiseSynthP [KR] buffer=0.0 threshold=0.1 numFrames=2.0 initflag=0.0
+pv_NoiseSynthP :: UGen -> UGen -> UGen -> UGen -> UGen
+pv_NoiseSynthP buffer threshold numFrames initflag = mkUGen Nothing [KR] (Left KR) "PV_NoiseSynthP" [buffer,threshold,numFrames,initflag] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_OddBin [KR] buffer=0.0
+pv_OddBin :: UGen -> UGen
+pv_OddBin buffer = mkUGen Nothing [KR] (Left KR) "PV_OddBin" [buffer] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_PartialSynthF [KR] buffer=0.0 threshold=0.1 numFrames=2.0 initflag=0.0
+pv_PartialSynthF :: UGen -> UGen -> UGen -> UGen -> UGen
+pv_PartialSynthF buffer threshold numFrames initflag = mkUGen Nothing [KR] (Left KR) "PV_PartialSynthF" [buffer,threshold,numFrames,initflag] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_PartialSynthP [KR] buffer=0.0 threshold=0.1 numFrames=2.0 initflag=0.0
+pv_PartialSynthP :: UGen -> UGen -> UGen -> UGen -> UGen
+pv_PartialSynthP buffer threshold numFrames initflag = mkUGen Nothing [KR] (Left KR) "PV_PartialSynthP" [buffer,threshold,numFrames,initflag] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_PitchShift [KR] buffer=0.0 ratio=0.0
+pv_PitchShift :: UGen -> UGen -> UGen
+pv_PitchShift buffer ratio = mkUGen Nothing [KR] (Left KR) "PV_PitchShift" [buffer,ratio] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_PlayBuf [KR] buffer=0.0 playbuf=0.0 rate=1.0 offset=0.0 loop=0.0
+pv_PlayBuf :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_PlayBuf buffer playbuf_ rate_ offset loop = mkUGen Nothing [KR] (Left KR) "PV_PlayBuf" [buffer,playbuf_,rate_,offset,loop] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_RecordBuf [KR] buffer=0.0 recbuf=0.0 offset=0.0 run=0.0 loop=0.0 hop=0.5 wintype=0.0
+pv_RecordBuf :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_RecordBuf buffer recbuf offset run loop hop wintype = mkUGen Nothing [KR] (Left KR) "PV_RecordBuf" [buffer,recbuf,offset,run,loop,hop,wintype] Nothing 1 (Special 0) NoId
+
+-- | combine low and high bins from two inputs with interpolation
+--
+--  PV_SoftWipe [KR] bufferA=0.0 bufferB=0.0 wipe=0.0
+pv_SoftWipe :: UGen -> UGen -> UGen -> UGen
+pv_SoftWipe bufferA bufferB wipe = mkUGen Nothing [KR] (Left KR) "PV_SoftWipe" [bufferA,bufferB,wipe] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_SpectralEnhance [KR] buffer=0.0 numPartials=8.0 ratio=2.0 strength=0.1
+pv_SpectralEnhance :: UGen -> UGen -> UGen -> UGen -> UGen
+pv_SpectralEnhance buffer numPartials ratio strength = mkUGen Nothing [KR] (Left KR) "PV_SpectralEnhance" [buffer,numPartials,ratio,strength] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_SpectralMap [KR] buffer=0.0 specBuffer=0.0 floor=0.0 freeze=0.0 mode=0.0 norm=0.0 window=0.0
+pv_SpectralMap :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_SpectralMap buffer specBuffer floor_ freeze mode norm window = mkUGen Nothing [KR] (Left KR) "PV_SpectralMap" [buffer,specBuffer,floor_,freeze,mode,norm,window] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PV_Whiten [KR] chain=0.0 trackbufnum=0.0 relaxtime=2.0 floor=0.1 smear=0.0 bindownsample=0.0
+pv_Whiten :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_Whiten chain trackbufnum relaxtime floor_ smear bindownsample = mkUGen Nothing [KR] (Left KR) "PV_Whiten" [chain,trackbufnum,relaxtime,floor_,smear,bindownsample] Nothing 1 (Special 0) NoId
+
+-- | one kind of spectral morphing
+--
+--  PV_XFade [KR] bufferA=0.0 bufferB=0.0 fade=0.0
+pv_XFade :: UGen -> UGen -> UGen -> UGen
+pv_XFade bufferA bufferB fade = mkUGen Nothing [KR] (Left KR) "PV_XFade" [bufferA,bufferB,fade] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PanX [KR,AR] numChans=0.0 in=0.0 pos=0.0 level=1.0 width=2.0
+panX :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+panX rate numChans in_ pos level width = mkUGen Nothing [KR,AR] (Left rate) "PanX" [numChans,in_,pos,level,width] Nothing 0 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PanX2D [KR,AR] numChansX=0.0 numChansY=0.0 in=0.0 posX=0.0 posY=0.0 level=1.0 widthX=2.0 widthY=2.0
+panX2D :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+panX2D rate numChansX numChansY in_ posX posY level widthX widthY = mkUGen Nothing [KR,AR] (Left rate) "PanX2D" [numChansX,numChansY,in_,posX,posY,level,widthX,widthY] Nothing 0 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PeakEQ2 [AR] in=0.0 freq=1200.0 rs=1.0 db=0.0
+peakEQ2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+peakEQ2 rate in_ freq rs db = mkUGen Nothing [AR] (Left rate) "PeakEQ2" [in_,freq,rs,db] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PeakEQ4 [AR] in=0.0 freq=1200.0 rs=1.0 db=0.0
+peakEQ4 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+peakEQ4 rate in_ freq rs db = mkUGen Nothing [AR] (Left rate) "PeakEQ4" [in_,freq,rs,db] Nothing 1 (Special 0) NoId
+
+-- | 3D Perlin Noise
+--
+--  Perlin3 [KR,AR] x=0.0 y=0.0 z=0.0
+perlin3 :: Rate -> UGen -> UGen -> UGen -> UGen
+perlin3 rate x y z = mkUGen Nothing [KR,AR] (Left rate) "Perlin3" [x,y,z] Nothing 1 (Special 0) NoId
+
+-- | Tree classifier using (hyper)planes – UGen or language-side
+--
+--  PlaneTree [KR] treebuf=0.0 in=0.0 gate=1.0
+planeTree :: Rate -> UGen -> UGen -> UGen -> UGen
+planeTree rate treebuf in_ gate_ = mkUGen Nothing [KR] (Left rate) "PlaneTree" [treebuf,in_,gate_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  PosRatio [AR] in=0.0 period=100.0 thresh=0.1
+posRatio :: Rate -> UGen -> UGen -> UGen -> UGen
+posRatio rate in_ period thresh = mkUGen Nothing [AR] (Left rate) "PosRatio" [in_,period,thresh] Nothing 1 (Special 0) NoId
+
+-- | debug assistance
+--
+--  PrintVal [KR] in=0.0 numblocks=100.0 id=0.0
+printVal :: Rate -> UGen -> UGen -> UGen -> UGen
+printVal rate in_ numblocks id_ = mkUGen Nothing [KR] (Left rate) "PrintVal" [in_,numblocks,id_] Nothing 1 (Special 0) NoId
+
+-- | constant Q transform pitch follower
+--
+--  Qitch [KR] in=0.0 databufnum=0.0 ampThreshold=1.0e-2 algoflag=1.0 ampbufnum=0.0 minfreq=0.0 maxfreq=2500.0
+qitch :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+qitch rate in_ databufnum ampThreshold algoflag ampbufnum minfreq maxfreq = mkUGen Nothing [KR] (Left rate) "Qitch" [in_,databufnum,ampThreshold,algoflag,ampbufnum,minfreq,maxfreq] Nothing 2 (Special 0) NoId
+
+-- | TB303 Filter Emulation
+--
+--  RLPFD [KR,AR] in=0.0 ffreq=440.0 res=0.0 dist=0.0
+rLPFD :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+rLPFD rate in_ ffreq res dist = mkUGen Nothing [KR,AR] (Left rate) "RLPFD" [in_,ffreq,res,dist] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  RMAFoodChainL [AR] freq=22050.0 a1=5.0 b1=3.0 d1=0.4 a2=0.1 b2=2.0 d2=1.0e-2 k=1.0943 r=0.8904 h=5.0e-2 xi=0.1 yi=0.0 zi=0.0
+rMAFoodChainL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+rMAFoodChainL rate freq a1 b1 d1 a2 b2 d2 k r h xi yi zi = mkUGen Nothing [AR] (Left rate) "RMAFoodChainL" [freq,a1,b1,d1,a2,b2,d2,k,r,h,xi,yi,zi] Nothing 3 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  RMEQ [AR] in=0.0 freq=440.0 rq=0.1 k=0.0
+rMEQ :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+rMEQ rate in_ freq rq k = mkUGen Nothing [AR] (Left rate) "RMEQ" [in_,freq,rq,k] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  RMEQSuite [] maxSize=0.0
+rMEQSuite :: Rate -> UGen -> UGen
+rMEQSuite rate maxSize = mkUGen Nothing [IR,KR,AR,DR] (Left rate) "RMEQSuite" [maxSize] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  RMShelf [AR] in=0.0 freq=440.0 k=0.0
+rMShelf :: Rate -> UGen -> UGen -> UGen -> UGen
+rMShelf rate in_ freq k = mkUGen Nothing [AR] (Left rate) "RMShelf" [in_,freq,k] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  RMShelf2 [AR] in=0.0 freq=440.0 k=0.0
+rMShelf2 :: Rate -> UGen -> UGen -> UGen -> UGen
+rMShelf2 rate in_ freq k = mkUGen Nothing [AR] (Left rate) "RMShelf2" [in_,freq,k] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  RegaliaMitraEQ [AR] in=0.0 freq=440.0 rq=0.1 k=0.0
+regaliaMitraEQ :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+regaliaMitraEQ rate in_ freq rq k = mkUGen Nothing [AR] (Left rate) "RegaliaMitraEQ" [in_,freq,rq,k] Nothing 1 (Special 0) NoId
+
+-- | Rossler chaotic generator
+--
+--  RosslerL [AR] freq=22050.0 a=0.2 b=0.2 c=5.7 h=5.0e-2 xi=0.1 yi=0.0 zi=0.0
+rosslerL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+rosslerL rate freq a b c h xi yi zi = mkUGen Nothing [AR] (Left rate) "RosslerL" [freq,a,b,c,h,xi,yi,zi] Nothing 3 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  RosslerResL [AR] in=0.0 stiff=1.0 freq=22050.0 a=0.2 b=0.2 c=5.7 h=5.0e-2 xi=0.1 yi=0.0 zi=0.0
+rosslerResL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+rosslerResL rate in_ stiff freq a b c h xi yi zi = mkUGen Nothing [AR] (Left rate) "RosslerResL" [in_,stiff,freq,a,b,c,h,xi,yi,zi] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Rotate [AR] w=0.0 x=0.0 y=0.0 z=0.0 rotate=0.0
+rotate :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+rotate rate w x y z rotate_ = mkUGen Nothing [AR] (Left rate) "Rotate" [w,x,y,z,rotate_] Nothing 1 (Special 0) NoId
+
+-- | experimental time domain onset detector
+--
+--  SLOnset [KR] input=0.0 memorysize1=20.0 before=5.0 after=5.0 threshold=10.0 hysteresis=10.0
+sLOnset :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+sLOnset rate input memorysize1 before after threshold hysteresis = mkUGen Nothing [KR] (Left rate) "SLOnset" [input,memorysize1,before,after,threshold,hysteresis] Nothing 1 (Special 0) NoId
+
+-- | Spectral Modeling Synthesis
+--
+--  SMS [AR] input=0.0 maxpeaks=80.0 currentpeaks=80.0 tolerance=4.0 noisefloor=0.2 freqmult=1.0 freqadd=0.0 formantpreserve=0.0 useifft=0.0 ampmult=1.0 graphicsbufnum=0.0;    FILTER: TRUE
+sms :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+sms input maxpeaks currentpeaks tolerance noisefloor freqmult freqadd formantpreserve useifft ampmult graphicsbufnum = mkUGen Nothing [AR] (Right [0]) "SMS" [input,maxpeaks,currentpeaks,tolerance,noisefloor,freqmult,freqadd,formantpreserve,useifft,ampmult,graphicsbufnum] Nothing 2 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SOMAreaWr [KR] bufnum=0.0 inputdata=0.0 coords=0.0 netsize=10.0 numdims=2.0 nhood=0.5 gate=1.0
+sOMAreaWr :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+sOMAreaWr rate bufnum inputdata coords netsize numdims nhood gate_ = mkUGen Nothing [KR] (Left rate) "SOMAreaWr" [bufnum,inputdata,coords,netsize,numdims,nhood,gate_] Nothing 1 (Special 0) NoId
+
+-- | Map an input using a Self-Organising Map
+--
+--  SOMRd [KR,AR] bufnum=0.0 inputdata=0.0 netsize=10.0 numdims=2.0 gate=1.0
+sOMRd :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+sOMRd rate bufnum inputdata netsize numdims gate_ = mkUGen Nothing [KR,AR] (Left rate) "SOMRd" [bufnum,inputdata,netsize,numdims,gate_] Nothing 2 (Special 0) NoId
+
+-- | Create (train) a Self-Organising Map
+--
+--  SOMTrain [KR] bufnum=0.0 inputdata=0.0 netsize=10.0 numdims=2.0 traindur=5000.0 nhood=0.5 gate=1.0 initweight=1.0
+sOMTrain :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+sOMTrain rate bufnum inputdata netsize numdims traindur nhood gate_ initweight = mkUGen Nothing [KR] (Left rate) "SOMTrain" [bufnum,inputdata,netsize,numdims,traindur,nhood,gate_,initweight] Nothing 3 (Special 0) NoId
+
+-- | 12db/Oct State Variable Filter
+--
+--  SVF [KR,AR] signal=0.0 cutoff=2200.0 res=0.1 lowpass=1.0 bandpass=0.0 highpass=0.0 notch=0.0 peak=0.0
+svf :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+svf signal cutoff res lowpass bandpass highpass notch peak_ = mkUGen Nothing [KR,AR] (Right [0]) "SVF" [signal,cutoff,res,lowpass,bandpass,highpass,notch,peak_] Nothing 1 (Special 0) NoId
+
+-- | super-efficient sawtooth oscillator with low aliasing
+--
+--  SawDPW [KR,AR] freq=440.0 iphase=0.0
+sawDPW :: Rate -> UGen -> UGen -> UGen
+sawDPW rate freq iphase = mkUGen Nothing [KR,AR] (Left rate) "SawDPW" [freq,iphase] Nothing 1 (Special 0) NoId
+
+-- | Perceptual feature modeling sensory dissonance
+--
+--  SensoryDissonance [KR] fft=0.0 maxpeaks=100.0 peakthreshold=0.1 norm=0.0 clamp=1.0
+sensoryDissonance :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+sensoryDissonance rate fft_ maxpeaks peakthreshold norm clamp = mkUGen Nothing [KR] (Left rate) "SensoryDissonance" [fft_,maxpeaks,peakthreshold,norm,clamp] Nothing 1 (Special 0) NoId
+
+-- | Fuzzy sieve based synthesis
+--
+--  Sieve1 [KR,AR] bufnum=0.0 gap=2.0 alternate=1.0
+sieve1 :: Rate -> UGen -> UGen -> UGen -> UGen
+sieve1 rate bufnum gap alternate = mkUGen Nothing [KR,AR] (Left rate) "Sieve1" [bufnum,gap,alternate] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SinGrain [AR] trigger=0.0 dur=1.0 freq=440.0
+sinGrain :: Rate -> UGen -> UGen -> UGen -> UGen
+sinGrain rate trigger dur freq = mkUGen Nothing [AR] (Left rate) "SinGrain" [trigger,dur,freq] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SinGrainB [AR] trigger=0.0 dur=1.0 freq=440.0 envbuf=0.0
+sinGrainB :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+sinGrainB rate trigger dur freq envbuf = mkUGen Nothing [AR] (Left rate) "SinGrainB" [trigger,dur,freq,envbuf] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SinGrainBBF [AR] trigger=0.0 dur=1.0 freq=440.0 envbuf=0.0 azimuth=0.0 elevation=0.0 rho=1.0 wComp=0.0
+sinGrainBBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+sinGrainBBF rate trigger dur freq envbuf azimuth elevation rho wComp = mkUGen Nothing [AR] (Left rate) "SinGrainBBF" [trigger,dur,freq,envbuf,azimuth,elevation,rho,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SinGrainBF [AR] trigger=0.0 dur=1.0 freq=440.0 azimuth=0.0 elevation=0.0 rho=1.0 wComp=0.0
+sinGrainBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+sinGrainBF rate trigger dur freq azimuth elevation rho wComp = mkUGen Nothing [AR] (Left rate) "SinGrainBF" [trigger,dur,freq,azimuth,elevation,rho,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SinGrainI [AR] trigger=0.0 dur=1.0 freq=440.0 envbuf1=0.0 envbuf2=0.0 ifac=0.5
+sinGrainI :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+sinGrainI rate trigger dur freq envbuf1 envbuf2 ifac = mkUGen Nothing [AR] (Left rate) "SinGrainI" [trigger,dur,freq,envbuf1,envbuf2,ifac] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SinGrainIBF [AR] trigger=0.0 dur=1.0 freq=440.0 envbuf1=0.0 envbuf2=0.0 ifac=0.5 azimuth=0.0 elevation=0.0 rho=1.0 wComp=0.0
+sinGrainIBF :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+sinGrainIBF rate trigger dur freq envbuf1 envbuf2 ifac azimuth elevation rho wComp = mkUGen Nothing [AR] (Left rate) "SinGrainIBF" [trigger,dur,freq,envbuf1,envbuf2,ifac,azimuth,elevation,rho,wComp] Nothing 4 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SinTone [AR] freq=440.0 phase=0.0
+sinTone :: Rate -> UGen -> UGen -> UGen
+sinTone rate freq phase = mkUGen Nothing [AR] (Left rate) "SinTone" [freq,phase] Nothing 1 (Special 0) NoId
+
+-- | port of some ladspa plugins
+--
+--  SineShaper [AR] in=0.0 limit=1.0
+sineShaper :: UGen -> UGen -> UGen
+sineShaper in_ limit = mkUGen Nothing [AR] (Right [0]) "SineShaper" [in_,limit] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SkipNeedle [AR] range=44100.0 rate=10.0 offset=0.0
+skipNeedle :: Rate -> UGen -> UGen -> UGen -> UGen
+skipNeedle rate range rate_ offset = mkUGen Nothing [AR] (Left rate) "SkipNeedle" [range,rate_,offset] Nothing 1 (Special 0) NoId
+
+-- | port of some ladspa plugins
+--
+--  SmoothDecimator [AR] in=0.0 rate=44100.0 smoothing=0.5
+smoothDecimator :: Rate -> UGen -> UGen -> UGen -> UGen
+smoothDecimator rate in_ rate_ smoothing = mkUGen Nothing [AR] (Left rate) "SmoothDecimator" [in_,rate_,smoothing] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SoftClipAmp [AR] in=0.0 pregain=1.0
+softClipAmp :: Rate -> UGen -> UGen -> UGen
+softClipAmp rate in_ pregain = mkUGen Nothing [AR] (Left rate) "SoftClipAmp" [in_,pregain] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SoftClipAmp4 [AR] in=0.0 pregain=1.0
+softClipAmp4 :: Rate -> UGen -> UGen -> UGen
+softClipAmp4 rate in_ pregain = mkUGen Nothing [AR] (Left rate) "SoftClipAmp4" [in_,pregain] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SoftClipAmp8 [AR] in=0.0 pregain=1.0
+softClipAmp8 :: Rate -> UGen -> UGen -> UGen
+softClipAmp8 rate in_ pregain = mkUGen Nothing [AR] (Left rate) "SoftClipAmp8" [in_,pregain] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SoftClipper4 [AR] in=0.0
+softClipper4 :: Rate -> UGen -> UGen
+softClipper4 rate in_ = mkUGen Nothing [AR] (Left rate) "SoftClipper4" [in_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  SoftClipper8 [AR] in=0.0
+softClipper8 :: Rate -> UGen -> UGen
+softClipper8 rate in_ = mkUGen Nothing [AR] (Left rate) "SoftClipper8" [in_] Nothing 1 (Special 0) NoId
+
+-- | Karplus-Strong via a sorting algorithm
+--
+--  SortBuf [AR] bufnum=0.0 sortrate=10.0 reset=0.0
+sortBuf :: Rate -> UGen -> UGen -> UGen -> UGen
+sortBuf rate bufnum sortrate reset = mkUGen Nothing [AR] (Left rate) "SortBuf" [bufnum,sortrate,reset] Nothing 1 (Special 0) NoId
+
+-- | Spectral feature extraction
+--
+--  SpectralEntropy [KR] fft=0.0 fftsize=2048.0 numbands=1.0
+spectralEntropy :: Rate -> UGen -> UGen -> UGen -> UGen
+spectralEntropy rate fft_ fftsize numbands = mkUGen Nothing [KR] (Left rate) "SpectralEntropy" [fft_,fftsize,numbands] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Spreader [AR] in=0.0 theta=1.5707963267949 filtsPerOctave=8.0
+spreader :: Rate -> UGen -> UGen -> UGen -> UGen
+spreader rate in_ theta filtsPerOctave = mkUGen Nothing [AR] (Left rate) "Spreader" [in_,theta,filtsPerOctave] Nothing 2 (Special 0) NoId
+
+-- | Spruce bud worm model equations
+--
+--  SpruceBudworm [AR] reset=0.0 rate=0.1 k1=27.9 k2=1.5 alpha=0.1 beta=10.1 mu=0.3 rho=10.1 initx=0.9 inity=0.1
+spruceBudworm :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+spruceBudworm rate reset rate_ k1 k2 alpha beta mu rho initx inity = mkUGen Nothing [AR] (Left rate) "SpruceBudworm" [reset,rate_,k1,k2,alpha,beta,mu,rho,initx,inity] Nothing 2 (Special 0) NoId
+
+-- | Wave squeezer. Maybe a kind of pitch shifter.
+--
+--  Squiz [KR,AR] in=0.0 pitchratio=2.0 zcperchunk=1.0 memlen=0.1;    FILTER: TRUE
+squiz :: UGen -> UGen -> UGen -> UGen -> UGen
+squiz in_ pitchratio zcperchunk memlen = mkUGen Nothing [KR,AR] (Right [0]) "Squiz" [in_,pitchratio,zcperchunk,memlen] Nothing 1 (Special 0) NoId
+
+-- | standard map 2D chaotic generator
+--
+--  Standard2DC [KR,AR] minfreq=11025.0 maxfreq=22050.0 k=1.4 x0=4.9789799812499 y0=5.7473416156381
+standard2DC :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+standard2DC rate minfreq maxfreq k x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Standard2DC" [minfreq,maxfreq,k,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | standard map 2D chaotic generator
+--
+--  Standard2DL [KR,AR] minfreq=11025.0 maxfreq=22050.0 k=1.4 x0=4.9789799812499 y0=5.7473416156381
+standard2DL :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+standard2DL rate minfreq maxfreq k x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Standard2DL" [minfreq,maxfreq,k,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | standard map 2D chaotic generator
+--
+--  Standard2DN [KR,AR] minfreq=11025.0 maxfreq=22050.0 k=1.4 x0=4.9789799812499 y0=5.7473416156381
+standard2DN :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+standard2DN rate minfreq maxfreq k x0 y0 = mkUGen Nothing [KR,AR] (Left rate) "Standard2DN" [minfreq,maxfreq,k,x0,y0] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkBandedWG [KR,AR] freq=440.0 instr=0.0 bowpressure=0.0 bowmotion=0.0 integration=0.0 modalresonance=64.0 bowvelocity=0.0 setstriking=0.0 trig=1.0
+stkBandedWG :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkBandedWG rate freq instr bowpressure bowmotion integration modalresonance bowvelocity setstriking trig_ = mkUGen Nothing [KR,AR] (Left rate) "StkBandedWG" [freq,instr,bowpressure,bowmotion,integration,modalresonance,bowvelocity,setstriking,trig_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkBeeThree [KR,AR] freq=440.0 op4gain=10.0 op3gain=20.0 lfospeed=64.0 lfodepth=0.0 adsrtarget=64.0 trig=1.0
+stkBeeThree :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkBeeThree rate freq op4gain op3gain lfospeed lfodepth adsrtarget trig_ = mkUGen Nothing [KR,AR] (Left rate) "StkBeeThree" [freq,op4gain,op3gain,lfospeed,lfodepth,adsrtarget,trig_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkBlowHole [KR,AR] freq=440.0 reedstiffness=64.0 noisegain=20.0 tonehole=64.0 register=11.0 breathpressure=64.0
+stkBlowHole :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkBlowHole rate freq reedstiffness noisegain tonehole register breathpressure = mkUGen Nothing [KR,AR] (Left rate) "StkBlowHole" [freq,reedstiffness,noisegain,tonehole,register,breathpressure] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkBowed [KR,AR] freq=220.0 bowpressure=64.0 bowposition=64.0 vibfreq=64.0 vibgain=64.0 loudness=64.0 gate=1.0 attackrate=1.0 decayrate=1.0
+stkBowed :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkBowed rate freq bowpressure bowposition vibfreq vibgain loudness_ gate_ attackrate decayrate = mkUGen Nothing [KR,AR] (Left rate) "StkBowed" [freq,bowpressure,bowposition,vibfreq,vibgain,loudness_,gate_,attackrate,decayrate] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkClarinet [KR,AR] freq=440.0 reedstiffness=64.0 noisegain=4.0 vibfreq=64.0 vibgain=11.0 breathpressure=64.0 trig=1.0
+stkClarinet :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkClarinet rate freq reedstiffness noisegain vibfreq vibgain breathpressure trig_ = mkUGen Nothing [KR,AR] (Left rate) "StkClarinet" [freq,reedstiffness,noisegain,vibfreq,vibgain,breathpressure,trig_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkFlute [KR,AR] freq=440.0 jetDelay=49.0 noisegain=0.15 jetRatio=0.32
+stkFlute :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+stkFlute rate freq jetDelay noisegain jetRatio = mkUGen Nothing [KR,AR] (Left rate) "StkFlute" [freq,jetDelay,noisegain,jetRatio] Nothing 1 (Special 0) NoId
+
+-- | Wrapping Synthesis toolkit.
+--
+--  StkGlobals [AR] showWarnings=0.0 printErrors=0.0 rawfilepath=0.0
+stkGlobals :: Rate -> UGen -> UGen -> UGen -> UGen
+stkGlobals rate showWarnings printErrors rawfilepath = mkUGen Nothing [AR] (Left rate) "StkGlobals" [showWarnings,printErrors,rawfilepath] Nothing 1 (Special 0) NoId
+
+-- | Wrapping Synthesis toolkit.
+--
+--  StkInst [AR] instNumber=6.0 freq=220.0 gate=1.0 onamp=1.0 offamp=0.5 args=0.0
+stkInst :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkInst rate instNumber freq gate_ onamp offamp args = mkUGen Nothing [AR] (Left rate) "StkInst" [instNumber,freq,gate_,onamp,offamp,args] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkMandolin [KR,AR] freq=520.0 bodysize=64.0 pickposition=64.0 stringdamping=69.0 stringdetune=10.0 aftertouch=64.0 trig=1.0
+stkMandolin :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkMandolin rate freq bodysize pickposition stringdamping stringdetune aftertouch trig_ = mkUGen Nothing [KR,AR] (Left rate) "StkMandolin" [freq,bodysize,pickposition,stringdamping,stringdetune,aftertouch,trig_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkModalBar [KR,AR] freq=440.0 instrument=0.0 stickhardness=64.0 stickposition=64.0 vibratogain=20.0 vibratofreq=20.0 directstickmix=64.0 volume=64.0 trig=1.0
+stkModalBar :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkModalBar rate freq instrument stickhardness stickposition vibratogain vibratofreq directstickmix volume trig_ = mkUGen Nothing [KR,AR] (Left rate) "StkModalBar" [freq,instrument,stickhardness,stickposition,vibratogain,vibratofreq,directstickmix,volume,trig_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkMoog [KR,AR] freq=440.0 filterQ=10.0 sweeprate=20.0 vibfreq=64.0 vibgain=0.0 gain=64.0 trig=1.0
+stkMoog :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkMoog rate freq filterQ sweeprate vibfreq vibgain gain trig_ = mkUGen Nothing [KR,AR] (Left rate) "StkMoog" [freq,filterQ,sweeprate,vibfreq,vibgain,gain,trig_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkPluck [KR,AR] freq=440.0 decay=0.99
+stkPluck :: Rate -> UGen -> UGen -> UGen
+stkPluck rate freq decay_ = mkUGen Nothing [KR,AR] (Left rate) "StkPluck" [freq,decay_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkSaxofony [KR,AR] freq=220.0 reedstiffness=64.0 reedaperture=64.0 noisegain=20.0 blowposition=26.0 vibratofrequency=20.0 vibratogain=20.0 breathpressure=128.0 trig=1.0
+stkSaxofony :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkSaxofony rate freq reedstiffness reedaperture noisegain blowposition vibratofrequency vibratogain breathpressure trig_ = mkUGen Nothing [KR,AR] (Left rate) "StkSaxofony" [freq,reedstiffness,reedaperture,noisegain,blowposition,vibratofrequency,vibratogain,breathpressure,trig_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkShakers [KR,AR] instr=0.0 energy=64.0 decay=64.0 objects=64.0 resfreq=64.0
+stkShakers :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkShakers rate instr energy decay_ objects resfreq = mkUGen Nothing [KR,AR] (Left rate) "StkShakers" [instr,energy,decay_,objects,resfreq] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  StkVoicForm [KR,AR] freq=440.0 vuvmix=64.0 vowelphon=64.0 vibfreq=64.0 vibgain=20.0 loudness=64.0 trig=1.0
+stkVoicForm :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+stkVoicForm rate freq vuvmix vowelphon vibfreq vibgain loudness_ trig_ = mkUGen Nothing [KR,AR] (Left rate) "StkVoicForm" [freq,vuvmix,vowelphon,vibfreq,vibgain,loudness_,trig_] Nothing 1 (Special 0) NoId
+
+-- | String resonance filter
+--
+--  Streson [KR,AR] input=0.0 delayTime=3.0e-3 res=0.9
+streson :: UGen -> UGen -> UGen -> UGen
+streson input delayTime res = mkUGen Nothing [KR,AR] (Right [0]) "Streson" [input,delayTime,res] Nothing 1 (Special 0) NoId
+
+-- | Pulse counter with floating point steps
+--
+--  Summer [KR,AR] trig=0.0 step=1.0 reset=0.0 resetval=0.0
+summer :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+summer rate trig_ step reset resetval = mkUGen Nothing [KR,AR] (Left rate) "Summer" [trig_,step,reset,resetval] Nothing 1 (Special 0) NoId
+
+-- | feedback delay line implementing switch-and-ramp buffer jumping
+--
+--  SwitchDelay [AR] in=0.0 drylevel=1.0 wetlevel=1.0 delaytime=1.0 delayfactor=0.7 maxdelaytime=20.0
+switchDelay :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+switchDelay in_ drylevel wetlevel delaytime delayfactor maxdelaytime = mkUGen Nothing [AR] (Right [0]) "SwitchDelay" [in_,drylevel,wetlevel,delaytime,delayfactor,maxdelaytime] Nothing 1 (Special 0) NoId
+
+-- | triggered beta random distribution
+--
+--  TBetaRand [KR,AR] lo=0.0 hi=1.0 prob1=0.0 prob2=0.0 trig=0.0;    FILTER: TRUE, NONDET
+tBetaRand :: ID a => a -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+tBetaRand z lo hi prob1 prob2 trig_ = mkUGen Nothing [KR,AR] (Right [4]) "TBetaRand" [lo,hi,prob1,prob2,trig_] Nothing 1 (Special 0) (toUId z)
+
+-- | triggered random walk generator
+--
+--  TBrownRand [KR,AR] lo=0.0 hi=1.0 dev=1.0 dist=0.0 trig=0.0;    FILTER: TRUE, NONDET
+tBrownRand :: ID a => a -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+tBrownRand z lo hi dev dist trig_ = mkUGen Nothing [KR,AR] (Right [4]) "TBrownRand" [lo,hi,dev,dist,trig_] Nothing 1 (Special 0) (toUId z)
+
+-- | triggered gaussian random distribution
+--
+--  TGaussRand [KR,AR] lo=0.0 hi=1.0 trig=0.0;    FILTER: TRUE, NONDET
+tGaussRand :: ID a => a -> UGen -> UGen -> UGen -> UGen
+tGaussRand z lo hi trig_ = mkUGen Nothing [KR,AR] (Right [2]) "TGaussRand" [lo,hi,trig_] Nothing 1 (Special 0) (toUId z)
+
+-- | buffer granulator with linear att/dec
+--
+--  TGrains2 [AR] trigger=0.0 bufnum=0.0 rate=1.0 centerPos=0.0 dur=0.1 pan=0.0 amp=0.1 att=0.5 dec=0.5 interp=4.0;    NC INPUT: True
+tGrains2 :: Int -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+tGrains2 numChannels rate trigger bufnum rate_ centerPos dur pan amp att dec interp = mkUGen Nothing [AR] (Left rate) "TGrains2" [trigger,bufnum,rate_,centerPos,dur,pan,amp,att,dec,interp] Nothing numChannels (Special 0) NoId
+
+-- | buffer granulator with user envelope
+--
+--  TGrains3 [AR] trigger=0.0 bufnum=0.0 rate=1.0 centerPos=0.0 dur=0.1 pan=0.0 amp=0.1 att=0.5 dec=0.5 window=1.0 interp=4.0;    NC INPUT: True
+tGrains3 :: Int -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+tGrains3 numChannels rate trigger bufnum rate_ centerPos dur pan amp att dec window interp = mkUGen Nothing [AR] (Left rate) "TGrains3" [trigger,bufnum,rate_,centerPos,dur,pan,amp,att,dec,window,interp] Nothing numChannels (Special 0) NoId
+
+-- | Tracking Phase Vocoder
+--
+--  TPV [AR] chain=0.0 windowsize=1024.0 hopsize=512.0 maxpeaks=80.0 currentpeaks=0.0 freqmult=1.0 tolerance=4.0 noisefloor=0.2
+tpv :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+tpv chain windowsize hopsize maxpeaks currentpeaks freqmult tolerance noisefloor = mkUGen Nothing [AR] (Left AR) "TPV" [chain,windowsize,hopsize,maxpeaks,currentpeaks,freqmult,tolerance,noisefloor] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  TTendency [KR,AR] trigger=0.0 dist=0.0 parX=0.0 parY=1.0 parA=0.0 parB=0.0
+tTendency :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+tTendency rate trigger dist parX parY parA parB = mkUGen Nothing [KR,AR] (Left rate) "TTendency" [trigger,dist,parX,parY,parA,parB] Nothing 1 (Special 0) NoId
+
+-- | pitch tracker
+--
+--  Tartini [KR] in=0.0 threshold=0.93 n=2048.0 k=0.0 overlap=1024.0 smallCutoff=0.5
+tartini :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+tartini rate in_ threshold n k overlap smallCutoff = mkUGen Nothing [KR] (Left rate) "Tartini" [in_,threshold,n,k,overlap,smallCutoff] Nothing 2 (Special 0) NoId
+
+-- | Neural Oscillator
+--
+--  TermanWang [AR] input=0.0 reset=0.0 ratex=1.0e-2 ratey=1.0e-2 alpha=1.0 beta=1.0 eta=1.0 initx=0.0 inity=0.0
+termanWang :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+termanWang rate input reset ratex ratey alpha beta eta initx inity = mkUGen Nothing [AR] (Left rate) "TermanWang" [input,reset,ratex,ratey,alpha,beta,eta,initx,inity] Nothing 1 (Special 0) NoId
+
+-- | display level of a UGen as a textual meter
+--
+--  TextVU [KR,AR] trig=2.0 in=0.0 label=0.0 width=21.0 reset=0.0 ana=0.0
+textVU :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+textVU rate trig_ in_ label_ width reset ana = mkUGen Nothing [KR,AR] (Left rate) "TextVU" [trig_,in_,label_,width,reset,ana] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Tilt [AR] w=0.0 x=0.0 y=0.0 z=0.0 tilt=0.0
+tilt :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+tilt rate w x y z tilt_ = mkUGen Nothing [AR] (Left rate) "Tilt" [w,x,y,z,tilt_] Nothing 1 (Special 0) NoId
+
+-- | triggered signal averager
+--
+--  TrigAvg [KR] in=0.0 trig=0.0
+trigAvg :: Rate -> UGen -> UGen -> UGen
+trigAvg rate in_ trig_ = mkUGen Nothing [KR] (Left rate) "TrigAvg" [in_,trig_] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  Tumble [AR] w=0.0 x=0.0 y=0.0 z=0.0 tilt=0.0
+tumble :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+tumble rate w x y z tilt_ = mkUGen Nothing [AR] (Left rate) "Tumble" [w,x,y,z,tilt_] Nothing 1 (Special 0) NoId
+
+-- | physical modeling simulation; two tubes
+--
+--  TwoTube [AR] input=0.0 k=1.0e-2 loss=1.0 d1length=100.0 d2length=100.0
+twoTube :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+twoTube rate input k loss d1length d2length = mkUGen Nothing [AR] (Left rate) "TwoTube" [input,k,loss,d1length,d2length] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  UHJ2B [AR] ls=0.0 rs=0.0
+uHJ2B :: Rate -> UGen -> UGen -> UGen
+uHJ2B rate ls rs = mkUGen Nothing [AR] (Left rate) "UHJ2B" [ls,rs] Nothing 3 (Special 0) NoId
+
+-- | Vector Base Amplitude Panner
+--
+--  VBAP [KR,AR] in=0.0 bufnum=0.0 azimuth=0.0 elevation=1.0 spread=0.0;    NC INPUT: True
+vBAP :: Int -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+vBAP numChannels rate in_ bufnum azimuth elevation spread = mkUGen Nothing [KR,AR] (Left rate) "VBAP" [in_,bufnum,azimuth,elevation,spread] Nothing numChannels (Special 0) NoId
+
+-- | 2D scanning pattern virtual machine
+--
+--  VMScan2D [AR] bufnum=0.0
+vMScan2D :: Rate -> UGen -> UGen
+vMScan2D rate bufnum = mkUGen Nothing [AR] (Left rate) "VMScan2D" [bufnum] Nothing 2 (Special 0) NoId
+
+-- | vosim pulse generator
+--
+--  VOSIM [AR] trig=0.1 freq=400.0 nCycles=1.0 decay=0.9
+vosim :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+vosim rate trig_ freq nCycles decay_ = mkUGen Nothing [AR] (Left rate) "VOSIM" [trig_,freq,nCycles,decay_] Nothing 1 (Special 0) NoId
+
+-- | windowed amplitude follower
+--
+--  WAmp [KR] in=0.0 winSize=0.1
+wAmp :: Rate -> UGen -> UGen -> UGen
+wAmp rate in_ winSize = mkUGen Nothing [KR] (Left rate) "WAmp" [in_,winSize] Nothing 1 (Special 0) NoId
+
+-- | decomposition into square waves, and reconstruction
+--
+--  WalshHadamard [AR] input=0.0 which=0.0
+walshHadamard :: Rate -> UGen -> UGen -> UGen
+walshHadamard rate input which = mkUGen Nothing [AR] (Left rate) "WalshHadamard" [input,which] Nothing 1 (Special 0) NoId
+
+-- | (Undocumented class)
+--
+--  WarpZ [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 zeroSearch=0.0 zeroStart=0.0;    NC INPUT: True
+warpZ :: Int -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+warpZ numChannels rate bufnum pointer freqScale windowSize envbufnum overlaps windowRandRatio interp zeroSearch zeroStart = mkUGen Nothing [AR] (Left rate) "WarpZ" [bufnum,pointer,freqScale,windowSize,envbufnum,overlaps,windowRandRatio,interp,zeroSearch,zeroStart] Nothing numChannels (Special 0) NoId
+
+-- | Lose bits of your waves
+--
+--  WaveLoss [KR,AR] in=0.0 drop=20.0 outof=40.0 mode=1.0
+waveLoss :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen
+waveLoss rate in_ drop_ outof mode = mkUGen Nothing [KR,AR] (Left rate) "WaveLoss" [in_,drop_,outof,mode] Nothing 1 (Special 0) NoId
+
+-- | wave terrain synthesis
+--
+--  WaveTerrain [AR] bufnum=0.0 x=0.0 y=0.0 xsize=100.0 ysize=100.0
+waveTerrain :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+waveTerrain rate bufnum x y xsize ysize = mkUGen Nothing [AR] (Left rate) "WaveTerrain" [bufnum,x,y,xsize,ysize] Nothing 1 (Special 0) NoId
+
+-- | decomposition into Daub4 wavelets, and reconstruction
+--
+--  WaveletDaub [AR] input=0.0 n=64.0 which=0.0
+waveletDaub :: Rate -> UGen -> UGen -> UGen -> UGen
+waveletDaub rate input n which = mkUGen Nothing [AR] (Left rate) "WaveletDaub" [input,n,which] Nothing 1 (Special 0) NoId
+
+-- | Weakly Nonlinear Oscillator
+--
+--  WeaklyNonlinear [AR] input=0.0 reset=0.0 ratex=1.0 ratey=1.0 freq=440.0 initx=0.0 inity=0.0 alpha=0.0 xexponent=0.0 beta=0.0 yexponent=0.0
+weaklyNonlinear :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+weaklyNonlinear rate input reset ratex ratey freq initx inity alpha xexponent beta yexponent = mkUGen Nothing [AR] (Left rate) "WeaklyNonlinear" [input,reset,ratex,ratey,freq,initx,inity,alpha,xexponent,beta,yexponent] Nothing 1 (Special 0) NoId
+
+-- | Weakly Nonlinear Oscillator
+--
+--  WeaklyNonlinear2 [AR] input=0.0 reset=0.0 ratex=1.0 ratey=1.0 freq=440.0 initx=0.0 inity=0.0 alpha=0.0 xexponent=0.0 beta=0.0 yexponent=0.0
+weaklyNonlinear2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+weaklyNonlinear2 rate input reset ratex ratey freq initx inity alpha xexponent beta yexponent = mkUGen Nothing [AR] (Left rate) "WeaklyNonlinear2" [input,reset,ratex,ratey,freq,initx,inity,alpha,xexponent,beta,yexponent] Nothing 1 (Special 0) NoId
+
+-- | Pulse counter with floating point steps
+--
+--  WrapSummer [KR,AR] trig=0.0 step=1.0 min=0.0 max=1.0 reset=0.0 resetval=0.0
+wrapSummer :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+wrapSummer rate trig_ step min_ max_ reset resetval = mkUGen Nothing [KR,AR] (Left rate) "WrapSummer" [trig_,step,min_,max_,reset,resetval] Nothing 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,8 +1,8 @@
 -- | Hand-written bindings.
 module Sound.SC3.UGen.Bindings.HW where
 
+import qualified Sound.SC3.Common.UId as I
 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 qualified Sound.SC3.UGen.UGen as U
@@ -19,12 +19,16 @@
     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) (U.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 = C.mkOsc KR "FFTTrigger" [b,h,p] 1
 
+-- | LADSPA plugins inside SuperCollider.
+ladspa :: Int -> Rate -> UGen -> [UGen] -> UGen
+ladspa nc rt k z = C.mkOsc rt "LADSPA" (constant nc : k : z) nc
+
 -- | 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 =
@@ -33,14 +37,24 @@
 
 -- | Poll value of input UGen when triggered.
 poll :: UGen -> UGen -> UGen -> UGen -> UGen
-poll t i l tr = C.mkFilter "Poll" ([t,i,tr] ++ U.unpackLabel l) 0
+poll trig_ in_ trigid label_ =
+  let q = U.unpackLabel label_
+      n = fromIntegral (length q)
+  in C.mkFilter "Poll" ([trig_,in_,trigid,n] ++ q) 0
 
+-- | FFT onset detector.
+pv_HainsworthFoote :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+pv_HainsworthFoote buf h f thr wt = C.mkOsc AR "PV_HainsworthFoote" [buf,h,f,thr,wt] 1
+
+-- | ASCII string to length prefixed list of constant UGens.
+--
+-- > string_to_ugens "/label" == map fromIntegral [6,47,108,97,98,101,108]
+string_to_ugens :: String -> [UGen]
+string_to_ugens nm = fromIntegral (length nm) : map (fromIntegral . fromEnum) nm
+
 -- | 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 C.mkFilter "SendReply" ([i,k,s] ++ n' ++ v) 0
+sendReply i k n v = C.mkFilter "SendReply" ([i,k] ++ string_to_ugens n ++ v) 0
 
 -- | Unpack a single value (magnitude or phase) from an FFT chain
 unpack1FFT :: UGen -> UGen -> UGen -> UGen -> UGen
diff --git a/Sound/SC3/UGen/Bindings/HW/External/F0.hs b/Sound/SC3/UGen/Bindings/HW/External/F0.hs
--- a/Sound/SC3/UGen/Bindings/HW/External/F0.hs
+++ b/Sound/SC3/UGen/Bindings/HW/External/F0.hs
@@ -1,12 +1,10 @@
--- | F0 UGens.
+-- | F0 UGens (f0plugins)
 module Sound.SC3.UGen.Bindings.HW.External.F0 where
 
 import Sound.SC3.UGen.Bindings.HW.Construct
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
 
--- * f0plugins
-
 -- | Emulation of the sound generation hardware of the Atari TIA chip.
 atari2600 :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 atari2600 audc0 audc1 audf0 audf1 audv0 audv1 rate = mkOsc AR "Atari2600" [audc0,audc1,audf0,audf1,audv0,audv1,rate] 1
@@ -14,6 +12,10 @@
 -- | POKEY Chip Sound Simulator
 mzPokey :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
 mzPokey f1 c1 f2 c2 f3 c3 f4 c4 ctl = mkOsc AR "MZPokey" [f1,c1,f2,c2,f3,c3,f4,c4,ctl] 1
+
+-- | A phasor that can loop.
+redPhasor :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+redPhasor rate trig rate_ start end loop loopstart loopend = mkOsc rate "RedPhasor" [trig,rate_,start,end,loop,loopstart,loopend] 1
 
 -- Local Variables:
 -- truncate-lines:t
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
@@ -1,356 +1,11 @@
 -- | Bindings to unit generators in sc3-plugins.
 module Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins 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
-
--- * AntiAliasingOscillators (Nick Collins)
-
--- | Band limited impulse generation
-blitB3 :: Rate -> UGen -> UGen
-blitB3 rate freq = mkOscR [AR] rate "BlitB3" [freq] 1
-
--- | BLIT derived sawtooth
-blitB3Saw :: Rate -> UGen -> UGen -> UGen
-blitB3Saw rate freq leak = mkOscR [AR] rate "BlitB3Saw" [freq,leak] 1
-
--- | Bipolar BLIT derived square waveform
-blitB3Square :: Rate -> UGen -> UGen -> UGen
-blitB3Square rate freq leak = mkOscR [AR] rate "BlitB3Square" [freq,leak] 1
-
--- | Bipolar BLIT derived triangle
-blitB3Tri :: Rate -> UGen -> UGen -> UGen -> UGen
-blitB3Tri rate freq leak leak2 = mkOscR [AR] rate "BlitB3Tri" [freq,leak,leak2] 1
-
--- | Triangle via 3rd order differerentiated polynomial waveform
-dPW3Tri :: Rate -> UGen -> UGen
-dPW3Tri rate freq = mkOscR [AR] rate "DPW3Tri" [freq] 1
-
--- | Sawtooth via 4th order differerentiated polynomial waveform
-dPW4Saw :: Rate -> UGen -> UGen
-dPW4Saw rate freq = mkOscR [AR] rate "DPW4Saw" [freq] 1
-
--- * AuditoryModeling
-
--- | Single gammatone filter
-gammatone :: UGen -> UGen -> UGen -> UGen
-gammatone input centrefrequency bandwidth = mkFilterR [AR] "Gammatone" [input,centrefrequency,bandwidth] 1
-
--- | Simple cochlear hair cell model
-hairCell :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-hairCell input spontaneousrate boostrate restorerate loss = mkFilterR [AR,KR] "HairCell" [input,spontaneousrate,boostrate,restorerate,loss] 1
-
--- | Meddis cochlear hair cell model
-meddis :: UGen -> UGen
-meddis input = mkFilterR [AR,KR] "Meddis" [input] 1
-
 -- * AY
 
--- | Emulation of AY (aka YM) soundchip, used in Spectrum\/Atari.
-ay :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-ay ta tb tc n c va vb vc ef es ct = mkOsc AR "AY" [ta, tb, tc, n, c, va, vb, vc, ef, es, ct] 1
-
 -- | Convert frequency value to value appropriate for AY tone inputs.
 ayFreqToTone :: Fractional a => a -> a
 ayFreqToTone f = 110300 / (f - 0.5)
-
--- * BatUGens
-
--- | An amplitude tracking based onset detector
-coyote :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-coyote rate in_ trackFall slowLag fastLag fastMul thresh minDur = mkOscR [KR] rate "Coyote" [in_,trackFall,slowLag,fastLag,fastMul,thresh,minDur] 1
-
--- | Windowed amplitude follower
-wAmp :: Rate -> UGen -> UGen -> UGen
-wAmp rate in_ winSize = mkOscR [KR] rate "WAmp" [in_,winSize] 1
-
--- * BhobUGens
-
--- | Impulses around a certain frequency
-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
-
--- | Triggered beta random distribution
-tBetaRand :: ID a => a -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-tBetaRand z lo hi prob1 prob2 trig_ = mkFilterIdR [AR,KR] (toUId z) "TBetaRand" [lo,hi,prob1,prob2,trig_] 1
-
--- | Triggered random walk generator
-tBrownRand :: ID a => a -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-tBrownRand z lo hi dev dist trig_ = mkFilterIdR [AR,KR] (toUId z) "TBrownRand" [lo,hi,dev,dist,trig_] 1
-
--- | Triggered gaussian random distribution
-tGaussRand :: ID a => a -> UGen -> UGen -> UGen -> UGen
-tGaussRand z lo hi trig_ = mkFilterIdR [AR,KR] (toUId z) "TGaussRand" [lo,hi,trig_] 1
-
--- * Concat
-
--- | Concatenative cross-synthesis.
-concat' :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-concat' ctl src sz sk sd ml fs zcr lms sc st rs = mkOsc AR "Concat" [ctl,src,sz,sk,sd,ml,fs,zcr,lms,sc,st,rs] 1
-
--- | Concatenative cross-synthesis (variant).
-concat2 :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-concat2 ctl src sz sk sd ml fs zcr lms sc st rs th = mkOsc AR "Concat2" [ctl,src,sz,sk,sd,ml,fs,zcr,lms,sc,st,rs,th] 1
-
--- * DEIND UGens
-
--- | FM-modulable resonating filter
-complexRes :: Rate -> UGen -> UGen -> UGen -> UGen
-complexRes rate in_ freq decay_ = mkOscR [AR] rate "ComplexRes" [in_,freq,decay_] 1
-
--- | Ring modulation based on the physical model of a diode.
-diodeRingMod :: Rate -> UGen -> UGen -> UGen
-diodeRingMod rate car mod_ = mkOscR [AR] rate "DiodeRingMod" [car,mod_] 1
-
--- | Demand rate implementation of a Wiard noise ring
-dNoiseRing :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-dNoiseRing rate change chance shift numBits resetval = mkOscR [] rate "DNoiseRing" [change,chance,shift,numBits,resetval] 1
-
--- | algorithmic delay
-greyholeRaw :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-greyholeRaw rate in1 in2 damping delaytime diffusion feedback moddepth modfreq size = mkOscR [AR] rate "GreyholeRaw" [in1,in2,damping,delaytime,diffusion,feedback,moddepth,modfreq,size] 1
-
--- | Raw version of the JPverb algorithmic reverberator, designed to produce long tails with chorusing
-jPverbRaw :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-jPverbRaw rate in1 in2 damp earlydiff highband highx lowband lowx mdepth mfreq midx size t60 = mkOscR [AR,KR] rate "JPverbRaw" [in1,in2,damp,earlydiff,highband,highx,lowband,lowx,mdepth,mfreq,midx,size,t60] 1
-
--- * Distortion
-
--- | Brown noise.
-disintegrator :: ID a => a -> UGen -> UGen -> UGen -> UGen
-disintegrator z i p m = mkFilterId (toUId z) "Disintegrator" [i,p,m] 1
-
--- * DWGUGens
-
--- | Plucked physical model.
-dWGPlucked2 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-dWGPlucked2 rate freq amp gate_ pos c1 c3 inp release mistune mp gc = mkOscR [AR] rate "DWGPlucked2" [freq,amp,gate_,pos,c1,c3,inp,release,mistune,mp,gc] 1
-
--- * Josh
-
--- | Resynthesize sinusoidal ATS analysis data.
-atsSynth :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-atsSynth b np ps pk fp m a = mkOsc AR "AtsSynth" [b, np, ps, pk, fp, m, a] 1
-
--- | Resynthesize sinusoidal and critical noise ATS analysis data.
-atsNoiSynth :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-atsNoiSynth b np ps pk fp sr nr m a nb bs bk = mkOsc AR "AtsNoiSynth" [b, np, ps, pk, fp, sr, nr, m, a, nb, bs, bk] 1
-
--- | Granular synthesis with FM grains.
-fmGrain :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-fmGrain trigger dur carfreq modfreq ix = mkOsc AR "FMGrain" [trigger,dur,carfreq,modfreq,ix] 1
-
--- | Granular synthesis with FM grains and user supplied envelope.
-fmGrainB :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-fmGrainB trigger dur carfreq modfreq ix e = mkOsc AR "FMGrain" [trigger,dur,carfreq,modfreq,ix,e] 1
-
--- | Resynthesize LPC analysis data.
-lpcSynth :: UGen -> UGen -> UGen -> UGen
-lpcSynth b s ptr = mkOsc AR "LPCSynth" [b, s, ptr] 1
-
--- | Extract cps, rmso and err signals from LPC data.
-lpcVals :: Rate -> UGen -> UGen -> UGen
-lpcVals r b ptr = mkOsc r "LPCVals" [b, ptr] 3
-
--- | Metronome
-metro :: Rate -> UGen -> UGen -> UGen
-metro rt bpm nb = mkOsc rt "Metro" [bpm,nb] 1
-
--- | Delay and Feedback on a bin by bin basis.
-pv_BinDelay :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-pv_BinDelay buffer maxdelay delaybuf fbbuf hop = mkOsc KR "PV_BinDelay" [buffer,maxdelay,delaybuf,fbbuf,hop] 1
-
--- | Play FFT data from a memory buffer.
-pv_BufRd :: UGen -> UGen -> UGen -> UGen
-pv_BufRd buffer playbuf_ point = mkOsc KR "PV_BufRd" [buffer,playbuf_,point] 1
-
--- | /dur/ and /hop/ are in seconds, /frameSize/ and /sampleRate/ in
--- frames, though the latter maybe fractional.
---
--- > pv_calcPVRecSize 4.2832879818594 1024 0.25 48000.0 == 823299
-pv_calcPVRecSize :: Double -> Int -> Double -> Double -> Int
-pv_calcPVRecSize dur frameSize hop sampleRate =
-    let frameSize' = fromIntegral frameSize
-        rawsize = ceiling ((dur * sampleRate) / frameSize') * frameSize
-    in ceiling (fromIntegral rawsize * recip hop + 3)
-
--- | Invert FFT amplitude data.
-pv_Invert :: UGen -> UGen
-pv_Invert b = mkOsc KR "PV_Invert" [b] 1
-
--- | Plays FFT data from a memory buffer.
-pv_PlayBuf :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-pv_PlayBuf buffer playbuf_ rate_ offset loop = mkOsc KR "PV_PlayBuf" [buffer,playbuf_,rate_,offset,loop] 1
-
--- | Records FFT data to a memory buffer.
-pv_RecordBuf :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-pv_RecordBuf buffer recbuf offset run loop hop wintype = mkOsc KR "PV_RecordBuf" [buffer,recbuf,offset,run,loop,hop,wintype] 1
-
--- | Sample looping oscillator
-loopBuf :: Int -> Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-loopBuf numChannels rate bufnum rate_ gate_ startPos startLoop endLoop interpolation = mkOscR [AR] rate "LoopBuf" [bufnum,rate_,gate_,startPos,startLoop,endLoop,interpolation] numChannels
-
--- * MCLD
-
--- | Detect the largest value (and its position) in an array of UGens
-arrayMax :: Rate -> UGen -> UGen
-arrayMax rate array = mkOscR [AR,KR] rate "ArrayMax" [array] 2
-
--- | Detect the smallest value (and its position) in an array of UGens
-arrayMin :: Rate -> UGen -> UGen
-arrayMin rate array = mkOscR [AR,KR] rate "ArrayMin" [array] 2
-
--- | Detect the largest value (and its position) in an array of UGens
-bufMax :: Rate -> UGen -> UGen -> UGen
-bufMax rate bufnum gate_ = mkOscR [KR] rate "BufMax" [bufnum,gate_] 2
-
--- | Detect the largest value (and its position) in an array of UGens
-bufMin :: Rate -> UGen -> UGen -> UGen
-bufMin rate bufnum gate_ = mkOscR [KR] rate "BufMin" [bufnum,gate_] 2
-
--- | 3D Perlin Noise
-perlin3 :: Rate -> UGen -> UGen -> UGen -> UGen
-perlin3 rate x y z = mkOscR [AR,KR] rate "Perlin3" [x,y,z] 1
-
--- | Wave squeezer. Maybe a kind of pitch shifter.
-squiz :: UGen -> UGen -> UGen -> UGen -> UGen
-squiz in_ pitchratio zcperchunk memlen = mkFilterR [AR,KR] "Squiz" [in_,pitchratio,zcperchunk,memlen] 1
-
--- * Membrane
-
--- | Triangular waveguide mesh of a drum-like membrane.
-membraneCircle :: UGen -> UGen -> UGen -> UGen
-membraneCircle i t l = mkOsc AR "MembraneCircle" [i, t, l] 1
-
--- | Triangular waveguide mesh of a drum-like membrane.
-membraneHexagon :: UGen -> UGen -> UGen -> UGen
-membraneHexagon i t l = mkOsc AR "MembraneHexagon" [i, t, l] 1
-
--- * NCAnalysisUGens
-
--- | Spectral Modeling Synthesis
-sms :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-sms input maxpeaks currentpeaks tolerance noisefloor freqmult freqadd formantpreserve useifft ampmult graphicsbufnum = mkFilterR [AR] "SMS" [input,maxpeaks,currentpeaks,tolerance,noisefloor,freqmult,freqadd,formantpreserve,useifft,ampmult,graphicsbufnum] 2
-
--- | Tracking Phase Vocoder
-tpv :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-tpv chain windowsize hopsize maxpeaks currentpeaks freqmult tolerance noisefloor = mkOsc AR "TPV" [chain,windowsize,hopsize,maxpeaks,currentpeaks,freqmult,tolerance,noisefloor] 1
-
--- * PitchDetection
-
--- | Tartini model pitch tracker.
-tartini ::  Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-tartini r input threshold n k overlap smallCutoff = mkOscR [KR] r "Tartini" [input,threshold,n,k,overlap,smallCutoff] 2
-
--- | Constant Q transform pitch follower.
-qitch ::  Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-qitch r input databufnum ampThreshold algoflag ampbufnum minfreq maxfreq = mkOscR [KR] r "Qitch" [input,databufnum,ampThreshold,algoflag,ampbufnum,minfreq,maxfreq] 2
-
--- * RFWUGens
-
--- | Calculates mean average of audio or control rate signal.
-averageOutput :: UGen -> UGen -> UGen
-averageOutput in_ trig_ = mkFilterR [KR,AR] "AverageOutput" [in_,trig_] 1
-
--- | Feedback delay line implementing switch-and-ramp buffer jumping.
-switchDelay :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-switchDelay in_ drylevel wetlevel delaytime delayfactor maxdelaytime = mkFilterR [AR] "SwitchDelay" [in_,drylevel,wetlevel,delaytime,delayfactor,maxdelaytime] 1
-
--- * SCMIRUGens
-
--- | Octave chroma band based representation of energy in a signal; Chromagram for nTET tuning systems with any base reference
-chromagram :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-chromagram rate fft_ fftsize n tuningbase octaves integrationflag coeff = mkOscR [KR] rate "Chromagram" [fft_,fftsize,n,tuningbase,octaves,integrationflag,coeff] 1
-
--- * skUG
-
--- | Phase modulation oscillator matrix.
-fm7 :: [[UGen]] -> [[UGen]] -> UGen
-fm7 ctl m0d = mkOsc AR "FM7" (concat ctl ++ concat m0d) 6
-
--- * SLU
-
--- | Prigogine oscillator
-brusselator :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-brusselator rate reset rate_ mu gamma initx inity = mkOscR [AR] rate "Brusselator" [reset,rate_,mu,gamma,initx,inity] 2
-
--- | Forced DoubleWell Oscillator
-doubleWell3 :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-doubleWell3 rate reset rate_ f delta initx inity = mkOscR [AR] rate "DoubleWell3" [reset,rate_,f,delta,initx,inity] 1
-
--- | Envelope Follower Filter
-envDetect :: Rate -> UGen -> UGen -> UGen -> UGen
-envDetect rate in_ attack release = mkOscR [AR] rate "EnvDetect" [in_,attack,release] 1
-
--- | Envelope Follower
-envFollow :: Rate -> UGen -> UGen -> UGen
-envFollow rate input decaycoeff = mkOscR [AR,KR] rate "EnvFollow" [input,decaycoeff] 1
-
--- | Linear Time Invariant General Filter Equation
-lti :: Rate -> UGen -> UGen -> UGen -> UGen
-lti rate input bufnuma bufnumb = mkOscR [AR] rate "LTI" [input,bufnuma,bufnumb] 1
-
--- | Experimental time domain onset detector
-sLOnset :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-sLOnset rate input memorysize1 before after threshold hysteresis = mkOscR [KR] rate "SLOnset" [input,memorysize1,before,after,threshold,hysteresis] 1
-
--- | wave terrain synthesis
-waveTerrain :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-waveTerrain rate bufnum x y xsize ysize = mkOscR [AR] rate "WaveTerrain" [bufnum,x,y,xsize,ysize] 1
-
--- * Stk
-
--- | STK bowed string model.
-stkBowed :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-stkBowed rt f pr po vf vg l g at dc = mkOsc rt "StkBowed" [f, pr, po, vf, vg, l, g, at, dc] 1
-
--- | STK flute model.
-stkFlute :: Rate-> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-stkFlute rt f jd ng vf vg bp tr = mkOsc rt "StkFlute" [f, jd, ng, vf, vg, bp, tr] 1
-
--- | STK mandolin model.
-stkMandolin :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-stkMandolin rt f bs pp dm dt at tr = mkOsc rt "StkMandolin" [f, bs, pp, dm, dt, at, tr] 1
-
--- | STK modal bar models.
-stkModalBar :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-stkModalBar rt f i sh sp vg vf mx v tr = mkOsc rt "StkModalBar" [f, i, sh, sp, vg, vf, mx, v, tr] 1
-
--- | STK shaker models.
-stkShakers :: Rate -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-stkShakers rt i e d o rf tr = mkOsc rt "StkShakers" [i, e, d, o, rf, tr] 1
-
--- * TJUGens
-
--- | Digitally modelled analog filter
-dfm1 :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-dfm1 i f r g ty nl = mkFilter "DFM1" [i,f,r,g,ty,nl] 1
-
--- * VOSIM
-
--- | Vocal simulation due to W. Kaegi.
-vosim :: UGen -> UGen -> UGen -> UGen -> UGen
-vosim t f nc d = mkOsc AR "VOSIM" [t, f, nc, d] 1
-
 
 -- Local Variables:
 -- truncate-lines:t
diff --git a/Sound/SC3/UGen/Bindings/HW/External/Zita.hs b/Sound/SC3/UGen/Bindings/HW/External/Zita.hs
--- a/Sound/SC3/UGen/Bindings/HW/External/Zita.hs
+++ b/Sound/SC3/UGen/Bindings/HW/External/Zita.hs
@@ -1,58 +1,32 @@
 -- | Zita UGen definitions.
 --
--- To build the SC3 plugin run @faust2supercollider -d@ on
--- @zita_rev1.dsp@, which is in the @examples@ directory of Faust, see
--- <http://faust.grame.fr/>.
+-- See hsc3/ext/faust to build the SC3 plugin.
 module Sound.SC3.UGen.Bindings.HW.External.Zita where
 
 import Sound.SC3.UGen.Bindings.HW.Construct
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
 
-data ZitaRev1 a =
-    ZitaRev1 {zr1_in1 :: a
-             ,zr1_in2 :: a
-             ,zr1_delay :: a
-             ,zr1_xover :: a
-             ,zr1_rtlow :: a
-             ,zr1_rtmid :: a
-             ,zr1_fdamp :: a
-             ,zr1_eq1fr :: a
-             ,zr1_eq1gn :: a
-             ,zr1_eq2fr :: a
-             ,zr1_eq2gn :: a
-             ,zr1_opmix :: a -- ^ (-1,+1)
-             ,zr1_level :: a}
-
-zitaRev1_r :: ZitaRev1 UGen -> UGen
-zitaRev1_r r =
-    let (ZitaRev1 in1 in2 dly xov rtl rtm fda e1f e1g e2f e2g opm lvl) = r
-    in zitaRev1 in1 in2 dly xov rtl rtm fda e1f e1g e2f e2g opm lvl
-
-zitaRev1 :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
-zitaRev1 in1 in2 dly xov rtl rtm fda e1f e1g e2f e2g opm lvl = mkFilterR [AR] "FaustZitaRev1" [in1,in2,dly,xov,rtl,rtm,fda,e1f,e1g,e2f,e2g,opm,lvl] 2
-
-{-
-hsc3-db:
-
-std_I :: Int -> String -> Double -> I
-std_I ix nm df = I (ix,ix) nm df Nothing
-
-zitaRev1_dsc :: U
-zitaRev1_dsc =
-    let i = [std_I 0 "in1" 0.0
-            ,std_I 1 "in2" 0.0
-            ,std_I 2 "delay" 0.04
-            ,std_I 3 "xover" 200.0
-            ,std_I 4 "rtlow" 3.0
-            ,std_I 5 "rtmid" 2.0
-            ,std_I 6 "fdamp" 6.0e3
-            ,std_I 7 "eq1fr" 160
-            ,std_I 8 "eq1gn" 0.0
-            ,std_I 9 "eq2fr" 2.5e3
-            ,std_I 10 "eq2gn" 0.0
-            ,std_I 11 "opmix" 0.5
-            ,std_I 12 "level" (-20)]
-    in U "FaustZitaRev1" [AR] AR Nothing i Nothing (Left 2) "Zita Reverb 1"
--}
+-- | Parameter (name,value) pairs.
+--
+-- > unwords $ map fst zitaRev_param
+zitaRev_param :: [(String, Double)]
+zitaRev_param =
+  [("in1",0.0)
+  ,("in2",0.0)
+  ,("in_delay",60.0)
+  ,("lf_x",200) -- log, 50, 1000
+  ,("low_rt60",3) -- log, 1, 8
+  ,("mid_rt60",2) -- log, 1, 8
+  ,("hf_damping",6000) -- log, 1500, 24000
+  ,("eq1_freq",315) -- log, 40, 2500
+  ,("eq1_level",0) -- lin, -15, 15
+  ,("eq2_freq",1500) -- log, 160, 10000
+  ,("eq2_level",0) -- lin, -15, 15
+  ,("dry_wet_mix",0) -- lin, 0, 1
+  ,("level",-20) -- lin, -9, 9
+  ]
 
+-- | ZitaRev binding.
+zitaRev :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen
+zitaRev in1 in2 in_delay lf_x low_rt60 mid_rt60 hf_damping eq1_freq eq1_level eq2_freq eq2_level dry_wet_mix level = mkFilterR [AR] "FaustZitaRev" [in1,in2,in_delay,lf_x,low_rt60,mid_rt60,hf_damping,eq1_freq,eq1_level,eq2_freq,eq2_level,dry_wet_mix,level] 2
diff --git a/Sound/SC3/UGen/Bindings/Monad.hs b/Sound/SC3/UGen/Bindings/Monad.hs
--- a/Sound/SC3/UGen/Bindings/Monad.hs
+++ b/Sound/SC3/UGen/Bindings/Monad.hs
@@ -1,13 +1,19 @@
 -- | Monad constructors for 'UGen's.
 module Sound.SC3.UGen.Bindings.Monad where
 
+import Control.Monad {- base -}
+
+import Sound.SC3.Common.UId
 import Sound.SC3.UGen.Bindings.DB
 import Sound.SC3.UGen.Bindings.HW
 import Sound.SC3.UGen.Enum
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
-import Sound.SC3.UGen.UId
 
+-- | Clone a unit generator (mce . replicateM).
+clone :: (UId m) => Int -> m UGen -> m UGen
+clone n = liftM mce . replicateM n
+
 -- * Demand
 
 -- | Buffer demand ugen.
@@ -96,11 +102,11 @@
 
 -- | Brown noise.
 brownNoiseM :: (UId m) => Rate -> m UGen
-brownNoiseM = liftUId brownNoise
+brownNoiseM = liftUId1 brownNoise
 
 -- | Clip noise.
 clipNoiseM :: (UId m) => Rate -> m UGen
-clipNoiseM = liftUId clipNoise
+clipNoiseM = liftUId1 clipNoise
 
 -- | Randomly pass or block triggers.
 coinGateM :: (UId m) => UGen -> UGen -> m UGen
@@ -120,7 +126,7 @@
 
 -- | Gray noise.
 grayNoiseM :: (UId m) => Rate -> m UGen
-grayNoiseM = liftUId grayNoise
+grayNoiseM = liftUId1 grayNoise
 
 -- | Random integer in uniform distribution.
 iRandM :: (UId m) => UGen -> UGen -> m UGen
@@ -168,7 +174,7 @@
 
 -- | Pink noise.
 pinkNoiseM :: (UId m) => Rate -> m UGen
-pinkNoiseM = liftUId pinkNoise
+pinkNoiseM = liftUId1 pinkNoise
 
 -- | Random value in uniform distribution.
 randM :: (UId m) => UGen -> UGen -> m UGen
@@ -179,8 +185,8 @@
 tExpRandM = liftUId3 tExpRand
 
 -- | Random integer in uniform distribution on trigger.
-tIRandM :: (UId m) => UGen -> UGen -> UGen -> m UGen
-tIRandM = liftUId3 tIRand
+tiRandM :: (UId m) => UGen -> UGen -> UGen -> m UGen
+tiRandM = liftUId3 tiRand
 
 -- | Random value in uniform distribution on trigger.
 tRandM :: (UId m) => UGen -> UGen -> UGen -> m UGen
@@ -192,4 +198,4 @@
 
 -- | White noise.
 whiteNoiseM :: (UId m) => Rate -> m UGen
-whiteNoiseM = liftUId whiteNoise
+whiteNoiseM = liftUId1 whiteNoise
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
@@ -19,18 +19,22 @@
 envTrapezoid :: OrdE t => t -> t -> t -> t -> Envelope t
 envTrapezoid = envTrapezoid_f ((<=*),(>=*))
 
+-- | 'env_circle_z' of 'latch' of 'impulse'.
+env_circle_u :: UGen -> Envelope_Curve UGen -> Envelope UGen -> Envelope UGen
+env_circle_u = env_circle_z (latch 1 (impulse KR 0 0))
+
 -- | 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
+        e = Envelope [startVal,1,0] [1,1] [curve] (Just 1) Nothing 0
     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' =
+envGate_def :: UGen
+envGate_def =
     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")
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
@@ -1,376 +1,265 @@
--- | 'Graph' and related types.
+{- | 'U_Graph' and related types.
+
+The UGen type is recursive, inputs to UGens are UGens.
+
+This makes writing UGen graphs simple, but manipulating them awkward.
+
+UGen equality is structural, and can be slow to determine for some UGen graph structures.
+
+A U_Node is a non-recursive notation for a UGen, all U_Nodes have unique identifiers.
+
+A U_Graph is constructed by a stateful traversal of a UGen.
+
+A U_Graph is represented as a partioned (by type) set of U_Nodes, edges are implicit.
+
+-}
 module Sound.SC3.UGen.Graph where
 
-import qualified Data.IntMap as M {- containers -}
 import Data.Function {- base -}
-import Data.List{- base -}
-import Data.Maybe{- base -}
+import Data.List {- base -}
+import Data.Maybe {- base -}
 
-import qualified Sound.SC3.UGen.Analysis as A
+import qualified Sound.SC3.UGen.Analysis as Analysis
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
 import Sound.SC3.UGen.UGen
 
--- * Type
-
--- | Node identifier.
-type NodeId = Int
+-- * Types
 
 -- | Port index.
-type PortIndex = Int
-
--- | Type to represent unit generator graph.
-data Graph = Graph {nextId :: NodeId
-                   ,constants :: [Node]
-                   ,controls :: [Node]
-                   ,ugens :: [Node]}
-            deriving (Show)
-
--- | Enumeration of the four operating rates for controls.
-data KType = K_IR | K_KR | K_TR | K_AR
-             deriving (Eq,Show,Ord)
+type Port_Index = Int
 
--- | Type to represent the left hand side of an edge in a unit
---   generator graph.
-data FromPort = FromPort_C {port_nid :: NodeId}
-              | FromPort_K {port_nid :: NodeId,port_kt :: KType}
-              | FromPort_U {port_nid :: NodeId,port_idx :: Maybe PortIndex}
-                deriving (Eq,Show)
+-- | Type to represent the left hand side of an edge in a unit generator graph.
+data From_Port = From_Port_C {from_port_nid :: UID_t}
+               | From_Port_K {from_port_nid :: UID_t,from_port_kt :: K_Type}
+               | From_Port_U {from_port_nid :: UID_t,from_port_idx :: Maybe Port_Index}
+               deriving (Eq,Show)
 
 -- | A destination port.
-data ToPort = ToPort NodeId PortIndex deriving (Eq,Show)
-
--- | A connection from 'FromPort' to 'ToPort'.
-type Edge = (FromPort,ToPort)
-
--- | Type to represent nodes in unit generator graph.
-data Node = NodeC {node_id :: NodeId
-                  ,node_c_value :: Sample}
-          | NodeK {node_id :: NodeId
-                  ,node_k_rate :: Rate
-                  ,node_k_index :: Maybe Int
-                  ,node_k_name :: String
-                  ,node_k_default :: Sample
-                  ,node_k_type :: KType
-                  ,node_k_meta :: Maybe (C_Meta Sample)}
-          | NodeU {node_id :: NodeId
-                  ,node_u_rate :: Rate
-                  ,node_u_name :: String
-                  ,node_u_inputs :: [FromPort]
-                  ,node_u_outputs :: [Output]
-                  ,node_u_special :: Special
-                  ,node_u_ugenid :: UGenId}
-          | NodeP {node_id :: NodeId
-                  ,node_p_node :: Node
-                  ,node_p_index :: PortIndex}
-            deriving (Show)
-
-node_k_eq :: Node -> Node -> Bool
-node_k_eq p q =
-    case (p,q) of
-      (NodeK k rt ix nm df tr me,NodeK k' rt' ix' nm' df' tr' me') ->
-          k == k' && rt == rt' && ix == ix' && nm == nm' && df == df' && tr == tr' && me == me'
-      _ -> error "node_k_eq? not Node_K"
+data To_Port = To_Port {to_port_nid :: UID_t,to_port_idx :: Port_Index}
+             deriving (Eq,Show)
 
--- | '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'
+-- | A connection from 'From_Port' to 'To_Port'.
+type U_Edge = (From_Port,To_Port)
 
--- * Building
+-- | Sum-type to represent nodes in unit generator graph.
+--   _C = constant, _K = control, _U = ugen, _P = proxy.
+data U_Node = U_Node_C {u_node_id :: UID_t
+                       ,u_node_c_value :: Sample}
+            | U_Node_K {u_node_id :: UID_t
+                       ,u_node_k_rate :: Rate
+                       ,u_node_k_index :: Maybe Int
+                       ,u_node_k_name :: String
+                       ,u_node_k_default :: Sample
+                       ,u_node_k_type :: K_Type
+                       ,u_node_k_meta :: Maybe (C_Meta Sample)}
+            | U_Node_U {u_node_id :: UID_t
+                       ,u_node_u_rate :: Rate
+                       ,u_node_u_name :: String
+                       ,u_node_u_inputs :: [From_Port]
+                       ,u_node_u_outputs :: [Output]
+                       ,u_node_u_special :: Special
+                       ,u_node_u_ugenid :: UGenId}
+            | U_Node_P {u_node_id :: UID_t
+                       ,u_node_p_node :: U_Node
+                       ,u_node_p_index :: Port_Index}
+            deriving (Eq,Show)
 
--- | Find 'Node' with indicated 'NodeId'.
-find_node :: Graph -> NodeId -> Maybe Node
-find_node (Graph _ cs ks us) n =
-    let f x = node_id x == n
-    in find f (cs ++ ks ++ us)
+-- | Type to represent a unit generator graph.
+data U_Graph = U_Graph {ug_next_id :: UID_t
+                       ,ug_constants :: [U_Node]
+                       ,ug_controls :: [U_Node]
+                       ,ug_ugens :: [U_Node]}
+             deriving (Show)
 
--- | Generate a label for 'Node' using the /type/ and the 'node_id'.
-node_label :: Node -> String
-node_label nd =
-    case nd of
-      NodeC n _ -> "c_" ++ show n
-      NodeK n _ _ _ _ _ _ -> "k_" ++ show n
-      NodeU n _ _ _ _ _ _ -> "u_" ++ show n
-      NodeP n _ _ -> "p_" ++ show n
+-- * Ports
 
--- | Get 'port_idx' for 'FromPort_U', else @0@.
-port_idx_or_zero :: FromPort -> PortIndex
+-- | Get 'port_idx' for 'From_Port_U', else @0@.
+port_idx_or_zero :: From_Port -> Port_Index
 port_idx_or_zero p =
     case p of
-      FromPort_U _ (Just x) -> x
+      From_Port_U _ (Just x) -> x
       _ -> 0
 
--- | Is 'Node' a /constant/.
-is_node_c :: Node -> Bool
-is_node_c n =
-    case n of
-      NodeC _ _ -> True
+-- | Is 'From_Port' 'From_Port_U'.
+is_from_port_u :: From_Port -> Bool
+is_from_port_u p =
+    case p of
+      From_Port_U _ _ -> True
       _ -> False
 
--- | Is 'Node' a /control/.
-is_node_k :: Node -> Bool
-is_node_k n =
-    case n of
-      NodeK {} -> True
-      _ -> False
+-- * Nodes
 
--- | Is 'Node' a /UGen/.
-is_node_u :: Node -> Bool
-is_node_u n =
+-- | Is 'U_Node' a /constant/.
+is_u_node_c :: U_Node -> Bool
+is_u_node_c n =
     case n of
-      NodeU {} -> True
+      U_Node_C _ _ -> True
       _ -> False
 
--- | Calculate all edges given a set of 'NodeU'.
-edges :: [Node] -> [Edge]
-edges =
-    let f n = case n of
-                NodeU x _ _ i _ _ _ -> zip i (map (ToPort x) [0..])
-                _ -> error "edges: non NodeU input node"
-    in concatMap f
-
--- | Transform 'Node' to 'FromPort'.
-as_from_port :: Node -> FromPort
-as_from_port d =
-    case d of
-      NodeC n _ -> FromPort_C n
-      NodeK n _ _ _ _ t _ -> FromPort_K n t
-      NodeU n _ _ _ o _ _ ->
-          case o of
-            [_] -> FromPort_U n Nothing
-            _ -> error (show ("as_from_port: non unary NodeU",d))
-      NodeP _ u p -> FromPort_U (node_id u) (Just p)
-
--- | Locate 'Node' of 'FromPort' in 'Graph'.
-from_port_node :: Graph -> FromPort -> Maybe Node
-from_port_node g fp = find_node g (port_nid fp)
-
--- | The empty 'Graph'.
-empty_graph :: Graph
-empty_graph = Graph 0 [] [] []
-
--- | Find the maximum 'NodeId' used at 'Graph' (this ought normally be
--- the 'nextId').
-graph_maximum_id :: Graph -> NodeId
-graph_maximum_id (Graph _ c k u) = maximum (map node_id (c ++ k ++ u))
-
--- | Compare 'NodeK' values 'on' 'node_k_type'.
-node_k_cmp :: Node -> Node -> Ordering
-node_k_cmp = compare `on` node_k_type
-
--- | Determine class of control given 'Rate' and /trigger/ status.
-ktype :: Rate -> Bool -> KType
-ktype r tr =
-    if tr
-    then case r of
-           KR -> K_TR
-           _ -> error "ktype: non KR trigger control"
-    else case r of
-           IR -> K_IR
-           KR -> K_KR
-           AR -> K_AR
-           DR -> error "ktype: DR control"
-
--- | Predicate to determine if 'Node' is a constant with indicated /value/.
-find_c_p :: Sample -> Node -> Bool
-find_c_p x n =
+-- | Predicate to determine if 'U_Node' is a constant with indicated /value/.
+is_u_node_c_of :: Sample -> U_Node -> Bool
+is_u_node_c_of x n =
     case n of
-      NodeC _ y -> x == y
-      _ -> error "find_c_p: non NodeC"
-
--- | Insert a constant 'Node' into the 'Graph'.
-push_c :: Sample -> Graph -> (Node,Graph)
-push_c x g =
-    let n = NodeC (nextId g) x
-    in (n,g {constants = n : constants g
-            ,nextId = nextId g + 1})
+      U_Node_C _ y -> x == y
+      _ -> error "is_u_node_c_of: non U_Node_C"
 
--- | Either find existing 'Constant' 'Node', or insert a new 'Node'.
-mk_node_c :: Constant -> Graph -> (Node,Graph)
-mk_node_c (Constant x) g =
-    let y = find (find_c_p x) (constants g)
-    in maybe (push_c x g) (\y' -> (y',g)) y
+-- | Is 'U_Node' a /control/.
+is_u_node_k :: U_Node -> Bool
+is_u_node_k n =
+    case n of
+      U_Node_K {} -> True
+      _ -> False
 
--- | Predicate to determine if 'Node' is a control with indicated
+-- | Predicate to determine if 'U_Node' is a control with indicated
 -- /name/.  Names must be unique.
-find_k_p :: String -> Node -> Bool
-find_k_p x n =
+is_u_node_k_of :: String -> U_Node -> Bool
+is_u_node_k_of x n =
     case n of
-      NodeK _ _ _ y _ _ _ -> x == y
-      _ -> error "find_k_p"
-
--- | Insert a control node into the 'Graph'.
-push_k :: Control -> Graph -> (Node,Graph)
-push_k (Control r ix nm d tr meta) g =
-    let n = NodeK (nextId g) r ix nm d (ktype r tr) meta
-    in (n,g {controls = n : controls g
-            ,nextId = nextId g + 1})
-
--- | Either find existing 'Control' 'Node', or insert a new 'Node'.
-mk_node_k :: Control -> Graph -> (Node,Graph)
-mk_node_k c g =
-    let nm = controlName c
-        y = find (find_k_p nm) (controls g)
-    in maybe (push_k c g) (\y' -> (y',g)) y
+      U_Node_K _ _ _ y _ _ _ -> x == y
+      _ -> error "is_u_node_k_of"
 
-type UGenParts = (Rate,String,[FromPort],[Output],Special,UGenId)
+-- | Is 'U_Node' a /UGen/.
+is_u_node_u :: U_Node -> Bool
+is_u_node_u n =
+    case n of
+      U_Node_U {} -> True
+      _ -> False
 
--- | Predicate to locate primitive, names must be unique.
-find_u_p :: UGenParts -> Node -> Bool
-find_u_p (r,n,i,o,s,d) nd =
-    case nd of
-      NodeU _ r' n' i' o' s' d' ->
-          r == r' && n == n' && i == i' && o == o' && s == s' && d == d'
-      _ ->  error "find_u_p"
+-- | Compare 'U_Node_K' values 'on' 'u_node_k_type'.
+u_node_k_cmp :: U_Node -> U_Node -> Ordering
+u_node_k_cmp = compare `on` u_node_k_type
 
--- | Insert a /primitive/ 'NodeU' into the 'Graph'.
-push_u :: UGenParts -> Graph -> (Node,Graph)
-push_u (r,nm,i,o,s,d) g =
-    let n = NodeU (nextId g) r nm i o s d
-    in (n,g {ugens = n : ugens g
-            ,nextId = nextId g + 1})
+-- | Sort by 'u_node_id'.
+u_node_sort :: [U_Node] -> [U_Node]
+u_node_sort = sortBy (compare `on` u_node_id)
 
-mk_node_u_acc :: [UGen] -> [Node] -> Graph -> ([Node],Graph)
-mk_node_u_acc u n g =
-    case u of
-      [] -> (reverse n,g)
-      x:xs -> let (y,g') = mk_node x g
-              in mk_node_u_acc xs (y:n) g'
+-- | Equality test, error if not U_Node_K.
+u_node_k_eq :: U_Node -> U_Node -> Bool
+u_node_k_eq p q =
+  if is_u_node_k p && is_u_node_k q
+  then p == q
+  else error "u_node_k_eq? not U_Node_K"
 
--- | Either find existing 'Primitive' node, or insert a new 'Node'.
-mk_node_u :: Primitive -> Graph -> (Node,Graph)
-mk_node_u (Primitive r nm i o s d) g =
-    let (i',g') = mk_node_u_acc i [] g
-        i'' = map as_from_port i'
-        u = (r,nm,i'',o,s,d)
-        y = find (find_u_p u) (ugens g')
-    in maybe (push_u u g') (\y' -> (y',g')) y
+-- | 'Rate' of 'U_Node', ie. 'IR' for constants & see through 'U_Node_P'.
+u_node_rate :: U_Node -> Rate
+u_node_rate n =
+    case n of
+      U_Node_C {} -> IR
+      U_Node_K {} -> u_node_k_rate n
+      U_Node_U {} -> u_node_u_rate n
+      U_Node_P _ n' _ -> u_node_rate n'
 
--- | Proxies do not get stored in the graph.
-mk_node_p :: Node -> PortIndex -> Graph -> (Node,Graph)
-mk_node_p n p g =
-    let z = nextId g
-    in (NodeP z n p,g {nextId = z + 1})
+-- | Generate a label for 'U_Node' using the /type/ and the 'u_node_id'.
+u_node_label :: U_Node -> String
+u_node_label nd =
+    case nd of
+      U_Node_C n _ -> "c_" ++ show n
+      U_Node_K n _ _ _ _ _ _ -> "k_" ++ show n
+      U_Node_U n _ _ _ _ _ _ -> "u_" ++ show n
+      U_Node_P n _ _ -> "p_" ++ show n
 
--- | Transform 'UGen' into 'Graph', appending to existing 'Graph'.
-mk_node :: UGen -> Graph -> (Node,Graph)
-mk_node u g =
-    case u of
-      Constant_U c -> mk_node_c c g
-      Control_U k -> mk_node_k k g
-      Label_U _ -> error (show ("mk_node: label",u))
-      Primitive_U p -> mk_node_u p g
-      Proxy_U p ->
-          let (n,g') = mk_node_u (proxySource p) g
-          in mk_node_p n (proxyIndex p) g'
-      MRG_U m ->
-          -- allow RHS of MRG node to be MCE (splice all nodes into graph)
-          let f g' l = case l of
-                         [] -> g'
-                         n:l' -> let (_,g'') = mk_node n g' in f g'' l'
-          in mk_node (mrgLeft m) (f g (mceChannels (mrgRight m)))
-      MCE_U _ -> error (show ("mk_node: mce",u))
+-- | Calculate all in edges for a 'U_Node_U'.
+u_node_in_edges :: U_Node -> [U_Edge]
+u_node_in_edges n =
+    case n of
+      U_Node_U x _ _ i _ _ _ -> zip i (map (To_Port x) [0..])
+      _ -> error "u_node_in_edges: non U_Node_U input node"
 
--- | Transform /mce/ nodes to /mrg/ nodes
-prepare_root :: UGen -> UGen
-prepare_root u =
-    case u of
-      MCE_U m -> mrg (mceProxies m)
-      MRG_U m -> mrg2 (prepare_root (mrgLeft m)) (prepare_root (mrgRight m))
-      _ -> u
+-- | Transform 'U_Node' to 'From_Port'.
+u_node_from_port :: U_Node -> From_Port
+u_node_from_port d =
+    case d of
+      U_Node_C n _ -> From_Port_C n
+      U_Node_K n _ _ _ _ t _ -> From_Port_K n t
+      U_Node_U n _ _ _ o _ _ ->
+          case o of
+            [_] -> From_Port_U n Nothing
+            _ -> error (show ("u_node_from_port: non unary U_Node_U",d))
+      U_Node_P _ u p -> From_Port_U (u_node_id u) (Just p)
 
 -- | If controls have been given indices they must be coherent.
-sort_controls :: [Node] -> [Node]
-sort_controls c =
-    let node_k_ix n = fromMaybe maxBound (node_k_index n)
-        cmp = compare `on` node_k_ix
+u_node_sort_controls :: [U_Node] -> [U_Node]
+u_node_sort_controls c =
+    let u_node_k_ix n = fromMaybe maxBound (u_node_k_index n)
+        cmp = compare `on` u_node_k_ix
         c' = sortBy cmp c
-        coheres z = maybe True (== z) . node_k_index
+        coheres z = maybe True (== z) . u_node_k_index
         coherent = all id (zipWith coheres [0..] c')
-    in if coherent then c' else error (show ("sort_controls: incoherent",c))
-
--- | Variant on 'mk_node' starting with an empty graph, reverses the
--- 'UGen' list and sorts the 'Control' list, and adds implicit nodes.
-mk_graph :: UGen -> Graph
-mk_graph u =
-    let (_,g) = mk_node (prepare_root u) empty_graph
-        g' = g {ugens = reverse (ugens g)
-               ,controls = sort_controls (controls g)}
-    in add_implicit g'
-
--- * Encoding
-
-type Map = M.IntMap Int
-
-type Maps = (Map,[Node],Map,Map,[(KType,Int)])
+    in if coherent then c' else error (show ("u_node_sort_controls: incoherent",c))
 
--- | Determine 'KType' of a /control/ UGen at 'NodeU', or not.
-node_ktype :: Node -> Maybe KType
-node_ktype n =
-    case (node_u_name n,node_u_rate n) of
+-- | Determine 'K_Type' of a /control/ UGen at 'U_Node_U', or not.
+u_node_ktype :: U_Node -> Maybe K_Type
+u_node_ktype n =
+    case (u_node_u_name n,u_node_u_rate n) of
       ("Control",IR) -> Just K_IR
       ("Control",KR) -> Just K_KR
       ("TrigControl",KR) -> Just K_TR
       ("AudioControl",AR) -> Just K_AR
       _ -> Nothing
 
--- | Map associating 'KType' with UGen index.
-mk_ktype_map :: [Node] -> [(KType,Int)]
-mk_ktype_map =
-    let f (i,n) = let g ty = (ty,i) in fmap g (node_ktype n)
-    in mapMaybe f . zip [0..]
-
--- | Lookup 'KType' index from map (erroring variant of 'lookup').
-ktype_map_lookup :: KType -> [(KType,Int)] -> Int
-ktype_map_lookup k =
-    let e = error (show ("ktype_map_lookup",k))
-    in fromMaybe e . lookup k
+-- | Is 'U_Node' an /implicit/ control UGen?
+u_node_is_implicit_control :: U_Node -> Bool
+u_node_is_implicit_control n =
+    let cs = ["AudioControl","Control","TrigControl"]
+    in case n of
+        U_Node_U x _ s _ _ _ _ -> x == -1 && s `elem` cs
+        _ -> False
 
--- | Generate 'Maps' translating node identifiers to synthdef indexes.
-mk_maps :: Graph -> Maps
-mk_maps (Graph _ cs ks us) =
-    (M.fromList (zip (map node_id cs) [0..])
-    ,ks
-    ,M.fromList (zip (map node_id ks) [0..])
-    ,M.fromList (zip (map node_id us) [0..])
-    ,mk_ktype_map us)
+-- | Is U_Node implicit?
+u_node_is_implicit :: U_Node -> Bool
+u_node_is_implicit n = u_node_u_name n == "MaxLocalBufs" || u_node_is_implicit_control n
 
--- | Locate index in map given node identifer 'NodeId'.
-fetch :: NodeId -> Map -> Int
-fetch = M.findWithDefault (error "fetch")
+-- | Zero if no local buffers, or if maxLocalBufs is given.
+u_node_localbuf_count :: [U_Node] -> Int
+u_node_localbuf_count us =
+    case find ((==) "MaxLocalBufs" . u_node_u_name) us of
+      Nothing -> length (filter ((==) "LocalBuf" . u_node_u_name) us)
+      Just _ -> 0
 
 -- | Controls are a special case.  We need to know not the overall
 -- index but the index in relation to controls of the same type.
-fetch_k :: NodeId -> KType -> [Node] -> Int
-fetch_k z t =
+u_node_fetch_k :: UID_t -> K_Type -> [U_Node] -> Int
+u_node_fetch_k z t =
     let recur i ns =
             case ns of
-              [] -> error "fetch_k"
-              n:ns' -> if z == node_id n
+              [] -> error "u_node_fetch_k"
+              n:ns' -> if z == u_node_id n
                        then i
-                       else if t == node_k_type n
+                       else if t == u_node_k_type n
                             then recur (i + 1) ns'
                             else recur i ns'
     in recur 0
 
--- * Implicit (Control, MaxLocalBuf)
+-- | All the elements of a U_Node_U, except the u_node_id.
+type U_Node_NOID = (Rate,String,[From_Port],[Output],Special,UGenId)
 
--- | 4-tuple to count 'KType's.
-type KS_COUNT = (Int,Int,Int,Int)
+-- | Predicate to locate primitive, names must be unique.
+u_node_eq_noid :: U_Node_NOID -> U_Node -> Bool
+u_node_eq_noid x nd =
+    case nd of
+      U_Node_U _ r n i o s d -> (r,n,i,o,s,d) == x
+      _ ->  error "u_node_eq_noid"
 
--- | Count the number of /controls/ of each 'KType'.
-ks_count :: [Node] -> KS_COUNT
-ks_count =
+-- | Make map associating 'K_Type' with UGen index.
+u_node_mk_ktype_map :: [U_Node] -> [(K_Type,Int)]
+u_node_mk_ktype_map =
+    let f (i,n) = let g ty = (ty,i) in fmap g (u_node_ktype n)
+    in mapMaybe f . zip [0..]
+
+-- * Nodes (Implicit)
+
+-- | 4-tuple to count 'K_Type's, ie. (IR,KR,TR,AR).
+type U_NODE_KS_COUNT = (Int,Int,Int,Int)
+
+-- | Count the number of /controls/ of each 'K_Type'.
+u_node_ks_count :: [U_Node] -> U_NODE_KS_COUNT
+u_node_ks_count =
     let recur r ns =
             let (i,k,t,a) = r
             in case ns of
                  [] -> r
-                 n:ns' -> let r' = case node_k_type n of
+                 n:ns' -> let r' = case u_node_k_type n of
                                      K_IR -> (i+1,k,t,a)
                                      K_KR -> (i,k+1,t,a)
                                      K_TR -> (i,k,t+1,a)
@@ -378,12 +267,12 @@
                           in recur r' ns'
     in recur (0,0,0,0)
 
--- | Construct implicit /control/ unit generator 'Nodes'.  Unit
+-- | Construct implicit /control/ unit generator 'U_Nodes'.  Unit
 -- generators are only constructed for instances of control types that
 -- are present.
-mk_implicit_ctl :: [Node] -> [Node]
-mk_implicit_ctl ks =
-    let (ni,nk,nt,na) = ks_count ks
+u_node_mk_implicit_ctl :: [U_Node] -> [U_Node]
+u_node_mk_implicit_ctl ks =
+    let (ni,nk,nt,na) = u_node_ks_count ks
         mk_n t n o =
             let (nm,r) = case t of
                             K_IR -> ("Control",IR)
@@ -393,111 +282,254 @@
                 i = replicate n r
             in if n == 0
                then Nothing
-               else Just (NodeU (-1) r nm [] i (Special o) no_id)
+               else Just (U_Node_U (-1) r nm [] i (Special o) no_id)
     in catMaybes [mk_n K_IR ni 0
                  ,mk_n K_KR nk ni
                  ,mk_n K_TR nt (ni + nk)
                  ,mk_n K_AR na (ni + nk + nt)]
 
--- | Add implicit /control/ UGens to 'Graph'.
-add_implicit_ctl :: Graph -> Graph
-add_implicit_ctl g =
-    let (Graph z cs ks us) = g
-        ks' = sortBy node_k_cmp ks
-        im = if null ks' then [] else mk_implicit_ctl ks'
-        us' = im ++ us
-    in Graph z cs ks' us'
+-- * Edges
 
--- | Zero if no local buffers, or if maxLocalBufs is given.
-localbuf_count :: [Node] -> Int
-localbuf_count us =
-    case find ((==) "MaxLocalBufs" . node_u_name) us of
-      Nothing -> length (filter ((==) "LocalBuf" . node_u_name) us)
-      Just _ -> 0
+-- | List of 'From_Port_U' at /e/ with multiple out edges.
+u_edge_multiple_out_edges :: [U_Edge] -> [From_Port]
+u_edge_multiple_out_edges e =
+    let p = filter is_from_port_u (map fst e)
+        p' = group (sortBy (compare `on` from_port_nid) p)
+    in map head (filter ((> 1) . length) p')
 
+-- * Graph
+
+-- | Calculate all edges of a 'U_Graph'.
+ug_edges :: U_Graph -> [U_Edge]
+ug_edges = concatMap u_node_in_edges . ug_ugens
+
+-- | The empty 'U_Graph'.
+ug_empty_graph :: U_Graph
+ug_empty_graph = U_Graph 0 [] [] []
+
+-- | Find the maximum 'UID_t' used at 'U_Graph'.  It is an error if this is not 'ug_next_id'.
+ug_maximum_id :: U_Graph -> UID_t
+ug_maximum_id (U_Graph z c k u) =
+  let z' = maximum (map u_node_id (c ++ k ++ u))
+  in if z' /= z
+     then error (show ("ug_maximum_id: not ug_next_id?",z,z'))
+     else z
+
+-- | Find 'U_Node' with indicated 'UID_t'.
+ug_find_node :: U_Graph -> UID_t -> Maybe U_Node
+ug_find_node (U_Graph _ cs ks us) n =
+    let f x = u_node_id x == n
+    in find f (cs ++ ks ++ us)
+
+-- | Locate 'U_Node' of 'From_Port' in 'U_Graph'.
+ug_from_port_node :: U_Graph -> From_Port -> Maybe U_Node
+ug_from_port_node g fp = ug_find_node g (from_port_nid fp)
+
+-- | Erroring variant.
+ug_from_port_node_err :: U_Graph -> From_Port -> U_Node
+ug_from_port_node_err g fp =
+    let e = error "ug_from_port_node_err"
+    in fromMaybe e (ug_from_port_node g fp)
+
+-- * Graph (Building)
+
+-- | Insert a constant 'U_Node' into the 'U_Graph'.
+ug_push_c :: Sample -> U_Graph -> (U_Node,U_Graph)
+ug_push_c x g =
+    let n = U_Node_C (ug_next_id g) x
+    in (n,g {ug_constants = n : ug_constants g
+            ,ug_next_id = ug_next_id g + 1})
+
+-- | Either find existing 'Constant' 'U_Node', or insert a new 'U_Node'.
+ug_mk_node_c :: Constant -> U_Graph -> (U_Node,U_Graph)
+ug_mk_node_c (Constant x) g =
+    let y = find (is_u_node_c_of x) (ug_constants g)
+    in maybe (ug_push_c x g) (\y' -> (y',g)) y
+
+-- | Insert a control node into the 'U_Graph'.
+ug_push_k :: Control -> U_Graph -> (U_Node,U_Graph)
+ug_push_k (Control r ix nm d tr meta) g =
+    let n = U_Node_K (ug_next_id g) r ix nm d (ktype r tr) meta
+    in (n,g {ug_controls = n : ug_controls g
+            ,ug_next_id = ug_next_id g + 1})
+
+-- | Either find existing 'Control' 'U_Node', or insert a new 'U_Node'.
+ug_mk_node_k :: Control -> U_Graph -> (U_Node,U_Graph)
+ug_mk_node_k c g =
+    let nm = controlName c
+        y = find (is_u_node_k_of nm) (ug_controls g)
+    in maybe (ug_push_k c g) (\y' -> (y',g)) y
+
+-- | Insert a /primitive/ 'U_Node_U' into the 'U_Graph'.
+ug_push_u :: U_Node_NOID -> U_Graph -> (U_Node,U_Graph)
+ug_push_u (r,nm,i,o,s,d) g =
+    let n = U_Node_U (ug_next_id g) r nm i o s d
+    in (n,g {ug_ugens = n : ug_ugens g
+            ,ug_next_id = ug_next_id g + 1})
+
+-- | Recursively traverse set of UGen calling 'ug_mk_node'.
+ug_mk_node_rec :: [UGen] -> [U_Node] -> U_Graph -> ([U_Node],U_Graph)
+ug_mk_node_rec u n g =
+    case u of
+      [] -> (reverse n,g)
+      x:xs -> let (y,g') = ug_mk_node x g
+              in ug_mk_node_rec xs (y:n) g'
+
+-- | Run 'ug_mk_node_rec' at inputs and either find existing primitive
+-- node or insert a new one.
+ug_mk_node_u :: Primitive -> U_Graph -> (U_Node,U_Graph)
+ug_mk_node_u (Primitive r nm i o s d) g =
+    let (i',g') = ug_mk_node_rec i [] g
+        i'' = map u_node_from_port i'
+        u = (r,nm,i'',o,s,d)
+        y = find (u_node_eq_noid u) (ug_ugens g')
+    in maybe (ug_push_u u g') (\y' -> (y',g')) y
+
+-- | Proxies do not get stored in the graph.
+ug_mk_node_p :: U_Node -> Port_Index -> U_Graph -> (U_Node,U_Graph)
+ug_mk_node_p n p g =
+    let z = ug_next_id g
+    in (U_Node_P z n p,g {ug_next_id = z + 1})
+
+-- | Transform 'UGen' into 'U_Graph', appending to existing 'U_Graph'.
+--   Allow RHS of MRG node to be MCE (splice all nodes into graph).
+ug_mk_node :: UGen -> U_Graph -> (U_Node,U_Graph)
+ug_mk_node u g =
+    case u of
+      Constant_U c -> ug_mk_node_c c g
+      Control_U k -> ug_mk_node_k k g
+      Label_U _ -> error (show ("ug_mk_node: label",u))
+      Primitive_U p -> ug_mk_node_u p g
+      Proxy_U p ->
+          let (n,g') = ug_mk_node_u (proxySource p) g
+          in ug_mk_node_p n (proxyIndex p) g'
+      MRG_U m ->
+          let f g' l = case l of
+                         [] -> g'
+                         n:l' -> let (_,g'') = ug_mk_node n g' in f g'' l'
+          in ug_mk_node (mrgLeft m) (f g (mceChannels (mrgRight m)))
+      MCE_U _ -> error (show ("ug_mk_node: mce",u))
+
+-- | Add implicit /control/ UGens to 'U_Graph'.
+ug_add_implicit_ctl :: U_Graph -> U_Graph
+ug_add_implicit_ctl g =
+    let (U_Graph z cs ks us) = g
+        ks' = sortBy u_node_k_cmp ks
+        im = if null ks' then [] else u_node_mk_implicit_ctl ks'
+        us' = im ++ us
+    in U_Graph z cs ks' us'
+
 -- | Add implicit 'maxLocalBufs' if not present.
-add_implicit_buf :: Graph -> Graph
-add_implicit_buf g =
-    case localbuf_count (ugens g) of
+ug_add_implicit_buf :: U_Graph -> U_Graph
+ug_add_implicit_buf g =
+    case u_node_localbuf_count (ug_ugens g) of
       0 -> g
-      n -> let (c,g') = mk_node_c (Constant (fromIntegral n)) g
-               p = as_from_port c
-               u = NodeU (-1) IR "MaxLocalBufs" [p] [] (Special 0) no_id
-           in g' {ugens = u : ugens g'}
+      n -> let (c,g') = ug_mk_node_c (Constant (fromIntegral n)) g
+               p = u_node_from_port c
+               u = U_Node_U (-1) IR "MaxLocalBufs" [p] [] (Special 0) no_id
+           in g' {ug_ugens = u : ug_ugens g'}
 
--- | 'add_implicit_buf' and 'add_implicit_ctl'.
-add_implicit :: Graph -> Graph
-add_implicit = add_implicit_buf . add_implicit_ctl
+-- | 'ug_add_implicit_buf' and 'ug_add_implicit_ctl'.
+ug_add_implicit :: U_Graph -> U_Graph
+ug_add_implicit = ug_add_implicit_buf . ug_add_implicit_ctl
 
--- | Is 'Node' an /implicit/ control UGen?
-is_implicit_control :: Node -> Bool
-is_implicit_control n =
-    let cs = ["AudioControl","Control","TrigControl"]
-    in case n of
-        NodeU x _ s _ _ _ _ -> x == -1 && s `elem` cs
-        _ -> False
+-- | Remove implicit UGens from 'U_Graph'
+ug_remove_implicit :: U_Graph -> U_Graph
+ug_remove_implicit g =
+    let u = filter (not . u_node_is_implicit) (ug_ugens g)
+    in g {ug_ugens = u}
 
--- | Is Node implicit?
-is_implicit :: Node -> Bool
-is_implicit n = node_u_name n == "MaxLocalBufs" || is_implicit_control n
+-- * Graph (Queries)
 
--- | Remove implicit UGens from 'Graph'
-remove_implicit :: Graph -> Graph
-remove_implicit g =
-    let u = filter (not . is_implicit) (ugens g)
-    in g {ugens = u}
+-- | Descendents at 'U_Graph' of 'U_Node'.
+u_node_descendents :: U_Graph -> U_Node -> [U_Node]
+u_node_descendents g n =
+    let e = ug_edges g
+        c = filter ((== u_node_id n) . from_port_nid . fst) e
+        f (To_Port k _) = k
+    in mapMaybe (ug_find_node g . f . snd) c
 
--- * Queries
+-- * PV edge accounting
 
--- | Is 'FromPort' 'FromPort_U'.
-is_from_port_u :: FromPort -> Bool
-is_from_port_u p =
-    case p of
-      FromPort_U _ _ -> True
-      _ -> False
+-- | List @PV@ 'U_Node's at 'U_Graph' with multiple out edges.
+ug_pv_multiple_out_edges :: U_Graph -> [U_Node]
+ug_pv_multiple_out_edges g =
+    let e = ug_edges g
+        p = u_edge_multiple_out_edges e
+        n = mapMaybe (ug_find_node g . from_port_nid) p
+    in filter (Analysis.primitive_is_pv_rate . u_node_u_name) n
 
--- | List of 'FromPort_U' at /e/ with multiple out edges.
-multiple_u_out_edges :: [Edge] -> [FromPort]
-multiple_u_out_edges e =
-    let p = filter is_from_port_u (map fst e)
-        p' = group (sortBy (compare `on` port_nid) p)
-    in map head (filter ((> 1) . length) p')
+-- | Error string if graph has an invalid @PV@ subgraph, ie. multiple out edges
+-- at @PV@ node not connecting to @Unpack1FFT@ & @PackFFT@, else Nothing.
+ug_pv_check :: U_Graph -> Maybe String
+ug_pv_check g =
+    case ug_pv_multiple_out_edges g of
+      [] -> Nothing
+      n ->
+        let d = concatMap (map u_node_u_name . u_node_descendents g) n
+        in if any Analysis.primitive_is_pv_rate d || any (`elem` ["IFFT"]) d
+           then Just (show ("PV: multiple out edges, see pv_split",map u_node_u_name n,d))
+           else Nothing
 
--- | Descendents at 'Graph' of 'Node'.
-node_descendents :: Graph -> Node -> [Node]
-node_descendents g n =
-    let e = edges (ugens g)
-        c = filter ((== node_id n) . port_nid . fst) e
-        f (ToPort k _) = k
-    in mapMaybe (find_node g . f . snd) c
+-- | Variant that runs 'error' as required.
+ug_pv_validate :: U_Graph -> U_Graph
+ug_pv_validate g =
+    case ug_pv_check g of
+      Nothing -> g
+      Just err -> error err
 
--- * PV edge accounting
+-- * UGen to U_Graph
 
--- | List @PV@ 'Node's at 'Graph' with multiple out edges.
-pv_multiple_out_edges :: Graph -> [Node]
-pv_multiple_out_edges g =
-    let e = edges (ugens g)
-        p = multiple_u_out_edges e
-        n = mapMaybe (find_node g . port_nid) p
-    in filter (A.primitive_is_pv_rate . node_u_name) n
+{- | Transform a unit generator into a graph.
+     'ug_mk_node' begins with an empty graph,
+     then reverses the resulting 'UGen' list and sorts the 'Control' list,
+     and finally adds implicit nodes and validates PV sub-graphs.
 
--- | Error if graph has invalid @PV@ subgraph, ie. multiple out edges
--- at @PV@ node not connecting to @Unpack1FFT@ & @PackFFT@.
-pv_validate :: Graph -> Graph
-pv_validate g =
-    case pv_multiple_out_edges g of
-      [] -> g
-      n -> let d = concatMap (map node_u_name . node_descendents g) n
-           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
-                          ,d))
-              else g
+> import Sound.SC3 {- hsc3 -}
+> ugen_to_graph (out 0 (pan2 (sinOsc AR 440 0) 0.5 0.1))
 
--- | Transform a unit generator into a graph.
---
--- > import Sound.SC3.UGen
--- > 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
+-}
+ugen_to_graph :: UGen -> U_Graph
+ugen_to_graph u =
+    let (_,g) = ug_mk_node (prepare_root u) ug_empty_graph
+        g' = g {ug_ugens = reverse (ug_ugens g)
+               ,ug_controls = u_node_sort_controls (ug_controls g)}
+    in ug_pv_validate (ug_add_implicit g')
+
+-- * Stat
+
+-- | Simple statistical analysis of a unit generator graph.
+ug_stat_ln :: U_Graph -> [String]
+ug_stat_ln s =
+    let cs = ug_constants s
+        ks = ug_controls s
+        us = ug_ugens s
+        u_nm z = ugen_user_name (u_node_u_name z) (u_node_u_special z)
+        hist pp_f =
+          let h (x:xs) = (x,length (x:xs))
+              h [] = error "graph_stat_ln"
+          in unwords . map (\(p,q) -> pp_f p ++ "×" ++ show q) . map h . group . sort
+    in ["number of constants       : " ++ show (length cs)
+       ,"number of controls        : " ++ show (length ks)
+       ,"control rates             : " ++ hist show (map u_node_k_rate ks)
+       ,"control names             : " ++ unwords (map u_node_k_name ks)
+       ,"number of unit generators : " ++ show (length us)
+       ,"unit generator rates      : " ++ hist show (map u_node_u_rate us)
+       ,"unit generator set        : " ++ hist id (map u_nm us)
+       ,"unit generator sequence   : " ++ unwords (map u_nm us)]
+
+-- | 'unlines' of 'ug_stat_ln'.
+ug_stat :: U_Graph -> String
+ug_stat = unlines . ug_stat_ln
+
+-- * Indices
+
+-- | Find indices of all instances of the named UGen at 'Graph'.
+-- The index is required when using 'Sound.SC3.Server.Command.u_cmd'.
+ug_ugen_indices :: (Num n,Enum n) => String -> U_Graph -> [n]
+ug_ugen_indices nm =
+    let f (k,nd) =
+            case nd of
+              U_Node_U _ _ nm' _ _ _ _ -> if nm == nm' then Just k else Nothing
+              _ -> Nothing
+    in mapMaybe f . zip [0..] . ug_ugens
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
@@ -2,26 +2,22 @@
 module Sound.SC3.UGen.Graph.Reconstruct where
 
 import Data.Char {- base -}
-import Data.Function {- base -}
 import Data.List {- base -}
 import Text.Printf {- base -}
 
-import Sound.SC3.UGen.Graph
-import Sound.SC3.UGen.Operator
+import qualified Sound.SC3.UGen.Graph as Graph
+import qualified Sound.SC3.UGen.Operator as Operator
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
 import Sound.SC3.UGen.UGen
 
-node_sort :: [Node] -> [Node]
-node_sort = sortBy (compare `on` node_id)
-
-from_port_label :: Char -> FromPort -> String
+from_port_label :: Char -> Graph.From_Port -> String
 from_port_label jn fp =
     case fp of
-      FromPort_C n -> printf "c_%d" n
-      FromPort_K n _ -> printf "k_%d" n
-      FromPort_U n Nothing -> printf "u_%d" n
-      FromPort_U n (Just i) -> printf "u_%d%co_%d" n jn i
+      Graph.From_Port_C n -> printf "c_%d" n
+      Graph.From_Port_K n _ -> printf "k_%d" n
+      Graph.From_Port_U n Nothing -> printf "u_%d" n
+      Graph.From_Port_U n (Just i) -> printf "u_%d%co_%d" n jn i
 
 is_operator_name :: String -> Bool
 is_operator_name nm =
@@ -35,15 +31,15 @@
     then printf "(%s)" nm
     else nm
 
-reconstruct_graph :: Graph -> ([String],String)
+reconstruct_graph :: Graph.U_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)
+    let (Graph.U_Graph _ c k u) = g
+        ls = concat [map reconstruct_c_str (Graph.u_node_sort c)
+                    ,map reconstruct_k_str (Graph.u_node_sort k)
                     ,concatMap reconstruct_u_str u]
     in (filter (not . null) ls,reconstruct_mrg_str u)
 
-reconstruct_graph_module :: String -> Graph -> [String]
+reconstruct_graph_module :: String -> Graph.U_Graph -> [String]
 reconstruct_graph_module nm gr =
   let imp = ["import Sound.SC3"
             ,"import Sound.SC3.Common"
@@ -55,42 +51,44 @@
 
 {- | Generate a reconstruction of a 'Graph'.
 
-> import Sound.SC3
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Graph {- hsc3 -}
+> import Sound.SC3.UGen.Graph.Reconstruct {- hsc3 -}
 
-> 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))
+> let k = control KR "bus" 0
+> let o = sinOsc AR 440 0 + whiteNoise 'α' AR
+> let u = out k (pan2 (o * 0.1) 0 1)
+> let m = mrg [u,out 1 (impulse AR 1 0 * 0.1)]
+> putStrLn (reconstruct_graph_str "anon" (ugen_to_graph m))
 
 -}
-reconstruct_graph_str :: String -> Graph -> String
+reconstruct_graph_str :: String -> Graph.U_Graph -> String
 reconstruct_graph_str nm = unlines . reconstruct_graph_module nm
 
-reconstruct_c_str :: Node -> String
+reconstruct_c_str :: Graph.U_Node -> String
 reconstruct_c_str u =
-    let l = node_label u
-        c = node_c_value u
+    let l = Graph.u_node_label u
+        c = Graph.u_node_c_value u
     in printf "%s = constant (%f::Sample)" l c
 
-reconstruct_c_ugen :: Node -> UGen
-reconstruct_c_ugen u = constant (node_c_value u)
+reconstruct_c_ugen :: Graph.U_Node -> UGen
+reconstruct_c_ugen u = constant (Graph.u_node_c_value u)
 
 -- | Discards index.
-reconstruct_k_rnd :: Node -> (Rate,String,Sample)
+reconstruct_k_rnd :: Graph.U_Node -> (Rate,String,Sample)
 reconstruct_k_rnd u =
-    let r = node_k_rate u
-        n = node_k_name u
-        d = node_k_default u
+    let r = Graph.u_node_k_rate u
+        n = Graph.u_node_k_name u
+        d = Graph.u_node_k_default u
     in (r,n,d)
 
-reconstruct_k_str :: Node -> String
+reconstruct_k_str :: Graph.U_Node -> String
 reconstruct_k_str u =
-    let l = node_label u
+    let l = Graph.u_node_label u
         (r,n,d) = reconstruct_k_rnd u
     in printf "%s = control %s \"%s\" %f" l (show r) n d
 
-reconstruct_k_ugen :: Node -> UGen
+reconstruct_k_ugen :: Graph.U_Node -> UGen
 reconstruct_k_ugen u =
     let (r,n,d) = reconstruct_k_rnd u
     in control_f64 r Nothing n d
@@ -98,46 +96,46 @@
 ugen_qname :: String -> Special -> (String,String)
 ugen_qname nm (Special n) =
     case nm of
-      "UnaryOpUGen" -> ("uop CS",unaryName n)
-      "BinaryOpUGen" -> ("binop CS",binaryName n)
+      "UnaryOpUGen" -> ("uop CS",Operator.unaryName n)
+      "BinaryOpUGen" -> ("binop CS",Operator.binaryName n)
       _ -> ("ugen",nm)
 
-reconstruct_mce_str :: Node -> String
+reconstruct_mce_str :: Graph.U_Node -> String
 reconstruct_mce_str u =
-    let o = length (node_u_outputs u)
-        l = node_label u
+    let o = length (Graph.u_node_u_outputs u)
+        l = Graph.u_node_label u
         p = map (printf "%s_o_%d" l) [0 .. o - 1]
         p' = intercalate "," p
     in if o <= 1
        then ""
        else printf "[%s] = mceChannels %s" p' l
 
-reconstruct_u_str :: Node -> [String]
+reconstruct_u_str :: Graph.U_Node -> [String]
 reconstruct_u_str u =
-    let l = node_label u
-        r = node_u_rate u
-        i = node_u_inputs u
+    let l = Graph.u_node_label u
+        r = Graph.u_node_u_rate u
+        i = Graph.u_node_u_inputs u
         i_s = unwords (map (from_port_label '_') i)
         i_l = intercalate "," (map (from_port_label '_') i)
-        s = node_u_special u
-        (q,n) = ugen_qname (node_u_name u) s
-        z = node_id u
-        o = length (node_u_outputs u)
+        s = Graph.u_node_u_special u
+        (q,n) = ugen_qname (Graph.u_node_u_name u) s
+        z = Graph.u_node_id u
+        o = length (Graph.u_node_u_outputs u)
         u_s = printf "%s = ugen \"%s\" %s [%s] %d" l n (show r) i_l o
         nd_s = let t = "%s = nondet \"%s\" (UId %d) %s [%s] %d"
                in printf t l n z (show r) i_l o
         c = case q of
-              "ugen" -> if node_u_ugenid u == NoId then u_s else nd_s
+              "ugen" -> if Graph.u_node_u_ugenid u == NoId then u_s else nd_s
               _ -> printf "%s = %s \"%s\" %s %s" l q n (show r) i_s
         m = reconstruct_mce_str u
-    in if is_implicit_control u
+    in if Graph.u_node_is_implicit_control u
        then []
        else if null m then [c] else [c,m]
 
-reconstruct_mrg_str :: [Node] -> String
+reconstruct_mrg_str :: [Graph.U_Node] -> String
 reconstruct_mrg_str u =
-    let zero_out n = not (is_implicit_control n) && null (node_u_outputs n)
-    in case map node_label (filter zero_out u) of
+    let zero_out n = not (Graph.u_node_is_implicit_control n) && null (Graph.u_node_u_outputs n)
+    in case map Graph.u_node_label (filter zero_out u) of
          [] -> error "reconstruct_mrg_str"
          [o] -> printf "%s" o
          o -> printf "mrg [%s]" (intercalate "," o)
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
@@ -3,58 +3,54 @@
 
 import Data.Either {- base -}
 import Data.List {- base -}
-import Data.Maybe {- base -}
 
 import Sound.SC3.UGen.Graph
 import Sound.SC3.UGen.Rate
+import Sound.SC3.UGen.Type
 
 -- * Lift constants
 
--- | Transform 'NodeC' to 'NodeK', 'id' for other 'Node' types.
+-- | Transform 'U_Node_C' to 'U_Node_K', 'id' for other 'U_Node' types.
 --
--- > let r = (NodeK 8 KR Nothing "k_8" 0.1 K_KR,9)
--- > in constant_to_control 8 (NodeC 0 0.1) == r
-constant_to_control :: NodeId -> Node -> (NodeId,Node)
+-- > let k = U_Node_K 8 KR Nothing "k_8" 0.1 K_KR Nothing
+-- > node_k_eq k (snd (constant_to_control 8 (U_Node_C 0 0.1)))
+constant_to_control :: UID_t -> U_Node -> (UID_t,U_Node)
 constant_to_control z n =
     case n of
-      NodeC _ k -> (z+1,NodeK z KR Nothing ("k_" ++ show z) k K_KR Nothing)
+      U_Node_C _ k -> (z + 1,U_Node_K z KR Nothing ("k_" ++ show z) k K_KR Nothing)
       _ -> (z,n)
 
--- | Erroring variant of 'from_port_node'.
-from_port_node_err :: Graph -> FromPort -> Node
-from_port_node_err g fp =
-    let e = error "from_port_node_err"
-    in fromMaybe e (from_port_node g fp)
-
--- | If the 'FromPort' is a /constant/ generate a /control/ 'Node',
--- else retain 'FromPort'.
-c_lift_from_port :: Graph -> NodeId -> FromPort -> (NodeId,Either FromPort Node)
+-- | If the 'From_Port' is a /constant/ generate a /control/ 'U_Node', else retain 'From_Port'.
+c_lift_from_port :: U_Graph -> UID_t -> From_Port -> (UID_t,Either From_Port U_Node)
 c_lift_from_port g z fp =
     case fp of
-      FromPort_C _ -> let n = from_port_node_err g fp
-                          (z',n') = constant_to_control z n
-                      in (z',Right n')
+      From_Port_C _ ->
+        let n = ug_from_port_node_err g fp
+            (z',n') = constant_to_control z n
+        in (z',Right n')
       _ -> (z,Left fp)
 
--- | Lift a set of 'NodeU' /inputs/ from constants to controls.  The
--- result triple gives the incremented 'NodeId', the transformed
--- 'FromPort' list, and the list of newly minted control 'Node's.
-c_lift_inputs :: Graph -> NodeId -> [FromPort] -> (NodeId,[FromPort],[Node])
+-- | Lift a set of 'U_NodeU' /inputs/ from constants to controls.  The
+-- result triple gives the incremented 'UID_t', the transformed
+-- 'From_Port' list, and the list of newly minted control 'U_Node's.
+c_lift_inputs :: U_Graph -> UID_t -> [From_Port] -> (UID_t,[From_Port],[U_Node])
 c_lift_inputs g z i =
     let (z',r) = mapAccumL (c_lift_from_port g) z i
         f e = case e of
                 Left fp -> fp
-                Right n -> as_from_port n
+                Right n -> u_node_from_port n
         r' = map f r
     in (z',r',rights r)
 
-c_lift_ugen :: Graph -> NodeId -> Node -> (NodeId,Node,[Node])
+-- | Lift inputs at 'U_Node_U' as required.
+c_lift_ugen :: U_Graph -> UID_t -> U_Node -> (UID_t,U_Node,[U_Node])
 c_lift_ugen g z n =
-    let i = node_u_inputs n
+    let i = u_node_u_inputs n
         (z',i',k) = c_lift_inputs g z i
-    in (z',n {node_u_inputs = i'},k)
+    in (z',n {u_node_u_inputs = i'},k)
 
-c_lift_ugens :: Graph -> NodeId -> [Node] -> (NodeId,[Node],[Node])
+-- | 'c_lift_ugen' at list of 'U_Node_U'.
+c_lift_ugens :: U_Graph -> UID_t -> [U_Node] -> (UID_t,[U_Node],[U_Node])
 c_lift_ugens g  =
     let recur (k,r) z u =
             case u of
@@ -63,16 +59,20 @@
                       in recur (k++k',n':r) z' u'
     in recur ([],[])
 
--- > import Sound.SC3
--- > import Sound.SC3.UGen.Dot
---
--- > let u = out 0 (sinOsc AR 440 0 * 0.1)
--- > let g = synth u
--- > draw g
--- > draw (lift_constants g)
-lift_constants :: Graph -> Graph
+{-| Lift constants to controls.
+
+> import Sound.SC3 {- hsc3 -}
+> import Sound.SC3.UGen.Dot {- hsc3-dot -}
+
+> let u = out 0 (sinOsc AR 440 0 * 0.1)
+> let g = ugen_to_graph u
+> draw g
+> draw (lift_constants g)
+
+-}
+lift_constants :: U_Graph -> U_Graph
 lift_constants g =
-    let (Graph z _ k u) = remove_implicit g
+    let (U_Graph z _ k u) = ug_remove_implicit g
         (z',k',u') = c_lift_ugens g z u
-        g' = Graph z' [] (nubBy node_k_eq (k ++ k')) u'
-    in add_implicit g'
+        g' = U_Graph z' [] (nubBy u_node_k_eq (k ++ k')) u'
+    in ug_add_implicit g'
diff --git a/Sound/SC3/UGen/HS.hs b/Sound/SC3/UGen/HS.hs
--- a/Sound/SC3/UGen/HS.hs
+++ b/Sound/SC3/UGen/HS.hs
@@ -5,6 +5,7 @@
 import qualified System.Random as R {- random -}
 
 import Sound.SC3.Common.Math
+import qualified Sound.SC3.Common.Math.Filter as Filter
 
 -- | F = function, ST = state
 type F_ST0 st o = st -> (o,st)
@@ -69,6 +70,10 @@
 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))
 
+-- | ff = feed-forward, fb = feed-back
+iir2_ff_fb :: (n -> n -> n -> T2 n) -> F_ST1 (T2 n) n n
+iir2_ff_fb f (n,(y1,y0)) = let (r,y0') = f n y0 y1 in (r,(y0,y0'))
+
 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))
 
@@ -115,60 +120,29 @@
 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
+resonz_f param x y1 y2 =
+    let (a0,b1,b2) = Filter.resonz_coef param
         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 = resonant low pass filter
 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
+rlpf_f max_f param x y1 y2 =
+    let (a0,b1,b2) = Filter.rlpf_coef max_f param
     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_hpf_ir (sample_rate,f) = sos (Filter.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)
+bw_lpf_ir (sample_rate,f) = sos (Filter.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)
@@ -184,19 +158,46 @@
         r = brown_noise_f (n / 8.0) y1
     in (r,(g',r))
 
+-- | <http://musicdsp.org/files/pink.txt>
+pk_pinking_filter_f :: Fractional a => (a, a, a, a, a, a, a) -> a -> (a, (a, a, a, a, a, a, a))
+pk_pinking_filter_f (b0,b1,b2,b3,b4,b5,b6) w =
+  let b0' = 0.99886 * b0 + w * 0.0555179
+      b1' = 0.99332 * b1 + w * 0.0750759
+      b2' = 0.96900 * b2 + w * 0.1538520
+      b3' = 0.86650 * b3 + w * 0.3104856
+      b4' = 0.55000 * b4 + w * 0.5329522
+      b5' = -0.7616 * b5 - w * 0.0168980
+      p = b0 + b1 + b2 + b3 + b4 + b5 + b6 + w * 0.5362
+      b6' = w * 0.115926
+  in (p,(b0',b1',b2',b3',b4',b5',b6'))
+
+-- | <http://musicdsp.org/files/pink.txt>
+pk_pinking_filter_economy_f :: Fractional a => (a, a, a) -> a -> (a, (a, a, a))
+pk_pinking_filter_economy_f (b0,b1,b2) w =
+  let b0' = 0.99765 * b0 + w * 0.0990460
+      b1' = 0.96300 * b1 + w * 0.2965164
+      b2' = 0.57000 * b2 + w * 1.0526913
+      p = b0 + b1 + b2 + w * 0.1848
+  in (p,(b0',b1',b2'))
+
+-- | dt must not be zero.
 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
 
+-- | dt must not be zero.
 lag_f :: Floating a => a -> a -> a -> a -> a
-lag_f sr t x y1 =
-    let b1 = exp (log (0.001 / (t * sr)))
+lag_f sr dt x y1 =
+    let b1 = exp (log 0.001 / (dt * 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)
 
+slope :: Num t => t -> F_ST1 t t t
+slope sr = fir1 (\n z0 -> (n - z0) * sr)
+
 latch :: F_ST1 t (t,Bool) t
 latch ((n,b),y1) = let r = if b then n else y1 in (r,r)
 
@@ -205,7 +206,7 @@
 
 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)
+    let r = if trig then resetPos else sc3_wrap start end (ph + rate)
     in (ph,r)
 
 -- | * LIST PROCESSING
@@ -213,9 +214,11 @@
 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'
 
+-- > take 10 (l_white_noise 'α')
 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))
 
+-- > take 10 (l_brown_noise 'α')
 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)
 
@@ -227,6 +230,9 @@
 
 l_lag :: Floating t => t -> [t] -> [t] -> [t]
 l_lag sr i t = l_apply_f_st1 (lag sr) 0 (zip i t)
+
+l_slope :: Floating t => t -> [t] -> [t]
+l_slope sr i = l_apply_f_st1 (slope sr) 0 i
 
 -- > 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]
diff --git a/Sound/SC3/UGen/Identifier.hs b/Sound/SC3/UGen/Identifier.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/Identifier.hs
+++ /dev/null
@@ -1,21 +0,0 @@
--- | Typeclass and functions to manage UGen identifiers.
-module Sound.SC3.UGen.Identifier where
-
-import qualified Data.Hashable as H {- hashable -}
-
--- | Typeclass to constrain UGen identifiers.
-class H.Hashable a => ID a where
-    resolveID :: a -> Int
-    resolveID = H.hash
-
-instance ID Int where
-instance ID Integer where
-instance ID Char where
-instance ID Float where
-instance ID Double where
-
--- | Hash 'ID's /p/ and /q/ and sum to form an 'Int'.
---
--- > 'a' `joinID` (1::Int) == 1627429042
-joinID :: (ID a,ID b) => a -> b -> Int
-joinID p q = H.hash p `H.hashWithSalt` H.hash q
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
@@ -5,6 +5,7 @@
 data MCE n = MCE_Unit n | MCE_Vector [n]
              deriving (Eq,Read,Show)
 
+-- | Elements at 'MCE'.
 mce_elem :: MCE t -> [t]
 mce_elem m =
     case m of
@@ -18,12 +19,14 @@
       MCE_Unit e -> MCE_Vector (replicate n e)
       MCE_Vector e -> MCE_Vector (take n (cycle e))
 
+-- | Apply /f/ at elements of /m/.
 mce_map :: (a -> b) -> MCE a -> MCE b
 mce_map f m =
     case m of
       MCE_Unit e -> MCE_Unit (f e)
       MCE_Vector e -> MCE_Vector (map f e)
 
+-- | Apply /f/ pairwise at elements of /m1/ and /m2/.
 mce_binop :: (a -> b -> c) -> MCE a -> MCE b -> MCE c
 mce_binop f m1 m2 =
     case (m1,m2) of
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
@@ -4,7 +4,7 @@
 import qualified Data.Fixed as F {- base -}
 import Data.Int {- base -}
 
-import Sound.SC3.Common.Math
+import qualified Sound.SC3.Common.Math as Math
 import Sound.SC3.UGen.Bindings.DB (mulAdd)
 import Sound.SC3.UGen.Operator
 import Sound.SC3.UGen.Type
@@ -13,74 +13,27 @@
 dinf :: UGen
 dinf = constant (9e8::Float)
 
--- | True is conventionally 1.  The test to determine true is @> 0@.
-sc3_true :: Num n => n
-sc3_true = 1
-
--- | False is conventionally 0.
-sc3_false :: Num n => n
-sc3_false = 0
-
--- | Lifted 'not'.
---
--- > sc3_not sc3_true == sc3_false
--- > sc3_not sc3_false == sc3_true
-sc3_not :: (Ord n,Num n) => n -> n
-sc3_not = sc3_bool . not . (> 0)
-
--- | Translate 'Bool' to 'sc3_true' and 'sc3_false'.
-sc3_bool :: Num n => Bool -> n
-sc3_bool b = if b then sc3_true else sc3_false
-
--- | Lift comparison function.
-sc3_comparison :: Num n => (n -> n -> Bool) -> n -> n -> n
-sc3_comparison f p q = sc3_bool (f p q)
-
--- | Lifted '=='.
-sc3_eq :: (Num n, Eq n) => n -> n -> n
-sc3_eq = sc3_comparison (==)
-
--- | Lifted '/='.
-sc3_neq :: (Num n, Eq n) => n -> n -> n
-sc3_neq = sc3_comparison (/=)
-
--- | Lifted '<'.
-sc3_lt :: (Num n, Ord n) => n -> n -> n
-sc3_lt = sc3_comparison (<)
-
--- | Lifted '<='.
-sc3_lte :: (Num n, Ord n) => n -> n -> n
-sc3_lte = sc3_comparison (<=)
-
--- | Lifted '>'.
-sc3_gt :: (Num n, Ord n) => n -> n -> n
-sc3_gt = sc3_comparison (>)
-
--- | Lifted '>='.
-sc3_gte :: (Num n, Ord n) => n -> n -> n
-sc3_gte = sc3_comparison (>=)
-
 -- | Association table for 'Binary' to haskell function implementing operator.
 binop_hs_tbl :: (Real n,Floating n,RealFrac n) => [(Binary,n -> n -> n)]
 binop_hs_tbl =
     [(Add,(+))
     ,(Sub,(-))
     ,(FDiv,(/))
-    ,(IDiv,sc3_idiv)
-    ,(Mod,sc3_mod)
-    ,(EQ_,sc3_eq)
-    ,(NE,sc3_neq)
-    ,(LT_,sc3_lt)
-    ,(LE,sc3_lte)
-    ,(GT_,sc3_gt)
-    ,(GE,sc3_gte)
+    ,(IDiv,Math.sc3_idiv)
+    ,(Mod,Math.sc3_mod)
+    ,(EQ_,Math.sc3_eq)
+    ,(NE,Math.sc3_neq)
+    ,(LT_,Math.sc3_lt)
+    ,(LE,Math.sc3_lte)
+    ,(GT_,Math.sc3_gt)
+    ,(GE,Math.sc3_gte)
     ,(Min,min)
     ,(Max,max)
     ,(Mul,(*))
     ,(Pow,(**))
     ,(Min,min)
     ,(Max,max)
-    ,(Round,sc3_round_to)]
+    ,(Round,Math.sc3_round_to)]
 
 -- | 'lookup' 'binop_hs_tbl' via 'toEnum'.
 binop_special_hs :: (RealFrac n,Floating n) => Int -> Maybe (n -> n -> n)
@@ -92,14 +45,14 @@
     [(Neg,negate)
     ,(Not,\z -> if z > 0 then 0 else 1)
     ,(Abs,abs)
-    ,(Ceil,sc_ceiling)
-    ,(Floor,sc_floor)
+    ,(Ceil,Math.sc3_ceiling)
+    ,(Floor,Math.sc3_floor)
     ,(Squared,\z -> z * z)
     ,(Cubed,\z -> z * z * z)
     ,(Sqrt,sqrt)
     ,(Recip,recip)
-    ,(MIDICPS,midi_to_cps)
-    ,(CPSMIDI,cps_to_midi)
+    ,(MIDICPS,Math.midi_to_cps)
+    ,(CPSMIDI,Math.cps_to_midi)
     ,(Sin,sin)
     ,(Cos,cos)
     ,(Tan,tan)]
@@ -114,9 +67,9 @@
 -- | Variant on Eq class, result is of the same type as the values compared.
 class (Eq a,Num a) => EqE a where
     (==*) :: a -> a -> a
-    (==*) = sc3_eq
+    (==*) = Math.sc3_eq
     (/=*) :: a -> a -> a
-    (/=*) = sc3_neq
+    (/=*) = Math.sc3_neq
 
 instance EqE Int where
 instance EqE Integer where
@@ -132,46 +85,46 @@
 -- | Variant on Ord class, result is of the same type as the values compared.
 class (Ord a,Num a) => OrdE a where
     (<*) :: a -> a -> a
-    (<*) = sc3_lt
+    (<*) = Math.sc3_lt
     (<=*) :: a -> a -> a
-    (<=*) = sc3_lte
+    (<=*) = Math.sc3_lte
     (>*) :: a -> a -> a
-    (>*) = sc3_gt
+    (>*) = Math.sc3_gt
     (>=*) :: a -> a -> a
-    (>=*) = sc3_gte
+    (>=*) = Math.sc3_gte
 
 instance OrdE Int
 instance OrdE Integer
-instance OrdE Int32 where
-instance OrdE Int64 where
+instance OrdE Int32
+instance OrdE Int64
 instance OrdE Float
 instance OrdE Double
 
 instance OrdE UGen where
-    (<*) = mkBinaryOperator LT_ sc3_lt
-    (<=*) = mkBinaryOperator LE sc3_lte
-    (>*) = mkBinaryOperator GT_ sc3_gt
-    (>=*) = mkBinaryOperator GE sc3_gte
+    (<*) = mkBinaryOperator LT_ Math.sc3_lt
+    (<=*) = mkBinaryOperator LE Math.sc3_lte
+    (>*) = mkBinaryOperator GT_ Math.sc3_gt
+    (>=*) = mkBinaryOperator GE Math.sc3_gte
 
 -- | Variant of 'RealFrac' with non 'Integral' results.
 class RealFrac a => RealFracE a where
   properFractionE :: a -> (a,a)
-  properFractionE = sc3_properFraction
+  properFractionE = Math.sc3_properFraction
   truncateE :: a -> a
-  truncateE = sc_truncate
+  truncateE = Math.sc3_truncate
   roundE :: a -> a
-  roundE = sc_round
+  roundE = Math.sc3_round
   ceilingE :: a -> a
-  ceilingE = sc_ceiling
+  ceilingE = Math.sc3_ceiling
   floorE :: a -> a
-  floorE = sc_floor
+  floorE = Math.sc3_floor
 
 instance RealFracE Float
 instance RealFracE Double
 
--- | 'UGen' form or 'sc3_round_to'.
+-- | 'UGen' form or 'Math.sc3_round_to'.
 roundTo :: UGen -> UGen -> UGen
-roundTo = mkBinaryOperator Round sc3_round_to
+roundTo = mkBinaryOperator Round Math.sc3_round_to
 
 instance RealFracE UGen where
     properFractionE = error "UGen.properFractionE"
@@ -189,21 +142,21 @@
 -- > map (floor . (* 1e4) . dbAmp) [-90,-60,-30,0] == [0,10,316,10000]
 class (Floating a, Ord a) => UnaryOp a where
     ampDb :: a -> a
-    ampDb = amp_to_db
+    ampDb = Math.amp_to_db
     asFloat :: a -> a
     asFloat = error "asFloat"
     asInt :: a -> a
     asInt = error "asInt"
     cpsMIDI :: a -> a
-    cpsMIDI = cps_to_midi
+    cpsMIDI = Math.cps_to_midi
     cpsOct :: a -> a
-    cpsOct = cps_to_oct
+    cpsOct = Math.cps_to_oct
     cubed :: a -> a
     cubed n = n * n * n
     dbAmp :: a -> a
-    dbAmp = db_to_amp
+    dbAmp = Math.db_to_amp
     distort :: a -> a
-    distort = error "distort"
+    distort = Math.sc3_distort
     frac :: a -> a
     frac = error "frac"
     isNil :: a -> a
@@ -213,21 +166,21 @@
     log2 :: a -> a
     log2 = logBase 2
     midiCPS :: a -> a
-    midiCPS = midi_to_cps
+    midiCPS = Math.midi_to_cps
     midiRatio :: a -> a
-    midiRatio = midi_to_ratio
+    midiRatio = Math.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 = oct_to_cps
+    octCPS = Math.oct_to_cps
     ramp_ :: a -> a
     ramp_ _ = error "ramp_"
     ratioMIDI :: a -> a
-    ratioMIDI = ratio_to_midi
+    ratioMIDI = Math.ratio_to_midi
     softClip :: a -> a
-    softClip = error "softClip"
+    softClip = Math.sc3_softclip
     squared :: a -> a
     squared = \z -> z * z
 
@@ -266,11 +219,11 @@
     atan2E :: a -> a -> a
     atan2E a b = atan (b/a)
     clip2 :: a -> a -> a
-    clip2 a b = sc_clip a (-b) b
+    clip2 a b = Math.sc3_clip a (-b) b
     difSqr :: a -> a -> a
-    difSqr = sc_dif_sqr
+    difSqr = Math.sc3_dif_sqr
     excess :: a -> a -> a
-    excess a b = a - sc_clip a (-b) b
+    excess a b = a - Math.sc3_clip a (-b) b
     exprandRange :: a -> a -> a
     exprandRange = error "exprandRange"
     fill :: a -> a -> a
@@ -278,15 +231,15 @@
     firstArg :: a -> a -> a
     firstArg a _ = a
     fold2 :: a -> a -> a
-    fold2 a b = fold_ a (-b) b
+    fold2 a b = Math.sc3_fold a (-b) b
     gcdE :: a -> a -> a
     gcdE = error "gcdE"
     hypot :: a -> a -> a
-    hypot = sc_hypot
+    hypot = Math.sc3_hypot
     hypotx :: a -> a -> a
-    hypotx = sc_hypotx
+    hypotx = Math.sc3_hypotx
     iDiv :: a -> a -> a
-    iDiv = sc3_idiv
+    iDiv = Math.sc3_idiv
     lcmE :: a -> a -> a
     lcmE = error "lcmE"
     modE :: a -> a -> a
@@ -319,16 +272,16 @@
     wrap2 = error "wrap2"
 
 instance BinaryOp Float where
-    fold2 a b = fold_ a (-b) b
+    fold2 a b = Math.sc3_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 = sc_wrap_ni a (-b) b
+    wrap2 a b = Math.sc3_wrap_ni a (-b) b
 
 instance BinaryOp Double where
-    fold2 a b = fold_ a (-b) b
+    fold2 a b = Math.sc3_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 = sc_wrap_ni a (-b) b
+    wrap2 a b = Math.sc3_wrap_ni a (-b) b
 
 instance BinaryOp UGen where
     iDiv = mkBinaryOperator IDiv iDiv
@@ -372,7 +325,7 @@
 
 -- | Map from one linear range to another linear range.
 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
+linlin_ma i sl sr dl dr = let (m,a) = Math.linlin_muladd sl sr dl dr in mul_add i m a
 
 -- | Scale uni-polar (0,1) input to linear (l,r) range
 urange_ma :: (Fractional a,MulAdd a) => a -> a -> a -> a
@@ -381,4 +334,4 @@
 -- | Scale bi-polar (-1,1) input to linear (l,r) range.  Note that the
 -- argument order is not the same as 'linLin'.
 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
+range_ma l r i = let (m,a) = Math.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
--- a/Sound/SC3/UGen/Math/Composite.hs
+++ b/Sound/SC3/UGen/Math/Composite.hs
@@ -1,12 +1,16 @@
+-- | Non-primitve math UGens.
 module Sound.SC3.UGen.Math.Composite where
 
 import Sound.SC3.UGen.Math
 import Sound.SC3.UGen.Type
 import Sound.SC3.UGen.UGen
 
+-- | Select /q/ or /r/ by /p/, ie. @if p == 1 then q else if p == 0 then r@.
 ugen_if :: Num a => a -> a -> a -> a
 ugen_if p q r = (p * q) + ((1 - p) * r)
 
+-- | Separate input into integral and fractional parts.
+--
 -- > ugen_integral_and_fractional_parts 1.5 == mce2 1 0.5
 ugen_integral_and_fractional_parts :: UGen -> UGen
 ugen_integral_and_fractional_parts n =
@@ -14,6 +18,9 @@
         lt_0 = let n' = ceilingE n in mce2 n' (n - n')
     in ugen_if (n >=* 0) gt_eq_0 lt_0
 
+-- | Fractional midi into integral midi and cents detune.
+--
+-- > ugen_fmidi_to_midi_detune 60.5 == mce2 60 50
 ugen_fmidi_to_midi_detune :: UGen -> UGen
 ugen_fmidi_to_midi_detune mnn =
     let (n,c) = unmce2 (ugen_integral_and_fractional_parts mnn)
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,85 +7,57 @@
 import Data.Char {- base -}
 import Data.List.Split {- split -}
 
-import Sound.SC3.Common.Prelude {- hsc3 -}
 import Sound.SC3.UGen.Rate {- hsc3 -}
 
--- | Convert from @hsc3@ name to @SC3@ name.
---
--- > toSC3Name "sinOsc" == "SinOsc"
--- > toSC3Name "lfSaw" == "LFSaw"
--- > toSC3Name "pv_Copy" == "PV_Copy"
--- > map toSC3Name ["bpf","fft","tpv","out","in'","fbSineN"]
-toSC3Name :: String -> String
-toSC3Name nm =
-    case nm of
-      "in'" -> "In"
-      "bpz2" -> "BPZ2"
-      "brz2" -> "BRZ2"
-      "ifft" -> "IFFT"
-      "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'
-      'p':'v':'_':nm' -> "PV_" ++ nm'
-      p:q -> if all isLower nm && length nm <= 3
-             then map toUpper nm
-             else toUpper p : q
-      [] -> []
+{-
+import qualified Sound.SC3.Common.Base {- hsc3 -}
 
--- | Inverse of 'toSC3Name'.
---
--- > let nm = ["SinOsc","LFSaw","PV_Copy","FBSineN"]
--- > in map fromSC3Name nm == ["sinOsc","lfSaw","pv_Copy","fbSineN"]
---
--- > map fromSC3Name ["BPF","FFT","TPV"] == ["bpf","fft","tpv"]
---
--- > map fromSC3Name (words "HPZ1 RLPF")
-fromSC3Name :: String -> String
-fromSC3Name nm =
-    case nm of
-      "In" -> "in'"
-      "BPZ2" -> "bpz2"
-      "BRZ2" -> "brz2"
-      "IFFT" -> "ifft"
-      "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'
-      'P':'V':'_':nm' -> "pv_" ++ nm'
-      p:q -> if all isUpper nm && length nm <= 3
-             then map toLower nm
-             else toLower p : q
-      [] -> []
+is_uc_or_num :: Char -> Bool
+is_uc_or_num c = isUpper c || isDigit c
 
--- | Find SC3 name edges.
+is_lc_or_num :: Char -> Bool
+is_lc_or_num c = isLower c || isDigit c
+-}
+
+-- | Find all SC3 name edges. Edges occur at non lower-case letters.
+sc3_name_edges_plain :: String -> [Bool]
+sc3_name_edges_plain = map (not . isLower)
+
+-- | Find non-initial SC3 name edges.
 --
 -- > sc3_name_edges "SinOsc" == [False,False,False,True,False,False]
+-- > sc3_name_edges "FFT" == [False,False,False]
+-- > sc3_name_edges "DFM1" == [False,False,False,False]
+-- > sc3_name_edges "PV_Add" == [False,False,False,True,False,False]
+-- > sc3_name_edges "A2K" == [False,False,False]
+-- > sc3_name_edges "Lag2UD" == [False,False,False,True,True,True]
 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 && [p,q,r] /= "UGe")
-                (Just p,q,Nothing) -> isLower p && isUpper q
-    in map f . pcn_triples
+sc3_name_edges s =
+  let (p,q) = span (== True) (sc3_name_edges_plain s)
+      n = length p
+  in if n < 2 || null q
+     then replicate n False ++ q
+     else replicate (n - 1) False ++ [True] ++ q
 
+-- | Convert from SC3 name to HS style name.
+--
+-- > s = words "SinOsc LFSaw FFT PV_Add AllpassN BHiPass BinaryOpUGen HPZ1 RLPF TGrains DFM1 FBSineC A2K Lag2UD IIRFilter FMGrainB"
+-- > l = words "sinOsc lfSaw fft pv_Add allpassN bHiPass binaryOpUGen hpz1 rlpf tGrains dfm1 fbSineC a2k lag2UD iirFilter fmGrainB"
+-- > map sc3_name_to_hs_name s == l
+sc3_name_to_hs_name :: String -> String
+sc3_name_to_hs_name s =
+    let f (c,e) = if e then toUpper c else c
+        s_lc = map toLower s
+    in map f (zip s_lc (sc3_name_edges s))
+
 -- | Convert from SC3 name to Lisp style name.
 --
--- > let {s = words "SinOsc LFSaw FFT PV_Add AllpassN BHiPass BinaryOpUGen HPZ1 RLPF TGrains"
--- >     ;l = words "sin-osc lf-saw fft pv-add allpass-n b-hi-pass binary-op-ugen hpz1 rlpf t-grains"}
--- > in map sc3_name_to_lisp_name s == l
+-- > s = words "SinOsc LFSaw FFT PV_Add AllpassN BHiPass BinaryOpUGen HPZ1 RLPF TGrains DFM1"
+-- > l = words "sin-osc lf-saw fft pv-add allpass-n b-hi-pass binary-op-u-gen hpz1 rlpf t-grains dfm1"
+-- > map sc3_name_to_lisp_name s == l
 sc3_name_to_lisp_name :: String -> String
 sc3_name_to_lisp_name s =
-    let f (c,e) = if e then ['-',c] else if c == '_' then "-" else [c]
+    let f (c,e) = if e then ['-',c] else if c == '_' then [] else [c]
     in concatMap f (zip (map toLower s) (sc3_name_edges s))
 
 -- | SC3 UGen /names/ are given with rate suffixes if oscillators, without if filters.
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
@@ -5,7 +5,7 @@
 import Control.Monad {- base -}
 import Data.Maybe {- base -}
 
-import Sound.SC3.Common.Prelude {- hsc3 -}
+import Sound.SC3.Common.Base {- hsc3 -}
 
 -- * Unary
 
@@ -201,7 +201,7 @@
 
 -- | Order of lookup: binary then unary.
 --
--- > map (resolve_operator CI) (words "+ - ADD SUB NEG")
+-- > map (resolve_operator Sound.SC3.Common.Base.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/Optimise.hs b/Sound/SC3/UGen/Optimise.hs
--- a/Sound/SC3/UGen/Optimise.hs
+++ b/Sound/SC3/UGen/Optimise.hs
@@ -8,6 +8,17 @@
 import Sound.SC3.UGen.Type
 import Sound.SC3.UGen.UGen
 
+-- | MulAdd optimiser, applicable at any UGen.
+--
+-- > import Sound.SC3
+-- > g1 = mul_add_optimise (sinOsc AR 440 0 * 0.1 + 0.05)
+-- > g2 = mul_add_optimise (0.05 + sinOsc AR 440 0 * 0.1)
+mul_add_optimise :: UGen -> UGen
+mul_add_optimise u =
+  case u of
+    Primitive_U (Primitive _ "BinaryOpUGen" _ [_] (Special 0) NoId) -> mul_add_optimise_direct u
+    _ -> u
+
 -- | Constant form of 'rand' UGen.
 c_rand :: Random a => Int -> a -> a -> a
 c_rand z l r = fst (randomR (l,r) (mkStdGen z))
@@ -22,7 +33,7 @@
 -- transformation for very large graphs which are being constructed
 -- and sent each time the graph is played.
 --
--- > import Sound.SC3.UGen.Dot
+-- > import Sound.SC3.UGen.Dot {- hsc3-dot -}
 --
 -- > let u = sinOsc AR (rand 'a' 220 440) 0 * 0.1
 -- > in draw (u + ugen_optimise_ir_rand u)
@@ -63,7 +74,8 @@
             case u of
               Primitive_U p ->
                   case p of
-                    Primitive _ "BinaryOpUGen" [Constant_U (Constant l),Constant_U (Constant r)] [_] (Special z) _ ->
+                    Primitive _ "BinaryOpUGen" [Constant_U (Constant l)
+                                               ,Constant_U (Constant r)] [_] (Special z) _ ->
                         case binop_special_hs z of
                           Just fn -> Constant_U (Constant (fn l r))
                           _ -> u
@@ -75,6 +87,7 @@
               _ -> u
     in ugenTraverse f
 
+-- | 'u_constant' of 'ugen_optimise_ir_rand'.
 constant_opt :: UGen -> Maybe Sample
 constant_opt = u_constant . ugen_optimise_ir_rand
 
diff --git a/Sound/SC3/UGen/PP.hs b/Sound/SC3/UGen/PP.hs
--- a/Sound/SC3/UGen/PP.hs
+++ b/Sound/SC3/UGen/PP.hs
@@ -1,25 +1,14 @@
+-- | 'UGen' pretty-printer.
 module Sound.SC3.UGen.PP where
 
 import Data.List {- split -}
-import Data.Ratio {- base -}
-import Numeric {- base -}
 
+import Sound.SC3.Common.Math
 import Sound.SC3.UGen.MCE
 import Sound.SC3.UGen.Type
 import Sound.SC3.UGen.UGen
 
--- | The default show is odd, 0.05 shows as 5.0e-2.
-double_pp :: Int -> Double -> String
-double_pp k n =
-    let f = reverse . dropWhile (== '0') . reverse
-    in f (showFFloat (Just k) n "")
-
--- | Print as integer if integral, else as real.
-real_pp :: Double -> String
-real_pp n =
-    let r = toRational n
-    in if denominator r == 1 then show (numerator r) else double_pp 5 n
-
+-- | Place /x/ in (/l/,/r/) brackets.
 bracketed :: (a,a) -> [a] -> [a]
 bracketed (l,r) x = l : x ++ [r]
 
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
@@ -8,7 +8,7 @@
 -- > audition (out 0 (sinOsc AR 440 0 * 0.1))
 module Sound.SC3.UGen.Plain where
 
-import Sound.SC3.Common.Prelude
+import Sound.SC3.Common.Base
 import Sound.SC3.UGen.Operator
 import Sound.SC3.UGen.Rate
 import Sound.SC3.UGen.Type
diff --git a/Sound/SC3/UGen/Protect.hs b/Sound/SC3/UGen/Protect.hs
--- a/Sound/SC3/UGen/Protect.hs
+++ b/Sound/SC3/UGen/Protect.hs
@@ -1,12 +1,12 @@
 -- | Functions to re-write assigned node identifiers at UGen graphs.
--- Used carefully it allows for composition of sub-graphs with
--- psuedo-random nodes.
+-- Used carefully it allows for composition of sub-graphs with psuedo-random nodes.
 module Sound.SC3.UGen.Protect where
 
-import Sound.SC3.UGen.Identifier
+import Sound.SC3.Common.UId
 import Sound.SC3.UGen.Type
 import Sound.SC3.UGen.UGen
 
+{-
 -- | Collect Ids at UGen graph
 ugenIds :: UGen -> [UGenId]
 ugenIds =
@@ -14,37 +14,37 @@
                 Primitive_U p -> [ugenId p]
                 _ -> []
     in ugenFoldr ((++) . f) []
+-}
 
--- | Apply /f/ at 'UId', or no-op at 'NoId'.
-atUGenId :: (Int -> Int) -> UGenId -> UGenId
-atUGenId f z =
+-- | Replace UId /i/ at /z/ with /(e,i)/.
+edit_ugenid :: ID a => a -> UGenId -> UGenId
+edit_ugenid e z =
     case z of
       NoId -> NoId
-      UId i -> UId (f i)
+      UId i -> UId (resolveID (e,i))
 
--- | Add 'idHash' of /e/ to all 'Primitive_U' at /u/.
+-- | 'edit_ugenid' of /e/ at all 'Primitive_U' of /u/.
 uprotect :: ID a => a -> UGen -> UGen
 uprotect e =
-    let e' = resolveID e
-        f u = case u of
-                Primitive_U p -> Primitive_U (p {ugenId = atUGenId (+ e') (ugenId p)})
+    let f u = case u of
+                Primitive_U p -> Primitive_U (p {ugenId = edit_ugenid e (ugenId p)})
                 _ -> u
     in ugenTraverse f
 
 -- | Variant of 'uprotect' with subsequent identifiers derived by
 -- incrementing initial identifier.
-uprotect' :: ID a => a -> [UGen] -> [UGen]
-uprotect' e =
+uprotect_seq :: ID a => a -> [UGen] -> [UGen]
+uprotect_seq e =
     let n = map (+ resolveID e) [1..]
     in zipWith uprotect n
 
--- | Make /n/ parallel instances of 'UGen' with protected identifiers.
-uclone' :: ID a => a -> Int -> UGen -> [UGen]
-uclone' e n = uprotect' e . replicate n
+-- | Make /n/ instances of 'UGen' with protected identifiers.
+uclone_seq :: ID a => a -> Int -> UGen -> [UGen]
+uclone_seq e n = uprotect_seq e . replicate n
 
--- | 'mce' variant of 'uclone''.
+-- | 'mce' of 'uclone_seq'.
 uclone :: ID a => a -> Int -> UGen -> UGen
-uclone e n = mce . uclone' e n
+uclone e n = mce . uclone_seq e n
 
 -- | Left to right UGen function composition with 'UGenId' protection.
 ucompose :: ID a => a -> [UGen -> UGen] -> UGen -> UGen
diff --git a/Sound/SC3/UGen/Rate.hs b/Sound/SC3/UGen/Rate.hs
--- a/Sound/SC3/UGen/Rate.hs
+++ b/Sound/SC3/UGen/Rate.hs
@@ -48,3 +48,23 @@
       "IR" -> Just IR
       "DR" -> Just DR
       _ -> Nothing
+
+-- * Control rates
+
+-- | Enumeration of the four operating rates for controls.
+--   IR = initialisation rate, KR = control rate, TR = trigger rate, AR = audio rate.
+data K_Type = K_IR | K_KR | K_TR | K_AR
+             deriving (Eq,Show,Ord)
+
+-- | Determine class of control given 'Rate' and /trigger/ status.
+ktype :: Rate -> Bool -> K_Type
+ktype r tr =
+    if tr
+    then case r of
+           KR -> K_TR
+           _ -> error "ktype: non KR trigger control"
+    else case r of
+           IR -> K_IR
+           KR -> K_KR
+           AR -> K_AR
+           DR -> error "ktype: DR control"
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,4 +1,4 @@
---  | Unit Generator ('UGen'), and associated types and instances.
+-- | Unit Generator ('UGen'), and associated types and instances.
 module Sound.SC3.UGen.Type where
 
 import Data.Bits {- base -}
@@ -6,16 +6,19 @@
 import Data.Maybe {- base -}
 import Safe {- safe -}
 import System.Random {- random -}
-import qualified Text.Read as R {- base -}
 
+import Sound.SC3.Common.Math
 import Sound.SC3.UGen.MCE
 import Sound.SC3.UGen.Operator
 import Sound.SC3.UGen.Rate
 
 -- * Basic types
 
--- | Data type for internalised identifier at 'UGen'.
-data UGenId = NoId | UId Int
+-- | Type of unique identifier.
+type UID_t = Int
+
+-- | Data type for the identifier at a 'Primitive' 'UGen'.
+data UGenId = NoId | UId UID_t
               deriving (Eq,Read,Show)
 
 -- | Alias of 'NoId', the 'UGenId' used for deterministic UGens.
@@ -82,7 +85,7 @@
                            ,ugenId :: UGenId}
                  deriving (Eq,Read,Show)
 
--- | Proxy to multiple channel input.
+-- | Proxy indicating an output port at a multi-channel primitive.
 data Proxy = Proxy {proxySource :: Primitive
                    ,proxyIndex :: Int}
             deriving (Eq,Read,Show)
@@ -104,10 +107,7 @@
 
 -- * Parser
 
--- | Type-specialised 'R.readMaybe'.
-parse_double :: String -> Maybe Double
-parse_double = R.readMaybe
-
+-- | 'constant' of 'parse_double'.
 parse_constant :: String -> Maybe UGen
 parse_constant = fmap constant . parse_double
 
@@ -166,6 +166,7 @@
       Proxy_U p -> Just p
       _ -> Nothing
 
+-- | Is 'UGen' a 'Proxy'?
 isProxy :: UGen -> Bool
 isProxy = isJust . un_proxy
 
@@ -280,7 +281,7 @@
 proxy u n =
     case u of
       Primitive_U p -> Proxy_U (Proxy p n)
-      _ -> error "proxy: not primitive"
+      _ -> error "proxy: not primitive?"
 
 -- | Determine the rate of a UGen.
 rateOf :: UGen -> Rate
@@ -313,9 +314,9 @@
 -- cf = constant function, rs = rate set, r = rate, nm = name, i =
 -- inputs, o = outputs.
 mkUGen :: Maybe ([Sample] -> Sample) -> [Rate] -> Either Rate [Int] ->
-          String -> [UGen] -> Maybe UGen -> Int -> Special -> UGenId -> UGen
+          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
+    let i' = maybe i ((i ++) . concatMap mceChannels) i_mce
         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)
@@ -337,7 +338,7 @@
     let ix = [0 .. length i - 1]
     in mkUGen (Just f) all_rates (Right ix) c i Nothing 1 (Special s) NoId
 
--- | Unary math constructor with constant optimization.
+-- | Unary math constructor.
 mkUnaryOperator :: Unary -> (Sample -> Sample) -> UGen -> UGen
 mkUnaryOperator i f a =
     let g [x] = f x
@@ -353,10 +354,10 @@
 -- > o - 0 == o && 0 - o /= o
 -- > o / 1 == o && 1 / o /= o
 -- > o ** 1 == o && o ** 2 /= o
-mkBinaryOperator_optimize :: Binary -> (Sample -> Sample -> Sample) ->
-                             (Either Sample Sample -> Bool) ->
-                             UGen -> UGen -> UGen
-mkBinaryOperator_optimize i f o a b =
+mkBinaryOperator_optimize_constants :: Binary -> (Sample -> Sample -> Sample) ->
+                                       (Either Sample Sample -> Bool) ->
+                                       UGen -> UGen -> UGen
+mkBinaryOperator_optimize_constants i f o a b =
    let g [x,y] = f x y
        g _ = error "mkBinaryOperator: non binary input"
        r = case (a,b) of
@@ -367,7 +368,7 @@
              _ -> Nothing
    in fromMaybe (mkOperator g "BinaryOpUGen" [a, b] (fromEnum i)) r
 
--- | Binary math constructor with constant optimization.
+-- | Plain (non-optimised) binary math constructor.
 mkBinaryOperator :: Binary -> (Sample -> Sample -> Sample) -> UGen -> UGen -> UGen
 mkBinaryOperator i f a b =
    let g [x,y] = f x y
@@ -376,12 +377,41 @@
 
 -- * Numeric instances
 
+-- | MulAdd re-writer, applicable only directly at add operator UGen.
+mul_add_optimise_direct :: UGen -> UGen
+mul_add_optimise_direct u =
+  case u of
+    Primitive_U
+      (Primitive r _ [Primitive_U (Primitive _ "BinaryOpUGen" [i,j] [_] (Special 2) NoId),k] [_] _ NoId) ->
+      Primitive_U (Primitive r "MulAdd" [i,j,k] [r] (Special 0) NoId)
+    Primitive_U
+      (Primitive r _ [k,Primitive_U (Primitive _ "BinaryOpUGen" [i,j] [_] (Special 2) NoId)] [_] _ NoId) ->
+      Primitive_U (Primitive r "MulAdd" [i,j,k] [r] (Special 0) NoId)
+    _ -> u
+
+-- | Sum3 re-writer, applicable only directly at add operator UGen.
+sum3_optimise_direct :: UGen -> UGen
+sum3_optimise_direct u =
+  case u of
+    Primitive_U
+      (Primitive r _ [Primitive_U (Primitive _ "BinaryOpUGen" [i,j] [_] (Special 0) NoId),k] [_] _ NoId) ->
+      Primitive_U (Primitive r "Sum3" [i,j,k] [r] (Special 0) NoId)
+    Primitive_U
+      (Primitive r _ [k,Primitive_U (Primitive _ "BinaryOpUGen" [i,j] [_] (Special 0) NoId)] [_] _ NoId) ->
+      Primitive_U (Primitive r "Sum3" [i,j,k] [r] (Special 0) NoId)
+    _ -> u
+
+-- | 'sum3_optimise_direct' of 'mul_add_optimise_direct'.
+add_optimise_direct :: UGen -> UGen
+add_optimise_direct = sum3_optimise_direct . mul_add_optimise_direct
+
 -- | Unit generators are numbers.
 instance Num UGen where
     negate = mkUnaryOperator Neg negate
-    (+) = mkBinaryOperator_optimize Add (+) (`elem` [Left 0,Right 0])
-    (-) = mkBinaryOperator_optimize Sub (-) (Right 0 ==)
-    (*) = mkBinaryOperator_optimize Mul (*) (`elem` [Left 1,Right 1])
+    (+) = fmap add_optimise_direct .
+          mkBinaryOperator_optimize_constants Add (+) (`elem` [Left 0,Right 0])
+    (-) = mkBinaryOperator_optimize_constants Sub (-) (Right 0 ==)
+    (*) = mkBinaryOperator_optimize_constants Mul (*) (`elem` [Left 1,Right 1])
     abs = mkUnaryOperator Abs abs
     signum = mkUnaryOperator Sign signum
     fromInteger = Constant_U . Constant . fromInteger
@@ -389,7 +419,7 @@
 -- | Unit generators are fractional.
 instance Fractional UGen where
     recip = mkUnaryOperator Recip recip
-    (/) = mkBinaryOperator_optimize FDiv (/) (Right 1 ==)
+    (/) = mkBinaryOperator_optimize_constants FDiv (/) (Right 1 ==)
     fromRational = Constant_U . Constant . fromRational
 
 -- | Unit generators are floating point.
@@ -398,7 +428,7 @@
     exp = mkUnaryOperator Exp exp
     log = mkUnaryOperator Log log
     sqrt = mkUnaryOperator Sqrt sqrt
-    (**) = mkBinaryOperator_optimize Pow (**) (Right 1 ==)
+    (**) = mkBinaryOperator_optimize_constants Pow (**) (Right 1 ==)
     logBase a b = log b / log a
     sin = mkUnaryOperator Sin sin
     cos = mkUnaryOperator Cos cos
@@ -485,16 +515,3 @@
     popCount = error "UGen.popCount"
     bitSizeMaybe = error "UGen.bitSizeMaybe"
     isSigned _ = True
-
-{-
-import Sound.SC3.UGen.Identifier
-
--- * UGen ID Instance
-
--- | Hash function for unit generators.
-hashUGen :: UGen -> Int
-hashUGen = hash . show
-
-instance ID UGen where
-    resolveID = hashUGen
--}
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
@@ -6,15 +6,15 @@
 import Data.List {- base -}
 
 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.Common.Base as B
+import qualified Sound.SC3.Common.UId as UId
 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.ID a => a -> UGenId
-toUId = UId . ID.resolveID
+toUId :: UId.ID a => a -> UGenId
+toUId = UId . UId.resolveID
 
 -- | Lookup operator name for operator UGens, else UGen name.
 ugen_user_name :: String -> Special -> String
@@ -112,12 +112,9 @@
       [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
+unmce2 = B.t2_from_list . mceChannels
 
 -- | Multiple channel expansion for two inputs.
 mce3 :: UGen -> UGen -> UGen -> UGen
@@ -164,17 +161,25 @@
 -- * Transform
 
 -- | 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?") (P.sep_last l)
+halt_mce_transform_f :: (a -> [a]) -> [a] -> [a]
+halt_mce_transform_f f l =
+    let (l',e) = fromMaybe (error "halt_mce_transform: null?") (B.sep_last l)
     in l' ++ f e
 
 -- | The halt MCE transform, ie. lift channels of last input into list.
 --
 -- > halt_mce_transform [1,2,mce2 3 4] == [1,2,3,4]
 halt_mce_transform :: [UGen] -> [UGen]
-halt_mce_transform = halt_mce_transform' mceChannels
+halt_mce_transform = halt_mce_transform_f mceChannels
 
+-- | If the root node of a UGen graph is /mce/, transform to /mrg/.
+prepare_root :: UGen -> UGen
+prepare_root u =
+    case u of
+      MCE_U m -> mrg (mceProxies m)
+      MRG_U m -> mrg2 (prepare_root (mrgLeft m)) (prepare_root (mrgRight m))
+      _ -> u
+
 -- * Multiple root graphs
 
 -- * Labels
@@ -198,43 +203,59 @@
           in n : s'
       MCE_U m ->
           let x = map unpackLabel (mceProxies m)
-          in if P.equal_length_p x
+          in if B.equal_length_p x
              then map mce (transpose x)
              else error (show ("unpackLabel: mce length /=",x))
       _ -> error (show ("unpackLabel: non-label",u))
 
 -- * Envelope
 
+-- | 'mce' of 'E.envelope_sc3_array'.
 envelope_to_ugen :: E.Envelope UGen -> UGen
 envelope_to_ugen =
     let err = error "envGen: bad Envelope"
     in mce . fromMaybe err . E.envelope_sc3_array
 
+-- | 'mce' of 'E.envelope_sc3_ienvgen_array'.
+envelope_to_ienvgen_ugen :: E.Envelope UGen -> UGen
+envelope_to_ienvgen_ugen =
+    let err = error "envGen: bad Envelope"
+    in mce . fromMaybe err . E.envelope_sc3_ienvgen_array
+
 -- * Bitwise
 
+-- | 'O.BitAnd'
 bitAnd :: UGen -> UGen -> UGen
 bitAnd = mkBinaryOperator O.BitAnd undefined
 
+-- | 'O.BitOr'
 bitOr :: UGen -> UGen -> UGen
 bitOr = mkBinaryOperator O.BitOr undefined
 
+-- | 'O.BitXor'
 bitXOr :: UGen -> UGen -> UGen
 bitXOr = mkBinaryOperator O.BitXor undefined
 
+-- | 'O.BitNot'
 bitNot :: UGen -> UGen
 bitNot = mkUnaryOperator O.BitNot undefined
 
+-- | 'O.ShiftLeft'
 shiftLeft :: UGen -> UGen -> UGen
 shiftLeft = mkBinaryOperator O.ShiftLeft undefined
 
+-- | 'O.ShiftRight'
 shiftRight :: UGen -> UGen -> UGen
 shiftRight = mkBinaryOperator O.ShiftRight undefined
 
+-- | 'O.UnsignedShift'
 unsignedShift :: UGen -> UGen -> UGen
 unsignedShift = mkBinaryOperator O.UnsignedShift undefined
 
+-- | 'shiftLeft' operator.
 (.<<.) :: UGen -> UGen -> UGen
 (.<<.) = shiftLeft
 
+-- | 'shiftRight' operator.
 (.>>.) :: UGen -> UGen -> UGen
 (.>>.) = shiftRight
diff --git a/Sound/SC3/UGen/UId.hs b/Sound/SC3/UGen/UId.hs
deleted file mode 100644
--- a/Sound/SC3/UGen/UId.hs
+++ /dev/null
@@ -1,95 +0,0 @@
-{-# 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.Monad {- base -}
-import Data.Functor.Identity {- base -}
-import Data.List {- base -}
-import qualified Data.Unique as U {- base -}
-
-import qualified Control.Monad.Trans.Reader as R {- transformers -}
-import qualified Control.Monad.Trans.State as S {- transformers -}
-
-import Sound.SC3.UGen.Type {- hsc3 -}
-
--- | 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
-
--- | '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 U.hashUnique U.newUnique
-
-instance UId m => UId (R.ReaderT t m) where
-   generateUId = R.ReaderT (const generateUId)
-
--- * Lift
-
--- | Unary function.
-type Fn1 a b = a -> b
-
--- | Binary function.
-type Fn2 a b c = a -> b -> c
-
--- | Ternary function.
-type Fn3 a b c d = a -> b -> c -> d
-
--- | Quaternary function.
-type Fn4 a b c d e = a -> b -> c -> d -> e
-
--- | Unary UId lift.
-liftUId :: UId m => (Int -> Fn1 a b) -> Fn1 a (m b)
-liftUId f a = do
-  n <- generateUId
-  return (f n a)
-
--- | Binary UId lift.
-liftUId2 :: UId m => (Int -> Fn2 a b c) -> Fn2 a b (m c)
-liftUId2 f a b = do
-  n <- generateUId
-  return (f n a b)
-
--- | Ternary UId lift.
-liftUId3 :: UId m => (Int -> Fn3 a b c d) -> Fn3 a b c (m d)
-liftUId3 f a b c = do
-  n <- generateUId
-  return (f n a b c)
-
--- | Quaternary UId lift.
-liftUId4 :: UId m => (Int -> Fn4 a b c d e) -> Fn4 a b c d (m e)
-liftUId4 f a b c d = do
-  n <- generateUId
-  return (f n a b c d)
-
--- * Clone
-
--- | Clone a unit generator (mce . replicateM).
-clone :: (UId m) => Int -> m UGen -> m UGen
-clone n = liftM mce . replicateM n
diff --git a/emacs/hsc3.el b/emacs/hsc3.el
--- a/emacs/hsc3.el
+++ b/emacs/hsc3.el
@@ -7,7 +7,7 @@
 (require 'comint)
 (require 'thingatpt)
 (require 'find-lisp)
-(require 'inf-haskell)
+(require 'inf-haskell) ;; debian=haskell-mode
 
 (defvar hsc3-help-directory
   nil
@@ -64,7 +64,7 @@
   (interactive)
   (hsc3-send-string
    (format
-    "Sound.SC3.viewSC3Help (Sound.SC3.toSC3Name \"%s\")"
+    "Sound.SC3.viewSC3Help (Sound.SC3.UGen.DB.ugenSC3Name \"%s\")"
     (thing-at-point 'symbol))))
 
 (defun hsc3-sc3-server-help ()
@@ -162,7 +162,7 @@
   (interactive)
   (if (and (executable-find "hasktags") (file-exists-p "hsc3.cabal"))
       (call-process-shell-command
-       "find Sound . -name '*.*hs' | xargs hasktags -e"
+       "find Sound . -name '*.hs' | xargs hasktags -e"
        nil
        nil)
     (error "no hasktags binary or not at hsc3 directory?")))
@@ -179,12 +179,24 @@
   (hsc3-send-string
    (concat "Sound.SC3.audition =<<" (thing-at-point 'symbol))))
 
+(defun hsc3-audition-pattern ()
+  "Audition the pattern at point."
+  (interactive)
+  (hsc3-send-string
+   (concat "Sound.SC3.Lang.Pattern.paudition " (thing-at-point 'symbol))))
+
 (defun hsc3-draw-graph ()
   "Draw the UGen graph at point."
   (interactive)
   (hsc3-send-string
    (concat "Sound.SC3.UGen.Dot.draw " (thing-at-point 'symbol))))
 
+(defun hsc3-draw-graph-plain ()
+  "Draw the UGen graph at point (plain)."
+  (interactive)
+  (hsc3-send-string
+   (concat "Sound.SC3.UGen.Dot.draw_plain " (thing-at-point 'symbol))))
+
 (defun hsc3-draw-graph-m ()
   "Draw the (monadic) UGen graph at point."
   (interactive)
@@ -221,7 +233,9 @@
   (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)
-  (define-key map [?\C-c ?\C-g] 'hsc3-draw-graph)
+  (define-key map (kbd "C-c p") 'hsc3-audition-pattern)
+  (define-key map (kbd "C-c C-g") 'hsc3-draw-graph)
+  (define-key map (kbd "C-c C-S-g") 'hsc3-draw-graph-plain)
   (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)
diff --git a/hsc3.cabal b/hsc3.cabal
--- a/hsc3.cabal
+++ b/hsc3.cabal
@@ -1,19 +1,19 @@
 Name:              hsc3
-Version:           0.16
+Version:           0.17
 Synopsis:          Haskell SuperCollider
 Description:       Haskell client for the SuperCollider synthesis server,
                    <http://audiosynth.com/>.
                    .
                    For installation and configuration see the Tutorial at
-                   <http://rd.slavepianos.org/t/hsc3-texts>.
-License:           GPL
+                   <http://rohandrape.net/t/hsc3-texts>.
+License:           GPL-3
 Category:          Sound
-Copyright:         (c) Rohan Drape and others, 2005-2017
+Copyright:         (c) Rohan Drape and others, 2005-2018
 Author:            Rohan Drape
-Maintainer:        rd@slavepianos.org
+Maintainer:        rd@rohandrape.net
 Stability:         Experimental
-Homepage:          http://rd.slavepianos.org/t/hsc3
-Tested-With:       GHC == 8.0.1
+Homepage:          http://rohandrape.net/t/hsc3
+Tested-With:       GHC == 8.4.3
 Build-Type:        Simple
 Cabal-Version:     >= 1.8
 
@@ -29,12 +29,11 @@
                    binary,
                    bytestring,
                    containers,
-                   data-default,
                    data-ordlist,
                    directory,
                    filepath,
-                   hashable,
-                   hosc == 0.16.*,
+                   hosc == 0.17.*,
+                   murmur-hash,
                    network,
                    process,
                    random,
@@ -45,17 +44,20 @@
   GHC-Options:     -Wall -fwarn-tabs
   Exposed-modules: Sound.SC3
                    Sound.SC3.Common
+                   Sound.SC3.Common.Base
                    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.Filter
+                   Sound.SC3.Common.Math.Filter.BEQ
                    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.Common.UId
                    Sound.SC3.FD
                    Sound.SC3.Server
                    Sound.SC3.Server.Command
@@ -82,28 +84,15 @@
                    Sound.SC3.UGen.Bindings
                    Sound.SC3.UGen.Bindings.Composite
                    Sound.SC3.UGen.Bindings.DB
+                   Sound.SC3.UGen.Bindings.DB.External
                    Sound.SC3.UGen.Bindings.HW
                    Sound.SC3.UGen.Bindings.Monad
-                   --Sound.SC3.UGen.Bindings.HW.Analysis
-                   --Sound.SC3.UGen.Bindings.HW.Buffer
-                   --Sound.SC3.UGen.Bindings.HW.Chaos
                    Sound.SC3.UGen.Bindings.HW.Construct
-                   --Sound.SC3.UGen.Bindings.HW.Demand
-                   --Sound.SC3.UGen.Bindings.HW.DiskIO
                    Sound.SC3.UGen.Bindings.HW.External
                    Sound.SC3.UGen.Bindings.HW.External.F0
                    Sound.SC3.UGen.Bindings.HW.External.SC3_Plugins
                    Sound.SC3.UGen.Bindings.HW.External.Wavelets
                    Sound.SC3.UGen.Bindings.HW.External.Zita
-                   --Sound.SC3.UGen.Bindings.HW.FFT
-                   --Sound.SC3.UGen.Bindings.HW.Filter
-                   --Sound.SC3.UGen.Bindings.HW.Granular
-                   --Sound.SC3.UGen.Bindings.HW.IO
-                   --Sound.SC3.UGen.Bindings.HW.Information
-                   --Sound.SC3.UGen.Bindings.HW.MachineListening
-                   --Sound.SC3.UGen.Bindings.HW.Noise
-                   --Sound.SC3.UGen.Bindings.HW.Oscillator
-                   --Sound.SC3.UGen.Bindings.HW.Panner
                    Sound.SC3.UGen.Enum
                    Sound.SC3.UGen.Envelope
                    Sound.SC3.UGen.Graph
@@ -112,7 +101,6 @@
                    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
@@ -125,8 +113,7 @@
                    Sound.SC3.UGen.Rate
                    Sound.SC3.UGen.Type
                    Sound.SC3.UGen.UGen
-                   Sound.SC3.UGen.UId
 
 Source-Repository  head
-  Type:            darcs
-  Location:        http://rd.slavepianos.org/sw/hsc3/
+  Type:            git
+  Location:        https://github.com/rd--/hsc3.git
