class library: SynthDef - lazy implementation of removeUGen
[supercollider.git] / HelpSource / Classes / LocalBuf.schelp
bloba61880cbaa15864fa02118d440a216a7895993c9
1 class:: LocalBuf
2 summary:: Allocate a buffer local to the synth
3 categories:: UGens>Buffer
4 related:: Classes/Buffer, Classes/SetBuf, Classes/ClearBuf
6 classmethods::
7 private:: categories, new1
9 method:: new
10 Allocate a local buffer
11 argument:: numFrames
12 number of frames (default: 1)
13 argument:: numChannels
14 number of channels for multiple channel buffers (default: 1)
15 returns:: a new buffer – the ugen outputs its buffer number and can thus be used in any other ugen that requires a buffer number input.
17 method:: newFrom
18 Allocates a new buffer from a given list of values
19 argument:: list
20 The list may be two-dimensional for numChannels > 1.
21 It is then reshaped into the buffer's current format by flattening.
22 returns:: a new buffer
23 discussion::
24 Since newFrom is called by the as message, one may thus convert an array to a LocalBuf:
25 code::
26 [1, 2, 3].as(LocalBuf)
29 instancemethods::
30 method:: set
31 set the buffer slots with a list of values.
32 discussion::
33 If list is smaller than numFrames, it will only set
34 part of the buffer. The list may be two-dimensional for numChannels > 1.
35 offset is the starting index (default: 0)
37 method:: clear
38 set the buffer slot to zero.
39 discussion::
40 This is important when randomly acessing buffer slots
41 (e.g. with a BufRd) or not overwriting them. Clear is not an efficient real time operation
42 for larger buffers, so it should be only used when really needed - but then it is essential:
43 a LocalBuf is "created" in each new synth, and it may reuse old space. So if an older
44 synth has already ended, this part of memory may be the same as the new synth's.
46 examples::
47 code::
48 // example: FFT
52 var in, chain;
53         in = WhiteNoise.ar(0.1.dup);
54         chain = FFT({LocalBuf(2048, 1)}.dup, in);
55         chain = PV_BrickWall(chain, SinOsc.kr([0.1, 0.11]));
56         IFFT(chain) // inverse FFT
57 }.play;
60 // spawn some FFT based synths:
62 SynthDef(\fftgrain, { |out, sustain = 1, rate = 0.2|
63         var in, chain;
64         in = WhiteNoise.ar(0.1).dup;
65         chain = FFT({LocalBuf(128, 1)}.dup, in);
66         chain = PV_BrickWall(chain,
67                 SinOsc.kr(rate * XLine.kr(1, 15 * [1, 1.6], sustain), Rand(0, pi))
68         );
69         Out.ar(out, IFFT(chain) * XLine.kr(1, 0.001, sustain, doneAction: 2)) // inverse FFT
70 }).add;
74 Pbind(
75         \instrument, \fftgrain,
76         \rate, Pwhite().linexp(0, 1, 0.01, 300),
77         \legato, Pwhite(1, 3.0, inf),
78         \dur, Prand([0.2, 1, 1.2], inf)
79 ).play
82 // IndexL
85         var buf = LocalBuf.newFrom((0..5).scramble);
86         var freq = IndexL.kr(buf, MouseX.kr(0, BufFrames.kr(buf))).poll * 100 + 40;
87         Saw.ar(freq * [1, 1.1]) * 0.1
88 }.play;
91 // DetectIndex
94         var buf1 = LocalBuf.newFrom((0..5).scramble);
95         var buf2 = LocalBuf.newFrom((0..5).scramble - 1);
96         var buf3 = LocalBuf.newFrom((0..5).scramble + 1);
97         var index = DetectIndex.kr([buf1, buf2], SinOsc.kr([0.85, 0.8], 0, 6).trunc).poll;
98         var freq = IndexL.kr([buf2, buf3], index).poll * 40 + 40;
99         Saw.ar(freq) * 0.1
100 }.play;
104 // DegreeToKey
105 // modal space
106 // mouse x controls discrete pitch in dorian mode
108 play({
109         var mix;
111         mix =
113         // lead tone
114         SinOsc.ar(
115                 (
116                         DegreeToKey.kr(
117                                 [0, 2, 3.2, 5, 7, 9, 10].as(LocalBuf),
118                                 MouseX.kr(0, 15),               // mouse indexes into scale
119                                 12,                                     // 12 notes per octave
120                                 1,                                      // mul = 1
121                                 72                                      // offset by 72 notes
122                         ).poll
123                         + LFNoise1.kr([3,3], 0.04)      // add some low freq stereo detuning
124                 ).midicps,                                              // convert midi notes to hertz
125                 0,
126                 0.1)
128         // drone 5ths
129         + RLPF.ar(LFPulse.ar([48,55].midicps, 0.15),
130                 SinOsc.kr(0.1, 0, 10, 72).midicps, 0.1, 0.1);
132         // add some 70's euro-space-rock echo
133         CombN.ar(mix, 0.31, 0.31, 2, 1, mix)
137 // Osc
140         var buf;
141         var list = Wavetable.sineFill(512, 1.0 / [1, 10, 3, 10, 5, 6, 10]);
142         // list.plot;
143         buf = LocalBuf.newFrom(list);
144         Osc.ar(buf,
145                 XLine.kr(2000, 200 + {30.0.rand}.dup, 10) + SinOsc.ar(Line.kr(2, 300, 10),
146                 0, 100)
147         ) * 0.1;
148 }.play;
151 // see how not clearing the buffer accesses old data:
152 // slowly overwrite data with noise
155         var buf = LocalBuf(2048, 2);
156         BufWr.ar(WhiteNoise.ar(1.dup), buf, LFNoise0.ar(530).range(0, BufFrames.kr(buf)));
157         PlayBuf.ar(2, buf, MouseX.kr(1, 2), loop: 1) * 0.1
158 }.play
161 // avoid this (unless you like the glitch) by clearing buffer first:
164         var buf = LocalBuf(2048, 2).clear;
165         BufWr.ar(WhiteNoise.ar(1.dup), buf, LFNoise0.ar(530).range(0, BufFrames.kr(buf)));
166         PlayBuf.ar(2, buf, MouseX.kr(1, 2), loop: 1) * 0.1
167 }.play
171 // BufCombC stereo (needs no clearing, because delay is filled by ugen)
174 var z = Decay.ar(Dust.ar(1.dup, 0.1), 0.3, WhiteNoise.ar);
175 BufCombC.ar(LocalBuf(SampleRate.ir, 2), z, XLine.kr(0.0001, 0.01, 20), 0.2);
176 }.play
179 // multichannel test
182 var in, chain, n = 4;
183         in = WhiteNoise.ar(0.1.dup(n));
184         chain = FFT({LocalBuf(2048, 1)}.dup(n), in);
185         chain = PV_BrickWall(chain, LFNoise2.kr(2.dup(n)));
186         Splay.ar(IFFT(chain)) // inverse FFT
187 }.play;