This page is supposed to be a short catalog of the fundamental techniques in digital sound synthesis. It doesn't go into great depth on any one topic but it is hoped it will provide some quick starting points for experimentation with SuperCollider.

I will keep adding to this as I discover more.

When designing synthesis instruments the task involves assembling simple building blocks which are know as *Unit Generators* (or UGens in SuperCollider).

The unit generator is a fundamental concept in digital synthesis. A UGen is either a signal

generatoror a signalmodifier. A signal generator (such as an oscillator [i.e. SinOsc, VarSaw]) synthesizes signals such as a musical waveforms and envelopes. A signal modifier, such as a filter, take a signal as its input, and transforms that input signal in some way. [Roads (1996)]

So we have generator (oscillators) and modifiers (filters) and to construct instruments we put the output of one into the input(s) of another or combine the signals together in various ways.

For a comprehensive look at most (all?) the UGens in SuperCollider, and their groupings, checkout the mighty Tour of UGens in the help.

You might want to see what your doing with this Frequency Scope:

```
FreqScope.new
```

If you are working on poor quality speakers (i.e. laptop speakers) then you will not be able to hear all the sound you are generating, particularly low frequency sounds which might surprise you later when played on speakers that can reach those depth. Thus its a good idea to use the Frequency scope to *see* what you otherwise can not *hear*.

Clicking on the sound server box and pressing `l`

will bring up the levels for that server so you can see if you are getting any clipping (i.e. the signal is above 1).

With additive synthesis we create complex sounds by summing together simpler ones.

From Moorer (1976):

```
(
Ndef(\dsf, {
var freq = 112 // fundamental
, a = 42 // decay
, b = 300 // distance
;
SinOsc.ar(freq) - (a * SinOsc.ar(freq - b)) / ((1 + a.pow(2)) - 2*a*SinOsc.ar(b, pi/2));
}).play;
)
```

Here `freq`

is the fundamental frequency, b is the harmonic spacing (distance), harmonic decay

Another approach from Dodge and Jerse (1985) which uses one less oscillator:

```
(
Ndef(\dsf2, {
var n = 12 // number of harmonics
, amp = 0.8
, freq = 100
;
f = freq / 2;
(SinOsc.ar((2*n+1)*f) / SinOsc.ar(f) - 1) * amp / (2 * n);
}).play;
)
```

From Waveshaping in SuperCollider by Chris Jeffs (also a good intro to the concepts there).

First to create the transfer function that the signal will be remapped with:

```
(
// in order to be turned into a wavetable,
// the signal must be half buffer size plus one
x = Signal.sineFill(513, [0.5, 0.2, 0.3, 0.0, 0.2]);
x.plot;
b = Buffer.alloc(s, 1024, 1);
)
b.sendCollection(x.asWavetableNoWrap);
```

Then use the Shaper UGen to use it:

```
(
Ndef(\waveshaper, {
var input, output;
input = SinOsc.ar(MouseX.kr(80, 800, \exponential), 0, 0.7);
// Shaper is the waveshaping Ugen
output = Shaper.ar(b.bufnum, input);
output ! 2
}).scope;
)
```

Modulation is the idea that you use one oscillator as the input to controlling a parameter of another.

```
(
Ndef(\fm, {
var modulator = 200;
var fm_index = 50;
var carrier = 600;
SinOsc.ar( SinOsc.ar(modulator) * fm_index + carrier )
}).play
)
```

FM modulation gives frequency sidebands at integer multiples of the modulating frequency.

Move your mouse around to explore the sound space:

```
(
Ndef(\fm_pm_fun, {
SinOsc.ar(SinOsc.ar(MouseX.kr(0.5, 1000, 1), MouseY.kr(0.5, 1000, 1), 100, 200))
}).play
)
```

Modulating the phase of an oscillator is the same as modulating its frequency. This gives us the chance to have both FM & PM at the same time.

AM is simply multiplying one signal by another which is like applying a dynamic envelope to a signal. The original signal is called the *carrier* and the multiplier signal is called the *modulator*.

```
(
Ndef(\ring, {
a = SinOsc.ar(320); // carrier
b = SinOsc.ar(440) + 1; // modulator
(a * b) * 0.5
}).play;
)
```

The `+1`

here means some carrier signal will make it to the output, the modulator frequency will not. Frequency sidebands appear at:

```
carrier, carrier ± modulator
```

so here its 320Hz, 760Hz and 120Hz (this last one is reflected about zero).

We can increase the number of components with the following

```
(
Ndef(\allband, {
a = SinOsc.ar(320); // carrier
b = SinOsc.ar(440); // modulator
(a + b) + (a * b) * 0.5
}).play;
)
```

Here we get Frequency sidebands of:

```
carrier, modulator, carrier ± modulator
```

so for the example 320Hz, 440Hz, 120Hz and 760Hz.

AM signals can be cascaded to increase the complexity of the output signal like so, taking our original `\ring`

example:

```
(
Ndef(\ring, {
a = SinOsc.ar(320); // carrier 1
b = SinOsc.ar(440); // carrier 2
c = SinOsc.ar(900); // modulator
((a + b) * 0.5) * c * 0.5
}).play;
)
```

This gives 4 frequency sidebands:

```
carrier 1 ± modulator, carrier 1 ± modulator
```

So for the above example we get sidebands at 1300Hz, 500Hz, 1200Hz and 600Hz.

Since because SuperCollider is not some patching interface but instead a language we can easily create as many cascades as we like with a loop

```
(
Ndef(\ring, {
var freq = 320; // Base frequency
var freq2 = 440;
var n = 6; // number of cascades
var sound = SinOsc.ar(freq) + SinOsc.ar(freq2); // carriers
// This repeats n-times and mixes the result together
Mix.fill(n, { | i |
sound * SinOsc.ar(freq + (i * 100)) * 0.5
})
}).play;
)
```

- Farnell, Andy (2010) Designing Sound, MIT Press
- Many of the code here originated from his PureData examples. There has also been some work to convert his more complex examples to SuperCollider code.
- Roads, Curtis (1996) The Computer Music Tutorial, MIT Press
- The seminal work of Curtis Roads that as comprehensive about computer music as it is heavy.