• jon@schemawound.com
Supercollider
Music Is Math

Music Is Math

In learning Supercollider, PureData, ChucK and Csound I found that there was one lesson missing from all the tutorials I read.  That was a lesson on of how simple math operations worked to produce effects on various signals.  This is basic information that is needed to be successful in any of these languages.  

My code samples will be in Supercollider as that is the language I am most comfortable in but these examples should be easy enough to replicate in your language of choice.

I do not claim to be an expert on the subject so any feedback or corrections are much appreciated.

Background

In digital audio amplitude is represented as a series of values from -1 to 1.  These values represent the maximum amplitude that can be reproduced correctly.  Anything outside of these ranges will result in a hard digital distortion called clipping.  The amplitude can exceed these values during processing but to avoid clipping they must be reduced before the final output.

A signal is said to be bipolar if it uses the full range from -1 to 1.  A signal that only uses 0 to 1 is called unipolar.

Multiplication Of Two Signals

a) SinOsc.ar(1000)

b) SinOsc.ar(100)

c) SinOsc.ar(1000) * SinOsc.ar(100)

Multiplying two signals together will result in the effect of amplitude modulation.  At slow speeds this sounds like volume fluctuation in the signal, at higher rates it will produce a noticeable change in the sound of the signal.  This will not ever result in clipping as long as both signals remain in the range of -1 to 1.

Multiplication By A Positive Fixed Amount

a) SinOsc.ar(1000)

b) 0.5

c) SinOsc.ar(1000) * 0.5

Multiplying by a fixed amount will result in the scaling of a waveform.  Values less then 1 will reduce the volume and values greater then 1 will increase it.

Multiplying By A Negative Fixed Amount

a) SinOsc.ar(1000)

b) -1

c) SinOsc.ar(1000) * -1

Multiplying by a negative works the same as multiplying by a positive except the waveform will have its phase shifted by 180 degrees.

Addition Of Two Signals

a) SinOsc.ar(1000)

b) SinOsc.ar(100)

c) (SinOsc.ar(1000) + SinOsc.ar(100)) * 0.5

Addition of two signals will result in both signals being able to be heard playing together.  Often times you will also need to multiply to scale the signals before or after the addition in order to avoid clipping.

Addition By A Fixed Amount

a) SinOsc.ar(1000)

b) 0.5

c) (SinOsc.ar(1000) * 0.5) + 0.5

Addition by a fixed amount is not useful directly on signal output to the speakers.  Addition is useful for adding an offset to a signal to move it into a desired output range in order to later apply it to another parameter.  

In the above example we multiple the SinOsc by 0.5 to reduce it’s amplitude by half.  We then add an offset of 0.5 to it.  This process has turned out bipolar sine into a unipolar sine.

Scaling

Supercollider has some shortcuts that help to avoid complicated formulas using fixed values.  

The first shortcut is that most Ugens include a mul and add parameter, this allows you to include your multiplication and addition values within the call to the Ugen.

The next shortcut method is to use the range method call to specify the exact output range you need rather then calculating the add and mul values.

All 3 of these statements produce the same result:

SinOsc.ar(1000) * 0.5 + 0.5
SinOsc.ar(1000, mul: 0.5, add:0.5)
SinOsc.ar(1000).range(0,1)

Further Experiments

a) SinOsc.ar(1000) ** 2

b) SinOsc.ar(1000) ** 70

c) SinOsc.ar(1000) % 5

Supercollider offers an impressive array of math functions.  By experimenting with different combinations of them even the simple sine wave can be transformed into something much more complex.