[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-dev] SF.net SVN: quarks:[2529] Feedback



Revision: 2529
          http://quarks.svn.sourceforge.net/quarks/?rev=2529&view=rev
Author:   nathanielvirgo
Date:     2013-01-03 06:51:17 +0000 (Thu, 03 Jan 2013)
Log Message:
-----------
added new classes FbK and FbNode, and some new help files

Modified Paths:
--------------
    Feedback/Fb.html
    Feedback/Fb.sc

Added Paths:
-----------
    Feedback/FbK.html
    Feedback/FbNode.html
    Feedback/Feedback.html

Modified: Feedback/Fb.html
===================================================================
--- Feedback/Fb.html	2012-12-30 13:54:54 UTC (rev 2528)
+++ Feedback/Fb.html	2013-01-03 06:51:17 UTC (rev 2529)
@@ -5,7 +5,7 @@
 <meta http-equiv="Content-Style-Type" content="text/css">
 <title></title>
 <meta name="Generator" content="Cocoa HTML Writer">
-<meta name="CocoaVersion" content="949.54">
+<meta name="CocoaVersion" content="1038.36">
 <style type="text/css">
 p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
 p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
@@ -16,16 +16,17 @@
 p.p7 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica; min-height: 14.0px}
 p.p8 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 12.0px Helvetica}
 p.p9 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica}
-p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #a53317}
-p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #606060}
+p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #e10000}
+p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #797979}
 p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
