Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Classes / PV_Copy.schelp
bloba11e1f3616cf88145d4550fd45a1c46189ed868d
1 class:: PV_Copy
2 summary:: Copy an FFT buffer
3 categories:: UGens>FFT
6 description::
8 Copies the spectral frame in bufferA to bufferB at that point in the chain of PV UGens. This allows for parallel processing of spectral data without the need for multiple FFT UGens, and to copy out data at that point in the chain for other purposes. bufferA and bufferB must be the same size.
10 classmethods::
11 method:: new
12 argument:: bufferA
13 source buffer.
14 argument:: bufferB
15 destination buffer.
17 examples::
18 code::
20 s.waitForBoot {
21         d = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");
26 //// crossfade between original and magmul-ed whitenoise
28 x = { var in, in2, chain, chainB, chainC;
29         in = PlayBuf.ar(1, d, BufRateScale.kr(d), loop: 1) * 2;
30         in2 = WhiteNoise.ar;
31         chain = FFT(LocalBuf(2048), in);
32         chainB = FFT(LocalBuf(2048), in2);
33         chainC = PV_Copy(chain, LocalBuf(2048));
34         chainB = PV_MagMul(chainB, chainC);
35         XFade2.ar(IFFT(chain), IFFT(chainB) * 0.1, SinOsc.kr(0.1, 1.5pi));
36 }.play(s);
38 x.free;
43 //// as previous but with Blip for 'vocoder' cross synthesis effect
45 x = { var in, in2, chain, chainB, chainC;
46         in = PlayBuf.ar(1, d, BufRateScale.kr(d), loop: 1) * 2;
47         in2 = Blip.ar(100, 50);
48         chain = FFT(LocalBuf(2048), in);
49         chainB = FFT(LocalBuf(2048), in2);
50         chainC = PV_Copy(chain, LocalBuf(2048));
51         chainB = PV_MagMul(chainB, chainC);
52         XFade2.ar(IFFT(chain), IFFT(chainB) * 0.1, SinOsc.ar(0.1));
53 }.play(s);
55 x.free;
58 //// Spectral 'pan'
60 x = { var in, chain, chainB, pan;
61         in = PlayBuf.ar(1, d, BufRateScale.kr(d), loop: 1);
62         chain = FFT(LocalBuf(2048), in);
63         chainB = PV_Copy(chain, LocalBuf(2048));
64         pan = MouseX.kr(0.001, 1.001, 'exponential') - 0.001;
65         chain = PV_BrickWall(chain, pan);
66         chainB = PV_BrickWall(chainB, -1 + pan);
67         0.5 * IFFT([chain, chainB]);
68 }.play(s);
70 x.free;
74 s.waitForBoot {
75         b = Buffer.alloc(s,2048,1);
76         c = Buffer.alloc(s,2048,1);
77         d = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");
78         e = Buffer.alloc(s,2048,1);
79         f = Buffer.alloc(s,2048,1);
84 //// proof of concept
86 x = { var inA, chainA, inB, chainB, chain;
87         inA = LFClipNoise.ar(100);
88         chainA = FFT(b, inA);
89         chainB = PV_Copy(chainA, c);
90         IFFT(chainA) - IFFT(chainB); // cancels to zero so silent!
91 }.play(s);
93 x.free;
94 // IFFTed frames contain the same windowed output data
95 b.plot(\b, Rect(200, 430, 700, 300)); c.plot(\c, Rect(200, 100, 700, 300));
99 //// Multiple Magnitude plots
101 x = { var in, chain, chainB, chainC;
102         in = WhiteNoise.ar;
103         chain = FFT(b, in);
104         PV_Copy(chain, LocalBuf(2048)); // initial spectrum
105         chain = PV_RectComb(chain, 20, 0, 0.2);
106         PV_Copy(chain, LocalBuf(2048)); // after comb
107         2.do({chain = PV_MagSquared(chain)});
108         PV_Copy(chain, LocalBuf(2048)); // after magsquared
109         0.00001 * Pan2.ar(IFFT(chain));
110 }.play(s);
112 x.free;
115 c.getToFloatArray(action: { arg array;
116         var z, x;
117         z = array.clump(2).flop;
118         // Initially data is in complex form
119         z = [Signal.newFrom(z[0]), Signal.newFrom(z[1])];
120         x = Complex(z[0], z[1]);
121         {x.magnitude.plot('Initial', Rect(200, 560, 700, 200))}.defer
123 e.getToFloatArray(action: { arg array;
124         var z, x;
125         z = array.clump(2).flop;
126         // RectComb doesn't convert, so it's still complex
127         z = [Signal.newFrom(z[0]), Signal.newFrom(z[1])];
128         x = Complex(z[0], z[1]);
129         {x.magnitude.plot('After RectComb', Rect(200, 330, 700, 200))}.defer
131 f.getToFloatArray(action: { arg array;
132         var z, x;
133         z = array.clump(2).flop;
134         // MagSquared converts to Polar
135         x = Signal.newFrom(z[0]); // magnitude first
136         {x.plot('After MagSquared', Rect(200, 100, 700, 200))}.defer
140 [b, c, d, e, f].do(_.free); // free the buffers