This file is indexed.

/usr/share/SuperCollider/HelpSource/Classes/Signal.schelp is in supercollider-common 1:3.8.0~repack-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
CLASS::Signal
summary::Sampled audio buffer
related::Classes/Wavetable
categories:: Collections>Ordered

DESCRIPTION::
A Signal is a FloatArray that represents a sampled function of time buffer.  Signals support math operations.

CLASSMETHODS::

method::sineFill
Fill a Signal of the given size with a sum of sines at the given amplitudes and phases. The Signal will be normalized.
code::
Signal.sineFill(1000, 1.0/[1, 2, 3, 4, 5, 6]).plot;
::
argument::size
the number of samples in the Signal.
argument::amplitudes
an Array of amplitudes for each harmonic beginning with the fundamental.
argument::phases
an Array of phases in radians for each harmonic beginning with the fundamental.

method::chebyFill
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.
argument::size
the number of samples in the Signal.
argument::amplitudes
an link::Classes/Array:: of amplitudes for each Chebyshev polynomial beginning with order 1.
argument::normalize
a link::Classes/Boolean:: indicating whether to normalize the resulting Signal. If the zeroOffset argument is true, the normalization is done for use as a transfer function, using link::Classes/Signal#-normalizeTransfer#normalizeTransfer::, otherwise it just uses link::Classes/Signal#-normalize#normalize:: to make the absolute peak value 1.  Default is true.
argument::zeroOffset
a link::Classes/Boolean:: indicating whether to offset the middle of each polynomial to zero. If true, then a zero input will always result in a zero output when used as a link::Classes/Shaper##waveshaper::. If false, then the "raw" (unshifted) Chebyshev polynomials are used. Default is false.
discussion::
note::
In previous versions, chebyFill always offset the curves to ensure the center value was zero. The zeroOffset argument was added in version 3.7, and the default behavior was changed, so that it no longer offsets.
::
code::
Signal.chebyFill(1000, [1]).plot;

// shifted to avoid DC offset when waveshaping a zero signal
Signal.chebyFill(1000, [0, 1], zeroOffset: true).plot;

// normalized sum of (unshifted) Chebyshev polynomials (the default)
Signal.chebyFill(1000, [0, 1, 0, 0, 0, 1], normalize: true, zeroOffset: false).plot;

Signal.chebyFill(1000, [0, 0, 1]).plot;
Signal.chebyFill(1000, [0.3, -0.8, 1.1]).plot;


// This waveshaping example uses two buffers, one with zero offset and
// the other not.
//
// 1. The offset version gives zero output (DC free) when waveshaping an
// input signal with amplitude of zero (e.g. DC.ar(0)).
//
// 2. The non-offset version makes better use of the full (-1 to 1) range
// when waveshaping a varying signal with amplitude near 1, but (if even
// Chebyshev polynomial degrees are used) will have a DC offset when
// waveshaping a signal with amplitude of zero.
//
// 3. Wrapping the non-offset Shaper in a LeakDC (the third signal in the
// example) cancels out any DC offsets (third version), while making full use
// of the -1 to 1 range.
(
s.waitForBoot({
	var amplitudes = [0, 1, 1, -2, 1];
	var sigs = [
		Signal.chebyFill(256+1, amplitudes, normalize: true, zeroOffset: true),
		Signal.chebyFill(256+1, amplitudes, normalize: true, zeroOffset: false)
	];
	b = sigs.collect{ arg sig; Buffer.loadCollection(s, sig.asWavetableNoWrap) };
	s.sync;
	x = {
		var in = SinOsc.ar(100, 0, SinOsc.kr(0.1, 0, 0.5, 0.5));
		Shaper.ar(b, in ) ++ LeakDC.ar(Shaper.ar(b[1], in))
	}.scope;
})
)
x.free; b.do(_.free); b = nil
::

method::hanningWindow
Fill a Signal of the given size with a Hanning window.
code::
Signal.hanningWindow(1024).plot;
Signal.hanningWindow(1024, 512).plot;
::
argument::size
the number of samples in the Signal.
argument::pad
the number of samples of the size that is zero padding.

method::hammingWindow
Fill a Signal of the given size with a Hamming window.
code::
Signal.hammingWindow(1024).plot;
Signal.hammingWindow(1024, 512).plot;
::
argument::size
the number of samples in the Signal.
argument::pad
the number of samples of the size that is zero padding.

