2 summary:: Read signal from a bus with a current or one cycle old timestamp.
3 related:: Classes/In, Classes/LagIn, Classes/LocalIn
4 categories:: UGens>InOut
9 When the various output UGens ( link::Classes/Out:: ,
10 link::Classes/OffsetOut:: , link::Classes/XOut:: ) write data to a bus,
11 they mix it with any data from the current cycle, but overwrite any data
12 from the previous cycle. ( link::Classes/ReplaceOut:: overwrites all
13 data regardless.) Thus depending on node order and what synths are
14 writing to the bus, the data on a given bus may be from the current cycle
15 or be one cycle old at the time of reading. In.ar checks the timestamp of
16 any data it reads in and zeros any data from the previous cycle (for use
17 within that node; the data remains on the bus). This is fine for audio
18 data, as it avoids feedback, but for control data it is useful to be able
19 to read data from any place in the node order. For this reason In.kr also
20 reads data that is older than the current cycle.
23 In some cases we might also want to read audio from a node later in the
24 current node order. This is the purpose of InFeedback. The delay
25 introduced by this is one block size, which equals about 0.0014 sec at
26 the default block size and sample rate. (See the resonator example below
27 to see the implications of this.)
30 The variably mixing and overwriting behaviour of the output UGens can
31 make order of execution crucial. (No pun intended.) For example with a
32 node order like the following the InFeedback UGen in Synth 2 will only
33 receive data from Synth 1 (→ = write out; ← = read in):
35 ## Synth1 → busA (this synth overwrites the output of Synth3 before it reaches Synth2)
36 ## Synth2 (with InFeedback) ← busA
40 If Synth1 were moved after Synth2 then Synth2's InFeedback would receive
41 a mix of the output from Synth1 and Synth3. This would also be true if
42 Synth2 came after Synth1 and Synth3. In both cases data from Synth1 and
43 Synth3 would have the same time stamp (either current or from the
44 previous cycle), so nothing would be overwritten.
47 Because of this it is often useful to allocate a separate bus for
48 feedback. With the following arrangement Synth2 will receive data from
49 Synth3 regardless of Synth1's position in the node order:
53 ## Synth2 (with InFeedback) ← busB
54 ## Synth3 → busB + busA
56 The second example below demonstrates this issue.
65 The index of the bus to read in from.
70 The number of channels (i.e. adjacent buses) to read in. The
71 default is 1. You cannot modulate this number by assigning it to
72 an argument in a SynthDef.
76 audio feedback modulation:
79 SynthDef("help-InFeedback", { arg out=0, in=0;
81 input = InFeedback.ar(in, 1);
82 sound = SinOsc.ar(input * 1300 + 300, 0, 0.4);
88 this shows how a node can read audio from a bus that is being written to by a synth following it:
91 SynthDef("help-InFeedback", { arg out=0, in=0;
96 SynthDef("help-SinOsc", { arg out=0, freq=440;
97 Out.ar(out, SinOsc.ar(freq, 0, 0.1))
103 // read from bus n play to bus 0 (silent)
104 a = Synth("help-InFeedback",[\in, x.index, \out, 0]);
106 // now play a synth after this one, playing to bus x
107 b = Synth.after(a, "help-SinOsc", [\out, x.index]);
109 // add another synth before a which also writes to bus x
110 // now you can't hear b, as its data is one cycle old, and is overwritten by c
111 c = Synth.before(a, "help-SinOsc", [\out, x.index, \freq, 800]);
113 // free c and you can hear b again
120 The example below implements a resonator. Note that you must subtract the blockSize in order for the tuning to be correct. See link::Classes/LocalIn:: for an equivalent example.
123 var play, imp, initial;
124 SynthDef("testRes", {
126 play = InFeedback.ar(10, 1); // 10 is feedback channel
130 OffsetOut.ar(10, DelayC.ar(imp + (play * 0.995), 1,
131 440.reciprocal - ControlRate.ir.reciprocal)); // subtract block size
133 OffsetOut.ar(0, play);
137 // Compare with this for tuning
138 { SinOsc.ar(440, 0, 0.2) }.play(s, 1);