-p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #a8220e}
-p.p14 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #a8220e; min-height: 12.0px}
 span.s1 {font: 18.0px Helvetica}
 span.s2 {color: #001af9}
-span.s3 {color: #001cbb}
-span.s4 {color: #000000}
-span.s5 {color: #0013bb}
+span.s3 {color: #3200ff}
+span.s4 {color: #001cbb}
+span.s5 {color: #000000}
+span.s6 {color: #2500cf}
+span.s7 {color: #be00ac}
+span.s8 {text-decoration: underline ; color: #0000ee}
 span.Apple-tab-span {white-space:pre}
 </style>
 </head>
@@ -34,11 +35,13 @@
 <p class="p2"><br></p>
 <p class="p1"><b>Inherits from: Object</b></p>
 <p class="p3"><br></p>
-<p class="p1">There are many ways to create feedback loops in SuperCollider.<span class="Apple-converted-space">  </span>Fb is a convenience class that allows you to create them in as painless a way as possible.<span class="Apple-converted-space">  </span>It achieves this by using <a href="SC://LocalBuf"><span class="s2">LocalBuf</span></a> internally.<span class="Apple-converted-space">  </span>The easiest way to understand it is probably to skip to the examples section.</p>
+<p class="p1">There are many ways to create feedback loops in SuperCollider.<span class="Apple-converted-space">  </span>Fb is a convenience class that allows you to create them in as painless a way as possible.<span class="Apple-converted-space">  </span>It achieves this by using <a href="sc://LocalBuf"><span class="s2">LocalBuf</span></a> internally.<span class="Apple-converted-space">  </span>The easiest way to understand it is probably to skip to the examples section. Fb is part of the Feedback quark.</p>
 <p class="p2"><br></p>
+<p class="p1">In addition to Fb, the Feedback quark provides <a href="FbNode.html"><span class="s3">FbNode</span></a>, which is a different way of doing the same thing. FbNode is more flexible and arguably more intuitive than Fb. See its help file for a comparison between the two classes.<span class="Apple-converted-space">  </span>There is also <a href="FbK.html"><span class="s3">FbK</span></a>, which is like Fb but for control-rate (kr) signals.</p>
+<p class="p2"><br></p>
 <p class="p1">Ways of creating feedback loops in SuperCollider can be divided into two types: those that use busses to route signals between SynthDefs, and those that create a feedback loop within a SynthDef.<span class="Apple-converted-space">  </span>Fb is of the latter type.</p>
 <p class="p2"><br></p>
-<p class="p1">The traditional way to create feedback within a SynthDef is to use <a href="SC://LocalIn"><span class="s2">LocalIn</span></a>/<a href="SC://LocalOut"><span class="s2">LocalOut</span></a>.<span class="Apple-converted-space">  </span>Fb has several advantages over this:</p>
+<p class="p1">The traditional way to create feedback within a SynthDef is to use <a href="sc://LocalIn"><span class="s2">LocalIn</span></a>/<a href="sc://LocalOut"><span class="s2">LocalOut</span></a>.<span class="Apple-converted-space">  </span>Fb has several advantages over this:</p>
 <p class="p2"><br></p>
 <p class="p1"><span class="Apple-converted-space"> </span>* You can have more than one instance of Fb in a single SynthDef -- either sequentially or nested inside each other -- allowing greater readability of code and more complex networks of feedback loops than would be practical with LocalIn/LocalOut.</p>
 <p class="p2"><span class="Apple-converted-space"> </span></p>
@@ -46,84 +49,84 @@
 <p class="p2"><span class="Apple-converted-space"> </span></p>
 <p class="p1"><span class="Apple-converted-space"> </span>* Fb will not crash the server if you send it the wrong number of channels</p>
 <p class="p2"><br></p>
-<p class="p1">Fb has a built-in delay line, so you can control the time period of the feedback loop.<span class="Apple-converted-space">  </span>As with (almost) all methods of achieving feedback in SuperCollider, the minimum delay is given by the server's block size, which is usually 64 samples.<span class="Apple-converted-space">  </span>Fb's inbuilt delay line does not interpolate (i.e. it uses <a href="SC://DelayN"><span class="s2">DelayN</span></a>), but its sister classes <a href="SC://FbL"><span class="s3">FbL</span></a> and <a href="SC://FbC"><span class="s3">FbC</span></a> use linear and cubic interpolation.</p>
+<p class="p1">Fb has a built-in delay line, so you can control the time period of the feedback loop.<span class="Apple-converted-space">  </span>As with (almost) all methods of achieving feedback in SuperCollider, the minimum delay is given by the server's block size, which is usually 64 samples.<span class="Apple-converted-space">  </span>Fb's inbuilt delay line does not interpolate (i.e. it uses <a href="sc://DelayN"><span class="s2">DelayN</span></a>), but its sister classes <a href="sc://FbL"><span class="s4">FbL</span></a> and <a href="sc://FbC"><span class="s4">FbC</span></a> use linear and cubic interpolation.</p>
 <p class="p2"><br></p>
 <p class="p2"><br></p>
-<p class="p1"><b>See also:</b> <a href="SC://FbL"><span class="s3">FbL</span></a>, <a href="SC://FbC"><span class="s3">FbC</span></a>, <a href="SC://LocalIn"><span class="s2">LocalIn</span></a>, <a href="SC://InFeedback"><span class="s2">InFeedback</span></a>, <a href="SC://NodeProxy"><span class="s2">NodeProxy</span></a>, <a href="SC://LocalBuf"><span class="s2">LocalBuf</span></a>, and also the single sample feedback file in the Examples folder that comes with SC.</p>
+<p class="p1"><b>See also: </b><a href="FbNode.html"><span class="s3">FbNode</span></a>, <a href="sc://FbL"><span class="s4">FbL</span></a>, <a href="sc://FbC"><span class="s4">FbC</span></a>, <a href="sc://LocalIn"><span class="s2">LocalIn</span></a>, <a href="sc://InFeedback"><span class="s2">InFeedback</span></a>, <a href="sc://NodeProxy"><span class="s2">NodeProxy</span></a>, <a href="sc://LocalBuf"><span class="s2">LocalBuf</span></a>, and also the single sample feedback file in the Examples folder that comes with SC.</p>
 <p class="p2"><br></p>
 <p class="p4"><b>Creation / Class Methods</b></p>
 <p class="p5"><br></p>
-<p class="p6"><b><span class="Apple-tab-span">	</span>*new (func, maxdelaytime, delaytime, channels)</b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>*new (func, maxdelaytime, delaytime, numChannels)</b></p>
 <p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
 <p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b>Create a feedback loop within a SynthDef</p>
 <p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>func </b>- This function should contain the UGens that will be inside the feedback loop.<span class="Apple-converted-space">  </span>Its output is delayed and then fed into its input.</p>
-<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>maxdelaytime </b>- the maximum delay time in seconds. used to initialize the delay buffer size.<span class="Apple-converted-space">  </span>You do not need to subtract <a href="SC://ControlDur"><span class="s2">ControlDur</span></a>.ir from this, as it is done automatically.<span class="Apple-converted-space">  </span>If you set it to less than<span class="Apple-converted-space">  </span><a href="SC://ControlDur"><span class="s2">ControlDur</span></a>.ir (i.e. less than 64/44100 ≈ 0.014s) then no extra delay line will be added.</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>maxdelaytime </b>- the maximum delay time in seconds. used to initialize the delay buffer size.<span class="Apple-converted-space">  </span>You do not need to subtract <a href="sc://ControlDur"><span class="s2">ControlDur</span></a>.ir from this, as it is done automatically.<span class="Apple-converted-space">  </span>If you set it to less than<span class="Apple-converted-space">  </span><a href="sc://ControlDur"><span class="s2">ControlDur</span></a>.ir (i.e. less than 64/44100 ≈ 0.014s) then no extra delay line will be added.</p>
 <p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>delaytime </b>- delay time in seconds.<span class="Apple-converted-space">  </span>If not set, this defaults to <b>maxdelaytime</b>.</p>
-<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>channels </b>- How many channels of audio to be fed back.<span class="Apple-converted-space">  </span>If this is not set, Fb will make a guess by sending <b>func</b> a mono signal and seeing how many channels it returns.<span class="Apple-converted-space">  </span>This is a good guess in a lot of cases, but if you're doing something complicated with lots of multichannel expansion it's worth setting this expicitly.</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>numChannels </b>- How many channels of audio to be fed back.<span class="Apple-converted-space">  </span>If this is not set, Fb will make a guess by sending <b>func</b> a mono signal and seeing how many channels it returns.<span class="Apple-converted-space">  </span>This is a good guess in a lot of cases, but if you're doing something complicated with lots of multichannel expansion it's worth setting this expicitly.</p>
 <p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
 <p class="p9"><b>Examples</b></p>
 <p class="p3"><br></p>
-<p class="p8">Note that some of these examples use <a href="SC://FbL"><span class="s3">FbL</span></a> for linear interpolation.</p>
+<p class="p8">Note that some of these examples use <a href="sc://FbL"><span class="s4">FbL</span></a> for linear interpolation.</p>
 <p class="p3"><br></p>
 <p class="p10">// simple dub delay effect</p>
 <p class="p3"><br></p>
-<p class="p11"><span class="s4">b = </span><span class="s5">Buffer</span><span class="s4">.read(s,</span>"sounds/a11wlk01.wav"<span class="s4">)</span></p>
+<p class="p11"><span class="s5">b = </span><span class="s6">Buffer</span><span class="s5">.read(s,</span>"sounds/a11wlk01.wav"<span class="s5">)</span></p>
 <p class="p3"><br></p>
 <p class="p12">(</p>
 <p class="p12">{</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="s5">var</span> in = <span class="s5">PlayBuf</span>.ar(1,b);</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="s5">var</span> out = in + <span class="s5">Fb</span>({</p>
-<p class="p13"><span class="s4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span><span class="s5">arg</span><span class="s4"> feedback; </span>// this will contain the delayed output from the Fb unit</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="s6">var</span> in = <span class="s6">PlayBuf</span>.ar(<span class="s7">1</span>,b);</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="s6">var</span> out = in + <span class="s6">Fb</span>({</p>
+<p class="p10"><span class="s5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span><span class="s6">arg</span><span class="s5"> feedback; </span>// this will contain the delayed output from the Fb unit</p>
 <p class="p3"><br></p>
-<p class="p13"><span class="s4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// filter and distort the feedback signal. <span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="s4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// Note that the input signal is fed in here as well:</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">BPF</span>.ar(feedback*0.8 + in, 2000, 3.8).distort;</p>
-<p class="p13"><span class="s4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// for fun effects, try changing the 0.8 to something greater than one</p>
-<p class="p14"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
-<p class="p12"><span class="Apple-tab-span">	</span>},0.6);</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="s5">DetectSilence</span>.ar(out,doneAction:2);</p>
-<p class="p12"><span class="Apple-tab-span">	</span>out!2;</p>
+<p class="p10"><span class="s5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// filter and distort the feedback signal. <span class="Apple-converted-space"> </span></p>
+<p class="p10"><span class="s5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// Note that the input signal is fed in here as well:</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s6">BPF</span>.ar(feedback*<span class="s7">0.8 </span>+ in, <span class="s7">2000</span>, <span class="s7">3.8</span>).distort;</p>
+<p class="p10"><span class="s5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// for fun effects, try changing the 0.8 to something greater than one</p>
+<p class="p3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p12"><span class="Apple-tab-span">	</span>},<span class="s7">0.6</span>);</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="s6">DetectSilence</span>.ar(out,doneAction:<span class="s7">2</span>);</p>
+<p class="p12"><span class="Apple-tab-span">	</span>out!<span class="s7">2</span>;</p>
 <p class="p12">}.play;</p>
 <p class="p12">)</p>
 <p class="p3"><br></p>
 <p class="p12">b.free</p>
 <p class="p3"><br></p>
-<p class="p13">// Karplus-Strong style plucked string algorithm (see also <a href="SC://Pluck"><span class="s2">Pluck</span></a>)</p>
+<p class="p10">// Karplus-Strong style plucked string algorithm (see also <a href="sc://Pluck"><span class="s8">Pluck</span></a>)</p>
 <p class="p12">(</p>
 <p class="p12">{</p>
-<p class="p13"><span class="s4"><span class="Apple-tab-span">	</span></span><span class="s5">var</span><span class="s4"> sig = </span><span class="s5">Impulse</span><span class="s4">.ar(0)!2; </span>// stereo input - feedback will expand to two channels <span class="s4"><span class="Apple-converted-space"> </span></span></p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="s5">var</span> freq = 200;</p>
-<p class="p12"><span class="Apple-tab-span">	</span>sig = <span class="s5">FbL</span>({<span class="s5">arg</span> fb; <span class="s5">LPF</span>.ar(<span class="s5">LeakDC</span>.ar(fb),8000)*0.99+sig;},1/freq);</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="s5">DetectSilence</span>.ar(sig,doneAction:2);</p>
+<p class="p10"><span class="s5"><span class="Apple-tab-span">	</span></span><span class="s6">var</span><span class="s5"> sig = </span><span class="s6">Impulse</span><span class="s5">.ar(</span><span class="s7">0</span><span class="s5">)!</span><span class="s7">2</span><span class="s5">; </span>// stereo input - feedback will expand to two channels <span class="Apple-converted-space"> </span></p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="s6">var</span> freq = <span class="s7">200</span>;</p>
+<p class="p12"><span class="Apple-tab-span">	</span>sig = <span class="s6">FbL</span>({<span class="s6">arg</span> fb; <span class="s6">LPF</span>.ar(<span class="s6">LeakDC</span>.ar(fb),<span class="s7">8000</span>)*<span class="s7">0.99</span>+sig;},<span class="s7">1</span>/freq);</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="s6">DetectSilence</span>.ar(sig,doneAction:<span class="s7">2</span>);</p>
 <p class="p12"><span class="Apple-tab-span">	</span>sig;</p>
 <p class="p12">}.play</p>
 <p class="p12">)</p>
 <p class="p3"><br></p>
-<p class="p13">// Multiple instances in one SynthDef: three Karplus-Strong style algorithms in a row</p>
+<p class="p10">// Multiple instances in one SynthDef: three Karplus-Strong style algorithms in a row</p>
 <p class="p12">(</p>
 <p class="p12">{</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="s5">var</span> sig = <span class="s5">Impulse</span>.ar(0);</p>
-<p class="p12"><span class="Apple-tab-span">	</span>sig = <span class="s5">FbL</span>({<span class="s5">arg</span> fb; <span class="s5">LPF</span>.ar(<span class="s5">LeakDC</span>.ar(fb),8000)*0.99+sig;},1/300);</p>
-<p class="p12"><span class="Apple-tab-span">	</span>sig = <span class="s5">FbL</span>({<span class="s5">arg</span> fb; <span class="s5">LPF</span>.ar(<span class="s5">LeakDC</span>.ar(fb),8000)*0.99+sig;},1/400);</p>
-<p class="p12"><span class="Apple-tab-span">	</span>sig = <span class="s5">FbL</span>({<span class="s5">arg</span> fb; <span class="s5">LPF</span>.ar(<span class="s5">LeakDC</span>.ar(fb),8000)*0.99+sig;},1/500);</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="s5">DetectSilence</span>.ar(sig,doneAction:2);</p>
-<p class="p12"><span class="Apple-tab-span">	</span>sig!2;</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="s6">var</span> sig = <span class="s6">Impulse</span>.ar(<span class="s7">0</span>);</p>
+<p class="p12"><span class="Apple-tab-span">	</span>sig = <span class="s6">FbL</span>({<span class="s6">arg</span> fb; <span class="s6">LPF</span>.ar(<span class="s6">LeakDC</span>.ar(fb),<span class="s7">8000</span>)*<span class="s7">0.99</span>+sig;},<span class="s7">1</span>/<span class="s7">300</span>);</p>
+<p class="p12"><span class="Apple-tab-span">	</span>sig = <span class="s6">FbL</span>({<span class="s6">arg</span> fb; <span class="s6">LPF</span>.ar(<span class="s6">LeakDC</span>.ar(fb),<span class="s7">8000</span>)*<span class="s7">0.99</span>+sig;},<span class="s7">1</span>/<span class="s7">400</span>);</p>
+<p class="p12"><span class="Apple-tab-span">	</span>sig = <span class="s6">FbL</span>({<span class="s6">arg</span> fb; <span class="s6">LPF</span>.ar(<span class="s6">LeakDC</span>.ar(fb),<span class="s7">8000</span>)*<span class="s7">0.99</span>+sig;},<span class="s7">1</span>/<span class="s7">500</span>);</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="s6">DetectSilence</span>.ar(sig,doneAction:<span class="s7">2</span>);</p>
+<p class="p12"><span class="Apple-tab-span">	</span>sig!<span class="s7">2</span>;</p>
 <p class="p12">}.play</p>
 <p class="p12">)</p>
 <p class="p3"><br></p>
-<p class="p13">// You can nest feedback loops inside each other</p>
+<p class="p10">// You can nest feedback loops inside each other</p>
 <p class="p12">(</p>
 <p class="p12">{</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="s5">var</span> sig = <span class="s5">Decay</span>.kr(<span class="s5">Impulse</span>.kr(1/2),0.6)*<span class="s5">PinkNoise</span>.ar(1!2);</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="s6">var</span> sig = <span class="s6">Decay</span>.kr(<span class="s6">Impulse</span>.kr(<span class="s7">1</span>/<span class="s7">2</span>),<span class="s7">0.6</span>)*<span class="s6">PinkNoise</span>.ar(<span class="s7">1</span>!<span class="s7">2</span>);</p>
 <p class="p3"><span class="Apple-tab-span">	</span></p>
-<p class="p12"><span class="Apple-tab-span">	</span>sig = <span class="s5">FbL</span>({</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">arg</span> fb1;</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>sig = sig + <span class="s5">FbL</span>({</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">arg</span> fb2;</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>(<span class="s5">OnePole</span>.ar(<span class="s5">LeakDC</span>.ar(0-fb2),0.2)*0.99*1)+(fb1*9) / 10;</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>},1/250);</p>
-<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">OnePole</span>.ar(sig,-0.01);</p>
-<p class="p12"><span class="Apple-tab-span">	</span>},0.1);</p>
+<p class="p12"><span class="Apple-tab-span">	</span>sig = <span class="s6">FbL</span>({</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s6">arg</span> fb1;</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>sig = sig + <span class="s6">FbL</span>({</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s6">arg</span> fb2;</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>(<span class="s6">OnePole</span>.ar(<span class="s6">LeakDC</span>.ar(<span class="s7">0</span>-fb2),<span class="s7">0.2</span>)*<span class="s7">0.99</span>*<span class="s7">1</span>)+(fb1*<span class="s7">9</span>) / <span class="s7">10</span>;</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>},<span class="s7">1</span>/<span class="s7">250</span>);</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s6">OnePole</span>.ar(sig,<span class="s7">-0.01</span>);</p>
+<p class="p12"><span class="Apple-tab-span">	</span>},<span class="s7">0.1</span>);</p>
 <p class="p3"><span class="Apple-tab-span">	</span></p>
 <p class="p12"><span class="Apple-tab-span">	</span>sig;</p>
 <p class="p12">}.play;</p>

Modified: Feedback/Fb.sc
===================================================================
--- Feedback/Fb.sc	2012-12-30 13:54:54 UTC (rev 2528)
+++ Feedback/Fb.sc	2013-01-03 06:51:17 UTC (rev 2529)
@@ -3,7 +3,8 @@
 
 	*delayUGen { ^DelayN }
 
-	*new { arg func, maxdelaytime, delaytime=maxdelaytime, numChannels;
+	*new { 
+		arg func, maxdelaytime, delaytime=maxdelaytime, numChannels;
 		var buf, phase, frames, sig, adddelay;
 		if (maxdelaytime.isNil) {
 			adddelay = false;
@@ -13,7 +14,7 @@
 			delaytime = delaytime - ControlDur.ir;
 		};
 		
-		numChannels = numChannels ?? { func.value(Silent.ar(1)).asArray.size };
+		numChannels = numChannels ?? { func.value([Silent.ar(1)]).asArray.size };
 		numChannels = numChannels max: maxdelaytime.asArray.size max: delaytime.asArray.size;
 		
 		frames = ControlDur.ir*SampleRate.ir;
@@ -31,34 +32,127 @@
 
 FbC : Fb {*delayUGen{^DelayC}}
 
-Fb1 : UGen {
-
-	*new { arg func, maxdelaytime, delaytime = maxdelaytime, numChannels;
-		var buffers, in, out, write;
-		var maxdelaysamples, delaysamples, readoffset, writeoffset;
-		var sr = SampleRate.ir;
+FbK : UGen {
+	
+	*new { 
+		arg func, initVals;
+		var buf, sig, numChannels;
 		
-		if (maxdelaytime.isNil) {
-			maxdelaysamples = 1;
-			delaysamples = 0;
-			readoffset = 0;
-			writeoffset = 0;
+		if (initVals.notNil) {
+			numChannels = initVals.size;
+			buf = LocalBuf(1, numChannels);
+			buf.set([initVals]);
 		} {
-			maxdelaysamples = sr * maxdelaytime - 1;
-			delaysamples = { sr * delaytime.value - 1 };
-			readoffset = { Dseries(0, 1, inf) % maxdelaysamples };
-			writeoffset =  { Dseries(0, 1, inf) + delaysamples.value % maxdelaysamples };
+			numChannels =  func.value([Silent.kr(1)]).asArray.size;
+			buf = LocalBuf(1, numChannels).clear
 		};
+
+		sig = func.value(BufRd.kr(numChannels, buf, 0));
+		BufWr.kr(sig, buf, 0);
+		^sig;
+	}
+}
+
+
+FbNode : UGen {
+	classvar currentSynthDef;
+	classvar phasors;
+
+	var buf, frames, output, phase;
+	var <numChannels;
+	var <interpolation;
+	var <maxDelayTime;
+	var <input;
 	
-		numChannels = numChannels ?? { func.value(Silent.ar(1)).asArray.size };
-		numChannels = numChannels max: maxdelaytime.asArray.size max: delaytime.asArray.size;
+	*new {
+		arg numChannels=1, maxdelaytime, interpolation=2;
+		^super.new.init(numChannels, maxdelaytime, interpolation);
+	}
+
+	init {
+		arg in_numChannels, in_maxDelayTime, in_interpolation;
+		var blockSize = Server.default.options.blockSize;
+		var sampleRate = Server.default.sampleRate;
+		numChannels = in_numChannels;
+		maxDelayTime = in_maxDelayTime;
+		interpolation = in_interpolation;
+
+		if (sampleRate.isNil) {
+			Error("FbNode cannot determine sample rate. (Try booting the server.)").throw;
+		};
+
+		if (UGen.buildSynthDef.isNil) {
+			Error("FbNode declared outside SynthDef").throw;
+		};
+
+		if (currentSynthDef !== UGen.buildSynthDef) {
+			// so that we only have one Phasor for each delay time, instead of one for every FbNode
+			currentSynthDef = UGen.buildSynthDef;
+			phasors = IdentityDictionary.new;
+		};
+
+		if (maxDelayTime.notNil && {maxDelayTime < (blockSize/sampleRate)}) {
+			"FbNode maxDelayTime less than one control period - setting to one block size.".warn;
+			maxDelayTime = nil;
+		};
+
+		if (maxDelayTime.isNil) {
+			maxDelayTime = blockSize/sampleRate;
+			interpolation = 0;
+			frames = blockSize * 2;
+		} {
+			frames = maxDelayTime*sampleRate + blockSize;
+			// the extra blockSize samples (in both these branches) is so that we're never 
+			// reading and writing the same part of the buffer in the same control period, 
+			// a bit like double buffering in the graphics world.  This is necessary because 
+			// this class has no way to know in which order the reading and writing will 
+			// be done.
+		};
+		if (phasors.includesKey(frames)) {
+			phase = phasors[frames];
+		} {
+			phase = Phasor.ar(0, 1, 0, frames);
+			phasors[frames] = phase;
+		};
 		
-		buffers = { LocalBuf(maxdelaysamples + 1) } ! numChannels;
-		in = Dbufrd(buffers, readoffset ! numChannels);
-		out = func.value(in.unbubble);
-		write = Dbufwr(out, buffers, writeoffset ! numChannels);
-		Duty.ar(SampleDur.ir, 0, write)
+		buf = LocalBuf(frames, numChannels).clear;
+		output = Thunk({ BufRd.ar(numChannels, buf, phase-blockSize, 1, interpolation) });
+		input = nil;
 	}
+
+	asUGenInput {
+		^output.value;
+	}
 	
+	at {
+		arg channels;
+		^output.value[channels]
+	}
+	
+	delay {
+		arg delaytime = maxDelayTime;
+		var blockSize = Server.default.options.blockSize;
+		var sampleRate = Server.default.sampleRate;
+		var offset;
+		
+		offset = max( delaytime*sampleRate, blockSize );
+		offset = min( offset, frames-blockSize );
+
+		^BufRd.ar(numChannels, buf, phase-offset,
+			1, interpolation);
+	}
+
+	write {
+		arg signal;
+		if (input.isNil) {
+			input = signal
+		} {
+			input = input + signal
+		};
+		BufWr.ar(input, buf, phase);
+		^signal;
+	}
 }
 
+
+

Added: Feedback/FbK.html
===================================================================
--- Feedback/FbK.html	                        (rev 0)
+++ Feedback/FbK.html	2013-01-03 06:51:17 UTC (rev 2529)
@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<title></title>
+<meta name="Generator" content="Cocoa HTML Writer">
+<meta name="CocoaVersion" content="1038.36">
+<style type="text/css">
+p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
+p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
+p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
+p.p5 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; min-height: 12.0px}
+p.p6 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica}
+p.p7 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p8 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 12.0px Helvetica}
+p.p9 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica}
+p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
+p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #e00000}
+span.s1 {font: 18.0px Helvetica}
+span.s2 {color: #3200ff}
+span.s3 {color: #001cbb}
+span.s4 {color: #001af9}
+span.s5 {color: #2500cf}
+span.s6 {color: #000000}
+span.s7 {color: #be00ac}
+span.Apple-tab-span {white-space:pre}
+</style>
+</head>
+<body>
+<p class="p1"><span class="s1"><b>FbK<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b></span><b>a painless way to create a feedback loop within a SynthDef, at control rate.</b></p>
+<p class="p2"><br></p>
+<p class="p1"><b>Inherits from: Object</b></p>
+<p class="p3"><br></p>
+<p class="p1">FbK is quite similar to <a href="Fb.html"><span class="s2">Fb</span></a>, except that it works for control-rate signals instead of audio-rate ones. It also doesn't have the additional delay line feature that Fb has. The best way to think of it is as a way to iterate difference equations at control-rate.</p>
+<p class="p2"><br></p>
+<p class="p1"><b>See also: </b><a href="FbNode.html"><span class="s2">FbNode</span></a>, <a href="sc://FbL"><span class="s3">FbL</span></a>, <a href="sc://FbC"><span class="s3">FbC</span></a>, <a href="sc://LocalIn"><span class="s4">LocalIn</span></a>, <a href="sc://InFeedback"><span class="s4">InFeedback</span></a>, <a href="sc://NodeProxy"><span class="s4">NodeProxy</span></a>, <a href="sc://LocalBuf"><span class="s4">LocalBuf</span></a>, and also the single sample feedback file in the Examples folder that comes with SC.</p>
+<p class="p2"><br></p>
+<p class="p4"><b>Creation / Class Methods</b></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>*new (func, initVals)</b></p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b>Create a feedback loop within a SynthDef</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>func </b>- This function should contain the UGens that will be inside the feedback loop.<span class="Apple-converted-space">  </span>Its output should be a control-rate UGen or an array of control-rate UGens. This is delayed by one control period and then fed into the function's input.</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>initVals </b>- The initial values that the function's arguments will have on the first iteration. If this argument is supplied, its size will determine the number of feedback channels. If FbK will try to guess the number of channels from its <b>func</b> parameter, and they will all have initial values of zero. If in doubt, supply this parameter.</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p9"><b>Examples</b></p>
+<p class="p3"><br></p>
+<p class="p10">(</p>
+<p class="p11">// A sine-wave LFO, implemented similarly to SinOscFB</p>
+<p class="p11">// (of course it would be better to use SinOsc.kr - this is just for demonstration purposes)</p>
+<p class="p10">play {</p>
+<p class="p10"><span class="Apple-tab-span">	</span><span class="s5">var</span> lfo;</p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span></span><span class="s5">var</span><span class="s6"> x = </span><span class="s5">SinOsc</span><span class="s6">.kr(</span><span class="s7">0.02</span><span class="s6">).exprange(</span><span class="s7">0.01</span><span class="s6">,</span><span class="s7">0.1</span><span class="s6">); </span>// related to the lfo rate</p>
+<p class="p10"><span class="Apple-tab-span">	</span>lfo = <span class="s5">FbK</span>({</p>
+<p class="p10"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">arg</span> fb;</p>
+<p class="p10"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>fb[<span class="s7">0</span>] = fb[<span class="s7">0</span>] +<span class="Apple-tab-span">	</span>(x*fb[<span class="s7">1</span>]);</p>
+<p class="p10"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>fb[<span class="s7">1</span>] = fb[<span class="s7">1</span>] -<span class="Apple-tab-span">	</span>(x*fb[<span class="s7">0</span>]);</p>
+<p class="p10"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>fb</p>
+<p class="p10"><span class="Apple-tab-span">	</span>}, [<span class="s7">0</span>,<span class="s7">1</span>]);</p>
+<p class="p3"><br></p>
+<p class="p10"><span class="Apple-tab-span">	</span><span class="s5">SinOsc</span>.ar(lfo[<span class="s7">0</span>].linexp(<span class="s7">0</span>,<span class="s7">1</span>,<span class="s7">100</span>,<span class="s7">400</span>))!<span class="s7">2</span>;</p>
+<p class="p10">}</p>
+<p class="p10">)</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p10">(</p>
+<p class="p11">// you can use control-rate UGens inside the update function</p>
+<p class="p10">play {</p>
+<p class="p10"><span class="Apple-tab-span">	</span><span class="s5">var</span> lfo;</p>
+<p class="p10"><span class="Apple-tab-span">	</span>lfo = <span class="s5">FbK</span>({</p>
+<p class="p10"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">arg</span> fb;</p>
+<p class="p10"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">SinOsc</span>.kr(<span class="s7">1</span>,fb*<span class="s7">2</span>);</p>
+<p class="p10"><span class="Apple-tab-span">	</span>}, [<span class="s7">0</span>]).poll;</p>
+<p class="p3"><span class="Apple-tab-span">	</span></p>
+<p class="p10"><span class="Apple-tab-span">	</span><span class="s5">SinOsc</span>.ar(lfo.linexp(<span class="s7">0</span>,<span class="s7">1</span>,<span class="s7">100</span>,<span class="s7">400</span>))!<span class="s7">2</span>;</p>
+<p class="p10">}<span class="Apple-tab-span">	</span></p>
+<p class="p10">)</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+</body>
+</html>

Added: Feedback/FbNode.html
===================================================================
--- Feedback/FbNode.html	                        (rev 0)
+++ Feedback/FbNode.html	2013-01-03 06:51:17 UTC (rev 2529)
@@ -0,0 +1,228 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<title></title>
+<meta name="Generator" content="Cocoa HTML Writer">
+<meta name="CocoaVersion" content="1038.36">
+<style type="text/css">
+p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
+p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
+p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
+p.p5 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; min-height: 12.0px}
+p.p6 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica}
+p.p7 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p8 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 12.0px Helvetica}
+p.p9 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p10 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica}
+p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #e00000}
+p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #797979}
+p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
+span.s1 {font: 18.0px Helvetica}
+span.s2 {color: #3200ff}
+span.s3 {color: #001af9}
+span.s4 {text-decoration: underline ; color: #0000ee}
+span.s5 {color: #001cbb}
+span.s6 {color: #000000}
+span.s7 {color: #2500cf}
+span.s8 {color: #be00ac}
+span.s9 {color: #e00000}
+span.Apple-tab-span {white-space:pre}
+</style>
+</head>
+<body>
+<p class="p1"><span class="s1"><b>FbNode<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b></span><b>an even more painless way to create a feedback loop within a SynthDef</b></p>
+<p class="p2"><br></p>
+<p class="p1"><b>Inherits from: UGen</b></p>
+<p class="p3"><br></p>
+<p class="p1">There are many ways to create feedback loops in SuperCollider.<span class="Apple-converted-space">  </span>Similarly to <a href="Fb.html"><span class="s2">Fb</span></a>, FbNode aims to help you create them in as painless a way as possible.<span class="Apple-converted-space">  </span>The easiest way to understand it is probably to skip to the examples section.<span class="Apple-converted-space">  </span>FbNode is part of the <a href="Feedback.html"><span class="s2">Feedback</span></a> quark.</p>
+<p class="p2"><br></p>
+<p class="p1">Ways of creating feedback loops in SuperCollider can be divided into two types: those that use busses to route signals between SynthDefs, and those that create a feedback loop within a SynthDef. FbNode is of the latter type.</p>
+<p class="p2"><br></p>
+<p class="p1">The traditional way to create feedback within a SynthDef is to use <a href="sc://LocalIn"><span class="s3">LocalIn</span></a>/<a href="sc://LocalOut"><span class="s3">LocalOut</span></a>.<span class="Apple-converted-space">  </span>FbNode is designed to be close to this model, but has a very major advantage over it, which is that you can have as many FbNodes as you like in a single SynthDef instead of just one, and have them all feed back into each other as much as you want. This makes it much easier to make complex networks of feedback lines, and leads to much more readable code.</p>
+<p class="p2"><br></p>
+<p class="p1">Additionally, FbNode has an optional built-in multi-tap delay line, so you can easily control the time period of your feedback loops.<span class="Apple-converted-space">  </span>As with (almost) all methods of achieving feedback in SuperCollider, the minimum delay is given by the server's block size, which is usually 64 samples.</p>
+<p class="p2"><br></p>
+<p class="p1"><b>FbNode vs. Fb</b></p>
+<p class="p2"><br></p>
+<p class="p1"><span class="s4"><a href="Fb.html">Fb</a></span> is the original way of doing feedback from the Feedback quark. After several years of using it, it became clear that although it worked very well in a lot of cases, for some things it just wasn't the right tool for the job. FbNode is designed to be both more flexible and more intuitive to use than Fb. Fb has a model in which the output of a function is fed back into its input, whereas FbNode is more about writing to and reading from delay lines. FbNode is probably the best one to learn first, but they're both useful and it's worth learning both and seeing which one best fits a given situation.<span class="Apple-converted-space">  </span>You can use both of them in the same SynthDef if you want.</p>
+<p class="p2"><br></p>
+<p class="p1">One plus-point of Fb over FbNode is that it does multichannel expansion, at least in most cases. FbNode tries to make it easy to do multichannel feedback, but you have to ask for it explicitly - it doesn't try to do it for you.<span class="Apple-converted-space"> </span></p>
+<p class="p2"><br></p>
+<p class="p1">Another tiny potential disadvantage of FbNode over Fb is that it allocates an additional blockSize of samples for every feedback loop, in order to do some necessary double buffering. The chances of this tiny bit of extra memory use being a significant problem in most applications are very small, however.</p>
+<p class="p2"><br></p>
+<p class="p1">On the other hand, FbNode makes it much easier to have multiple interacting feedback delay lines, especially if you want them all to have different delay times.</p>
+<p class="p2"><br></p>
+<p class="p1"><b>A caveat regarding multiple servers</b></p>
+<p class="p2"><br></p>
+<p class="p1">The following will not be an issue for most users, but because of the way FbNode works, it needs to know the server's sample rate and block size at the time the SynthDef is compiled. To do this, it uses Server.default.options.blockSize (because there's no way to get the block size of a running server) and Server.default.sampleRate (because there's no way to reliably get the sample rate of a server that <i>isn't</i> running). This means that the server has to be booted in order to compile SynthDefs containing FbNodes, and there's no way to compile such SynthDefs for a remote server that has a different sample rate from the default one. I'd like to fix this, but I don't know the best way to approach it.</p>
+<p class="p2"><br></p>
+<p class="p2"><br></p>
+<p class="p1"><b>See also:</b> <a href="Fb.html"><span class="s2">Fb</span></a>, <a href="sc://FbL"><span class="s5">FbL</span></a>, <a href="sc://FbC"><span class="s5">FbC</span></a>, <a href="FbK.html"><span class="s2">FbK</span></a>, <a href="sc://LocalIn"><span class="s3">LocalIn</span></a>, <a href="sc://InFeedback"><span class="s3">InFeedback</span></a>, <a href="sc://NodeProxy"><span class="s3">NodeProxy</span></a>, <a href="sc://LocalBuf"><span class="s3">LocalBuf</span></a>, and also the single sample feedback file in the Examples folder that comes with SC. These are all alternative ways to do feedback in SuperCollider.</p>
+<p class="p2"><br></p>
+<p class="p4"><b>Creation / Class Methods</b></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>*new (numChannels, maxdelaytime, interpolation)</b></p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b>This creates a new feedback node, which you can then read from and write to.</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>numChannels </b>- the number of channels that the feedback loop will have. This defaults to 1. Note that you can either use this argument, or you can just create more than one FbNode. Multi-channel FbNodes are useful for things like stereo delay lines, but if you're doing something complicated with lots of channels, it will probably be better to use multiple FbNodes, as in the last example below.</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>maxdelaytime </b>- the maximum delay time in seconds. Used to initialize the delay buffer size. You do not need to subtract <a href="sc://ControlDur"><span class="s3">ControlDur</span></a>.ir from this, as this is handled automatically.<span class="Apple-converted-space">  </span>If you don't set it, or you set it to less than one control period (i.e. less than 64/44100 ≈ 0.014s) then no extra delay line will be added.</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>interpolation </b>- what kind of interpolation to use when reading back from the delay line. (This is only relevant if maxdelaytime is set.) This argument uses the same numbering scheme as <a href="sc://BufRd"><span class="s2">BufRd</span></a>'s interpolation argument, which for some reason goes like this:</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>1 - no interpolation</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>2 - linear interpolation</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>4 - cubic interpolation</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>the default is 2 (linear interpolation).</p>
+<p class="p9"><br></p>
+<p class="p10"><b>Reading from an FbNode</b></p>
+<p class="p9"><span class="Apple-tab-span">	</span></p>
+<p class="p1">You don't have to do anything special to read from an FbNode if you don't want to add a delay to its output - just pass the node itself as an argument to a UGen. (See the third example below.)</p>
+<p class="p9"><span class="Apple-tab-span">	</span></p>
+<p class="p8"><b><span class="Apple-tab-span">	</span>delay (delaytime)</b></p>
+<p class="p9"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b>Output the FbNode's feedback signal with an added delay. The delay time can be modulated. The maximum delay time and the interplolation method must be given when you create the FbNode. You can use this method as many times as you want, with different delay times, so this effectively gives you a multi-tap delay line on every FbNode.</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>delaytime </b>- the amount by which to delay the signal. This will be clipped to be between one block size (about 14 milliseconds by default) and<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>the FbNode's maxdelaytime. If you didn't set a maxdelaytime when creating the FbNode then this argument will be ignored and the signal will be delayed by one block size. This defaults to the FbNode's maxdelaytime.</p>
+<p class="p2"><span class="Apple-tab-span">	</span></p>
+<p class="p10"><b>Writing to an FbNode</b></p>
+<p class="p9"><br></p>
+<p class="p8"><b><span class="Apple-tab-span">	</span>write (signal)</b></p>
+<p class="p9"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b>Write a signal to the FbNode's internal buffer. You can do this before or after you read from it, or both. In either case, the signal you get when you read from the FbNode will be the signal that was written to it in the previous control period.<span class="Apple-converted-space">  </span>This method returns its input.</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>If you write to a FbNode more than once, the two signals will be added. (But note that a BufWr UGen will be created every time you write to the node, even though only the last of these is necessary. If you're doing it a lot it's better to sum the signals manually and only write once.)</p>
+<p class="p9"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>signal </b>- the signal to write to the FbNode's buffer. This signal must have the same number of channels as the FbNode, otherwise you will get a<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>buffer mismatch error.</p>
+<p class="p9"><br></p>
+<p class="p8">It isn't possible to write to only one channel of an FbNode at a time. If you want to do that, it's better to create an array of FbNodes.</p>
+<p class="p9"><br></p>
+<p class="p7"><br></p>
+<p class="p10"><b>Examples</b></p>
+<p class="p3"><br></p>
+<p class="p6">The first two examples are the same as for Fb, so you can see how FbNode compares for basic tasks.</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p11">// simple dub delay effect</p>
+<p class="p3"><br></p>
+<p class="p12"><span class="s6">b = </span><span class="s7">Buffer</span><span class="s6">.read(s,</span>"sounds/a11wlk01.wav"<span class="s6">)</span></p>
+<p class="p3"><br></p>
+<p class="p13">(</p>
+<p class="p13">{</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> in = <span class="s7">PlayBuf</span>.ar(<span class="s8">1</span>,b);</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> fbNode = <span class="s7">FbNode</span>(<span class="s8">1</span>,<span class="s8">0.6</span>);</p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span></span><span class="s7">var</span><span class="s6"> signal = fbNode.delay; </span>// read the feedback bus and delay the result.<span class="Apple-converted-space"> </span></p>
+<p class="p11"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// The delay time defaults to the max delay time, 0.6 s in this case.</p>
+<p class="p3"><br></p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span></span>// Add the input to the feedback signal, then filter and distort it.</p>
+<p class="p13"><span class="Apple-tab-span">	</span>signal = <span class="s7">BPF</span>.ar(signal*<span class="s8">0.8 </span>+ in, <span class="s8">2000</span>, <span class="s8">3.8</span>).distort;</p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span></span>// for fun effects, try changing the 0.8 to something greater than one</p>
+<p class="p3"><br></p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span></span>// write the signal to the feedback buffer</p>
+<p class="p13"><span class="Apple-tab-span">	</span>fbNode.write(signal);</p>
+<p class="p3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">DetectSilence</span>.ar(signal ,doneAction:<span class="s8">2</span>);</p>
+<p class="p13"><span class="Apple-tab-span">	</span>signal!<span class="s8">2</span>;</p>
+<p class="p13">}.play;</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p13">b.free</p>
+<p class="p3"><br></p>
+<p class="p11">// Karplus-Strong style plucked string algorithm (see also <a href="sc://Pluck"><span class="s4">Pluck</span></a>)</p>
+<p class="p13">(</p>
+<p class="p13">{</p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span></span><span class="s7">var</span><span class="s6"> in = </span><span class="s7">Impulse</span><span class="s6">.ar(</span><span class="s8">0</span><span class="s6">)!</span><span class="s8">2</span><span class="s6">; </span>// stereo input (although in this case both channels are the same)</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> freq = <span class="s8">200</span>;</p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span></span><span class="s7">var</span><span class="s6"> fbNode = </span><span class="s7">FbNode</span><span class="s6">(</span><span class="s8">2</span><span class="s6">, </span><span class="s8">0.1</span><span class="s6">); </span>// two channel feedback with a maximum delay time of 0.1 s</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> signal = fbNode.delay(<span class="s8">1</span>/freq);</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span">	</span>signal = <span class="s7">LPF</span>.ar(<span class="s7">LeakDC</span>.ar(signal),<span class="s8">8000</span>)*<span class="s8">0.99 </span>+ in;</p>
+<p class="p3"><br></p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span>fbNode.write(signal); </span>// two channel signal being written into two-channel FbNode</p>
+<p class="p3"><span class="Apple-tab-span">	</span></p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">DetectSilence</span>.ar(signal,doneAction:<span class="s8">2</span>);</p>
+<p class="p13"><span class="Apple-tab-span">	</span>signal;</p>
+<p class="p13">}.play</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p11">// basic usage without adding a delay line: self-modulating sine wave.</p>
+<p class="p13">(</p>
+<p class="p13">{</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> fbNode = <span class="s7">FbNode</span>(<span class="s8">1</span>);</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> signal = <span class="s7">SinOsc</span>.ar(<span class="s8">100</span>, fbNode * <span class="s7">Line</span>.kr(<span class="s8">0</span>,<span class="s8">2</span>,<span class="s8">10</span>) );<span class="Apple-converted-space"> </span></p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// the FbNode is used to modulate the SinOsc's phase</p>
+<p class="p3"><span class="Apple-tab-span">	</span></p>
+<p class="p13"><span class="Apple-tab-span">	</span>fbNode.write(signal);</p>
+<p class="p13"><span class="Apple-tab-span">	</span>signal ! <span class="s8">2</span>;</p>
+<p class="p13">}.play;</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p11">// Two delay lines with cross talk. This would be quite awkward to do with Fb.</p>
+<p class="p13">(</p>
+<p class="p13">{</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> in = <span class="s7">WhiteNoise</span>.ar*<span class="s7">Line</span>.kr(<span class="s8">1</span>,<span class="s8">0</span>,<span class="s8">0.1</span>);</p>
+<p class="p3"><br></p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span></span>// create two FbNodes with different delay times</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> fbNode1 = <span class="s7">FbNode</span>(<span class="s8">1</span>,<span class="s8">9</span>/<span class="s8">8</span>);</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> fbNode2 = <span class="s7">FbNode</span>(<span class="s8">1</span>,<span class="s8">1</span>);</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> sig1 = in + (fbNode1.delay * <span class="s8">0.8</span>) + (fbNode2.delay * <span class="s8">0.1</span>);</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> sig2 = in + (fbNode1.delay * <span class="s8">0.1</span>) + (fbNode2.delay * <span class="s8">0.8</span>);</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span">	</span>fbNode1.write(sig1);</p>
+<p class="p13"><span class="Apple-tab-span">	</span>fbNode2.write(sig2);</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">Pan2</span>.ar(sig1, <span class="s8">-0.8</span>) + <span class="s7">Pan2</span>.ar(sig2, <span class="s8">0.8</span>);</p>
+<p class="p13">}.play;</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p11">// using the multi-tap delay feature</p>
+<p class="p13">(</p>
+<p class="p13">{</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> in = <span class="s7">Saw</span>.ar([<span class="s8">100</span>,<span class="s8">102</span>])*<span class="s7">Line</span>.kr(<span class="s8">1</span>,<span class="s8">0</span>,<span class="s8">0.1</span>); <span class="s9">// stereo input signal</span></p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> fbNode = <span class="s7">FbNode</span>(<span class="s8">2</span>, <span class="s8">1.0</span>);</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> signal = <span class="s7">Mix</span>.fill(<span class="s8">10</span>,{fbNode.delay(<span class="s8">1.0</span>.rand)});</p>
+<p class="p3"><span class="Apple-tab-span">	</span></p>
+<p class="p13"><span class="Apple-tab-span">	</span>fbNode.write(in + (signal*<span class="s8">0.1</span>));</p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span></span>// if you want, you can use FbNode as a normal multi-tap delay, just by not adding in the</p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span></span>// feedback signal here.</p>
+<p class="p3"><span class="Apple-tab-span">	</span></p>
+<p class="p13"><span class="Apple-tab-span">	</span>signal;</p>
+<p class="p3"><br></p>
+<p class="p13">}.play;</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p11">// How to create an array of many feedback delay lines.</p>
+<p class="p11">// (This doesn't sound great, but it illustrates the technique.)</p>
+<p class="p13">(</p>
+<p class="p13">{</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> in = <span class="s7">WhiteNoise</span>.ar*<span class="s7">Line</span>.kr(<span class="s8">1</span>,<span class="s8">0</span>,<span class="s8">0.05</span>);<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> n = <span class="s8">10</span>;</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> fbNodes = {<span class="s7">FbNode</span>( <span class="s8">1</span>, rrand(<span class="s8">0.1</span>,<span class="s8">1.0</span>) )}!n;<span class="Apple-converted-space"> </span></p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// create n mono FbNodes, each with a different max delay time.</p>
+<p class="p3"><span class="Apple-tab-span">	</span></p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">var</span> signals = n.collect {</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s7">arg</span> i;</p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// the nodes are arranged in a circle, with each one getting some feedthough from</p>
+<p class="p11"><span class="s6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// the nodes on either side.</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s7">var</span> signal = in + (fbNodes[i].delay*<span class="s8">0.4</span>)</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>+ (fbNodes[(i+<span class="s8">1</span>)%n].delay*<span class="s8">0.3</span>)</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>+ (fbNodes[(i-<span class="s8">1</span>)%n].delay*<span class="s8">0.3</span>);</p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>fbNodes[i].write(signal);</p>
+<p class="p13"><span class="Apple-tab-span">	</span>};</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span">	</span><span class="s7">Splay</span>.ar(signals);</p>
+<p class="p13">}.play;</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+</body>
+</html>

Added: Feedback/Feedback.html
===================================================================
--- Feedback/Feedback.html	                        (rev 0)
+++ Feedback/Feedback.html	2013-01-03 06:51:17 UTC (rev 2529)
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<title></title>
+<meta name="Generator" content="Cocoa HTML Writer">
+<meta name="CocoaVersion" content="1038.36">
+<style type="text/css">
+p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
+p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
+span.s1 {font: 18.0px Helvetica}
+span.s2 {color: #3200ff}
+span.Apple-tab-span {white-space:pre}
+</style>
+</head>
+<body>
+<p class="p1"><span class="s1"><b>Feedback<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b></span><b>a quark for implementing feedback loops painlessly</b></p>
+<p class="p2"><br></p>
+<p class="p1">The Feedback quark provides a small collection of classes aimed at making it easier to create feedback loops within a SynthDef. These classes are particularly useful if you want to implement a complicated network of many feedbacks.<span class="Apple-converted-space">  </span>The classes provided are</p>
+<p class="p2"><br></p>
+<p class="p1"><span class="s2"><a href="FbNode.html"><b>FbNode</b></a></span> - this is probably the best place for new users to start. It provides a way to read from and write to a feedback bus, similarly to <a href="SC://LocalIn"><span class="s2">LocalIn</span></a> and <a href="SC://LocalOut"><span class="s2">LocalOut</span></a>. The big difference is that you can have many FbNodes in a single SynthDef, and they can all feed back into each other if you want. In addition, FbNode makes it easy to implement feedback delay lines, by adding an optional modulateable multi-tap delay to every FbNode.</p>
+<p class="p2"><br></p>
+<p class="p1"><span class="s2"><a href="Fb.html"><b>Fb</b></a></span> (and its interpolating versions <a href="FbL.html"><span class="s2">FbL</span></a> and <a href="FbC.html"><span class="s2">FbC</span></a>) - this does the same sort of thing as FbNode, but with a different interface. With Fb, you supply a function, whose output is delayed (by an amount you specify) and then fed back into its input. You can have many such feedback functions within a single SynthDef, and they can even be nested. Fb is the class to use if you're thinking in terms of <i>feedback loops</i>, whereas FbNode is better if you're thinking in terms of <i>feedback delay lines.</i></p>
+<p class="p2"><i></i><br></p>
+<p class="p1"><span class="s2"><a href="FbK.html"><b>FbK</b></a></span> - this is similar to Fb, except that it operates on control-rate (kr) signals instead of audio rate ones, and doesn't have an extra delay line. It can be used to iterate equations at control rate.</p>
+</body>
+</html>

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.


_______________________________________________
sc-dev mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: https://listarc.bham.ac.uk/marchives/sc-dev/
search: https://listarc.bham.ac.uk/lists/sc-dev/search/