1 <!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
4 <meta http-equiv=
"Content-Type" content=
"text/html; charset=UTF-8">
5 <meta http-equiv=
"Content-Style-Type" content=
"text/css">
7 <meta name=
"Generator" content=
"Cocoa HTML Writer">
8 <meta name=
"CocoaVersion" content=
"949.43">
9 <style type=
"text/css">
10 p
.p1
{margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Helvetica
}
11 p
.p2
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; min-height: 14.0px}
12 p
.p3
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
}
13 p
.p4
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #0b15e8}
14 p
.p5
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
}
15 p
.p6
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #606060}
16 p
.p7
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; min-height: 12.0px}
17 p
.p8
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #6f2f21}
18 span
.s1
{color: #1e45de}
19 span
.s2
{color: #000000}
20 span
.s3
{text-decoration: underline
}
21 span
.s4
{color: #2c4693}
22 span
.s5
{color: #1735a5}
23 span
.s6
{color: #0910ba}
24 span
.s7
{color: #6f2f21}
25 span
.s8
{font: 9.0px Monaco
}
26 span
.Apple-tab-span
{white-space:pre
}
27 ul
.ul1
{list-style-type: disc
}
31 <p class=
"p1"><b>pvcollect
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>Process each bin of an FFT chain, separately
</b></p>
32 <p class=
"p2"><br></p>
33 <p class=
"p3"><b><span class=
"Apple-tab-span"> </span>chain = chain.pvcollect(numframes, func, frombin, tobin, zeroothers)
</b></p>
34 <p class=
"p2"><br></p>
35 <p class=
"p3">pvcollect applies function
<b>func
</b> to each bin of an
<a href=
"FFT.html"><span class=
"s1">FFT
</span></a> chain.
<b>func
</b> should be a function that takes
<i>magnitude, phase, index
</i> as inputs and returns a resulting [magnitude, phase].
</p>
36 <p class=
"p2"><br></p>
37 <p class=
"p3">The
"index" is the integer bin number, starting at
0 for DC. You can optionally ignore the phase and only return a single (magnitude) value, in which case the phase is assumed to be left unchanged.
</p>
38 <p class=
"p2"><br></p>
39 <p class=
"p3"><b>frombin
</b>,
<b>tobin
</b>, and
<b>zeroothers
</b> are optional arguments which limit the processing to a specified integer range of FFT bins. If
<b>zeroothers
</b> is set to
1 then bins outside of the range being processed are silenced.
</p>
40 <p class=
"p2"><br></p>
41 <p class=
"p3">Note that this procedure can be relatively CPU-heavy, depending on how you use it. See
"efficiency considerations" below.
<span class=
"Apple-converted-space"> </span></p>
42 <p class=
"p2"><br></p>
43 <p class=
"p4"><span class=
"s2">See also:
<a href=
"pvcalc.html"><span class=
"s3">pvcalc
</span></a>,
<a href=
"pvcalc2.html"><span class=
"s3">pvcalc2
</span></a>,
<a href=
"UnpackFFT.html"><span class=
"s3">UnpackFFT
</span></a>.
</span></p>
44 <p class=
"p2"><br></p>
45 <p class=
"p2"><br></p>
46 <p class=
"p3"><b>Examples
</b></p>
47 <p class=
"p2"><br></p>
49 <p class=
"p5">s.boot.doWhenBooted{
</p>
50 <p class=
"p6"><span class=
"s2">c =
</span><span class=
"s4">Buffer
</span><span class=
"s2">.read(s,
</span>"sounds/a11wlk01.wav"<span class=
"s2">);
</span></p>
53 <p class=
"p7"><br></p>
55 <p class=
"p5">x = {
</p>
56 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s5">var
</span> in, chain, v;
</p>
57 <p class=
"p5"><span class=
"Apple-tab-span"> </span>in =
<span class=
"s5">PlayBuf
</span>.ar(
1, c,
<span class=
"s5">BufRateScale
</span>.kr(c), loop:
1);
</p>
58 <p class=
"p5"><span class=
"Apple-tab-span"> </span>chain =
<span class=
"s6">FFT
</span>(
<span class=
"s6">LocalBuf
</span>(
1024), in);
</p>
59 <p class=
"p7"><span class=
"Apple-tab-span"> </span></p>
60 <p class=
"p5"><span class=
"Apple-tab-span"> </span>v =
<span class=
"s5">LFPar
</span>.kr(
0.5).range(
0.1,
1);
</p>
61 <p class=
"p7"><span class=
"Apple-tab-span"> </span></p>
62 <p class=
"p5"><span class=
"Apple-tab-span"> </span>chain = chain.pvcollect(
1024, {
<span class=
"s5">|mag, phase, index|
</span></p>
63 <p class=
"p8">//////// Try uncommenting each of these lines in turn and re-running the synth:
</p>
64 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//mag;
</p>
65 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//[mag, phase];
</p>
66 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//[mag, phase] /
3;
</p>
67 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//[mag, phase].sqrt;
</p>
68 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//[mag,
3.14.rand];
</p>
69 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//[mag, LFNoise0.kr.range(
0,
3.14)];
</p>
70 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//[mag * Dseq([
1,
0,
0,
1,
1,
0,
1,
0].stutter(
8),
999999999999)]; // Can even use Demand ugens! One val demanded each frame
</p>
71 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//[mag.sqrt,
3.14.rand];
</p>
72 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//if(index %
7 ==
0, mag,
0); // Comb filter
</p>
73 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//if(LFNoise0.kr(
10)
> 0.5, mag,
0);
</p>
74 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>//mag + DelayN.kr(mag,
1, v); // Spectral delay
</p>
75 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if((index-
<span class=
"s5">LFPar
</span>.kr(
0.1).range(
2,
1024/
20)).abs
< 10, mag,
0);
<span class=
"s7">// Swept bandpass
</span></p>
76 <p class=
"p5"><span class=
"Apple-tab-span"> </span>}, frombin:
0, tobin:
250, zeroothers:
0);
</p>
77 <p class=
"p7"><span class=
"Apple-tab-span"> </span></p>
78 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s5">Out
</span>.ar(
0,
0.5 *
<span class=
"s5">IFFT
</span>(chain).dup);
</p>
79 <p class=
"p5">}.play(s);
</p>
81 <p class=
"p5">x.free;
</p>
82 <p class=
"p2"><br></p>
83 <p class=
"p2"><br></p>
84 <p class=
"p3"><b>Efficiency considerations
</b></p>
85 <p class=
"p2"><br></p>
86 <p class=
"p3">Using pvcollect (or its components, UnpackFFT
& PackFFT) is usually less efficient than using a single
"PV_" unit generator to process an FFT chain, because it involves the creation of quite a large graph of demand-rate unit generators.
</p>
87 <p class=
"p2"><br></p>
88 <p class=
"p3">If you wish to reduce the CPU impact of using this approach, try the following:
</p>
89 <p class=
"p2"><br></p>
91 <li style=
"margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica">Use the
<b>frombin
</b> and
<b>tobin
</b> arguments to limit the number of FFT bins that will be included in the calculation. Often the lower FFT bins contain the loudest and/or most relevant information, so perhaps your effect sounds very similar if you ignore the higher-up bins (either leave them unprocessed, or discard them by setting the
<b>zeroothers
</b> argument to
1, which has the effect of a band-pass frequency-domain filter).
</li>
92 <li style=
"margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica">Use a smaller FFT buffer size.
</li>
93 <li style=
"margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica">Avoid creating ugens inside your calculation function if at all possible. For example, a deterministic ugen such as
<span class=
"s8">LFPar.kr(
0.5,
0,
1)
</span> will be replicated
<i>once for each bin
</i> if specified inside the function, despite the fact that the output is always the same. Define it outside the calculation function and then reference it by variable name.
</li>
94 <li style=
"margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica">Avoid unused calculations! For example, uncommenting all the different lines in the above will waste effort because many values will be calculated but not used. This cannot be optimised away during compilation. It is particularly important because all calculations are duplicated (once for each bin) so can have a significant impact on efficiency.
</li>
95 <li style=
"margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica">If you find yourself calling pvcollect on an FFT chain more than once in series, you should definitely try to combine your processing into a single pvcollect function, to avoid unneccessary unpacking-then-packing-then-unpacking-then-packing.
</li>