method::welchWindow
Fill a Signal of the given size with a Welch window.
code::
Signal.welchWindow(1024).plot;
Signal.welchWindow(1024, 512).plot;
::
argument::size
the number of samples in the Signal.
argument::pad
the number of samples of the size that is zero padding.

method::rectWindow
Fill a Signal of the given size with a rectangular window.
code::
Signal.rectWindow(1024).plot;
Signal.rectWindow(1024, 512).plot;
::
argument::size
the number of samples in the Signal.
argument::pad
the number of samples of the size that is zero padding.

method::fftCosTable
Fourier Transform: Fill a Signal with the cosine table needed by the FFT methods. See also the instance methods link::#-fft:: and link::#-ifft::.
code::
Signal.fftCosTable(512).plot;
::

INSTANCEMETHODS::

private::performBinaryOpOnSignal, performBinaryOpOnComplex, performBinaryOpOnSimpleNumber

method::plot
Plot the Signal in a window. The arguments are not required and if not given defaults will be used.
code::
Signal.sineFill(512, [1]).plot;
Signal.sineFill(512, [1]).plot("Signal 1", Rect(50, 50, 150, 450));
::
argument::name
a String, the name of the window.
argument::bounds
a Rect giving the bounds of the window.

method::play
Loads the signal into a buffer on the server and plays it. Returns the buffer so you can free it again.
code::
b = Signal.sineFill(512, [1]).play(true, 0.2);
b.free;	// free the buffer again.
::
argument::loop
A link::Classes/Boolean:: whether to loop the entire signal or play it once. Default is false.
argument::mul
volume at which to play it, 0.2 by default.
argument::numChannels
if the signal is an interleaved multichannel file, number of channels, default is 1.
argument::server
the server on which to load the signal into a buffer.

method::waveFill
Fill the Signal with a function evaluated over an interval.

argument::function
a function that should calculate the value of a sample.
code::
(
a = Signal.newClear(256);
a.waveFill({ arg x, old, i; sin(x)}, 0, 3pi);
a.waveFill({ arg x, old, i; old * sin(11 * x + 0.3) }, 0, 3pi);
a.waveFill({ arg x, old, i; old * (x % 4) }, 0, 3pi);

a.plot;
)
::


The function is called with three arguments:
definitionList::
## x || the value along the interval.
## old || the old value (if the signal is overwritten)
## i || the sample index.
::
As arguments, three values are passed to the function: the current input value (abscissa), the old value (if the signal is overwritten), and the index.
code::
(
a = Signal.newClear(16);
a.waveFill({ arg x, prev, i; [x, prev, i].postln; sin(x).max(0) }, 0, 3pi);
a.plot;
)
::



argument::start
the starting value of the interval.
argument::end
the ending value of the interval.

method::asWavetable
Convert the Signal into a Wavetable.
code::
Signal.sineFill(512, [1]).asWavetable.plot;
::

method::fill
Fill the Signal with a value.
code::
Signal.newClear(512).fill(0.2).plot;
::

method::scale
Scale the Signal by a factor strong::in place::.
code::
a = Signal[1, 2, 3, 4];
a.scale(0.5); a;
::

method::offset
Offset the Signal by a value strong::in place::.
code::
a = Signal[1, 2, 3, 4];
a.offset(0.5); a;
::

method::peak
Return the peak absolute value of a Signal.
code::
Signal[1, 2, -3, 2.5].peak;
::

method::normalize
Normalize the Signal strong::in place:: such that the maximum absolute peak value is 1.
code::
Signal[1, 2, -4, 2.5].normalize;
Signal[1, 2, -4, 2.5].normalize(0, 1);	// normalize only a range
::

method::normalizeTransfer
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.
code::
Signal[1, 2, 3, 2.5, 1].normalizeTransfer;
::

method::invert
Invert the Signal strong::in place::.
code::
a = Signal[1, 2, 3, 4];
a.invert(0.5); a;
::

method::reverse
Reverse a subrange of the Signal strong::in place::.
code::
a = Signal[1, 2, 3, 4];
a.reverse(1, 2); a;
::

method::fade
Fade a subrange of the Signal strong::in place::.
code::
a = Signal.fill(10, 1);
a.fade(0, 3);		// fade in
a.fade(6, 9, 1, 0);	// fade out
::

method::integral
Return the integral of a signal.
code::
Signal[1, 2, 3, 4].integral;
::

