2 categories:: Language, Common methods
3 summary:: common unary and binary operators
4 related:: Reference/Adverbs
6 SuperCollider supports operator overloading. Operators can thus be applied to a variety of different objects; Numbers, Ugens, Collections, and so on. When operators are applied to ugens they result in link::Classes/BinaryOpUGen::s or link::Classes/UnaryOpUGen::s, through the methods of link::Classes/AbstractFunction::.
8 This is a list of some of the common unary and binary operators that are implemented by several classes.
9 See the specific classes for details and other operators.
11 You can see which classes implements a specific operator by clicking on the method name.
13 section:: Unary Operators
14 Unary operators may be written in two ways:
43 a = Line.ar(-1, 1, 0.01);
54 a = Line.ar(-1, 1, 0.01);
65 -1 when a < 0, +1 when a > 0, 0 when a is 0
80 The definition of square root is extended for signals so that sqrt(a) when a<0 returns
87 Convert MIDI note number to cycles per second.
91 Saw.ar(Line.kr(24,108,10).midicps, 0.2)
96 Convert cycles per second to MIDI note.
99 Convert an interval in MIDI notes into a frequency ratio.
102 Convert a frequency ratio to an interval in MIDI notes.
105 Convert decibels to linear amplitude.
108 Convert linear amplitude to decibels.
111 Convert decimal octaves to cycles per second.
114 Convert cycles per second to decimal octaves.
123 a = Line.ar(e, 1/e, 0.01);
162 Nonlinear distortion.
168 a = Line.ar(-4, 4, 0.01);
173 { FSinOsc.ar(500, 0.0, XLine.kr(0.1, 10, 10)).distort * 0.25 }.scope;
177 Nonlinear distortion.
179 Distortion with a perfectly linear region from -0.5 to +0.5
184 a = Line.ar(-2, 2, 0.01);
190 { FSinOsc.ar(500,0.0, XLine.kr(0.1, 10, 10)).softclip * 0.25 }.scope(2);
194 Test if signal is >= 0.
197 Test if signal is < 0.
199 method:: isStrictlyPositive
200 Test if signal is > 0.
202 section:: Binary Operators
203 Three different syntaxes can be used for binary operators consisting of letters:
211 Operators consisting of symbols are written like this:
216 subsection:: Arithmetics
231 Floating point modulo.
234 Exponentiation. When used with UGens which produce a negative signal this function extends the usual definition of
235 exponentiation and returns neg(neg(a) ** b). This allows exponentiation of negative signal values by noninteger exponents. For the normal behaviour use pow (see below).
240 subsection:: Comparisions
251 With UGens, this can be useful for triggering purposes, among other things:
253 { // trigger an envelope
255 trig = SinOsc.ar(1) > 0;
257 EnvGen.kr(Env.perc, trig, doneAction: 0)
258 * SinOsc.ar(440,0,0.1)
263 SynthDef("help-EnvGen",{ arg out=0;
265 EnvGen.kr(Env.perc,1.0,doneAction: 2)
266 * SinOsc.ar(440,0,0.1)
270 // This synth has no output. It only checks amplitude of input and looks for a transition from < 0.2
273 SynthDef("help-> trig", {
274 SendTrig.kr(Amplitude.kr(SoundIn.ar(0)) > 0.2);
277 // OSCFunc to trigger synth
278 OSCFunc({ "triggered".postln; Synth.new("help-EnvGen") },'/tr', s.addr);
283 Greater than or equal.
294 Return first argument.
300 { // distorts and envelopes z
303 z min: FSinOsc.ar(0.1);
311 { // modulates and envelopes z
314 z max: FSinOsc.ar(0.1);
319 Quantization by rounding. Rounds a to the nearest multiple of b.
322 Quantization by truncation. Truncate a to a multiple of b.
325 Hypotenuse. Returns the square root of the sum of the squares of a and b. Or equivalently, the distance from the origin
328 In this example, hypot is used to calculate a doppler shift pitch and amplitude based on distance.
332 var x, y, distance, velocity, pitchRatio, amplitude;
333 // object travels 200 meters in 6 secs (=120kph) passing 10 meters
336 y = LFSaw.kr(1/6, 0, 100);
337 distance = hypot(x, y);
338 velocity = Slope.kr(distance);
339 pitchRatio = (344 - velocity) / 344; // speed of sound is 344 meters/sec
340 amplitude = 10 / distance.squared;
341 FSinOsc.ar(1000 * pitchRatio, 0, amplitude)
344 The next example uses the distance to modulate a delay line.
348 var x, y, distance, velocity, pitchRatio, amplitude, motorSound;
349 // object travels 200 meters in 6 secs (=120kph) passing 10 meters
352 y = LFSaw.kr(1/6, 0, 100);
353 distance = hypot(x, y);
354 amplitude = 40 / distance.squared;
355 motorSound = RLPF.ar(FSinOsc.ar(200, 0, LFPulse.ar(31.3, 0, 0.4)), 400, 0.3);
356 DelayL.ar(motorSound, 110/344, distance/344, amplitude)
361 Hypotenuse approximation. Returns an approximation of the square root of the sum of the squares of x and y.
363 The formula used is :
365 abs(x) + abs(y) - ((sqrt(2) - 1) * min(abs(x), abs(y)))
367 hypotApx is used to implement Complex method magnitudeApx.
368 This should not be used for simulating a doppler shift because it is discontinuous. Use hypot.
370 See also link::#.hypot::, link::#.atan2::.
373 Returns the arctangent of y/x.
375 OK, now we can add a pan to the link::#.hypot:: doppler examples by using atan2 to find the azimuth,
376 or direction angle, of the sound source.
377 Assume speakers at +/- 45 degrees and clip the direction to between those.
381 var x, y, distance, velocity, pitchRatio, amplitude, azimuth, panValue;
382 // object travels 200 meters in 6 secs (=120kph) passing 10 meters
385 y = LFSaw.kr(1/6, 0, 100);
386 distance = hypot(x, y);
387 velocity = Slope.kr(distance);
388 pitchRatio = (344 - velocity) / 344; // speed of sound is 344 meters/sec
389 amplitude = 10 / distance.squared;
390 azimuth = atan2(y, x); // azimuth in radians
391 panValue = (azimuth / 0.5pi).clip2(1);
392 Pan2.ar(FSinOsc.ar(1000 * pitchRatio), panValue, amplitude)
397 var x, y, distance, velocity, pitchRatio, amplitude, motorSound,
399 // object travels 200 meters in 6 secs (=120kph) passing 10 meters
402 y = LFSaw.kr(1/6, 0, 100);
403 distance = hypot(x, y);
404 amplitude = 40 / distance.squared;
405 motorSound = RLPF.ar(FSinOsc.ar(200, 0, LFPulse.ar(31.3, 0, 0.4)), 400, 0.3);
406 azimuth = atan2(y, x); // azimuth in radians
407 panValue = (azimuth / 0.5pi).clip2(1); // make a value for Pan2 from azimuth
408 Pan2.ar(DelayL.ar(motorSound, 110/344, distance/344), panValue, amplitude)
413 Ring modulation plus first source.
415 Return the value of ((a*b) + a). This is more efficient than using
416 separate unit generators for the multiply and add.
418 See also link::#.*::, link::#.ring1::, link::#.ring2::, link::#.ring3::, link::#.ring4::.
420 { (FSinOsc.ar(800) ring1: FSinOsc.ar(XLine.kr(200,500,5))) * 0.125 }.play;
428 b = FSinOsc.ar(XLine.kr(200,500,5));
429 ((a * b) + a) * 0.125
432 normal ring modulation:
438 b = FSinOsc.ar(XLine.kr(200,500,5));
444 Ring modulation plus both sources.
446 Return the value of ((a*b) + a + b). This is more efficient than using
447 separate unit generators for the multiply and adds.
449 { (FSinOsc.ar(800) ring2: FSinOsc.ar(XLine.kr(200,500,5))) * 0.125 }.play;
457 b = FSinOsc.ar(XLine.kr(200,500,5));
458 ((a * b) + a + b) * 0.125
463 Ring modulation variant.
465 Return the value of (a*a *b). This is more efficient than using
466 separate unit generators for each multiply.
468 { (FSinOsc.ar(800) ring3: FSinOsc.ar(XLine.kr(200,500,5))) * 0.125 }.play;
476 b = FSinOsc.ar(XLine.kr(200,500,5));
482 Ring modulation variant.
484 Return the value of ((a*a *b) - (a*b*b)). This is more efficient than using
485 separate unit generators for each operation.
487 { (FSinOsc.ar(800) ring4: FSinOsc.ar(XLine.kr(200,500,5))) * 0.125 }.play;
495 b = FSinOsc.ar(XLine.kr(200,500,5));
496 ((a * a * b) - (a * b * b)) * 0.125
503 Return the value of (a*a) + (b*b). This is more efficient than using
504 separate unit generators for each operation.
506 { (FSinOsc.ar(800) sumsqr: FSinOsc.ar(XLine.kr(200,500,5))) * 0.125 }.play;
514 b = FSinOsc.ar(XLine.kr(200,500,5));
515 ((a * a) + (b * b)) * 0.125
520 Difference of squares.
522 Return the value of (a*a) - (b*b). This is more efficient than using
523 separate unit generators for each operation.
525 { (FSinOsc.ar(800) difsqr: FSinOsc.ar(XLine.kr(200,500,5))) * 0.125 }.play;
533 b = FSinOsc.ar(XLine.kr(200,500,5));
534 ((a * a) - (b * b)) * 0.125
541 Return the value of (a + b)**2. This is more efficient than using
542 separate unit generators for each operation.
544 { (FSinOsc.ar(800) sqrsum: FSinOsc.ar(XLine.kr(200,500,5))) * 0.125 }.play;
552 b = FSinOsc.ar(XLine.kr(200,500,5));
559 Square of the difference.
561 Return the value of (a - b)**2. This is more efficient than using
562 separate unit generators for each operation.
564 { (FSinOsc.ar(800) sqrdif: FSinOsc.ar(XLine.kr(200,500,5))) * 0.125 }.play;
572 b = FSinOsc.ar(XLine.kr(200,500,5));
579 Absolute value of the difference. code:: abs(a - b) ::
582 { // creates a rhythm
584 mul = 0.2 absdif: FSinOsc.ar(2, 0, 0.5);
585 FSinOsc.ar(440, 0, mul);
592 0 when a < b, otherwise a.
594 { LFNoise0.ar(50, 0.5) thresh: 0.45 }.play // a low-rent gate
598 Two quadrant multiply.
600 0 when b <= 0, a*b when b > 0
602 { WhiteNoise.ar.amclip(FSinOsc.kr(1,0.2)) }.play; // makes a sine envelope
606 Scale negative part of input.
608 a*b when a < 0, otherwise a.
610 { FSinOsc.ar(500).scaleneg(Line.ar(1,-1,4)) }.play;
616 clips input wave a to +/- b
621 a = Line.ar(-2, 2, 0.01);
626 { FSinOsc.ar(400).clip2(0.2) }.scope; // clipping distortion
628 { FSinOsc.ar(1000).clip2(Line.kr(0,1,8)) }.scope;
634 wraps input wave to +/- b
639 a = Line.ar(-2, 2, 0.01);
644 { FSinOsc.ar(1000).wrap2(Line.kr(0,1.01,8)) }.scope;
650 folds input wave a to +/- b
655 a = Line.ar(-2, 2, 0.01);
661 { FSinOsc.ar(1000).fold2(Line.kr(0,1,8)) }.scope;
665 Residual of clipping.
667 Returns the difference of the original signal and its clipped form: (a - clip2(a,b)).
672 a = Line.ar(-2, 2, 0.01);
677 { FSinOsc.ar(1000).excess(Line.kr(0,1,8)) }.play;