/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, <!
|