method::overDub
Add a signal to myself starting at the index. If the other signal is too long only the first part is overdubbed.
code::
a = Signal.fill(10, 100);
a.overDub(Signal[1, 2, 3, 4], 3);

		// run out of range
a = Signal.fill(10, 100);
a.overDub(Signal[1, 2, 3, 4], 8);

a = Signal.fill(10, 100);
a.overDub(Signal[1, 2, 3, 4], -4);

a = Signal.fill(10, 100);
a.overDub(Signal[1, 2, 3, 4], -1);

a = Signal.fill(10, 100);
a.overDub(Signal[1, 2, 3, 4], -2);

a = Signal.fill(4, 100);
a.overDub(Signal[1, 2, 3, 4, 5, 6, 7, 8], -2);
::

method::overWrite
Write a signal to myself starting at the index. If the other signal is too long only the first part is overdubbed.
code::
a = Signal.fill(10, 100);
a.overWrite(Signal[1, 2, 3, 4], 3);

		// run out of range
a = Signal.fill(10, 100);
a.overWrite(Signal[1, 2, 3, 4], 8);

a = Signal.fill(10, 100);
a.overWrite(Signal[1, 2, 3, 4], -4);

a = Signal.fill(10, 100);
a.overWrite(Signal[1, 2, 3, 4], -1);

a = Signal.fill(10, 100);
a.overWrite(Signal[1, 2, 3, 4], -2);

a = Signal.fill(4, 100);
a.overWrite(Signal[1, 2, 3, 4, 5, 6, 7, 8], -2);
::

method::blend
Blend two signals by some proportion.
code::
Signal[1, 2, 3, 4].blend(Signal[5, 5, 5, 0], 0);
Signal[1, 2, 3, 4].blend(Signal[5, 5, 5, 0], 0.2);
Signal[1, 2, 3, 4].blend(Signal[5, 5, 5, 0], 0.4);
Signal[1, 2, 3, 4].blend(Signal[5, 5, 5, 0], 1);
Signal[1, 2, 3, 4].blend(Signal[5, 5, 5, 0], 2);
::

subsection::Fourier Transform

method::fft
Perform an FFT on a real and imaginary signal in place. See also the class method link::#*fftCosTable::.
code::
(
var size = 512, real, imag, cosTable, complex;

real = Signal.newClear(size);
		// some harmonics
real.sineFill2([[8], [13, 0.5], [21, 0.25], [55, 0.125, 0.5pi]]);
		// add a little noise
real.overDub(Signal.fill(size, { 0.2.bilinrand }));

imag = Signal.newClear(size);
cosTable = Signal.fftCosTable(size);

complex = fft(real, imag, cosTable);
[real, imag, (complex.magnitude) / 100 ].flop.flat
	.plot("fft", Rect(0, 0, 512 + 8, 500), numChannels: 3);
)
::

method::ifft
Perform an inverse FFT on a real and imaginary signal in place. See also the class method link::#*fftCosTable::.
code::
(
var size = 512, real, imag, cosTable, complex, ifft;

real = Signal.newClear(size);
		// some harmonics
real.sineFill2([[8], [13, 0.5], [21, 0.25], [55, 0.125, 0.5pi]]);
		// add a little noise
real.overDub(Signal.fill(size, { 0.2.bilinrand }));

imag = Signal.newClear(size);
cosTable = Signal.fftCosTable(size);

complex = fft(real, imag, cosTable).postln;
ifft = complex.real.ifft(complex.imag, cosTable);

[real, ifft.real].flop.flat
	.plot("fft and back", Rect(0, 0, 512 + 8, 500), numChannels: 2);
)
::

subsection::Unary Messages

Signal will respond to unary operators by returning a new Signal.
code::
x = Signal.sineFill(512, [0, 0, 0, 1]);
[x, x.neg, x.abs, x.sign, x.squared, x.cubed, x.asin.normalize, x.exp.normalize, x.distort].flop.flat
	.plot(numChannels: 9);
::

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

subsection::Binary Messages

Signal will respond to binary operators by returning a new Signal.
code::
(
x = Signal.fill(512, { rrand(0.0, 1.0) });
y = Signal.fill(512, { |i| (i * pi / 64).sin });
[x, y, (x + y) * 0.5, x * y, min(x, y), max(x, y) ].flop.flat
	.plot(numChannels: 6);
)
::
method::+, -, *, /, div, %, **, min, max, ring1, ring2, ring3, ring4, difsqr, sumsqr, sqrdif, absdif, amclip, scaleneg, clip2, excess, <!