Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Classes / Signal.schelp
blobbb11a87a52ad7e0a34489c64efa584c81c7dad3b
1 CLASS::Signal
2 summary::Sampled audio buffer
3 related::Classes/Wavetable
4 categories:: Signals
6 DESCRIPTION::
7 A Signal is a FloatArray that represents a sampled function of time buffer.  Signals support math operations.
9 CLASSMETHODS::
11 method::sineFill
12 Fill a Signal of the given size with a sum of sines at the given amplitudes and phases. The Signal will be normalized.
13 code::
14 Signal.sineFill(1000, 1.0/[1, 2, 3, 4, 5, 6]).plot;
16 argument::size
17 the number of samples in the Signal.
18 argument::amplitudes
19 an Array of amplitudes for each harmonic beginning with the fundamental.
20 argument::phases
21 an Array of phases in radians for each harmonic beginning with the fundamental.
23 method::chebyFill
24 Fill a Signal of the given size with a sum of Chebyshev polynomials at the given amplitudes. For eventual use in waveshaping by the Shaper ugen; see link::Classes/Shaper:: helpfile and link::Classes/Buffer#-cheby#Buffer:cheby:: too.
25 code::
26 Signal.chebyFill(1000, [1]).plot;
27 Signal.chebyFill(1000, [0, 1]).plot;
28 Signal.chebyFill(1000, [0, 0, 1]).plot;
29 Signal.chebyFill(1000, [0.3, -0.8, 1.1]).plot;
31 argument::size
32 the number of samples in the Signal.
33 argument::amplitudes
34 an link::Classes/Array:: of amplitudes for each Chebyshev polynomial beginning with order 1.
35 argument::normalize
36 a link::Classes/Boolean::
38 method::hanningWindow
39 Fill a Signal of the given size with a Hanning window.
40 code::
41 Signal.hanningWindow(1024).plot;
42 Signal.hanningWindow(1024, 512).plot;
44 argument::size
45 the number of samples in the Signal.
46 argument::pad
47 the number of samples of the size that is zero padding.
49 method::hammingWindow
50 Fill a Signal of the given size with a Hamming window.
51 code::
52 Signal.hammingWindow(1024).plot;
53 Signal.hammingWindow(1024, 512).plot;
55 argument::size
56 the number of samples in the Signal.
57 argument::pad
58 the number of samples of the size that is zero padding.
60 method::welchWindow
61 Fill a Signal of the given size with a Welch window.
62 code::
63 Signal.welchWindow(1024).plot;
64 Signal.welchWindow(1024, 512).plot;
66 argument::size
67 the number of samples in the Signal.
68 argument::pad
69 the number of samples of the size that is zero padding.
71 method::rectWindow
72 Fill a Signal of the given size with a rectangular window.
73 code::
74 Signal.rectWindow(1024).plot;
75 Signal.rectWindow(1024, 512).plot;
77 argument::size
78 the number of samples in the Signal.
79 argument::pad
80 the number of samples of the size that is zero padding.
82 method::fftCosTable
83 Fourier Transform: Fill a Signal with the cosine table needed by the FFT methods. See also the instance methods link::#-fft:: and link::#-ifft::.
84 code::
85 Signal.fftCosTable(512).plot;
88 INSTANCEMETHODS::
90 private::performBinaryOpOnSignal, performBinaryOpOnComplex, performBinaryOpOnSimpleNumber
92 method::plot
93 Plot the Signal in a window. The arguments are not required and if not given defaults will be used.
94 code::
95 Signal.sineFill(512, [1]).plot;
96 Signal.sineFill(512, [1]).plot("Signal 1", Rect(50, 50, 150, 450));
98 argument::name
99 a String, the name of the window.
100 argument::bounds
101 a Rect giving the bounds of the window.
103 method::play
104 Loads the signal into a buffer on the server and plays it. Returns the buffer so you can free it again.
105 code::
106 b = Signal.sineFill(512, [1]).play(true, 0.2);
107 b.free; // free the buffer again.
109 argument::loop
110 A link::Classes/Boolean:: whether to loop the entire signal or play it once. Default is to loop.
111 argument::mul
112 volume at which to play it, 0.2 by default.
113 argument::numChannels
114 if the signal is an interleaved multichannel file, number of channels, default is 1.
115 argument::server
116 the server on which to load the signal into a buffer.
118 method::waveFill
119 Fill the Signal with a function evaluated over an interval.
120 code::
122 a = Signal.newClear(512);
123 a.waveFill({ arg x, i; sin(x).max(0) }, 0, 3pi);
124 a.plot;
127 argument::function
128 a function that should calculate the value of a sample.
130 The function is called with two arguments:
131 definitionList::
132 ## x || the value along the interval.
133 ## i || the sample index.
136 argument::start
137 the starting value of the interval.
138 argument::end
139 the ending value of the interval.
141 method::asWavetable
142 Convert the Signal into a Wavetable.
143 code::
144 Signal.sineFill(512, [1]).asWavetable.plot;
147 method::fill
148 Fill the Signal with a value.
149 code::
150 Signal.newClear(512).fill(0.2).plot;
153 method::scale
154 Scale the Signal by a factor strong::in place::.
155 code::
156 a = Signal[1, 2, 3, 4];
157 a.scale(0.5); a;
160 method::offset
161 Offset the Signal by a value strong::in place::.
162 code::
163 a = Signal[1, 2, 3, 4];
164 a.offset(0.5); a;
167 method::peak
168 Return the peak absolute value of a Signal.
169 code::
170 Signal[1, 2, -3, 2.5].peak;
173 method::normalize
174 Normalize the Signal strong::in place:: such that the maximum absolute peak value is 1.
175 code::
176 Signal[1, 2, -4, 2.5].normalize;
177 Signal[1, 2, -4, 2.5].normalize(0, 1);  // normalize only a range
180 method::normalizeTransfer
181 Normalizes a transfer function so that the center value of the table is offset to zero and the absolute peak value is 1. Transfer functions are meant to be used in the link::Classes/Shaper:: ugen.
182 code::
183 Signal[1, 2, 3, 2.5, 1].normalizeTransfer;
186 method::invert
187 Invert the Signal strong::in place::.
188 code::
189 a = Signal[1, 2, 3, 4];
190 a.invert(0.5); a;
193 method::reverse
194 Reverse a subrange of the Signal strong::in place::.
195 code::
196 a = Signal[1, 2, 3, 4];
197 a.reverse(1, 2); a;
200 method::fade
201 Fade a subrange of the Signal strong::in place::.
202 code::
203 a = Signal.fill(10, 1);
204 a.fade(0, 3);           // fade in
205 a.fade(6, 9, 1, 0);     // fade out
208 method::integral
209 Return the integral of a signal.
210 code::
211 Signal[1, 2, 3, 4].integral;
214 method::overDub
215 Add a signal to myself starting at the index. If the other signal is too long only the first part is overdubbed.
216 code::
217 a = Signal.fill(10, 100);
218 a.overDub(Signal[1, 2, 3, 4], 3);
220                 // run out of range
221 a = Signal.fill(10, 100);
222 a.overDub(Signal[1, 2, 3, 4], 8);
224 a = Signal.fill(10, 100);
225 a.overDub(Signal[1, 2, 3, 4], -4);
227 a = Signal.fill(10, 100);
228 a.overDub(Signal[1, 2, 3, 4], -1);
230 a = Signal.fill(10, 100);
231 a.overDub(Signal[1, 2, 3, 4], -2);
233 a = Signal.fill(4, 100);
234 a.overDub(Signal[1, 2, 3, 4, 5, 6, 7, 8], -2);
237 method::overWrite
238 Write a signal to myself starting at the index. If the other signal is too long only the first part is overdubbed.
239 code::
240 a = Signal.fill(10, 100);
241 a.overWrite(Signal[1, 2, 3, 4], 3);
243                 // run out of range
244 a = Signal.fill(10, 100);
245 a.overWrite(Signal[1, 2, 3, 4], 8);
247 a = Signal.fill(10, 100);
248 a.overWrite(Signal[1, 2, 3, 4], -4);
250 a = Signal.fill(10, 100);
251 a.overWrite(Signal[1, 2, 3, 4], -1);
253 a = Signal.fill(10, 100);
254 a.overWrite(Signal[1, 2, 3, 4], -2);
256 a = Signal.fill(4, 100);
257 a.overWrite(Signal[1, 2, 3, 4, 5, 6, 7, 8], -2);
260 method::blend
261 Blend two signals by some proportion.
262 code::
263 Signal[1, 2, 3, 4].blend(Signal[5, 5, 5, 0], 0);
264 Signal[1, 2, 3, 4].blend(Signal[5, 5, 5, 0], 0.2);
265 Signal[1, 2, 3, 4].blend(Signal[5, 5, 5, 0], 0.4);
266 Signal[1, 2, 3, 4].blend(Signal[5, 5, 5, 0], 1);
267 Signal[1, 2, 3, 4].blend(Signal[5, 5, 5, 0], 2);
270 subsection::Fourier Transform
272 method::fft
273 Perform an FFT on a real and imaginary signal in place. See also the class method link::#*fftCosTable::.
274 code::
276 var size = 512, real, imag, cosTable, complex;
278 real = Signal.newClear(size);
279                 // some harmonics
280 real.sineFill2([[8], [13, 0.5], [21, 0.25], [55, 0.125, 0.5pi]]);
281                 // add a little noise
282 real.overDub(Signal.fill(size, { 0.2.bilinrand }));
284 imag = Signal.newClear(size);
285 cosTable = Signal.fftCosTable(size);
287 complex = fft(real, imag, cosTable);
288 [real, imag, (complex.magnitude) / 100 ].flop.flat
289         .plot("fft", Rect(0, 0, 512 + 8, 500), numChannels: 3);
293 method::ifft
294 Perform an inverse FFT on a real and imaginary signal in place. See also the class method link::#*fftCosTable::.
295 code::
297 var size = 512, real, imag, cosTable, complex, ifft;
299 real = Signal.newClear(size);
300                 // some harmonics
301 real.sineFill2([[8], [13, 0.5], [21, 0.25], [55, 0.125, 0.5pi]]);
302                 // add a little noise
303 real.overDub(Signal.fill(size, { 0.2.bilinrand }));
305 imag = Signal.newClear(size);
306 cosTable = Signal.fftCosTable(size);
308 complex = fft(real, imag, cosTable).postln;
309 ifft = complex.real.ifft(complex.imag, cosTable);
311 [real, ifft.real].flop.flat
312         .plot("fft and back", Rect(0, 0, 512 + 8, 500), numChannels: 2);
316 subsection::Unary Messages
318 Signal will respond to unary operators by returning a new Signal.
319 code::
320 x = Signal.sineFill(512, [0, 0, 0, 1]);
321 [x, x.neg, x.abs, x.sign, x.squared, x.cubed, x.asin.normalize, x.exp.normalize, x.distort].flop.flat
322         .plot(numChannels: 9);
325 method::neg, abs, sign, squared, cubed, sqrt, exp, log, log2, log10, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, distort, softclip, isPositive, isNegative, isStrictlyPositive
327 subsection::Binary Messages
329 Signal will respond to binary operators by returning a new Signal.
330 code::
332 x = Signal.fill(512, { rrand(0.0, 1.0) });
333 y = Signal.fill(512, { |i| (i * pi / 64).sin });
334 [x, y, (x + y) * 0.5, x * y, min(x, y), max(x, y) ].flop.flat
335         .plot(numChannels: 6);
338 method::+, -, *, /, div, %, **, min, max, ring1, ring2, ring3, ring4, difsqr, sumsqr, sqrdif, absdif, amclip, scaleneg, clip2, excess, <!